@burdenoff/microfe-admin 2026.610.1 → 2026.624.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/admin/components/AccessDenied.js +2 -2
- package/dist/admin/components/AccessDenied.js.map +1 -1
- package/dist/admin/components/ActivityFeed.js +4 -4
- package/dist/admin/components/ActivityFeed.js.map +1 -1
- package/dist/admin/components/Charts.js +4 -4
- package/dist/admin/components/Charts.js.map +1 -1
- package/dist/admin/components/ConfirmDialog.js +6 -6
- package/dist/admin/components/ConfirmDialog.js.map +1 -1
- package/dist/admin/components/DataTable.js +7 -7
- package/dist/admin/components/DataTable.js.map +1 -1
- package/dist/admin/components/FormSheet.js +7 -7
- package/dist/admin/components/FormSheet.js.map +1 -1
- package/dist/admin/components/MetricCard.js +4 -4
- package/dist/admin/components/MetricCard.js.map +1 -1
- package/dist/admin/components/PageLayout.js +3 -3
- package/dist/admin/components/PageLayout.js.map +1 -1
- package/dist/admin/components/PermissionGuard.js +1 -1
- package/dist/admin/components/PermissionGuard.js.map +1 -1
- package/dist/admin/components/RowActions.js +2 -2
- package/dist/admin/components/RowActions.js.map +1 -1
- package/dist/admin/components/TenantMembersPanel.js +15 -15
- package/dist/admin/components/TenantMembersPanel.js.map +1 -1
- package/dist/admin/components/TenantSsoPanel.js +14 -14
- package/dist/admin/components/TenantSsoPanel.js.map +1 -1
- package/dist/admin/components/Toast.js +9 -9
- package/dist/admin/components/Toast.js.map +1 -1
- package/dist/admin/components/forms/SubscriptionForm.js +10 -10
- package/dist/admin/components/forms/SubscriptionForm.js.map +1 -1
- package/dist/admin/components/forms/TenantForm.js +8 -8
- package/dist/admin/components/forms/TenantForm.js.map +1 -1
- package/dist/admin/components/forms/TicketForm.js +2 -2
- package/dist/admin/components/forms/TicketForm.js.map +1 -1
- package/dist/admin/components/forms/UserForm.js +8 -8
- package/dist/admin/components/forms/UserForm.js.map +1 -1
- package/dist/admin/components/ui.js +16 -16
- package/dist/admin/components/ui.js.map +1 -1
- package/dist/admin/constants/index.js +8 -8
- package/dist/admin/constants/index.js.map +1 -1
- package/dist/admin/pages/AuditLogsPage.js +8 -8
- package/dist/admin/pages/AuditLogsPage.js.map +1 -1
- package/dist/admin/pages/CommunicationsPage.js +2 -2
- package/dist/admin/pages/CommunicationsPage.js.map +1 -1
- package/dist/admin/pages/FeatureFlagsPage.js +4 -4
- package/dist/admin/pages/FeatureFlagsPage.js.map +1 -1
- package/dist/admin/pages/OrganizationsListPage.js +6 -6
- package/dist/admin/pages/OrganizationsListPage.js.map +1 -1
- package/dist/admin/pages/ProductsPage.js +7 -7
- package/dist/admin/pages/ProductsPage.js.map +1 -1
- package/dist/admin/pages/ReferralsPage.js +23 -23
- package/dist/admin/pages/ReferralsPage.js.map +1 -1
- package/dist/admin/pages/RolesPermissionsPage.js +8 -8
- package/dist/admin/pages/RolesPermissionsPage.js.map +1 -1
- package/dist/admin/pages/SREPage.js +8 -8
- package/dist/admin/pages/SREPage.js.map +1 -1
- package/dist/admin/pages/SandboxSettingsPage.js +20 -20
- package/dist/admin/pages/SandboxSettingsPage.js.map +1 -1
- package/dist/admin/pages/SettingsPage.js +20 -20
- package/dist/admin/pages/SettingsPage.js.map +1 -1
- package/dist/admin/pages/SyncFailuresPage.js +11 -11
- package/dist/admin/pages/SyncFailuresPage.js.map +1 -1
- package/dist/admin/pages/TenantDetailPage.js +22 -22
- package/dist/admin/pages/TenantDetailPage.js.map +1 -1
- package/dist/admin/pages/TenantFormRoutePage.js +2 -2
- package/dist/admin/pages/TenantFormRoutePage.js.map +1 -1
- package/dist/admin/pages/TenantsListPage.js +5 -5
- package/dist/admin/pages/TenantsListPage.js.map +1 -1
- package/dist/admin/pages/UsersListPage.js +6 -6
- package/dist/admin/pages/UsersListPage.js.map +1 -1
- package/dist/admin/pages/WaitlistPage.js +7 -7
- package/dist/admin/pages/WaitlistPage.js.map +1 -1
- package/dist/admin/pages/WorkflowsPage.js +3 -3
- package/dist/admin/pages/WorkflowsPage.js.map +1 -1
- package/dist/admin/pages/WorkspacesListPage.js +8 -8
- package/dist/admin/pages/WorkspacesListPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WaitlistPage.js","names":[],"sources":["../../../src/admin/pages/WaitlistPage.tsx"],"sourcesContent":["import { useState, useMemo, useCallback, useEffect } from 'react';\nimport { ClipboardList, Search, Check, X, Trash2 } from 'lucide-react';\nimport { useAdminPermissions } from '../hooks/useAdminPermissions';\nimport {\n PageLayout,\n Input,\n DataTable,\n Pagination,\n EmptyState,\n Badge,\n PermissionGuard,\n} from '../components';\nimport { formatDate } from '../utils/formatters';\nimport { useGatewayClient } from '@burdenoff/fe-libs/shared/graphql';\nimport { gql } from '@apollo/client';\n\nconst PAGE_SIZE = 20;\n\ntype WaitlistStatus = 'PENDING' | 'APPROVED' | 'REJECTED';\n\nconst STATUS_VARIANT: Record<WaitlistStatus, 'default' | 'secondary' | 'outline' | 'destructive'> =\n {\n PENDING: 'outline',\n APPROVED: 'default',\n REJECTED: 'destructive',\n };\n\nconst GET_WAITLIST = gql`\n query GetWaitlist($filter: WaitlistFilterInput) {\n waitlist(filter: $filter) {\n id\n email\n name\n company\n platformProductId\n status\n reason\n rejectionReason\n processedAt\n processedBy\n createdAt\n }\n }\n`;\n\nconst APPROVE_WAITLIST = gql`\n mutation ApproveWaitlist($input: ApproveWaitlistInput!) {\n approveWaitlist(input: $input) {\n id\n status\n }\n }\n`;\n\nconst REJECT_WAITLIST = gql`\n mutation RejectWaitlist($input: RejectWaitlistInput!) {\n rejectWaitlist(input: $input) {\n id\n status\n }\n }\n`;\n\nconst REMOVE_WAITLIST = gql`\n mutation RemoveFromWaitlist($id: ID!) {\n removeFromWaitlist(id: $id)\n }\n`;\n\ntype WaitlistItem = {\n id: string;\n email: string;\n name: string | null;\n company: string | null;\n platformProductId: string;\n status: WaitlistStatus;\n reason: string | null;\n rejectionReason: string | null;\n processedAt: string | null;\n processedBy: string | null;\n createdAt: string;\n};\n\nexport function WaitlistPage() {\n const {\n canViewWaitlist,\n canManageWaitlist,\n isLoading: permissionsLoading,\n } = useAdminPermissions();\n const globalClient = useGatewayClient('global');\n\n const [page, setPage] = useState(1);\n const [search, setSearch] = useState('');\n const [statusFilter, setStatusFilter] = useState<WaitlistStatus | ''>('');\n const [data, setData] = useState<{ waitlist?: WaitlistItem[] } | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<{ message: string } | null>(null);\n const [fetchCount, setFetchCount] = useState(0);\n\n const filter = useMemo(() => {\n const f: Record<string, unknown> = {};\n if (statusFilter) f.status = statusFilter;\n return Object.keys(f).length > 0 ? f : undefined;\n }, [statusFilter]);\n\n const refetch = useCallback(() => setFetchCount((c) => c + 1), []);\n\n useEffect(() => {\n if (permissionsLoading || !canViewWaitlist) return;\n setLoading(true);\n globalClient\n .query({ query: GET_WAITLIST, variables: { filter }, fetchPolicy: 'network-only' })\n .then((result) => {\n const d = result.data as { waitlist?: WaitlistItem[] } | undefined;\n setData(d ?? null);\n setError(null);\n })\n .catch((err: Error) => setError({ message: err.message }))\n .finally(() => setLoading(false));\n }, [globalClient, filter, permissionsLoading, canViewWaitlist, fetchCount]);\n\n const allEntries: WaitlistItem[] = useMemo(\n () => (data?.waitlist ?? []) as WaitlistItem[],\n [data]\n );\n\n // Client-side search filter (email, name, company)\n const filtered = useMemo(() => {\n if (!search) return allEntries;\n const q = search.toLowerCase();\n return allEntries.filter(\n (e) =>\n e.email.toLowerCase().includes(q) ||\n (e.name && e.name.toLowerCase().includes(q)) ||\n (e.company && e.company.toLowerCase().includes(q))\n );\n }, [allEntries, search]);\n\n const total = filtered.length;\n const totalPages = Math.ceil(total / PAGE_SIZE);\n const paged = filtered.slice((page - 1) * PAGE_SIZE, page * PAGE_SIZE);\n\n const handleApprove = useCallback(\n async (id: string) => {\n await globalClient.mutate({ mutation: APPROVE_WAITLIST, variables: { input: { id } } });\n refetch();\n },\n [globalClient, refetch]\n );\n\n const handleReject = useCallback(\n async (id: string) => {\n const reason = window.prompt('Rejection reason (optional):');\n await globalClient.mutate({\n mutation: REJECT_WAITLIST,\n variables: { input: { id, reason } },\n });\n refetch();\n },\n [globalClient, refetch]\n );\n\n const handleRemove = useCallback(\n async (id: string) => {\n if (!window.confirm('Remove this waitlist entry?')) return;\n await globalClient.mutate({ mutation: REMOVE_WAITLIST, variables: { id } });\n refetch();\n },\n [globalClient, refetch]\n );\n\n const columns = [\n {\n key: 'email',\n header: 'Email',\n render: (e: WaitlistItem) => (\n <div className=\"min-w-0\">\n <div className=\"font-medium text-foreground\">{e.email}</div>\n {e.name && <div className=\"text-xs text-muted-foreground\">{e.name}</div>}\n </div>\n ),\n },\n {\n key: 'company',\n header: 'Company',\n width: '140px',\n render: (e: WaitlistItem) => (\n <span className=\"text-sm text-muted-foreground\">{e.company || '-'}</span>\n ),\n },\n {\n key: 'status',\n header: 'Status',\n width: '100px',\n render: (e: WaitlistItem) => (\n <Badge variant={STATUS_VARIANT[e.status] ?? 'outline'} className=\"text-xs capitalize\">\n {e.status.toLowerCase()}\n </Badge>\n ),\n },\n {\n key: 'createdAt',\n header: 'Joined',\n width: '110px',\n render: (e: WaitlistItem) => formatDate(e.createdAt),\n },\n ...(canManageWaitlist\n ? [\n {\n key: 'actions',\n header: 'Actions',\n width: '140px',\n render: (e: WaitlistItem) => (\n <div className=\"flex items-center gap-1\">\n {e.status === 'PENDING' && (\n <>\n <button\n onClick={() => handleApprove(e.id)}\n className=\"rounded p-1 text-green-500 hover:bg-green-500/10\"\n title=\"Approve\"\n >\n <Check className=\"h-4 w-4\" />\n </button>\n <button\n onClick={() => handleReject(e.id)}\n className=\"rounded p-1 text-red-500 hover:bg-red-500/10\"\n title=\"Reject\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n </>\n )}\n <button\n onClick={() => handleRemove(e.id)}\n className=\"rounded p-1 text-muted-foreground hover:bg-muted\"\n title=\"Remove\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </button>\n </div>\n ),\n },\n ]\n : []),\n ];\n\n return (\n <PermissionGuard\n allowed={canViewWaitlist}\n isLoading={permissionsLoading}\n pageTitle=\"Waitlist\"\n denyMessage=\"You don't have permission to view the waitlist.\"\n >\n <PageLayout\n title=\"Waitlist Management\"\n description={`Product waitlist entries${total ? ` \\u00b7 ${total} total` : ''}`}\n >\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"relative max-w-sm flex-1\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n placeholder=\"Search by email, name, or company...\"\n value={search}\n onChange={(e) => {\n setPage(1);\n setSearch(e.target.value);\n }}\n className=\"pl-9\"\n />\n </div>\n <select\n value={statusFilter}\n onChange={(e) => {\n setPage(1);\n setStatusFilter(e.target.value as WaitlistStatus | '');\n }}\n className=\"rounded-md border border-input bg-background px-3 py-2 text-sm\"\n >\n <option value=\"\">All statuses</option>\n <option value=\"PENDING\">Pending</option>\n <option value=\"APPROVED\">Approved</option>\n <option value=\"REJECTED\">Rejected</option>\n </select>\n </div>\n\n {error && (\n <div className=\"rounded-md border border-destructive/50 bg-destructive/10 p-4 text-sm text-destructive\">\n Failed to load waitlist: {error.message}\n </div>\n )}\n\n <DataTable\n columns={columns}\n data={paged}\n keyExtractor={(e) => e.id}\n loading={loading}\n emptyState={\n <EmptyState\n icon={<ClipboardList className=\"h-8 w-8\" />}\n title=\"No waitlist entries\"\n description=\"No entries match your current filters\"\n />\n }\n />\n\n {total > PAGE_SIZE && (\n <Pagination\n page={page}\n totalPages={totalPages}\n totalItems={total}\n pageSize={PAGE_SIZE}\n onPageChange={setPage}\n />\n )}\n </div>\n </PageLayout>\n </PermissionGuard>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WaitlistPage.js","names":[],"sources":["../../../src/admin/pages/WaitlistPage.tsx"],"sourcesContent":["import { useState, useMemo, useCallback, useEffect } from 'react';\nimport { ClipboardList, Search, Check, X, Trash2 } from 'lucide-react';\nimport { useAdminPermissions } from '../hooks/useAdminPermissions';\nimport {\n PageLayout,\n Input,\n DataTable,\n Pagination,\n EmptyState,\n Badge,\n PermissionGuard,\n} from '../components';\nimport { formatDate } from '../utils/formatters';\nimport { useGatewayClient } from '@burdenoff/fe-libs/shared/graphql';\nimport { gql } from '@apollo/client';\n\nconst PAGE_SIZE = 20;\n\ntype WaitlistStatus = 'PENDING' | 'APPROVED' | 'REJECTED';\n\nconst STATUS_VARIANT: Record<WaitlistStatus, 'default' | 'secondary' | 'outline' | 'destructive'> =\n {\n PENDING: 'outline',\n APPROVED: 'default',\n REJECTED: 'destructive',\n };\n\nconst GET_WAITLIST = gql`\n query GetWaitlist($filter: WaitlistFilterInput) {\n waitlist(filter: $filter) {\n id\n email\n name\n company\n platformProductId\n status\n reason\n rejectionReason\n processedAt\n processedBy\n createdAt\n }\n }\n`;\n\nconst APPROVE_WAITLIST = gql`\n mutation ApproveWaitlist($input: ApproveWaitlistInput!) {\n approveWaitlist(input: $input) {\n id\n status\n }\n }\n`;\n\nconst REJECT_WAITLIST = gql`\n mutation RejectWaitlist($input: RejectWaitlistInput!) {\n rejectWaitlist(input: $input) {\n id\n status\n }\n }\n`;\n\nconst REMOVE_WAITLIST = gql`\n mutation RemoveFromWaitlist($id: ID!) {\n removeFromWaitlist(id: $id)\n }\n`;\n\ntype WaitlistItem = {\n id: string;\n email: string;\n name: string | null;\n company: string | null;\n platformProductId: string;\n status: WaitlistStatus;\n reason: string | null;\n rejectionReason: string | null;\n processedAt: string | null;\n processedBy: string | null;\n createdAt: string;\n};\n\nexport function WaitlistPage() {\n const {\n canViewWaitlist,\n canManageWaitlist,\n isLoading: permissionsLoading,\n } = useAdminPermissions();\n const globalClient = useGatewayClient('global');\n\n const [page, setPage] = useState(1);\n const [search, setSearch] = useState('');\n const [statusFilter, setStatusFilter] = useState<WaitlistStatus | ''>('');\n const [data, setData] = useState<{ waitlist?: WaitlistItem[] } | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<{ message: string } | null>(null);\n const [fetchCount, setFetchCount] = useState(0);\n\n const filter = useMemo(() => {\n const f: Record<string, unknown> = {};\n if (statusFilter) f.status = statusFilter;\n return Object.keys(f).length > 0 ? f : undefined;\n }, [statusFilter]);\n\n const refetch = useCallback(() => setFetchCount((c) => c + 1), []);\n\n useEffect(() => {\n if (permissionsLoading || !canViewWaitlist) return;\n setLoading(true);\n globalClient\n .query({ query: GET_WAITLIST, variables: { filter }, fetchPolicy: 'network-only' })\n .then((result) => {\n const d = result.data as { waitlist?: WaitlistItem[] } | undefined;\n setData(d ?? null);\n setError(null);\n })\n .catch((err: Error) => setError({ message: err.message }))\n .finally(() => setLoading(false));\n }, [globalClient, filter, permissionsLoading, canViewWaitlist, fetchCount]);\n\n const allEntries: WaitlistItem[] = useMemo(\n () => (data?.waitlist ?? []) as WaitlistItem[],\n [data]\n );\n\n // Client-side search filter (email, name, company)\n const filtered = useMemo(() => {\n if (!search) return allEntries;\n const q = search.toLowerCase();\n return allEntries.filter(\n (e) =>\n e.email.toLowerCase().includes(q) ||\n (e.name && e.name.toLowerCase().includes(q)) ||\n (e.company && e.company.toLowerCase().includes(q))\n );\n }, [allEntries, search]);\n\n const total = filtered.length;\n const totalPages = Math.ceil(total / PAGE_SIZE);\n const paged = filtered.slice((page - 1) * PAGE_SIZE, page * PAGE_SIZE);\n\n const handleApprove = useCallback(\n async (id: string) => {\n await globalClient.mutate({ mutation: APPROVE_WAITLIST, variables: { input: { id } } });\n refetch();\n },\n [globalClient, refetch]\n );\n\n const handleReject = useCallback(\n async (id: string) => {\n const reason = window.prompt('Rejection reason (optional):');\n await globalClient.mutate({\n mutation: REJECT_WAITLIST,\n variables: { input: { id, reason } },\n });\n refetch();\n },\n [globalClient, refetch]\n );\n\n const handleRemove = useCallback(\n async (id: string) => {\n if (!window.confirm('Remove this waitlist entry?')) return;\n await globalClient.mutate({ mutation: REMOVE_WAITLIST, variables: { id } });\n refetch();\n },\n [globalClient, refetch]\n );\n\n const columns = [\n {\n key: 'email',\n header: 'Email',\n render: (e: WaitlistItem) => (\n <div className=\"min-w-0\">\n <div className=\"font-medium text-text-primary\">{e.email}</div>\n {e.name && <div className=\"text-xs text-text-secondary\">{e.name}</div>}\n </div>\n ),\n },\n {\n key: 'company',\n header: 'Company',\n width: '140px',\n render: (e: WaitlistItem) => (\n <span className=\"text-sm text-text-secondary\">{e.company || '-'}</span>\n ),\n },\n {\n key: 'status',\n header: 'Status',\n width: '100px',\n render: (e: WaitlistItem) => (\n <Badge variant={STATUS_VARIANT[e.status] ?? 'outline'} className=\"text-xs capitalize\">\n {e.status.toLowerCase()}\n </Badge>\n ),\n },\n {\n key: 'createdAt',\n header: 'Joined',\n width: '110px',\n render: (e: WaitlistItem) => formatDate(e.createdAt),\n },\n ...(canManageWaitlist\n ? [\n {\n key: 'actions',\n header: 'Actions',\n width: '140px',\n render: (e: WaitlistItem) => (\n <div className=\"flex items-center gap-1\">\n {e.status === 'PENDING' && (\n <>\n <button\n onClick={() => handleApprove(e.id)}\n className=\"rounded p-1 text-green-500 hover:bg-green-500/10\"\n title=\"Approve\"\n >\n <Check className=\"h-4 w-4\" />\n </button>\n <button\n onClick={() => handleReject(e.id)}\n className=\"rounded p-1 text-red-500 hover:bg-red-500/10\"\n title=\"Reject\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n </>\n )}\n <button\n onClick={() => handleRemove(e.id)}\n className=\"rounded p-1 text-text-secondary hover:bg-bg-sunken\"\n title=\"Remove\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </button>\n </div>\n ),\n },\n ]\n : []),\n ];\n\n return (\n <PermissionGuard\n allowed={canViewWaitlist}\n isLoading={permissionsLoading}\n pageTitle=\"Waitlist\"\n denyMessage=\"You don't have permission to view the waitlist.\"\n >\n <PageLayout\n title=\"Waitlist Management\"\n description={`Product waitlist entries${total ? ` \\u00b7 ${total} total` : ''}`}\n >\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"relative max-w-sm flex-1\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input\n placeholder=\"Search by email, name, or company...\"\n value={search}\n onChange={(e) => {\n setPage(1);\n setSearch(e.target.value);\n }}\n className=\"pl-9\"\n />\n </div>\n <select\n value={statusFilter}\n onChange={(e) => {\n setPage(1);\n setStatusFilter(e.target.value as WaitlistStatus | '');\n }}\n className=\"rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n >\n <option value=\"\">All statuses</option>\n <option value=\"PENDING\">Pending</option>\n <option value=\"APPROVED\">Approved</option>\n <option value=\"REJECTED\">Rejected</option>\n </select>\n </div>\n\n {error && (\n <div className=\"rounded-md border border-status-error-border/50 bg-status-error-bg/10 p-4 text-sm text-status-error-text\">\n Failed to load waitlist: {error.message}\n </div>\n )}\n\n <DataTable\n columns={columns}\n data={paged}\n keyExtractor={(e) => e.id}\n loading={loading}\n emptyState={\n <EmptyState\n icon={<ClipboardList className=\"h-8 w-8\" />}\n title=\"No waitlist entries\"\n description=\"No entries match your current filters\"\n />\n }\n />\n\n {total > PAGE_SIZE && (\n <Pagination\n page={page}\n totalPages={totalPages}\n totalItems={total}\n pageSize={PAGE_SIZE}\n onPageChange={setPage}\n />\n )}\n </div>\n </PageLayout>\n </PermissionGuard>\n );\n}\n"],"mappings":"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"}
|
|
@@ -55,7 +55,7 @@ function b() {
|
|
|
55
55
|
children: "Active Workflow Runs"
|
|
56
56
|
}), /* @__PURE__ */ y("div", {
|
|
57
57
|
className: "relative max-w-sm flex-1 ml-4",
|
|
58
|
-
children: [/* @__PURE__ */ v(_, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-
|
|
58
|
+
children: [/* @__PURE__ */ v(_, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary" }), /* @__PURE__ */ v(r, {
|
|
59
59
|
placeholder: "Search active runs...",
|
|
60
60
|
className: "pl-9"
|
|
61
61
|
})]
|
|
@@ -68,10 +68,10 @@ function b() {
|
|
|
68
68
|
render: (e) => /* @__PURE__ */ y("div", {
|
|
69
69
|
className: "flex flex-col",
|
|
70
70
|
children: [/* @__PURE__ */ v("span", {
|
|
71
|
-
className: "font-medium text-
|
|
71
|
+
className: "font-medium text-text-primary",
|
|
72
72
|
children: e.workflowName
|
|
73
73
|
}), /* @__PURE__ */ y("span", {
|
|
74
|
-
className: "text-xs text-
|
|
74
|
+
className: "text-xs text-text-secondary",
|
|
75
75
|
children: ["v", e.workflowVersion]
|
|
76
76
|
})]
|
|
77
77
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkflowsPage.js","names":[],"sources":["../../../src/admin/pages/WorkflowsPage.tsx"],"sourcesContent":["import { GitBranch, Search, Plus, Activity, AlertCircle, Clock, Play } from 'lucide-react';\nimport {\n PageLayout,\n Input,\n Button,\n EmptyState,\n MetricCard,\n MetricsGrid,\n DataTable,\n Badge,\n} from '../components';\nimport {\n useGetWorkflowSystemOverviewQuery,\n useListActiveWorkflowsQuery,\n} from '../../generated/wspace-operations';\nimport { formatDateTime } from '../utils/formatters';\n\nexport function WorkflowsPage() {\n const { data: overviewData, loading: overviewLoading } = useGetWorkflowSystemOverviewQuery();\n\n const { data: listData, loading: listLoading } = useListActiveWorkflowsQuery({\n variables: { limit: 10, offset: 0 },\n });\n\n const overview = overviewData?.systemOverview;\n const activeRuns = listData?.activeWorkflows || [];\n\n const columns = [\n {\n key: 'workflowName',\n header: 'Workflow',\n render: (run: any) => (\n <div className=\"flex flex-col\">\n <span className=\"font-medium text-
|
|
1
|
+
{"version":3,"file":"WorkflowsPage.js","names":[],"sources":["../../../src/admin/pages/WorkflowsPage.tsx"],"sourcesContent":["import { GitBranch, Search, Plus, Activity, AlertCircle, Clock, Play } from 'lucide-react';\nimport {\n PageLayout,\n Input,\n Button,\n EmptyState,\n MetricCard,\n MetricsGrid,\n DataTable,\n Badge,\n} from '../components';\nimport {\n useGetWorkflowSystemOverviewQuery,\n useListActiveWorkflowsQuery,\n} from '../../generated/wspace-operations';\nimport { formatDateTime } from '../utils/formatters';\n\nexport function WorkflowsPage() {\n const { data: overviewData, loading: overviewLoading } = useGetWorkflowSystemOverviewQuery();\n\n const { data: listData, loading: listLoading } = useListActiveWorkflowsQuery({\n variables: { limit: 10, offset: 0 },\n });\n\n const overview = overviewData?.systemOverview;\n const activeRuns = listData?.activeWorkflows || [];\n\n const columns = [\n {\n key: 'workflowName',\n header: 'Workflow',\n render: (run: any) => (\n <div className=\"flex flex-col\">\n <span className=\"font-medium text-text-primary\">{run.workflowName}</span>\n <span className=\"text-xs text-text-secondary\">v{run.workflowVersion}</span>\n </div>\n ),\n },\n {\n key: 'runId',\n header: 'Run ID',\n render: (run: any) => <code className=\"text-xs\">{run.runId.substring(0, 8)}...</code>,\n },\n {\n key: 'status',\n header: 'Status',\n render: (run: any) => {\n const variants: Record<\n string,\n 'default' | 'secondary' | 'success' | 'warning' | 'destructive' | 'outline'\n > = {\n RUNNING: 'success',\n PENDING: 'warning',\n FAILED: 'destructive',\n COMPLETED: 'default',\n };\n return <Badge variant={variants[run.status] || 'outline'}>{run.status}</Badge>;\n },\n },\n {\n key: 'currentNode',\n header: 'Current Node',\n },\n {\n key: 'createdAt',\n header: 'Started At',\n render: (run: any) => formatDateTime(run.createdAt),\n },\n ];\n\n return (\n <PageLayout\n title=\"Workflows\"\n description=\"Manage and monitor platform workflows\"\n actions={\n <Button>\n <Plus className=\"mr-2 h-4 w-4\" />\n Create Workflow\n </Button>\n }\n >\n <div className=\"space-y-8\">\n <MetricsGrid>\n <MetricCard\n title=\"Total Workflows\"\n value={overview?.totalWorkflows ?? 0}\n loading={overviewLoading}\n icon={<GitBranch className=\"h-4 w-4\" />}\n />\n <MetricCard\n title=\"Active Runs\"\n value={overview?.activeWorkflows ?? 0}\n loading={overviewLoading}\n icon={<Play className=\"h-4 w-4\" />}\n trend={overview?.activeWorkflows && overview.activeWorkflows > 0 ? 'up' : 'neutral'}\n />\n <MetricCard\n title=\"Failed (24h)\"\n value={overview?.failedWorkflows ?? 0}\n loading={overviewLoading}\n icon={<AlertCircle className=\"h-4 w-4\" />}\n priority={overview?.failedWorkflows && overview.failedWorkflows > 0 ? 'high' : 'normal'}\n />\n <MetricCard\n title=\"Queued Jobs\"\n value={overview?.queuedJobs ?? 0}\n loading={overviewLoading}\n icon={<Clock className=\"h-4 w-4\" />}\n />\n </MetricsGrid>\n\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold\">Active Workflow Runs</h2>\n <div className=\"relative max-w-sm flex-1 ml-4\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input placeholder=\"Search active runs...\" className=\"pl-9\" />\n </div>\n </div>\n\n <DataTable\n columns={columns}\n data={activeRuns as any[]}\n keyExtractor={(run) => run.runId}\n loading={listLoading}\n emptyState={\n <EmptyState\n icon={<Activity className=\"h-8 w-8\" />}\n title=\"No active workflows\"\n description=\"There are currently no workflows running in the system\"\n />\n }\n />\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;AAiBA,SAAgB,IAAgB;CAC9B,IAAM,EAAE,MAAM,GAAc,SAAS,MAAoB,GAAmC,EAEtF,EAAE,MAAM,GAAU,SAAS,MAAgB,EAA4B,EAC3E,WAAW;EAAE,OAAO;EAAI,QAAQ;EAAG,EACpC,CAAC,EAEI,IAAW,GAAc,gBACzB,IAAa,GAAU,mBAAmB,EAAE;AA6ClD,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAM,WAAU,gBAAiB,CAAA,EAAA,kBAE1B,EAAA,CAAA;YAGX,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD,EAAA,UAAA;IACE,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,GAAU,kBAAkB;KACnC,SAAS;KACT,MAAM,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA;KACvC,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,GAAU,mBAAmB;KACpC,SAAS;KACT,MAAM,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA;KAClC,OAAO,GAAU,mBAAmB,EAAS,kBAAkB,IAAI,OAAO;KAC1E,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,GAAU,mBAAmB;KACpC,SAAS;KACT,MAAM,kBAAC,GAAD,EAAa,WAAU,WAAY,CAAA;KACzC,UAAU,GAAU,mBAAmB,EAAS,kBAAkB,IAAI,SAAS;KAC/E,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,GAAU,cAAc;KAC/B,SAAS;KACT,MAAM,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;KACnC,CAAA;IACU,EAAA,CAAA,EAEd,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBAAwB;MAAyB,CAAA,EAC/D,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAQ,WAAU,wEAAyE,CAAA,EAC3F,kBAAC,GAAD;OAAO,aAAY;OAAwB,WAAU;OAAS,CAAA,CAC1D;QACF;QAEN,kBAAC,GAAD;KACW,SA9FH;MACd;OACE,KAAK;OACL,QAAQ;OACR,SAAS,MACP,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,QAAD;SAAM,WAAU;mBAAiC,EAAI;SAAoB,CAAA,EACzE,kBAAC,QAAD;SAAM,WAAU;mBAAhB,CAA8C,KAAE,EAAI,gBAAuB;WACvE;;OAET;MACD;OACE,KAAK;OACL,QAAQ;OACR,SAAS,MAAa,kBAAC,QAAD;QAAM,WAAU;kBAAhB,CAA2B,EAAI,MAAM,UAAU,GAAG,EAAE,EAAC,MAAU;;OACtF;MACD;OACE,KAAK;OACL,QAAQ;OACR,SAAS,MAUA,kBAAC,GAAD;QAAO,SANV;SACF,SAAS;SACT,SAAS;SACT,QAAQ;SACR,WAAW;SACZ,CAC+B,EAAI,WAAW;kBAAY,EAAI;QAAe,CAAA;OAEjF;MACD;OACE,KAAK;OACL,QAAQ;OACT;MACD;OACE,KAAK;OACL,QAAQ;OACR,SAAS,MAAa,EAAe,EAAI,UAAU;OACpD;MACF;KAsDS,MAAM;KACN,eAAe,MAAQ,EAAI;KAC3B,SAAS;KACT,YACE,kBAAC,GAAD;MACE,MAAM,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA;MACtC,OAAM;MACN,aAAY;MACZ,CAAA;KAEJ,CAAA,CACE;MACF;;EACK,CAAA"}
|
|
@@ -11,9 +11,9 @@ import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
|
11
11
|
//#region src/admin/pages/WorkspacesListPage.tsx
|
|
12
12
|
var h = {
|
|
13
13
|
[c.Active]: "bg-success/10 text-success border-success/20",
|
|
14
|
-
[c.Suspended]: "bg-
|
|
15
|
-
[c.Archived]: "bg-
|
|
16
|
-
[c.Deleted]: "bg-
|
|
14
|
+
[c.Suspended]: "bg-status-error-bg/10 text-status-error-text border-status-error-border/20",
|
|
15
|
+
[c.Archived]: "bg-bg-sunken text-text-secondary border-muted",
|
|
16
|
+
[c.Deleted]: "bg-status-error-bg/10 text-status-error-text border-status-error-border/20"
|
|
17
17
|
};
|
|
18
18
|
function g() {
|
|
19
19
|
let [c, g] = l(1), { data: _, loading: v, error: y } = s({ variables: {
|
|
@@ -31,7 +31,7 @@ function g() {
|
|
|
31
31
|
className: "flex items-center justify-between",
|
|
32
32
|
children: /* @__PURE__ */ m("div", {
|
|
33
33
|
className: "relative max-w-sm flex-1",
|
|
34
|
-
children: [/* @__PURE__ */ p(f, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-
|
|
34
|
+
children: [/* @__PURE__ */ p(f, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary" }), /* @__PURE__ */ p(r, {
|
|
35
35
|
placeholder: "Search workspaces...",
|
|
36
36
|
className: "pl-9"
|
|
37
37
|
})]
|
|
@@ -43,7 +43,7 @@ function g() {
|
|
|
43
43
|
key: "name",
|
|
44
44
|
header: "Workspace Name",
|
|
45
45
|
render: (e) => /* @__PURE__ */ p("div", {
|
|
46
|
-
className: "font-medium text-
|
|
46
|
+
className: "font-medium text-text-primary",
|
|
47
47
|
children: e.name
|
|
48
48
|
})
|
|
49
49
|
},
|
|
@@ -51,7 +51,7 @@ function g() {
|
|
|
51
51
|
key: "id",
|
|
52
52
|
header: "ID",
|
|
53
53
|
render: (e) => /* @__PURE__ */ p("code", {
|
|
54
|
-
className: "text-xs text-
|
|
54
|
+
className: "text-xs text-text-secondary",
|
|
55
55
|
children: e.id
|
|
56
56
|
})
|
|
57
57
|
},
|
|
@@ -71,13 +71,13 @@ function g() {
|
|
|
71
71
|
emptyState: /* @__PURE__ */ m("div", {
|
|
72
72
|
className: "flex flex-col items-center justify-center py-12 text-center",
|
|
73
73
|
children: [
|
|
74
|
-
/* @__PURE__ */ p(u, { className: "h-12 w-12 text-
|
|
74
|
+
/* @__PURE__ */ p(u, { className: "h-12 w-12 text-text-secondary/50 mb-4" }),
|
|
75
75
|
/* @__PURE__ */ p("h3", {
|
|
76
76
|
className: "text-lg font-medium",
|
|
77
77
|
children: "No workspaces found"
|
|
78
78
|
}),
|
|
79
79
|
/* @__PURE__ */ p("p", {
|
|
80
|
-
className: "text-
|
|
80
|
+
className: "text-text-secondary",
|
|
81
81
|
children: "Workspaces will appear here when they are created."
|
|
82
82
|
})
|
|
83
83
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkspacesListPage.js","names":[],"sources":["../../../src/admin/pages/WorkspacesListPage.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { Layout, Search, Plus } from 'lucide-react';\nimport { PageLayout, Input, Button, DataTable, Pagination } from '../components';\nimport { useListWorkspacesQuery } from '../../generated/global-operations';\nimport { WorkspaceStatus } from '../../generated/global-types';\nimport { Badge } from '../components/ui';\nimport { cn } from '../utils/cn';\n\nconst STATUS_STYLING: Record<WorkspaceStatus, string> = {\n [WorkspaceStatus.Active]: 'bg-success/10 text-success border-success/20',\n [WorkspaceStatus.Suspended]: 'bg-
|
|
1
|
+
{"version":3,"file":"WorkspacesListPage.js","names":[],"sources":["../../../src/admin/pages/WorkspacesListPage.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { Layout, Search, Plus } from 'lucide-react';\nimport { PageLayout, Input, Button, DataTable, Pagination } from '../components';\nimport { useListWorkspacesQuery } from '../../generated/global-operations';\nimport { WorkspaceStatus } from '../../generated/global-types';\nimport { Badge } from '../components/ui';\nimport { cn } from '../utils/cn';\n\nconst STATUS_STYLING: Record<WorkspaceStatus, string> = {\n [WorkspaceStatus.Active]: 'bg-success/10 text-success border-success/20',\n [WorkspaceStatus.Suspended]: 'bg-status-error-bg/10 text-status-error-text border-status-error-border/20',\n [WorkspaceStatus.Archived]: 'bg-bg-sunken text-text-secondary border-muted',\n [WorkspaceStatus.Deleted]: 'bg-status-error-bg/10 text-status-error-text border-status-error-border/20',\n};\n\nexport function WorkspacesListPage() {\n const [page, setPage] = useState(1);\n const pageSize = 20;\n\n const { data, loading, error } = useListWorkspacesQuery({\n variables: {\n limit: pageSize,\n offset: (page - 1) * pageSize,\n },\n });\n\n const workspaces = data?.allWorkspaces.items ?? [];\n const total = data?.allWorkspaces.total ?? 0;\n const totalPages = Math.ceil(total / pageSize);\n\n const columns = [\n {\n key: 'name',\n header: 'Workspace Name',\n render: (w: any) => <div className=\"font-medium text-text-primary\">{w.name}</div>,\n },\n {\n key: 'id',\n header: 'ID',\n render: (w: any) => <code className=\"text-xs text-text-secondary\">{w.id}</code>,\n },\n {\n key: 'status',\n header: 'Status',\n render: (w: any) => (\n <Badge className={cn(STATUS_STYLING[w.status as WorkspaceStatus])} variant=\"outline\">\n {w.status}\n </Badge>\n ),\n },\n ];\n\n return (\n <PageLayout\n title=\"Workspaces\"\n description=\"Manage and monitor platform workspaces\"\n actions={\n <Button>\n <Plus className=\"mr-2 h-4 w-4\" />\n Create Workspace\n </Button>\n }\n >\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"relative max-w-sm flex-1\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input placeholder=\"Search workspaces...\" className=\"pl-9\" />\n </div>\n </div>\n\n <DataTable\n columns={columns}\n data={workspaces}\n keyExtractor={(w) => w.id}\n loading={loading}\n emptyState={\n <div className=\"flex flex-col items-center justify-center py-12 text-center\">\n <Layout className=\"h-12 w-12 text-text-secondary/50 mb-4\" />\n <h3 className=\"text-lg font-medium\">No workspaces found</h3>\n <p className=\"text-text-secondary\">\n Workspaces will appear here when they are created.\n </p>\n </div>\n }\n />\n\n {total > pageSize && (\n <Pagination\n page={page}\n totalPages={totalPages}\n totalItems={total}\n pageSize={pageSize}\n onPageChange={setPage}\n />\n )}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;AAQA,IAAM,IAAkD;EACrD,EAAgB,SAAS;EACzB,EAAgB,YAAY;EAC5B,EAAgB,WAAW;EAC3B,EAAgB,UAAU;CAC5B;AAED,SAAgB,IAAqB;CACnC,IAAM,CAAC,GAAM,KAAW,EAAS,EAAE,EAG7B,EAAE,SAAM,YAAS,aAAU,EAAuB,EACtD,WAAW;EACT,OAAO;EACP,SAAS,IAAO,KAAK;EACtB,EACF,CAAC,EAEI,IAAa,GAAM,cAAc,SAAS,EAAE,EAC5C,IAAQ,GAAM,cAAc,SAAS,GACrC,IAAa,KAAK,KAAK,IAAQ,GAAS;AAwB9C,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAM,WAAU,gBAAiB,CAAA,EAAA,mBAE1B,EAAA,CAAA;YAGX,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAQ,WAAU,wEAAyE,CAAA,EAC3F,kBAAC,GAAD;OAAO,aAAY;OAAuB,WAAU;OAAS,CAAA,CACzD;;KACF,CAAA;IAEN,kBAAC,GAAD;KACW,SA1CD;MACd;OACE,KAAK;OACL,QAAQ;OACR,SAAS,MAAW,kBAAC,OAAD;QAAK,WAAU;kBAAiC,EAAE;QAAW,CAAA;OAClF;MACD;OACE,KAAK;OACL,QAAQ;OACR,SAAS,MAAW,kBAAC,QAAD;QAAM,WAAU;kBAA+B,EAAE;QAAU,CAAA;OAChF;MACD;OACE,KAAK;OACL,QAAQ;OACR,SAAS,MACP,kBAAC,GAAD;QAAO,WAAW,EAAG,EAAe,EAAE,QAA2B;QAAE,SAAQ;kBACxE,EAAE;QACG,CAAA;OAEX;MACF;KAuBO,MAAM;KACN,eAAe,MAAM,EAAE;KACd;KACT,YACE,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,GAAD,EAAQ,WAAU,yCAA0C,CAAA;OAC5D,kBAAC,MAAD;QAAI,WAAU;kBAAsB;QAAwB,CAAA;OAC5D,kBAAC,KAAD;QAAG,WAAU;kBAAsB;QAE/B,CAAA;OACA;;KAER,CAAA;IAED,IAAQ,MACP,kBAAC,GAAD;KACQ;KACM;KACZ,YAAY;KACF;KACV,cAAc;KACd,CAAA;IAEA;;EACK,CAAA"}
|