diff --git a/web/src/api/buster-rest/permission_groups/requests.ts b/web/src/api/buster-rest/permission_groups/requests.ts index 0ff43cc92..d962c11d8 100644 --- a/web/src/api/buster-rest/permission_groups/requests.ts +++ b/web/src/api/buster-rest/permission_groups/requests.ts @@ -88,7 +88,7 @@ export const getPermissionGroupDatasetGroups = async ({ id }: { id: string; -}): Promise => { +}): Promise => { return await mainApi.get(`/permission_groups/${id}/dataset_groups`).then((res) => res.data); }; diff --git a/web/src/api/buster-rest/permission_groups/responseInterfaces.ts b/web/src/api/buster-rest/permission_groups/responseInterfaces.ts index a2896d55b..9354aa85e 100644 --- a/web/src/api/buster-rest/permission_groups/responseInterfaces.ts +++ b/web/src/api/buster-rest/permission_groups/responseInterfaces.ts @@ -26,4 +26,5 @@ export interface GetPermissionGroupDatasetsResponse { export interface GetPermissionGroupDatasetGroupsResponse { id: string; assigned: boolean; + name: string; } diff --git a/web/src/app/app/settings/permission-groups/[permissionGroupId]/dataset-groups/PermissionGroupDatasetGroupsController.tsx b/web/src/app/app/settings/permission-groups/[permissionGroupId]/dataset-groups/PermissionGroupDatasetGroupsController.tsx new file mode 100644 index 000000000..eb3fb6f78 --- /dev/null +++ b/web/src/app/app/settings/permission-groups/[permissionGroupId]/dataset-groups/PermissionGroupDatasetGroupsController.tsx @@ -0,0 +1,66 @@ +'use client'; + +import { useGetPermissionGroupDatasetGroups } from '@/api/buster-rest'; +import { useDebounceSearch } from '@/hooks/useDebounceSearch'; +import { + NewDatasetGroupModal, + PermissionSearchAndListWrapper +} from '@appComponents/PermissionComponents'; +import React, { useMemo, useState } from 'react'; +import { Button } from 'antd'; +import { AppMaterialIcons } from '@/components/icons'; +import { PermissionGroupDatasetGroupsListContainer } from './PermissionGroupDatasetsListContainer'; +import { useMemoizedFn } from 'ahooks'; + +export const PermissionGroupDatasetGroupsController: React.FC<{ + permissionGroupId: string; +}> = ({ permissionGroupId }) => { + const { data } = useGetPermissionGroupDatasetGroups(permissionGroupId); + const [isNewDatasetGroupModalOpen, setIsNewDatasetGroupModalOpen] = useState(false); + + const { filteredItems, handleSearchChange, searchText } = useDebounceSearch({ + items: data || [], + searchPredicate: (item, searchText) => + item.name.toLowerCase().includes(searchText.toLowerCase()) + }); + + const onCloseNewDatasetGroupModal = useMemoizedFn(() => { + setIsNewDatasetGroupModalOpen(false); + }); + + const onOpenNewDatasetGroupModal = useMemoizedFn(() => { + setIsNewDatasetGroupModalOpen(true); + }); + + const NewDatasetGroupButton: React.ReactNode = useMemo(() => { + return ( + + ); + }, []); + + return ( + <> + + + + + + + ); +}; diff --git a/web/src/app/app/settings/permission-groups/[permissionGroupId]/dataset-groups/PermissionGroupDatasetSelectedPopup.tsx b/web/src/app/app/settings/permission-groups/[permissionGroupId]/dataset-groups/PermissionGroupDatasetSelectedPopup.tsx new file mode 100644 index 000000000..cf6a60d19 --- /dev/null +++ b/web/src/app/app/settings/permission-groups/[permissionGroupId]/dataset-groups/PermissionGroupDatasetSelectedPopup.tsx @@ -0,0 +1,36 @@ +import { useUpdatePermissionGroupDatasetGroups } from '@/api/buster-rest'; +import { PermissionAssignedButton } from '@/app/app/_components/PermissionComponents'; +import { BusterListSelectedOptionPopupContainer } from '@/components/list'; +import { useMemoizedFn } from 'ahooks'; +import React from 'react'; + +export const PermissionGroupDatasetGroupSelectedPopup: React.FC<{ + selectedRowKeys: string[]; + onSelectChange: (selectedRowKeys: string[]) => void; + permissionGroupId: string; +}> = React.memo(({ selectedRowKeys, onSelectChange, permissionGroupId }) => { + const { mutateAsync: updatePermissionGroupDatasetGroups } = + useUpdatePermissionGroupDatasetGroups(permissionGroupId); + + const onSelectAssigned = useMemoizedFn(async (params: { id: string; assigned: boolean }[]) => { + await updatePermissionGroupDatasetGroups(params); + }); + + return ( + + ]} + /> + ); +}); + +PermissionGroupDatasetGroupSelectedPopup.displayName = 'PermissionGroupDatasetGroupSelectedPopup'; diff --git a/web/src/app/app/settings/permission-groups/[permissionGroupId]/dataset-groups/PermissionGroupDatasetsListContainer.tsx b/web/src/app/app/settings/permission-groups/[permissionGroupId]/dataset-groups/PermissionGroupDatasetsListContainer.tsx new file mode 100644 index 000000000..e39c90dc2 --- /dev/null +++ b/web/src/app/app/settings/permission-groups/[permissionGroupId]/dataset-groups/PermissionGroupDatasetsListContainer.tsx @@ -0,0 +1,139 @@ +import { + GetPermissionGroupDatasetGroupsResponse, + useUpdatePermissionGroupDatasetGroups +} from '@/api/buster-rest'; +import { PermissionAssignedCell } from '@appComponents/PermissionComponents'; +import { + BusterInfiniteList, + BusterListColumn, + BusterListRowItem, + EmptyStateList, + InfiniteListContainer +} from '@/components/list'; +import { BusterRoutes, createBusterRoute } from '@/routes'; +import { useMemoizedFn } from 'ahooks'; +import React, { useMemo, useState } from 'react'; +import { PermissionGroupDatasetGroupSelectedPopup } from './PermissionGroupDatasetSelectedPopup'; + +export const PermissionGroupDatasetGroupsListContainer: React.FC<{ + filteredDatasetGroups: GetPermissionGroupDatasetGroupsResponse[]; + permissionGroupId: string; +}> = React.memo(({ filteredDatasetGroups, permissionGroupId }) => { + const [selectedRowKeys, setSelectedRowKeys] = useState([]); + const { mutateAsync: updatePermissionGroupDatasetGroups } = + useUpdatePermissionGroupDatasetGroups(permissionGroupId); + + const onSelectAssigned = useMemoizedFn(async (params: { id: string; assigned: boolean }) => { + await updatePermissionGroupDatasetGroups([params]); + }); + + const columns: BusterListColumn[] = useMemo( + () => [ + { + title: 'Name', + dataIndex: 'name' + }, + { + title: 'Assigned', + dataIndex: 'assigned', + width: 130 + 85, + render: (assigned: boolean, datasetGroup: GetPermissionGroupDatasetGroupsResponse) => { + return ( +
+ +
+ ); + } + } + ], + [] + ); + + const { cannotQueryPermissionDatasetGroups, canQueryPermissionDatasetGroups } = useMemo(() => { + const result: { + cannotQueryPermissionDatasetGroups: BusterListRowItem[]; + canQueryPermissionDatasetGroups: BusterListRowItem[]; + } = filteredDatasetGroups.reduce<{ + cannotQueryPermissionDatasetGroups: BusterListRowItem[]; + canQueryPermissionDatasetGroups: BusterListRowItem[]; + }>( + (acc, datasetGroup) => { + const datasetGroupItem: BusterListRowItem = { + id: datasetGroup.id, + data: datasetGroup, + link: createBusterRoute({ + route: BusterRoutes.APP_SETTINGS_DATASET_GROUPS_ID, + datasetGroupId: datasetGroup.id + }) + }; + if (datasetGroup.assigned) { + acc.canQueryPermissionDatasetGroups.push(datasetGroupItem); + } else { + acc.cannotQueryPermissionDatasetGroups.push(datasetGroupItem); + } + return acc; + }, + { + cannotQueryPermissionDatasetGroups: [] as BusterListRowItem[], + canQueryPermissionDatasetGroups: [] as BusterListRowItem[] + } + ); + return result; + }, [filteredDatasetGroups]); + + const rows = useMemo( + () => + [ + { + id: 'header-assigned', + data: {}, + hidden: canQueryPermissionDatasetGroups.length === 0, + rowSection: { + title: 'Assigned', + secondaryTitle: canQueryPermissionDatasetGroups.length.toString() + } + }, + ...canQueryPermissionDatasetGroups, + { + id: 'header-not-assigned', + data: {}, + hidden: cannotQueryPermissionDatasetGroups.length === 0, + rowSection: { + title: 'Not Assigned', + secondaryTitle: cannotQueryPermissionDatasetGroups.length.toString() + } + }, + ...cannotQueryPermissionDatasetGroups + ].filter((row) => !(row as any).hidden), + [canQueryPermissionDatasetGroups, cannotQueryPermissionDatasetGroups] + ); + + return ( + + }> + } + /> + + ); +}); + +PermissionGroupDatasetGroupsListContainer.displayName = 'PermissionGroupDatasetGroupsListContainer'; diff --git a/web/src/app/app/settings/permission-groups/[permissionGroupId]/dataset-groups/page.tsx b/web/src/app/app/settings/permission-groups/[permissionGroupId]/dataset-groups/page.tsx index c94bbe4b8..c9b0f4b3a 100644 --- a/web/src/app/app/settings/permission-groups/[permissionGroupId]/dataset-groups/page.tsx +++ b/web/src/app/app/settings/permission-groups/[permissionGroupId]/dataset-groups/page.tsx @@ -1,3 +1,17 @@ -export default function Page() { - return
Dataset Groups
; +import { prefetchPermissionGroupDatasetGroups } from '@/api/buster-rest'; +import { HydrationBoundary, dehydrate } from '@tanstack/react-query'; +import { PermissionGroupDatasetGroupsController } from './PermissionGroupDatasetGroupsController'; + +export default async function Page({ + params: { permissionGroupId } +}: { + params: { permissionGroupId: string }; +}) { + const queryClient = await prefetchPermissionGroupDatasetGroups(permissionGroupId); + + return ( + + + + ); }