@burdenoff/microfe-organization 2026.624.1 → 2026.625.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.
- package/dist/organization-management/AdminOrganizationRoot.js +4 -4
- package/dist/organization-management/AdminOrganizationRoot.js.map +1 -1
- package/dist/organization-management/UserOrganizationRoot.js +4 -4
- package/dist/organization-management/UserOrganizationRoot.js.map +1 -1
- package/dist/organization-management/modules/members/components/BulkInviteForm.js +155 -174
- package/dist/organization-management/modules/members/components/BulkInviteForm.js.map +1 -1
- package/dist/organization-management/modules/members/components/PendingInvitesList.js +78 -101
- package/dist/organization-management/modules/members/components/PendingInvitesList.js.map +1 -1
- package/dist/organization-management/modules/members/pages/InviteMemberPage.js +58 -52
- package/dist/organization-management/modules/members/pages/InviteMemberPage.js.map +1 -1
- package/dist/organization-management/modules/members/pages/InvitePeoplePage.js +42 -40
- package/dist/organization-management/modules/members/pages/InvitePeoplePage.js.map +1 -1
- package/dist/organization-management/modules/members/pages/MemberDetailPage.js +71 -69
- package/dist/organization-management/modules/members/pages/MemberDetailPage.js.map +1 -1
- package/dist/organization-management/modules/members/pages/MembersListPage.js +233 -204
- package/dist/organization-management/modules/members/pages/MembersListPage.js.map +1 -1
- package/dist/organization-management/modules/members/pages/MyInvitesPage.js +38 -37
- package/dist/organization-management/modules/members/pages/MyInvitesPage.js.map +1 -1
- package/dist/organization-management/modules/members/pages/OrganizationInviteAcceptancePage.js +134 -132
- package/dist/organization-management/modules/members/pages/OrganizationInviteAcceptancePage.js.map +1 -1
- package/dist/organization-management/modules/organizations/pages/OrganizationCreatePage.js +39 -37
- package/dist/organization-management/modules/organizations/pages/OrganizationCreatePage.js.map +1 -1
- package/dist/organization-management/modules/organizations/pages/OrganizationDetailPage.js +164 -167
- package/dist/organization-management/modules/organizations/pages/OrganizationDetailPage.js.map +1 -1
- package/dist/organization-management/modules/organizations/pages/OrganizationEditPage.js +49 -47
- package/dist/organization-management/modules/organizations/pages/OrganizationEditPage.js.map +1 -1
- package/dist/organization-management/modules/organizations/pages/OrganizationsListPage.js +258 -230
- package/dist/organization-management/modules/organizations/pages/OrganizationsListPage.js.map +1 -1
- package/dist/organization-management/modules/workspaces/components/WorkspaceCard.js +43 -50
- package/dist/organization-management/modules/workspaces/components/WorkspaceCard.js.map +1 -1
- package/dist/organization-management/modules/workspaces/pages/WorkspaceCreatePage.js +40 -38
- package/dist/organization-management/modules/workspaces/pages/WorkspaceCreatePage.js.map +1 -1
- package/dist/organization-management/modules/workspaces/pages/WorkspaceDetailPage.js +230 -299
- package/dist/organization-management/modules/workspaces/pages/WorkspaceDetailPage.js.map +1 -1
- package/dist/organization-management/modules/workspaces/pages/WorkspaceEditPage.js +47 -45
- package/dist/organization-management/modules/workspaces/pages/WorkspaceEditPage.js.map +1 -1
- package/dist/organization-management/modules/workspaces/pages/WorkspacesListPage.js +117 -74
- package/dist/organization-management/modules/workspaces/pages/WorkspacesListPage.js.map +1 -1
- package/dist/organization-management/shared/components/feedback/EmptyState.js +1 -1
- package/dist/organization-management/shared/components/feedback/EmptyState.js.map +1 -1
- package/dist/organization-management/shared/components/feedback/ErrorState.js +1 -1
- package/dist/organization-management/shared/components/feedback/ErrorState.js.map +1 -1
- package/dist/organization-management/shared/components/feedback/LoadingState.js +1 -1
- package/dist/organization-management/shared/components/feedback/LoadingState.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkspaceDetailPage.js","names":[],"sources":["../../../../../src/organization-management/modules/workspaces/pages/WorkspaceDetailPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { ArrowLeft, Briefcase, Edit, Trash2, UserPlus, Users } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport {\n ActorIdentity,\n buildActorFallback,\n useActorProfiles,\n type ActorInput,\n} from '@burdenoff/fe-libs/shared';\nimport { useOrgConsole } from '../../../providers/OrgConsoleProvider';\nimport { useWorkspace } from '../hooks/useWorkspaces';\nimport { useRemoveWorkspaceMember, useWorkspaceMembers } from '../hooks/useWorkspaceMembers';\nimport { WorkspaceStatusBadge } from '../components/WorkspaceStatusBadge';\nimport { LoadingState } from '../../../shared/components/feedback/LoadingState';\nimport { ErrorState } from '../../../shared/components/feedback/ErrorState';\nimport { EmptyState } from '../../../shared/components/feedback/EmptyState';\nimport { MemberRoleBadge } from '../../members/components/MemberRoleBadge';\nimport { AddWorkspaceMemberDialog } from '../components/AddWorkspaceMemberDialog';\nimport { useConfirmDialog } from '../../../shared/components/dialog/ConfirmDialog';\nimport { PERMISSIONS } from '../../../constants/permissions';\nimport { useTr } from '../../../shared/hooks/useTr';\n\ntype ActiveTab = 'overview' | 'members';\n\nfunction formatDate(dateString: string) {\n return new Date(dateString).toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\nexport function WorkspaceDetailPage() {\n const tr = useTr();\n const { id } = useParams<{ id: string }>();\n const { navigate, basePath = '/organizations', apiGatewayUrl, authToken } = useOrgConsole();\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const { workspace, loading, error } = useWorkspace(id ?? '');\n const [activeTab, setActiveTab] = useState<ActiveTab>('overview');\n const [isAddMemberDialogOpen, setIsAddMemberDialogOpen] = useState(false);\n const { openConfirmDialog, ConfirmDialog } = useConfirmDialog();\n\n const shouldFetchMembers = activeTab === 'members' && Boolean(id);\n const {\n members,\n loading: membersLoading,\n error: membersError,\n refetch: refetchMembers,\n } = useWorkspaceMembers(shouldFetchMembers ? (id ?? '') : '', 50, 0);\n const { removeWorkspaceMember, loading: removingMember } = useRemoveWorkspaceMember();\n const resolvedMemberCount =\n members.length > 0 || activeTab === 'members' ? members.length : (workspace?.memberCount ?? 0);\n\n const memberActors = useMemo<ActorInput[]>(\n () => members.map((member) => ({ actorId: member.userId, actorType: 'user' })),\n [members]\n );\n const profileMap = useActorProfiles(memberActors, {\n apiGatewayUrl,\n authToken,\n orgId: workspace?.organizationId,\n workspaceId: id,\n });\n\n const tabItems = useMemo(\n () => [\n { id: 'overview' as const, label: tr('workspaces.detail.tab.overview', 'Overview') },\n {\n id: 'members' as const,\n label: `${tr('workspaces.detail.tab.members', 'Members')} (${resolvedMemberCount})`,\n },\n ],\n [resolvedMemberCount, tr]\n );\n\n const handleRemoveMember = (userId: string) => {\n if (!id) return;\n\n openConfirmDialog({\n title: tr('workspaces.removeMember.title', 'Remove workspace member'),\n description: `${tr('workspaces.removeMember.prefix', 'Remove')} ${userId} ${tr('workspaces.removeMember.suffix', 'from this workspace? They will keep their organization membership.')}`,\n confirmText: tr('common.remove', 'Remove'),\n variant: 'danger',\n onConfirm: () => {\n void (async () => {\n try {\n const result = await removeWorkspaceMember(id, userId);\n if (result.errors?.length) {\n throw new Error(\n result.errors[0]?.message ??\n tr('workspaces.removeMember.failed', 'Failed to remove workspace member')\n );\n }\n\n await refetchMembers();\n toast.success(\n tr('workspaces.removeMember.success', 'Workspace member removed successfully')\n );\n } catch (removeError) {\n toast.error(\n removeError instanceof Error\n ? removeError.message\n : tr('workspaces.removeMember.failed', 'Failed to remove workspace member')\n );\n }\n })();\n },\n });\n };\n\n if (permissionsLoading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <LoadingState message={tr('common.loadingPermissions', 'Loading permissions...')} />\n </div>\n );\n }\n\n if (!hasPermission(PERMISSIONS.WORKSPACE_READ)) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <div className=\"p-8 text-center text-[var(--color-text-secondary)]\">\n {tr(\n 'workspaces.detail.noPermission',\n \"You don't have permission to view this workspace.\"\n )}\n </div>\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <LoadingState message={tr('workspaces.detail.loading', 'Loading workspace details...')} />\n </div>\n );\n }\n\n if (error || !workspace) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <ErrorState\n message={error?.message || tr('workspaces.detail.notFound', 'Workspace not found')}\n action={{\n label: tr('workspaces.create.backToWorkspaces', 'Back to Workspaces'),\n onClick: () => navigate(`${basePath}/workspaces`),\n }}\n />\n </div>\n );\n }\n\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6 animate-in fade-in duration-300\">\n <div className=\"mx-auto flex w-full max-w-7xl flex-col gap-6\">\n <div className=\"space-y-4\">\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/workspaces`)}\n className=\"inline-flex min-h-10 items-center gap-2 text-[var(--color-text-secondary)] transition-all duration-200 hover:text-[var(--color-text-primary)]\"\n >\n <ArrowLeft size={20} aria-hidden=\"true\" />\n <span className=\"text-sm font-medium\">\n {tr('workspaces.create.backToWorkspaces', 'Back to Workspaces')}\n </span>\n </button>\n\n <div className=\"flex flex-col gap-4 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] p-5 shadow-[var(--shadow-elevation-1)] lg:flex-row lg:items-start lg:justify-between\">\n <div className=\"flex min-w-0 items-start gap-4\">\n <div className=\"flex size-16 items-center justify-center rounded-xl bg-[var(--color-status-info-bgSubtle)] text-[var(--color-status-info-text)]\">\n <Briefcase size={28} aria-hidden=\"true\" />\n </div>\n\n <div className=\"min-w-0 space-y-2\">\n <div className=\"flex flex-wrap items-start gap-2\">\n <h1 className=\"text-3xl font-bold text-[var(--color-text-primary)]\">\n {workspace.name}\n </h1>\n <WorkspaceStatusBadge status={workspace.status} />\n </div>\n <p className=\"break-all font-mono text-sm text-[var(--color-text-secondary)]\">\n /{workspace.slug}\n </p>\n </div>\n </div>\n\n <div className=\"flex flex-col gap-3 sm:flex-row\">\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${workspace.organizationId}`)}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg border border-[var(--color-border-default)] px-4 py-2.5 text-[var(--color-text-primary)] transition-all duration-200 hover:bg-[var(--color-bg-subtle)]\"\n >\n <Users size={16} aria-hidden=\"true\" />\n <span>{tr('workspaces.detail.viewOrganization', 'View Organization')}</span>\n </button>\n {hasPermission(PERMISSIONS.WORKSPACE_UPDATE) && (\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/workspaces/${id}/edit`)}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg bg-[var(--color-action-primary-bg)] px-4 py-2.5 text-[var(--color-action-primary-text)] transition-all duration-200 hover:opacity-90\"\n >\n <Edit size={16} aria-hidden=\"true\" />\n <span>{tr('workspaces.edit.title', 'Edit Workspace')}</span>\n </button>\n )}\n </div>\n </div>\n </div>\n\n <div className=\"rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] shadow-[var(--shadow-elevation-1)]\">\n <div className=\"overflow-x-auto border-b border-[var(--color-border-default)]\">\n <div className=\"flex min-w-max gap-2 px-4 pt-4 sm:px-6\">\n {tabItems.map((tabItem) => {\n const isActive = activeTab === tabItem.id;\n return (\n <button\n type=\"button\"\n key={tabItem.id}\n onClick={() => setActiveTab(tabItem.id)}\n className={`inline-flex min-h-11 items-center rounded-t-lg border-b-2 px-4 py-3 text-sm font-medium transition-colors ${\n isActive\n ? 'border-[var(--color-action-primary-bg)] text-[var(--color-action-primary-bg)]'\n : 'border-transparent text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)]'\n }`}\n aria-pressed={isActive}\n >\n {tabItem.label}\n </button>\n );\n })}\n </div>\n </div>\n\n <div className=\"p-4 sm:p-6\">\n {activeTab === 'overview' ? (\n <div className=\"grid grid-cols-1 gap-6 xl:grid-cols-[minmax(0,1fr)_320px]\">\n <section className=\"rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-canvas)] p-5\">\n <h2 className=\"text-lg font-semibold text-[var(--color-text-primary)]\">\n {tr('workspaces.detail.detailsSection', 'Workspace details')}\n </h2>\n\n <dl className=\"mt-5 grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.name', 'Name')}\n </dt>\n <dd className=\"mt-1 text-sm text-[var(--color-text-primary)]\">\n {workspace.name}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.slug', 'Slug')}\n </dt>\n <dd className=\"mt-1 break-all font-mono text-sm text-[var(--color-text-primary)]\">\n {workspace.slug}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.status', 'Status')}\n </dt>\n <dd className=\"mt-1\">\n <WorkspaceStatusBadge status={workspace.status} />\n </dd>\n </div>\n <div className=\"sm:col-span-2\">\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('members.detail.orgId', 'Organization ID')}\n </dt>\n <dd className=\"mt-1 break-all font-mono text-sm text-[var(--color-text-primary)]\">\n {workspace.organizationId}\n </dd>\n </div>\n {workspace.endpoint ? (\n <div className=\"sm:col-span-2\">\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('workspaces.detail.endpoint', 'Endpoint')}\n </dt>\n <dd className=\"mt-1 break-all font-mono text-sm text-[var(--color-text-primary)]\">\n {workspace.endpoint}\n </dd>\n </div>\n ) : null}\n </dl>\n </section>\n\n <aside className=\"rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-canvas)] p-5\">\n <h2 className=\"text-lg font-semibold text-[var(--color-text-primary)]\">\n {tr('common.metadata', 'Metadata')}\n </h2>\n\n <dl className=\"mt-5 space-y-4\">\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('workspaces.list.members', 'Members')}\n </dt>\n <dd className=\"mt-1 text-sm text-[var(--color-text-primary)]\">\n {resolvedMemberCount}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.created', 'Created')}\n </dt>\n <dd className=\"mt-1 text-sm text-[var(--color-text-primary)]\">\n {formatDate(workspace.createdAt)}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.lastUpdated', 'Last updated')}\n </dt>\n <dd className=\"mt-1 text-sm text-[var(--color-text-primary)]\">\n {formatDate(workspace.updatedAt)}\n </dd>\n </div>\n {workspace.region ? (\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('workspaces.detail.region', 'Region')}\n </dt>\n <dd className=\"mt-1 text-sm text-[var(--color-text-primary)]\">\n {workspace.region}\n </dd>\n </div>\n ) : null}\n </dl>\n </aside>\n </div>\n ) : (\n <section className=\"space-y-4\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h2 className=\"text-lg font-semibold text-[var(--color-text-primary)]\">\n {tr('workspaces.detail.membersTitle', 'Workspace members')}\n </h2>\n <p className=\"text-sm text-[var(--color-text-secondary)]\">\n {tr(\n 'workspaces.detail.membersSubtitle',\n 'Add organization members to this workspace and manage access.'\n )}\n </p>\n </div>\n {hasPermission(PERMISSIONS.MEMBER_INVITE) && (\n <button\n type=\"button\"\n onClick={() => setIsAddMemberDialogOpen(true)}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg bg-[var(--color-action-primary-bg)] px-4 py-2.5 text-[var(--color-action-primary-text)] transition-all duration-200 hover:opacity-90\"\n >\n <UserPlus size={16} aria-hidden=\"true\" />\n <span>{tr('workspaces.detail.addMember', 'Add Member')}</span>\n </button>\n )}\n </div>\n\n {membersLoading ? (\n <div className=\"py-8\">\n <LoadingState\n message={tr(\n 'workspaces.detail.loadingMembers',\n 'Loading workspace members...'\n )}\n />\n </div>\n ) : membersError ? (\n <ErrorState\n message={membersError.message}\n action={{\n label: tr('common.retry', 'Retry'),\n onClick: () => {\n void refetchMembers();\n },\n }}\n />\n ) : members.length > 0 ? (\n <>\n <div className=\"grid gap-4 md:hidden\">\n {members.map((member) => (\n <article\n key={member.id}\n className=\"rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-canvas)] p-4\"\n >\n <div className=\"space-y-3\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <ActorIdentity\n profile={\n profileMap[member.userId] ??\n buildActorFallback({\n actorId: member.userId,\n actorType: 'user',\n })\n }\n variant=\"inline\"\n />\n <p className=\"mt-1 text-sm text-[var(--color-text-secondary)]\">\n {tr('members.list.joined', 'Joined')}{' '}\n {formatDate(member.joinedAt)}\n </p>\n </div>\n <MemberRoleBadge role={member.role} />\n </div>\n\n <dl className=\"grid grid-cols-1 gap-3 text-sm\">\n <div>\n <dt className=\"text-[var(--color-text-secondary)]\">\n {tr('members.list.invitedBy', 'Invited by')}\n </dt>\n <dd className=\"mt-1 break-all font-mono text-[var(--color-text-primary)]\">\n {member.invitedBy || '—'}\n </dd>\n </div>\n </dl>\n\n <button\n type=\"button\"\n onClick={() => handleRemoveMember(member.userId)}\n disabled={removingMember}\n className=\"inline-flex min-h-10 items-center gap-2 rounded-lg border border-[var(--color-status-error-border)] px-3 py-2 text-sm text-[var(--color-status-error-text)] transition-all duration-200 hover:bg-[var(--color-status-error-bgSubtle)] disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <Trash2 size={16} aria-hidden=\"true\" />\n {tr('common.remove', 'Remove')}\n </button>\n </div>\n </article>\n ))}\n </div>\n\n <div className=\"hidden overflow-hidden rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-canvas)] md:block\">\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full\">\n <thead className=\"bg-[var(--color-bg-subtle)]\">\n <tr>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('members.detail.userId', 'User ID')}\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('members.list.column.role', 'Role')}\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('members.list.joined', 'Joined')}\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('members.list.invitedBy', 'Invited by')}\n </th>\n <th className=\"px-6 py-3 text-right text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('common.actions', 'Actions')}\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-[var(--color-border-default)]\">\n {members.map((member) => (\n <tr\n key={member.id}\n className=\"transition-colors hover:bg-[var(--color-bg-subtle)]\"\n >\n <td className=\"px-6 py-4\">\n <ActorIdentity\n profile={\n profileMap[member.userId] ??\n buildActorFallback({\n actorId: member.userId,\n actorType: 'user',\n })\n }\n variant=\"cell\"\n />\n </td>\n <td className=\"px-6 py-4\">\n <MemberRoleBadge role={member.role} />\n </td>\n <td className=\"px-6 py-4 text-sm text-[var(--color-text-secondary)]\">\n {formatDate(member.joinedAt)}\n </td>\n <td className=\"px-6 py-4 break-all font-mono text-sm text-[var(--color-text-secondary)]\">\n {member.invitedBy || '—'}\n </td>\n <td className=\"px-6 py-4 text-right\">\n <button\n type=\"button\"\n onClick={() => handleRemoveMember(member.userId)}\n disabled={removingMember}\n className=\"rounded-lg p-2 text-[var(--color-status-error-text)] transition-all duration-200 hover:bg-[var(--color-status-error-bgSubtle)] disabled:cursor-not-allowed disabled:opacity-50\"\n aria-label={`${tr('workspaces.removeMember.ariaPrefix', 'Remove')} ${member.userId} ${tr('workspaces.removeMember.ariaSuffix', 'from workspace')}`}\n title={`${tr('workspaces.removeMember.ariaPrefix', 'Remove')} ${member.userId} ${tr('workspaces.removeMember.ariaSuffix', 'from workspace')}`}\n >\n <Trash2 size={18} aria-hidden=\"true\" />\n </button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n </>\n ) : (\n <div className=\"rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-canvas)] p-6\">\n <EmptyState\n icon={<Users size={40} aria-hidden=\"true\" />}\n title={tr('workspaces.detail.emptyMembersTitle', 'No workspace members yet')}\n description={tr(\n 'workspaces.detail.emptyMembersDescription',\n 'Add people from the parent organization to grant workspace access.'\n )}\n action={{\n label: tr('workspaces.detail.addMember', 'Add Member'),\n onClick: () => setIsAddMemberDialogOpen(true),\n }}\n />\n </div>\n )}\n </section>\n )}\n </div>\n </div>\n </div>\n\n <AddWorkspaceMemberDialog\n open={isAddMemberDialogOpen}\n onOpenChange={setIsAddMemberDialogOpen}\n workspaceId={workspace.id}\n organizationId={workspace.organizationId}\n existingMembers={members}\n onInviteOrganizationMember={() =>\n navigate(`${basePath}/${workspace.organizationId}/members/invite`)\n }\n />\n {ConfirmDialog}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WorkspaceDetailPage.js","names":[],"sources":["../../../../../src/organization-management/modules/workspaces/pages/WorkspaceDetailPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { ArrowLeft, Briefcase, Edit, Trash2, UserPlus, Users } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport {\n ActorIdentity,\n buildActorFallback,\n useActorProfiles,\n type ActorInput,\n} from '@burdenoff/fe-libs/shared';\nimport {\n CTAOverflowMenu,\n EmphasisPanel,\n GlassCard,\n ResponsiveTable,\n type ResponsiveTableColumn,\n} from '@burdenoff/fe-libs/ui';\nimport type { WorkspaceMember } from '../types/workspace-member';\nimport { useOrgConsole } from '../../../providers/OrgConsoleProvider';\nimport { useWorkspace } from '../hooks/useWorkspaces';\nimport { useRemoveWorkspaceMember, useWorkspaceMembers } from '../hooks/useWorkspaceMembers';\nimport { WorkspaceStatusBadge } from '../components/WorkspaceStatusBadge';\nimport { LoadingState } from '../../../shared/components/feedback/LoadingState';\nimport { ErrorState } from '../../../shared/components/feedback/ErrorState';\nimport { EmptyState } from '../../../shared/components/feedback/EmptyState';\nimport { MemberRoleBadge } from '../../members/components/MemberRoleBadge';\nimport { AddWorkspaceMemberDialog } from '../components/AddWorkspaceMemberDialog';\nimport { useConfirmDialog } from '../../../shared/components/dialog/ConfirmDialog';\nimport { PERMISSIONS } from '../../../constants/permissions';\nimport { useTr } from '../../../shared/hooks/useTr';\n\ntype ActiveTab = 'overview' | 'members';\n\nfunction formatDate(dateString: string) {\n return new Date(dateString).toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\nexport function WorkspaceDetailPage() {\n const tr = useTr();\n const { id } = useParams<{ id: string }>();\n const { navigate, basePath = '/organizations', apiGatewayUrl, authToken } = useOrgConsole();\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const { workspace, loading, error } = useWorkspace(id ?? '');\n const [activeTab, setActiveTab] = useState<ActiveTab>('overview');\n const [isAddMemberDialogOpen, setIsAddMemberDialogOpen] = useState(false);\n const { openConfirmDialog, ConfirmDialog } = useConfirmDialog();\n\n const shouldFetchMembers = activeTab === 'members' && Boolean(id);\n const {\n members,\n loading: membersLoading,\n error: membersError,\n refetch: refetchMembers,\n } = useWorkspaceMembers(shouldFetchMembers ? (id ?? '') : '', 50, 0);\n const { removeWorkspaceMember, loading: removingMember } = useRemoveWorkspaceMember();\n const resolvedMemberCount =\n members.length > 0 || activeTab === 'members' ? members.length : (workspace?.memberCount ?? 0);\n\n const memberActors = useMemo<ActorInput[]>(\n () => members.map((member) => ({ actorId: member.userId, actorType: 'user' })),\n [members]\n );\n const profileMap = useActorProfiles(memberActors, {\n apiGatewayUrl,\n authToken,\n orgId: workspace?.organizationId,\n workspaceId: id,\n });\n\n const tabItems = useMemo(\n () => [\n { id: 'overview' as const, label: tr('workspaces.detail.tab.overview', 'Overview') },\n {\n id: 'members' as const,\n label: `${tr('workspaces.detail.tab.members', 'Members')} (${resolvedMemberCount})`,\n },\n ],\n [resolvedMemberCount, tr]\n );\n\n const handleRemoveMember = (userId: string) => {\n if (!id) return;\n\n openConfirmDialog({\n title: tr('workspaces.removeMember.title', 'Remove workspace member'),\n description: `${tr('workspaces.removeMember.prefix', 'Remove')} ${userId} ${tr('workspaces.removeMember.suffix', 'from this workspace? They will keep their organization membership.')}`,\n confirmText: tr('common.remove', 'Remove'),\n variant: 'danger',\n onConfirm: () => {\n void (async () => {\n try {\n const result = await removeWorkspaceMember(id, userId);\n if (result.errors?.length) {\n throw new Error(\n result.errors[0]?.message ??\n tr('workspaces.removeMember.failed', 'Failed to remove workspace member')\n );\n }\n\n await refetchMembers();\n toast.success(\n tr('workspaces.removeMember.success', 'Workspace member removed successfully')\n );\n } catch (removeError) {\n toast.error(\n removeError instanceof Error\n ? removeError.message\n : tr('workspaces.removeMember.failed', 'Failed to remove workspace member')\n );\n }\n })();\n },\n });\n };\n\n const memberColumns: ResponsiveTableColumn<WorkspaceMember>[] = [\n {\n key: 'user',\n header: tr('members.detail.userId', 'User ID'),\n priority: 'primary',\n cell: (member) => (\n <ActorIdentity\n profile={\n profileMap[member.userId] ??\n buildActorFallback({ actorId: member.userId, actorType: 'user' })\n }\n variant=\"cell\"\n />\n ),\n },\n {\n key: 'role',\n header: tr('members.list.column.role', 'Role'),\n priority: 'secondary',\n cell: (member) => <MemberRoleBadge role={member.role} />,\n },\n {\n key: 'joined',\n header: tr('members.list.joined', 'Joined'),\n priority: 'secondary',\n cell: (member) => (\n <span className=\"text-sm text-[var(--color-text-secondary)]\">\n {formatDate(member.joinedAt)}\n </span>\n ),\n },\n {\n key: 'invitedBy',\n header: tr('members.list.invitedBy', 'Invited by'),\n priority: 'secondary',\n cell: (member) => (\n <span className=\"break-all font-mono text-sm text-[var(--color-text-secondary)]\">\n {member.invitedBy || '—'}\n </span>\n ),\n },\n ];\n\n const renderMemberActions = (member: WorkspaceMember) => (\n <button\n type=\"button\"\n onClick={() => handleRemoveMember(member.userId)}\n disabled={removingMember}\n className=\"rounded-lg p-2 text-[var(--color-status-error-text)] transition-all duration-200 hover:bg-[var(--color-status-error-bgSubtle)] disabled:cursor-not-allowed disabled:opacity-50\"\n aria-label={`${tr('workspaces.removeMember.ariaPrefix', 'Remove')} ${member.userId} ${tr('workspaces.removeMember.ariaSuffix', 'from workspace')}`}\n title={`${tr('workspaces.removeMember.ariaPrefix', 'Remove')} ${member.userId} ${tr('workspaces.removeMember.ariaSuffix', 'from workspace')}`}\n >\n <Trash2 size={18} aria-hidden=\"true\" />\n </button>\n );\n\n if (permissionsLoading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <LoadingState message={tr('common.loadingPermissions', 'Loading permissions...')} />\n </div>\n );\n }\n\n if (!hasPermission(PERMISSIONS.WORKSPACE_READ)) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <div className=\"p-8 text-center text-[var(--color-text-secondary)]\">\n {tr(\n 'workspaces.detail.noPermission',\n \"You don't have permission to view this workspace.\"\n )}\n </div>\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <LoadingState message={tr('workspaces.detail.loading', 'Loading workspace details...')} />\n </div>\n );\n }\n\n if (error || !workspace) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <ErrorState\n message={error?.message || tr('workspaces.detail.notFound', 'Workspace not found')}\n action={{\n label: tr('workspaces.create.backToWorkspaces', 'Back to Workspaces'),\n onClick: () => navigate(`${basePath}/workspaces`),\n }}\n />\n </div>\n );\n }\n\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6 animate-in fade-in duration-200\">\n <div className=\"mx-auto flex w-full max-w-7xl flex-col gap-6\">\n <div className=\"space-y-4\">\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/workspaces`)}\n className=\"inline-flex min-h-10 items-center gap-2 text-[var(--color-text-secondary)] transition-all duration-200 hover:text-[var(--color-text-primary)]\"\n >\n <ArrowLeft size={20} aria-hidden=\"true\" />\n <span className=\"text-sm font-medium\">\n {tr('workspaces.create.backToWorkspaces', 'Back to Workspaces')}\n </span>\n </button>\n\n <EmphasisPanel className=\"flex flex-col gap-4 p-5 lg:flex-row lg:items-start lg:justify-between\">\n <div className=\"flex min-w-0 items-start gap-4\">\n <div className=\"flex size-16 items-center justify-center rounded-xl bg-[var(--color-status-info-bgSubtle)] text-[var(--color-status-info-text)]\">\n <Briefcase size={28} aria-hidden=\"true\" />\n </div>\n\n <div className=\"min-w-0 space-y-2\">\n <div className=\"flex flex-wrap items-start gap-2\">\n <h1 className=\"text-3xl font-bold text-[var(--color-text-primary)]\">\n {workspace.name}\n </h1>\n <WorkspaceStatusBadge status={workspace.status} />\n </div>\n <p className=\"break-all font-mono text-sm text-[var(--color-text-secondary)]\">\n /{workspace.slug}\n </p>\n </div>\n </div>\n\n <CTAOverflowMenu\n primary={\n hasPermission(PERMISSIONS.WORKSPACE_UPDATE)\n ? {\n label: tr('workspaces.edit.title', 'Edit Workspace'),\n icon: <Edit size={16} aria-hidden=\"true\" />,\n onSelect: () => navigate(`${basePath}/workspaces/${id}/edit`),\n }\n : undefined\n }\n actions={[\n {\n label: tr('workspaces.detail.viewOrganization', 'View Organization'),\n icon: <Users size={16} aria-hidden=\"true\" />,\n onSelect: () => navigate(`${basePath}/${workspace.organizationId}`),\n },\n ]}\n />\n </EmphasisPanel>\n </div>\n\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-0\">\n <div className=\"overflow-x-auto border-b border-[var(--color-border-seam)]\">\n <div className=\"flex min-w-max gap-2 px-4 pt-4 sm:px-6\">\n {tabItems.map((tabItem) => {\n const isActive = activeTab === tabItem.id;\n return (\n <button\n type=\"button\"\n key={tabItem.id}\n onClick={() => setActiveTab(tabItem.id)}\n className={`inline-flex min-h-11 items-center rounded-t-lg border-b-2 px-4 py-3 text-sm font-medium transition-colors ${\n isActive\n ? 'border-[var(--color-action-primary-bg)] text-[var(--color-action-primary-bg)]'\n : 'border-transparent text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)]'\n }`}\n aria-pressed={isActive}\n >\n {tabItem.label}\n </button>\n );\n })}\n </div>\n </div>\n\n <div className=\"p-4 sm:p-6\">\n {activeTab === 'overview' ? (\n <div className=\"grid grid-cols-1 gap-6 xl:grid-cols-[minmax(0,1fr)_320px]\">\n <GlassCard\n treatment=\"plain\"\n className=\"border-border-seam bg-[var(--color-bg-canvas)] p-5\"\n >\n <h2 className=\"text-lg font-semibold text-[var(--color-text-primary)]\">\n {tr('workspaces.detail.detailsSection', 'Workspace details')}\n </h2>\n\n <dl className=\"mt-5 grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.name', 'Name')}\n </dt>\n <dd className=\"mt-1 text-sm text-[var(--color-text-primary)]\">\n {workspace.name}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.slug', 'Slug')}\n </dt>\n <dd className=\"mt-1 break-all font-mono text-sm text-[var(--color-text-primary)]\">\n {workspace.slug}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.status', 'Status')}\n </dt>\n <dd className=\"mt-1\">\n <WorkspaceStatusBadge status={workspace.status} />\n </dd>\n </div>\n <div className=\"sm:col-span-2\">\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('members.detail.orgId', 'Organization ID')}\n </dt>\n <dd className=\"mt-1 break-all font-mono text-sm text-[var(--color-text-primary)]\">\n {workspace.organizationId}\n </dd>\n </div>\n {workspace.endpoint ? (\n <div className=\"sm:col-span-2\">\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('workspaces.detail.endpoint', 'Endpoint')}\n </dt>\n <dd className=\"mt-1 break-all font-mono text-sm text-[var(--color-text-primary)]\">\n {workspace.endpoint}\n </dd>\n </div>\n ) : null}\n </dl>\n </GlassCard>\n\n <GlassCard\n treatment=\"plain\"\n className=\"border-border-seam bg-[var(--color-bg-canvas)] p-5 xl:sticky xl:top-6 xl:self-start\"\n >\n <h2 className=\"text-lg font-semibold text-[var(--color-text-primary)]\">\n {tr('common.metadata', 'Metadata')}\n </h2>\n\n <dl className=\"mt-5 space-y-4\">\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('workspaces.list.members', 'Members')}\n </dt>\n <dd className=\"mt-1 text-sm text-[var(--color-text-primary)]\">\n {resolvedMemberCount}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.created', 'Created')}\n </dt>\n <dd className=\"mt-1 text-sm text-[var(--color-text-primary)]\">\n {formatDate(workspace.createdAt)}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.lastUpdated', 'Last updated')}\n </dt>\n <dd className=\"mt-1 text-sm text-[var(--color-text-primary)]\">\n {formatDate(workspace.updatedAt)}\n </dd>\n </div>\n {workspace.region ? (\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('workspaces.detail.region', 'Region')}\n </dt>\n <dd className=\"mt-1 text-sm text-[var(--color-text-primary)]\">\n {workspace.region}\n </dd>\n </div>\n ) : null}\n </dl>\n </GlassCard>\n </div>\n ) : (\n <section className=\"space-y-4\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h2 className=\"text-lg font-semibold text-[var(--color-text-primary)]\">\n {tr('workspaces.detail.membersTitle', 'Workspace members')}\n </h2>\n <p className=\"text-sm text-[var(--color-text-secondary)]\">\n {tr(\n 'workspaces.detail.membersSubtitle',\n 'Add organization members to this workspace and manage access.'\n )}\n </p>\n </div>\n {hasPermission(PERMISSIONS.MEMBER_INVITE) && (\n <button\n type=\"button\"\n onClick={() => setIsAddMemberDialogOpen(true)}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg bg-[var(--color-action-primary-bg)] px-4 py-2.5 text-[var(--color-action-primary-text)] transition-all duration-200 hover:opacity-90\"\n >\n <UserPlus size={16} aria-hidden=\"true\" />\n <span>{tr('workspaces.detail.addMember', 'Add Member')}</span>\n </button>\n )}\n </div>\n\n {membersLoading ? (\n <div className=\"py-8\">\n <LoadingState\n message={tr(\n 'workspaces.detail.loadingMembers',\n 'Loading workspace members...'\n )}\n />\n </div>\n ) : membersError ? (\n <ErrorState\n message={membersError.message}\n action={{\n label: tr('common.retry', 'Retry'),\n onClick: () => {\n void refetchMembers();\n },\n }}\n />\n ) : members.length > 0 ? (\n <div className=\"overflow-hidden rounded-xl border border-[var(--color-border-seam)] bg-[var(--color-bg-canvas)] md:p-2\">\n <ResponsiveTable\n columns={memberColumns}\n data={members}\n rowKey={(member) => member.id}\n rowActions={renderMemberActions}\n />\n </div>\n ) : (\n <div className=\"rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-canvas)] p-6\">\n <EmptyState\n icon={<Users size={40} aria-hidden=\"true\" />}\n title={tr('workspaces.detail.emptyMembersTitle', 'No workspace members yet')}\n description={tr(\n 'workspaces.detail.emptyMembersDescription',\n 'Add people from the parent organization to grant workspace access.'\n )}\n action={{\n label: tr('workspaces.detail.addMember', 'Add Member'),\n onClick: () => setIsAddMemberDialogOpen(true),\n }}\n />\n </div>\n )}\n </section>\n )}\n </div>\n </GlassCard>\n </div>\n\n <AddWorkspaceMemberDialog\n open={isAddMemberDialogOpen}\n onOpenChange={setIsAddMemberDialogOpen}\n workspaceId={workspace.id}\n organizationId={workspace.organizationId}\n existingMembers={members}\n onInviteOrganizationMember={() =>\n navigate(`${basePath}/${workspace.organizationId}/members/invite`)\n }\n />\n {ConfirmDialog}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -7,85 +7,87 @@ import { PERMISSIONS as a } from "../../../constants/permissions.js";
|
|
|
7
7
|
import { useUpdateWorkspace as o, useWorkspace as s } from "../hooks/useWorkspaces.js";
|
|
8
8
|
import { WorkspaceForm as c } from "../components/WorkspaceForm.js";
|
|
9
9
|
import { ArrowLeft as l } from "lucide-react";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
10
|
+
import { GlassCard as u } from "@burdenoff/fe-libs/ui";
|
|
11
|
+
import { usePermissions as d } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
12
|
+
import { jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
13
|
+
import { useParams as m } from "react-router-dom";
|
|
13
14
|
//#region src/organization-management/modules/workspaces/pages/WorkspaceEditPage.tsx
|
|
14
|
-
function
|
|
15
|
-
let
|
|
16
|
-
if (
|
|
17
|
-
let n = await
|
|
18
|
-
if (n.errors?.length) throw Error(n.errors[0]?.message ??
|
|
19
|
-
t.success(
|
|
15
|
+
function h() {
|
|
16
|
+
let h = n(), { id: g } = m(), { navigate: _, basePath: v = "/organizations" } = e(), { hasPermission: y, isLoading: b } = d(), { workspace: x, loading: S, error: C } = s(g), { updateWorkspace: w, loading: T } = o(), E = async (e) => {
|
|
17
|
+
if (g) try {
|
|
18
|
+
let n = await w(g, e);
|
|
19
|
+
if (n.errors?.length) throw Error(n.errors[0]?.message ?? h("workspaces.edit.failed", "Failed to update workspace"));
|
|
20
|
+
t.success(h("workspaces.edit.success", "Workspace updated successfully")), _(`${v}/workspaces/${g}`);
|
|
20
21
|
} catch (e) {
|
|
21
|
-
t.error(e instanceof Error ? e.message :
|
|
22
|
+
t.error(e instanceof Error ? e.message : h("workspaces.edit.failed", "Failed to update workspace"));
|
|
22
23
|
}
|
|
23
|
-
},
|
|
24
|
-
|
|
24
|
+
}, D = () => {
|
|
25
|
+
_(`${v}/workspaces/${g}`);
|
|
25
26
|
};
|
|
26
|
-
return
|
|
27
|
+
return b ? /* @__PURE__ */ f("div", {
|
|
27
28
|
className: "min-h-full bg-[var(--color-bg-canvas)] p-6",
|
|
28
|
-
children: /* @__PURE__ */
|
|
29
|
-
}) :
|
|
29
|
+
children: /* @__PURE__ */ f(r, { message: h("common.loadingPermissions", "Loading permissions...") })
|
|
30
|
+
}) : y(a.WORKSPACE_UPDATE) ? S ? /* @__PURE__ */ f("div", {
|
|
30
31
|
className: "min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6",
|
|
31
|
-
children: /* @__PURE__ */
|
|
32
|
-
}) :
|
|
32
|
+
children: /* @__PURE__ */ f(r, { message: h("workspaces.edit.loading", "Loading workspace...") })
|
|
33
|
+
}) : C || !x ? /* @__PURE__ */ f("div", {
|
|
33
34
|
className: "min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6",
|
|
34
|
-
children: /* @__PURE__ */
|
|
35
|
-
message:
|
|
35
|
+
children: /* @__PURE__ */ f(i, {
|
|
36
|
+
message: C?.message || h("workspaces.detail.notFound", "Workspace not found"),
|
|
36
37
|
action: {
|
|
37
|
-
label:
|
|
38
|
-
onClick: () =>
|
|
38
|
+
label: h("workspaces.create.backToWorkspaces", "Back to Workspaces"),
|
|
39
|
+
onClick: () => _(`${v}/workspaces`)
|
|
39
40
|
}
|
|
40
41
|
})
|
|
41
|
-
}) : /* @__PURE__ */
|
|
42
|
-
className: "min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6 animate-in fade-in duration-
|
|
43
|
-
children: [/* @__PURE__ */
|
|
42
|
+
}) : /* @__PURE__ */ p("div", {
|
|
43
|
+
className: "min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6 animate-in fade-in duration-200",
|
|
44
|
+
children: [/* @__PURE__ */ p("div", {
|
|
44
45
|
className: "mb-6",
|
|
45
46
|
children: [
|
|
46
|
-
/* @__PURE__ */
|
|
47
|
+
/* @__PURE__ */ p("button", {
|
|
47
48
|
type: "button",
|
|
48
|
-
onClick:
|
|
49
|
+
onClick: D,
|
|
49
50
|
className: "\n inline-flex items-center gap-2 mb-4\n text-[var(--color-text-secondary)]\n hover:text-[var(--color-text-primary)]\n \n transition-all duration-200\n ",
|
|
50
|
-
children: [/* @__PURE__ */
|
|
51
|
+
children: [/* @__PURE__ */ f(l, { size: 20 }), /* @__PURE__ */ p("span", {
|
|
51
52
|
className: "text-sm font-medium",
|
|
52
53
|
children: [
|
|
53
|
-
|
|
54
|
+
h("common.backTo", "Back to"),
|
|
54
55
|
" ",
|
|
55
|
-
|
|
56
|
+
x.name
|
|
56
57
|
]
|
|
57
58
|
})]
|
|
58
59
|
}),
|
|
59
|
-
/* @__PURE__ */
|
|
60
|
+
/* @__PURE__ */ f("h1", {
|
|
60
61
|
className: "text-3xl font-bold text-[var(--color-text-primary)] mb-2",
|
|
61
|
-
children:
|
|
62
|
+
children: h("workspaces.edit.title", "Edit Workspace")
|
|
62
63
|
}),
|
|
63
|
-
/* @__PURE__ */
|
|
64
|
+
/* @__PURE__ */ f("p", {
|
|
64
65
|
className: "text-[var(--color-text-secondary)]",
|
|
65
|
-
children:
|
|
66
|
+
children: h("workspaces.edit.subtitle", "Update workspace information")
|
|
66
67
|
})
|
|
67
68
|
]
|
|
68
|
-
}), /* @__PURE__ */
|
|
69
|
+
}), /* @__PURE__ */ f("div", {
|
|
69
70
|
className: "max-w-2xl",
|
|
70
|
-
children: /* @__PURE__ */
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
children: /* @__PURE__ */ f(u, {
|
|
72
|
+
treatment: "plain",
|
|
73
|
+
className: "border-border-seam p-6",
|
|
74
|
+
children: /* @__PURE__ */ f(c, {
|
|
75
|
+
workspace: x,
|
|
76
|
+
onSubmit: E,
|
|
77
|
+
onCancel: D,
|
|
78
|
+
loading: T
|
|
77
79
|
})
|
|
78
80
|
})
|
|
79
81
|
})]
|
|
80
|
-
}) : /* @__PURE__ */
|
|
82
|
+
}) : /* @__PURE__ */ f("div", {
|
|
81
83
|
className: "min-h-full bg-[var(--color-bg-canvas)] p-6",
|
|
82
|
-
children: /* @__PURE__ */
|
|
84
|
+
children: /* @__PURE__ */ f("div", {
|
|
83
85
|
className: "p-8 text-center text-[var(--color-text-secondary)]",
|
|
84
|
-
children:
|
|
86
|
+
children: h("workspaces.edit.noPermission", "You don't have permission to edit workspaces.")
|
|
85
87
|
})
|
|
86
88
|
});
|
|
87
89
|
}
|
|
88
90
|
//#endregion
|
|
89
|
-
export {
|
|
91
|
+
export { h as WorkspaceEditPage };
|
|
90
92
|
|
|
91
93
|
//# sourceMappingURL=WorkspaceEditPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkspaceEditPage.js","names":[],"sources":["../../../../../src/organization-management/modules/workspaces/pages/WorkspaceEditPage.tsx"],"sourcesContent":["import { useParams } from 'react-router-dom';\nimport { ArrowLeft } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useOrgConsole } from '../../../providers/OrgConsoleProvider';\nimport { useWorkspace, useUpdateWorkspace } from '../hooks/useWorkspaces';\nimport { WorkspaceForm } from '../components/WorkspaceForm';\nimport { LoadingState } from '../../../shared/components/feedback/LoadingState';\nimport { ErrorState } from '../../../shared/components/feedback/ErrorState';\nimport { PERMISSIONS } from '../../../constants/permissions';\nimport { useTr } from '../../../shared/hooks/useTr';\nimport type { UpdateWorkspaceInput } from '../types';\n\nexport function WorkspaceEditPage() {\n const tr = useTr();\n const { id } = useParams<{ id: string }>();\n const { navigate, basePath = '/organizations' } = useOrgConsole();\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const { workspace, loading: fetchLoading, error } = useWorkspace(id!);\n const { updateWorkspace, loading: updateLoading } = useUpdateWorkspace();\n\n const handleSubmit = async (data: UpdateWorkspaceInput) => {\n if (!id) return;\n\n try {\n const result = await updateWorkspace(id, data);\n if (result.errors?.length) {\n throw new Error(\n result.errors[0]?.message ?? tr('workspaces.edit.failed', 'Failed to update workspace')\n );\n }\n\n toast.success(tr('workspaces.edit.success', 'Workspace updated successfully'));\n navigate(`${basePath}/workspaces/${id}`);\n } catch (error) {\n toast.error(\n error instanceof Error\n ? error.message\n : tr('workspaces.edit.failed', 'Failed to update workspace')\n );\n }\n };\n\n const handleCancel = () => {\n navigate(`${basePath}/workspaces/${id}`);\n };\n\n if (permissionsLoading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <LoadingState message={tr('common.loadingPermissions', 'Loading permissions...')} />\n </div>\n );\n }\n\n if (!hasPermission(PERMISSIONS.WORKSPACE_UPDATE)) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <div className=\"p-8 text-center text-[var(--color-text-secondary)]\">\n {tr('workspaces.edit.noPermission', \"You don't have permission to edit workspaces.\")}\n </div>\n </div>\n );\n }\n\n if (fetchLoading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <LoadingState message={tr('workspaces.edit.loading', 'Loading workspace...')} />\n </div>\n );\n }\n\n if (error || !workspace) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <ErrorState\n message={error?.message || tr('workspaces.detail.notFound', 'Workspace not found')}\n action={{\n label: tr('workspaces.create.backToWorkspaces', 'Back to Workspaces'),\n onClick: () => navigate(`${basePath}/workspaces`),\n }}\n />\n </div>\n );\n }\n\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6 animate-in fade-in duration-
|
|
1
|
+
{"version":3,"file":"WorkspaceEditPage.js","names":[],"sources":["../../../../../src/organization-management/modules/workspaces/pages/WorkspaceEditPage.tsx"],"sourcesContent":["import { useParams } from 'react-router-dom';\nimport { ArrowLeft } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useOrgConsole } from '../../../providers/OrgConsoleProvider';\nimport { useWorkspace, useUpdateWorkspace } from '../hooks/useWorkspaces';\nimport { WorkspaceForm } from '../components/WorkspaceForm';\nimport { LoadingState } from '../../../shared/components/feedback/LoadingState';\nimport { ErrorState } from '../../../shared/components/feedback/ErrorState';\nimport { PERMISSIONS } from '../../../constants/permissions';\nimport { useTr } from '../../../shared/hooks/useTr';\nimport type { UpdateWorkspaceInput } from '../types';\n\nexport function WorkspaceEditPage() {\n const tr = useTr();\n const { id } = useParams<{ id: string }>();\n const { navigate, basePath = '/organizations' } = useOrgConsole();\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const { workspace, loading: fetchLoading, error } = useWorkspace(id!);\n const { updateWorkspace, loading: updateLoading } = useUpdateWorkspace();\n\n const handleSubmit = async (data: UpdateWorkspaceInput) => {\n if (!id) return;\n\n try {\n const result = await updateWorkspace(id, data);\n if (result.errors?.length) {\n throw new Error(\n result.errors[0]?.message ?? tr('workspaces.edit.failed', 'Failed to update workspace')\n );\n }\n\n toast.success(tr('workspaces.edit.success', 'Workspace updated successfully'));\n navigate(`${basePath}/workspaces/${id}`);\n } catch (error) {\n toast.error(\n error instanceof Error\n ? error.message\n : tr('workspaces.edit.failed', 'Failed to update workspace')\n );\n }\n };\n\n const handleCancel = () => {\n navigate(`${basePath}/workspaces/${id}`);\n };\n\n if (permissionsLoading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <LoadingState message={tr('common.loadingPermissions', 'Loading permissions...')} />\n </div>\n );\n }\n\n if (!hasPermission(PERMISSIONS.WORKSPACE_UPDATE)) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <div className=\"p-8 text-center text-[var(--color-text-secondary)]\">\n {tr('workspaces.edit.noPermission', \"You don't have permission to edit workspaces.\")}\n </div>\n </div>\n );\n }\n\n if (fetchLoading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <LoadingState message={tr('workspaces.edit.loading', 'Loading workspace...')} />\n </div>\n );\n }\n\n if (error || !workspace) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <ErrorState\n message={error?.message || tr('workspaces.detail.notFound', 'Workspace not found')}\n action={{\n label: tr('workspaces.create.backToWorkspaces', 'Back to Workspaces'),\n onClick: () => navigate(`${basePath}/workspaces`),\n }}\n />\n </div>\n );\n }\n\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6 animate-in fade-in duration-200\">\n <div className=\"mb-6\">\n <button\n type=\"button\"\n onClick={handleCancel}\n className=\"\n inline-flex items-center gap-2 mb-4\n text-[var(--color-text-secondary)]\n hover:text-[var(--color-text-primary)]\n \n transition-all duration-200\n \"\n >\n <ArrowLeft size={20} />\n <span className=\"text-sm font-medium\">\n {tr('common.backTo', 'Back to')} {workspace.name}\n </span>\n </button>\n\n <h1 className=\"text-3xl font-bold text-[var(--color-text-primary)] mb-2\">\n {tr('workspaces.edit.title', 'Edit Workspace')}\n </h1>\n <p className=\"text-[var(--color-text-secondary)]\">\n {tr('workspaces.edit.subtitle', 'Update workspace information')}\n </p>\n </div>\n\n <div className=\"max-w-2xl\">\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-6\">\n <WorkspaceForm\n workspace={workspace}\n onSubmit={handleSubmit}\n onCancel={handleCancel}\n loading={updateLoading}\n />\n </GlassCard>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAcA,SAAgB,IAAoB;CAClC,IAAM,IAAK,GAAO,EACZ,EAAE,UAAO,GAA2B,EACpC,EAAE,aAAU,cAAW,qBAAqB,GAAe,EAC3D,EAAE,kBAAe,WAAW,MAAuB,GAAgB,EACnE,EAAE,cAAW,SAAS,GAAc,aAAU,EAAa,EAAI,EAC/D,EAAE,oBAAiB,SAAS,MAAkB,GAAoB,EAElE,IAAe,OAAO,MAA+B;AACpD,QAEL,KAAI;GACF,IAAM,IAAS,MAAM,EAAgB,GAAI,EAAK;AAC9C,OAAI,EAAO,QAAQ,OACjB,OAAU,MACR,EAAO,OAAO,IAAI,WAAW,EAAG,0BAA0B,6BAA6B,CACxF;AAIH,GADA,EAAM,QAAQ,EAAG,2BAA2B,iCAAiC,CAAC,EAC9E,EAAS,GAAG,EAAS,cAAc,IAAK;WACjC,GAAO;AACd,KAAM,MACJ,aAAiB,QACb,EAAM,UACN,EAAG,0BAA0B,6BAA6B,CAC/D;;IAIC,UAAqB;AACzB,IAAS,GAAG,EAAS,cAAc,IAAK;;AA2C1C,QAxCI,IAEA,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD,EAAc,SAAS,EAAG,6BAA6B,yBAAyB,EAAI,CAAA;EAChF,CAAA,GAIL,EAAc,EAAY,iBAAiB,GAU5C,IAEA,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD,EAAc,SAAS,EAAG,2BAA2B,uBAAuB,EAAI,CAAA;EAC5E,CAAA,GAIN,KAAS,CAAC,IAEV,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD;GACE,SAAS,GAAO,WAAW,EAAG,8BAA8B,sBAAsB;GAClF,QAAQ;IACN,OAAO,EAAG,sCAAsC,qBAAqB;IACrE,eAAe,EAAS,GAAG,EAAS,aAAa;IAClD;GACD,CAAA;EACE,CAAA,GAKR,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,UAAD;KACE,MAAK;KACL,SAAS;KACT,WAAU;eAHZ,CAWE,kBAAC,GAAD,EAAW,MAAM,IAAM,CAAA,EACvB,kBAAC,QAAD;MAAM,WAAU;gBAAhB;OACG,EAAG,iBAAiB,UAAU;OAAC;OAAE,EAAU;OACvC;QACA;;IAET,kBAAC,MAAD;KAAI,WAAU;eACX,EAAG,yBAAyB,iBAAiB;KAC3C,CAAA;IACL,kBAAC,KAAD;KAAG,WAAU;eACV,EAAG,4BAA4B,+BAA+B;KAC7D,CAAA;IACA;MAEN,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,GAAD;IAAW,WAAU;IAAQ,WAAU;cACrC,kBAAC,GAAD;KACa;KACX,UAAU;KACV,UAAU;KACV,SAAS;KACT,CAAA;IACQ,CAAA;GACR,CAAA,CACF;MApEJ,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAG,gCAAgC,gDAAgD;GAChF,CAAA;EACF,CAAA"}
|