From f725ef9386c2f61317cb6f9f4b221333f20ad278 Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Thu, 17 Jul 2025 10:43:08 -0600 Subject: [PATCH] add avatar urls to the share --- .../api/libs/handlers/src/chats/get_chat_handler.rs | 4 +++- apps/api/libs/handlers/src/chats/types.rs | 1 + .../src/collections/get_collection_handler.rs | 3 +++ apps/api/libs/handlers/src/collections/types.rs | 1 + .../src/dashboards/get_dashboard_handler.rs | 4 +++- apps/api/libs/handlers/src/dashboards/types.rs | 1 + .../src/metrics/get_metric_for_dashboard_handler.rs | 4 +++- .../libs/handlers/src/metrics/get_metric_handler.rs | 4 +++- apps/api/libs/handlers/src/metrics/types.rs | 1 + .../shared_interfaces/shareInterfaces.ts | 12 ------------ .../web/src/api/buster_rest/collections/requests.ts | 2 +- .../src/api/buster_rest/dashboards/queryRequests.ts | 9 +++------ apps/web/src/api/buster_rest/dashboards/requests.ts | 2 +- apps/web/src/api/buster_rest/metrics/requests.ts | 5 ++--- .../metrics/updateMetricQueryRequests.ts | 9 +++------ packages/server-shared/src/chats/chat.types.ts | 11 ++--------- .../server-shared/src/metrics/requests.types.ts | 10 ---------- packages/server-shared/src/share/index.ts | 1 + packages/server-shared/src/share/requests.ts | 13 +++++++++++++ 19 files changed, 45 insertions(+), 52 deletions(-) create mode 100644 packages/server-shared/src/share/requests.ts diff --git a/apps/api/libs/handlers/src/chats/get_chat_handler.rs b/apps/api/libs/handlers/src/chats/get_chat_handler.rs index 38d6f5435..e53b2beef 100644 --- a/apps/api/libs/handlers/src/chats/get_chat_handler.rs +++ b/apps/api/libs/handlers/src/chats/get_chat_handler.rs @@ -53,6 +53,7 @@ struct AssetPermissionInfo { role: AssetPermissionRole, email: String, name: Option, + avatar_url: Option, } pub async fn get_chat_handler( @@ -154,7 +155,7 @@ pub async fn get_chat_handler( .filter(asset_permissions::asset_type.eq(AssetType::Chat)) .filter(asset_permissions::identity_type.eq(IdentityType::User)) .filter(asset_permissions::deleted_at.is_null()) - .select((asset_permissions::role, users::email, users::name)) + .select((asset_permissions::role, users::email, users::name, users::avatar_url)) .load::(&mut conn) .await; @@ -302,6 +303,7 @@ pub async fn get_chat_handler( email: p.email, role: p.role, name: p.name, + avatar_url: p.avatar_url, }) .collect::>(), ) diff --git a/apps/api/libs/handlers/src/chats/types.rs b/apps/api/libs/handlers/src/chats/types.rs index 0e64bc5d5..2af48d536 100644 --- a/apps/api/libs/handlers/src/chats/types.rs +++ b/apps/api/libs/handlers/src/chats/types.rs @@ -12,6 +12,7 @@ pub struct BusterShareIndividual { pub email: String, pub role: AssetPermissionRole, pub name: Option, + pub avatar_url: Option, } #[derive(Debug, Serialize, Deserialize, Clone)] diff --git a/apps/api/libs/handlers/src/collections/get_collection_handler.rs b/apps/api/libs/handlers/src/collections/get_collection_handler.rs index 251b38927..4d31a0b57 100644 --- a/apps/api/libs/handlers/src/collections/get_collection_handler.rs +++ b/apps/api/libs/handlers/src/collections/get_collection_handler.rs @@ -25,6 +25,7 @@ struct AssetPermissionInfo { role: AssetPermissionRole, email: String, name: Option, + avatar_url: Option, } /// Type for querying asset data from database @@ -128,6 +129,7 @@ pub async fn get_collection_handler( asset_permissions::role, users::email, users::name, + users::avatar_url, )) .load::(&mut conn) .await; @@ -150,6 +152,7 @@ pub async fn get_collection_handler( email: p.email, role: p.role, name: p.name, + avatar_url: p.avatar_url, }) .collect::>(), ) diff --git a/apps/api/libs/handlers/src/collections/types.rs b/apps/api/libs/handlers/src/collections/types.rs index 84a18844a..5c57276fd 100644 --- a/apps/api/libs/handlers/src/collections/types.rs +++ b/apps/api/libs/handlers/src/collections/types.rs @@ -12,6 +12,7 @@ pub struct BusterShareIndividual { pub email: String, pub role: AssetPermissionRole, pub name: Option, + pub avatar_url: Option, } // List collections types diff --git a/apps/api/libs/handlers/src/dashboards/get_dashboard_handler.rs b/apps/api/libs/handlers/src/dashboards/get_dashboard_handler.rs index f91211faf..cfdf090ad 100644 --- a/apps/api/libs/handlers/src/dashboards/get_dashboard_handler.rs +++ b/apps/api/libs/handlers/src/dashboards/get_dashboard_handler.rs @@ -52,6 +52,7 @@ struct AssetPermissionInfo { role: AssetPermissionRole, email: String, name: Option, + avatar_url: Option, } /// Fetches collections that the dashboard belongs to, filtered by user permissions @@ -328,7 +329,7 @@ pub async fn get_dashboard_handler( .filter(asset_permissions::asset_type.eq(AssetType::DashboardFile)) .filter(asset_permissions::identity_type.eq(IdentityType::User)) .filter(asset_permissions::deleted_at.is_null()) - .select((asset_permissions::role, users::email, users::name)) + .select((asset_permissions::role, users::email, users::name, users::avatar_url)) .load::(&mut conn) .await; @@ -371,6 +372,7 @@ pub async fn get_dashboard_handler( email: p.email, role: p.role, name: p.name, + avatar_url: p.avatar_url, }) .collect::>(), ) diff --git a/apps/api/libs/handlers/src/dashboards/types.rs b/apps/api/libs/handlers/src/dashboards/types.rs index 2cc6be98c..9908ae959 100644 --- a/apps/api/libs/handlers/src/dashboards/types.rs +++ b/apps/api/libs/handlers/src/dashboards/types.rs @@ -31,6 +31,7 @@ pub struct BusterShareIndividual { pub email: String, pub role: AssetPermissionRole, pub name: Option, + pub avatar_url: Option, } // Note: This extends BusterShare which needs to be defined diff --git a/apps/api/libs/handlers/src/metrics/get_metric_for_dashboard_handler.rs b/apps/api/libs/handlers/src/metrics/get_metric_for_dashboard_handler.rs index abe33cb54..7907958cf 100644 --- a/apps/api/libs/handlers/src/metrics/get_metric_for_dashboard_handler.rs +++ b/apps/api/libs/handlers/src/metrics/get_metric_for_dashboard_handler.rs @@ -32,6 +32,7 @@ struct AssetPermissionInfo { role: AssetPermissionRole, email: String, name: Option, + avatar_url: Option, } /// Fetch the dashboards associated with the given metric id, filtered by user permissions @@ -348,7 +349,7 @@ pub async fn get_metric_for_dashboard_handler( .filter(asset_permissions::asset_type.eq(AssetType::MetricFile)) .filter(asset_permissions::identity_type.eq(IdentityType::User)) .filter(asset_permissions::deleted_at.is_null()) - .select((asset_permissions::role, users::email, users::name)) + .select((asset_permissions::role, users::email, users::name, users::avatar_url)) .load::(&mut conn) .await; @@ -412,6 +413,7 @@ pub async fn get_metric_for_dashboard_handler( email: p.email, role: p.role, name: p.name, + avatar_url: p.avatar_url, }) .collect::>(), ) diff --git a/apps/api/libs/handlers/src/metrics/get_metric_handler.rs b/apps/api/libs/handlers/src/metrics/get_metric_handler.rs index 41c7ca42c..cece06458 100644 --- a/apps/api/libs/handlers/src/metrics/get_metric_handler.rs +++ b/apps/api/libs/handlers/src/metrics/get_metric_handler.rs @@ -30,6 +30,7 @@ struct AssetPermissionInfo { role: AssetPermissionRole, email: String, name: Option, + avatar_url: Option, } /// Fetch the dashboards associated with the given metric id, filtered by user permissions @@ -374,7 +375,7 @@ pub async fn get_metric_handler( .filter(asset_permissions::asset_type.eq(AssetType::MetricFile)) .filter(asset_permissions::identity_type.eq(IdentityType::User)) .filter(asset_permissions::deleted_at.is_null()) - .select((asset_permissions::role, users::email, users::name)) + .select((asset_permissions::role, users::email, users::name, users::avatar_url)) .load::(&mut conn) .await; @@ -438,6 +439,7 @@ pub async fn get_metric_handler( email: p.email, role: p.role, name: p.name, + avatar_url: p.avatar_url, }) .collect::>(), ) diff --git a/apps/api/libs/handlers/src/metrics/types.rs b/apps/api/libs/handlers/src/metrics/types.rs index 7c6b2ec60..ae313c527 100644 --- a/apps/api/libs/handlers/src/metrics/types.rs +++ b/apps/api/libs/handlers/src/metrics/types.rs @@ -23,6 +23,7 @@ pub struct BusterShareIndividual { pub email: String, pub role: AssetPermissionRole, pub name: Option, + pub avatar_url: Option, } #[derive(Debug, Serialize, Deserialize, Clone)] diff --git a/apps/web/src/api/asset_interfaces/shared_interfaces/shareInterfaces.ts b/apps/web/src/api/asset_interfaces/shared_interfaces/shareInterfaces.ts index e0c2c1764..cb3b492d0 100644 --- a/apps/web/src/api/asset_interfaces/shared_interfaces/shareInterfaces.ts +++ b/apps/web/src/api/asset_interfaces/shared_interfaces/shareInterfaces.ts @@ -1,17 +1,5 @@ import type { ShareRole } from '@buster/server-shared/share'; -/** - * Type defining the sharing permissions and settings for a dashboard - * - * @interface ShareRequest - */ -export type SharePostRequest = { - email: string; - role: ShareRole; - avatar_url?: string | null; - name?: string | undefined; -}[]; - export type ShareDeleteRequest = string[]; export type ShareUpdateRequest = { diff --git a/apps/web/src/api/buster_rest/collections/requests.ts b/apps/web/src/api/buster_rest/collections/requests.ts index f727cd95c..83dcf65d0 100644 --- a/apps/web/src/api/buster_rest/collections/requests.ts +++ b/apps/web/src/api/buster_rest/collections/requests.ts @@ -2,10 +2,10 @@ import type { ShareAssetType } from '@buster/server-shared/share'; import type { BusterCollection, BusterCollectionListItem } from '@/api/asset_interfaces/collection'; import type { ShareDeleteRequest, - SharePostRequest, ShareUpdateRequest } from '@/api/asset_interfaces/shared_interfaces'; import mainApi from '@/api/buster_rest/instances'; +import { SharePostRequest } from '@buster/server-shared/share'; export const collectionsGetList = async (params: { /** Current page number (1-based indexing) */ diff --git a/apps/web/src/api/buster_rest/dashboards/queryRequests.ts b/apps/web/src/api/buster_rest/dashboards/queryRequests.ts index 0e3e1c63d..5ef411592 100644 --- a/apps/web/src/api/buster_rest/dashboards/queryRequests.ts +++ b/apps/web/src/api/buster_rest/dashboards/queryRequests.ts @@ -355,17 +355,14 @@ export const useShareDashboard = () => { const { latestVersionNumber } = useGetDashboardVersionNumber(); return useMutation({ mutationFn: shareDashboard, - onMutate: (variables) => { - const queryKey = dashboardQueryKeys.dashboardGetDashboard( - variables.id, - latestVersionNumber - ).queryKey; + onMutate: ({ id, params }) => { + const queryKey = dashboardQueryKeys.dashboardGetDashboard(id, latestVersionNumber).queryKey; queryClient.setQueryData(queryKey, (previousData) => { if (!previousData) return previousData; return create(previousData, (draft) => { draft.individual_permissions = [ - ...variables.params.map((p) => ({ + ...params.map((p) => ({ ...p, name: p.name, avatar_url: p.avatar_url || null diff --git a/apps/web/src/api/buster_rest/dashboards/requests.ts b/apps/web/src/api/buster_rest/dashboards/requests.ts index 72464fa8d..7be43330f 100644 --- a/apps/web/src/api/buster_rest/dashboards/requests.ts +++ b/apps/web/src/api/buster_rest/dashboards/requests.ts @@ -5,11 +5,11 @@ import type { } from '@/api/asset_interfaces/dashboard'; import type { ShareDeleteRequest, - SharePostRequest, ShareUpdateRequest } from '@/api/asset_interfaces/shared_interfaces'; import mainApi from '@/api/buster_rest/instances'; import { serverFetch } from '@/api/createServerInstance'; +import { SharePostRequest } from '@buster/server-shared/share'; export const dashboardsGetList = async (params: { /** The page number to fetch */ diff --git a/apps/web/src/api/buster_rest/metrics/requests.ts b/apps/web/src/api/buster_rest/metrics/requests.ts index 4f49eb11e..bbd64cc7e 100644 --- a/apps/web/src/api/buster_rest/metrics/requests.ts +++ b/apps/web/src/api/buster_rest/metrics/requests.ts @@ -9,8 +9,6 @@ import type { DuplicateMetricResponse, GetMetricDataRequest, ListMetricsResponse, - ShareMetricRequest, - ShareMetricResponse, UpdateMetricRequest, GetMetricRequest, GetMetricListRequest, @@ -22,6 +20,7 @@ import type { } from '@buster/server-shared/metrics'; import { serverFetch } from '@/api/createServerInstance'; import { mainApi } from '../instances'; +import { SharePostRequest } from '@buster/server-shared/share'; export const getMetric = async (params: GetMetricRequest): Promise => { return mainApi @@ -85,7 +84,7 @@ export const bulkUpdateMetricVerificationStatus = async ( // share metrics -export const shareMetric = async ({ id, params }: { id: string; params: ShareMetricRequest }) => { +export const shareMetric = async ({ id, params }: { id: string; params: SharePostRequest }) => { return mainApi.post(`/metric_files/${id}/sharing`, params).then((res) => res.data); }; diff --git a/apps/web/src/api/buster_rest/metrics/updateMetricQueryRequests.ts b/apps/web/src/api/buster_rest/metrics/updateMetricQueryRequests.ts index fc0893d22..7af7903df 100644 --- a/apps/web/src/api/buster_rest/metrics/updateMetricQueryRequests.ts +++ b/apps/web/src/api/buster_rest/metrics/updateMetricQueryRequests.ts @@ -221,17 +221,14 @@ export const useShareMetric = () => { const { selectedVersionNumber } = useGetMetricVersionNumber(); return useMutation({ mutationFn: shareMetric, - onMutate: (variables) => { - const queryKey = metricsQueryKeys.metricsGetMetric( - variables.id, - selectedVersionNumber - ).queryKey; + onMutate: ({ id, params }) => { + const queryKey = metricsQueryKeys.metricsGetMetric(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) => ({ + ...params.map((p) => ({ ...p, name: p.name, avatar_url: p.avatar_url || null diff --git a/packages/server-shared/src/chats/chat.types.ts b/packages/server-shared/src/chats/chat.types.ts index 05b3ac5c4..ac72c602c 100644 --- a/packages/server-shared/src/chats/chat.types.ts +++ b/packages/server-shared/src/chats/chat.types.ts @@ -1,4 +1,5 @@ import { z } from 'zod'; +import { ShareIndividualSchema } from '../share'; import { ChatMessageSchema } from './chat-message.types'; const AssetType = z.enum(['metric_file', 'dashboard_file']); @@ -6,13 +7,6 @@ const AssetType = z.enum(['metric_file', 'dashboard_file']); // Asset Permission Role enum (matching database enum) export const AssetPermissionRoleSchema = z.enum(['viewer', 'editor', 'owner']); -// Individual permission schema -export const BusterShareIndividualSchema = z.object({ - email: z.string().email(), - role: AssetPermissionRoleSchema, - name: z.string().optional(), -}); - // Main ChatWithMessages schema export const ChatWithMessagesSchema = z.object({ id: z.string(), @@ -27,7 +21,7 @@ export const ChatWithMessagesSchema = z.object({ created_by_name: z.string(), created_by_avatar: z.string().nullable(), // Sharing fields - individual_permissions: z.array(BusterShareIndividualSchema).optional(), + individual_permissions: z.array(ShareIndividualSchema).optional(), publicly_accessible: z.boolean(), public_expiry_date: z.string().datetime().optional(), public_enabled_by: z.string().optional(), @@ -67,7 +61,6 @@ export const CancelChatParamsSchema = z.object({ // Infer types from schemas export type AssetPermissionRole = z.infer; -export type BusterShareIndividual = z.infer; export type ChatWithMessages = z.infer; export type ChatCreateRequest = z.infer; export type ChatCreateHandlerRequest = z.infer; diff --git a/packages/server-shared/src/metrics/requests.types.ts b/packages/server-shared/src/metrics/requests.types.ts index ccf658bdb..e2b088006 100644 --- a/packages/server-shared/src/metrics/requests.types.ts +++ b/packages/server-shared/src/metrics/requests.types.ts @@ -53,15 +53,6 @@ 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(), - }) -); - export const ShareDeleteRequestSchema = z.array(z.string()); export const ShareUpdateRequestSchema = z.object({ @@ -87,6 +78,5 @@ export type DuplicateMetricRequest = z.infer; -export type ShareMetricRequest = z.infer; export type ShareDeleteRequest = z.infer; export type ShareUpdateRequest = z.infer; diff --git a/packages/server-shared/src/share/index.ts b/packages/server-shared/src/share/index.ts index 51be04808..6332cb85b 100644 --- a/packages/server-shared/src/share/index.ts +++ b/packages/server-shared/src/share/index.ts @@ -1,2 +1,3 @@ export * from './share-interfaces.types'; export * from './verification.types'; +export * from './requests'; diff --git a/packages/server-shared/src/share/requests.ts b/packages/server-shared/src/share/requests.ts new file mode 100644 index 000000000..76fea2f67 --- /dev/null +++ b/packages/server-shared/src/share/requests.ts @@ -0,0 +1,13 @@ +import { z } from 'zod'; +import { ShareRoleSchema } from './share-interfaces.types'; + +export const SharePostRequestSchema = z.array( + z.object({ + email: z.string().email(), + role: ShareRoleSchema, + avatar_url: z.string().nullable().optional(), + name: z.string().optional(), + }) +); + +export type SharePostRequest = z.infer;