mirror of https://github.com/buster-so/buster.git
add permission groups lists
This commit is contained in:
parent
2171e3edad
commit
0d132576d5
|
@ -88,7 +88,7 @@ export const getPermissionGroupDatasetGroups = async ({
|
||||||
id
|
id
|
||||||
}: {
|
}: {
|
||||||
id: string;
|
id: string;
|
||||||
}): Promise<GetPermissionGroupDatasetGroupsResponse> => {
|
}): Promise<GetPermissionGroupDatasetGroupsResponse[]> => {
|
||||||
return await mainApi.get(`/permission_groups/${id}/dataset_groups`).then((res) => res.data);
|
return await mainApi.get(`/permission_groups/${id}/dataset_groups`).then((res) => res.data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -26,4 +26,5 @@ export interface GetPermissionGroupDatasetsResponse {
|
||||||
export interface GetPermissionGroupDatasetGroupsResponse {
|
export interface GetPermissionGroupDatasetGroupsResponse {
|
||||||
id: string;
|
id: string;
|
||||||
assigned: boolean;
|
assigned: boolean;
|
||||||
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 (
|
||||||
|
<Button
|
||||||
|
type="default"
|
||||||
|
icon={<AppMaterialIcons icon="add" />}
|
||||||
|
onClick={onOpenNewDatasetGroupModal}>
|
||||||
|
New dataset group
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<PermissionSearchAndListWrapper
|
||||||
|
searchText={searchText}
|
||||||
|
handleSearchChange={handleSearchChange}
|
||||||
|
searchPlaceholder="Search by dataset group name..."
|
||||||
|
searchChildren={NewDatasetGroupButton}>
|
||||||
|
<PermissionGroupDatasetGroupsListContainer
|
||||||
|
filteredDatasetGroups={filteredItems}
|
||||||
|
permissionGroupId={permissionGroupId}
|
||||||
|
/>
|
||||||
|
</PermissionSearchAndListWrapper>
|
||||||
|
|
||||||
|
<NewDatasetGroupModal
|
||||||
|
isOpen={isNewDatasetGroupModalOpen}
|
||||||
|
onClose={onCloseNewDatasetGroupModal}
|
||||||
|
datasetId={null}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
|
@ -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 (
|
||||||
|
<BusterListSelectedOptionPopupContainer
|
||||||
|
selectedRowKeys={selectedRowKeys}
|
||||||
|
onSelectChange={onSelectChange}
|
||||||
|
buttons={[
|
||||||
|
<PermissionAssignedButton
|
||||||
|
key="assign"
|
||||||
|
text="assigned"
|
||||||
|
selectedRowKeys={selectedRowKeys}
|
||||||
|
onSelectChange={onSelectChange}
|
||||||
|
onUpdate={onSelectAssigned}
|
||||||
|
/>
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
PermissionGroupDatasetGroupSelectedPopup.displayName = 'PermissionGroupDatasetGroupSelectedPopup';
|
|
@ -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<string[]>([]);
|
||||||
|
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 (
|
||||||
|
<div className="flex justify-end">
|
||||||
|
<PermissionAssignedCell
|
||||||
|
id={datasetGroup.id}
|
||||||
|
assigned={assigned}
|
||||||
|
text="assigned"
|
||||||
|
onSelect={onSelectAssigned}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
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 (
|
||||||
|
<InfiniteListContainer
|
||||||
|
popupNode={
|
||||||
|
<PermissionGroupDatasetGroupSelectedPopup
|
||||||
|
selectedRowKeys={selectedRowKeys}
|
||||||
|
onSelectChange={setSelectedRowKeys}
|
||||||
|
permissionGroupId={permissionGroupId}
|
||||||
|
/>
|
||||||
|
}>
|
||||||
|
<BusterInfiniteList
|
||||||
|
columns={columns}
|
||||||
|
rows={rows}
|
||||||
|
showHeader={false}
|
||||||
|
showSelectAll={false}
|
||||||
|
useRowClickSelectChange={false}
|
||||||
|
selectedRowKeys={selectedRowKeys}
|
||||||
|
onSelectChange={setSelectedRowKeys}
|
||||||
|
emptyState={<EmptyStateList text="No dataset groups found" />}
|
||||||
|
/>
|
||||||
|
</InfiniteListContainer>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
PermissionGroupDatasetGroupsListContainer.displayName = 'PermissionGroupDatasetGroupsListContainer';
|
|
@ -1,3 +1,17 @@
|
||||||
export default function Page() {
|
import { prefetchPermissionGroupDatasetGroups } from '@/api/buster-rest';
|
||||||
return <div>Dataset Groups</div>;
|
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 (
|
||||||
|
<HydrationBoundary state={dehydrate(queryClient)}>
|
||||||
|
<PermissionGroupDatasetGroupsController permissionGroupId={permissionGroupId} />
|
||||||
|
</HydrationBoundary>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue