mirror of https://github.com/buster-so/buster.git
share update
This commit is contained in:
parent
80d2c88d90
commit
0be0744bd0
|
@ -8,6 +8,8 @@ import type { ShareRole } from '@buster/server-shared/share';
|
|||
export type SharePostRequest = {
|
||||
email: string;
|
||||
role: ShareRole;
|
||||
avatar_url?: string | null;
|
||||
name?: string | undefined;
|
||||
}[];
|
||||
|
||||
export type ShareDeleteRequest = string[];
|
||||
|
|
|
@ -180,17 +180,20 @@ export const useShareCollection = () => {
|
|||
if (!previousData) return previousData;
|
||||
return create(previousData, (draft: BusterCollection) => {
|
||||
draft.individual_permissions = [
|
||||
...params.map((p) => ({ ...p, avatar_url: null })),
|
||||
...params.map((p) => ({ ...p })),
|
||||
...(draft.individual_permissions || [])
|
||||
];
|
||||
});
|
||||
});
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
queryClient.setQueryData(
|
||||
collectionQueryKeys.collectionsGetCollection(data.id).queryKey,
|
||||
data
|
||||
);
|
||||
const partialMatchedKey = collectionQueryKeys
|
||||
.collectionsGetCollection(data)
|
||||
.queryKey.slice(0, -1);
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: partialMatchedKey,
|
||||
refetchType: 'all'
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -80,9 +80,7 @@ export const collectionsDeleteCollection = async (data: {
|
|||
// share collections
|
||||
|
||||
export const shareCollection = async ({ id, params }: { id: string; params: SharePostRequest }) => {
|
||||
return mainApi
|
||||
.post<BusterCollection>(`/collections/${id}/sharing`, params)
|
||||
.then((res) => res.data);
|
||||
return mainApi.post<string>(`/collections/${id}/sharing`, params).then((res) => res.data);
|
||||
};
|
||||
|
||||
export const unshareCollection = async ({ id, data }: { id: string; data: ShareDeleteRequest }) => {
|
||||
|
|
|
@ -44,6 +44,7 @@ import {
|
|||
unshareDashboard,
|
||||
updateDashboardShare
|
||||
} from './requests';
|
||||
import { userQueryKeys } from '../../query_keys/users';
|
||||
|
||||
export const useGetDashboard = <TData = BusterDashboardResponse>(
|
||||
{
|
||||
|
@ -359,19 +360,28 @@ export const useShareDashboard = () => {
|
|||
variables.id,
|
||||
latestVersionNumber
|
||||
).queryKey;
|
||||
|
||||
queryClient.setQueryData(queryKey, (previousData) => {
|
||||
if (!previousData) return previousData;
|
||||
return create(previousData, (draft) => {
|
||||
draft.individual_permissions = [
|
||||
...variables.params.map((p) => ({ ...p, avatar_url: null })),
|
||||
...variables.params.map((p) => ({
|
||||
...p,
|
||||
name: p.name,
|
||||
avatar_url: p.avatar_url || null
|
||||
})),
|
||||
...(draft.individual_permissions || [])
|
||||
];
|
||||
});
|
||||
});
|
||||
},
|
||||
onSuccess: (data, variables) => {
|
||||
const partialMatchedKey = dashboardQueryKeys
|
||||
.dashboardGetDashboard(variables.id, null)
|
||||
.queryKey.slice(0, -1);
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: dashboardQueryKeys.dashboardGetDashboard(variables.id, null).queryKey
|
||||
queryKey: partialMatchedKey,
|
||||
refetchType: 'all'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -56,7 +56,9 @@ export const listMetrics_server = async (params: Parameters<typeof listMetrics>[
|
|||
};
|
||||
|
||||
export const updateMetric = async (params: UpdateMetricRequest) => {
|
||||
return mainApi.put<UpdateMetricResponse>(`/metric_files/${params.id}`, params).then((res) => res.data);
|
||||
return mainApi
|
||||
.put<UpdateMetricResponse>(`/metric_files/${params.id}`, params)
|
||||
.then((res) => res.data);
|
||||
};
|
||||
|
||||
export const deleteMetrics = async (data: DeleteMetricRequest) => {
|
||||
|
@ -84,9 +86,7 @@ export const bulkUpdateMetricVerificationStatus = async (
|
|||
// share metrics
|
||||
|
||||
export const shareMetric = async ({ id, params }: { id: string; params: ShareMetricRequest }) => {
|
||||
return mainApi
|
||||
.post<ShareMetricResponse>(`/metric_files/${id}/sharing`, params)
|
||||
.then((res) => res.data);
|
||||
return mainApi.post<string>(`/metric_files/${id}/sharing`, params).then((res) => res.data);
|
||||
};
|
||||
|
||||
export const unshareMetric = async ({ id, data }: { id: string; data: ShareDeleteRequest }) => {
|
||||
|
@ -102,5 +102,7 @@ export const updateMetricShare = async ({
|
|||
id: string;
|
||||
params: ShareUpdateRequest;
|
||||
}) => {
|
||||
return mainApi.put<ShareUpdateResponse>(`/metric_files/${id}/sharing`, params).then((res) => res.data);
|
||||
return mainApi
|
||||
.put<ShareUpdateResponse>(`/metric_files/${id}/sharing`, params)
|
||||
.then((res) => res.data);
|
||||
};
|
||||
|
|
|
@ -22,6 +22,7 @@ import {
|
|||
updateMetric,
|
||||
updateMetricShare
|
||||
} from './requests';
|
||||
import { userQueryKeys } from '../../query_keys/users';
|
||||
|
||||
/**
|
||||
* This is a mutation that saves a metric to the server.
|
||||
|
@ -225,26 +226,29 @@ export const useShareMetric = () => {
|
|||
variables.id,
|
||||
selectedVersionNumber
|
||||
).queryKey;
|
||||
|
||||
queryClient.setQueryData(queryKey, (previousData: BusterMetric | undefined) => {
|
||||
if (!previousData) return previousData;
|
||||
return create(previousData, (draft: BusterMetric) => {
|
||||
draft.individual_permissions = [
|
||||
...variables.params.map((p) => ({ ...p, avatar_url: null })),
|
||||
...variables.params.map((p) => ({
|
||||
...p,
|
||||
name: p.name,
|
||||
avatar_url: p.avatar_url || null
|
||||
})),
|
||||
...(draft.individual_permissions || [])
|
||||
];
|
||||
});
|
||||
});
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
const oldMetric = queryClient.getQueryData(
|
||||
metricsQueryKeys.metricsGetMetric(data.id, data.version_number).queryKey
|
||||
);
|
||||
const upgradedMetric = upgradeMetricToIMetric(data, oldMetric || null);
|
||||
|
||||
queryClient.setQueryData(
|
||||
metricsQueryKeys.metricsGetMetric(data.id, data.version_number).queryKey,
|
||||
upgradedMetric
|
||||
);
|
||||
onSuccess: (data, variables) => {
|
||||
const partialMatchedKey = metricsQueryKeys
|
||||
.metricsGetMetric(variables.id, null)
|
||||
.queryKey.slice(0, -1);
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: partialMatchedKey,
|
||||
refetchType: 'all'
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -59,7 +59,7 @@ const userGetUserDatasetGroups = (userId: string) =>
|
|||
const userGetUserToOrganization = (params: GetUserToOrganizationRequest) =>
|
||||
queryOptions<GetUserToOrganizationResponse>({
|
||||
queryKey: ['users', 'organization', params] as const,
|
||||
staleTime: 10 * 1000
|
||||
staleTime: 20 * 1000
|
||||
});
|
||||
|
||||
export const userQueryKeys = {
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import React from 'react';
|
||||
import { Avatar } from '@/components/ui/avatar';
|
||||
import { Text } from '@/components/ui/typography';
|
||||
import { useMemoizedFn } from '@/hooks';
|
||||
import { AccessDropdown } from './AccessDropdown';
|
||||
import type { ShareAssetType, ShareRole } from '@buster/server-shared/share';
|
||||
|
@ -10,13 +8,11 @@ export const IndividualSharePerson: React.FC<{
|
|||
name?: string;
|
||||
email: string;
|
||||
role: ShareRole;
|
||||
avatar_url: string | null;
|
||||
avatar_url?: string | null;
|
||||
onUpdateShareRole: (email: string, role: ShareRole | null) => void;
|
||||
assetType: ShareAssetType;
|
||||
disabled: boolean;
|
||||
}> = React.memo(({ name, onUpdateShareRole, email, avatar_url, role, assetType, disabled }) => {
|
||||
const isSameEmailName = name === email;
|
||||
|
||||
const onChangeShareLevel = useMemoizedFn((v: ShareRole | null) => {
|
||||
onUpdateShareRole(email, v);
|
||||
});
|
||||
|
|
|
@ -1,25 +1,10 @@
|
|||
import React from 'react';
|
||||
import type { ShareAssetType, ShareConfig, ShareRole } from '@buster/server-shared/share';
|
||||
import { isValidEmail } from '@/lib/email';
|
||||
import {
|
||||
useShareCollection,
|
||||
useUnshareCollection,
|
||||
useUpdateCollectionShare
|
||||
} from '@/api/buster_rest/collections';
|
||||
import {
|
||||
useShareDashboard,
|
||||
useUnshareDashboard,
|
||||
useUpdateDashboardShare
|
||||
} from '@/api/buster_rest/dashboards';
|
||||
import { useShareMetric, useUnshareMetric, useUpdateMetricShare } from '@/api/buster_rest/metrics';
|
||||
import { Button } from '@/components/ui/buttons';
|
||||
import { Input } from '@/components/ui/inputs';
|
||||
import { InputSearchDropdown } from '@/components/ui/inputs/InputSearchDropdown';
|
||||
import { useBusterNotifications } from '@/context/BusterNotifications';
|
||||
import { useUnshareCollection, useUpdateCollectionShare } from '@/api/buster_rest/collections';
|
||||
import { useUnshareDashboard, useUpdateDashboardShare } from '@/api/buster_rest/dashboards';
|
||||
import { useUnshareMetric, useUpdateMetricShare } from '@/api/buster_rest/metrics';
|
||||
import { useMemoizedFn } from '@/hooks';
|
||||
import { cn } from '@/lib/classMerge';
|
||||
import { inputHasText } from '@/lib/text';
|
||||
import { AccessDropdown } from './AccessDropdown';
|
||||
import { IndividualSharePerson } from './IndividualSharePerson';
|
||||
import { ShareMenuContentEmbed } from './ShareMenuContentEmbed';
|
||||
import { ShareMenuContentPublish } from './ShareMenuContentPublish';
|
||||
|
@ -75,7 +60,6 @@ const ShareMenuContentShare: React.FC<ShareMenuContentBodyProps> = React.memo(
|
|||
const { mutateAsync: onUnshareMetric } = useUnshareMetric();
|
||||
const { mutateAsync: onUnshareDashboard } = useUnshareDashboard();
|
||||
const { mutateAsync: onUnshareCollection } = useUnshareCollection();
|
||||
const { openErrorMessage } = useBusterNotifications();
|
||||
|
||||
const hasIndividualPermissions = !!individual_permissions?.length;
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ export const ShareMenuInvite: React.FC<ShareMenuInviteProps> = React.memo(
|
|||
const [defaultPermissionLevel, setDefaultPermissionLevel] =
|
||||
React.useState<ShareRole>('canView');
|
||||
|
||||
const debouncedInputValue = useDebounce(inputValue, { wait: 350 });
|
||||
const debouncedInputValue = useDebounce(inputValue, { wait: 150 });
|
||||
const { data: usersData } = useGetUserToOrganization({
|
||||
user_name: debouncedInputValue,
|
||||
email: debouncedInputValue,
|
||||
|
@ -82,12 +82,16 @@ export const ShareMenuInvite: React.FC<ShareMenuInviteProps> = React.memo(
|
|||
return;
|
||||
}
|
||||
|
||||
const user = usersData?.data.find((user) => user.email === inputValue);
|
||||
|
||||
const payload: Parameters<typeof onShareMetric>[0] = {
|
||||
id: assetId,
|
||||
params: [
|
||||
{
|
||||
email: inputValue,
|
||||
role: defaultPermissionLevel
|
||||
role: defaultPermissionLevel,
|
||||
name: user?.name || '',
|
||||
avatar_url: user?.avatarUrl || null
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
|
@ -56,7 +56,9 @@ export const BulkUpdateMetricVerificationStatusRequestSchema = z.array(
|
|||
export const ShareMetricRequestSchema = z.array(
|
||||
z.object({
|
||||
email: z.string(),
|
||||
name: z.string().optional(),
|
||||
role: ShareRoleSchema,
|
||||
avatar_url: z.string().nullable().optional(),
|
||||
})
|
||||
);
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ export const ShareIndividualSchema = z.object({
|
|||
email: z.string(),
|
||||
role: ShareRoleSchema,
|
||||
name: z.string().optional(),
|
||||
avatar_url: z.string().nullable(),
|
||||
avatar_url: z.string().nullable().optional(),
|
||||
});
|
||||
|
||||
export const ShareConfigSchema = z.object({
|
||||
|
|
Loading…
Reference in New Issue