| background: #155eef url(./assets/check.svg) center center no-repeat; | background: #155eef url(./assets/check.svg) center center no-repeat; | ||||
| background-size: 12px 12px; | background-size: 12px 12px; | ||||
| border-color: #155eef; | border-color: #155eef; | ||||
| } | |||||
| .checked.disabled { | |||||
| background-color: #d0d5dd; | |||||
| border-color: #d0d5dd; | |||||
| } | } |
| checked?: boolean | checked?: boolean | ||||
| onCheck?: () => void | onCheck?: () => void | ||||
| className?: string | className?: string | ||||
| disabled?: boolean | |||||
| } | } | ||||
| const Checkbox = ({ checked, onCheck, className }: CheckboxProps) => { | |||||
| const Checkbox = ({ checked, onCheck, className, disabled }: CheckboxProps) => { | |||||
| return ( | return ( | ||||
| <div | <div | ||||
| className={cn(s.wrapper, checked && s.checked, 'w-4 h-4 border rounded border-gray-300', className)} | |||||
| onClick={onCheck} | |||||
| className={cn( | |||||
| s.wrapper, | |||||
| checked && s.checked, | |||||
| disabled && s.disabled, | |||||
| 'w-4 h-4 border rounded border-gray-300', | |||||
| className, | |||||
| )} | |||||
| onClick={() => { | |||||
| if (disabled) | |||||
| return | |||||
| onCheck?.() | |||||
| }} | |||||
| /> | /> | ||||
| ) | ) | ||||
| } | } |
| const firstWorkspaceId = notionWorkspaces[0]?.workspace_id | const firstWorkspaceId = notionWorkspaces[0]?.workspace_id | ||||
| const currentWorkspace = notionWorkspaces.find(workspace => workspace.workspace_id === currentWorkspaceId) | const currentWorkspace = notionWorkspaces.find(workspace => workspace.workspace_id === currentWorkspaceId) | ||||
| const getPagesMapAndSelectedPagesId: [DataSourceNotionPageMap, Set<string>] = useMemo(() => { | |||||
| const getPagesMapAndSelectedPagesId: [DataSourceNotionPageMap, Set<string>, Set<string>] = useMemo(() => { | |||||
| const selectedPagesId = new Set<string>() | const selectedPagesId = new Set<string>() | ||||
| const boundPagesId = new Set<string>() | |||||
| const pagesMap = notionWorkspaces.reduce((prev: DataSourceNotionPageMap, next: DataSourceNotionWorkspace) => { | const pagesMap = notionWorkspaces.reduce((prev: DataSourceNotionPageMap, next: DataSourceNotionWorkspace) => { | ||||
| next.pages.forEach((page) => { | next.pages.forEach((page) => { | ||||
| if (page.is_bound) | |||||
| if (page.is_bound) { | |||||
| selectedPagesId.add(page.page_id) | selectedPagesId.add(page.page_id) | ||||
| boundPagesId.add(page.page_id) | |||||
| } | |||||
| prev[page.page_id] = { | prev[page.page_id] = { | ||||
| ...page, | ...page, | ||||
| workspace_id: next.workspace_id, | workspace_id: next.workspace_id, | ||||
| return prev | return prev | ||||
| }, {}) | }, {}) | ||||
| return [pagesMap, selectedPagesId] | |||||
| return [pagesMap, selectedPagesId, boundPagesId] | |||||
| }, [notionWorkspaces]) | }, [notionWorkspaces]) | ||||
| const defaultSelectedPagesId = [...Array.from(getPagesMapAndSelectedPagesId[1]), ...(value || [])] | const defaultSelectedPagesId = [...Array.from(getPagesMapAndSelectedPagesId[1]), ...(value || [])] | ||||
| const [selectedPagesId, setSelectedPagesId] = useState<Set<string>>(new Set(defaultSelectedPagesId)) | const [selectedPagesId, setSelectedPagesId] = useState<Set<string>>(new Set(defaultSelectedPagesId)) | ||||
| <div className='rounded-b-xl overflow-hidden'> | <div className='rounded-b-xl overflow-hidden'> | ||||
| <PageSelector | <PageSelector | ||||
| value={selectedPagesId} | value={selectedPagesId} | ||||
| disabledValue={getPagesMapAndSelectedPagesId[2]} | |||||
| searchValue={searchValue} | searchValue={searchValue} | ||||
| list={currentWorkspace?.pages || []} | list={currentWorkspace?.pages || []} | ||||
| pagesMap={getPagesMapAndSelectedPagesId[0]} | pagesMap={getPagesMapAndSelectedPagesId[0]} |
| type PageSelectorProps = { | type PageSelectorProps = { | ||||
| value: Set<string> | value: Set<string> | ||||
| disabledValue: Set<string> | |||||
| searchValue: string | searchValue: string | ||||
| pagesMap: DataSourceNotionPageMap | pagesMap: DataSourceNotionPageMap | ||||
| list: DataSourceNotionPage[] | list: DataSourceNotionPage[] | ||||
| dataList: NotionPageItem[] | dataList: NotionPageItem[] | ||||
| handleToggle: (index: number) => void | handleToggle: (index: number) => void | ||||
| checkedIds: Set<string> | checkedIds: Set<string> | ||||
| disabledCheckedIds: Set<string> | |||||
| handleCheck: (index: number) => void | handleCheck: (index: number) => void | ||||
| canPreview?: boolean | canPreview?: boolean | ||||
| handlePreview: (index: number) => void | handlePreview: (index: number) => void | ||||
| pagesMap: DataSourceNotionPageMap | pagesMap: DataSourceNotionPageMap | ||||
| }>) => { | }>) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const { dataList, handleToggle, checkedIds, handleCheck, canPreview, handlePreview, listMapWithChildrenAndDescendants, searchValue, previewPageId, pagesMap } = data | |||||
| const { dataList, handleToggle, checkedIds, disabledCheckedIds, handleCheck, canPreview, handlePreview, listMapWithChildrenAndDescendants, searchValue, previewPageId, pagesMap } = data | |||||
| const current = dataList[index] | const current = dataList[index] | ||||
| const currentWithChildrenAndDescendants = listMapWithChildrenAndDescendants[current.page_id] | const currentWithChildrenAndDescendants = listMapWithChildrenAndDescendants[current.page_id] | ||||
| const hasChild = currentWithChildrenAndDescendants.descendants.size > 0 | const hasChild = currentWithChildrenAndDescendants.descendants.size > 0 | ||||
| const ancestors = currentWithChildrenAndDescendants.ancestors | const ancestors = currentWithChildrenAndDescendants.ancestors | ||||
| const breadCrumbs = ancestors.length ? [...ancestors, current.page_name] : [current.page_name] | const breadCrumbs = ancestors.length ? [...ancestors, current.page_name] : [current.page_name] | ||||
| const disabled = disabledCheckedIds.has(current.page_id) | |||||
| const renderArrow = () => { | const renderArrow = () => { | ||||
| if (hasChild) { | if (hasChild) { | ||||
| style={{ ...style, top: style.top as number + 8, left: 8, right: 8, width: 'calc(100% - 16px)' }} | style={{ ...style, top: style.top as number + 8, left: 8, right: 8, width: 'calc(100% - 16px)' }} | ||||
| > | > | ||||
| <Checkbox | <Checkbox | ||||
| className='shrink-0 mr-2 group-hover:border-primary-600 group-hover:border-[2px]' | |||||
| className={cn( | |||||
| 'shrink-0 mr-2 group-hover:border-primary-600 group-hover:border-[2px]', | |||||
| disabled && 'group-hover:border-transparent', | |||||
| )} | |||||
| checked={checkedIds.has(current.page_id)} | checked={checkedIds.has(current.page_id)} | ||||
| onCheck={() => handleCheck(index)} | |||||
| disabled={disabled} | |||||
| onCheck={() => { | |||||
| if (disabled) | |||||
| return | |||||
| handleCheck(index) | |||||
| }} | |||||
| /> | /> | ||||
| {!searchValue && renderArrow()} | {!searchValue && renderArrow()} | ||||
| <NotionIcon | <NotionIcon | ||||
| const PageSelector = ({ | const PageSelector = ({ | ||||
| value, | value, | ||||
| disabledValue, | |||||
| searchValue, | searchValue, | ||||
| pagesMap, | pagesMap, | ||||
| list, | list, | ||||
| dataList: currentDataList, | dataList: currentDataList, | ||||
| handleToggle, | handleToggle, | ||||
| checkedIds: value, | checkedIds: value, | ||||
| disabledCheckedIds: disabledValue, | |||||
| handleCheck, | handleCheck, | ||||
| canPreview, | canPreview, | ||||
| handlePreview, | handlePreview, |