@burdenoff/microfe-workspaces 2026.625.4 → 2026.626.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/hooks/useMemberMutations.js +6 -6
  2. package/dist/hooks/useMemberMutations.js.map +1 -1
  3. package/dist/pages/ActivityListPage.js +94 -90
  4. package/dist/pages/ActivityListPage.js.map +1 -1
  5. package/dist/pages/CreateWorkspacePage.js +68 -63
  6. package/dist/pages/CreateWorkspacePage.js.map +1 -1
  7. package/dist/pages/InviteAcceptancePage.js +101 -96
  8. package/dist/pages/InviteAcceptancePage.js.map +1 -1
  9. package/dist/pages/MembersListPage.js +185 -184
  10. package/dist/pages/MembersListPage.js.map +1 -1
  11. package/dist/pages/PendingInvitesPage.js +70 -68
  12. package/dist/pages/PendingInvitesPage.js.map +1 -1
  13. package/dist/pages/ProjectDetailPage.js +119 -78
  14. package/dist/pages/ProjectDetailPage.js.map +1 -1
  15. package/dist/pages/ProjectMembersPage.js +105 -104
  16. package/dist/pages/ProjectMembersPage.js.map +1 -1
  17. package/dist/pages/ProjectsListPage.js +158 -157
  18. package/dist/pages/ProjectsListPage.js.map +1 -1
  19. package/dist/pages/WorkspaceDetailPage.js +236 -198
  20. package/dist/pages/WorkspaceDetailPage.js.map +1 -1
  21. package/dist/pages/WorkspaceInvitePage.js +341 -300
  22. package/dist/pages/WorkspaceInvitePage.js.map +1 -1
  23. package/dist/pages/WorkspaceSettingsPage.js +87 -85
  24. package/dist/pages/WorkspaceSettingsPage.js.map +1 -1
  25. package/dist/pages/WorkspacesListPage.js +122 -121
  26. package/dist/pages/WorkspacesListPage.js.map +1 -1
  27. package/dist/pages/dashboard/DashboardPage.js +55 -51
  28. package/dist/pages/dashboard/DashboardPage.js.map +1 -1
  29. package/dist/pages/dashboard/widgets/GroupsWidget.js +16 -17
  30. package/dist/pages/dashboard/widgets/GroupsWidget.js.map +1 -1
  31. package/dist/pages/dashboard/widgets/TagCloudWidget.js +18 -19
  32. package/dist/pages/dashboard/widgets/TagCloudWidget.js.map +1 -1
  33. package/dist/pages/dashboard/widgets/WorkflowStatsWidget.js +10 -11
  34. package/dist/pages/dashboard/widgets/WorkflowStatsWidget.js.map +1 -1
  35. package/package.json +2 -2
@@ -13,8 +13,8 @@ function v(e, t) {
13
13
  t
14
14
  ] }));
15
15
  }
16
- function y(e, t, n) {
17
- e.invalidateQueries({ queryKey: ["workspaceInvitations"] }), e.invalidateQueries({ queryKey: ["myPendingInvitations"] }), t && e.invalidateQueries({ queryKey: ["invitation", t] }), n && e.invalidateQueries({ queryKey: ["workspaceInvitations", n] });
16
+ function y(e, t, n, r = !1) {
17
+ t && r && e.setQueriesData({ queryKey: ["myPendingInvitations"] }, (e) => Array.isArray(e) ? e.filter((e) => e.id !== t) : e), e.invalidateQueries({ queryKey: ["workspaceInvitations"] }), e.invalidateQueries({ queryKey: ["myPendingInvitations"] }), t && e.invalidateQueries({ queryKey: ["invitation", t] }), n && e.invalidateQueries({ queryKey: ["workspaceInvitations", n] });
18
18
  }
19
19
  var b = () => {
20
20
  let { authToken: t, workspaceId: r } = e(), i = h(), { emit: a } = f();
@@ -191,7 +191,7 @@ var b = () => {
191
191
  return i.data.acceptInvitation;
192
192
  },
193
193
  onSuccess: (e) => {
194
- y(i, e.id, e.workspaceId), v(i, e.workspaceId), a("workspace-invitation.accepted", {
194
+ y(i, e.id, e.workspaceId, !0), v(i, e.workspaceId), a("workspace-invitation.accepted", {
195
195
  invitationId: e.id,
196
196
  workspaceId: e.workspaceId,
197
197
  source: "microfe-workspaces"
@@ -222,7 +222,7 @@ var b = () => {
222
222
  return r.data.rejectInvitation;
223
223
  },
224
224
  onSuccess: (e) => {
225
- y(r, e.id, e.workspaceId), i("workspace-invitation.rejected", {
225
+ y(r, e.id, e.workspaceId, !0), i("workspace-invitation.rejected", {
226
226
  invitationId: e.id,
227
227
  workspaceId: e.workspaceId,
228
228
  source: "microfe-workspaces"
@@ -253,7 +253,7 @@ var b = () => {
253
253
  return t.data.cancelInvitation;
254
254
  },
255
255
  onSuccess: (e) => {
256
- y(a, e.id, e.workspaceId ?? s), o("workspace-invitation.cancelled", {
256
+ y(a, e.id, e.workspaceId ?? s, !0), o("workspace-invitation.cancelled", {
257
257
  invitationId: e.id,
258
258
  workspaceId: e.workspaceId,
259
259
  source: "microfe-workspaces"
@@ -315,7 +315,7 @@ var b = () => {
315
315
  return r.data.deleteInvitation;
316
316
  },
317
317
  onSuccess: (e, t) => {
318
- y(r, t, n), i("workspace-invitation.deleted", {
318
+ y(r, t, n, !0), i("workspace-invitation.deleted", {
319
319
  invitationId: t,
320
320
  source: "microfe-workspaces"
321
321
  });
@@ -1 +1 @@
1
- {"version":3,"file":"useMemberMutations.js","names":[],"sources":["../../src/hooks/useMemberMutations.ts"],"sourcesContent":["import { useMutation, useQueryClient, type QueryClient } from '@tanstack/react-query';\nimport { print } from 'graphql';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { useWorkspacesContext } from '../providers/WorkspacesProvider';\nimport {\n AddWorkspaceMemberDocument,\n RemoveWorkspaceMemberDocument,\n RemoveUserFromWorkspaceDocument,\n CreateInvitationDocument,\n UpdateInvitationDocument,\n AcceptInvitationDocument,\n RejectInvitationDocument,\n CancelInvitationDocument,\n ResendInvitationDocument,\n DeleteInvitationDocument,\n BulkCreateInvitationsDocument,\n} from '../generated/wspace-operations';\nimport type {\n WorkspaceMember,\n WorkspaceInvitation,\n AddWorkspaceMemberInput,\n CreateInvitationInput,\n UpdateInvitationInput,\n} from '../types';\nimport { useWorkspacesEventEmitter } from './useWorkspacesEventEmitter';\nimport { safeTelemetryError } from '../utils/telemetryError';\n\nfunction invalidateMemberViews(queryClient: QueryClient, workspaceId?: string | null) {\n queryClient.invalidateQueries({ queryKey: ['workspaceMembers'] });\n queryClient.invalidateQueries({ queryKey: ['workspaceMembersInfinite'] });\n queryClient.invalidateQueries({ queryKey: ['userWorkspaces'] });\n queryClient.invalidateQueries({ queryKey: ['myWorkspaces'] });\n queryClient.invalidateQueries({ queryKey: ['dashboard', 'global'] });\n if (workspaceId) {\n queryClient.invalidateQueries({ queryKey: ['workspaceMembers', workspaceId] });\n queryClient.invalidateQueries({ queryKey: ['workspaceMembersInfinite', workspaceId] });\n queryClient.invalidateQueries({ queryKey: ['dashboard', 'workspace', workspaceId] });\n }\n}\n\nfunction invalidateInvitationViews(\n queryClient: QueryClient,\n invitationId?: string,\n workspaceId?: string | null\n) {\n queryClient.invalidateQueries({ queryKey: ['workspaceInvitations'] });\n queryClient.invalidateQueries({ queryKey: ['myPendingInvitations'] });\n if (invitationId) {\n queryClient.invalidateQueries({ queryKey: ['invitation', invitationId] });\n }\n if (workspaceId) {\n queryClient.invalidateQueries({ queryKey: ['workspaceInvitations', workspaceId] });\n }\n}\n\n/**\n * Hook to add a member to a workspace\n * Requires x-workspace-id header for workspace context\n */\nexport const useAddWorkspaceMember = () => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n const { emit } = useWorkspacesEventEmitter();\n\n return useMutation({\n mutationFn: async (input: AddWorkspaceMemberInput): Promise<WorkspaceMember> => {\n const result = await graphqlFetch<{ addWorkspaceMember: WorkspaceMember }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(AddWorkspaceMemberDocument),\n variables: { input },\n workspaceId: workspaceId || undefined,\n workspaceToken: true, // Auto-read from profile context for x-workspace-id header\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.addWorkspaceMember;\n },\n onSuccess: (data) => {\n invalidateMemberViews(queryClient, data.workspaceId);\n emit('workspace-member.added', {\n memberId: data.id,\n workspaceId: data.workspaceId,\n userId: data.userId,\n source: 'microfe-workspaces',\n });\n },\n onError: (err, input) => {\n emit('workspace-member.add_failed', {\n workspaceId: workspaceId || undefined,\n userId: input?.userId,\n source: 'microfe-workspaces',\n errorMessage: safeTelemetryError(err),\n });\n },\n });\n};\n\n/**\n * Hook to remove a member from a workspace by member ID\n */\nexport const useRemoveWorkspaceMember = (workspaceIdOverride?: string) => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n const { emit } = useWorkspacesEventEmitter();\n const effectiveWorkspaceId = workspaceIdOverride || workspaceId;\n\n return useMutation({\n mutationFn: async (id: string): Promise<boolean> => {\n const result = await graphqlFetch<{ removeWorkspaceMember: boolean }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(RemoveWorkspaceMemberDocument),\n variables: { id },\n workspaceId: effectiveWorkspaceId || undefined,\n workspaceToken: true, // Required by gateway RBAC for wspace-scoped operations\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.removeWorkspaceMember;\n },\n onSuccess: (_, id) => {\n invalidateMemberViews(queryClient, effectiveWorkspaceId);\n emit('workspace-member.removed', { memberId: id, source: 'microfe-workspaces' });\n },\n onError: (err, id) => {\n emit('workspace-member.remove_failed', {\n memberId: id,\n workspaceId: effectiveWorkspaceId || undefined,\n source: 'microfe-workspaces',\n errorMessage: safeTelemetryError(err),\n });\n },\n });\n};\n\n/**\n * Hook to remove a user from a workspace\n * Requires x-workspace-id header for workspace context\n */\nexport const useRemoveUserFromWorkspace = (workspaceIdOverride?: string) => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n const { emit } = useWorkspacesEventEmitter();\n const effectiveWorkspaceId = workspaceIdOverride || workspaceId;\n\n return useMutation({\n mutationFn: async (userId: string): Promise<boolean> => {\n const result = await graphqlFetch<{ removeUserFromWorkspace: boolean }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(RemoveUserFromWorkspaceDocument),\n variables: { userId },\n workspaceId: effectiveWorkspaceId || undefined,\n workspaceToken: true, // Auto-read from profile context for x-workspace-id header\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.removeUserFromWorkspace;\n },\n onSuccess: (_, userId) => {\n invalidateMemberViews(queryClient, effectiveWorkspaceId);\n queryClient.invalidateQueries({ queryKey: ['userWorkspaces', userId] });\n emit('workspace-member.removed', { userId, source: 'microfe-workspaces' });\n },\n onError: (err, userId) => {\n emit('workspace-member.remove_failed', {\n userId,\n workspaceId: effectiveWorkspaceId || undefined,\n source: 'microfe-workspaces',\n errorMessage: safeTelemetryError(err),\n });\n },\n });\n};\n\n/**\n * NOTE: The updateWorkspaceMemberRoles mutation has been removed from the backend.\n * Role management is now handled via invitations - when creating an invitation,\n * you can specify roleIds that will be assigned when the invitation is accepted.\n *\n * Use CreateInvitationInput.roleIds to assign roles to new members.\n */\n\n/**\n * Hook to create a workspace invitation\n * Uses x-workspace-id header as fallback when input.workspaceId is not provided\n */\nexport const useCreateInvitation = (workspaceIdOverride?: string) => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n const { emit } = useWorkspacesEventEmitter();\n const effectiveWorkspaceId = workspaceIdOverride || workspaceId;\n\n return useMutation({\n mutationFn: async (input: CreateInvitationInput): Promise<WorkspaceInvitation> => {\n const result = await graphqlFetch<{ createInvitation: WorkspaceInvitation }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(CreateInvitationDocument),\n variables: { input },\n workspaceId: input.workspaceId || effectiveWorkspaceId || undefined,\n workspaceToken: true, // Auto-read from profile context for x-workspace-id header fallback\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.createInvitation;\n },\n onSuccess: (data) => {\n const wsId = data.workspaceId ?? effectiveWorkspaceId;\n invalidateInvitationViews(queryClient, data.id, wsId);\n emit('workspace-invitation.created', {\n invitationId: data.id,\n workspaceId: data.workspaceId,\n email: data.email,\n source: 'microfe-workspaces',\n });\n },\n onError: (err, input) => {\n emit('workspace-invitation.create_failed', {\n workspaceId: input?.workspaceId || effectiveWorkspaceId || undefined,\n email: input?.email,\n source: 'microfe-workspaces',\n errorMessage: safeTelemetryError(err),\n });\n },\n });\n};\n\n/**\n * Hook to update an invitation\n */\nexport const useUpdateInvitation = () => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n const { emit } = useWorkspacesEventEmitter();\n\n return useMutation({\n mutationFn: async ({\n id,\n input,\n }: {\n id: string;\n input: UpdateInvitationInput;\n }): Promise<WorkspaceInvitation> => {\n const result = await graphqlFetch<{ updateInvitation: WorkspaceInvitation }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(UpdateInvitationDocument),\n variables: { id, input },\n workspaceId: workspaceId || undefined,\n workspaceToken: true, // Required by gateway RBAC for wspace-scoped operations\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.updateInvitation;\n },\n onSuccess: (data) => {\n invalidateInvitationViews(queryClient, data.id, data.workspaceId);\n emit('workspace-invitation.updated', {\n invitationId: data.id,\n workspaceId: data.workspaceId,\n source: 'microfe-workspaces',\n });\n },\n onError: (err, variables) => {\n emit('workspace-invitation.update_failed', {\n invitationId: variables?.id,\n workspaceId: workspaceId || undefined,\n source: 'microfe-workspaces',\n errorMessage: safeTelemetryError(err),\n });\n },\n });\n};\n\n/**\n * Hook to accept an invitation\n */\nexport const useAcceptInvitation = () => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n const { emit } = useWorkspacesEventEmitter();\n\n return useMutation({\n mutationFn: async (id: string): Promise<WorkspaceInvitation> => {\n const result = await graphqlFetch<{ acceptInvitation: WorkspaceInvitation }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(AcceptInvitationDocument),\n variables: { id },\n workspaceId: workspaceId || undefined,\n workspaceToken: true, // Required by gateway RBAC for wspace-scoped operations\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.acceptInvitation;\n },\n onSuccess: (data) => {\n invalidateInvitationViews(queryClient, data.id, data.workspaceId);\n invalidateMemberViews(queryClient, data.workspaceId);\n emit('workspace-invitation.accepted', {\n invitationId: data.id,\n workspaceId: data.workspaceId,\n source: 'microfe-workspaces',\n });\n },\n onError: (err, id) => {\n emit('workspace-invitation.accept_failed', {\n invitationId: id,\n workspaceId: workspaceId || undefined,\n source: 'microfe-workspaces',\n errorMessage: safeTelemetryError(err),\n });\n },\n });\n};\n\n/**\n * Hook to reject an invitation\n */\nexport const useRejectInvitation = () => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n const { emit } = useWorkspacesEventEmitter();\n\n return useMutation({\n mutationFn: async (id: string): Promise<WorkspaceInvitation> => {\n const result = await graphqlFetch<{ rejectInvitation: WorkspaceInvitation }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(RejectInvitationDocument),\n variables: { id },\n workspaceId: workspaceId || undefined,\n workspaceToken: true, // Required by gateway RBAC for wspace-scoped operations\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.rejectInvitation;\n },\n onSuccess: (data) => {\n invalidateInvitationViews(queryClient, data.id, data.workspaceId);\n emit('workspace-invitation.rejected', {\n invitationId: data.id,\n workspaceId: data.workspaceId,\n source: 'microfe-workspaces',\n });\n },\n onError: (err, id) => {\n emit('workspace-invitation.reject_failed', {\n invitationId: id,\n workspaceId: workspaceId || undefined,\n source: 'microfe-workspaces',\n errorMessage: safeTelemetryError(err),\n });\n },\n });\n};\n\n/**\n * Hook to cancel an invitation\n */\nexport const useCancelInvitation = (workspaceIdOverride?: string) => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n const { emit } = useWorkspacesEventEmitter();\n const effectiveWorkspaceId = workspaceIdOverride || workspaceId;\n\n return useMutation({\n mutationFn: async (id: string): Promise<WorkspaceInvitation> => {\n const result = await graphqlFetch<{ cancelInvitation: WorkspaceInvitation }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(CancelInvitationDocument),\n variables: { id },\n workspaceId: effectiveWorkspaceId || undefined,\n workspaceToken: true, // Required by gateway RBAC for wspace-scoped operations\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.cancelInvitation;\n },\n onSuccess: (data) => {\n invalidateInvitationViews(queryClient, data.id, data.workspaceId ?? effectiveWorkspaceId);\n emit('workspace-invitation.cancelled', {\n invitationId: data.id,\n workspaceId: data.workspaceId,\n source: 'microfe-workspaces',\n });\n },\n onError: (err, id) => {\n emit('workspace-invitation.cancel_failed', {\n invitationId: id,\n workspaceId: effectiveWorkspaceId || undefined,\n source: 'microfe-workspaces',\n errorMessage: safeTelemetryError(err),\n });\n },\n });\n};\n\n/**\n * Hook to resend an invitation\n */\nexport const useResendInvitation = (workspaceIdOverride?: string) => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n const { emit } = useWorkspacesEventEmitter();\n const effectiveWorkspaceId = workspaceIdOverride || workspaceId;\n\n return useMutation({\n mutationFn: async (id: string): Promise<WorkspaceInvitation> => {\n const result = await graphqlFetch<{ resendInvitation: WorkspaceInvitation }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(ResendInvitationDocument),\n variables: { id },\n workspaceId: effectiveWorkspaceId || undefined,\n workspaceToken: true, // Required by gateway RBAC for wspace-scoped operations\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.resendInvitation;\n },\n onSuccess: (data) => {\n invalidateInvitationViews(queryClient, data.id, data.workspaceId ?? effectiveWorkspaceId);\n emit('workspace-invitation.resent', {\n invitationId: data.id,\n workspaceId: data.workspaceId,\n source: 'microfe-workspaces',\n });\n },\n onError: (err, id) => {\n emit('workspace-invitation.resend_failed', {\n invitationId: id,\n workspaceId: effectiveWorkspaceId || undefined,\n source: 'microfe-workspaces',\n errorMessage: safeTelemetryError(err),\n });\n },\n });\n};\n\n/**\n * Hook to delete an invitation\n */\nexport const useDeleteInvitation = () => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n const { emit } = useWorkspacesEventEmitter();\n\n return useMutation({\n mutationFn: async (id: string): Promise<boolean> => {\n const result = await graphqlFetch<{ deleteInvitation: boolean }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(DeleteInvitationDocument),\n variables: { id },\n workspaceId: workspaceId || undefined,\n workspaceToken: true, // Required by gateway RBAC for wspace-scoped operations\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.deleteInvitation;\n },\n onSuccess: (_, id) => {\n invalidateInvitationViews(queryClient, id, workspaceId);\n emit('workspace-invitation.deleted', { invitationId: id, source: 'microfe-workspaces' });\n },\n onError: (err, id) => {\n emit('workspace-invitation.delete_failed', {\n invitationId: id,\n workspaceId: workspaceId || undefined,\n source: 'microfe-workspaces',\n errorMessage: safeTelemetryError(err),\n });\n },\n });\n};\n\n/**\n * Hook to bulk create invitations\n * Uses x-workspace-id header as fallback when inputs[].workspaceId is not provided\n */\nexport const useBulkCreateInvitations = () => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async (inputs: CreateInvitationInput[]): Promise<WorkspaceInvitation[]> => {\n const result = await graphqlFetch<{ bulkCreateInvitations: WorkspaceInvitation[] }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(BulkCreateInvitationsDocument),\n variables: { inputs },\n workspaceId: inputs[0]?.workspaceId || workspaceId || undefined,\n workspaceToken: true, // Auto-read from profile context for x-workspace-id header fallback\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.bulkCreateInvitations;\n },\n onSuccess: (invitations) => {\n queryClient.invalidateQueries({ queryKey: ['workspaceInvitations'] });\n queryClient.invalidateQueries({ queryKey: ['myPendingInvitations'] });\n const workspaceIds = new Set(\n invitations.map((invitation) => invitation.workspaceId).filter(Boolean)\n );\n for (const wsId of workspaceIds) {\n queryClient.invalidateQueries({ queryKey: ['workspaceInvitations', wsId] });\n }\n },\n });\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"useMemberMutations.js","names":[],"sources":["../../src/hooks/useMemberMutations.ts"],"sourcesContent":["import { useMutation, useQueryClient, type QueryClient } from '@tanstack/react-query';\nimport { print } from 'graphql';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { useWorkspacesContext } from '../providers/WorkspacesProvider';\nimport {\n AddWorkspaceMemberDocument,\n RemoveWorkspaceMemberDocument,\n RemoveUserFromWorkspaceDocument,\n CreateInvitationDocument,\n UpdateInvitationDocument,\n AcceptInvitationDocument,\n RejectInvitationDocument,\n CancelInvitationDocument,\n ResendInvitationDocument,\n DeleteInvitationDocument,\n BulkCreateInvitationsDocument,\n} from '../generated/wspace-operations';\nimport type {\n WorkspaceMember,\n WorkspaceInvitation,\n AddWorkspaceMemberInput,\n CreateInvitationInput,\n UpdateInvitationInput,\n} from '../types';\nimport { useWorkspacesEventEmitter } from './useWorkspacesEventEmitter';\nimport { safeTelemetryError } from '../utils/telemetryError';\n\nfunction invalidateMemberViews(queryClient: QueryClient, workspaceId?: string | null) {\n queryClient.invalidateQueries({ queryKey: ['workspaceMembers'] });\n queryClient.invalidateQueries({ queryKey: ['workspaceMembersInfinite'] });\n queryClient.invalidateQueries({ queryKey: ['userWorkspaces'] });\n queryClient.invalidateQueries({ queryKey: ['myWorkspaces'] });\n queryClient.invalidateQueries({ queryKey: ['dashboard', 'global'] });\n if (workspaceId) {\n queryClient.invalidateQueries({ queryKey: ['workspaceMembers', workspaceId] });\n queryClient.invalidateQueries({ queryKey: ['workspaceMembersInfinite', workspaceId] });\n queryClient.invalidateQueries({ queryKey: ['dashboard', 'workspace', workspaceId] });\n }\n}\n\nfunction invalidateInvitationViews(\n queryClient: QueryClient,\n invitationId?: string,\n workspaceId?: string | null,\n // Only TERMINAL actions (accept / reject / cancel / delete) leave the invite\n // no longer pending and should evict it from the recipient's My Invites list.\n // Non-terminal actions (create / update / resend) keep it PENDING and must NOT\n // remove it — otherwise resending/updating a still-pending invite would make\n // it vanish from the recipient's list until a full reload.\n evictFromPending = false\n) {\n // Optimistically drop the invitation from the recipient's pending list so the\n // card disappears immediately after a terminal action. Invalidation alone has\n // proven unreliable at triggering a refetch of `myPendingInvitations` here —\n // the accepted invite stays on screen with no feedback, which leads users to\n // re-click Accept and hit \"Invitation is already accepted\". The cache write\n // is the source of the visible update; the invalidations below still run for\n // eventual consistency. Matches all `['myPendingInvitations', <email>]` keys.\n if (invitationId && evictFromPending) {\n queryClient.setQueriesData<WorkspaceInvitation[] | undefined>(\n { queryKey: ['myPendingInvitations'] },\n (old) => (Array.isArray(old) ? old.filter((invite) => invite.id !== invitationId) : old)\n );\n }\n queryClient.invalidateQueries({ queryKey: ['workspaceInvitations'] });\n queryClient.invalidateQueries({ queryKey: ['myPendingInvitations'] });\n if (invitationId) {\n queryClient.invalidateQueries({ queryKey: ['invitation', invitationId] });\n }\n if (workspaceId) {\n queryClient.invalidateQueries({ queryKey: ['workspaceInvitations', workspaceId] });\n }\n}\n\n/**\n * Hook to add a member to a workspace\n * Requires x-workspace-id header for workspace context\n */\nexport const useAddWorkspaceMember = () => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n const { emit } = useWorkspacesEventEmitter();\n\n return useMutation({\n mutationFn: async (input: AddWorkspaceMemberInput): Promise<WorkspaceMember> => {\n const result = await graphqlFetch<{ addWorkspaceMember: WorkspaceMember }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(AddWorkspaceMemberDocument),\n variables: { input },\n workspaceId: workspaceId || undefined,\n workspaceToken: true, // Auto-read from profile context for x-workspace-id header\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.addWorkspaceMember;\n },\n onSuccess: (data) => {\n invalidateMemberViews(queryClient, data.workspaceId);\n emit('workspace-member.added', {\n memberId: data.id,\n workspaceId: data.workspaceId,\n userId: data.userId,\n source: 'microfe-workspaces',\n });\n },\n onError: (err, input) => {\n emit('workspace-member.add_failed', {\n workspaceId: workspaceId || undefined,\n userId: input?.userId,\n source: 'microfe-workspaces',\n errorMessage: safeTelemetryError(err),\n });\n },\n });\n};\n\n/**\n * Hook to remove a member from a workspace by member ID\n */\nexport const useRemoveWorkspaceMember = (workspaceIdOverride?: string) => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n const { emit } = useWorkspacesEventEmitter();\n const effectiveWorkspaceId = workspaceIdOverride || workspaceId;\n\n return useMutation({\n mutationFn: async (id: string): Promise<boolean> => {\n const result = await graphqlFetch<{ removeWorkspaceMember: boolean }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(RemoveWorkspaceMemberDocument),\n variables: { id },\n workspaceId: effectiveWorkspaceId || undefined,\n workspaceToken: true, // Required by gateway RBAC for wspace-scoped operations\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.removeWorkspaceMember;\n },\n onSuccess: (_, id) => {\n invalidateMemberViews(queryClient, effectiveWorkspaceId);\n emit('workspace-member.removed', { memberId: id, source: 'microfe-workspaces' });\n },\n onError: (err, id) => {\n emit('workspace-member.remove_failed', {\n memberId: id,\n workspaceId: effectiveWorkspaceId || undefined,\n source: 'microfe-workspaces',\n errorMessage: safeTelemetryError(err),\n });\n },\n });\n};\n\n/**\n * Hook to remove a user from a workspace\n * Requires x-workspace-id header for workspace context\n */\nexport const useRemoveUserFromWorkspace = (workspaceIdOverride?: string) => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n const { emit } = useWorkspacesEventEmitter();\n const effectiveWorkspaceId = workspaceIdOverride || workspaceId;\n\n return useMutation({\n mutationFn: async (userId: string): Promise<boolean> => {\n const result = await graphqlFetch<{ removeUserFromWorkspace: boolean }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(RemoveUserFromWorkspaceDocument),\n variables: { userId },\n workspaceId: effectiveWorkspaceId || undefined,\n workspaceToken: true, // Auto-read from profile context for x-workspace-id header\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.removeUserFromWorkspace;\n },\n onSuccess: (_, userId) => {\n invalidateMemberViews(queryClient, effectiveWorkspaceId);\n queryClient.invalidateQueries({ queryKey: ['userWorkspaces', userId] });\n emit('workspace-member.removed', { userId, source: 'microfe-workspaces' });\n },\n onError: (err, userId) => {\n emit('workspace-member.remove_failed', {\n userId,\n workspaceId: effectiveWorkspaceId || undefined,\n source: 'microfe-workspaces',\n errorMessage: safeTelemetryError(err),\n });\n },\n });\n};\n\n/**\n * NOTE: The updateWorkspaceMemberRoles mutation has been removed from the backend.\n * Role management is now handled via invitations - when creating an invitation,\n * you can specify roleIds that will be assigned when the invitation is accepted.\n *\n * Use CreateInvitationInput.roleIds to assign roles to new members.\n */\n\n/**\n * Hook to create a workspace invitation\n * Uses x-workspace-id header as fallback when input.workspaceId is not provided\n */\nexport const useCreateInvitation = (workspaceIdOverride?: string) => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n const { emit } = useWorkspacesEventEmitter();\n const effectiveWorkspaceId = workspaceIdOverride || workspaceId;\n\n return useMutation({\n mutationFn: async (input: CreateInvitationInput): Promise<WorkspaceInvitation> => {\n const result = await graphqlFetch<{ createInvitation: WorkspaceInvitation }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(CreateInvitationDocument),\n variables: { input },\n workspaceId: input.workspaceId || effectiveWorkspaceId || undefined,\n workspaceToken: true, // Auto-read from profile context for x-workspace-id header fallback\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.createInvitation;\n },\n onSuccess: (data) => {\n const wsId = data.workspaceId ?? effectiveWorkspaceId;\n invalidateInvitationViews(queryClient, data.id, wsId);\n emit('workspace-invitation.created', {\n invitationId: data.id,\n workspaceId: data.workspaceId,\n email: data.email,\n source: 'microfe-workspaces',\n });\n },\n onError: (err, input) => {\n emit('workspace-invitation.create_failed', {\n workspaceId: input?.workspaceId || effectiveWorkspaceId || undefined,\n email: input?.email,\n source: 'microfe-workspaces',\n errorMessage: safeTelemetryError(err),\n });\n },\n });\n};\n\n/**\n * Hook to update an invitation\n */\nexport const useUpdateInvitation = () => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n const { emit } = useWorkspacesEventEmitter();\n\n return useMutation({\n mutationFn: async ({\n id,\n input,\n }: {\n id: string;\n input: UpdateInvitationInput;\n }): Promise<WorkspaceInvitation> => {\n const result = await graphqlFetch<{ updateInvitation: WorkspaceInvitation }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(UpdateInvitationDocument),\n variables: { id, input },\n workspaceId: workspaceId || undefined,\n workspaceToken: true, // Required by gateway RBAC for wspace-scoped operations\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.updateInvitation;\n },\n onSuccess: (data) => {\n invalidateInvitationViews(queryClient, data.id, data.workspaceId);\n emit('workspace-invitation.updated', {\n invitationId: data.id,\n workspaceId: data.workspaceId,\n source: 'microfe-workspaces',\n });\n },\n onError: (err, variables) => {\n emit('workspace-invitation.update_failed', {\n invitationId: variables?.id,\n workspaceId: workspaceId || undefined,\n source: 'microfe-workspaces',\n errorMessage: safeTelemetryError(err),\n });\n },\n });\n};\n\n/**\n * Hook to accept an invitation\n */\nexport const useAcceptInvitation = () => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n const { emit } = useWorkspacesEventEmitter();\n\n return useMutation({\n mutationFn: async (id: string): Promise<WorkspaceInvitation> => {\n const result = await graphqlFetch<{ acceptInvitation: WorkspaceInvitation }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(AcceptInvitationDocument),\n variables: { id },\n workspaceId: workspaceId || undefined,\n workspaceToken: true, // Required by gateway RBAC for wspace-scoped operations\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.acceptInvitation;\n },\n onSuccess: (data) => {\n // Terminal: the invite is now accepted — evict it from My Invites.\n invalidateInvitationViews(queryClient, data.id, data.workspaceId, true);\n invalidateMemberViews(queryClient, data.workspaceId);\n emit('workspace-invitation.accepted', {\n invitationId: data.id,\n workspaceId: data.workspaceId,\n source: 'microfe-workspaces',\n });\n },\n onError: (err, id) => {\n emit('workspace-invitation.accept_failed', {\n invitationId: id,\n workspaceId: workspaceId || undefined,\n source: 'microfe-workspaces',\n errorMessage: safeTelemetryError(err),\n });\n },\n });\n};\n\n/**\n * Hook to reject an invitation\n */\nexport const useRejectInvitation = () => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n const { emit } = useWorkspacesEventEmitter();\n\n return useMutation({\n mutationFn: async (id: string): Promise<WorkspaceInvitation> => {\n const result = await graphqlFetch<{ rejectInvitation: WorkspaceInvitation }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(RejectInvitationDocument),\n variables: { id },\n workspaceId: workspaceId || undefined,\n workspaceToken: true, // Required by gateway RBAC for wspace-scoped operations\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.rejectInvitation;\n },\n onSuccess: (data) => {\n // Terminal: the invite is now rejected — evict it from My Invites.\n invalidateInvitationViews(queryClient, data.id, data.workspaceId, true);\n emit('workspace-invitation.rejected', {\n invitationId: data.id,\n workspaceId: data.workspaceId,\n source: 'microfe-workspaces',\n });\n },\n onError: (err, id) => {\n emit('workspace-invitation.reject_failed', {\n invitationId: id,\n workspaceId: workspaceId || undefined,\n source: 'microfe-workspaces',\n errorMessage: safeTelemetryError(err),\n });\n },\n });\n};\n\n/**\n * Hook to cancel an invitation\n */\nexport const useCancelInvitation = (workspaceIdOverride?: string) => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n const { emit } = useWorkspacesEventEmitter();\n const effectiveWorkspaceId = workspaceIdOverride || workspaceId;\n\n return useMutation({\n mutationFn: async (id: string): Promise<WorkspaceInvitation> => {\n const result = await graphqlFetch<{ cancelInvitation: WorkspaceInvitation }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(CancelInvitationDocument),\n variables: { id },\n workspaceId: effectiveWorkspaceId || undefined,\n workspaceToken: true, // Required by gateway RBAC for wspace-scoped operations\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.cancelInvitation;\n },\n onSuccess: (data) => {\n // Terminal: the invite is cancelled — evict it from My Invites.\n invalidateInvitationViews(\n queryClient,\n data.id,\n data.workspaceId ?? effectiveWorkspaceId,\n true\n );\n emit('workspace-invitation.cancelled', {\n invitationId: data.id,\n workspaceId: data.workspaceId,\n source: 'microfe-workspaces',\n });\n },\n onError: (err, id) => {\n emit('workspace-invitation.cancel_failed', {\n invitationId: id,\n workspaceId: effectiveWorkspaceId || undefined,\n source: 'microfe-workspaces',\n errorMessage: safeTelemetryError(err),\n });\n },\n });\n};\n\n/**\n * Hook to resend an invitation\n */\nexport const useResendInvitation = (workspaceIdOverride?: string) => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n const { emit } = useWorkspacesEventEmitter();\n const effectiveWorkspaceId = workspaceIdOverride || workspaceId;\n\n return useMutation({\n mutationFn: async (id: string): Promise<WorkspaceInvitation> => {\n const result = await graphqlFetch<{ resendInvitation: WorkspaceInvitation }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(ResendInvitationDocument),\n variables: { id },\n workspaceId: effectiveWorkspaceId || undefined,\n workspaceToken: true, // Required by gateway RBAC for wspace-scoped operations\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.resendInvitation;\n },\n onSuccess: (data) => {\n invalidateInvitationViews(queryClient, data.id, data.workspaceId ?? effectiveWorkspaceId);\n emit('workspace-invitation.resent', {\n invitationId: data.id,\n workspaceId: data.workspaceId,\n source: 'microfe-workspaces',\n });\n },\n onError: (err, id) => {\n emit('workspace-invitation.resend_failed', {\n invitationId: id,\n workspaceId: effectiveWorkspaceId || undefined,\n source: 'microfe-workspaces',\n errorMessage: safeTelemetryError(err),\n });\n },\n });\n};\n\n/**\n * Hook to delete an invitation\n */\nexport const useDeleteInvitation = () => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n const { emit } = useWorkspacesEventEmitter();\n\n return useMutation({\n mutationFn: async (id: string): Promise<boolean> => {\n const result = await graphqlFetch<{ deleteInvitation: boolean }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(DeleteInvitationDocument),\n variables: { id },\n workspaceId: workspaceId || undefined,\n workspaceToken: true, // Required by gateway RBAC for wspace-scoped operations\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.deleteInvitation;\n },\n onSuccess: (_, id) => {\n // Terminal: the invite is deleted — evict it from My Invites.\n invalidateInvitationViews(queryClient, id, workspaceId, true);\n emit('workspace-invitation.deleted', { invitationId: id, source: 'microfe-workspaces' });\n },\n onError: (err, id) => {\n emit('workspace-invitation.delete_failed', {\n invitationId: id,\n workspaceId: workspaceId || undefined,\n source: 'microfe-workspaces',\n errorMessage: safeTelemetryError(err),\n });\n },\n });\n};\n\n/**\n * Hook to bulk create invitations\n * Uses x-workspace-id header as fallback when inputs[].workspaceId is not provided\n */\nexport const useBulkCreateInvitations = () => {\n const { authToken, workspaceId } = useWorkspacesContext();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async (inputs: CreateInvitationInput[]): Promise<WorkspaceInvitation[]> => {\n const result = await graphqlFetch<{ bulkCreateInvitations: WorkspaceInvitation[] }>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: print(BulkCreateInvitationsDocument),\n variables: { inputs },\n workspaceId: inputs[0]?.workspaceId || workspaceId || undefined,\n workspaceToken: true, // Auto-read from profile context for x-workspace-id header fallback\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'GraphQL error');\n }\n\n return result.data!.bulkCreateInvitations;\n },\n onSuccess: (invitations) => {\n queryClient.invalidateQueries({ queryKey: ['workspaceInvitations'] });\n queryClient.invalidateQueries({ queryKey: ['myPendingInvitations'] });\n const workspaceIds = new Set(\n invitations.map((invitation) => invitation.workspaceId).filter(Boolean)\n );\n for (const wsId of workspaceIds) {\n queryClient.invalidateQueries({ queryKey: ['workspaceInvitations', wsId] });\n }\n },\n });\n};\n"],"mappings":";;;;;;;;AA2BA,SAAS,EAAsB,GAA0B,GAA6B;AAMpF,CALA,EAAY,kBAAkB,EAAE,UAAU,CAAC,mBAAmB,EAAE,CAAC,EACjE,EAAY,kBAAkB,EAAE,UAAU,CAAC,2BAA2B,EAAE,CAAC,EACzE,EAAY,kBAAkB,EAAE,UAAU,CAAC,iBAAiB,EAAE,CAAC,EAC/D,EAAY,kBAAkB,EAAE,UAAU,CAAC,eAAe,EAAE,CAAC,EAC7D,EAAY,kBAAkB,EAAE,UAAU,CAAC,aAAa,SAAS,EAAE,CAAC,EAChE,MACF,EAAY,kBAAkB,EAAE,UAAU,CAAC,oBAAoB,EAAY,EAAE,CAAC,EAC9E,EAAY,kBAAkB,EAAE,UAAU,CAAC,4BAA4B,EAAY,EAAE,CAAC,EACtF,EAAY,kBAAkB,EAAE,UAAU;EAAC;EAAa;EAAa;EAAY,EAAE,CAAC;;AAIxF,SAAS,EACP,GACA,GACA,GAMA,IAAmB,IACnB;AAmBA,CAXI,KAAgB,KAClB,EAAY,eACV,EAAE,UAAU,CAAC,uBAAuB,EAAE,GACrC,MAAS,MAAM,QAAQ,EAAI,GAAG,EAAI,QAAQ,MAAW,EAAO,OAAO,EAAa,GAAG,EACrF,EAEH,EAAY,kBAAkB,EAAE,UAAU,CAAC,uBAAuB,EAAE,CAAC,EACrE,EAAY,kBAAkB,EAAE,UAAU,CAAC,uBAAuB,EAAE,CAAC,EACjE,KACF,EAAY,kBAAkB,EAAE,UAAU,CAAC,cAAc,EAAa,EAAE,CAAC,EAEvE,KACF,EAAY,kBAAkB,EAAE,UAAU,CAAC,wBAAwB,EAAY,EAAE,CAAC;;AAQtF,IAAa,UAA8B;CACzC,IAAM,EAAE,cAAW,mBAAgB,GAAsB,EACnD,IAAc,GAAgB,EAC9B,EAAE,YAAS,GAA2B;AAE5C,QAAO,EAAY;EACjB,YAAY,OAAO,MAA6D;GAC9E,IAAM,IAAS,MAAM,EAAsD;IACzE,SAAS;IACT,WAAW,KAAa,KAAA;IACxB,OAAO,EAAM,EAA2B;IACxC,WAAW,EAAE,UAAO;IACpB,aAAa,KAAe,KAAA;IAC5B,gBAAgB;IACjB,CAAC;AAEF,OAAI,EAAO,QAAQ,OACjB,OAAU,MAAM,EAAO,OAAO,IAAI,WAAW,gBAAgB;AAG/D,UAAO,EAAO,KAAM;;EAEtB,YAAY,MAAS;AAEnB,GADA,EAAsB,GAAa,EAAK,YAAY,EACpD,EAAK,0BAA0B;IAC7B,UAAU,EAAK;IACf,aAAa,EAAK;IAClB,QAAQ,EAAK;IACb,QAAQ;IACT,CAAC;;EAEJ,UAAU,GAAK,MAAU;AACvB,KAAK,+BAA+B;IAClC,aAAa,KAAe,KAAA;IAC5B,QAAQ,GAAO;IACf,QAAQ;IACR,cAAc,EAAmB,EAAI;IACtC,CAAC;;EAEL,CAAC;GAMS,KAA4B,MAAiC;CACxE,IAAM,EAAE,cAAW,mBAAgB,GAAsB,EACnD,IAAc,GAAgB,EAC9B,EAAE,YAAS,GAA2B,EACtC,IAAuB,KAAuB;AAEpD,QAAO,EAAY;EACjB,YAAY,OAAO,MAAiC;GAClD,IAAM,IAAS,MAAM,EAAiD;IACpE,SAAS;IACT,WAAW,KAAa,KAAA;IACxB,OAAO,EAAM,EAA8B;IAC3C,WAAW,EAAE,OAAI;IACjB,aAAa,KAAwB,KAAA;IACrC,gBAAgB;IACjB,CAAC;AAEF,OAAI,EAAO,QAAQ,OACjB,OAAU,MAAM,EAAO,OAAO,IAAI,WAAW,gBAAgB;AAG/D,UAAO,EAAO,KAAM;;EAEtB,YAAY,GAAG,MAAO;AAEpB,GADA,EAAsB,GAAa,EAAqB,EACxD,EAAK,4BAA4B;IAAE,UAAU;IAAI,QAAQ;IAAsB,CAAC;;EAElF,UAAU,GAAK,MAAO;AACpB,KAAK,kCAAkC;IACrC,UAAU;IACV,aAAa,KAAwB,KAAA;IACrC,QAAQ;IACR,cAAc,EAAmB,EAAI;IACtC,CAAC;;EAEL,CAAC;GAOS,KAA8B,MAAiC;CAC1E,IAAM,EAAE,cAAW,mBAAgB,GAAsB,EACnD,IAAc,GAAgB,EAC9B,EAAE,YAAS,GAA2B,EACtC,IAAuB,KAAuB;AAEpD,QAAO,EAAY;EACjB,YAAY,OAAO,MAAqC;GACtD,IAAM,IAAS,MAAM,EAAmD;IACtE,SAAS;IACT,WAAW,KAAa,KAAA;IACxB,OAAO,EAAM,EAAgC;IAC7C,WAAW,EAAE,WAAQ;IACrB,aAAa,KAAwB,KAAA;IACrC,gBAAgB;IACjB,CAAC;AAEF,OAAI,EAAO,QAAQ,OACjB,OAAU,MAAM,EAAO,OAAO,IAAI,WAAW,gBAAgB;AAG/D,UAAO,EAAO,KAAM;;EAEtB,YAAY,GAAG,MAAW;AAGxB,GAFA,EAAsB,GAAa,EAAqB,EACxD,EAAY,kBAAkB,EAAE,UAAU,CAAC,kBAAkB,EAAO,EAAE,CAAC,EACvE,EAAK,4BAA4B;IAAE;IAAQ,QAAQ;IAAsB,CAAC;;EAE5E,UAAU,GAAK,MAAW;AACxB,KAAK,kCAAkC;IACrC;IACA,aAAa,KAAwB,KAAA;IACrC,QAAQ;IACR,cAAc,EAAmB,EAAI;IACtC,CAAC;;EAEL,CAAC;GAeS,KAAuB,MAAiC;CACnE,IAAM,EAAE,cAAW,mBAAgB,GAAsB,EACnD,IAAc,GAAgB,EAC9B,EAAE,YAAS,GAA2B,EACtC,IAAuB,KAAuB;AAEpD,QAAO,EAAY;EACjB,YAAY,OAAO,MAA+D;GAChF,IAAM,IAAS,MAAM,EAAwD;IAC3E,SAAS;IACT,WAAW,KAAa,KAAA;IACxB,OAAO,EAAM,EAAyB;IACtC,WAAW,EAAE,UAAO;IACpB,aAAa,EAAM,eAAe,KAAwB,KAAA;IAC1D,gBAAgB;IACjB,CAAC;AAEF,OAAI,EAAO,QAAQ,OACjB,OAAU,MAAM,EAAO,OAAO,IAAI,WAAW,gBAAgB;AAG/D,UAAO,EAAO,KAAM;;EAEtB,YAAY,MAAS;GACnB,IAAM,IAAO,EAAK,eAAe;AAEjC,GADA,EAA0B,GAAa,EAAK,IAAI,EAAK,EACrD,EAAK,gCAAgC;IACnC,cAAc,EAAK;IACnB,aAAa,EAAK;IAClB,OAAO,EAAK;IACZ,QAAQ;IACT,CAAC;;EAEJ,UAAU,GAAK,MAAU;AACvB,KAAK,sCAAsC;IACzC,aAAa,GAAO,eAAe,KAAwB,KAAA;IAC3D,OAAO,GAAO;IACd,QAAQ;IACR,cAAc,EAAmB,EAAI;IACtC,CAAC;;EAEL,CAAC;GAMS,UAA4B;CACvC,IAAM,EAAE,cAAW,mBAAgB,GAAsB,EACnD,IAAc,GAAgB,EAC9B,EAAE,YAAS,GAA2B;AAE5C,QAAO,EAAY;EACjB,YAAY,OAAO,EACjB,OACA,eAIkC;GAClC,IAAM,IAAS,MAAM,EAAwD;IAC3E,SAAS;IACT,WAAW,KAAa,KAAA;IACxB,OAAO,EAAM,EAAyB;IACtC,WAAW;KAAE;KAAI;KAAO;IACxB,aAAa,KAAe,KAAA;IAC5B,gBAAgB;IACjB,CAAC;AAEF,OAAI,EAAO,QAAQ,OACjB,OAAU,MAAM,EAAO,OAAO,IAAI,WAAW,gBAAgB;AAG/D,UAAO,EAAO,KAAM;;EAEtB,YAAY,MAAS;AAEnB,GADA,EAA0B,GAAa,EAAK,IAAI,EAAK,YAAY,EACjE,EAAK,gCAAgC;IACnC,cAAc,EAAK;IACnB,aAAa,EAAK;IAClB,QAAQ;IACT,CAAC;;EAEJ,UAAU,GAAK,MAAc;AAC3B,KAAK,sCAAsC;IACzC,cAAc,GAAW;IACzB,aAAa,KAAe,KAAA;IAC5B,QAAQ;IACR,cAAc,EAAmB,EAAI;IACtC,CAAC;;EAEL,CAAC;GAMS,UAA4B;CACvC,IAAM,EAAE,cAAW,mBAAgB,GAAsB,EACnD,IAAc,GAAgB,EAC9B,EAAE,YAAS,GAA2B;AAE5C,QAAO,EAAY;EACjB,YAAY,OAAO,MAA6C;GAC9D,IAAM,IAAS,MAAM,EAAwD;IAC3E,SAAS;IACT,WAAW,KAAa,KAAA;IACxB,OAAO,EAAM,EAAyB;IACtC,WAAW,EAAE,OAAI;IACjB,aAAa,KAAe,KAAA;IAC5B,gBAAgB;IACjB,CAAC;AAEF,OAAI,EAAO,QAAQ,OACjB,OAAU,MAAM,EAAO,OAAO,IAAI,WAAW,gBAAgB;AAG/D,UAAO,EAAO,KAAM;;EAEtB,YAAY,MAAS;AAInB,GAFA,EAA0B,GAAa,EAAK,IAAI,EAAK,aAAa,GAAK,EACvE,EAAsB,GAAa,EAAK,YAAY,EACpD,EAAK,iCAAiC;IACpC,cAAc,EAAK;IACnB,aAAa,EAAK;IAClB,QAAQ;IACT,CAAC;;EAEJ,UAAU,GAAK,MAAO;AACpB,KAAK,sCAAsC;IACzC,cAAc;IACd,aAAa,KAAe,KAAA;IAC5B,QAAQ;IACR,cAAc,EAAmB,EAAI;IACtC,CAAC;;EAEL,CAAC;GAMS,UAA4B;CACvC,IAAM,EAAE,cAAW,mBAAgB,GAAsB,EACnD,IAAc,GAAgB,EAC9B,EAAE,YAAS,GAA2B;AAE5C,QAAO,EAAY;EACjB,YAAY,OAAO,MAA6C;GAC9D,IAAM,IAAS,MAAM,EAAwD;IAC3E,SAAS;IACT,WAAW,KAAa,KAAA;IACxB,OAAO,EAAM,EAAyB;IACtC,WAAW,EAAE,OAAI;IACjB,aAAa,KAAe,KAAA;IAC5B,gBAAgB;IACjB,CAAC;AAEF,OAAI,EAAO,QAAQ,OACjB,OAAU,MAAM,EAAO,OAAO,IAAI,WAAW,gBAAgB;AAG/D,UAAO,EAAO,KAAM;;EAEtB,YAAY,MAAS;AAGnB,GADA,EAA0B,GAAa,EAAK,IAAI,EAAK,aAAa,GAAK,EACvE,EAAK,iCAAiC;IACpC,cAAc,EAAK;IACnB,aAAa,EAAK;IAClB,QAAQ;IACT,CAAC;;EAEJ,UAAU,GAAK,MAAO;AACpB,KAAK,sCAAsC;IACzC,cAAc;IACd,aAAa,KAAe,KAAA;IAC5B,QAAQ;IACR,cAAc,EAAmB,EAAI;IACtC,CAAC;;EAEL,CAAC;GAMS,KAAuB,MAAiC;CACnE,IAAM,EAAE,cAAW,mBAAgB,GAAsB,EACnD,IAAc,GAAgB,EAC9B,EAAE,YAAS,GAA2B,EACtC,IAAuB,KAAuB;AAEpD,QAAO,EAAY;EACjB,YAAY,OAAO,MAA6C;GAC9D,IAAM,IAAS,MAAM,EAAwD;IAC3E,SAAS;IACT,WAAW,KAAa,KAAA;IACxB,OAAO,EAAM,EAAyB;IACtC,WAAW,EAAE,OAAI;IACjB,aAAa,KAAwB,KAAA;IACrC,gBAAgB;IACjB,CAAC;AAEF,OAAI,EAAO,QAAQ,OACjB,OAAU,MAAM,EAAO,OAAO,IAAI,WAAW,gBAAgB;AAG/D,UAAO,EAAO,KAAM;;EAEtB,YAAY,MAAS;AAQnB,GANA,EACE,GACA,EAAK,IACL,EAAK,eAAe,GACpB,GACD,EACD,EAAK,kCAAkC;IACrC,cAAc,EAAK;IACnB,aAAa,EAAK;IAClB,QAAQ;IACT,CAAC;;EAEJ,UAAU,GAAK,MAAO;AACpB,KAAK,sCAAsC;IACzC,cAAc;IACd,aAAa,KAAwB,KAAA;IACrC,QAAQ;IACR,cAAc,EAAmB,EAAI;IACtC,CAAC;;EAEL,CAAC;GAMS,KAAuB,MAAiC;CACnE,IAAM,EAAE,cAAW,mBAAgB,GAAsB,EACnD,IAAc,GAAgB,EAC9B,EAAE,YAAS,GAA2B,EACtC,IAAuB,KAAuB;AAEpD,QAAO,EAAY;EACjB,YAAY,OAAO,MAA6C;GAC9D,IAAM,IAAS,MAAM,EAAwD;IAC3E,SAAS;IACT,WAAW,KAAa,KAAA;IACxB,OAAO,EAAM,EAAyB;IACtC,WAAW,EAAE,OAAI;IACjB,aAAa,KAAwB,KAAA;IACrC,gBAAgB;IACjB,CAAC;AAEF,OAAI,EAAO,QAAQ,OACjB,OAAU,MAAM,EAAO,OAAO,IAAI,WAAW,gBAAgB;AAG/D,UAAO,EAAO,KAAM;;EAEtB,YAAY,MAAS;AAEnB,GADA,EAA0B,GAAa,EAAK,IAAI,EAAK,eAAe,EAAqB,EACzF,EAAK,+BAA+B;IAClC,cAAc,EAAK;IACnB,aAAa,EAAK;IAClB,QAAQ;IACT,CAAC;;EAEJ,UAAU,GAAK,MAAO;AACpB,KAAK,sCAAsC;IACzC,cAAc;IACd,aAAa,KAAwB,KAAA;IACrC,QAAQ;IACR,cAAc,EAAmB,EAAI;IACtC,CAAC;;EAEL,CAAC;GAMS,UAA4B;CACvC,IAAM,EAAE,cAAW,mBAAgB,GAAsB,EACnD,IAAc,GAAgB,EAC9B,EAAE,YAAS,GAA2B;AAE5C,QAAO,EAAY;EACjB,YAAY,OAAO,MAAiC;GAClD,IAAM,IAAS,MAAM,EAA4C;IAC/D,SAAS;IACT,WAAW,KAAa,KAAA;IACxB,OAAO,EAAM,EAAyB;IACtC,WAAW,EAAE,OAAI;IACjB,aAAa,KAAe,KAAA;IAC5B,gBAAgB;IACjB,CAAC;AAEF,OAAI,EAAO,QAAQ,OACjB,OAAU,MAAM,EAAO,OAAO,IAAI,WAAW,gBAAgB;AAG/D,UAAO,EAAO,KAAM;;EAEtB,YAAY,GAAG,MAAO;AAGpB,GADA,EAA0B,GAAa,GAAI,GAAa,GAAK,EAC7D,EAAK,gCAAgC;IAAE,cAAc;IAAI,QAAQ;IAAsB,CAAC;;EAE1F,UAAU,GAAK,MAAO;AACpB,KAAK,sCAAsC;IACzC,cAAc;IACd,aAAa,KAAe,KAAA;IAC5B,QAAQ;IACR,cAAc,EAAmB,EAAI;IACtC,CAAC;;EAEL,CAAC;GAOS,UAAiC;CAC5C,IAAM,EAAE,cAAW,mBAAgB,GAAsB,EACnD,IAAc,GAAgB;AAEpC,QAAO,EAAY;EACjB,YAAY,OAAO,MAAoE;GACrF,IAAM,IAAS,MAAM,EAA+D;IAClF,SAAS;IACT,WAAW,KAAa,KAAA;IACxB,OAAO,EAAM,EAA8B;IAC3C,WAAW,EAAE,WAAQ;IACrB,aAAa,EAAO,IAAI,eAAe,KAAe,KAAA;IACtD,gBAAgB;IACjB,CAAC;AAEF,OAAI,EAAO,QAAQ,OACjB,OAAU,MAAM,EAAO,OAAO,IAAI,WAAW,gBAAgB;AAG/D,UAAO,EAAO,KAAM;;EAEtB,YAAY,MAAgB;AAE1B,GADA,EAAY,kBAAkB,EAAE,UAAU,CAAC,uBAAuB,EAAE,CAAC,EACrE,EAAY,kBAAkB,EAAE,UAAU,CAAC,uBAAuB,EAAE,CAAC;GACrE,IAAM,IAAe,IAAI,IACvB,EAAY,KAAK,MAAe,EAAW,YAAY,CAAC,OAAO,QAAQ,CACxE;AACD,QAAK,IAAM,KAAQ,EACjB,GAAY,kBAAkB,EAAE,UAAU,CAAC,wBAAwB,EAAK,EAAE,CAAC;;EAGhF,CAAC"}
@@ -4,115 +4,119 @@ import { useWorkspacePermissions as n } from "../hooks/useWorkspacePermissions.j
4
4
  import { formatDate as r } from "../utils/formatters.js";
5
5
  import { useWorkspaceActivity as i } from "../hooks/useWorkspaceActivity.js";
6
6
  import { jsx as a, jsxs as o } from "react/jsx-runtime";
7
- import { CardContent as s, CardHeader as c, CardTitle as l, GlassCard as u, IllustratedEmptyState as d, Skeleton as f } from "@burdenoff/fe-libs/ui";
8
- import { useParams as p } from "react-router-dom";
9
- import { useI18n as m } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
7
+ import { CardContent as s, CardHeader as c, CardTitle as l, GlassCard as u, IllustratedEmptyState as d, PagePurpose as f, Skeleton as p } from "@burdenoff/fe-libs/ui";
8
+ import { useParams as m } from "react-router-dom";
9
+ import { useI18n as h } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
10
10
  //#region src/pages/ActivityListPage.tsx
11
- function h() {
12
- let { t: h } = m(), { workspaceId: g } = p();
11
+ function g() {
12
+ let { t: g } = h(), { workspaceId: _ } = m();
13
13
  t("workspaces.activity", {
14
- workspaceId: g,
14
+ workspaceId: _,
15
15
  requireParams: !0
16
16
  });
17
- let { data: _, isLoading: v, error: y } = i(g), { canViewActivity: b, isLoading: x } = n();
18
- return x ? /* @__PURE__ */ o("div", {
17
+ let { data: v, isLoading: y, error: b } = i(_), { canViewActivity: x, isLoading: S } = n();
18
+ return S ? /* @__PURE__ */ o("div", {
19
19
  className: "space-y-4 p-6",
20
- children: [/* @__PURE__ */ a(f, { className: "h-10 w-1/3" }), /* @__PURE__ */ a(f, { className: "h-64" })]
21
- }) : b ? /* @__PURE__ */ o("div", {
20
+ children: [/* @__PURE__ */ a(p, { className: "h-10 w-1/3" }), /* @__PURE__ */ a(p, { className: "h-64" })]
21
+ }) : x ? /* @__PURE__ */ o("div", {
22
22
  className: "space-y-4 sm:space-y-6 p-3 sm:p-6",
23
- children: [/* @__PURE__ */ o("div", { children: [/* @__PURE__ */ a("h1", {
24
- className: "text-2xl sm:text-3xl font-bold",
25
- children: e(h, "activityList.title", "Activity")
26
- }), /* @__PURE__ */ a("p", {
27
- className: "text-text-secondary",
28
- children: e(h, "activityList.description", "Track workspace activity")
29
- })] }), v ? /* @__PURE__ */ a(u, {
30
- treatment: "plain",
31
- className: "border-border-seam",
32
- children: /* @__PURE__ */ a(s, {
33
- className: "py-8 text-sm text-text-muted",
34
- children: e(h, "activityList.loading", "Loading activity…")
35
- })
36
- }) : y ? /* @__PURE__ */ a(u, {
37
- treatment: "plain",
38
- className: "border-border-seam",
39
- children: /* @__PURE__ */ a(s, {
40
- className: "py-8 text-sm text-status-error-text",
41
- children: y instanceof Error ? y.message : e(h, "activityList.loadError", "Failed to load activity")
42
- })
43
- }) : (_?.length ?? 0) === 0 ? /* @__PURE__ */ a(d, {
44
- illustration: "empty-data",
45
- title: e(h, "activityList.emptyTitle", "No recent activity"),
46
- description: e(h, "activityList.emptyDescription", "Recent workspace actions will appear here as your team creates, updates, and manages work.")
47
- }) : /* @__PURE__ */ a("div", {
48
- className: "space-y-3",
49
- children: _?.map((t) => /* @__PURE__ */ o(u, {
50
- treatment: "insight",
23
+ children: [
24
+ /* @__PURE__ */ o("div", { children: [/* @__PURE__ */ a("h1", {
25
+ className: "text-2xl sm:text-3xl font-bold",
26
+ children: e(g, "activityList.title", "Activity")
27
+ }), /* @__PURE__ */ a("p", {
28
+ className: "text-text-secondary",
29
+ children: e(g, "activityList.description", "Track workspace activity")
30
+ })] }),
31
+ /* @__PURE__ */ a(f, { children: e(g, "activityList.purpose", "This is the audit trail for the workspace — a running log of who did what and when. Use it to catch up after time away, confirm a change went through, or investigate when and by whom a project or member was modified.") }),
32
+ y ? /* @__PURE__ */ a(u, {
33
+ treatment: "plain",
51
34
  className: "border-border-seam",
52
- children: [/* @__PURE__ */ a(c, {
53
- className: "pb-2",
54
- children: /* @__PURE__ */ a(l, {
55
- className: "text-base",
56
- children: t.description || t.action
57
- })
58
- }), /* @__PURE__ */ o(s, {
59
- className: "space-y-1 text-sm text-text-muted",
60
- children: [
61
- /* @__PURE__ */ o("p", { children: [
62
- e(h, "activityList.labelAction", "Action"),
63
- ":",
64
- " ",
65
- /* @__PURE__ */ a("span", {
66
- className: "text-text-primary",
67
- children: t.action
68
- })
69
- ] }),
70
- t.resourceType && /* @__PURE__ */ o("p", { children: [
71
- e(h, "activityList.labelResource", "Resource"),
72
- ":",
73
- " ",
74
- /* @__PURE__ */ a("span", {
75
- className: "text-text-primary",
76
- children: t.resourceType
77
- })
78
- ] }),
79
- /* @__PURE__ */ o("p", { children: [
80
- e(h, "activityList.labelWhen", "When"),
81
- ":",
82
- " ",
83
- /* @__PURE__ */ a("span", {
84
- className: "text-text-primary",
85
- children: r(t.timestamp)
86
- })
87
- ] }),
88
- /* @__PURE__ */ o("p", { children: [
89
- e(h, "activityList.labelActor", "Actor"),
90
- ":",
91
- " ",
92
- /* @__PURE__ */ a("span", {
93
- className: "break-all text-text-primary",
94
- children: t.userId
95
- })
96
- ] })
97
- ]
98
- })]
99
- }, t.id))
100
- })]
35
+ children: /* @__PURE__ */ a(s, {
36
+ className: "py-8 text-sm text-text-muted",
37
+ children: e(g, "activityList.loading", "Loading activity…")
38
+ })
39
+ }) : b ? /* @__PURE__ */ a(u, {
40
+ treatment: "plain",
41
+ className: "border-border-seam",
42
+ children: /* @__PURE__ */ a(s, {
43
+ className: "py-8 text-sm text-status-error-text",
44
+ children: b instanceof Error ? b.message : e(g, "activityList.loadError", "Failed to load activity")
45
+ })
46
+ }) : (v?.length ?? 0) === 0 ? /* @__PURE__ */ a(d, {
47
+ illustration: "empty-data",
48
+ title: e(g, "activityList.emptyTitle", "No recent activity"),
49
+ description: e(g, "activityList.emptyDescription", "Recent workspace actions will appear here as your team creates, updates, and manages work.")
50
+ }) : /* @__PURE__ */ a("div", {
51
+ className: "space-y-3",
52
+ children: v?.map((t) => /* @__PURE__ */ o(u, {
53
+ treatment: "insight",
54
+ className: "border-border-seam",
55
+ children: [/* @__PURE__ */ a(c, {
56
+ className: "pb-2",
57
+ children: /* @__PURE__ */ a(l, {
58
+ className: "text-base",
59
+ children: t.description || t.action
60
+ })
61
+ }), /* @__PURE__ */ o(s, {
62
+ className: "space-y-1 text-sm text-text-muted",
63
+ children: [
64
+ /* @__PURE__ */ o("p", { children: [
65
+ e(g, "activityList.labelAction", "Action"),
66
+ ":",
67
+ " ",
68
+ /* @__PURE__ */ a("span", {
69
+ className: "text-text-primary",
70
+ children: t.action
71
+ })
72
+ ] }),
73
+ t.resourceType && /* @__PURE__ */ o("p", { children: [
74
+ e(g, "activityList.labelResource", "Resource"),
75
+ ":",
76
+ " ",
77
+ /* @__PURE__ */ a("span", {
78
+ className: "text-text-primary",
79
+ children: t.resourceType
80
+ })
81
+ ] }),
82
+ /* @__PURE__ */ o("p", { children: [
83
+ e(g, "activityList.labelWhen", "When"),
84
+ ":",
85
+ " ",
86
+ /* @__PURE__ */ a("span", {
87
+ className: "text-text-primary",
88
+ children: r(t.timestamp)
89
+ })
90
+ ] }),
91
+ /* @__PURE__ */ o("p", { children: [
92
+ e(g, "activityList.labelActor", "Actor"),
93
+ ":",
94
+ " ",
95
+ /* @__PURE__ */ a("span", {
96
+ className: "break-all text-text-primary",
97
+ children: t.userId
98
+ })
99
+ ] })
100
+ ]
101
+ })]
102
+ }, t.id))
103
+ })
104
+ ]
101
105
  }) : /* @__PURE__ */ a("div", {
102
106
  className: "flex items-center justify-center min-h-[400px]",
103
107
  children: /* @__PURE__ */ o("div", {
104
108
  className: "text-center space-y-2",
105
109
  children: [/* @__PURE__ */ a("h2", {
106
110
  className: "text-lg font-semibold",
107
- children: e(h, "activityList.accessDenied", "Access Denied")
111
+ children: e(g, "activityList.accessDenied", "Access Denied")
108
112
  }), /* @__PURE__ */ a("p", {
109
113
  className: "text-sm text-text-secondary",
110
- children: e(h, "activityList.accessDeniedDescription", "You don't have permission to view activity.")
114
+ children: e(g, "activityList.accessDeniedDescription", "You don't have permission to view activity.")
111
115
  })]
112
116
  })
113
117
  });
114
118
  }
115
119
  //#endregion
116
- export { h as ActivityListPage };
120
+ export { g as ActivityListPage };
117
121
 
118
122
  //# sourceMappingURL=ActivityListPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ActivityListPage.js","names":[],"sources":["../../src/pages/ActivityListPage.tsx"],"sourcesContent":["import { useParams } from 'react-router-dom';\nimport {\n GlassCard,\n CardContent,\n CardHeader,\n CardTitle,\n Skeleton,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { useWorkspaceActivity } from '../hooks/useWorkspaceActivity';\nimport { useWorkspacePermissions } from '../hooks/useWorkspacePermissions';\nimport { useWorkspacesPageView } from '../hooks/useWorkspacesPageView';\nimport { formatDate } from '../utils/formatters';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { tWithFallback } from '../utils/i18n';\n\nexport function ActivityListPage() {\n const { t } = useI18n();\n\n // The URL path `:workspaceId` (when present) intentionally overrides the active\n // context. WorkspaceContextPathSync rewrites this segment on a context switch so\n // the override can't point at a stale workspace. (BOFF-2805 follow-up)\n const { workspaceId } = useParams<{ workspaceId: string }>();\n useWorkspacesPageView('workspaces.activity', { workspaceId, requireParams: true });\n const { data: activities, isLoading, error } = useWorkspaceActivity(workspaceId);\n const { canViewActivity, isLoading: permissionsLoading } = useWorkspacePermissions();\n\n if (permissionsLoading) {\n return (\n <div className=\"space-y-4 p-6\">\n <Skeleton className=\"h-10 w-1/3\" />\n <Skeleton className=\"h-64\" />\n </div>\n );\n }\n\n if (!canViewActivity) {\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <h2 className=\"text-lg font-semibold\">\n {tWithFallback(t, 'activityList.accessDenied', 'Access Denied')}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {tWithFallback(\n t,\n 'activityList.accessDeniedDescription',\n \"You don't have permission to view activity.\"\n )}\n </p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n <div>\n <h1 className=\"text-2xl sm:text-3xl font-bold\">\n {tWithFallback(t, 'activityList.title', 'Activity')}\n </h1>\n <p className=\"text-text-secondary\">\n {tWithFallback(t, 'activityList.description', 'Track workspace activity')}\n </p>\n </div>\n\n {isLoading ? (\n <GlassCard treatment=\"plain\" className=\"border-border-seam\">\n <CardContent className=\"py-8 text-sm text-text-muted\">\n {tWithFallback(t, 'activityList.loading', 'Loading activity…')}\n </CardContent>\n </GlassCard>\n ) : error ? (\n <GlassCard treatment=\"plain\" className=\"border-border-seam\">\n <CardContent className=\"py-8 text-sm text-status-error-text\">\n {error instanceof Error\n ? error.message\n : tWithFallback(t, 'activityList.loadError', 'Failed to load activity')}\n </CardContent>\n </GlassCard>\n ) : (activities?.length ?? 0) === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={tWithFallback(t, 'activityList.emptyTitle', 'No recent activity')}\n description={tWithFallback(\n t,\n 'activityList.emptyDescription',\n 'Recent workspace actions will appear here as your team creates, updates, and manages work.'\n )}\n />\n ) : (\n <div className=\"space-y-3\">\n {activities?.map((item) => (\n <GlassCard key={item.id} treatment=\"insight\" className=\"border-border-seam\">\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-base\">{item.description || item.action}</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-1 text-sm text-text-muted\">\n <p>\n {tWithFallback(t, 'activityList.labelAction', 'Action')}:{' '}\n <span className=\"text-text-primary\">{item.action}</span>\n </p>\n {item.resourceType && (\n <p>\n {tWithFallback(t, 'activityList.labelResource', 'Resource')}:{' '}\n <span className=\"text-text-primary\">{item.resourceType}</span>\n </p>\n )}\n <p>\n {tWithFallback(t, 'activityList.labelWhen', 'When')}:{' '}\n <span className=\"text-text-primary\">{formatDate(item.timestamp)}</span>\n </p>\n <p>\n {tWithFallback(t, 'activityList.labelActor', 'Actor')}:{' '}\n <span className=\"break-all text-text-primary\">{item.userId}</span>\n </p>\n </CardContent>\n </GlassCard>\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;AAgBA,SAAgB,IAAmB;CACjC,IAAM,EAAE,SAAM,GAAS,EAKjB,EAAE,mBAAgB,GAAoC;AAC5D,GAAsB,uBAAuB;EAAE;EAAa,eAAe;EAAM,CAAC;CAClF,IAAM,EAAE,MAAM,GAAY,cAAW,aAAU,EAAqB,EAAY,EAC1E,EAAE,oBAAiB,WAAW,MAAuB,GAAyB;AA8BpF,QA5BI,IAEA,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,GAAD,EAAU,WAAU,cAAe,CAAA,EACnC,kBAAC,GAAD,EAAU,WAAU,QAAS,CAAA,CACzB;MAIL,IAoBH,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;GAAI,WAAU;aACX,EAAc,GAAG,sBAAsB,WAAW;GAChD,CAAA,EACL,kBAAC,KAAD;GAAG,WAAU;aACV,EAAc,GAAG,4BAA4B,2BAA2B;GACvE,CAAA,CACA,EAAA,CAAA,EAEL,IACC,kBAAC,GAAD;GAAW,WAAU;GAAQ,WAAU;aACrC,kBAAC,GAAD;IAAa,WAAU;cACpB,EAAc,GAAG,wBAAwB,oBAAoB;IAClD,CAAA;GACJ,CAAA,GACV,IACF,kBAAC,GAAD;GAAW,WAAU;GAAQ,WAAU;aACrC,kBAAC,GAAD;IAAa,WAAU;cACpB,aAAiB,QACd,EAAM,UACN,EAAc,GAAG,0BAA0B,0BAA0B;IAC7D,CAAA;GACJ,CAAA,IACT,GAAY,UAAU,OAAO,IAChC,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAc,GAAG,2BAA2B,qBAAqB;GACxE,aAAa,EACX,GACA,iCACA,6FACD;GACD,CAAA,GAEF,kBAAC,OAAD;GAAK,WAAU;aACZ,GAAY,KAAK,MAChB,kBAAC,GAAD;IAAyB,WAAU;IAAU,WAAU;cAAvD,CACE,kBAAC,GAAD;KAAY,WAAU;eACpB,kBAAC,GAAD;MAAW,WAAU;gBAAa,EAAK,eAAe,EAAK;MAAmB,CAAA;KACnE,CAAA,EACb,kBAAC,GAAD;KAAa,WAAU;eAAvB;MACE,kBAAC,KAAD,EAAA,UAAA;OACG,EAAc,GAAG,4BAA4B,SAAS;OAAC;OAAE;OAC1D,kBAAC,QAAD;QAAM,WAAU;kBAAqB,EAAK;QAAc,CAAA;OACtD,EAAA,CAAA;MACH,EAAK,gBACJ,kBAAC,KAAD,EAAA,UAAA;OACG,EAAc,GAAG,8BAA8B,WAAW;OAAC;OAAE;OAC9D,kBAAC,QAAD;QAAM,WAAU;kBAAqB,EAAK;QAAoB,CAAA;OAC5D,EAAA,CAAA;MAEN,kBAAC,KAAD,EAAA,UAAA;OACG,EAAc,GAAG,0BAA0B,OAAO;OAAC;OAAE;OACtD,kBAAC,QAAD;QAAM,WAAU;kBAAqB,EAAW,EAAK,UAAU;QAAQ,CAAA;OACrE,EAAA,CAAA;MACJ,kBAAC,KAAD,EAAA,UAAA;OACG,EAAc,GAAG,2BAA2B,QAAQ;OAAC;OAAE;OACxD,kBAAC,QAAD;QAAM,WAAU;kBAA+B,EAAK;QAAc,CAAA;OAChE,EAAA,CAAA;MACQ;OACJ;MAxBI,EAAK,GAwBT,CACZ;GACE,CAAA,CAEJ;MAnFJ,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,MAAD;IAAI,WAAU;cACX,EAAc,GAAG,6BAA6B,gBAAgB;IAC5D,CAAA,EACL,kBAAC,KAAD;IAAG,WAAU;cACV,EACC,GACA,wCACA,8CACD;IACC,CAAA,CACA;;EACF,CAAA"}
1
+ {"version":3,"file":"ActivityListPage.js","names":[],"sources":["../../src/pages/ActivityListPage.tsx"],"sourcesContent":["import { useParams } from 'react-router-dom';\nimport {\n GlassCard,\n CardContent,\n CardHeader,\n CardTitle,\n Skeleton,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { useWorkspaceActivity } from '../hooks/useWorkspaceActivity';\nimport { useWorkspacePermissions } from '../hooks/useWorkspacePermissions';\nimport { useWorkspacesPageView } from '../hooks/useWorkspacesPageView';\nimport { formatDate } from '../utils/formatters';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { tWithFallback } from '../utils/i18n';\n\nexport function ActivityListPage() {\n const { t } = useI18n();\n\n // The URL path `:workspaceId` (when present) intentionally overrides the active\n // context. WorkspaceContextPathSync rewrites this segment on a context switch so\n // the override can't point at a stale workspace. (BOFF-2805 follow-up)\n const { workspaceId } = useParams<{ workspaceId: string }>();\n useWorkspacesPageView('workspaces.activity', { workspaceId, requireParams: true });\n const { data: activities, isLoading, error } = useWorkspaceActivity(workspaceId);\n const { canViewActivity, isLoading: permissionsLoading } = useWorkspacePermissions();\n\n if (permissionsLoading) {\n return (\n <div className=\"space-y-4 p-6\">\n <Skeleton className=\"h-10 w-1/3\" />\n <Skeleton className=\"h-64\" />\n </div>\n );\n }\n\n if (!canViewActivity) {\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <h2 className=\"text-lg font-semibold\">\n {tWithFallback(t, 'activityList.accessDenied', 'Access Denied')}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {tWithFallback(\n t,\n 'activityList.accessDeniedDescription',\n \"You don't have permission to view activity.\"\n )}\n </p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n <div>\n <h1 className=\"text-2xl sm:text-3xl font-bold\">\n {tWithFallback(t, 'activityList.title', 'Activity')}\n </h1>\n <p className=\"text-text-secondary\">\n {tWithFallback(t, 'activityList.description', 'Track workspace activity')}\n </p>\n </div>\n\n <PagePurpose>\n {tWithFallback(\n t,\n 'activityList.purpose',\n 'This is the audit trail for the workspace — a running log of who did what and when. Use it to catch up after time away, confirm a change went through, or investigate when and by whom a project or member was modified.'\n )}\n </PagePurpose>\n\n {isLoading ? (\n <GlassCard treatment=\"plain\" className=\"border-border-seam\">\n <CardContent className=\"py-8 text-sm text-text-muted\">\n {tWithFallback(t, 'activityList.loading', 'Loading activity…')}\n </CardContent>\n </GlassCard>\n ) : error ? (\n <GlassCard treatment=\"plain\" className=\"border-border-seam\">\n <CardContent className=\"py-8 text-sm text-status-error-text\">\n {error instanceof Error\n ? error.message\n : tWithFallback(t, 'activityList.loadError', 'Failed to load activity')}\n </CardContent>\n </GlassCard>\n ) : (activities?.length ?? 0) === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={tWithFallback(t, 'activityList.emptyTitle', 'No recent activity')}\n description={tWithFallback(\n t,\n 'activityList.emptyDescription',\n 'Recent workspace actions will appear here as your team creates, updates, and manages work.'\n )}\n />\n ) : (\n <div className=\"space-y-3\">\n {activities?.map((item) => (\n <GlassCard key={item.id} treatment=\"insight\" className=\"border-border-seam\">\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-base\">{item.description || item.action}</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-1 text-sm text-text-muted\">\n <p>\n {tWithFallback(t, 'activityList.labelAction', 'Action')}:{' '}\n <span className=\"text-text-primary\">{item.action}</span>\n </p>\n {item.resourceType && (\n <p>\n {tWithFallback(t, 'activityList.labelResource', 'Resource')}:{' '}\n <span className=\"text-text-primary\">{item.resourceType}</span>\n </p>\n )}\n <p>\n {tWithFallback(t, 'activityList.labelWhen', 'When')}:{' '}\n <span className=\"text-text-primary\">{formatDate(item.timestamp)}</span>\n </p>\n <p>\n {tWithFallback(t, 'activityList.labelActor', 'Actor')}:{' '}\n <span className=\"break-all text-text-primary\">{item.userId}</span>\n </p>\n </CardContent>\n </GlassCard>\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;AAiBA,SAAgB,IAAmB;CACjC,IAAM,EAAE,SAAM,GAAS,EAKjB,EAAE,mBAAgB,GAAoC;AAC5D,GAAsB,uBAAuB;EAAE;EAAa,eAAe;EAAM,CAAC;CAClF,IAAM,EAAE,MAAM,GAAY,cAAW,aAAU,EAAqB,EAAY,EAC1E,EAAE,oBAAiB,WAAW,MAAuB,GAAyB;AA8BpF,QA5BI,IAEA,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,GAAD,EAAU,WAAU,cAAe,CAAA,EACnC,kBAAC,GAAD,EAAU,WAAU,QAAS,CAAA,CACzB;MAIL,IAoBH,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;IAAI,WAAU;cACX,EAAc,GAAG,sBAAsB,WAAW;IAChD,CAAA,EACL,kBAAC,KAAD;IAAG,WAAU;cACV,EAAc,GAAG,4BAA4B,2BAA2B;IACvE,CAAA,CACA,EAAA,CAAA;GAEN,kBAAC,GAAD,EAAA,UACG,EACC,GACA,wBACA,2NACD,EACW,CAAA;GAEb,IACC,kBAAC,GAAD;IAAW,WAAU;IAAQ,WAAU;cACrC,kBAAC,GAAD;KAAa,WAAU;eACpB,EAAc,GAAG,wBAAwB,oBAAoB;KAClD,CAAA;IACJ,CAAA,GACV,IACF,kBAAC,GAAD;IAAW,WAAU;IAAQ,WAAU;cACrC,kBAAC,GAAD;KAAa,WAAU;eACpB,aAAiB,QACd,EAAM,UACN,EAAc,GAAG,0BAA0B,0BAA0B;KAC7D,CAAA;IACJ,CAAA,IACT,GAAY,UAAU,OAAO,IAChC,kBAAC,GAAD;IACE,cAAa;IACb,OAAO,EAAc,GAAG,2BAA2B,qBAAqB;IACxE,aAAa,EACX,GACA,iCACA,6FACD;IACD,CAAA,GAEF,kBAAC,OAAD;IAAK,WAAU;cACZ,GAAY,KAAK,MAChB,kBAAC,GAAD;KAAyB,WAAU;KAAU,WAAU;eAAvD,CACE,kBAAC,GAAD;MAAY,WAAU;gBACpB,kBAAC,GAAD;OAAW,WAAU;iBAAa,EAAK,eAAe,EAAK;OAAmB,CAAA;MACnE,CAAA,EACb,kBAAC,GAAD;MAAa,WAAU;gBAAvB;OACE,kBAAC,KAAD,EAAA,UAAA;QACG,EAAc,GAAG,4BAA4B,SAAS;QAAC;QAAE;QAC1D,kBAAC,QAAD;SAAM,WAAU;mBAAqB,EAAK;SAAc,CAAA;QACtD,EAAA,CAAA;OACH,EAAK,gBACJ,kBAAC,KAAD,EAAA,UAAA;QACG,EAAc,GAAG,8BAA8B,WAAW;QAAC;QAAE;QAC9D,kBAAC,QAAD;SAAM,WAAU;mBAAqB,EAAK;SAAoB,CAAA;QAC5D,EAAA,CAAA;OAEN,kBAAC,KAAD,EAAA,UAAA;QACG,EAAc,GAAG,0BAA0B,OAAO;QAAC;QAAE;QACtD,kBAAC,QAAD;SAAM,WAAU;mBAAqB,EAAW,EAAK,UAAU;SAAQ,CAAA;QACrE,EAAA,CAAA;OACJ,kBAAC,KAAD,EAAA,UAAA;QACG,EAAc,GAAG,2BAA2B,QAAQ;QAAC;QAAE;QACxD,kBAAC,QAAD;SAAM,WAAU;mBAA+B,EAAK;SAAc,CAAA;QAChE,EAAA,CAAA;OACQ;QACJ;OAxBI,EAAK,GAwBT,CACZ;IACE,CAAA;GAEJ;MA3FJ,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,MAAD;IAAI,WAAU;cACX,EAAc,GAAG,6BAA6B,gBAAgB;IAC5D,CAAA,EACL,kBAAC,KAAD;IAAG,WAAU;cACV,EACC,GACA,wCACA,8CACD;IACC,CAAA,CACA;;EACF,CAAA"}