@burdenoff/microfe-workspaces 2026.1006.1 → 2026.1013.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/WorkspacesRoot.js +0 -2
- package/dist/WorkspacesRoutes.js +0 -2
- package/dist/components/CreateProjectDialog.js +0 -2
- package/dist/components/CreateWorkspaceDialog.js +0 -2
- package/dist/components/InviteMemberDialog.js +0 -2
- package/dist/components/MemberListItem.js +0 -2
- package/dist/components/ProjectCard.js +0 -2
- package/dist/components/ProjectMemberPickerDialog.js +0 -2
- package/dist/components/RenameProjectDialog.js +0 -2
- package/dist/components/WorkspaceCard.js +0 -2
- package/dist/components/WorkspaceContextPathSync.js +0 -2
- package/dist/components/WorkspacesErrorBoundary.js +0 -2
- package/dist/components/tags/ProjectTagsWidget.js +0 -2
- package/dist/constants/permissions.js +0 -2
- package/dist/generated/global-operations.js +0 -2
- package/dist/generated/wspace-operations.js +0 -2
- package/dist/hooks/useMemberMutations.js +0 -2
- package/dist/hooks/useOrgsWithPermission.js +0 -2
- package/dist/hooks/usePendingInvitations.js +0 -2
- package/dist/hooks/useProjectMemberMutations.js +0 -2
- package/dist/hooks/useProjectMembers.js +0 -2
- package/dist/hooks/useProjectMutations.js +0 -2
- package/dist/hooks/useProjects.js +0 -2
- package/dist/hooks/useScopedNavigation.js +0 -2
- package/dist/hooks/useTenants.js +0 -2
- package/dist/hooks/useTr.js +0 -2
- package/dist/hooks/useWorkspaceActivity.js +0 -2
- package/dist/hooks/useWorkspaceMembers.js +0 -2
- package/dist/hooks/useWorkspaceMutations.js +0 -2
- package/dist/hooks/useWorkspacePermissions.js +0 -2
- package/dist/hooks/useWorkspaceRoles.js +0 -2
- package/dist/hooks/useWorkspaces.js +0 -2
- package/dist/hooks/useWorkspacesEventEmitter.js +0 -2
- package/dist/hooks/useWorkspacesPageView.js +0 -2
- package/dist/pages/ActivityListPage.js +0 -2
- package/dist/pages/CreateWorkspacePage.js +0 -2
- package/dist/pages/InviteAcceptancePage.js +0 -2
- package/dist/pages/MembersListPage.js +0 -2
- package/dist/pages/PendingInvitesPage.js +0 -2
- package/dist/pages/ProjectDetailPage.js +0 -2
- package/dist/pages/ProjectMembersPage.js +0 -2
- package/dist/pages/ProjectsListPage.js +0 -2
- package/dist/pages/WorkspaceDetailPage.js +0 -2
- package/dist/pages/WorkspaceInvitePage.js +0 -2
- package/dist/pages/WorkspaceSettingsPage.js +0 -2
- package/dist/pages/WorkspacesListPage.js +0 -2
- package/dist/pages/dashboard/DashboardCustomizer.js +0 -2
- package/dist/pages/dashboard/DashboardGrid.js +0 -2
- package/dist/pages/dashboard/DashboardPage.js +0 -2
- package/dist/pages/dashboard/WidgetWrapper.js +0 -2
- package/dist/pages/dashboard/config.js +0 -2
- package/dist/pages/dashboard/hooks/useDashboardData.js +0 -2
- package/dist/pages/dashboard/hooks/useDashboardPreferences.js +0 -2
- package/dist/pages/dashboard/reorder.js +0 -2
- package/dist/pages/dashboard/widgets/AgentsWidget.js +0 -2
- package/dist/pages/dashboard/widgets/GroupsWidget.js +0 -2
- package/dist/pages/dashboard/widgets/MembersWidget.js +0 -2
- package/dist/pages/dashboard/widgets/ProjectsWidget.js +0 -2
- package/dist/pages/dashboard/widgets/QuickActionsWidget.js +0 -2
- package/dist/pages/dashboard/widgets/RecentActivityWidget.js +0 -2
- package/dist/pages/dashboard/widgets/SessionsWidget.js +0 -2
- package/dist/pages/dashboard/widgets/StorageWidget.js +0 -2
- package/dist/pages/dashboard/widgets/TagCloudWidget.js +0 -2
- package/dist/pages/dashboard/widgets/TipsWidget.js +0 -2
- package/dist/pages/dashboard/widgets/UpcomingEventsWidget.js +0 -2
- package/dist/pages/dashboard/widgets/VibesWidget.js +0 -2
- package/dist/pages/dashboard/widgets/WelcomeWidget.js +0 -2
- package/dist/pages/dashboard/widgets/WorkflowRunsWidget.js +0 -2
- package/dist/pages/dashboard/widgets/WorkflowStatsWidget.js +0 -2
- package/dist/pages/dashboard/widgets/WorkflowsOverviewWidget.js +0 -2
- package/dist/pages/dashboard/widgets/WorkspacesWidget.js +0 -2
- package/dist/providers/WorkspacesProvider.js +0 -2
- package/dist/store/workspacesStore.js +0 -2
- package/dist/translations/en.js +0 -2
- package/dist/utils/formatters.js +0 -2
- package/dist/utils/i18n.js +0 -2
- package/dist/utils/invitationDisplay.js +0 -2
- package/dist/utils/projectTags.js +0 -2
- package/dist/utils/slug.js +0 -2
- package/dist/utils/telemetryError.js +0 -2
- package/dist/utils/tokenHelpers.js +0 -2
- package/dist/utils/workspaceBulkInviteCsv.js +0 -2
- package/package.json +3 -2
- package/dist/WorkspacesRoot.js.map +0 -1
- package/dist/WorkspacesRoutes.js.map +0 -1
- package/dist/components/CreateProjectDialog.js.map +0 -1
- package/dist/components/CreateWorkspaceDialog.js.map +0 -1
- package/dist/components/InviteMemberDialog.js.map +0 -1
- package/dist/components/MemberListItem.js.map +0 -1
- package/dist/components/ProjectCard.js.map +0 -1
- package/dist/components/ProjectMemberPickerDialog.js.map +0 -1
- package/dist/components/RenameProjectDialog.js.map +0 -1
- package/dist/components/WorkspaceCard.js.map +0 -1
- package/dist/components/WorkspaceContextPathSync.js.map +0 -1
- package/dist/components/WorkspacesErrorBoundary.js.map +0 -1
- package/dist/components/tags/ProjectTagsWidget.js.map +0 -1
- package/dist/constants/permissions.js.map +0 -1
- package/dist/generated/global-operations.js.map +0 -1
- package/dist/generated/wspace-operations.js.map +0 -1
- package/dist/hooks/useMemberMutations.js.map +0 -1
- package/dist/hooks/useOrgsWithPermission.js.map +0 -1
- package/dist/hooks/usePendingInvitations.js.map +0 -1
- package/dist/hooks/useProjectMemberMutations.js.map +0 -1
- package/dist/hooks/useProjectMembers.js.map +0 -1
- package/dist/hooks/useProjectMutations.js.map +0 -1
- package/dist/hooks/useProjects.js.map +0 -1
- package/dist/hooks/useScopedNavigation.js.map +0 -1
- package/dist/hooks/useTenants.js.map +0 -1
- package/dist/hooks/useTr.js.map +0 -1
- package/dist/hooks/useWorkspaceActivity.js.map +0 -1
- package/dist/hooks/useWorkspaceMembers.js.map +0 -1
- package/dist/hooks/useWorkspaceMutations.js.map +0 -1
- package/dist/hooks/useWorkspacePermissions.js.map +0 -1
- package/dist/hooks/useWorkspaceRoles.js.map +0 -1
- package/dist/hooks/useWorkspaces.js.map +0 -1
- package/dist/hooks/useWorkspacesEventEmitter.js.map +0 -1
- package/dist/hooks/useWorkspacesPageView.js.map +0 -1
- package/dist/pages/ActivityListPage.js.map +0 -1
- package/dist/pages/CreateWorkspacePage.js.map +0 -1
- package/dist/pages/InviteAcceptancePage.js.map +0 -1
- package/dist/pages/MembersListPage.js.map +0 -1
- package/dist/pages/PendingInvitesPage.js.map +0 -1
- package/dist/pages/ProjectDetailPage.js.map +0 -1
- package/dist/pages/ProjectMembersPage.js.map +0 -1
- package/dist/pages/ProjectsListPage.js.map +0 -1
- package/dist/pages/WorkspaceDetailPage.js.map +0 -1
- package/dist/pages/WorkspaceInvitePage.js.map +0 -1
- package/dist/pages/WorkspaceSettingsPage.js.map +0 -1
- package/dist/pages/WorkspacesListPage.js.map +0 -1
- package/dist/pages/dashboard/DashboardCustomizer.js.map +0 -1
- package/dist/pages/dashboard/DashboardGrid.js.map +0 -1
- package/dist/pages/dashboard/DashboardPage.js.map +0 -1
- package/dist/pages/dashboard/WidgetWrapper.js.map +0 -1
- package/dist/pages/dashboard/config.js.map +0 -1
- package/dist/pages/dashboard/hooks/useDashboardData.js.map +0 -1
- package/dist/pages/dashboard/hooks/useDashboardPreferences.js.map +0 -1
- package/dist/pages/dashboard/reorder.js.map +0 -1
- package/dist/pages/dashboard/widgets/AgentsWidget.js.map +0 -1
- package/dist/pages/dashboard/widgets/GroupsWidget.js.map +0 -1
- package/dist/pages/dashboard/widgets/MembersWidget.js.map +0 -1
- package/dist/pages/dashboard/widgets/ProjectsWidget.js.map +0 -1
- package/dist/pages/dashboard/widgets/QuickActionsWidget.js.map +0 -1
- package/dist/pages/dashboard/widgets/RecentActivityWidget.js.map +0 -1
- package/dist/pages/dashboard/widgets/SessionsWidget.js.map +0 -1
- package/dist/pages/dashboard/widgets/StorageWidget.js.map +0 -1
- package/dist/pages/dashboard/widgets/TagCloudWidget.js.map +0 -1
- package/dist/pages/dashboard/widgets/TipsWidget.js.map +0 -1
- package/dist/pages/dashboard/widgets/UpcomingEventsWidget.js.map +0 -1
- package/dist/pages/dashboard/widgets/VibesWidget.js.map +0 -1
- package/dist/pages/dashboard/widgets/WelcomeWidget.js.map +0 -1
- package/dist/pages/dashboard/widgets/WorkflowRunsWidget.js.map +0 -1
- package/dist/pages/dashboard/widgets/WorkflowStatsWidget.js.map +0 -1
- package/dist/pages/dashboard/widgets/WorkflowsOverviewWidget.js.map +0 -1
- package/dist/pages/dashboard/widgets/WorkspacesWidget.js.map +0 -1
- package/dist/providers/WorkspacesProvider.js.map +0 -1
- package/dist/store/workspacesStore.js.map +0 -1
- package/dist/translations/en.js.map +0 -1
- package/dist/utils/formatters.js.map +0 -1
- package/dist/utils/i18n.js.map +0 -1
- package/dist/utils/invitationDisplay.js.map +0 -1
- package/dist/utils/projectTags.js.map +0 -1
- package/dist/utils/slug.js.map +0 -1
- package/dist/utils/telemetryError.js.map +0 -1
- package/dist/utils/tokenHelpers.js.map +0 -1
- package/dist/utils/workspaceBulkInviteCsv.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"WorkflowRunsWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/WorkflowRunsWidget.tsx"],"sourcesContent":["import { Activity, ArrowRight, Play, Clock, CheckCircle2, XCircle } from 'lucide-react';\nimport { Badge, Button, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport type { I18nContextValue } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport { tWithFallback } from '../../../utils/i18n';\nimport type { WidgetProps } from '../types';\n\nconst RUN_STATUS_ICON: Record<string, { icon: typeof Play; color: string }> = {\n RUNNING: { icon: Play, color: 'text-accent-blue' },\n PENDING: { icon: Clock, color: 'text-status-warning-text' },\n WAITING: { icon: Clock, color: 'text-status-warning-text' },\n COMPLETED: { icon: CheckCircle2, color: 'text-status-success-text' },\n FAILED: { icon: XCircle, color: 'text-status-error-text' },\n CANCELLED: { icon: XCircle, color: 'text-text-tertiary' },\n TERMINATED: { icon: XCircle, color: 'text-text-tertiary' },\n};\n\nfunction formatRelative(t: I18nContextValue['t'], dateString: string): string {\n const diffMs = Date.now() - new Date(dateString).getTime();\n const diffMin = Math.floor(diffMs / 60000);\n if (diffMin < 1) return tWithFallback(t, 'dashboard.workflowRuns.justNow', 'just now');\n if (diffMin < 60)\n return tWithFallback(t, 'dashboard.workflowRuns.minutesAgo', '{count}m ago', {\n count: diffMin,\n });\n const diffHr = Math.floor(diffMin / 60);\n if (diffHr < 24)\n return tWithFallback(t, 'dashboard.workflowRuns.hoursAgo', '{count}h ago', { count: diffHr });\n return new Date(dateString).toLocaleDateString(undefined, {\n month: 'short',\n day: 'numeric',\n });\n}\n\nexport function WorkflowRunsWidget({ workspaceData, isLoading, navigate }: WidgetProps) {\n const { t } = useI18n();\n const stats = workspaceData?.workflowStats;\n const recentRuns = stats?.recentRuns ?? [];\n const successRate = stats?.workflowSuccessRate;\n\n return (\n <WidgetWrapper\n title={tWithFallback(t, 'dashboard.workflowRuns.title', 'Workflow Runs')}\n icon={<Activity className=\"size-4\" />}\n size=\"medium\"\n isLoading={isLoading}\n unavailable={!workspaceData}\n headerAction={\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-xs\"\n onClick={() => navigate('/workflows/runs')}\n >\n {tWithFallback(t, 'dashboard.workflowRuns.viewAll', 'View all')}{' '}\n <ArrowRight className=\"ml-1 size-3\" />\n </Button>\n }\n >\n {!stats ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={tWithFallback(t, 'dashboard.workflowRuns.emptyTitle', 'No runs yet')}\n description={tWithFallback(\n t,\n 'dashboard.workflowRuns.emptyDescription',\n 'Trigger a workflow to see its execution history here.'\n )}\n className=\"py-4\"\n />\n ) : (\n <div className=\"space-y-3\">\n <div className=\"grid grid-cols-3 gap-2\">\n <div className=\"rounded-lg bg-bg-canvas p-2.5 border border-border-default text-center\">\n <p className=\"text-xl font-bold text-text-primary tabular-nums\">\n {stats.runsRunningCount ?? 0}\n </p>\n <p className=\"text-[11px] text-text-secondary\">\n {tWithFallback(t, 'dashboard.workflowRuns.statRunning', 'Running')}\n </p>\n </div>\n <div className=\"rounded-lg bg-bg-canvas p-2.5 border border-border-default text-center\">\n <p className=\"text-xl font-bold text-status-error-text tabular-nums\">\n {stats.runsFailedLast24h ?? 0}\n </p>\n <p className=\"text-[11px] text-text-secondary\">\n {tWithFallback(t, 'dashboard.workflowRuns.statFailed24h', 'Failed (24h)')}\n </p>\n </div>\n <div className=\"rounded-lg bg-bg-canvas p-2.5 border border-border-default text-center\">\n <p className=\"text-xl font-bold text-status-success-text tabular-nums\">\n {successRate != null ? `${Math.round(successRate)}%` : '—'}\n </p>\n <p className=\"text-[11px] text-text-secondary\">\n {tWithFallback(t, 'dashboard.workflowRuns.statSuccessRate', 'Success rate')}\n </p>\n </div>\n </div>\n {recentRuns.length > 0 && (\n <div className=\"space-y-1.5\">\n <p className=\"text-xs font-medium text-text-secondary uppercase tracking-wider\">\n {tWithFallback(t, 'dashboard.workflowRuns.recentRunsHeading', 'Recent Runs')}\n </p>\n {recentRuns.slice(0, 4).map((run) => {\n const statusInfo = RUN_STATUS_ICON[run.status] ?? RUN_STATUS_ICON.RUNNING;\n const StatusIcon = statusInfo.icon;\n return (\n <button\n key={run.id}\n type=\"button\"\n onClick={() => navigate(`/workflows/runs/${run.id}`)}\n className=\"flex w-full items-center justify-between gap-2 rounded-md p-1.5 text-left transition-colors hover:bg-accent/5\"\n >\n <div className=\"flex items-center gap-2 min-w-0\">\n <StatusIcon className={`size-3.5 shrink-0 ${statusInfo.color}`} />\n <span className=\"truncate text-sm text-text-primary\">{run.workflowKey}</span>\n </div>\n <div className=\"flex items-center gap-2 shrink-0\">\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {run.status.toLowerCase()}\n </Badge>\n <span className=\"text-[11px] text-text-secondary\">\n {formatRelative(t, run.startedAt)}\n </span>\n </div>\n </button>\n );\n })}\n </div>\n )}\n </div>\n )}\n </WidgetWrapper>\n );\n}\n"],"mappings":";;;;;;;AAQA,IAAM,IAAwE;CAC5E,SAAS;EAAE,MAAM;EAAM,OAAO;EAAoB;CAClD,SAAS;EAAE,MAAM;EAAO,OAAO;EAA4B;CAC3D,SAAS;EAAE,MAAM;EAAO,OAAO;EAA4B;CAC3D,WAAW;EAAE,MAAM;EAAc,OAAO;EAA4B;CACpE,QAAQ;EAAE,MAAM;EAAS,OAAO;EAA0B;CAC1D,WAAW;EAAE,MAAM;EAAS,OAAO;EAAsB;CACzD,YAAY;EAAE,MAAM;EAAS,OAAO;EAAsB;CAC3D;AAED,SAAS,EAAe,GAA0B,GAA4B;CAC5E,IAAM,IAAS,KAAK,KAAK,GAAG,IAAI,KAAK,EAAW,CAAC,SAAS,EACpD,IAAU,KAAK,MAAM,IAAS,IAAM;AAC1C,KAAI,IAAU,EAAG,QAAO,EAAc,GAAG,kCAAkC,WAAW;AACtF,KAAI,IAAU,GACZ,QAAO,EAAc,GAAG,qCAAqC,gBAAgB,EAC3E,OAAO,GACR,CAAC;CACJ,IAAM,IAAS,KAAK,MAAM,IAAU,GAAG;AAGvC,QAFI,IAAS,KACJ,EAAc,GAAG,mCAAmC,gBAAgB,EAAE,OAAO,GAAQ,CAAC,GACxF,IAAI,KAAK,EAAW,CAAC,mBAAmB,KAAA,GAAW;EACxD,OAAO;EACP,KAAK;EACN,CAAC;;AAGJ,SAAgB,EAAmB,EAAE,kBAAe,cAAW,eAAyB;CACtF,IAAM,EAAE,SAAM,GAAS,EACjB,IAAQ,GAAe,eACvB,IAAa,GAAO,cAAc,EAAE,EACpC,IAAc,GAAO;AAE3B,QACE,kBAAC,GAAD;EACE,OAAO,EAAc,GAAG,gCAAgC,gBAAgB;EACxE,MAAM,kBAAC,GAAD,EAAU,WAAU,UAAW,CAAA;EACrC,MAAK;EACM;EACX,aAAa,CAAC;EACd,cACE,kBAAC,GAAD;GACE,SAAQ;GACR,MAAK;GACL,WAAU;GACV,eAAe,EAAS,kBAAkB;aAJ5C;IAMG,EAAc,GAAG,kCAAkC,WAAW;IAAE;IACjE,kBAAC,GAAD,EAAY,WAAU,eAAgB,CAAA;IAC/B;;YAGT,IAYA,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAM,oBAAoB;OACzB,CAAA,EACJ,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAc,GAAG,sCAAsC,UAAU;OAChE,CAAA,CACA;;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAM,qBAAqB;OAC1B,CAAA,EACJ,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAc,GAAG,wCAAwC,eAAe;OACvE,CAAA,CACA;;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,KAAD;OAAG,WAAU;iBACV,KAAe,OAAuC,MAAhC,GAAG,KAAK,MAAM,EAAY,CAAC;OAChD,CAAA,EACJ,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAc,GAAG,0CAA0C,eAAe;OACzE,CAAA,CACA;;KACF;OACL,EAAW,SAAS,KACnB,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,KAAD;KAAG,WAAU;eACV,EAAc,GAAG,4CAA4C,cAAc;KAC1E,CAAA,EACH,EAAW,MAAM,GAAG,EAAE,CAAC,KAAK,MAAQ;KACnC,IAAM,IAAa,EAAgB,EAAI,WAAW,EAAgB,SAC5D,IAAa,EAAW;AAC9B,YACE,kBAAC,UAAD;MAEE,MAAK;MACL,eAAe,EAAS,mBAAmB,EAAI,KAAK;MACpD,WAAU;gBAJZ,CAME,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAY,WAAW,qBAAqB,EAAW,SAAW,CAAA,EAClE,kBAAC,QAAD;QAAM,WAAU;kBAAsC,EAAI;QAAmB,CAAA,CACzE;UACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD;QAAO,SAAQ;QAAU,WAAU;kBAChC,EAAI,OAAO,aAAa;QACnB,CAAA,EACR,kBAAC,QAAD;QAAM,WAAU;kBACb,EAAe,GAAG,EAAI,UAAU;QAC5B,CAAA,CACH;SACC;QAjBF,EAAI,GAiBF;MAEX,CACE;MAEJ;OAtEN,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAc,GAAG,qCAAqC,cAAc;GAC3E,aAAa,EACX,GACA,2CACA,wDACD;GACD,WAAU;GACV,CAAA;EA+DU,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"WorkflowStatsWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/WorkflowStatsWidget.tsx"],"sourcesContent":["import { GitBranch, ArrowRight, Play, Pause, CheckCircle2, XCircle } from 'lucide-react';\nimport { Badge, Button, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport { tWithFallback } from '../../../utils/i18n';\nimport type { WidgetProps } from '../types';\n\nconst runStatusIcons: Record<string, { icon: typeof Play; color: string }> = {\n RUNNING: { icon: Play, color: 'text-accent-blue' },\n COMPLETED: { icon: CheckCircle2, color: 'text-status-success-text' },\n FAILED: { icon: XCircle, color: 'text-status-error-text' },\n PAUSED: { icon: Pause, color: 'text-status-warning-text' },\n};\n\nexport function WorkflowStatsWidget({ workspaceData, isLoading, navigate }: WidgetProps) {\n const { t } = useI18n();\n const stats = workspaceData?.workflowStats;\n\n return (\n <WidgetWrapper\n title={tWithFallback(t, 'dashboard.workflowStats.title', 'Workflows')}\n icon={<GitBranch className=\"size-4\" />}\n size=\"medium\"\n isLoading={isLoading}\n unavailable={!workspaceData}\n headerAction={\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-xs\"\n onClick={() => navigate('/workflows')}\n >\n {tWithFallback(t, 'dashboard.workflowStats.viewAll', 'View all')}{' '}\n <ArrowRight className=\"ml-1 size-3\" />\n </Button>\n }\n >\n {!stats ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={tWithFallback(\n t,\n 'dashboard.workflowStats.emptyTitle',\n 'No workflow data available'\n )}\n description={tWithFallback(\n t,\n 'dashboard.workflowStats.emptyDescription',\n 'Once you run automations, their status and counts will appear here.'\n )}\n className=\"py-4\"\n />\n ) : (\n <div className=\"space-y-3\">\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"rounded-lg bg-bg-canvas p-3 border border-border-default text-center\">\n <p className=\"text-2xl font-bold text-text-primary tabular-nums\">\n {stats.activeWorkflowsCount}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {tWithFallback(t, 'dashboard.workflowStats.statActive', 'Active')}\n </p>\n </div>\n <div className=\"rounded-lg bg-bg-canvas p-3 border border-border-default text-center\">\n <p className=\"text-2xl font-bold text-text-primary tabular-nums\">\n {stats.archivedWorkflowsCount}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {tWithFallback(t, 'dashboard.workflowStats.statArchived', 'Archived')}\n </p>\n </div>\n </div>\n {stats.recentRuns.length > 0 && (\n <div className=\"space-y-1.5\">\n <p className=\"text-xs font-medium text-text-secondary uppercase tracking-wider\">\n {tWithFallback(t, 'dashboard.workflowStats.recentRunsHeading', 'Recent Runs')}\n </p>\n {stats.recentRuns.slice(0, 3).map((run) => {\n const statusInfo = runStatusIcons[run.status] || runStatusIcons.RUNNING;\n const StatusIcon = statusInfo.icon;\n return (\n <div\n key={run.id}\n className=\"flex items-center justify-between p-1.5 rounded hover:bg-accent/5 transition-colors\"\n >\n <div className=\"flex items-center gap-2 min-w-0\">\n <StatusIcon className={`size-3.5 ${statusInfo.color}`} />\n <span className=\"text-sm text-text-primary truncate\">{run.workflowKey}</span>\n </div>\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {run.status}\n </Badge>\n </div>\n );\n })}\n </div>\n )}\n </div>\n )}\n </WidgetWrapper>\n );\n}\n"],"mappings":";;;;;;;AAOA,IAAM,IAAuE;CAC3E,SAAS;EAAE,MAAM;EAAM,OAAO;EAAoB;CAClD,WAAW;EAAE,MAAM;EAAc,OAAO;EAA4B;CACpE,QAAQ;EAAE,MAAM;EAAS,OAAO;EAA0B;CAC1D,QAAQ;EAAE,MAAM;EAAO,OAAO;EAA4B;CAC3D;AAED,SAAgB,EAAoB,EAAE,kBAAe,cAAW,eAAyB;CACvF,IAAM,EAAE,SAAM,GAAS,EACjB,IAAQ,GAAe;AAE7B,QACE,kBAAC,GAAD;EACE,OAAO,EAAc,GAAG,iCAAiC,YAAY;EACrE,MAAM,kBAAC,GAAD,EAAW,WAAU,UAAW,CAAA;EACtC,MAAK;EACM;EACX,aAAa,CAAC;EACd,cACE,kBAAC,GAAD;GACE,SAAQ;GACR,MAAK;GACL,WAAU;GACV,eAAe,EAAS,aAAa;aAJvC;IAMG,EAAc,GAAG,mCAAmC,WAAW;IAAE;IAClE,kBAAC,GAAD,EAAY,WAAU,eAAgB,CAAA;IAC/B;;YAGT,IAgBA,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAM;MACL,CAAA,EACJ,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAc,GAAG,sCAAsC,SAAS;MAC/D,CAAA,CACA;QACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAM;MACL,CAAA,EACJ,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAc,GAAG,wCAAwC,WAAW;MACnE,CAAA,CACA;OACF;OACL,EAAM,WAAW,SAAS,KACzB,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,KAAD;KAAG,WAAU;eACV,EAAc,GAAG,6CAA6C,cAAc;KAC3E,CAAA,EACH,EAAM,WAAW,MAAM,GAAG,EAAE,CAAC,KAAK,MAAQ;KACzC,IAAM,IAAa,EAAe,EAAI,WAAW,EAAe,SAC1D,IAAa,EAAW;AAC9B,YACE,kBAAC,OAAD;MAEE,WAAU;gBAFZ,CAIE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAY,WAAW,YAAY,EAAW,SAAW,CAAA,EACzD,kBAAC,QAAD;QAAM,WAAU;kBAAsC,EAAI;QAAmB,CAAA,CACzE;UACN,kBAAC,GAAD;OAAO,SAAQ;OAAU,WAAU;iBAChC,EAAI;OACC,CAAA,CACJ;QAVC,EAAI,GAUL;MAER,CACE;MAEJ;OA3DN,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EACL,GACA,sCACA,6BACD;GACD,aAAa,EACX,GACA,4CACA,sEACD;GACD,WAAU;GACV,CAAA;EAgDU,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"WorkflowsOverviewWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/WorkflowsOverviewWidget.tsx"],"sourcesContent":["import { GitBranch, ArrowRight, Plus } from 'lucide-react';\nimport { Button, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport type { I18nContextValue } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport { tWithFallback } from '../../../utils/i18n';\nimport type { WidgetProps } from '../types';\n\nfunction formatRelative(t: I18nContextValue['t'], dateString: string): string {\n const diffMs = Date.now() - new Date(dateString).getTime();\n const diffMin = Math.floor(diffMs / 60000);\n if (diffMin < 1) return tWithFallback(t, 'dashboard.workflowsOverview.justNow', 'just now');\n if (diffMin < 60)\n return tWithFallback(t, 'dashboard.workflowsOverview.minutesAgo', '{count}m ago', {\n count: diffMin,\n });\n const diffHr = Math.floor(diffMin / 60);\n if (diffHr < 24)\n return tWithFallback(t, 'dashboard.workflowsOverview.hoursAgo', '{count}h ago', {\n count: diffHr,\n });\n const diffDay = Math.floor(diffHr / 24);\n if (diffDay < 7)\n return tWithFallback(t, 'dashboard.workflowsOverview.daysAgo', '{count}d ago', {\n count: diffDay,\n });\n return new Date(dateString).toLocaleDateString(undefined, {\n month: 'short',\n day: 'numeric',\n });\n}\n\nexport function WorkflowsOverviewWidget({ workspaceData, isLoading, navigate }: WidgetProps) {\n const { t } = useI18n();\n const stats = workspaceData?.workflowStats;\n const recentWorkflows = stats?.recentWorkflows ?? [];\n\n return (\n <WidgetWrapper\n title={tWithFallback(t, 'dashboard.workflowsOverview.title', 'Workflows')}\n icon={<GitBranch className=\"size-4\" />}\n size=\"medium\"\n isLoading={isLoading}\n unavailable={!workspaceData}\n headerAction={\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-xs\"\n onClick={() => navigate('/workflows/list')}\n >\n {tWithFallback(t, 'dashboard.workflowsOverview.viewAll', 'View all')}{' '}\n <ArrowRight className=\"ml-1 size-3\" />\n </Button>\n }\n >\n {!stats ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={tWithFallback(t, 'dashboard.workflowsOverview.emptyTitle', 'No workflows yet')}\n description={tWithFallback(\n t,\n 'dashboard.workflowsOverview.emptyDescription',\n 'Build your first workflow to automate a process.'\n )}\n className=\"py-4\"\n action={\n <Button variant=\"outline\" size=\"sm\" onClick={() => navigate('/workflows/new')}>\n <Plus className=\"mr-1.5 size-3.5\" />{' '}\n {tWithFallback(t, 'dashboard.workflowsOverview.emptyAction', 'New Workflow')}\n </Button>\n }\n />\n ) : (\n <div className=\"space-y-3\">\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"rounded-lg bg-bg-canvas p-3 border border-border-default text-center\">\n <p className=\"text-2xl font-bold text-text-primary tabular-nums\">\n {stats.activeWorkflowsCount}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {tWithFallback(t, 'dashboard.workflowsOverview.statActive', 'Active')}\n </p>\n </div>\n <div className=\"rounded-lg bg-bg-canvas p-3 border border-border-default text-center\">\n <p className=\"text-2xl font-bold text-text-primary tabular-nums\">\n {stats.archivedWorkflowsCount}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {tWithFallback(t, 'dashboard.workflowsOverview.statArchived', 'Archived')}\n </p>\n </div>\n </div>\n {recentWorkflows.length > 0 && (\n <div className=\"space-y-1.5\">\n <p className=\"text-xs font-medium text-text-secondary uppercase tracking-wider\">\n {tWithFallback(\n t,\n 'dashboard.workflowsOverview.recentlyUpdatedHeading',\n 'Recently Updated'\n )}\n </p>\n {recentWorkflows.slice(0, 4).map((wf) => (\n <button\n key={`${wf.workflowKey}-${wf.version}`}\n type=\"button\"\n onClick={() => navigate(`/workflows/workflow/${wf.workflowKey}/${wf.version}`)}\n className=\"flex w-full items-center justify-between gap-2 rounded-md p-1.5 text-left transition-colors hover:bg-accent/5\"\n >\n <span className=\"truncate text-sm text-text-primary\">{wf.name}</span>\n <span className=\"shrink-0 text-[11px] text-text-secondary\">\n {formatRelative(t, wf.updatedAt)}\n </span>\n </button>\n ))}\n </div>\n )}\n </div>\n )}\n </WidgetWrapper>\n );\n}\n"],"mappings":";;;;;;;AAQA,SAAS,EAAe,GAA0B,GAA4B;CAC5E,IAAM,IAAS,KAAK,KAAK,GAAG,IAAI,KAAK,EAAW,CAAC,SAAS,EACpD,IAAU,KAAK,MAAM,IAAS,IAAM;AAC1C,KAAI,IAAU,EAAG,QAAO,EAAc,GAAG,uCAAuC,WAAW;AAC3F,KAAI,IAAU,GACZ,QAAO,EAAc,GAAG,0CAA0C,gBAAgB,EAChF,OAAO,GACR,CAAC;CACJ,IAAM,IAAS,KAAK,MAAM,IAAU,GAAG;AACvC,KAAI,IAAS,GACX,QAAO,EAAc,GAAG,wCAAwC,gBAAgB,EAC9E,OAAO,GACR,CAAC;CACJ,IAAM,IAAU,KAAK,MAAM,IAAS,GAAG;AAKvC,QAJI,IAAU,IACL,EAAc,GAAG,uCAAuC,gBAAgB,EAC7E,OAAO,GACR,CAAC,GACG,IAAI,KAAK,EAAW,CAAC,mBAAmB,KAAA,GAAW;EACxD,OAAO;EACP,KAAK;EACN,CAAC;;AAGJ,SAAgB,EAAwB,EAAE,kBAAe,cAAW,eAAyB;CAC3F,IAAM,EAAE,SAAM,GAAS,EACjB,IAAQ,GAAe,eACvB,IAAkB,GAAO,mBAAmB,EAAE;AAEpD,QACE,kBAAC,GAAD;EACE,OAAO,EAAc,GAAG,qCAAqC,YAAY;EACzE,MAAM,kBAAC,GAAD,EAAW,WAAU,UAAW,CAAA;EACtC,MAAK;EACM;EACX,aAAa,CAAC;EACd,cACE,kBAAC,GAAD;GACE,SAAQ;GACR,MAAK;GACL,WAAU;GACV,eAAe,EAAS,kBAAkB;aAJ5C;IAMG,EAAc,GAAG,uCAAuC,WAAW;IAAE;IACtE,kBAAC,GAAD,EAAY,WAAU,eAAgB,CAAA;IAC/B;;YAGT,IAkBA,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAM;MACL,CAAA,EACJ,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAc,GAAG,0CAA0C,SAAS;MACnE,CAAA,CACA;QACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAM;MACL,CAAA,EACJ,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAc,GAAG,4CAA4C,WAAW;MACvE,CAAA,CACA;OACF;OACL,EAAgB,SAAS,KACxB,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,KAAD;KAAG,WAAU;eACV,EACC,GACA,sDACA,mBACD;KACC,CAAA,EACH,EAAgB,MAAM,GAAG,EAAE,CAAC,KAAK,MAChC,kBAAC,UAAD;KAEE,MAAK;KACL,eAAe,EAAS,uBAAuB,EAAG,YAAY,GAAG,EAAG,UAAU;KAC9E,WAAU;eAJZ,CAME,kBAAC,QAAD;MAAM,WAAU;gBAAsC,EAAG;MAAY,CAAA,EACrE,kBAAC,QAAD;MAAM,WAAU;gBACb,EAAe,GAAG,EAAG,UAAU;MAC3B,CAAA,CACA;OATF,GAAG,EAAG,YAAY,GAAG,EAAG,UAStB,CACT,CACE;MAEJ;OA5DN,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAc,GAAG,0CAA0C,mBAAmB;GACrF,aAAa,EACX,GACA,gDACA,mDACD;GACD,WAAU;GACV,QACE,kBAAC,GAAD;IAAQ,SAAQ;IAAU,MAAK;IAAK,eAAe,EAAS,iBAAiB;cAA7E;KACE,kBAAC,GAAD,EAAM,WAAU,mBAAoB,CAAA;KAAC;KACpC,EAAc,GAAG,2CAA2C,eAAe;KACrE;;GAEX,CAAA;EA+CU,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"WorkspacesWidget.js","names":[],"sources":["../../../../src/pages/dashboard/widgets/WorkspacesWidget.tsx"],"sourcesContent":["import { Building2, ArrowRight, Circle } from 'lucide-react';\nimport { Badge, Button, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { WidgetWrapper } from '../WidgetWrapper';\nimport { tWithFallback } from '../../../utils/i18n';\nimport type { WidgetProps } from '../types';\n\nconst statusColors: Record<string, string> = {\n ACTIVE: 'bg-status-success-bg',\n SUSPENDED: 'bg-status-warning-bg',\n ARCHIVED: 'bg-text-tertiary',\n};\n\nexport function WorkspacesWidget({ workspaceData, isLoading, navigate }: WidgetProps) {\n const { t } = useI18n();\n const workspaces = workspaceData?.workspaces.items ?? [];\n const total = workspaceData?.workspaces.total ?? 0;\n\n return (\n <WidgetWrapper\n title={tWithFallback(t, 'dashboard.workspaces.title', 'Workspaces')}\n icon={<Building2 className=\"size-4\" />}\n size=\"medium\"\n isLoading={isLoading}\n unavailable={!workspaceData}\n headerAction={\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-xs\"\n onClick={() => navigate('/workspaces/list')}\n >\n {tWithFallback(t, 'dashboard.workspaces.viewAll', 'View all')}{' '}\n <ArrowRight className=\"ml-1 size-3\" />\n </Button>\n }\n >\n {workspaces.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={tWithFallback(t, 'dashboard.workspaces.emptyTitle', 'No workspaces yet')}\n className=\"py-4\"\n action={\n <Button variant=\"outline\" size=\"sm\" onClick={() => navigate('/workspaces/list')}>\n {tWithFallback(t, 'dashboard.workspaces.emptyAction', 'Create your first workspace')}\n </Button>\n }\n />\n ) : (\n <div className=\"space-y-2\">\n {workspaces.slice(0, 5).map((ws) => (\n <button\n key={ws.id}\n type=\"button\"\n className=\"w-full flex items-center justify-between p-2 rounded-md hover:bg-accent/5 cursor-pointer transition-colors text-left\"\n onClick={() => navigate(`/workspaces/${ws.id}`)}\n >\n <div className=\"flex items-center gap-2 min-w-0\">\n <Circle\n className={`size-2 ${statusColors[ws.status] || 'bg-text-tertiary'} fill-current ${\n ws.status === 'ACTIVE' ? 'motion-safe:animate-vc-glow-pulse' : ''\n }`}\n />\n <span className=\"text-sm font-medium text-text-primary truncate\">{ws.name}</span>\n </div>\n <Badge variant=\"outline\" className=\"text-[10px] shrink-0\">\n {ws.type}\n </Badge>\n </button>\n ))}\n {total > 5 && (\n <p className=\"text-xs text-text-secondary text-center pt-1\">\n {tWithFallback(t, 'dashboard.workspaces.more', '+{count} more workspaces', {\n count: total - 5,\n })}\n </p>\n )}\n </div>\n )}\n </WidgetWrapper>\n );\n}\n"],"mappings":";;;;;;;AAOA,IAAM,IAAuC;CAC3C,QAAQ;CACR,WAAW;CACX,UAAU;CACX;AAED,SAAgB,EAAiB,EAAE,kBAAe,cAAW,eAAyB;CACpF,IAAM,EAAE,SAAM,GAAS,EACjB,IAAa,GAAe,WAAW,SAAS,EAAE,EAClD,IAAQ,GAAe,WAAW,SAAS;AAEjD,QACE,kBAAC,GAAD;EACE,OAAO,EAAc,GAAG,8BAA8B,aAAa;EACnE,MAAM,kBAAC,GAAD,EAAW,WAAU,UAAW,CAAA;EACtC,MAAK;EACM;EACX,aAAa,CAAC;EACd,cACE,kBAAC,GAAD;GACE,SAAQ;GACR,MAAK;GACL,WAAU;GACV,eAAe,EAAS,mBAAmB;aAJ7C;IAMG,EAAc,GAAG,gCAAgC,WAAW;IAAE;IAC/D,kBAAC,GAAD,EAAY,WAAU,eAAgB,CAAA;IAC/B;;YAGV,EAAW,WAAW,IACrB,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAc,GAAG,mCAAmC,oBAAoB;GAC/E,WAAU;GACV,QACE,kBAAC,GAAD;IAAQ,SAAQ;IAAU,MAAK;IAAK,eAAe,EAAS,mBAAmB;cAC5E,EAAc,GAAG,oCAAoC,8BAA8B;IAC7E,CAAA;GAEX,CAAA,GAEF,kBAAC,OAAD;GAAK,WAAU;aAAf,CACG,EAAW,MAAM,GAAG,EAAE,CAAC,KAAK,MAC3B,kBAAC,UAAD;IAEE,MAAK;IACL,WAAU;IACV,eAAe,EAAS,eAAe,EAAG,KAAK;cAJjD,CAME,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD,EACE,WAAW,UAAU,EAAa,EAAG,WAAW,mBAAmB,gBACjE,EAAG,WAAW,WAAW,sCAAsC,MAEjE,CAAA,EACF,kBAAC,QAAD;MAAM,WAAU;gBAAkD,EAAG;MAAY,CAAA,CAC7E;QACN,kBAAC,GAAD;KAAO,SAAQ;KAAU,WAAU;eAChC,EAAG;KACE,CAAA,CACD;MAhBF,EAAG,GAgBD,CACT,EACD,IAAQ,KACP,kBAAC,KAAD;IAAG,WAAU;cACV,EAAc,GAAG,6BAA6B,4BAA4B,EACzE,OAAO,IAAQ,GAChB,CAAC;IACA,CAAA,CAEF;;EAEM,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"WorkspacesProvider.js","names":[],"sources":["../../src/providers/WorkspacesProvider.tsx"],"sourcesContent":["import { type FC, type PropsWithChildren, createContext, use } from 'react';\nimport { PermissionProvider } from '@burdenoff/fe-libs/shared/providers/shell';\nimport type { WorkspacesRootProps } from '../types';\n\n/**\n * Context value for Workspaces microfrontend\n */\ntype WorkspacesContextValue = WorkspacesRootProps;\n\nconst WorkspacesContext = createContext<WorkspacesContextValue | null>(null);\n\n/**\n * Hook to access Workspaces context\n */\nexport const useWorkspacesContext = () => {\n const context = use(WorkspacesContext);\n if (!context) {\n throw new Error('useWorkspacesContext must be used within WorkspacesProvider');\n }\n return context;\n};\n\n/**\n * Provider component for Workspaces microfrontend\n * Sets up context and dependencies including permission management\n */\nexport const WorkspacesProvider: FC<PropsWithChildren<WorkspacesRootProps>> = ({\n children,\n ...props\n}) => {\n const contextValue: WorkspacesContextValue = {\n ...props,\n };\n\n return (\n <WorkspacesContext.Provider value={contextValue}>\n <PermissionProvider scopeId={props.workspaceId ?? null} gateway=\"workspace\" debug={false}>\n {children}\n </PermissionProvider>\n </WorkspacesContext.Provider>\n );\n};\n"],"mappings":";;;;AASA,IAAM,IAAoB,EAA6C,KAAK,EAK/D,UAA6B;CACxC,IAAM,IAAU,EAAI,EAAkB;AACtC,KAAI,CAAC,EACH,OAAU,MAAM,8DAA8D;AAEhF,QAAO;GAOI,KAAkE,EAC7E,aACA,GAAG,QACC;CACJ,IAAM,IAAuC,EAC3C,GAAG,GACJ;AAED,QACE,kBAAC,EAAkB,UAAnB;EAA4B,OAAO;YACjC,kBAAC,GAAD;GAAoB,SAAS,EAAM,eAAe;GAAM,SAAQ;GAAY,OAAO;GAChF;GACkB,CAAA;EACM,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workspacesStore.js","names":[],"sources":["../../src/store/workspacesStore.ts"],"sourcesContent":["import { create } from 'zustand';\nimport { devtools, persist } from 'zustand/middleware';\nimport { createProfileScopedStorage } from '@burdenoff/fe-libs/shared/utils';\n\nimport type {\n ViewMode,\n SortBy,\n SortDirection,\n WorkspaceFilters,\n ProjectFilters,\n MemberFilters,\n Workspace,\n} from '../types';\n\ninterface WorkspacesState {\n // View state\n viewMode: ViewMode;\n sortBy: SortBy;\n sortDirection: SortDirection;\n\n // Filters\n workspaceFilters: WorkspaceFilters;\n projectFilters: ProjectFilters;\n memberFilters: MemberFilters;\n\n // Selection state\n selectedWorkspaceIds: Set<string>;\n selectedProjectIds: Set<string>;\n selectedMemberIds: Set<string>;\n\n // UI state\n isCreateWorkspaceDialogOpen: boolean;\n isCreateProjectDialogOpen: boolean;\n isInviteMemberDialogOpen: boolean;\n currentWorkspace: Workspace | null;\n currentWorkspaceId: string | null;\n\n // Actions - View\n setViewMode: (mode: ViewMode) => void;\n setSortBy: (sortBy: SortBy) => void;\n toggleSortDirection: () => void;\n\n // Actions - Filters\n setWorkspaceFilters: (filters: Partial<WorkspaceFilters>) => void;\n clearWorkspaceFilters: () => void;\n setProjectFilters: (filters: Partial<ProjectFilters>) => void;\n clearProjectFilters: () => void;\n setMemberFilters: (filters: Partial<MemberFilters>) => void;\n clearMemberFilters: () => void;\n\n // Actions - Selection\n toggleWorkspaceSelection: (id: string) => void;\n clearWorkspaceSelection: () => void;\n toggleProjectSelection: (id: string) => void;\n clearProjectSelection: () => void;\n toggleMemberSelection: (id: string) => void;\n clearMemberSelection: () => void;\n\n // Actions - UI\n openCreateWorkspaceDialog: () => void;\n closeCreateWorkspaceDialog: () => void;\n openCreateProjectDialog: (workspace: Workspace) => void;\n closeCreateProjectDialog: () => void;\n openInviteMemberDialog: (workspace: Workspace) => void;\n closeInviteMemberDialog: () => void;\n setCurrentWorkspace: (workspace: Workspace | null) => void;\n\n // Actions - Reset\n reset: () => void;\n}\n\nconst initialState = {\n viewMode: 'grid' as ViewMode,\n sortBy: 'name' as SortBy,\n sortDirection: 'asc' as SortDirection,\n workspaceFilters: {},\n projectFilters: {},\n memberFilters: {},\n selectedWorkspaceIds: new Set<string>(),\n selectedProjectIds: new Set<string>(),\n selectedMemberIds: new Set<string>(),\n isCreateWorkspaceDialogOpen: false,\n isCreateProjectDialogOpen: false,\n isInviteMemberDialogOpen: false,\n currentWorkspace: null,\n currentWorkspaceId: null,\n};\n\nexport const useWorkspacesStore = create<WorkspacesState>()(\n devtools(\n persist(\n (set) => ({\n ...initialState,\n\n // View actions\n setViewMode: (mode) => set({ viewMode: mode }),\n setSortBy: (sortBy) => set({ sortBy }),\n toggleSortDirection: () =>\n set((state) => ({\n sortDirection: state.sortDirection === 'asc' ? 'desc' : 'asc',\n })),\n\n // Filter actions\n setWorkspaceFilters: (filters) =>\n set((state) => ({\n workspaceFilters: { ...state.workspaceFilters, ...filters },\n })),\n clearWorkspaceFilters: () => set({ workspaceFilters: {} }),\n setProjectFilters: (filters) =>\n set((state) => ({\n projectFilters: { ...state.projectFilters, ...filters },\n })),\n clearProjectFilters: () => set({ projectFilters: {} }),\n setMemberFilters: (filters) =>\n set((state) => ({\n memberFilters: { ...state.memberFilters, ...filters },\n })),\n clearMemberFilters: () => set({ memberFilters: {} }),\n\n // Selection actions\n toggleWorkspaceSelection: (id) =>\n set((state) => {\n const newSet = new Set(state.selectedWorkspaceIds);\n if (newSet.has(id)) {\n newSet.delete(id);\n } else {\n newSet.add(id);\n }\n return { selectedWorkspaceIds: newSet };\n }),\n clearWorkspaceSelection: () => set({ selectedWorkspaceIds: new Set() }),\n toggleProjectSelection: (id) =>\n set((state) => {\n const newSet = new Set(state.selectedProjectIds);\n if (newSet.has(id)) {\n newSet.delete(id);\n } else {\n newSet.add(id);\n }\n return { selectedProjectIds: newSet };\n }),\n clearProjectSelection: () => set({ selectedProjectIds: new Set() }),\n toggleMemberSelection: (id) =>\n set((state) => {\n const newSet = new Set(state.selectedMemberIds);\n if (newSet.has(id)) {\n newSet.delete(id);\n } else {\n newSet.add(id);\n }\n return { selectedMemberIds: newSet };\n }),\n clearMemberSelection: () => set({ selectedMemberIds: new Set() }),\n\n // UI actions\n openCreateWorkspaceDialog: () => set({ isCreateWorkspaceDialogOpen: true }),\n closeCreateWorkspaceDialog: () => set({ isCreateWorkspaceDialogOpen: false }),\n openCreateProjectDialog: (workspace) =>\n set({\n isCreateProjectDialogOpen: true,\n currentWorkspace: workspace,\n }),\n closeCreateProjectDialog: () =>\n set({\n isCreateProjectDialogOpen: false,\n currentWorkspace: null,\n }),\n openInviteMemberDialog: (workspace) =>\n set({\n isInviteMemberDialogOpen: true,\n currentWorkspace: workspace,\n currentWorkspaceId: workspace.id,\n }),\n closeInviteMemberDialog: () =>\n set({\n isInviteMemberDialogOpen: false,\n currentWorkspace: null,\n currentWorkspaceId: null,\n }),\n setCurrentWorkspace: (workspace) => set({ currentWorkspace: workspace }),\n\n // Reset\n reset: () => set(initialState),\n }),\n {\n name: 'burdenoff-workspaces-storage',\n storage: createProfileScopedStorage(),\n partialize: (state) => ({\n viewMode: state.viewMode,\n sortBy: state.sortBy,\n sortDirection: state.sortDirection,\n }),\n }\n ),\n { name: 'Workspaces Store', enabled: process.env.NODE_ENV === 'development' }\n )\n);\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"en.js","names":[],"sources":["../../src/translations/en.ts"],"sourcesContent":["/**\n * English fallback translations for microfe-workspaces.\n *\n * Keys use dot-notation (e.g., 'workspacesList.title') which the\n * I18nProvider resolves against this nested object structure.\n *\n * This file is the source of truth for all translation keys used in this MFE.\n * Register it with the host shell's AppShellProvider.fallbackTranslations\n * to enable offline/fallback support.\n */\nexport const enTranslations = {\n activityList: {\n accessDenied: 'Access Denied',\n description: 'Track workspace activity',\n emptyDescription:\n 'Recent workspace actions will appear here as your team creates, updates, and manages work.',\n emptyTitle: 'No recent activity',\n labelAction: 'Action',\n labelActor: 'Actor',\n labelResource: 'Resource',\n labelWhen: 'When',\n loadError: 'Failed to load activity',\n loading: 'Loading activity…',\n 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 title: 'Activity',\n },\n common: {\n cancel: 'Cancel',\n delete: 'Delete',\n },\n createProjectDialog: {\n creating: 'Creating...',\n description: 'Create a new project in your workspace. Projects help organize your work.',\n descriptionLabel: 'Description (Optional)',\n descriptionPlaceholder: 'Brief description of the project',\n keyHint: 'Short identifier (uppercase letters, numbers, underscores)',\n keyLabel: 'Project Key',\n keyPlaceholder: 'MYPROJ',\n nameHint: 'A descriptive name for your project',\n nameLabel: 'Project Name',\n namePlaceholder: 'My Project',\n submit: 'Create Project',\n title: 'Create Project',\n validation: {\n keyFormat: 'Key must be uppercase letters, numbers, underscores, or hyphens',\n keyMax: 'Key must be less than 10 characters',\n keyMin: 'Key must be at least 2 characters',\n nameMax: 'Name must be less than 100 characters',\n nameMin: 'Name must be at least 2 characters',\n },\n },\n createWorkspace: {\n backToWorkspaces: 'Back to Workspaces',\n cancel: 'Cancel',\n creating: 'Creating...',\n disabledAtCap: 'Workspace limit reached — upgrade your plan to create more.',\n failedToLoadOrganizations: 'Failed to load organizations',\n failedToLoadTenants: 'Failed to load tenants',\n goBack: 'Go Back',\n nameHint: 'A descriptive name for your workspace',\n nameLabel: 'Workspace Name *',\n namePlaceholder: 'My Workspace',\n noOrganizationsFound: 'No organizations found for this tenant',\n noTenantsAvailable: 'No tenants available. Contact your administrator.',\n organizationHint: 'Select which organization owns this workspace',\n organizationLabel: 'Organization *',\n permissionRequiredDetails: 'Required: workspace:create',\n permissionRequiredTitle: 'Permission Required',\n purpose:\n 'Create a workspace to give a team, client or initiative its own dedicated space — with its own projects, members, agents and activity, kept separate from the rest. Give it a clear name, pick the organization that owns it, and you can invite people and add projects right after.',\n selectOrganizationPlaceholder: 'Select an organization',\n selectTenantFirst: 'Please select a tenant first',\n selectTenantPlaceholder: 'Select a tenant',\n slugHint: 'URL-friendly identifier (auto-generated, but you can edit it)',\n slugLabel: 'Slug *',\n slugPlaceholder: 'my-workspace',\n submit: 'Create Workspace',\n subtitle: 'Set up a new workspace for your team',\n tenantHint: 'Select which tenant this workspace belongs to',\n tenantLabel: 'Tenant *',\n title: 'Create New Workspace',\n upgradeApproachingMessage: 'Upgrade to create more workspaces.',\n validation: {\n nameMin: 'Name must be at least 2 characters',\n organizationRequired: 'Please select an organization',\n slugFormat: 'Slug can only contain lowercase letters, numbers, and hyphens',\n slugMin: 'Slug must be at least 2 characters',\n tenantRequired: 'Please select a tenant',\n },\n },\n createWorkspaceDialog: {\n creating: 'Creating...',\n failedToLoadOrganizations: 'Failed to load organizations',\n failedToLoadTenants: 'Failed to load tenants',\n nameHint: 'A descriptive name for your workspace',\n nameLabel: 'Workspace Name *',\n namePlaceholder: 'My Workspace',\n noOrganizationsFound: 'No organizations found for this tenant',\n noTenantsAvailable: 'No tenants available. Contact your administrator.',\n organizationHint: 'Select which organization owns this workspace',\n organizationLabel: 'Organization *',\n selectOrganizationPlaceholder: 'Select an organization',\n selectTenantFirst: 'Please select a tenant first',\n selectTenantPlaceholder: 'Select a tenant',\n slugHint: 'URL-friendly identifier (auto-generated)',\n slugLabel: 'Slug *',\n slugPlaceholder: 'my-workspace',\n submit: 'Create Workspace',\n tenantHint: 'Select which tenant this workspace belongs to',\n tenantLabel: 'Tenant *',\n title: 'Create Workspace',\n validation: {\n nameMin: 'Name must be at least 2 characters',\n organizationRequired: 'Please select an organization',\n slugFormat: 'Slug can only contain lowercase letters, numbers, and hyphens',\n slugMin: 'Slug must be at least 2 characters',\n tenantRequired: 'Please select a tenant',\n },\n },\n dashboard: {\n agents: {\n connectAgent: 'Connect agent',\n degraded: 'degraded',\n emptyTitle: 'No agents connected',\n lastSeen: 'Last seen {time}',\n offline: 'offline',\n online: 'online',\n open: 'Open',\n title: 'Agent Fleet',\n total: 'total',\n },\n customize: 'Customize',\n error: {\n globalDown: 'Global services may be down.',\n partialData: 'Some data may be unavailable.',\n tryRefreshing: 'Try refreshing',\n workspaceDown: 'Workspace services may be down.',\n },\n groups: {\n emptyDescription: 'Groups bundle members together so you can manage and mention them as one.',\n emptyTitle: 'No groups yet',\n more: '+{count} more groups',\n title: 'Groups',\n },\n members: {\n invite: 'Invite a member',\n memberPlural: 'Members',\n memberSingular: 'Member',\n summary: '{memberLabel} across {count} {workspaceLabel}',\n title: 'Members',\n workspacePlural: 'workspaces',\n workspaceSingular: 'workspace',\n },\n projects: {\n activeCount: '{count} active',\n createProject: 'Create a project',\n emptyTitle: 'No projects yet',\n inactiveCount: '{count} inactive',\n title: 'Projects',\n totalCount: '{count} total',\n viewAll: 'View all',\n },\n quickActions: {\n connectAgent: 'Connect Agent',\n inviteMember: 'Invite Member',\n manageTags: 'Manage Tags',\n newEvent: 'New Event',\n newProject: 'New Project',\n newVibe: 'New Vibe',\n newWorkflow: 'New Workflow',\n newWorkspace: 'New Workspace',\n sessions: 'Sessions',\n settings: 'Settings',\n templates: 'Templates',\n title: 'Quick Actions',\n uploadFile: 'Upload File',\n viewRuns: 'View Runs',\n workflows: 'Workflows',\n },\n recentActivity: {\n commentAdded: 'Added comment',\n emptyDescription: 'Activity will appear here as you use the platform',\n emptyTitle: 'No recent activity',\n eventCreated: 'Created event',\n fileUploaded: 'Uploaded file',\n memberAdded: 'Added member',\n memberRemoved: 'Removed member',\n projectCreated: 'Created project',\n projectUpdated: 'Updated project',\n tagAssigned: 'Assigned tag',\n tagCreated: 'Created tag',\n title: 'Recent Activity',\n viewAll: 'View all',\n workflowCompleted: 'Completed workflow',\n workflowStarted: 'Started workflow',\n workspaceCreated: 'Created workspace',\n workspaceUpdated: 'Updated workspace',\n },\n refresh: 'Refresh',\n sessions: {\n emptyTitle: 'No active sessions',\n hoursAgo: '{count}h',\n justNow: 'just now',\n minutesAgo: '{count}m',\n statusActive: 'active',\n statusError: 'error',\n statusRunning: 'running',\n statusStarting: 'starting',\n statusStopped: 'stopped',\n title: 'Active Sessions',\n unnamedSession: 'Session {id}',\n viewAll: 'View all',\n },\n storage: {\n percentUsed: '{percent}% used',\n title: 'Storage',\n totalFiles: 'Total files',\n unitBytes: 'B',\n unitGigabytes: 'GB',\n unitKilobytes: 'KB',\n unitMegabytes: 'MB',\n unitTerabytes: 'TB',\n used: 'Used',\n usedOfTotal: '{used} / {total}',\n },\n tagCloud: {\n emptyDescription: 'Tags help you label and filter projects and content across the workspace.',\n emptyTitle: 'No tags created yet',\n more: '+{count} more tags',\n title: 'Tags',\n },\n tips: {\n fluidgrids: {\n buildWorkflow: {\n description: 'Drag nodes onto the canvas to automate a process end to end.',\n title: 'Build your first workflow',\n },\n community: {\n description: 'Share workflows and get help from other builders.',\n title: 'Join the community',\n },\n debugRun: {\n description: 'Inspect node-by-node execution logs for any workflow run.',\n title: 'Debug a failed run',\n },\n readDocs: {\n description: 'Guides and node reference at docs.fluidgrids.com.',\n title: 'Read the docs',\n },\n template: {\n description: 'Skip the blank canvas with a ready-made workflow template.',\n title: 'Start from a template',\n },\n },\n title: 'Tips & Resources',\n vibecontrols: {\n blog: {\n description: 'Product updates, deep dives, and engineering posts.',\n title: 'Latest from the blog',\n },\n community: {\n description: 'Ask questions, share workflows, and chat with the team.',\n title: 'Join the community',\n },\n featurePreviews: {\n description: 'Try opt-in features before they ship to everyone.',\n title: 'Feature previews',\n },\n plugins: {\n description: '50+ plugins for terminals, AI, tunnels, sandboxes, and more.',\n title: 'Browse plugins',\n },\n readDocs: {\n description: 'Guides, references, and tutorials at docs.vibecontrols.com.',\n title: 'Read the docs',\n },\n },\n workspaces: {\n automateWorkflows: {\n description: 'Build automation workflows to streamline your processes.',\n title: 'Automate with workflows',\n },\n createWorkspace: {\n description: 'Organize your team with a dedicated workspace.',\n title: 'Create your first workspace',\n },\n exploreApi: {\n description: 'Check out our developer portal for API documentation.',\n title: 'Explore the API',\n },\n permissions: {\n description: 'Configure role-based access for your workspace members.',\n title: 'Set up permissions',\n },\n },\n },\n titleSuffix: 'Dashboard',\n upcomingEvents: {\n allDay: 'All day',\n emptyAction: 'Schedule an event',\n emptyTitle: 'No upcoming events',\n title: 'Upcoming Events',\n today: 'Today at {time}',\n tomorrow: 'Tomorrow at {time}',\n viewAll: 'View all',\n },\n vibes: {\n daysAgo: '{count}d ago',\n emptyAction: 'Create your first vibe',\n emptyTitle: 'No vibes yet',\n hoursAgo: '{count}h ago',\n justNow: 'just now',\n minutesAgo: '{count}m ago',\n title: 'Recent Vibes',\n viewAll: 'View all',\n },\n welcome: {\n fallbackName: 'there',\n greetingAfternoon: 'Good afternoon',\n greetingEvening: 'Good evening',\n greetingMorning: 'Good morning',\n statGroups: 'Groups',\n statProjects: 'Projects',\n statRecentActivity: 'Recent Activity',\n statWorkspaces: 'Workspaces',\n title: 'Dashboard',\n },\n widget: {\n activity: {\n description: 'Timeline of recent activity across modules',\n title: 'Recent Activity',\n },\n agents: {\n description: 'Online, offline, and degraded agents at a glance',\n title: 'Agent Fleet',\n },\n calendar: {\n description: 'Next upcoming calendar events',\n title: 'Upcoming Events',\n },\n groups: {\n description: 'Your groups and teams',\n title: 'Groups',\n },\n members: {\n description: 'Workspace member overview',\n title: 'Members',\n },\n projects: {\n description: 'Recent projects and status breakdown',\n title: 'Projects',\n },\n quickActions: {\n description: 'Frequently used actions and shortcuts',\n title: 'Quick Actions',\n },\n sessions: {\n description: 'Running terminal and agent sessions',\n title: 'Active Sessions',\n },\n storage: {\n description: 'Storage usage and file statistics',\n title: 'Storage',\n },\n tags: {\n description: 'Popular tags across your workspace',\n title: 'Tags',\n },\n tips: {\n description: 'Getting started tips and documentation links',\n title: 'Tips & Resources',\n },\n vibes: {\n description: 'Your most recently active development vibes',\n title: 'Recent Vibes',\n },\n welcome: {\n description: 'Greeting and overview statistics',\n title: 'Welcome',\n },\n workflowRuns: {\n description: 'Run health, success rate, and recent executions',\n title: 'Workflow Runs',\n },\n workflows: {\n description: 'Active workflow stats and recent runs',\n title: 'Workflows',\n },\n workflowsOverview: {\n description: 'Active/archived workflow counts and recently updated workflows',\n title: 'Workflows',\n },\n workspaces: {\n description: 'Your workspaces overview and quick access',\n title: 'Workspaces',\n },\n },\n workflowRuns: {\n emptyDescription: 'Trigger a workflow to see its execution history here.',\n emptyTitle: 'No runs yet',\n hoursAgo: '{count}h ago',\n justNow: 'just now',\n minutesAgo: '{count}m ago',\n recentRunsHeading: 'Recent Runs',\n statFailed24h: 'Failed (24h)',\n statRunning: 'Running',\n statSuccessRate: 'Success rate',\n title: 'Workflow Runs',\n viewAll: 'View all',\n },\n workflowStats: {\n emptyDescription: 'Once you run automations, their status and counts will appear here.',\n emptyTitle: 'No workflow data available',\n recentRunsHeading: 'Recent Runs',\n statActive: 'Active',\n statArchived: 'Archived',\n title: 'Workflows',\n viewAll: 'View all',\n },\n workflowsOverview: {\n daysAgo: '{count}d ago',\n emptyAction: 'New Workflow',\n emptyDescription: 'Build your first workflow to automate a process.',\n emptyTitle: 'No workflows yet',\n hoursAgo: '{count}h ago',\n justNow: 'just now',\n minutesAgo: '{count}m ago',\n recentlyUpdatedHeading: 'Recently Updated',\n statActive: 'Active',\n statArchived: 'Archived',\n title: 'Workflows',\n viewAll: 'View all',\n },\n workspaces: {\n emptyAction: 'Create your first workspace',\n emptyTitle: 'No workspaces yet',\n more: '+{count} more workspaces',\n title: 'Workspaces',\n viewAll: 'View all',\n },\n },\n dashboardCustomizer: {\n description: 'Toggle widgets on or off and reorder them to personalize your dashboard.',\n resetToDefaults: 'Reset to defaults',\n saveLayout: 'Save layout',\n title: 'Customize Dashboard',\n },\n dashboardGrid: {\n noWidgetsEnabled: 'No widgets enabled',\n noWidgetsHint: 'Click \"Customize\" to add widgets to your dashboard',\n },\n errorBoundary: {\n contactSupport: 'Contact Support',\n description:\n 'We encountered an unexpected error. Please try refreshing the page or contact support if the problem persists.',\n errorDetails: 'Error Details',\n goHome: 'Go Home',\n needHelp: 'Need help?',\n reloadPage: 'Reload Page',\n title: 'Something went wrong',\n tryAgain: 'Try Again',\n },\n inviteAcceptance: {\n acceptButton: 'Accept Invitation',\n accepting: 'Accepting...',\n alreadyAcceptedDescription: 'This invitation has already been accepted',\n alreadyAcceptedPrefix: 'This invitation to ',\n alreadyAcceptedSuffix: ' has already been accepted.',\n alreadyAcceptedTitle: 'Invitation Already Accepted',\n backToWorkspaces: 'Back to Workspaces',\n cancelledDescription: 'This invitation has been cancelled by the sender',\n cancelledHeading: 'Invitation No Longer Available',\n cancelledPrefix: 'This invitation to ',\n cancelledSuffix: ' was cancelled by the workspace admin and is no longer valid.',\n cancelledTitle: 'Invitation Cancelled',\n emailAddressLabel: 'Email Address',\n errorDetailsLabel: 'Error Details',\n errorTitle: 'Error Loading Invitation',\n expiredContactAdmin: 'Please contact the workspace admin to request a new invitation.',\n expiredDescription: 'This invitation has expired',\n expiredHeading: 'Invitation No Longer Valid',\n expiredMiddle: ' expired on ',\n expiredPrefix: 'This invitation to ',\n expiredTitle: 'Invitation Expired',\n expiresLabel: 'Expires',\n goToWorkspace: 'Go to Workspace',\n goToWorkspaces: 'Go to Workspaces',\n invalidLinkHeading: 'Invalid Invitation Link',\n invitationDeclined: 'Invitation Declined',\n invitationIdLabel: 'Invitation ID',\n noProjects: 'No project memberships will be granted automatically with this invitation.',\n notFoundDescription: 'This invitation link is invalid or has been removed',\n notFoundTitle: 'Invitation Not Found',\n pageTitle: 'Workspace Invitation',\n projectsLabel: 'Projects',\n purpose:\n 'Someone has invited you to join their workspace. Review the details below — which workspace it is, the roles and projects you would receive, and when the invite expires — then accept to become a member or reject to decline.',\n rejectButton: 'Reject',\n rejectedPrefix: 'This invitation to ',\n rejectedSuffix: ' was previously rejected.',\n rejectedTitle: 'Invitation Rejected',\n rejecting: 'Rejecting...',\n rolesLabel: 'Roles',\n signInButton: 'Sign In',\n signInDescription:\n 'Workspace invitations require an authenticated Burdenoff account before you can review or accept them.',\n signInHint:\n 'Use the same email address that received the invitation, then come back here to accept or reject it.',\n signInRequired: 'Sign in to view your invitation',\n tryAgain: 'Try Again',\n workspaceLabel: 'Workspace',\n },\n inviteMemberDialog: {\n emailHint: 'Enter the email address of the person you want to invite',\n emailLabel: 'Email Address *',\n emailPlaceholder: 'member@example.com',\n loadingProjects: 'Loading projects…',\n loadingRoles: 'Loading roles…',\n noProjects: 'No active projects are available in this workspace yet.',\n noRoleDescription: 'No description available for this role.',\n noRoles: 'No assignable roles were returned for this workspace.',\n noWorkspaceError: 'No workspace selected. Please select a workspace first.',\n projectsHint:\n 'The invited user will be added to these projects automatically after they accept the workspace invitation.',\n projectsLabel: 'Projects to add on acceptance (Optional)',\n rolesHint: 'Choose roles. Hover any role to preview its full description.',\n rolesLabel: 'Roles (Optional)',\n selectProjectAriaLabel: 'Select {{projectName}}',\n selectRoleAriaLabel: 'Select {{roleName}}',\n selectedCount: 'selected',\n sendError: 'Failed to send invitation',\n sending: 'Sending...',\n submit: 'Send Invitation',\n systemRole: 'System role',\n title: 'Invite Member',\n validation: {\n emailInvalid: 'Invalid email address',\n },\n },\n memberListItem: {\n joined: 'Joined {{time}}',\n openActions: 'Open member actions',\n removeButton: 'Remove Member',\n removeDescription:\n 'Are you sure you want to remove {{name}} from the workspace? This action cannot be undone.',\n removeMember: 'Remove Member',\n removeTitle: 'Remove Member',\n removing: 'Removing...',\n selectMemberAriaLabel: 'Select member {{name}}',\n thisMemberFallback: 'this member',\n workspaceMember: 'Workspace member',\n },\n membersList: {\n accessDenied: 'Access Denied',\n activeMembers: 'Active Members',\n bulkRemoveConfirmPlural: 'selected members',\n bulkRemoveConfirmPrefix: 'Remove',\n bulkRemoveConfirmSingular: 'selected member',\n bulkRemoveConfirmSuffix: 'from this workspace?',\n clearSelection: 'Clear selection',\n errorLoadingMembers: 'An error occurred while loading members',\n failedToLoad: 'Failed to Load Members',\n inviteFirstMember: 'Invite Your First Member',\n inviteMember: 'Invite Member',\n invited: 'Invited',\n noMembersFound: 'No Members Found',\n noMembersFoundPrompt: 'No members match your search criteria. Try adjusting your search.',\n noMembersPrompt: 'Start building your team by inviting members to this workspace',\n noMembersYet: 'No Members Yet',\n noWorkspaceSelected: 'No Workspace Selected',\n pageSubtitle: 'Manage workspace members and invitations',\n pageTitle: 'Members',\n pending: 'Pending',\n pendingInvitation: 'Pending Invitation',\n pendingInvitations: 'Pending Invitations',\n pendingInvitationsHeader: 'Pending Invitations',\n purpose:\n 'Members are the people who belong to this workspace. From here you invite teammates, see who has accepted, resend or track invitations that are still pending, and remove people who no longer need access. Search by name or email to find someone quickly.',\n removeButton: 'Remove',\n removeMembersTitle: 'Remove members',\n removeSelected: 'Remove Selected',\n resend: 'Resend',\n resendSelected: 'Resend Selected',\n searchPlaceholder: 'Search members...',\n selectAllInvitations: 'Select all invitations',\n selectAllInvitationsAriaLabel: 'Select all pending invitations',\n selectAllMembersAriaLabel: 'Select all workspace members',\n selectAllVisibleMembers: 'Select all visible members',\n selectInvitationAriaLabel: 'Select invitation',\n selectWorkspacePrompt: 'Select a workspace to view and manage its members',\n selected: 'selected',\n sending: 'Sending...',\n },\n pendingInvites: {\n acceptButton: 'Accept',\n acceptError: 'Failed to accept invitation',\n backToWorkspaces: 'Back to Workspaces',\n emptyDescription: 'When someone invites you to a workspace, it will appear here.',\n emptyTitle: 'No pending invites',\n expiresLabel: 'Expires',\n invitedByLabel: 'Invited by',\n loadError: 'Failed to load pending invitations',\n noProjects: 'No project access will be granted automatically',\n noRoles: 'No explicit roles assigned',\n pageSubtitle: 'Review and respond to workspace invitations sent to your account.',\n pageTitle: 'Pending Invites',\n projectsLabel: 'Projects',\n purpose:\n 'These are workspace invitations sent to your email but not yet answered. Accepting one adds you to that workspace (with the roles and project access shown); rejecting declines it. Invitations expire, so respond to the ones you want before their expiry date.',\n receivedLabel: 'Received',\n rejectButton: 'Reject',\n rejectError: 'Failed to reject invitation',\n rolesLabel: 'Roles',\n signInDescription:\n 'You need an authenticated account before you can review or respond to workspace invitations.',\n signInTitle: 'Sign in to view your pending invites',\n viewWorkspaces: 'View Workspaces',\n workspaceLabel: 'Workspace',\n },\n projectCard: {\n archive: 'Archive',\n archivedLabel: 'Archived',\n created: 'Created {{date}}',\n delete: 'Delete',\n deleteMessage: 'Are you sure you want to delete \"{{name}}\"?',\n deleteTitle: 'Delete project',\n getId: 'Get ID',\n keyLabel: 'Key',\n openActions: 'Open project actions',\n openProjectAriaLabel: 'Open project {{name}}',\n projectTagsAriaLabel: 'Project tags',\n rename: 'Rename',\n selectProjectAriaLabel: 'Select project {{name}}',\n unarchive: 'Unarchive',\n workspaceIdLabel: 'Workspace ID',\n },\n projectDetail: {\n accessDenied: 'Access Denied',\n activityCardTitle: 'Activity',\n addProjectMember: 'Add Member',\n archive: 'Archive',\n archived: 'Archived',\n backToProjects: 'Back to Projects',\n cancel: 'Cancel',\n configuration: 'Configuration',\n created: 'Created',\n creatorId: 'Creator ID',\n deleteConfirmPrefix: 'Are you sure you want to delete \"',\n deleteConfirmSuffix:\n '\"? This action cannot be undone and all project data will be permanently removed.',\n deleteDialogTitle: 'Delete Project',\n deleteProject: 'Delete Project',\n deleting: 'Deleting...',\n getId: 'Get ID',\n lastUpdated: 'Last Updated',\n manageProjectMembers: 'Manage Members',\n membersCardTitle: 'Members',\n openProjectActionsAriaLabel: 'Open project actions',\n processing: 'Processing...',\n projectId: 'Project ID',\n projectInformation: 'Project Information',\n projectKey: 'Project Key',\n projectMembers: 'Project members',\n projectMembersPage: 'Project Members',\n projectNotFound: 'Project not found',\n purpose:\n 'This is a single project — a focused stream of work within its workspace. From here you can manage the people working on it, organise it with tags so it surfaces in filters and reports, and keep track of related activity. Use the menu in the top-right to archive or delete it when it wraps up.',\n quickActions: 'Quick Actions',\n recentActivityItems: 'Recent activity items',\n renameProject: 'Rename Project',\n stepActivity: 'Check recent activity',\n stepActivityDesc: 'Catch up on what has changed across the workspace.',\n stepAddMember: 'Add people to the project',\n stepAddMemberDesc: 'Pull in the teammates who will actually work on this project.',\n stepManageMembers: 'Review project members',\n stepManageMembersDesc: 'See who has access and adjust their project roles.',\n stepTag: 'Tag the project',\n stepTagDesc: 'Add tags so this project shows up in the right filters and views.',\n tagsDescription: 'Use universal tags to classify and filter this project across the workspace.',\n tagsTitle: 'Tags',\n unarchive: 'Unarchive',\n workspaceActivity: 'Workspace Activity',\n workspaceId: 'Workspace ID',\n workspaceMembers: 'Workspace Members',\n },\n projectMemberPickerDialog: {\n add: 'Add',\n addError: 'Failed to add member to project',\n adding: 'Adding...',\n autoloadCapNote:\n 'Loaded the first {{count}} project members to avoid an excessively long blocking load.',\n description:\n 'Add an existing workspace member to {{projectName}}. Only current workspace members are eligible.',\n eligibleCount: '{{count}} eligible',\n emptyDescription:\n 'All workspace members are already part of this project, or nothing matched your search.',\n emptyTitle: 'No eligible members found',\n loadMore: 'Load More Members',\n loadingMore: 'Loading more…',\n retryLoadingMembers: 'Retry Loading Members',\n searchPlaceholder: 'Search workspace members',\n showingCount: 'Showing {{shown}} of {{total}} workspace members.',\n thisProject: 'this project',\n title: 'Add member to project',\n },\n projectMembers: {\n accessDenied: 'Access Denied',\n addFirstMember: 'Add First Member',\n addMember: 'Add Member',\n addedLabel: 'Added',\n backToProject: 'Back to Project',\n cancel: 'Cancel',\n emptySubtitle: 'Add workspace members to this project so they can collaborate here.',\n emptyTitle: 'No project members yet',\n loadError: 'Failed to load project members',\n memberBadge: 'Project member',\n noResultsSubtitle: 'Try a different search to find a project member.',\n noResultsTitle: 'No matching members found',\n pageSubtitle: 'Only existing workspace members can be added to this project.',\n pageTitle: 'Project Members',\n purpose:\n 'This is the subset of workspace members who can work on this specific project. Add people here to give them project-level access, search to find someone, or remove members who have moved on. Only existing workspace members can be added.',\n removeAction: 'Remove',\n removeConfirmPrefix: 'Remove',\n removeConfirmSuffix: 'from this project?',\n removeConfirmTitle: 'Remove project member',\n removeError: 'Failed to remove project member. Please try again.',\n removing: 'Removing...',\n searchPlaceholder: 'Search project members',\n },\n projectTagsWidget: {\n add: 'Add',\n addTagAriaLabel: 'Add tag',\n addTags: 'Add tags',\n create: 'Create \"{{label}}\"',\n createGenericError: 'Failed to create tag',\n createValidationError: 'Must contain at least one letter or number',\n createVocabularyError: 'Failed to create default vocabulary',\n creating: 'Creating...',\n maxTagsReached: 'Maximum {{maxTags}} tags reached',\n noTagsFound: 'No tags found',\n searchPlaceholder: 'Search or create a tag...',\n typeToSearch: 'Type to search or create a tag',\n },\n projectsList: {\n activeTagFilters: 'Active tag filters',\n activeTagFiltersDescription:\n 'Click a project tag to add or remove it from the current filter set.',\n adjustSearchOrFilters: 'Try adjusting your search or filters',\n archiveActiveProjects: 'Active Projects',\n archiveAll: 'All Projects',\n archiveArchived: 'Archived',\n archiveSelected: 'Archive Selected',\n bulkDeleteConfirmPluralSuffix: 's',\n bulkDeleteConfirmPrefix: 'Delete ',\n bulkDeleteConfirmProject: 'selected project',\n bulkDeleteConfirmSuffix: '? This cannot be undone.',\n clearFilters: 'Clear Filters',\n clearSelection: 'Clear selection',\n createFirstProject: 'Create your first project to get started organizing your work',\n createProject: 'Create Project',\n deleteProjectsTitle: 'Delete projects',\n deleteSelected: 'Delete Selected',\n errorLoading: 'Error loading projects',\n filterByArchive: 'Filter by archive',\n filterByStatus: 'Filter by status',\n gridViewAriaLabel: 'Show projects in grid view',\n listViewAriaLabel: 'Show projects in list view',\n noProjectsFound: 'No projects found',\n pageSubtitle: 'Manage and organize your projects',\n pageTitle: 'Projects',\n purpose:\n 'Projects are the individual streams of work inside your workspaces — a launch, a client engagement, a feature. Each carries its own members, tags and activity. Use search, status and tag filters to find the one you need, or create a new project to start tracking work.',\n searchPlaceholder: 'Search projects...',\n selectAllAriaLabel: 'Select all projects',\n selectAllVisible: 'Select all visible',\n selected: 'selected',\n showingOf: 'of',\n showingPrefix: 'Showing',\n showingProjects: 'projects',\n statusActive: 'Active',\n statusAll: 'All Statuses',\n statusInactive: 'Inactive',\n tagMatchAll: 'Match all tags',\n tagMatchAny: 'Match any tag',\n tagMatchMode: 'Tag match mode',\n unarchiveSelected: 'Unarchive Selected',\n unknownError: 'An unknown error occurred',\n },\n renameProjectDialog: {\n description: 'Give this project a new name. The project key stays the same.',\n nameHint: 'A descriptive name for your project',\n nameLabel: 'Project Name',\n namePlaceholder: 'My Project',\n save: 'Save',\n saving: 'Saving...',\n submitError: 'Failed to rename project',\n title: 'Rename Project',\n validation: {\n nameMax: 'Name must be less than 100 characters',\n nameMin: 'Name must be at least 2 characters',\n },\n },\n widgetWrapper: {\n serviceUnavailable: 'Service unavailable',\n },\n workspaceCard: {\n memberCount: '{{count}} member{{suffix}}',\n openWorkspaceAriaLabel: 'Open workspace {{name}}',\n projectCount: '{{count}} project{{suffix}}',\n },\n workspaceDetail: {\n accessDenied: 'Access Denied',\n activity: 'Activity',\n activityDesc: 'Recent activity items',\n archive: 'Archive',\n archiveDescription: 'This removes the workspace from active work while preserving its data.',\n archiveFailed: 'The workspace could not be archived. Please try again.',\n archiveTitle: 'Archive workspace?',\n archiveWorkspace: 'Archive Workspace',\n archiving: 'Archiving...',\n backToWorkspaces: 'Back to Workspaces',\n contactEmail: 'Contact Email:',\n created: 'Created:',\n domain: 'Domain:',\n id: 'ID:',\n inviteMembers: 'Invite Member',\n members: 'Members',\n membersDesc: 'Workspace members',\n notFound: 'Workspace not found',\n projects: 'Projects',\n projectsDesc: 'Projects in this workspace',\n purpose:\n 'This is the home for a single workspace — the hub that ties together its projects, the people who collaborate in it, and everything that happens inside. Use the cards below to jump into work, manage who has access, or review recent activity.',\n settings: 'Settings',\n stepInvite: 'Invite a teammate',\n stepInviteDesc: 'Bring people into this workspace so they can collaborate.',\n stepMembers: 'Review who has access',\n stepMembersDesc: 'Check the current members and their roles.',\n stepProjects: 'Open the projects board',\n stepProjectsDesc: 'Projects are where the actual work lives — start or pick one up.',\n stepSettings: 'Configure workspace settings',\n stepSettingsDesc: 'Set the name, domain and contact details for this workspace.',\n website: 'Website:',\n workspaceInformation: 'Workspace Information',\n },\n workspaceInvite: {\n accessDenied: 'Access Denied',\n backToWorkspace: 'Back to Workspace',\n backToWorkspaces: 'Back to Workspaces',\n bulkDescription:\n 'Upload a CSV with one email column. All valid rows will receive the currently selected roles and projects.',\n chooseCsvFileAriaLabel: 'Choose CSV file',\n chooseFile: 'Choose file',\n downloadTemplate: 'Download template',\n emailLabel: 'Email Address',\n emailPlaceholder: 'member@example.com',\n modeBulk: 'Bulk CSV',\n modeSingle: 'Single',\n noWorkspaceDescription:\n 'Choose a current workspace from the header or open a workspace detail page before inviting members.',\n noWorkspaceTitle: 'Select a workspace first',\n pendingEmpty:\n 'Invitations you send for this workspace will show up here until they are accepted, so you can resend or cancel them.',\n pendingEmptyTitle: 'No pending invitations',\n pendingLoadFailed: 'Failed to load pending invitations for this workspace.',\n pendingStaleWarning: 'Pending invitations may be outdated. Try again to refresh this list.',\n pendingTitle: 'Pending Invitations',\n purpose:\n 'Use this page to bring new people into the workspace. First choose the roles and projects they should get the moment they accept, then send a single invitation by email or upload a CSV to invite many people at once. Invitations you have already sent appear at the bottom, where you can resend or cancel them.',\n retrying: 'Retrying…',\n sendBulkButton: 'Send Bulk Invites',\n sendSingleButton: 'Send Invitation',\n sendTitle: 'Send invitations',\n setupTitle: 'Access to grant on acceptance',\n stepAccess: 'Pick the roles and projects to grant',\n stepAccessDesc: 'These are applied automatically when each person accepts.',\n stepPending: 'Track your pending invitations',\n stepPendingDesc: 'Resend or cancel invitations that have not been accepted yet.',\n stepSend: 'Send the invitation',\n stepSendDesc: 'Enter one email, or switch to the Bulk CSV tab to invite many at once.',\n subtitle: 'Invite people into this workspace and optionally grant project access.',\n title: 'Invite Members',\n tryAgain: 'Try again',\n workspaceLoadError: 'Unable to load workspace invite details.',\n },\n workspaceSettings: {\n advancedDescription: 'Custom domain + website. Most workspaces leave these blank.',\n advancedTitle: 'Advanced settings',\n backToWorkspace: 'Back to Workspace',\n cancel: 'Cancel',\n contactEmail: 'Contact Email',\n domain: 'Domain',\n generalSettings: 'General Settings',\n goBack: 'Go Back',\n loading: 'Loading...',\n notFound: 'Workspace not found',\n permissionRequired: 'Permission Required',\n permissionRequiredDetails: 'Required: workspace:update',\n saveChanges: 'Save Changes',\n saving: 'Saving...',\n subtitle: 'Manage workspace configuration',\n tags: 'Tags',\n tagsDescription: 'Use universal tags to classify and filter this workspace.',\n title: 'Workspace Settings',\n website: 'Website',\n workspaceName: 'Workspace Name',\n },\n workspaces: {\n count: 'You have {{count}} workspaces',\n dashboard: {\n title: 'Dashboard',\n },\n delete: {\n confirm: 'Delete {{count}} items?',\n },\n greet: 'Hello {{name}} ({{count}})',\n title: 'Workspaces',\n },\n workspacesList: {\n createButton: 'Create Workspace',\n createButtonShort: 'Create',\n createFirstButton: 'Create Your First Workspace',\n description: 'Manage and organize your workspaces',\n emptyCreateHint: 'Get started by creating your first workspace',\n emptySearchHint: 'Try adjusting your search criteria',\n emptyTitle: 'No workspaces found',\n gridViewAriaLabel: 'Show workspaces in grid view',\n gridViewTitle: 'Grid view',\n inviteMemberButton: 'Invite Member',\n listViewAriaLabel: 'Show workspaces in list view',\n listViewTitle: 'List view',\n loadError: 'Error loading workspaces',\n moreAvailable: 'More workspaces available - pagination coming soon',\n of: 'of',\n pendingInvitesButton: 'Pending Invites',\n purpose:\n 'Workspaces are shared homes for a team or initiative — each one groups its own projects, members, agents and activity. Create one per team, client or product line to keep work isolated, then switch between them from the sidebar.',\n searchPlaceholder: 'Search workspaces...',\n showing: 'Showing',\n title: 'Workspaces',\n unknownError: 'Unknown error',\n workspace: 'workspace',\n workspaces: 'workspaces',\n },\n};\n// Note: 2 key(s) had conflicting fallbacks in source (test-only).\n"],"mappings":"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ACR,aAAa;KACb,OAAO;KACR;IACD,UAAU;KACR,aAAa;KACb,OAAO;KACR;IACF;GACD,OAAO;GACP,cAAc;IACZ,MAAM;KACJ,aAAa;KACb,OAAO;KACR;IACD,WAAW;KACT,aAAa;KACb,OAAO;KACR;IACD,iBAAiB;KACf,aAAa;KACb,OAAO;KACR;IACD,SAAS;KACP,aAAa;KACb,OAAO;KACR;IACD,UAAU;KACR,aAAa;KACb,OAAO;KACR;IACF;GACD,YAAY;IACV,mBAAmB;KACjB,aAAa;KACb,OAAO;KACR;IACD,iBAAiB;KACf,aAAa;KACb,OAAO;KACR;IACD,YAAY;KACV,aAAa;KACb,OAAO;KACR;IACD,aAAa;KACX,aAAa;KACb,OAAO;KACR;IACF;GACF;EACD,aAAa;EACb,gBAAgB;GACd,QAAQ;GACR,aAAa;GACb,YAAY;GACZ,OAAO;GACP,OAAO;GACP,UAAU;GACV,SAAS;GACV;EACD,OAAO;GACL,SAAS;GACT,aAAa;GACb,YAAY;GACZ,UAAU;GACV,SAAS;GACT,YAAY;GACZ,OAAO;GACP,SAAS;GACV;EACD,SAAS;GACP,cAAc;GACd,mBAAmB;GACnB,iBAAiB;GACjB,iBAAiB;GACjB,YAAY;GACZ,cAAc;GACd,oBAAoB;GACpB,gBAAgB;GAChB,OAAO;GACR;EACD,QAAQ;GACN,UAAU;IACR,aAAa;IACb,OAAO;IACR;GACD,QAAQ;IACN,aAAa;IACb,OAAO;IACR;GACD,UAAU;IACR,aAAa;IACb,OAAO;IACR;GACD,QAAQ;IACN,aAAa;IACb,OAAO;IACR;GACD,SAAS;IACP,aAAa;IACb,OAAO;IACR;GACD,UAAU;IACR,aAAa;IACb,OAAO;IACR;GACD,cAAc;IACZ,aAAa;IACb,OAAO;IACR;GACD,UAAU;IACR,aAAa;IACb,OAAO;IACR;GACD,SAAS;IACP,aAAa;IACb,OAAO;IACR;GACD,MAAM;IACJ,aAAa;IACb,OAAO;IACR;GACD,MAAM;IACJ,aAAa;IACb,OAAO;IACR;GACD,OAAO;IACL,aAAa;IACb,OAAO;IACR;GACD,SAAS;IACP,aAAa;IACb,OA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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"formatters.js","names":[],"sources":["../../src/utils/formatters.ts"],"sourcesContent":["/**\n * Utility functions for formatting dates and strings in the workspace module\n */\n\n/**\n * Format a date string or Date object to a human-readable format\n * @param date - Date string or Date object\n * @param options - Intl.DateTimeFormatOptions\n * @returns Formatted date string\n */\nconst DEFAULT_DATE_OPTIONS: Intl.DateTimeFormatOptions = {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n};\n\nconst dateFormatterCache = new Map<string, Intl.DateTimeFormat>();\n\nfunction getDateFormatter(options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {\n const key = JSON.stringify(options);\n let formatter = dateFormatterCache.get(key);\n if (!formatter) {\n formatter = new Intl.DateTimeFormat('en-US', options);\n dateFormatterCache.set(key, formatter);\n }\n return formatter;\n}\n\nexport function formatDate(\n date: string | Date,\n options: Intl.DateTimeFormatOptions = DEFAULT_DATE_OPTIONS\n): string {\n try {\n const dateObj = typeof date === 'string' ? new Date(date) : date;\n return getDateFormatter(options).format(dateObj);\n } catch {\n return 'Invalid date';\n }\n}\n\n/**\n * Format a date to a relative time string (e.g., \"2 days ago\")\n * @param date - Date string or Date object\n * @returns Relative time string\n */\nexport function formatRelativeTime(date: string | Date): string {\n try {\n const dateObj = typeof date === 'string' ? new Date(date) : date;\n const now = new Date();\n const diffMs = now.getTime() - dateObj.getTime();\n const diffSec = Math.floor(diffMs / 1000);\n const diffMin = Math.floor(diffSec / 60);\n const diffHour = Math.floor(diffMin / 60);\n const diffDay = Math.floor(diffHour / 24);\n const diffWeek = Math.floor(diffDay / 7);\n const diffMonth = Math.floor(diffDay / 30);\n const diffYear = Math.floor(diffDay / 365);\n\n if (diffSec < 60) {\n return 'just now';\n } else if (diffMin < 60) {\n return `${diffMin} ${diffMin === 1 ? 'minute' : 'minutes'} ago`;\n } else if (diffHour < 24) {\n return `${diffHour} ${diffHour === 1 ? 'hour' : 'hours'} ago`;\n } else if (diffDay < 7) {\n return `${diffDay} ${diffDay === 1 ? 'day' : 'days'} ago`;\n } else if (diffWeek < 4) {\n return `${diffWeek} ${diffWeek === 1 ? 'week' : 'weeks'} ago`;\n } else if (diffMonth < 12) {\n return `${diffMonth} ${diffMonth === 1 ? 'month' : 'months'} ago`;\n } else {\n return `${diffYear} ${diffYear === 1 ? 'year' : 'years'} ago`;\n }\n } catch {\n return 'Invalid date';\n }\n}\n\n/**\n * Format a date and time to a readable string\n * @param date - Date string or Date object\n * @returns Formatted date and time string\n */\nexport function formatDateTime(date: string | Date): string {\n return formatDate(date, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n });\n}\n\n/**\n * Truncate a string to a maximum length and add ellipsis\n * @param str - String to truncate\n * @param maxLength - Maximum length before truncation\n * @returns Truncated string\n */\nexport function truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str;\n return `${str.slice(0, maxLength)}...`;\n}\n\n/**\n * Convert a string to title case\n * @param str - String to convert\n * @returns Title cased string\n */\nexport function toTitleCase(str: string): string {\n return str\n .toLowerCase()\n .split(' ')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n}\n\n/**\n * Format a workspace status to a human-readable string\n * @param status - Workspace status\n * @returns Formatted status string\n */\nexport function formatWorkspaceStatus(status: string): string {\n return toTitleCase(status.replace(/_/g, ' '));\n}\n\n/**\n * Format a project status to a human-readable string\n * @param status - Project status\n * @returns Formatted status string\n */\nexport function formatProjectStatus(status: string): string {\n return toTitleCase(status.replace(/_/g, ' '));\n}\n\n/**\n * Generate initials from a name\n * @param name - Full name\n * @returns Initials (up to 2 characters)\n */\nexport function getInitials(name: string): string {\n const parts = name.trim().split(/\\s+/);\n if (parts.length === 1) {\n return parts[0].charAt(0).toUpperCase();\n }\n return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase();\n}\n\n/**\n * Format a file size in bytes to a human-readable string\n * @param bytes - Size in bytes\n * @returns Formatted size string (e.g., \"1.5 MB\")\n */\nexport function formatFileSize(bytes: number): string {\n if (bytes === 0) return '0 Bytes';\n\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;\n}\n"],"mappings":";AAUA,IAAM,IAAmD;CACvD,MAAM;CACN,OAAO;CACP,KAAK;CACN,EAEK,oBAAqB,IAAI,KAAkC;AAEjE,SAAS,EAAiB,GAA0D;CAClF,IAAM,IAAM,KAAK,UAAU,EAAQ,EAC/B,IAAY,EAAmB,IAAI,EAAI;AAK3C,QAJK,MACH,IAAY,IAAI,KAAK,eAAe,SAAS,EAAQ,EACrD,EAAmB,IAAI,GAAK,EAAU,GAEjC;;AAGT,SAAgB,EACd,GACA,IAAsC,GAC9B;AACR,KAAI;EACF,IAAM,IAAU,OAAO,KAAS,WAAW,IAAI,KAAK,EAAK,GAAG;AAC5D,SAAO,EAAiB,EAAQ,CAAC,OAAO,EAAQ;SAC1C;AACN,SAAO;;;AASX,SAAgB,EAAmB,GAA6B;AAC9D,KAAI;EACF,IAAM,IAAU,OAAO,KAAS,WAAW,IAAI,KAAK,EAAK,GAAG,GAEtD,qBADM,IAAI,MAAM,EACH,SAAS,GAAG,EAAQ,SAAS,EAC1C,IAAU,KAAK,MAAM,IAAS,IAAK,EACnC,IAAU,KAAK,MAAM,IAAU,GAAG,EAClC,IAAW,KAAK,MAAM,IAAU,GAAG,EACnC,IAAU,KAAK,MAAM,IAAW,GAAG,EACnC,IAAW,KAAK,MAAM,IAAU,EAAE,EAClC,IAAY,KAAK,MAAM,IAAU,GAAG,EACpC,IAAW,KAAK,MAAM,IAAU,IAAI;AAexC,SAbE,IAAU,KACL,aACE,IAAU,KACZ,GAAG,EAAQ,GAAG,MAAY,IAAI,WAAW,UAAU,QACjD,IAAW,KACb,GAAG,EAAS,GAAG,MAAa,IAAI,SAAS,QAAQ,QAC/C,IAAU,IACZ,GAAG,EAAQ,GAAG,MAAY,IAAI,QAAQ,OAAO,QAC3C,IAAW,IACb,GAAG,EAAS,GAAG,MAAa,IAAI,SAAS,QAAQ,QAC/C,IAAY,KACd,GAAG,EAAU,GAAG,MAAc,IAAI,UAAU,SAAS,QAErD,GAAG,EAAS,GAAG,MAAa,IAAI,SAAS,QAAQ;SAEpD;AACN,SAAO;;;AASX,SAAgB,EAAe,GAA6B;AAC1D,QAAO,EAAW,GAAM;EACtB,MAAM;EACN,OAAO;EACP,KAAK;EACL,MAAM;EACN,QAAQ;EACT,CAAC;;AASJ,SAAgB,EAAS,GAAa,GAA2B;AAE/D,QADI,EAAI,UAAU,IAAkB,IAC7B,GAAG,EAAI,MAAM,GAAG,EAAU,CAAC;;AAQpC,SAAgB,EAAY,GAAqB;AAC/C,QAAO,EACJ,aAAa,CACb,MAAM,IAAI,CACV,KAAK,MAAS,EAAK,OAAO,EAAE,CAAC,aAAa,GAAG,EAAK,MAAM,EAAE,CAAC,CAC3D,KAAK,IAAI;;AAQd,SAAgB,EAAsB,GAAwB;AAC5D,QAAO,EAAY,EAAO,QAAQ,MAAM,IAAI,CAAC;;AAQ/C,SAAgB,EAAoB,GAAwB;AAC1D,QAAO,EAAY,EAAO,QAAQ,MAAM,IAAI,CAAC;;AAQ/C,SAAgB,EAAY,GAAsB;CAChD,IAAM,IAAQ,EAAK,MAAM,CAAC,MAAM,MAAM;AAItC,QAHI,EAAM,WAAW,IACZ,EAAM,GAAG,OAAO,EAAE,CAAC,aAAa,IAEjC,EAAM,GAAG,OAAO,EAAE,GAAG,EAAM,EAAM,SAAS,GAAG,OAAO,EAAE,EAAE,aAAa;;AAQ/E,SAAgB,EAAe,GAAuB;AACpD,KAAI,MAAU,EAAG,QAAO;CAExB,IAAM,IAAI,MACJ,IAAQ;EAAC;EAAS;EAAM;EAAM;EAAM;EAAK,EACzC,IAAI,KAAK,MAAM,KAAK,IAAI,EAAM,GAAG,KAAK,IAAI,EAAE,CAAC;AAEnD,QAAO,GAAG,YAAY,IAAiB,MAAG,GAAI,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAM"}
|
package/dist/utils/i18n.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"i18n.js","names":[],"sources":["../../src/utils/i18n.ts"],"sourcesContent":["import type { I18nContextValue } from '@burdenoff/fe-libs/shared/providers/shell';\n\ntype TranslationParams = Record<string, string | number>;\n\n/**\n * Translate `key` and fall back to `fallback` when the i18n provider\n * returns the key itself (the convention shell's `useI18n().t(...)` uses\n * to indicate a missing translation). Optional `params` are forwarded to\n * the translator and also used for `{name}` style interpolation in the\n * fallback string.\n */\nexport function tWithFallback(\n t: I18nContextValue['t'],\n key: string,\n fallback: string,\n params?: TranslationParams\n): string {\n const translated = t(key, params);\n if (translated !== key) {\n return translated;\n }\n if (!params) return fallback;\n return fallback.replace(/\\{(\\w+)\\}/g, (match, name: string) => {\n const value = params[name];\n return value === undefined ? match : String(value);\n });\n}\n"],"mappings":";AAWA,SAAgB,EACd,GACA,GACA,GACA,GACQ;CACR,IAAM,IAAa,EAAE,GAAK,EAAO;AAKjC,QAJI,MAAe,IAGd,IACE,EAAS,QAAQ,eAAe,GAAO,MAAiB;EAC7D,IAAM,IAAQ,EAAO;AACrB,SAAO,MAAU,KAAA,IAAY,IAAQ,OAAO,EAAM;GAClD,GAJkB,IAFX"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"invitationDisplay.js","names":[],"sources":["../../src/utils/invitationDisplay.ts"],"sourcesContent":["import type { WorkspaceInvitation } from '../types';\n\ntype InvitationLike = Pick<\n WorkspaceInvitation,\n 'workspaceName' | 'workspaceId' | 'roleNames' | 'roleIds' | 'projectId' | 'projectIds' | 'context'\n>;\n\nexport function getWorkspaceDisplayName(invitation: InvitationLike): string {\n if (invitation.workspaceName) {\n return invitation.workspaceName;\n }\n\n const metadataWorkspaceName = invitation.context?.metadata?.workspaceName;\n if (typeof metadataWorkspaceName === 'string' && metadataWorkspaceName.trim().length > 0) {\n return metadataWorkspaceName;\n }\n\n return invitation.workspaceId || '—';\n}\n\nexport function getRoleDisplayNames(invitation: InvitationLike): string[] {\n if (Array.isArray(invitation.roleNames) && invitation.roleNames.length > 0) {\n return invitation.roleNames;\n }\n\n const metadataRoleNames = invitation.context?.metadata?.roleNames;\n if (\n Array.isArray(metadataRoleNames) &&\n metadataRoleNames.every((value) => typeof value === 'string')\n ) {\n return metadataRoleNames;\n }\n\n return invitation.roleIds;\n}\n\nexport function getProjectDisplayNames(invitation: InvitationLike): string[] {\n const metadataProjectNames = invitation.context?.metadata?.projectNames;\n if (\n Array.isArray(metadataProjectNames) &&\n metadataProjectNames.every((value) => typeof value === 'string')\n ) {\n return metadataProjectNames;\n }\n\n const metadataProjectIds = invitation.context?.metadata?.projectIds;\n const projectIds = [\n ...(Array.isArray(invitation.projectIds) ? invitation.projectIds : []),\n ...(invitation.projectId ? [invitation.projectId] : []),\n ...(Array.isArray(metadataProjectIds)\n ? metadataProjectIds.filter((value): value is string => typeof value === 'string')\n : []),\n ];\n const projectCount = new Set(projectIds).size;\n\n if (projectCount === 0) {\n return [];\n }\n\n return [`${projectCount} project${projectCount === 1 ? '' : 's'} selected`];\n}\n"],"mappings":";AAOA,SAAgB,EAAwB,GAAoC;AAC1E,KAAI,EAAW,cACb,QAAO,EAAW;CAGpB,IAAM,IAAwB,EAAW,SAAS,UAAU;AAK5D,QAJI,OAAO,KAA0B,YAAY,EAAsB,MAAM,CAAC,SAAS,IAC9E,IAGF,EAAW,eAAe;;AAGnC,SAAgB,EAAoB,GAAsC;AACxE,KAAI,MAAM,QAAQ,EAAW,UAAU,IAAI,EAAW,UAAU,SAAS,EACvE,QAAO,EAAW;CAGpB,IAAM,IAAoB,EAAW,SAAS,UAAU;AAQxD,QANE,MAAM,QAAQ,EAAkB,IAChC,EAAkB,OAAO,MAAU,OAAO,KAAU,SAAS,GAEtD,IAGF,EAAW;;AAGpB,SAAgB,EAAuB,GAAsC;CAC3E,IAAM,IAAuB,EAAW,SAAS,UAAU;AAC3D,KACE,MAAM,QAAQ,EAAqB,IACnC,EAAqB,OAAO,MAAU,OAAO,KAAU,SAAS,CAEhE,QAAO;CAGT,IAAM,IAAqB,EAAW,SAAS,UAAU,YACnD,IAAa;EACjB,GAAI,MAAM,QAAQ,EAAW,WAAW,GAAG,EAAW,aAAa,EAAE;EACrE,GAAI,EAAW,YAAY,CAAC,EAAW,UAAU,GAAG,EAAE;EACtD,GAAI,MAAM,QAAQ,EAAmB,GACjC,EAAmB,QAAQ,MAA2B,OAAO,KAAU,SAAS,GAChF,EAAE;EACP,EACK,IAAe,IAAI,IAAI,EAAW,CAAC;AAMzC,QAJI,MAAiB,IACZ,EAAE,GAGJ,CAAC,GAAG,EAAa,UAAU,MAAiB,IAAI,KAAK,IAAI,WAAW"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"projectTags.js","names":[],"sources":["../../src/utils/projectTags.ts"],"sourcesContent":["import type { TagItem } from '@burdenoff/fe-libs/tag';\n\nimport type { Project, ProjectTag } from '../types';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction asOptionalString(value: unknown): string | null | undefined {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;\n}\n\nexport function normalizeProjectTags(value: unknown): ProjectTag[] {\n if (!Array.isArray(value)) {\n return [];\n }\n\n return value.flatMap((entry) => {\n if (!isRecord(entry)) {\n return [];\n }\n\n const id = asOptionalString(entry['tagId']) ?? asOptionalString(entry['id']);\n const key = asOptionalString(entry['key']);\n const label = asOptionalString(entry['label']) ?? asOptionalString(entry['name']);\n\n if (!id || !key || !label) {\n return [];\n }\n\n return [\n {\n id,\n tagId: id,\n key,\n label,\n value: asOptionalString(entry['value']) ?? null,\n vocabularyId: asOptionalString(entry['vocabularyId']) ?? null,\n vocabularyKey: asOptionalString(entry['vocabularyKey']) ?? null,\n parentTagId: asOptionalString(entry['parentTagId']) ?? null,\n hierarchyPath: asOptionalString(entry['hierarchyPath']) ?? null,\n color: asOptionalString(entry['color']) ?? null,\n icon: asOptionalString(entry['icon']) ?? null,\n description: asOptionalString(entry['description']) ?? null,\n metadata: isRecord(entry['metadata']) ? entry['metadata'] : null,\n } satisfies ProjectTag,\n ];\n });\n}\n\nexport function normalizeProjectTagAssignments(value: unknown): ProjectTag[] {\n if (!Array.isArray(value)) {\n return [];\n }\n\n return value.flatMap((entry) => {\n if (!isRecord(entry)) {\n return [];\n }\n\n const tagRecord = isRecord(entry['tag']) ? entry['tag'] : null;\n const tagId = asOptionalString(entry['tagId']);\n const id = tagId ?? (tagRecord ? asOptionalString(tagRecord['id']) : undefined);\n const key = tagRecord ? asOptionalString(tagRecord['key']) : undefined;\n const label = tagRecord\n ? (asOptionalString(tagRecord['label']) ?? asOptionalString(tagRecord['name']))\n : undefined;\n\n if (!id || !tagId || !key || !label) {\n return [];\n }\n\n const vocabularyRecord =\n tagRecord && isRecord(tagRecord['vocabulary']) ? tagRecord['vocabulary'] : null;\n\n return [\n {\n id,\n tagId,\n key,\n label,\n value: tagRecord ? (asOptionalString(tagRecord['value']) ?? null) : null,\n vocabularyId: tagRecord ? (asOptionalString(tagRecord['vocabularyId']) ?? null) : null,\n vocabularyKey: vocabularyRecord\n ? (asOptionalString(vocabularyRecord['key']) ?? null)\n : null,\n parentTagId: tagRecord ? (asOptionalString(tagRecord['parentId']) ?? null) : null,\n hierarchyPath: tagRecord ? (asOptionalString(tagRecord['hierarchyPath']) ?? null) : null,\n color: tagRecord ? (asOptionalString(tagRecord['color']) ?? null) : null,\n icon: tagRecord ? (asOptionalString(tagRecord['icon']) ?? null) : null,\n description: tagRecord ? (asOptionalString(tagRecord['description']) ?? null) : null,\n metadata: isRecord(entry['metadata']) ? entry['metadata'] : null,\n } satisfies ProjectTag,\n ];\n });\n}\n\nexport function getProjectDisplayTags(\n project: Pick<Project, 'tags' | 'tagAssignments'> | null | undefined\n): ProjectTag[] {\n if (project?.tagAssignments !== undefined) {\n return normalizeProjectTagAssignments(project.tagAssignments);\n }\n\n return normalizeProjectTags(project?.tags);\n}\n\nexport function toProjectTag(tag: TagItem): ProjectTag {\n return {\n id: tag.id,\n tagId: tag.id,\n key: tag.key,\n label: tag.label,\n value: tag.value ?? null,\n vocabularyId: tag.vocabularyId ?? null,\n vocabularyKey: tag.vocabularyKey ?? tag.vocabulary?.key ?? null,\n parentTagId: tag.parentId ?? null,\n hierarchyPath: tag.hierarchyPath ?? null,\n color: tag.color ?? null,\n icon: tag.icon ?? null,\n description: tag.description ?? null,\n metadata: null,\n };\n}\n"],"mappings":"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"}
|
package/dist/utils/slug.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"slug.js","names":[],"sources":["../../src/utils/slug.ts"],"sourcesContent":["/**\n * Slug utility functions\n *\n * Shared utilities for generating URL-friendly slugs\n */\n\n/**\n * Generate a URL-friendly slug from a name\n *\n * @param name - The name to convert to a slug\n * @returns A lowercase, hyphenated string suitable for URLs\n */\nexport function generateSlug(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .substring(0, 50);\n}\n"],"mappings":";AAYA,SAAgB,EAAa,GAAsB;AACjD,QAAO,EACJ,aAAa,CACb,QAAQ,eAAe,IAAI,CAC3B,QAAQ,YAAY,GAAG,CACvB,UAAU,GAAG,GAAG"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"telemetryError.js","names":[],"sources":["../../src/utils/telemetryError.ts"],"sourcesContent":["/**\n * Build a payload-safe error string for the event bus / OtelBrowserSink.\n *\n * Apollo errors expose a `graphQLErrors[*].message` array — these are the\n * server-sanitized messages. For native Errors and arbitrary throws we fall\n * back to `.message` / String coercion. Everything is capped at 200 chars\n * so stack frames or SQL fragments that slip through don't end up in audit\n * sinks. Keep in sync with SRE guide §7.\n *\n * Trust assumption: server error messages are assumed sanitized. Callers\n * MUST NOT pass raw user input through this helper — its job is to bound\n * the size and shape, not to scrub PII.\n */\nconst MAX_TELEMETRY_ERROR_LEN = 200;\n\ninterface ApolloErrorLike {\n graphQLErrors?: Array<{ message: string }>;\n networkError?: Error & { statusCode?: number };\n message: string;\n}\n\nfunction isApolloErrorLike(err: unknown): err is ApolloErrorLike {\n if (typeof err !== 'object' || err === null) return false;\n const e = err as Record<string, unknown>;\n // Must look like an Apollo error in shape, not just key-presence:\n // - `graphQLErrors`, when present, must be an array (null / wrong-type\n // versions of the property silently passed the old guard).\n // - `networkError`, when present, must be an Error instance.\n // - `message` must be a string (Apollo always sets one).\n if (typeof e['message'] !== 'string') return false;\n const hasArrayGqlErrors = Array.isArray(e['graphQLErrors']);\n const hasErrorNetwork = e['networkError'] instanceof Error;\n return hasArrayGqlErrors || hasErrorNetwork;\n}\n\nfunction rawMessage(err: unknown): string {\n if (err == null) return 'An unknown error occurred';\n if (isApolloErrorLike(err)) {\n if (err.graphQLErrors && err.graphQLErrors.length > 0) {\n // Filter out anything without a string message — wrong-shape entries\n // would otherwise stringify to \"undefined\" and dilute the output.\n const messages = err.graphQLErrors.flatMap((e) =>\n typeof e?.message === 'string' && e.message.length > 0 ? [e.message] : []\n );\n if (messages.length > 0) return messages.join(', ');\n }\n if (err.networkError) {\n return 'Network error. Please check your connection.';\n }\n return err.message;\n }\n if (err instanceof Error) return err.message;\n if (typeof err === 'string') return err;\n return String(err);\n}\n\nexport function safeTelemetryError(err: unknown): string {\n const msg = rawMessage(err);\n if (msg.length <= MAX_TELEMETRY_ERROR_LEN) return msg;\n return `${msg.slice(0, MAX_TELEMETRY_ERROR_LEN - 1)}…`;\n}\n"],"mappings":";AAaA,IAAM,IAA0B;AAQhC,SAAS,EAAkB,GAAsC;AAC/D,KAAI,OAAO,KAAQ,aAAY,EAAc,QAAO;CACpD,IAAM,IAAI;AAMV,KAAI,OAAO,EAAE,WAAe,SAAU,QAAO;CAC7C,IAAM,IAAoB,MAAM,QAAQ,EAAE,cAAiB,EACrD,IAAkB,EAAE,wBAA2B;AACrD,QAAO,KAAqB;;AAG9B,SAAS,EAAW,GAAsB;AACxC,KAAI,KAAO,KAAM,QAAO;AACxB,KAAI,EAAkB,EAAI,EAAE;AAC1B,MAAI,EAAI,iBAAiB,EAAI,cAAc,SAAS,GAAG;GAGrD,IAAM,IAAW,EAAI,cAAc,SAAS,MAC1C,OAAO,GAAG,WAAY,YAAY,EAAE,QAAQ,SAAS,IAAI,CAAC,EAAE,QAAQ,GAAG,EAAE,CAC1E;AACD,OAAI,EAAS,SAAS,EAAG,QAAO,EAAS,KAAK,KAAK;;AAKrD,SAHI,EAAI,eACC,iDAEF,EAAI;;AAIb,QAFI,aAAe,QAAc,EAAI,UACjC,OAAO,KAAQ,WAAiB,IAC7B,OAAO,EAAI;;AAGpB,SAAgB,EAAmB,GAAsB;CACvD,IAAM,IAAM,EAAW,EAAI;AAE3B,QADI,EAAI,UAAU,IAAgC,IAC3C,GAAG,EAAI,MAAM,GAAG,IAA0B,EAAE,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tokenHelpers.js","names":[],"sources":["../../src/utils/tokenHelpers.ts"],"sourcesContent":["/**\n * Token-based style helpers for Workspaces module\n *\n * These helpers map domain concepts (workspace status, project status, member roles)\n * to semantic tokens, ensuring consistent, theme-aware styling across components.\n *\n * @module workspaces/utils/tokenHelpers\n */\n\nimport type { WorkspaceStatus, ProjectStatus, WorkspaceRole } from '../types';\n\n/**\n * Get semantic token classes for workspace status badges\n *\n * Uses semantic tokens that automatically adapt to theme (light/dark)\n * and brand (workspaces, fluidgrids, etc.)\n *\n * @param status - The workspace status\n * @returns Tailwind class string with semantic token classes\n *\n * @example\n * ```tsx\n * <Badge className={getWorkspaceStatusClasses('ACTIVE')}>\n * ACTIVE\n * </Badge>\n * ```\n */\nexport function getWorkspaceStatusClasses(status: WorkspaceStatus): string {\n const statusClasses: Record<WorkspaceStatus, string> = {\n ACTIVE:\n 'bg-workspace-active-bgSubtle text-workspace-active-text border-workspace-active-border',\n SUSPENDED:\n 'bg-workspace-suspended-bgSubtle text-workspace-suspended-text border-workspace-suspended-border',\n ARCHIVED:\n 'bg-workspace-archived-bgSubtle text-workspace-archived-text border-workspace-archived-border',\n DELETED:\n 'bg-workspace-deleted-bgSubtle text-workspace-deleted-text border-workspace-deleted-border',\n };\n\n return statusClasses[status] || statusClasses.ARCHIVED;\n}\n\n/**\n * Get semantic token classes for project status badges\n *\n * @param status - The project status\n * @returns Tailwind class string with semantic token classes\n *\n * @example\n * ```tsx\n * <Badge className={getProjectStatusClasses('ACTIVE')}>\n * ACTIVE\n * </Badge>\n * ```\n */\nexport function getProjectStatusClasses(status: ProjectStatus): string {\n const statusClasses: Record<ProjectStatus, string> = {\n ACTIVE: 'bg-project-active-bgSubtle text-project-active-text border-project-active-border',\n INACTIVE:\n 'bg-project-inactive-bgSubtle text-project-inactive-text border-project-inactive-border',\n ARCHIVED:\n 'bg-workspace-archived-bgSubtle text-workspace-archived-text border-workspace-archived-border',\n };\n\n return statusClasses[status] || statusClasses.INACTIVE;\n}\n\n/**\n * Get semantic token classes for member role badges\n *\n * @param role - The workspace member role\n * @returns Tailwind class string with semantic token classes\n *\n * @example\n * ```tsx\n * <Badge className={getMemberRoleClasses('owner')}>\n * Owner\n * </Badge>\n * ```\n */\nexport function getMemberRoleClasses(role: WorkspaceRole): string {\n const roleClasses: Record<WorkspaceRole, string> = {\n owner: 'bg-role-owner-bgSubtle text-role-owner-text border-role-owner-border',\n admin: 'bg-role-admin-bgSubtle text-role-admin-text border-role-admin-border',\n member: 'bg-role-member-bgSubtle text-role-member-text border-role-member-border',\n guest: 'bg-role-member-bgSubtle text-role-member-text border-role-member-border', // Guest uses member styling\n };\n\n return roleClasses[role] || roleClasses.member;\n}\n\n/**\n * Get semantic icon color class for workspace status\n *\n * Used for status indicator icons that need to match the status color\n *\n * @param status - The workspace status\n * @returns Tailwind class string for text color\n *\n * @example\n * ```tsx\n * <CheckCircle className={getWorkspaceStatusIconClass('ACTIVE')} size={16} />\n * ```\n */\nexport function getWorkspaceStatusIconClass(status: WorkspaceStatus): string {\n const iconClasses: Record<WorkspaceStatus, string> = {\n ACTIVE: 'text-workspace-active-text',\n SUSPENDED: 'text-workspace-suspended-text',\n ARCHIVED: 'text-workspace-archived-text',\n DELETED: 'text-workspace-deleted-text',\n };\n\n return iconClasses[status] || iconClasses.ARCHIVED;\n}\n\n/**\n * Get semantic icon color class for project status\n *\n * @param status - The project status\n * @returns Tailwind class string for text color\n *\n * @example\n * ```tsx\n * <Circle className={getProjectStatusIconClass(project.status)} size={12} />\n * ```\n */\nexport function getProjectStatusIconClass(status: ProjectStatus): string {\n const iconClasses: Record<ProjectStatus, string> = {\n ACTIVE: 'text-project-active-text',\n INACTIVE: 'text-project-inactive-text',\n ARCHIVED: 'text-workspace-archived-text',\n };\n\n return iconClasses[status] || iconClasses.INACTIVE;\n}\n\n/**\n * Get semantic background class for workspace status (for larger areas)\n *\n * @param status - The workspace status\n * @returns Tailwind class string for background color\n *\n * @example\n * ```tsx\n * <div className={getWorkspaceStatusBgClass('SUSPENDED')}>\n * Workspace is suspended\n * </div>\n * ```\n */\nexport function getWorkspaceStatusBgClass(status: WorkspaceStatus): string {\n const bgClasses: Record<WorkspaceStatus, string> = {\n ACTIVE: 'bg-workspace-active-bg',\n SUSPENDED: 'bg-workspace-suspended-bg',\n ARCHIVED: 'bg-workspace-archived-bg',\n DELETED: 'bg-workspace-deleted-bg',\n };\n\n return bgClasses[status] || bgClasses.ARCHIVED;\n}\n\n/**\n * Get human-readable label for workspace status\n *\n * @param status - The workspace status\n * @returns Formatted status label\n *\n * @example\n * ```tsx\n * getWorkspaceStatusLabel('ACTIVE') // \"Active\"\n * ```\n */\nexport function getWorkspaceStatusLabel(status: WorkspaceStatus): string {\n const labels: Record<WorkspaceStatus, string> = {\n ACTIVE: 'Active',\n SUSPENDED: 'Suspended',\n ARCHIVED: 'Archived',\n DELETED: 'Deleted',\n };\n\n return labels[status] || status;\n}\n\n/**\n * Get human-readable label for project status\n *\n * @param status - The project status\n * @returns Formatted status label\n */\nexport function getProjectStatusLabel(status: ProjectStatus): string {\n const labels: Record<ProjectStatus, string> = {\n ACTIVE: 'Active',\n INACTIVE: 'Inactive',\n ARCHIVED: 'Archived',\n };\n\n return labels[status] || status;\n}\n\n/**\n * Get human-readable label for member role\n *\n * @param role - The workspace member role\n * @returns Formatted role label\n */\nexport function getMemberRoleLabel(role: WorkspaceRole): string {\n const labels: Record<WorkspaceRole, string> = {\n owner: 'Owner',\n admin: 'Admin',\n member: 'Member',\n guest: 'Guest',\n };\n\n return labels[role] || role;\n}\n"],"mappings":";AA2BA,SAAgB,EAA0B,GAAiC;CACzE,IAAM,IAAiD;EACrD,QACE;EACF,WACE;EACF,UACE;EACF,SACE;EACH;AAED,QAAO,EAAc,MAAW,EAAc;;AAgBhD,SAAgB,EAAwB,GAA+B;CACrE,IAAM,IAA+C;EACnD,QAAQ;EACR,UACE;EACF,UACE;EACH;AAED,QAAO,EAAc,MAAW,EAAc;;AAgBhD,SAAgB,EAAqB,GAA6B;CAChE,IAAM,IAA6C;EACjD,OAAO;EACP,OAAO;EACP,QAAQ;EACR,OAAO;EACR;AAED,QAAO,EAAY,MAAS,EAAY;;AAgB1C,SAAgB,EAA4B,GAAiC;CAC3E,IAAM,IAA+C;EACnD,QAAQ;EACR,WAAW;EACX,UAAU;EACV,SAAS;EACV;AAED,QAAO,EAAY,MAAW,EAAY;;AAc5C,SAAgB,EAA0B,GAA+B;CACvE,IAAM,IAA6C;EACjD,QAAQ;EACR,UAAU;EACV,UAAU;EACX;AAED,QAAO,EAAY,MAAW,EAAY;;AAgB5C,SAAgB,EAA0B,GAAiC;CACzE,IAAM,IAA6C;EACjD,QAAQ;EACR,WAAW;EACX,UAAU;EACV,SAAS;EACV;AAED,QAAO,EAAU,MAAW,EAAU;;AAcxC,SAAgB,EAAwB,GAAiC;AAQvE,QAPgD;EAC9C,QAAQ;EACR,WAAW;EACX,UAAU;EACV,SAAS;EACV,CAEa,MAAW;;AAS3B,SAAgB,EAAsB,GAA+B;AAOnE,QAN8C;EAC5C,QAAQ;EACR,UAAU;EACV,UAAU;EACX,CAEa,MAAW;;AAS3B,SAAgB,EAAmB,GAA6B;AAQ9D,QAP8C;EAC5C,OAAO;EACP,OAAO;EACP,QAAQ;EACR,OAAO;EACR,CAEa,MAAS"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workspaceBulkInviteCsv.js","names":[],"sources":["../../src/utils/workspaceBulkInviteCsv.ts"],"sourcesContent":["const EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\nexport interface WorkspaceBulkInviteRow {\n rowNumber: number;\n email: string;\n errors: string[];\n}\n\nfunction splitCsvLine(line: string): string[] {\n const fields: string[] = [];\n let current = '';\n let inQuotes = false;\n\n for (let i = 0; i < line.length; i += 1) {\n const ch = line[i];\n if (inQuotes) {\n if (ch === '\"') {\n if (line[i + 1] === '\"') {\n current += '\"';\n i += 1;\n } else {\n inQuotes = false;\n }\n } else {\n current += ch;\n }\n } else if (ch === '\"') {\n inQuotes = true;\n } else if (ch === ',') {\n fields.push(current);\n current = '';\n } else {\n current += ch;\n }\n }\n\n fields.push(current);\n return fields.map((field) => field.trim());\n}\n\nexport function parseWorkspaceBulkInviteCsv(text: string): WorkspaceBulkInviteRow[] {\n const lines = text\n .replace(/^\\uFEFF/, '')\n .split(/\\r?\\n/)\n .filter((line) => line.trim().length > 0);\n\n if (lines.length === 0) {\n return [];\n }\n\n const header = splitCsvLine(lines[0]).map((column) => column.toLowerCase());\n const emailIdx = header.indexOf('email');\n\n if (emailIdx === -1) {\n return [\n {\n rowNumber: 1,\n email: '',\n errors: ['CSV header must include an \"email\" column.'],\n },\n ];\n }\n\n const seen = new Set<string>();\n\n return lines.slice(1).map((line, index) => {\n const rowNumber = index + 2;\n const fields = splitCsvLine(line);\n const email = (fields[emailIdx] ?? '').trim().toLowerCase();\n const errors: string[] = [];\n\n if (!email) {\n errors.push('Email is required.');\n } else if (!EMAIL_RE.test(email)) {\n errors.push('Invalid email format.');\n } else if (seen.has(email)) {\n errors.push('Duplicate email in this CSV.');\n } else {\n seen.add(email);\n }\n\n return {\n rowNumber,\n email,\n errors,\n };\n });\n}\n\nexport const WORKSPACE_BULK_INVITE_TEMPLATE_FILENAME = 'workspace-invite-template.csv';\n\nexport const WORKSPACE_BULK_INVITE_TEMPLATE_CONTENT = [\n 'email',\n 'alice@example.com',\n 'bob@example.com',\n].join('\\n');\n\nexport function downloadWorkspaceBulkInviteTemplate(): void {\n const blob = new Blob([WORKSPACE_BULK_INVITE_TEMPLATE_CONTENT], {\n type: 'text/csv;charset=utf-8',\n });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = WORKSPACE_BULK_INVITE_TEMPLATE_FILENAME;\n document.body.appendChild(anchor);\n anchor.click();\n document.body.removeChild(anchor);\n URL.revokeObjectURL(url);\n}\n"],"mappings":";AAAA,IAAM,IAAW;AAQjB,SAAS,EAAa,GAAwB;CAC5C,IAAM,IAAmB,EAAE,EACvB,IAAU,IACV,IAAW;AAEf,MAAK,IAAI,IAAI,GAAG,IAAI,EAAK,QAAQ,KAAK,GAAG;EACvC,IAAM,IAAK,EAAK;AAChB,EAAI,IACE,MAAO,OACL,EAAK,IAAI,OAAO,QAClB,KAAW,MACX,KAAK,KAEL,IAAW,KAGb,KAAW,IAEJ,MAAO,OAChB,IAAW,KACF,MAAO,OAChB,EAAO,KAAK,EAAQ,EACpB,IAAU,MAEV,KAAW;;AAKf,QADA,EAAO,KAAK,EAAQ,EACb,EAAO,KAAK,MAAU,EAAM,MAAM,CAAC;;AAG5C,SAAgB,EAA4B,GAAwC;CAClF,IAAM,IAAQ,EACX,QAAQ,WAAW,GAAG,CACtB,MAAM,QAAQ,CACd,QAAQ,MAAS,EAAK,MAAM,CAAC,SAAS,EAAE;AAE3C,KAAI,EAAM,WAAW,EACnB,QAAO,EAAE;CAIX,IAAM,IADS,EAAa,EAAM,GAAG,CAAC,KAAK,MAAW,EAAO,aAAa,CAAC,CACnD,QAAQ,QAAQ;AAExC,KAAI,MAAa,GACf,QAAO,CACL;EACE,WAAW;EACX,OAAO;EACP,QAAQ,CAAC,+CAA6C;EACvD,CACF;CAGH,IAAM,oBAAO,IAAI,KAAa;AAE9B,QAAO,EAAM,MAAM,EAAE,CAAC,KAAK,GAAM,MAAU;EACzC,IAAM,IAAY,IAAQ,GAEpB,KADS,EAAa,EAAK,CACX,MAAa,IAAI,MAAM,CAAC,aAAa,EACrD,IAAmB,EAAE;AAY3B,SAVK,IAEO,EAAS,KAAK,EAAM,GAErB,EAAK,IAAI,EAAM,GACxB,EAAO,KAAK,+BAA+B,GAE3C,EAAK,IAAI,EAAM,GAJf,EAAO,KAAK,wBAAwB,GAFpC,EAAO,KAAK,qBAAqB,EAS5B;GACL;GACA;GACA;GACD;GACD;;AAGJ,IAAa,IAA0C,iCAE1C,IAAyC;CACpD;CACA;CACA;CACD,CAAC,KAAK,KAAK;AAEZ,SAAgB,IAA4C;CAC1D,IAAM,IAAO,IAAI,KAAK,CAAC,EAAuC,EAAE,EAC9D,MAAM,0BACP,CAAC,EACI,IAAM,IAAI,gBAAgB,EAAK,EAC/B,IAAS,SAAS,cAAc,IAAI;AAM1C,CALA,EAAO,OAAO,GACd,EAAO,WAAW,GAClB,SAAS,KAAK,YAAY,EAAO,EACjC,EAAO,OAAO,EACd,SAAS,KAAK,YAAY,EAAO,EACjC,IAAI,gBAAgB,EAAI"}
|