diff --git a/web/src/api/busterv2/datasets/queryRequests.ts b/web/src/api/busterv2/datasets/queryRequests.ts index abdce7c54..b1f167757 100644 --- a/web/src/api/busterv2/datasets/queryRequests.ts +++ b/web/src/api/busterv2/datasets/queryRequests.ts @@ -77,7 +77,7 @@ export const prefetchGetDatasetMetadata = async ( export const useCreateDataset = () => { const queryClient = useQueryClient(); const mutationFn = useMemoizedFn((dataset: BusterDataset) => createDataset(dataset)); - const onSuccess = useMemoizedFn((newDataset: BusterDataset) => { + const onSuccess = useMemoizedFn((newDataset: unknown) => { queryClient.setQueryData(['datasets', {}], (oldData) => { // const newListItem: BusterDatasetListItem = { // ...newDataset, @@ -93,6 +93,7 @@ export const useCreateDataset = () => { const onError = useMemoizedFn((error: any) => { console.error('Failed to create dataset:', error); }); + return useCreateReactMutation({ mutationFn, onSuccess, diff --git a/web/src/api/busterv2/permission_groups/index.ts b/web/src/api/busterv2/permission_groups/index.ts new file mode 100644 index 000000000..d3f48297f --- /dev/null +++ b/web/src/api/busterv2/permission_groups/index.ts @@ -0,0 +1,2 @@ +export * from './requests'; +export * from './responseInterfaces'; diff --git a/web/src/api/busterv2/permission_groups/queryRequests.ts b/web/src/api/busterv2/permission_groups/queryRequests.ts new file mode 100644 index 000000000..02d5ab25b --- /dev/null +++ b/web/src/api/busterv2/permission_groups/queryRequests.ts @@ -0,0 +1,59 @@ +import { useCreateReactQuery, useCreateReactMutation } from '@/api/createReactQuery'; +import { + getPermissionGroup, + listPermissionGroups, + createPermissionGroup, + deletePermissionGroup, + updatePermissionGroup +} from './requests'; +import { useMemoizedFn } from 'ahooks'; +import { useQueryClient } from '@tanstack/react-query'; +import { useMemo } from 'react'; + +export const useListPermissionGroups = () => { + return useCreateReactQuery({ + queryKey: ['permission_groups'], + queryFn: listPermissionGroups + }); +}; + +export const useGetPermissionGroup = (permissionGroupId: string) => { + const queryFn = useMemoizedFn(() => getPermissionGroup({ id: permissionGroupId })); + return useCreateReactQuery({ + queryKey: ['permission_group', permissionGroupId], + queryFn + }); +}; + +export const useCreatePermissionGroup = (dataset_id?: string) => { + const queryClient = useQueryClient(); + return useCreateReactMutation({ + mutationFn: createPermissionGroup, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ['permission_groups'] }); + if (dataset_id) { + queryClient.invalidateQueries({ queryKey: ['list_permission_groups', dataset_id] }); + } + } + }); +}; + +export const useDeletePermissionGroup = () => { + const queryClient = useQueryClient(); + return useCreateReactMutation({ + mutationFn: deletePermissionGroup, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ['permission_groups'] }); + } + }); +}; + +export const useUpdatePermissionGroup = () => { + const queryClient = useQueryClient(); + return useCreateReactMutation({ + mutationFn: updatePermissionGroup, + onSuccess: (data, varaiables, context) => { + // queryClient.invalidateQueries({ queryKey: ['permission_groups'] }); + } + }); +}; diff --git a/web/src/api/busterv2/permission_groups/requests.ts b/web/src/api/busterv2/permission_groups/requests.ts new file mode 100644 index 000000000..fcc5c125f --- /dev/null +++ b/web/src/api/busterv2/permission_groups/requests.ts @@ -0,0 +1,32 @@ +import { mainApi } from '../../buster'; +import { GetPermissionGroupResponse } from './responseInterfaces'; + +export const listPermissionGroups = async (): Promise => { + return await mainApi.get(`/permission_groups`).then((res) => res.data); +}; + +export const getPermissionGroup = async ({ + id +}: { + id: string; +}): Promise => { + return await mainApi.get(`/permission_groups/${id}`).then((res) => res.data); +}; + +export const updatePermissionGroup = async ({ + id, + data +}: { + id: string; + data: { id: string; name: string }[]; +}): Promise => { + return await mainApi.put(`/permission_groups/${id}`, data); +}; + +export const deletePermissionGroup = async ({ id }: { id: string }): Promise => { + return await mainApi.delete(`/permission_groups/${id}`); +}; + +export const createPermissionGroup = async (data: { name: string }): Promise => { + return await mainApi.post(`/permission_groups`, data); +}; diff --git a/web/src/api/busterv2/permission_groups/responseInterfaces.ts b/web/src/api/busterv2/permission_groups/responseInterfaces.ts new file mode 100644 index 000000000..53cd0fbc8 --- /dev/null +++ b/web/src/api/busterv2/permission_groups/responseInterfaces.ts @@ -0,0 +1 @@ +export interface GetPermissionGroupResponse {} diff --git a/web/src/api/createReactQuery.ts b/web/src/api/createReactQuery.ts index 5385f5b1d..a6c9777a8 100644 --- a/web/src/api/createReactQuery.ts +++ b/web/src/api/createReactQuery.ts @@ -77,8 +77,8 @@ export const useResetReactQuery = () => { interface CreateMutationProps { mutationFn: (data: T) => Promise; - onSuccess?: (data: V) => void; - onError?: (error: Error) => void; + onSuccess?: Parameters['0']['onSuccess']; + onError?: Parameters['0']['onError']; } export const useCreateReactMutation = ({ diff --git a/web/src/app/app/datasets/[datasetId]/permissions/_PermissionPermissionGroup/NewPermissionGroupModal.tsx b/web/src/app/app/datasets/[datasetId]/permissions/_PermissionPermissionGroup/NewPermissionGroupModal.tsx new file mode 100644 index 000000000..c92e2ca6b --- /dev/null +++ b/web/src/app/app/datasets/[datasetId]/permissions/_PermissionPermissionGroup/NewPermissionGroupModal.tsx @@ -0,0 +1,70 @@ +import { useCreatePermissionGroup } from '@/api/busterv2/permission_groups/queryRequests'; +import { AppModal } from '@/components'; +import { useMemoizedFn } from 'ahooks'; +import React, { useEffect, useMemo, useRef, useState } from 'react'; +import { Input, InputRef } from 'antd'; +import { useBusterNotifications } from '@/context/BusterNotifications'; + +interface NewPermissionGroupModalProps { + isOpen: boolean; + onClose: () => void; + datasetId: string; +} + +export const NewPermissionGroupModal: React.FC = React.memo( + ({ isOpen, onClose, datasetId }) => { + const { mutateAsync, isPending } = useCreatePermissionGroup(datasetId); + const inputRef = useRef(null); + const { openInfoMessage } = useBusterNotifications(); + + const onCreateNewPermissionGroup = useMemoizedFn(async () => { + const inputValue = inputRef.current?.input?.value; + if (!inputValue) { + openInfoMessage('Please enter a name for the permission group'); + inputRef.current?.focus(); + return; + } + await mutateAsync({ + name: inputValue + }); + onClose(); + }); + + const header = useMemo(() => { + return { + title: 'New permission group', + description: 'Create a new permission group' + }; + }, []); + + const footer = useMemo(() => { + return { + secondaryButton: { + text: 'Cancel', + onClick: onClose + }, + primaryButton: { + text: 'Create permission group', + onClick: onCreateNewPermissionGroup, + loading: isPending + } + }; + }, [isPending]); + + useEffect(() => { + if (isOpen) { + setTimeout(() => { + inputRef.current?.focus(); + }, 100); + } + }, [isOpen]); + + return ( + + + + ); + } +); + +NewPermissionGroupModal.displayName = 'NewPermissionGroupModal'; diff --git a/web/src/app/app/datasets/[datasetId]/permissions/_PermissionPermissionGroup/PermissionListPermissionGroupContainer.tsx b/web/src/app/app/datasets/[datasetId]/permissions/_PermissionPermissionGroup/PermissionListPermissionGroupContainer.tsx index 7d7f7ae39..95b27d3a5 100644 --- a/web/src/app/app/datasets/[datasetId]/permissions/_PermissionPermissionGroup/PermissionListPermissionGroupContainer.tsx +++ b/web/src/app/app/datasets/[datasetId]/permissions/_PermissionPermissionGroup/PermissionListPermissionGroupContainer.tsx @@ -116,9 +116,6 @@ export const PermissionListPermissionGroupContainer: React.FC<{ showSelectAll={false} selectedRowKeys={selectedRowKeys} onSelectChange={setSelectedRowKeys} - onScrollEnd={() => { - console.log('scrolled'); - }} emptyState={
No teams found
} /> @@ -139,6 +136,7 @@ const useStyles = createStyles(({ css, token }) => ({ const PermissionGroupInfoCell = React.memo(({ name }: { name: string }) => { return
{name}
; }); +PermissionGroupInfoCell.displayName = 'PermissionGroupInfoCell'; const options = [ { diff --git a/web/src/app/app/datasets/[datasetId]/permissions/_PermissionPermissionGroup/PermissionPermissionGroup.tsx b/web/src/app/app/datasets/[datasetId]/permissions/_PermissionPermissionGroup/PermissionPermissionGroup.tsx index 1ccb5bee4..140ad58ad 100644 --- a/web/src/app/app/datasets/[datasetId]/permissions/_PermissionPermissionGroup/PermissionPermissionGroup.tsx +++ b/web/src/app/app/datasets/[datasetId]/permissions/_PermissionPermissionGroup/PermissionPermissionGroup.tsx @@ -6,12 +6,15 @@ import { Button } from 'antd'; import { AppMaterialIcons } from '@/components'; import { PermissionListPermissionGroupContainer } from './PermissionListPermissionGroupContainer'; import { ListPermissionGroupsResponse, useListPermissionGroups } from '@/api/busterv2/datasets'; +import { NewPermissionGroupModal } from './NewPermissionGroupModal'; export const PermissionPermissionGroup: React.FC<{ datasetId: string; }> = React.memo(({ datasetId }) => { const [isPending, startTransition] = useTransition(); - const { data: permissionGroups } = useListPermissionGroups(datasetId); + const { data: permissionGroups, isFetched: isPermissionGroupsFetched } = + useListPermissionGroups(datasetId); + const [isNewPermissionGroupModalOpen, setIsNewPermissionGroupModalOpen] = useState(false); const [searchText, setSearchText] = useState(''); const [filteredPermissionGroups, setFilteredPermissionGroups] = useState< ListPermissionGroupsResponse[] @@ -43,6 +46,14 @@ export const PermissionPermissionGroup: React.FC<{ debouncedSearch(text); }); + const onCloseNewPermissionGroupModal = useMemoizedFn(() => { + setIsNewPermissionGroupModalOpen(false); + }); + + const onOpenNewPermissionGroupModal = useMemoizedFn(() => { + setIsNewPermissionGroupModalOpen(true); + }); + useEffect(() => { setFilteredPermissionGroups(permissionGroups || []); }, [permissionGroups]); @@ -62,15 +73,26 @@ export const PermissionPermissionGroup: React.FC<{ placeholder="Search by permission group" /> - - + {isPermissionGroupsFetched && ( + + )} + + ); });