@burdenoff/microfe-bigconsole 2026.924.1 → 2026.924.3
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/bigconsole/BigConsoleRoutes.js +137 -138
- package/dist/bigconsole/BigConsoleRoutes.js.map +1 -1
- package/dist/bigconsole/assistant/previewController.js +10 -10
- package/dist/bigconsole/assistant/useAssistantPanelShowsPreview.js +25 -0
- package/dist/bigconsole/assistant/useAssistantPanelShowsPreview.js.map +1 -0
- package/dist/bigconsole/components/DrilldownDashboardRenderer.js +17 -17
- package/dist/bigconsole/components/builder/inspector/DataBindingSection.js +32 -32
- package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js +52 -52
- package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardCanvas.js +7 -7
- package/dist/bigconsole/components/dashboard/DashboardStatusPill.js +53 -0
- package/dist/bigconsole/components/dashboard/DashboardStatusPill.js.map +1 -0
- package/dist/bigconsole/components/dashboard/DashboardToolbar.js +60 -60
- package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +21 -21
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js +30 -30
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js +36 -36
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js +34 -34
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js +38 -38
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js.map +1 -1
- package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +121 -121
- package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/PublishToStoreDialog.js +22 -22
- package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js +46 -46
- package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js +53 -53
- package/dist/bigconsole/components/dashboard/TemplatePicker/TemplatePicker.js +1 -1
- package/dist/bigconsole/components/dashboard/WidgetPalette.js +47 -47
- package/dist/bigconsole/components/dashboard/index.js +1 -0
- package/dist/bigconsole/components/datasink/CacheTTLSelector.js +35 -35
- package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +18 -18
- package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +20 -20
- package/dist/bigconsole/components/datasink/DataSinkStatusBadge.js +30 -29
- package/dist/bigconsole/components/datasink/DataSinkStatusBadge.js.map +1 -1
- package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js +48 -48
- package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +103 -103
- package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +35 -35
- package/dist/bigconsole/components/overview/DashboardGuide.js +214 -0
- package/dist/bigconsole/components/overview/DashboardGuide.js.map +1 -0
- package/dist/bigconsole/components/overview/DataHealthCard.js +97 -0
- package/dist/bigconsole/components/overview/DataHealthCard.js.map +1 -0
- package/dist/bigconsole/components/overview/OverviewQuickActions.js +32 -0
- package/dist/bigconsole/components/overview/OverviewQuickActions.js.map +1 -0
- package/dist/bigconsole/components/overview/OverviewStatCard.js +57 -0
- package/dist/bigconsole/components/overview/OverviewStatCard.js.map +1 -0
- package/dist/bigconsole/components/overview/RecentDashboardsPanel.js +107 -0
- package/dist/bigconsole/components/overview/RecentDashboardsPanel.js.map +1 -0
- package/dist/bigconsole/components/overview/dashboardGuideSteps.js +119 -0
- package/dist/bigconsole/components/overview/dashboardGuideSteps.js.map +1 -0
- package/dist/bigconsole/components/overview/index.js +8 -0
- package/dist/bigconsole/components/overview/overviewModel.js +119 -0
- package/dist/bigconsole/components/overview/overviewModel.js.map +1 -0
- package/dist/bigconsole/components/overview/useOverviewData.js +48 -0
- package/dist/bigconsole/components/overview/useOverviewData.js.map +1 -0
- package/dist/bigconsole/components/parser/DataSinkSelector.js +40 -40
- package/dist/bigconsole/components/parser/ImportParserDialog.js +127 -127
- package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserSelector.js +51 -51
- package/dist/bigconsole/components/preview/AiPreviewContent.js +5 -5
- package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js +62 -61
- package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js.map +1 -1
- package/dist/bigconsole/components/preview/AiPreviewPanel.js +82 -81
- package/dist/bigconsole/components/preview/AiPreviewPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/ActionConfigDialog.js +13 -13
- package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +70 -70
- package/dist/bigconsole/components/widgets/PropertiesPanel.js +28 -28
- package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +25 -25
- package/dist/bigconsole/components/widgets/chart/ChartConfig.js +48 -48
- package/dist/bigconsole/components/widgets/comments/WidgetComments.js +46 -46
- package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js +61 -61
- package/dist/bigconsole/components/widgets/form/FormWidget.js +36 -36
- package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js +42 -42
- package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js +25 -25
- package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +21 -21
- package/dist/bigconsole/components/widgets/list/ListConfig.js +30 -30
- package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js +38 -38
- package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js +9 -9
- package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js +9 -9
- package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +49 -49
- package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +39 -39
- package/dist/bigconsole/components/widgets/table/TableConfig.js +73 -73
- package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js +64 -64
- package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js +10 -10
- package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js +68 -68
- package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js.map +1 -1
- package/dist/bigconsole/pages/AdminPage.js +136 -136
- package/dist/bigconsole/pages/DashboardBuilderPage.js +10 -10
- package/dist/bigconsole/pages/DashboardViewPage.js +61 -61
- package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
- package/dist/bigconsole/pages/DashboardsPage.js +327 -348
- package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
- package/dist/bigconsole/pages/DataParsersPage.js +5 -5
- package/dist/bigconsole/pages/DataSinkBuilderPage.js +10 -10
- package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkViewPage.js +83 -83
- package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinksPage.js +11 -11
- package/dist/bigconsole/pages/DataSourcesPage.js +5 -5
- package/dist/bigconsole/pages/InsightsPage.js +315 -315
- package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
- package/dist/bigconsole/pages/OverviewPage.js +244 -0
- package/dist/bigconsole/pages/OverviewPage.js.map +1 -0
- package/dist/bigconsole/pages/ParserBuilderPage.js +5 -5
- package/dist/bigconsole/pages/ParserViewPage.js +98 -98
- package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelineBuilderPage.js +8 -8
- package/dist/bigconsole/pages/PipelineViewPage.js +46 -46
- package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelinesPage.js +80 -80
- package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
- package/dist/bigconsole/pages/SettingsPage.js +70 -70
- package/dist/bigconsole/pages/WidgetDemoPage.js +42 -42
- package/dist/bigconsole/pages/WorkflowViewPage.js +200 -200
- package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
- package/dist/bigconsole/pages/WorkflowsPage.js +78 -78
- package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
- package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js +34 -34
- package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js +79 -79
- package/dist/bigconsole/renderers/adapters/CustomRenderer.js +46 -46
- package/dist/bigconsole/utils/createDialogParam.js +14 -0
- package/dist/bigconsole/utils/createDialogParam.js.map +1 -0
- package/dist/generated/global-operations.js +1 -1
- package/dist/generated/wspace-operations.js +285 -222
- package/dist/generated/wspace-operations.js.map +1 -1
- package/dist/shared/hooks/useTr.js +10 -7
- package/dist/shared/hooks/useTr.js.map +1 -1
- package/package.json +1 -1
- package/dist/bigconsole/pages/HomePage.js +0 -318
- package/dist/bigconsole/pages/HomePage.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkflowsPage.js","names":[],"sources":["../../../src/bigconsole/pages/WorkflowsPage.tsx"],"sourcesContent":["/**\n * Workflows Page\n *\n * List and manage FluidGrids Workflows.\n *\n * Section hierarchy (BOFF-5634):\n * - page header strip .............. `bare` — identity + the one create action\n * - \"Filters\" ...................... `standard` — status tabs + search, one labelled group\n * - \"Workflows\" .................... `primary` — the result set this route exists for;\n * loading / empty / no-results / grid all\n * live inside it so the page keeps its shape\n * - load failure ................... `danger` — in-page status section, not a page swap\n */\n\nimport { memo, useState, useMemo, useCallback } from 'react';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { AccessDenied, PermissionButton } from '@burdenoff/fe-libs/shared/components';\nimport { BIGCONSOLE_PERMISSIONS } from '../../constants/permissions';\nimport { useAppNavigate } from '../contexts';\nimport { isNative, nativeNotify } from '../../utils/nativeBridge';\nimport { newWorkflowPath } from '../BigConsoleRoutes';\nimport { useWorkflowOperations } from '../hooks/useWorkflowOperations';\nimport { useWorkflowStore } from '../store/workflowStore';\nimport { WorkflowCard } from '../components/workflow/WorkflowCard';\nimport { WorkflowDeleteDialog } from '../components/workflow/WorkflowDeleteDialog';\nimport { Section, SectionStack, SECTION_FOCUS_RING } from '../components/common';\nimport type { FluidGridsWorkflowStatus } from '../types';\n\n// fe-libs UI components\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Input } from '@burdenoff/fe-libs/ui';\nimport { Spinner } from '@burdenoff/fe-libs/ui';\nimport { AuroraBackground, GradientText, IllustratedEmptyState, PagePurpose } from '@burdenoff/fe-libs/ui';\n\n// Lucide icons\nimport { Plus, Search, Workflow, AlertCircle } from 'lucide-react';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ntype StatusFilter = 'all' | FluidGridsWorkflowStatus;\n\n/** Result of the last manual run triggered from a card. */\ninterface RunOutcome {\n workflowName: string;\n ok: boolean;\n message: string;\n}\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const WorkflowsPage = memo(function WorkflowsPage() {\n const navigate = useAppNavigate();\n const { t } = useI18n();\n\n // RBAC permissions\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const canRead = hasPermission(BIGCONSOLE_PERMISSIONS.WORKFLOW_READ);\n const canUpdate = hasPermission(BIGCONSOLE_PERMISSIONS.WORKFLOW_UPDATE);\n const canDelete = hasPermission(BIGCONSOLE_PERMISSIONS.WORKFLOW_DELETE);\n const canExecute = hasPermission(BIGCONSOLE_PERMISSIONS.WORKFLOW_EXECUTE);\n\n // Local state\n const [statusFilter, setStatusFilter] = useState<StatusFilter>('all');\n /** Outcome of the most recent run, shown inline above the grid. */\n const [runOutcome, setRunOutcome] = useState<RunOutcome | null>(null);\n\n // Store state\n const searchQuery = useWorkflowStore((state) => state.searchQuery);\n const setSearchQuery = useWorkflowStore((state) => state.setSearchQuery);\n const deleteDialogOpen = useWorkflowStore((state) => state.deleteDialogOpen);\n const currentWorkflow = useWorkflowStore((state) => state.currentWorkflow);\n const openDeleteDialog = useWorkflowStore((state) => state.openDeleteDialog);\n const closeDeleteDialog = useWorkflowStore((state) => state.closeDeleteDialog);\n\n // Operations\n const { loading, error, workflows, deleteWorkflow, refetch } = useWorkflowOperations();\n\n /**\n * Runs go through a SECOND hook instance on purpose. `useWorkflowOperations`\n * keeps one shared `error` for every operation, and this page swaps the whole\n * result set for a \"Failed to load Workflows\" panel whenever that error is\n * set — so a failed run on one card would wipe the list. A separate instance\n * (fetch skipped) keeps run failures local while still writing through to the\n * shared workflow store, so the card's execution count and last-run time\n * update in place.\n */\n const { executeWorkflow } = useWorkflowOperations({ skipFetch: true });\n\n // Per-card execution flags, maintained by the hook's executeWorkflow.\n const workflowUIStates = useWorkflowStore((state) => state.workflowUIStates);\n\n // Filter workflows\n const filteredWorkflows = useMemo(() => {\n let filtered = [...workflows];\n\n // Apply status filter\n if (statusFilter !== 'all') {\n filtered = filtered.filter((wf) => wf.status === statusFilter);\n }\n\n // Apply search filter\n if (searchQuery.trim()) {\n const query = searchQuery.toLowerCase();\n filtered = filtered.filter(\n (wf) =>\n wf.name.toLowerCase().includes(query) ||\n wf.key.toLowerCase().includes(query) ||\n wf.description?.toLowerCase().includes(query)\n );\n }\n\n // Sort by updatedAt descending\n return filtered.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());\n }, [workflows, statusFilter, searchQuery]);\n\n // Handlers\n const handleCreateWorkflow = useCallback(() => {\n navigate(newWorkflowPath());\n }, [navigate]);\n\n const handleViewWorkflow = useCallback(\n (id: string) => {\n navigate(`/workflows/${id}`);\n },\n [navigate]\n );\n\n const handleEditWorkflow = useCallback(\n (id: string) => {\n navigate(`/workflows/${id}/edit`);\n },\n [navigate]\n );\n\n const handleDeleteClick = useCallback(\n (id: string) => {\n const workflow = workflows.find((wf) => wf.id === id);\n if (workflow) {\n openDeleteDialog(workflow);\n }\n },\n [workflows, openDeleteDialog]\n );\n\n const handleRunWorkflow = useCallback(\n async (id: string) => {\n const workflow = workflows.find((wf) => wf.id === id);\n if (!workflow) return;\n\n setRunOutcome(null);\n // `executeWorkflow` swallows the Apollo error and resolves to null, so a\n // null result IS the failure signal — never treat it as a silent success.\n const result = await executeWorkflow(id);\n\n if (result) {\n if (isNative()) void nativeNotify('success');\n setRunOutcome({\n workflowName: workflow.name,\n ok: true,\n message: t(\n 'bigconsole.workflows.run.triggered',\n 'Run triggered. The execution count and last-run time update as the run progresses.'\n ),\n });\n return;\n }\n\n if (isNative()) void nativeNotify('error');\n setRunOutcome({\n workflowName: workflow.name,\n ok: false,\n message: t('bigconsole.workflows.run.failed', 'The workflow could not be started. Nothing has been changed.'),\n });\n },\n [workflows, executeWorkflow, t]\n );\n\n const handleDeleteConfirm = useCallback(async () => {\n if (currentWorkflow) {\n try {\n await deleteWorkflow(currentWorkflow.id);\n if (isNative()) void nativeNotify('success');\n } catch (err) {\n if (isNative()) void nativeNotify('error');\n throw err;\n }\n closeDeleteDialog();\n }\n }, [currentWorkflow, deleteWorkflow, closeDeleteDialog]);\n\n // Status filter options\n const statusOptions: { value: StatusFilter; label: string }[] = [\n { value: 'all', label: t('bigconsole.workflows.filters.all', 'All') },\n { value: 'draft', label: t('bigconsole.workflows.status.draft', 'Draft') },\n { value: 'active', label: t('bigconsole.workflows.status.active', 'Active') },\n { value: 'paused', label: t('bigconsole.workflows.status.paused', 'Paused') },\n { value: 'error', label: t('bigconsole.workflows.status.error', 'Error') },\n { value: 'archived', label: t('bigconsole.workflows.status.archived', 'Archived') },\n ];\n\n // Page-level read gate — only after permissions have finished loading so we\n // don't flash Access Denied while the permission set is still being fetched.\n if (!permissionsLoading && !canRead) {\n return (\n <AccessDenied\n title={t('bigconsole.workflows.errors.accessDeniedTitle', 'Access Denied')}\n description={t(\n 'bigconsole.workflows.errors.accessDeniedListDescription',\n \"You don't have permission to view workflows.\"\n )}\n />\n );\n }\n\n const isEmpty = !loading && workflows.length === 0;\n const isNoResults = !loading && filteredWorkflows.length === 0 && workflows.length > 0;\n\n return (\n <div className=\"min-h-dvh bg-bg-canvas\">\n {/* ------------------------------------------------------------------ *\n * Page header strip — `bare` emphasis: structural only. It carries the\n * page identity and the single create action, and must never out-weigh\n * the result set below it. Rendered as <header> (the page banner) so it\n * stays a landmark without competing with the labelled sections below.\n * The band itself was invisible before: `border-border-seam` and\n * `bg-gloss-card` are unregistered utilities that emit no CSS.\n * ------------------------------------------------------------------ */}\n <header\n data-section-emphasis=\"bare\"\n className=\"relative min-w-0 overflow-hidden border-b border-[var(--color-border-seam)] bg-[image:var(--gradient-gloss-card)]\"\n >\n <AuroraBackground intensity=\"subtle\" />\n <div className=\"relative flex flex-col gap-form-gap p-[var(--space-pagePadding)] sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex min-w-0 items-center gap-form-gap\">\n <span\n aria-hidden=\"true\"\n className=\"flex h-control-lg w-[var(--size-controlHeight-lg)] shrink-0 items-center justify-center rounded-card bg-action-primary-bg\"\n >\n <Workflow className=\"h-icon-lg w-icon-lg text-action-primary-text\" />\n </span>\n <div className=\"min-w-0\">\n <h1 className=\"text-2xl font-bold text-text-primary\">\n <GradientText>{t('bigconsole.workflows.list.title', 'Workflows')}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {t(\n 'bigconsole.workflows.list.subtitle',\n 'Design ETL workflows with FluidGrids and link them to DataSinks'\n )}\n </p>\n </div>\n </div>\n\n <div className=\"flex flex-wrap items-center gap-control-gap\">\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.WORKFLOW_CREATE} deniedBehavior=\"disable\">\n <Button onClick={handleCreateWorkflow}>\n <Plus className=\"h-icon-sm w-icon-sm\" />\n {t('bigconsole.workflows.actions.designWorkflow', 'Design Workflow')}\n </Button>\n </PermissionButton>\n </div>\n </div>\n </header>\n\n {/* Main Content */}\n <div className=\"p-[var(--space-pagePadding)]\">\n <SectionStack>\n <PagePurpose>\n {t(\n 'bigconsole.workflows.list.purpose',\n 'Workflows are visual ETL jobs built with the FluidGrids builder — they fetch data from external systems, transform it, and load it into your BigConsole DataSinks on a schedule or on demand. Use them to keep dashboards fed with fresh, shaped data without writing glue code.'\n )}\n </PagePurpose>\n\n {error ? (\n /* Load failure reads as a status section inside the page — the\n header band and the create action stay reachable. */\n <Section\n headingLevel={2}\n tone=\"danger\"\n title={t('bigconsole.workflows.errors.loadFailedTitle', 'Failed to load Workflows')}\n description=\"The workflow service did not respond. Nothing has been changed — retry when you are ready.\"\n icon={<AlertCircle className=\"h-icon-md w-icon-md\" />}\n actions={\n <Button size=\"sm\" onClick={() => refetch()}>\n {t('bigconsole.workflows.actions.tryAgain', 'Try Again')}\n </Button>\n }\n data-testid=\"workflows-error\"\n >\n <p className=\"break-words text-sm text-[var(--color-status-error-text)]\">{error.message}</p>\n </Section>\n ) : (\n <>\n {/* Configuration: the two filter controls read as ONE group. */}\n <Section\n headingLevel={2}\n title=\"Filters\"\n description=\"Narrow the list by status, or search by name, key or description.\"\n padding=\"compact\"\n data-testid=\"workflows-filters\"\n >\n <div className=\"flex flex-col gap-form-gap lg:flex-row lg:items-center lg:justify-between\">\n <div\n role=\"group\"\n aria-label=\"Filter workflows by status\"\n className=\"flex flex-wrap items-center gap-1 rounded-card bg-bg-sunken p-1\"\n >\n {statusOptions.map((option) => (\n <button\n key={option.value}\n type=\"button\"\n aria-pressed={statusFilter === option.value}\n onClick={() => setStatusFilter(option.value)}\n className={`min-h-[var(--size-controlHeight-md)] rounded-button px-3 text-sm font-medium motion-safe:transition-colors ${SECTION_FOCUS_RING} ${\n statusFilter === option.value\n ? 'bg-bg-surface text-text-primary shadow-[var(--shadow-elevation-1)]'\n : 'text-text-secondary hover:text-text-primary'\n }`}\n >\n {option.label}\n </button>\n ))}\n </div>\n\n <div className=\"relative w-full lg:max-w-[360px]\">\n <Search\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-3 top-1/2 h-icon-sm w-icon-sm -translate-y-1/2 text-text-muted\"\n />\n <Input\n type=\"text\"\n aria-label={t('bigconsole.workflows.filters.searchPlaceholder', 'Search workflows...')}\n placeholder={t('bigconsole.workflows.filters.searchPlaceholder', 'Search workflows...')}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"h-control-md pl-10\"\n />\n </div>\n </div>\n </Section>\n\n {/* ------------------------------------------------------------ *\n * The result set — the ONE `primary` block on this route.\n * Loading, empty, no-results and the grid all render inside it,\n * so the page keeps the same shape whatever the data does.\n * ------------------------------------------------------------ */}\n <Section\n headingLevel={2}\n emphasis=\"primary\"\n title={t('bigconsole.workflows.list.title', 'Workflows')}\n description=\"Every workflow in this workspace, most recently updated first.\"\n meta={\n <span className=\"rounded-pill bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary\">\n {filteredWorkflows.length}\n {filteredWorkflows.length !== workflows.length ? ` of ${workflows.length}` : ''}\n </span>\n }\n data-testid=\"workflows-results\"\n >\n {loading && workflows.length === 0 && (\n <div className=\"flex min-h-[240px] items-center justify-center\">\n <div className=\"text-center\">\n <Spinner size=\"lg\" className=\"mb-form-gap\" />\n <p className=\"text-sm text-text-muted\">\n {t('bigconsole.workflows.list.loading', 'Loading workflows...')}\n </p>\n </div>\n </div>\n )}\n\n {isEmpty && (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('bigconsole.workflows.list.emptyTitle', 'No Workflows yet')}\n description={t(\n 'bigconsole.workflows.list.emptyDescription',\n 'Design ETL workflows with the FluidGrids visual builder to fetch, transform, and deliver data into BigConsole DataSinks.'\n )}\n action={\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.WORKFLOW_CREATE} deniedBehavior=\"disable\">\n <Button onClick={handleCreateWorkflow}>\n <Plus className=\"h-icon-sm w-icon-sm\" />\n {t('bigconsole.workflows.actions.designWorkflow', 'Design Workflow')}\n </Button>\n </PermissionButton>\n }\n />\n )}\n\n {isNoResults && (\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title={t('bigconsole.workflows.list.noResultsTitle', 'No matching workflows')}\n description={t('bigconsole.workflows.list.noResultsDescription', 'No workflows match your filters')}\n />\n )}\n\n {runOutcome && (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className={`mb-form-gap flex flex-wrap items-center justify-between gap-icon-gap rounded-input border p-3 text-sm ${\n runOutcome.ok\n ? 'border-[var(--color-status-success-border)] bg-[var(--color-status-success-bgSubtle)] text-[var(--color-status-success-text)]'\n : 'border-[var(--color-status-error-border)] bg-[var(--color-status-error-bgSubtle)] text-[var(--color-status-error-text)]'\n }`}\n data-testid=\"workflows-run-outcome\"\n >\n <span className=\"min-w-0\">\n <strong className=\"font-semibold\">{runOutcome.workflowName}</strong> — {runOutcome.message}\n </span>\n <button\n type=\"button\"\n onClick={() => setRunOutcome(null)}\n className={`rounded-button px-2 py-1 text-xs font-medium underline-offset-2 hover:underline ${SECTION_FOCUS_RING}`}\n >\n {t('bigconsole.workflows.run.dismiss', 'Dismiss')}\n </button>\n </div>\n )}\n\n {filteredWorkflows.length > 0 && (\n <div className=\"grid grid-cols-1 gap-form-gap sm:grid-cols-2 xl:grid-cols-3\">\n {filteredWorkflows.map((workflow) => (\n <WorkflowCard\n key={workflow.id}\n workflow={workflow}\n onView={handleViewWorkflow}\n onEdit={canUpdate ? handleEditWorkflow : undefined}\n onDelete={canDelete ? handleDeleteClick : undefined}\n onRun={canExecute ? handleRunWorkflow : undefined}\n isRunning={workflowUIStates.get(workflow.id)?.isExecuting ?? false}\n />\n ))}\n </div>\n )}\n </Section>\n </>\n )}\n </SectionStack>\n </div>\n\n {/* Delete Dialog */}\n {currentWorkflow && (\n <WorkflowDeleteDialog\n workflow={currentWorkflow}\n isOpen={deleteDialogOpen}\n onClose={closeDeleteDialog}\n onConfirm={handleDeleteConfirm}\n />\n )}\n </div>\n );\n});\n\nexport default WorkflowsPage;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WorkflowsPage.js","names":[],"sources":["../../../src/bigconsole/pages/WorkflowsPage.tsx"],"sourcesContent":["/**\n * Workflows Page\n *\n * List and manage FluidGrids Workflows.\n *\n * Section hierarchy (BOFF-5634):\n * - page header strip .............. `bare` — identity + the one create action\n * - \"Filters\" ...................... `standard` — status tabs + search, one labelled group\n * - \"Workflows\" .................... `primary` — the result set this route exists for;\n * loading / empty / no-results / grid all\n * live inside it so the page keeps its shape\n * - load failure ................... `danger` — in-page status section, not a page swap\n */\n\nimport { memo, useState, useMemo, useCallback } from 'react';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { AccessDenied, PermissionButton } from '@burdenoff/fe-libs/shared/components';\nimport { BIGCONSOLE_PERMISSIONS } from '../../constants/permissions';\nimport { useAppNavigate } from '../contexts';\nimport { isNative, nativeNotify } from '../../utils/nativeBridge';\nimport { newWorkflowPath } from '../BigConsoleRoutes';\nimport { useWorkflowOperations } from '../hooks/useWorkflowOperations';\nimport { useWorkflowStore } from '../store/workflowStore';\nimport { WorkflowCard } from '../components/workflow/WorkflowCard';\nimport { WorkflowDeleteDialog } from '../components/workflow/WorkflowDeleteDialog';\nimport { Section, SectionStack, SECTION_FOCUS_RING } from '../components/common';\nimport type { FluidGridsWorkflowStatus } from '../types';\n\n// fe-libs UI components\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Input } from '@burdenoff/fe-libs/ui';\nimport { Spinner } from '@burdenoff/fe-libs/ui';\nimport { AuroraBackground, GradientText, IllustratedEmptyState, PagePurpose } from '@burdenoff/fe-libs/ui';\n\n// Lucide icons\nimport { Plus, Search, Workflow, AlertCircle } from 'lucide-react';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ntype StatusFilter = 'all' | FluidGridsWorkflowStatus;\n\n/** Result of the last manual run triggered from a card. */\ninterface RunOutcome {\n workflowName: string;\n ok: boolean;\n message: string;\n}\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const WorkflowsPage = memo(function WorkflowsPage() {\n const navigate = useAppNavigate();\n const { t } = useI18n();\n\n // RBAC permissions\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const canRead = hasPermission(BIGCONSOLE_PERMISSIONS.WORKFLOW_READ);\n const canUpdate = hasPermission(BIGCONSOLE_PERMISSIONS.WORKFLOW_UPDATE);\n const canDelete = hasPermission(BIGCONSOLE_PERMISSIONS.WORKFLOW_DELETE);\n const canExecute = hasPermission(BIGCONSOLE_PERMISSIONS.WORKFLOW_EXECUTE);\n\n // Local state\n const [statusFilter, setStatusFilter] = useState<StatusFilter>('all');\n /** Outcome of the most recent run, shown inline above the grid. */\n const [runOutcome, setRunOutcome] = useState<RunOutcome | null>(null);\n\n // Store state\n const searchQuery = useWorkflowStore((state) => state.searchQuery);\n const setSearchQuery = useWorkflowStore((state) => state.setSearchQuery);\n const deleteDialogOpen = useWorkflowStore((state) => state.deleteDialogOpen);\n const currentWorkflow = useWorkflowStore((state) => state.currentWorkflow);\n const openDeleteDialog = useWorkflowStore((state) => state.openDeleteDialog);\n const closeDeleteDialog = useWorkflowStore((state) => state.closeDeleteDialog);\n\n // Operations\n const { loading, error, workflows, deleteWorkflow, refetch } = useWorkflowOperations();\n\n /**\n * Runs go through a SECOND hook instance on purpose. `useWorkflowOperations`\n * keeps one shared `error` for every operation, and this page swaps the whole\n * result set for a \"Failed to load Workflows\" panel whenever that error is\n * set — so a failed run on one card would wipe the list. A separate instance\n * (fetch skipped) keeps run failures local while still writing through to the\n * shared workflow store, so the card's execution count and last-run time\n * update in place.\n */\n const { executeWorkflow } = useWorkflowOperations({ skipFetch: true });\n\n // Per-card execution flags, maintained by the hook's executeWorkflow.\n const workflowUIStates = useWorkflowStore((state) => state.workflowUIStates);\n\n // Filter workflows\n const filteredWorkflows = useMemo(() => {\n let filtered = [...workflows];\n\n // Apply status filter\n if (statusFilter !== 'all') {\n filtered = filtered.filter((wf) => wf.status === statusFilter);\n }\n\n // Apply search filter\n if (searchQuery.trim()) {\n const query = searchQuery.toLowerCase();\n filtered = filtered.filter(\n (wf) =>\n wf.name.toLowerCase().includes(query) ||\n wf.key.toLowerCase().includes(query) ||\n wf.description?.toLowerCase().includes(query)\n );\n }\n\n // Sort by updatedAt descending\n return filtered.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());\n }, [workflows, statusFilter, searchQuery]);\n\n // Handlers\n const handleCreateWorkflow = useCallback(() => {\n navigate(newWorkflowPath());\n }, [navigate]);\n\n const handleViewWorkflow = useCallback(\n (id: string) => {\n navigate(`/workflows/${id}`);\n },\n [navigate]\n );\n\n const handleEditWorkflow = useCallback(\n (id: string) => {\n navigate(`/workflows/${id}/edit`);\n },\n [navigate]\n );\n\n const handleDeleteClick = useCallback(\n (id: string) => {\n const workflow = workflows.find((wf) => wf.id === id);\n if (workflow) {\n openDeleteDialog(workflow);\n }\n },\n [workflows, openDeleteDialog]\n );\n\n const handleRunWorkflow = useCallback(\n async (id: string) => {\n const workflow = workflows.find((wf) => wf.id === id);\n if (!workflow) return;\n\n setRunOutcome(null);\n // `executeWorkflow` swallows the Apollo error and resolves to null, so a\n // null result IS the failure signal — never treat it as a silent success.\n const result = await executeWorkflow(id);\n\n if (result) {\n if (isNative()) void nativeNotify('success');\n setRunOutcome({\n workflowName: workflow.name,\n ok: true,\n message: t(\n 'bigconsole.workflows.run.triggered',\n 'Run triggered. The execution count and last-run time update as the run progresses.'\n ),\n });\n return;\n }\n\n if (isNative()) void nativeNotify('error');\n setRunOutcome({\n workflowName: workflow.name,\n ok: false,\n message: t('bigconsole.workflows.run.failed', 'The workflow could not be started. Nothing has been changed.'),\n });\n },\n [workflows, executeWorkflow, t]\n );\n\n const handleDeleteConfirm = useCallback(async () => {\n if (currentWorkflow) {\n try {\n await deleteWorkflow(currentWorkflow.id);\n if (isNative()) void nativeNotify('success');\n } catch (err) {\n if (isNative()) void nativeNotify('error');\n throw err;\n }\n closeDeleteDialog();\n }\n }, [currentWorkflow, deleteWorkflow, closeDeleteDialog]);\n\n // Status filter options\n const statusOptions: { value: StatusFilter; label: string }[] = [\n { value: 'all', label: t('bigconsole.workflows.filters.all', 'All') },\n { value: 'draft', label: t('bigconsole.workflows.status.draft', 'Draft') },\n { value: 'active', label: t('bigconsole.workflows.status.active', 'Active') },\n { value: 'paused', label: t('bigconsole.workflows.status.paused', 'Paused') },\n { value: 'error', label: t('bigconsole.workflows.status.error', 'Error') },\n { value: 'archived', label: t('bigconsole.workflows.status.archived', 'Archived') },\n ];\n\n // Page-level read gate — only after permissions have finished loading so we\n // don't flash Access Denied while the permission set is still being fetched.\n if (!permissionsLoading && !canRead) {\n return (\n <AccessDenied\n title={t('bigconsole.workflows.errors.accessDeniedTitle', 'Access Denied')}\n description={t(\n 'bigconsole.workflows.errors.accessDeniedListDescription',\n \"You don't have permission to view workflows.\"\n )}\n />\n );\n }\n\n const isEmpty = !loading && workflows.length === 0;\n const isNoResults = !loading && filteredWorkflows.length === 0 && workflows.length > 0;\n\n return (\n <div className=\"min-h-dvh bg-bg-canvas\">\n {/* ------------------------------------------------------------------ *\n * Page header strip — `bare` emphasis: structural only. It carries the\n * page identity and the single create action, and must never out-weigh\n * the result set below it. Rendered as <header> (the page banner) so it\n * stays a landmark without competing with the labelled sections below.\n * The band itself was invisible before: `border-border-seam` and\n * `bg-gloss-card` are unregistered utilities that emit no CSS.\n * ------------------------------------------------------------------ */}\n <header\n data-section-emphasis=\"bare\"\n className=\"relative min-w-0 overflow-hidden border-b border-[var(--color-border-seam)] bg-[image:var(--gradient-gloss-card)]\"\n >\n <AuroraBackground intensity=\"subtle\" />\n <div className=\"relative flex flex-col gap-form-gap p-[var(--space-pagePadding)] sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex min-w-0 items-center gap-form-gap\">\n <span\n aria-hidden=\"true\"\n className=\"flex h-control-lg w-[var(--size-controlHeight-lg)] shrink-0 items-center justify-center rounded-card bg-action-primary-bg\"\n >\n <Workflow className=\"h-icon-lg w-icon-lg text-action-primary-text\" />\n </span>\n <div className=\"min-w-0\">\n <h1 className=\"text-2xl font-bold text-text-primary\">\n <GradientText>{t('bigconsole.workflows.list.title', 'Workflows')}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {t(\n 'bigconsole.workflows.list.subtitle',\n 'Design ETL workflows with FluidGrids and link them to DataSinks'\n )}\n </p>\n </div>\n </div>\n\n <div className=\"flex flex-wrap items-center gap-control-gap\">\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.WORKFLOW_CREATE} deniedBehavior=\"disable\">\n <Button onClick={handleCreateWorkflow}>\n <Plus className=\"h-icon-sm w-icon-sm\" />\n {t('bigconsole.workflows.actions.designWorkflow', 'Design Workflow')}\n </Button>\n </PermissionButton>\n </div>\n </div>\n </header>\n\n {/* Main Content */}\n <div className=\"p-[var(--space-pagePadding)]\">\n <SectionStack>\n <PagePurpose>\n {t(\n 'bigconsole.workflows.list.purpose',\n 'Workflows are visual ETL jobs built with the FluidGrids builder — they fetch data from external systems, transform it, and load it into your BigConsole DataSinks on a schedule or on demand. Use them to keep dashboards fed with fresh, shaped data without writing glue code.'\n )}\n </PagePurpose>\n\n {error ? (\n /* Load failure reads as a status section inside the page — the\n header band and the create action stay reachable. */\n <Section\n headingLevel={2}\n tone=\"danger\"\n title={t('bigconsole.workflows.errors.loadFailedTitle', 'Failed to load Workflows')}\n description=\"The workflow service did not respond. Nothing has been changed — retry when you are ready.\"\n icon={<AlertCircle className=\"h-icon-md w-icon-md\" />}\n actions={\n <Button size=\"sm\" onClick={() => refetch()}>\n {t('bigconsole.workflows.actions.tryAgain', 'Try Again')}\n </Button>\n }\n data-testid=\"workflows-error\"\n >\n <p className=\"break-words text-sm text-[var(--color-status-error-text)]\">{error.message}</p>\n </Section>\n ) : (\n <>\n {/* Configuration: the two filter controls read as ONE group. */}\n <Section\n headingLevel={2}\n title=\"Filters\"\n description=\"Narrow the list by status, or search by name, key or description.\"\n padding=\"compact\"\n data-testid=\"workflows-filters\"\n >\n <div className=\"flex flex-col gap-form-gap lg:flex-row lg:items-center lg:justify-between\">\n <div\n role=\"group\"\n aria-label=\"Filter workflows by status\"\n className=\"flex flex-wrap items-center gap-1 rounded-card bg-bg-sunken p-1\"\n >\n {statusOptions.map((option) => (\n <button\n key={option.value}\n type=\"button\"\n aria-pressed={statusFilter === option.value}\n onClick={() => setStatusFilter(option.value)}\n className={`min-h-[var(--size-controlHeight-md)] rounded-button px-3 text-sm font-medium motion-safe:transition-colors ${SECTION_FOCUS_RING} ${\n statusFilter === option.value\n ? 'bg-bg-surface text-text-primary shadow-[var(--shadow-elevation-1)]'\n : 'text-text-secondary hover:text-text-primary'\n }`}\n >\n {option.label}\n </button>\n ))}\n </div>\n\n <div className=\"relative w-full lg:max-w-[360px]\">\n <Search\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-3 top-1/2 h-icon-sm w-icon-sm -translate-y-1/2 text-text-muted\"\n />\n <Input\n type=\"text\"\n aria-label={t('bigconsole.workflows.filters.searchPlaceholder', 'Search workflows...')}\n placeholder={t('bigconsole.workflows.filters.searchPlaceholder', 'Search workflows...')}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"h-control-md pl-10\"\n />\n </div>\n </div>\n </Section>\n\n {/* ------------------------------------------------------------ *\n * The result set — the ONE `primary` block on this route.\n * Loading, empty, no-results and the grid all render inside it,\n * so the page keeps the same shape whatever the data does.\n * ------------------------------------------------------------ */}\n <Section\n headingLevel={2}\n emphasis=\"primary\"\n title={t('bigconsole.workflows.list.title', 'Workflows')}\n description=\"Every workflow in this workspace, most recently updated first.\"\n meta={\n <span className=\"rounded-pill bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary\">\n {filteredWorkflows.length}\n {filteredWorkflows.length !== workflows.length ? ` of ${workflows.length}` : ''}\n </span>\n }\n data-testid=\"workflows-results\"\n >\n {loading && workflows.length === 0 && (\n <div className=\"flex min-h-[240px] items-center justify-center\">\n <div className=\"text-center\">\n <Spinner size=\"lg\" className=\"mb-form-gap\" />\n <p className=\"text-sm text-text-muted\">\n {t('bigconsole.workflows.list.loading', 'Loading workflows...')}\n </p>\n </div>\n </div>\n )}\n\n {isEmpty && (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('bigconsole.workflows.list.emptyTitle', 'No Workflows yet')}\n description={t(\n 'bigconsole.workflows.list.emptyDescription',\n 'Design ETL workflows with the FluidGrids visual builder to fetch, transform, and deliver data into BigConsole DataSinks.'\n )}\n action={\n <PermissionButton permission={BIGCONSOLE_PERMISSIONS.WORKFLOW_CREATE} deniedBehavior=\"disable\">\n <Button onClick={handleCreateWorkflow}>\n <Plus className=\"h-icon-sm w-icon-sm\" />\n {t('bigconsole.workflows.actions.designWorkflow', 'Design Workflow')}\n </Button>\n </PermissionButton>\n }\n />\n )}\n\n {isNoResults && (\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title={t('bigconsole.workflows.list.noResultsTitle', 'No matching workflows')}\n description={t('bigconsole.workflows.list.noResultsDescription', 'No workflows match your filters')}\n />\n )}\n\n {runOutcome && (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className={`mb-form-gap flex flex-wrap items-center justify-between gap-icon-gap rounded-input border p-3 text-sm ${\n runOutcome.ok\n ? 'border-[var(--color-status-success-border)] bg-[var(--color-status-success-bgSubtle)] text-[var(--color-status-success-text)]'\n : 'border-[var(--color-status-error-border)] bg-[var(--color-status-error-bgSubtle)] text-[var(--color-status-error-text)]'\n }`}\n data-testid=\"workflows-run-outcome\"\n >\n <span className=\"min-w-0\">\n <strong className=\"font-semibold\">{runOutcome.workflowName}</strong> — {runOutcome.message}\n </span>\n <button\n type=\"button\"\n onClick={() => setRunOutcome(null)}\n className={`rounded-button px-2 py-1 text-xs font-medium underline-offset-2 hover:underline ${SECTION_FOCUS_RING}`}\n >\n {t('bigconsole.workflows.run.dismiss', 'Dismiss')}\n </button>\n </div>\n )}\n\n {filteredWorkflows.length > 0 && (\n <div className=\"grid grid-cols-1 gap-form-gap sm:grid-cols-2 xl:grid-cols-3\">\n {filteredWorkflows.map((workflow) => (\n <WorkflowCard\n key={workflow.id}\n workflow={workflow}\n onView={handleViewWorkflow}\n onEdit={canUpdate ? handleEditWorkflow : undefined}\n onDelete={canDelete ? handleDeleteClick : undefined}\n onRun={canExecute ? handleRunWorkflow : undefined}\n isRunning={workflowUIStates.get(workflow.id)?.isExecuting ?? false}\n />\n ))}\n </div>\n )}\n </Section>\n </>\n )}\n </SectionStack>\n </div>\n\n {/* Delete Dialog */}\n {currentWorkflow && (\n <WorkflowDeleteDialog\n workflow={currentWorkflow}\n isOpen={deleteDialogOpen}\n onClose={closeDeleteDialog}\n onConfirm={handleDeleteConfirm}\n />\n )}\n </div>\n );\n});\n\nexport default WorkflowsPage;\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { memo as e, useCallback as t, useEffect as n, useRef as r, useState as i } from "react";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
3
|
+
import { useI18n as s } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
4
4
|
import * as c from "adaptivecards";
|
|
5
5
|
//#region src/bigconsole/renderers/adapters/AdaptiveCardRenderer.tsx
|
|
6
6
|
function l(e, t, n) {
|
|
@@ -288,7 +288,7 @@ var f = new c.HostConfig({
|
|
|
288
288
|
lineColor: "#374151"
|
|
289
289
|
}
|
|
290
290
|
}), m = e(function({ widget: e, data: u, template: d, isLoading: m, error: h, onAction: g }) {
|
|
291
|
-
let { t: _ } =
|
|
291
|
+
let { t: _ } = s(), v = r(null), y = r(null), [b, x] = i(null), [S, C] = i(!1), [w, T] = i([]), [E, D] = i(null), [O, k] = i(null);
|
|
292
292
|
n(() => {
|
|
293
293
|
let e = !0;
|
|
294
294
|
return import("adaptivecards-templating").then((t) => {
|
|
@@ -361,45 +361,45 @@ var f = new c.HostConfig({
|
|
|
361
361
|
E,
|
|
362
362
|
O,
|
|
363
363
|
_
|
|
364
|
-
]), m ? /* @__PURE__ */
|
|
364
|
+
]), m ? /* @__PURE__ */ a("div", {
|
|
365
365
|
className: "flex items-center justify-center h-full p-4 animate-in fade-in duration-200",
|
|
366
|
-
children: /* @__PURE__ */
|
|
366
|
+
children: /* @__PURE__ */ o("div", {
|
|
367
367
|
className: "animate-pulse space-y-3 w-full",
|
|
368
368
|
children: [
|
|
369
|
-
/* @__PURE__ */
|
|
370
|
-
/* @__PURE__ */
|
|
369
|
+
/* @__PURE__ */ a("div", { className: "h-5 bg-bg-sunken rounded w-3/4" }),
|
|
370
|
+
/* @__PURE__ */ o("div", {
|
|
371
371
|
className: "flex gap-3",
|
|
372
|
-
children: [/* @__PURE__ */
|
|
372
|
+
children: [/* @__PURE__ */ a("div", { className: "h-10 w-10 bg-bg-sunken rounded-full" }), /* @__PURE__ */ o("div", {
|
|
373
373
|
className: "flex-1 space-y-2",
|
|
374
|
-
children: [/* @__PURE__ */
|
|
374
|
+
children: [/* @__PURE__ */ a("div", { className: "h-4 bg-bg-sunken rounded w-1/2" }), /* @__PURE__ */ a("div", { className: "h-3 bg-bg-sunken rounded w-1/3" })]
|
|
375
375
|
})]
|
|
376
376
|
}),
|
|
377
|
-
/* @__PURE__ */
|
|
378
|
-
/* @__PURE__ */
|
|
379
|
-
/* @__PURE__ */
|
|
377
|
+
/* @__PURE__ */ a("div", { className: "h-4 bg-bg-sunken rounded w-full" }),
|
|
378
|
+
/* @__PURE__ */ a("div", { className: "h-4 bg-bg-sunken rounded w-5/6" }),
|
|
379
|
+
/* @__PURE__ */ o("div", {
|
|
380
380
|
className: "grid grid-cols-2 gap-2 mt-4",
|
|
381
381
|
children: [
|
|
382
|
-
/* @__PURE__ */
|
|
383
|
-
/* @__PURE__ */
|
|
384
|
-
/* @__PURE__ */
|
|
385
|
-
/* @__PURE__ */
|
|
382
|
+
/* @__PURE__ */ a("div", { className: "h-3 bg-bg-sunken rounded" }),
|
|
383
|
+
/* @__PURE__ */ a("div", { className: "h-3 bg-bg-sunken rounded" }),
|
|
384
|
+
/* @__PURE__ */ a("div", { className: "h-3 bg-bg-sunken rounded" }),
|
|
385
|
+
/* @__PURE__ */ a("div", { className: "h-3 bg-bg-sunken rounded" })
|
|
386
386
|
]
|
|
387
387
|
})
|
|
388
388
|
]
|
|
389
389
|
})
|
|
390
|
-
}) : h || b ? /* @__PURE__ */
|
|
390
|
+
}) : h || b ? /* @__PURE__ */ a("div", {
|
|
391
391
|
className: "flex items-center justify-center h-full p-4",
|
|
392
|
-
children: /* @__PURE__ */
|
|
392
|
+
children: /* @__PURE__ */ o("div", {
|
|
393
393
|
className: "text-center max-w-sm",
|
|
394
394
|
children: [
|
|
395
|
-
/* @__PURE__ */
|
|
395
|
+
/* @__PURE__ */ a("div", {
|
|
396
396
|
className: "w-12 h-12 mx-auto mb-3 rounded-full bg-red-100 dark:bg-red-900/30 flex items-center justify-center",
|
|
397
|
-
children: /* @__PURE__ */
|
|
397
|
+
children: /* @__PURE__ */ a("svg", {
|
|
398
398
|
className: "w-6 h-6 text-red-600 dark:text-red-400",
|
|
399
399
|
fill: "none",
|
|
400
400
|
viewBox: "0 0 24 24",
|
|
401
401
|
stroke: "currentColor",
|
|
402
|
-
children: /* @__PURE__ */
|
|
402
|
+
children: /* @__PURE__ */ a("path", {
|
|
403
403
|
strokeLinecap: "round",
|
|
404
404
|
strokeLinejoin: "round",
|
|
405
405
|
strokeWidth: 2,
|
|
@@ -407,39 +407,39 @@ var f = new c.HostConfig({
|
|
|
407
407
|
})
|
|
408
408
|
})
|
|
409
409
|
}),
|
|
410
|
-
/* @__PURE__ */
|
|
410
|
+
/* @__PURE__ */ a("p", {
|
|
411
411
|
className: "font-medium text-status-error-text",
|
|
412
412
|
children: _("bigconsole.widget.renderer.adaptiveCard.errorRendering", "Error rendering card")
|
|
413
413
|
}),
|
|
414
|
-
/* @__PURE__ */
|
|
414
|
+
/* @__PURE__ */ a("p", {
|
|
415
415
|
className: "text-sm text-secondary mt-1",
|
|
416
416
|
children: h || b
|
|
417
417
|
}),
|
|
418
|
-
w.length > 0 && /* @__PURE__ */
|
|
418
|
+
w.length > 0 && /* @__PURE__ */ o("div", {
|
|
419
419
|
className: "mt-3 p-2 bg-yellow-50 dark:bg-yellow-900/20 rounded text-left",
|
|
420
|
-
children: [/* @__PURE__ */
|
|
420
|
+
children: [/* @__PURE__ */ a("p", {
|
|
421
421
|
className: "text-xs font-medium text-yellow-700 dark:text-yellow-400 mb-1",
|
|
422
422
|
children: _("bigconsole.widget.renderer.adaptiveCard.templateWarnings", "Template Warnings:")
|
|
423
|
-
}), w.map((e, t) => /* @__PURE__ */
|
|
423
|
+
}), w.map((e, t) => /* @__PURE__ */ a("p", {
|
|
424
424
|
className: "text-xs text-yellow-600 dark:text-yellow-300",
|
|
425
425
|
children: e
|
|
426
426
|
}, t))]
|
|
427
427
|
})
|
|
428
428
|
]
|
|
429
429
|
})
|
|
430
|
-
}) : !d && !u ? /* @__PURE__ */
|
|
430
|
+
}) : !d && !u ? /* @__PURE__ */ a("div", {
|
|
431
431
|
className: "flex items-center justify-center h-full p-4 animate-in fade-in duration-200",
|
|
432
|
-
children: /* @__PURE__ */
|
|
432
|
+
children: /* @__PURE__ */ o("div", {
|
|
433
433
|
className: "text-center max-w-sm",
|
|
434
434
|
children: [
|
|
435
|
-
/* @__PURE__ */
|
|
435
|
+
/* @__PURE__ */ a("div", {
|
|
436
436
|
className: "w-12 h-12 mx-auto mb-3 rounded-full bg-bg-sunken flex items-center justify-center",
|
|
437
|
-
children: /* @__PURE__ */
|
|
437
|
+
children: /* @__PURE__ */ a("svg", {
|
|
438
438
|
className: "w-6 h-6 text-text-secondary",
|
|
439
439
|
fill: "none",
|
|
440
440
|
viewBox: "0 0 24 24",
|
|
441
441
|
stroke: "currentColor",
|
|
442
|
-
children: /* @__PURE__ */
|
|
442
|
+
children: /* @__PURE__ */ a("path", {
|
|
443
443
|
strokeLinecap: "round",
|
|
444
444
|
strokeLinejoin: "round",
|
|
445
445
|
strokeWidth: 2,
|
|
@@ -447,17 +447,17 @@ var f = new c.HostConfig({
|
|
|
447
447
|
})
|
|
448
448
|
})
|
|
449
449
|
}),
|
|
450
|
-
/* @__PURE__ */
|
|
450
|
+
/* @__PURE__ */ a("p", {
|
|
451
451
|
className: "font-medium text-secondary",
|
|
452
452
|
children: _("bigconsole.widget.renderer.adaptiveCard.noContent", "No content")
|
|
453
453
|
}),
|
|
454
|
-
/* @__PURE__ */
|
|
454
|
+
/* @__PURE__ */ a("p", {
|
|
455
455
|
className: "text-sm text-text-secondary mt-1",
|
|
456
456
|
children: _("bigconsole.widget.renderer.adaptiveCard.noContentHint", "Configure a template or provide data to display an Adaptive Card")
|
|
457
457
|
})
|
|
458
458
|
]
|
|
459
459
|
})
|
|
460
|
-
}) : /* @__PURE__ */
|
|
460
|
+
}) : /* @__PURE__ */ a("div", {
|
|
461
461
|
ref: v,
|
|
462
462
|
className: "adaptive-card-wrapper h-full overflow-auto",
|
|
463
463
|
style: { "--ac-font-family": "Inter, system-ui, -apple-system, sans-serif" }
|