@burdenoff/microfe-bigconsole 2026.1004.5 → 2026.1004.7
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/assistant/assistantProduct.d.ts +19 -0
- package/dist/bigconsole/assistant/assistantProduct.d.ts.map +1 -1
- package/dist/bigconsole/assistant/assistantProduct.js +64 -1
- package/dist/bigconsole/assistant/assistantProduct.js.map +1 -1
- package/dist/bigconsole/components/widgets/kanban/KanbanView.d.ts.map +1 -1
- package/dist/bigconsole/components/widgets/kanban/KanbanView.js +1 -1
- package/dist/bigconsole/components/widgets/kanban/KanbanView.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { LocalUiCommandOptions } from '@burdenoff/fe-libs/shared/assistant/localUiCommands';
|
|
2
|
+
import { AssistantEntityRoute } from '@burdenoff/fe-libs/shared/assistant/uiActions/entityRoutes';
|
|
2
3
|
import { AssistantProductProviderProps } from '@burdenoff/fe-libs/shared/assistant/product';
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -19,6 +20,24 @@ export declare const STORAGE_FOLDERS: {
|
|
|
19
20
|
readonly attachments: "/BigConsole/AI Assistant/Attachments";
|
|
20
21
|
readonly artifacts: "/BigConsole/AI Assistant/Artifacts";
|
|
21
22
|
};
|
|
23
|
+
/**
|
|
24
|
+
* The pages of ONE record that no sidebar entry names (BOFF-8060 N1b), so "take me
|
|
25
|
+
* there" can open them from a link in the assistant's own reply.
|
|
26
|
+
*
|
|
27
|
+
* ★★ `exclude` lists the router's STATIC siblings of each `:id` segment
|
|
28
|
+
* (`BigConsoleRoutes.tsx`): `datasinks/new` is the builder, not a data source.
|
|
29
|
+
* `entityRoutes.test.ts` resolves every template through the real route table and
|
|
30
|
+
* checks every static sibling against them, so the two lists cannot drift from the
|
|
31
|
+
* router unnoticed.
|
|
32
|
+
*
|
|
33
|
+
* ★ A workflow's address is `workflows/workflow/<key>/<version>` (a slug key such
|
|
34
|
+
* as `github_user_profile` or a UUID, plus `v1`); the version-less
|
|
35
|
+
* `workflows/:workflowId` is a different page and is deliberately not declared.
|
|
36
|
+
*
|
|
37
|
+
* ★ `/integrations/connections` is the app shell's Connected Systems page, shown
|
|
38
|
+
* to whoever can see the Integrations entry.
|
|
39
|
+
*/
|
|
40
|
+
export declare const ENTITY_ROUTES: readonly AssistantEntityRoute[];
|
|
22
41
|
/**
|
|
23
42
|
* How the panel reads a UI command it carries out itself (BOFF-7802), for
|
|
24
43
|
* BigConsole.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assistantProduct.d.ts","sourceRoot":"","sources":["../../../src/bigconsole/assistant/assistantProduct.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qDAAqD,CAAC;AACjG,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,6CAA6C,CAAC;AAOjG;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,eAAe;;;CAGlB,CAAC;AAEX;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"assistantProduct.d.ts","sourceRoot":"","sources":["../../../src/bigconsole/assistant/assistantProduct.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qDAAqD,CAAC;AACjG,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4DAA4D,CAAC;AACvG,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,6CAA6C,CAAC;AAOjG;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,eAAe;;;CAGlB,CAAC;AAEX;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,oBAAoB,EAoCxD,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,EAAE,qBAG/B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAC/C,IAAI,CAAC,6BAA6B,EAAE,UAAU,GAAG,kBAAkB,GAAG,cAAc,CAAC,CACtF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,4BAA4B,EAAE,0BA+B1C,CAAC"}
|
|
@@ -13,7 +13,70 @@ var a = {
|
|
|
13
13
|
gatherPageContext: n,
|
|
14
14
|
buildPrompt: r,
|
|
15
15
|
storageFolders: a,
|
|
16
|
-
localUiCommands: {
|
|
16
|
+
localUiCommands: {
|
|
17
|
+
themeWords: "mode-only",
|
|
18
|
+
entityRoutes: [
|
|
19
|
+
{
|
|
20
|
+
id: "bigconsole-datasink",
|
|
21
|
+
pattern: "/bigconsole/datasinks/:id",
|
|
22
|
+
params: { id: {
|
|
23
|
+
kind: "id",
|
|
24
|
+
exclude: ["new"]
|
|
25
|
+
} },
|
|
26
|
+
visibleWith: "bigconsole-datasinks",
|
|
27
|
+
noun: {
|
|
28
|
+
key: "entity.datasink",
|
|
29
|
+
fallback: "data source"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: "bigconsole-dashboard",
|
|
34
|
+
pattern: "/bigconsole/dashboards/:id",
|
|
35
|
+
params: { id: { kind: "id" } },
|
|
36
|
+
visibleWith: "bigconsole-dashboards",
|
|
37
|
+
noun: {
|
|
38
|
+
key: "entity.dashboard",
|
|
39
|
+
fallback: "dashboard"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: "bigconsole-parser",
|
|
44
|
+
pattern: "/bigconsole/parsers/:id",
|
|
45
|
+
params: { id: {
|
|
46
|
+
kind: "id",
|
|
47
|
+
exclude: ["new"]
|
|
48
|
+
} },
|
|
49
|
+
visibleWith: "bigconsole-parsers",
|
|
50
|
+
noun: {
|
|
51
|
+
key: "entity.parser",
|
|
52
|
+
fallback: "parser"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: "bigconsole-workflow",
|
|
57
|
+
pattern: "/bigconsole/workflows/workflow/:key/:version",
|
|
58
|
+
params: {
|
|
59
|
+
key: { kind: "slug" },
|
|
60
|
+
version: { kind: "slug" }
|
|
61
|
+
},
|
|
62
|
+
visibleWith: "bigconsole-workflows-list",
|
|
63
|
+
noun: {
|
|
64
|
+
key: "entity.workflow",
|
|
65
|
+
fallback: "workflow"
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: "bigconsole-connections",
|
|
70
|
+
pattern: "/integrations/connections",
|
|
71
|
+
params: {},
|
|
72
|
+
visibleWith: "integrations",
|
|
73
|
+
noun: {
|
|
74
|
+
key: "entity.connections",
|
|
75
|
+
fallback: "Connected Systems"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
},
|
|
17
80
|
reportTurnTimings: !0,
|
|
18
81
|
writeApproval: "proposal-v1"
|
|
19
82
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assistantProduct.js","names":[],"sources":["../../../src/bigconsole/assistant/assistantProduct.ts"],"sourcesContent":["/**\n * BigConsole's answers to the shared assistant's product seam, as one value.\n *\n * ★★ Every capability field on fe-libs' `AssistantProductProvider` is OPTIONAL,\n * and a missing one does not throw — it degrades SILENTLY. No `gatherPageContext`\n * sends every turn with no page context; no `buildPrompt` drops both the\n * confirm-before-mutate guardrail and the language directive; no\n * `storageFolders` starts a second folder beside the one holding every saved\n * attachment.\n *\n * So the value is typed `Required<…>` over the provider's own props: forgetting\n * a field, or fe-libs ADDING one, is a type error in this file rather than a\n * quiet regression in production.\n */\nimport type { LocalUiCommandOptions } from '@burdenoff/fe-libs/shared/assistant/localUiCommands';\nimport type { AssistantProductProviderProps } from '@burdenoff/fe-libs/shared/assistant/product';\n\nimport { buildPromptForMode } from './assistantPrompt';\nimport { BIGCONSOLE_ASSISTANT_MODES } from './modes';\nimport { describeCurrentPage, gatherPageContext } from './pageContext';\nimport { BIGCONSOLE_PRODUCT } from './product';\n\n/**\n * Where this product's assistant files land in the workspace file library.\n *\n * ★★ Capitalised as a DISPLAY name while the product id is `bigconsole`, which\n * is exactly why fe-libs cannot derive it: its fallback is\n * `/${product}/AI Assistant/…` → `/bigconsole/AI Assistant/…`.\n *\n * These strings become load-bearing the moment anything is saved. A wrong value\n * does not fail loudly — it quietly starts a SECOND folder beside the first and\n * orphans everything in the original. Today nothing can be orphaned: BigConsole's\n * legacy transport extracts uploaded files into the prompt and saves nothing to\n * the library, so no `/BigConsole/AI Assistant/*` path exists yet. That makes\n * this a free choice now and an expensive one the moment BC4 ships attachments.\n */\nexport const STORAGE_FOLDERS = {\n attachments: '/BigConsole/AI Assistant/Attachments',\n artifacts: '/BigConsole/AI Assistant/Artifacts',\n} as const;\n\n/**\n * How the panel reads a UI command it carries out itself (BOFF-7802), for\n * BigConsole.\n *\n * ★★ `mode-only` because BigConsole's CONTENT has themes of its own: a\n * dashboard has a theme, so \"use the dark theme\" in a dashboard builder is a\n * request about the dashboard, and must reach the model rather than flip the\n * app. fe-libs names this exact case (`LocalUiCommandOptions.themeWords`). Only\n * \"<name> mode\" (\"dark mode\") or a theme qualified as the app's (\"change the\n * app theme to dark\") still changes the app locally, with no turn.\n *\n * ★ Its own exported constant so the seam test can pin the field by identity,\n * like every other field on the seam value.\n */\nexport const LOCAL_UI_COMMANDS: LocalUiCommandOptions = {
|
|
1
|
+
{"version":3,"file":"assistantProduct.js","names":[],"sources":["../../../src/bigconsole/assistant/assistantProduct.ts"],"sourcesContent":["/**\n * BigConsole's answers to the shared assistant's product seam, as one value.\n *\n * ★★ Every capability field on fe-libs' `AssistantProductProvider` is OPTIONAL,\n * and a missing one does not throw — it degrades SILENTLY. No `gatherPageContext`\n * sends every turn with no page context; no `buildPrompt` drops both the\n * confirm-before-mutate guardrail and the language directive; no\n * `storageFolders` starts a second folder beside the one holding every saved\n * attachment.\n *\n * So the value is typed `Required<…>` over the provider's own props: forgetting\n * a field, or fe-libs ADDING one, is a type error in this file rather than a\n * quiet regression in production.\n */\nimport type { LocalUiCommandOptions } from '@burdenoff/fe-libs/shared/assistant/localUiCommands';\nimport type { AssistantEntityRoute } from '@burdenoff/fe-libs/shared/assistant/uiActions/entityRoutes';\nimport type { AssistantProductProviderProps } from '@burdenoff/fe-libs/shared/assistant/product';\n\nimport { buildPromptForMode } from './assistantPrompt';\nimport { BIGCONSOLE_ASSISTANT_MODES } from './modes';\nimport { describeCurrentPage, gatherPageContext } from './pageContext';\nimport { BIGCONSOLE_PRODUCT } from './product';\n\n/**\n * Where this product's assistant files land in the workspace file library.\n *\n * ★★ Capitalised as a DISPLAY name while the product id is `bigconsole`, which\n * is exactly why fe-libs cannot derive it: its fallback is\n * `/${product}/AI Assistant/…` → `/bigconsole/AI Assistant/…`.\n *\n * These strings become load-bearing the moment anything is saved. A wrong value\n * does not fail loudly — it quietly starts a SECOND folder beside the first and\n * orphans everything in the original. Today nothing can be orphaned: BigConsole's\n * legacy transport extracts uploaded files into the prompt and saves nothing to\n * the library, so no `/BigConsole/AI Assistant/*` path exists yet. That makes\n * this a free choice now and an expensive one the moment BC4 ships attachments.\n */\nexport const STORAGE_FOLDERS = {\n attachments: '/BigConsole/AI Assistant/Attachments',\n artifacts: '/BigConsole/AI Assistant/Artifacts',\n} as const;\n\n/**\n * The pages of ONE record that no sidebar entry names (BOFF-8060 N1b), so \"take me\n * there\" can open them from a link in the assistant's own reply.\n *\n * ★★ `exclude` lists the router's STATIC siblings of each `:id` segment\n * (`BigConsoleRoutes.tsx`): `datasinks/new` is the builder, not a data source.\n * `entityRoutes.test.ts` resolves every template through the real route table and\n * checks every static sibling against them, so the two lists cannot drift from the\n * router unnoticed.\n *\n * ★ A workflow's address is `workflows/workflow/<key>/<version>` (a slug key such\n * as `github_user_profile` or a UUID, plus `v1`); the version-less\n * `workflows/:workflowId` is a different page and is deliberately not declared.\n *\n * ★ `/integrations/connections` is the app shell's Connected Systems page, shown\n * to whoever can see the Integrations entry.\n */\nexport const ENTITY_ROUTES: readonly AssistantEntityRoute[] = [\n {\n id: 'bigconsole-datasink',\n pattern: '/bigconsole/datasinks/:id',\n params: { id: { kind: 'id', exclude: ['new'] } },\n visibleWith: 'bigconsole-datasinks',\n noun: { key: 'entity.datasink', fallback: 'data source' },\n },\n {\n id: 'bigconsole-dashboard',\n pattern: '/bigconsole/dashboards/:id',\n params: { id: { kind: 'id' } },\n visibleWith: 'bigconsole-dashboards',\n noun: { key: 'entity.dashboard', fallback: 'dashboard' },\n },\n {\n id: 'bigconsole-parser',\n pattern: '/bigconsole/parsers/:id',\n params: { id: { kind: 'id', exclude: ['new'] } },\n visibleWith: 'bigconsole-parsers',\n noun: { key: 'entity.parser', fallback: 'parser' },\n },\n {\n id: 'bigconsole-workflow',\n pattern: '/bigconsole/workflows/workflow/:key/:version',\n params: { key: { kind: 'slug' }, version: { kind: 'slug' } },\n visibleWith: 'bigconsole-workflows-list',\n noun: { key: 'entity.workflow', fallback: 'workflow' },\n },\n {\n id: 'bigconsole-connections',\n pattern: '/integrations/connections',\n params: {},\n visibleWith: 'integrations',\n noun: { key: 'entity.connections', fallback: 'Connected Systems' },\n },\n];\n\n/**\n * How the panel reads a UI command it carries out itself (BOFF-7802), for\n * BigConsole.\n *\n * ★★ `mode-only` because BigConsole's CONTENT has themes of its own: a\n * dashboard has a theme, so \"use the dark theme\" in a dashboard builder is a\n * request about the dashboard, and must reach the model rather than flip the\n * app. fe-libs names this exact case (`LocalUiCommandOptions.themeWords`). Only\n * \"<name> mode\" (\"dark mode\") or a theme qualified as the app's (\"change the\n * app theme to dark\") still changes the app locally, with no turn.\n *\n * ★ Its own exported constant so the seam test can pin the field by identity,\n * like every other field on the seam value.\n */\nexport const LOCAL_UI_COMMANDS: LocalUiCommandOptions = {\n themeWords: 'mode-only',\n entityRoutes: ENTITY_ROUTES,\n};\n\n/**\n * Every seam field, required — the provider's props minus its children, and\n * minus the two answers BigConsole deliberately does not give.\n *\n * ★★ `reportTokenUsage` is omitted ON EVIDENCE, not by oversight, and this\n * `Omit` member is the only place that decision is expressed in the type system.\n * `wspace-bigconsole-svc` declares NO token-usage mutation at all, and nothing in\n * this MFE reports one today. The obvious \"fix\" — wiring fe-libs' shared\n * reporter — would bill VibeControls for BigConsole turns: `reportAiTokenUsage`\n * is declared only in `wspace-vibecontrols-svc`, against the\n * `vibecontrols.ai.credits` quota. Metering BigConsole is a backend change.\n *\n * Note that BigConsole's `bigconsole.*` quotas are a different mechanism —\n * they cap entity counts, not AI spend — so their presence is not evidence that\n * turns are metered.\n *\n * ★★ `confirmWrite` is omitted so a HIGH-risk write proposal is confirmed in\n * fe-libs' shared `AssistantWriteConfirmDialog` (BOFF-7803 5a). That is the\n * documented default when a product has no dialog of its own, and BigConsole\n * has none. A product dialog must meet the whole contract fe-libs sets for it\n * (readback, target count, consequences, the exact confirm label, sensitive\n * values masked, never `window.confirm`), and the shared one already does, so a\n * BigConsole copy would only be a second place for that to go wrong. The\n * bigconsole-app ambient declaration of this value mirrors this `Omit`.\n */\nexport type BigConsoleAssistantProduct = Required<\n Omit<AssistantProductProviderProps, 'children' | 'reportTokenUsage' | 'confirmWrite'>\n>;\n\n/**\n * ★ Each field points at a product-owned implementation BY IDENTITY — no inline\n * arrow wrappers. The seam guard asserts `toBe`, because a wrapper is how a\n * function silently stops being the one the tests cover.\n *\n * ★ `writeAccess` is deliberately absent: it is a PROP on the shared panel, not\n * a seam field, so it belongs to BC4's panel mount rather than here. Same for\n * the preview controller, which the panel takes as `panelProps.preview`.\n */\nexport const BIGCONSOLE_ASSISTANT_PRODUCT: BigConsoleAssistantProduct = {\n product: BIGCONSOLE_PRODUCT,\n modes: BIGCONSOLE_ASSISTANT_MODES,\n describeCurrentPage,\n gatherPageContext,\n buildPrompt: buildPromptForMode,\n storageFolders: STORAGE_FOLDERS,\n localUiCommands: LOCAL_UI_COMMANDS,\n /**\n * ★ On. That is fe-libs' own default (on unless `false`, BOFF-7801) and\n * what BigConsole does today: this seam never set the field, so its turns\n * have been reported by default. The reports carry timings and coarse\n * dimensions only, and BigConsole is the first proposal-v1 product, so its\n * latency is the measurement the rollout needs.\n */\n reportTurnTimings: true,\n /**\n * ★★★ BigConsole is the FIRST proposal-v1 product (BOFF-7803 5a). At\n * `'proposal-v1'` fe-libs provisions Ask and Build (`api-calls`) through the\n * `assistant:use`-gated `provisionAssistantSandbox`, requests the proposal\n * flow for Build, and lets a spoken Build turn through when the sandbox's\n * own `/health` also says v1. Every change then waits for the button on its\n * card; the sandbox and wspace-sandbox-svc decide whether it runs.\n *\n * ★★ That provisioning path has NO `createSandbox` fallback: while\n * wspace-sandbox-svc answers it with 503 (its session relay switched off),\n * BigConsole's assistant cannot start at all. This flag reaches users only\n * when bigconsole-app pins the microfe version that carries it, so the app\n * bump is the release switch, and it waits for the relay.\n */\n writeApproval: 'proposal-v1',\n};\n"],"mappings":";;;;;AAqCA,IAAa,IAAkB;CAC7B,aAAa;CACb,WAAW;CACZ,EAkHY,IAA2D;CACtE,SAAS;CACT,OAAO;CACP;CACA;CACA,aAAa;CACb,gBAAgB;CAChB,iBAlDsD;EACtD,YAAY;EACZ,cAtD4D;GAC5D;IACE,IAAI;IACJ,SAAS;IACT,QAAQ,EAAE,IAAI;KAAE,MAAM;KAAM,SAAS,CAAC,MAAM;KAAE,EAAE;IAChD,aAAa;IACb,MAAM;KAAE,KAAK;KAAmB,UAAU;KAAe;IAC1D;GACD;IACE,IAAI;IACJ,SAAS;IACT,QAAQ,EAAE,IAAI,EAAE,MAAM,MAAM,EAAE;IAC9B,aAAa;IACb,MAAM;KAAE,KAAK;KAAoB,UAAU;KAAa;IACzD;GACD;IACE,IAAI;IACJ,SAAS;IACT,QAAQ,EAAE,IAAI;KAAE,MAAM;KAAM,SAAS,CAAC,MAAM;KAAE,EAAE;IAChD,aAAa;IACb,MAAM;KAAE,KAAK;KAAiB,UAAU;KAAU;IACnD;GACD;IACE,IAAI;IACJ,SAAS;IACT,QAAQ;KAAE,KAAK,EAAE,MAAM,QAAQ;KAAE,SAAS,EAAE,MAAM,QAAQ;KAAE;IAC5D,aAAa;IACb,MAAM;KAAE,KAAK;KAAmB,UAAU;KAAY;IACvD;GACD;IACE,IAAI;IACJ,SAAS;IACT,QAAQ,EAAE;IACV,aAAa;IACb,MAAM;KAAE,KAAK;KAAsB,UAAU;KAAqB;IACnE;GACF;EAmBA;CAuDC,mBAAmB;CAenB,eAAe;CAChB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KanbanView.d.ts","sourceRoot":"","sources":["../../../../../src/bigconsole/components/widgets/kanban/KanbanView.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAE,EAAmC,MAAM,OAAO,CAAC;AACjE,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,gBAAgB,EACtB,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAM5D,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,qGAAqG;IACrG,CAAC,EAAE,iBAAiB,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC/D;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;CACtC;AAmBD,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,
|
|
1
|
+
{"version":3,"file":"KanbanView.d.ts","sourceRoot":"","sources":["../../../../../src/bigconsole/components/widgets/kanban/KanbanView.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAE,EAAmC,MAAM,OAAO,CAAC;AACjE,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,gBAAgB,EACtB,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAM5D,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,qGAAqG;IACrG,CAAC,EAAE,iBAAiB,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC/D;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;CACtC;AAmBD,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CAqNzC,CAAC;AAEH,eAAe,UAAU,CAAC"}
|
|
@@ -70,7 +70,7 @@ var u = r(function({ widget: r, data: u, onClick: d, t: f, onSaveMoves: p, inter
|
|
|
70
70
|
"aria-label": `Column ${e.title}`,
|
|
71
71
|
className: "flex-shrink-0 w-48 flex flex-col bg-bg-sunken/50 rounded-lg",
|
|
72
72
|
onDragOver: (e) => {
|
|
73
|
-
w.current && !b && (e.preventDefault(), e.dataTransfer.dropEffect = "move");
|
|
73
|
+
w.current && !b && (e.stopPropagation(), e.preventDefault(), e.dataTransfer.dropEffect = "move");
|
|
74
74
|
},
|
|
75
75
|
onDrop: (t) => {
|
|
76
76
|
t.preventDefault(), t.stopPropagation();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KanbanView.js","names":[],"sources":["../../../../../src/bigconsole/components/widgets/kanban/KanbanView.tsx"],"sourcesContent":["/**\n * KanbanWidget Component\n *\n * Simple kanban board view with columns and tasks.\n */\n\nimport { type FC, memo, useMemo, useRef, useState } from 'react';\nimport {\n normalizeKanban,\n applyKanbanMoves,\n validKanbanMoves,\n type KanbanData,\n type KanbanTask,\n type KanbanColumnMove,\n} from './model';\nexport type { KanbanData, KanbanTask, KanbanColumn } from './model';\nimport type { Widget } from '../../../types';\nimport type { WidgetTranslateFn } from '../utils/translate';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface KanbanViewProps extends KanbanWidgetProps {\n /** Translator — the app passes useI18n().t; the public embed passes a static fallback translator. */\n t: WidgetTranslateFn;\n interactive?: boolean;\n onSaveMoves?: (moves: KanbanColumnMove[]) => Promise<boolean>;\n}\n\nexport interface KanbanWidgetProps {\n widget: Widget;\n data?: KanbanData;\n onClick?: (task: KanbanTask) => void;\n}\n\nfunction getPriorityColor(priority?: string): string {\n switch (priority) {\n case 'high':\n return 'bg-status-error-bg/20 text-status-error-text';\n case 'medium':\n return 'bg-status-warning-bg/20 text-[var(--color-status-warning-text)]';\n case 'low':\n return 'bg-status-success-bg/20 text-status-success-text';\n default:\n return 'bg-bg-sunken text-text-secondary';\n }\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const KanbanView: FC<KanbanViewProps> = memo(function KanbanView({\n widget,\n data,\n onClick,\n t,\n onSaveMoves,\n interactive = false,\n}) {\n const config = widget.config as Record<string, unknown> | undefined;\n const { columns, tasks: sourceTasks } = useMemo(() => normalizeKanban(data, config), [data, config]);\n const [local, setLocal] = useState<{ data: unknown; widgetId: string; moves: KanbanColumnMove[] } | null>(null);\n const [saving, setSaving] = useState(false);\n const [announcement, setAnnouncement] = useState('');\n const dragging = useRef<string | null>(null);\n const moves =\n local && local.data === data && local.widgetId === widget.id\n ? local.moves\n : validKanbanMoves(config?.kanbanColumnMoves);\n const tasks = useMemo(() => applyKanbanMoves(sourceTasks, columns, moves), [sourceTasks, columns, moves]);\n const moveTask = async (taskId: string, targetColumn: string) => {\n if (!interactive || saving || !columns.some((column) => column.id === targetColumn)) return;\n const task = sourceTasks.find((item) => item.id === taskId);\n if (!task || tasks.find((item) => item.id === taskId)?.column === targetColumn) return;\n const previous = validKanbanMoves(moves);\n const next = [\n ...previous.filter((move) => move.taskId !== taskId),\n { taskId, sourceColumn: task.column, targetColumn },\n ];\n setLocal({ data, widgetId: widget.id, moves: next });\n if (!onSaveMoves || !task.stableId) {\n setAnnouncement(\n t('bigconsole.widget.kanban.move.temporary', '{{title}} moved to {{column}} for this view.', {\n title: task.title,\n column: targetColumn,\n })\n );\n return;\n }\n setSaving(true);\n let saved: boolean;\n try {\n saved = await onSaveMoves(\n next.filter((move) => sourceTasks.some((source) => source.id === move.taskId && source.stableId))\n );\n } catch {\n saved = false;\n }\n setSaving(false);\n if (!saved) {\n setLocal({ data, widgetId: widget.id, moves: previous });\n setAnnouncement(\n t(\n 'bigconsole.widget.kanban.move.failed',\n 'Could not save the move. The card was returned to its previous column.'\n )\n );\n } else {\n setAnnouncement(\n t('bigconsole.widget.kanban.move.saved', '{{title}} moved to {{column}} and saved.', {\n title: task.title,\n column: targetColumn,\n })\n );\n }\n };\n\n // Group tasks by column\n const tasksByColumn = useMemo(() => {\n const grouped = new Map<string, KanbanTask[]>();\n columns.forEach((col) => {\n grouped.set(\n col.id,\n tasks.filter((t) => t.column === col.id)\n );\n });\n return grouped;\n }, [columns, tasks]);\n\n if (!columns.length) {\n return (\n <div className=\"flex items-center justify-center h-full text-text-secondary text-sm\">\n <div className=\"text-center\">\n <svg className=\"w-12 h-12 mx-auto mb-2 text-text-muted\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2\"\n />\n </svg>\n <p>{t('bigconsole.widget.kanban.emptyState', 'No board data')}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex h-full flex-col\">\n {interactive && (\n <p role=\"status\" className=\"px-2 pt-2 text-xs text-text-secondary\">\n {announcement ||\n (onSaveMoves\n ? t('bigconsole.widget.kanban.move.editorHint', 'Moves are saved to this widget.')\n : t('bigconsole.widget.kanban.move.viewerHint', 'Moves are temporary in this view.'))}\n </p>\n )}\n <div className=\"flex min-h-0 flex-1 p-2 gap-2 overflow-x-auto\">\n {columns.map((column) => {\n const columnTasks = tasksByColumn.get(column.id) || [];\n\n return (\n <div\n key={column.id}\n aria-label={`Column ${column.title}`}\n className=\"flex-shrink-0 w-48 flex flex-col bg-bg-sunken/50 rounded-lg\"\n onDragOver={(event) => {\n if (dragging.current && !saving) {\n event.preventDefault();\n event.dataTransfer.dropEffect = 'move';\n }\n }}\n onDrop={(event) => {\n event.preventDefault();\n event.stopPropagation();\n const id = dragging.current;\n dragging.current = null;\n if (id) void moveTask(id, column.id);\n }}\n >\n {/* Column Header */}\n <div className=\"flex items-center gap-2 p-2 border-b border-border-default\">\n <div\n className=\"w-2 h-2 rounded-full\"\n style={{ backgroundColor: column.color || 'var(--color-text-muted)' }}\n />\n <span className=\"text-xs font-medium text-text-primary truncate\">{column.title}</span>\n <span className=\"ml-auto text-xs text-text-muted\">{columnTasks.length}</span>\n </div>\n\n {/* Tasks */}\n <div className=\"flex-1 p-2 space-y-2 overflow-y-auto\">\n {columnTasks.map((task) => (\n <div\n key={task.id}\n draggable={interactive && !saving}\n onDragStart={(event) => {\n event.stopPropagation();\n dragging.current = task.id;\n event.dataTransfer.effectAllowed = 'move';\n event.dataTransfer.setData('text/plain', task.id);\n }}\n onDragEnd={() => {\n dragging.current = null;\n }}\n className={`\n p-2 bg-bg-surface rounded border border-border-default\n ${onClick ? 'cursor-pointer hover:border-action-primary-bg' : ''}\n transition-colors\n `}\n onClick={() => onClick?.(task)}\n >\n <p className=\"text-xs font-medium text-text-primary line-clamp-2\">{task.title}</p>\n {task.description && (\n <p className=\"mt-1 text-xs text-text-secondary line-clamp-3\">{task.description}</p>\n )}\n {interactive && (\n <select\n aria-label={`Move ${task.title} to column`}\n value={task.column}\n disabled={saving}\n onClick={(event) => event.stopPropagation()}\n onChange={(event) => {\n void moveTask(task.id, event.target.value);\n }}\n className=\"mt-2 w-full rounded border border-border-default bg-bg-surface text-xs text-text-secondary\"\n >\n {columns.map((target) => (\n <option key={target.id} value={target.id}>\n {target.title}\n </option>\n ))}\n </select>\n )}\n\n <div className=\"flex items-center gap-1 mt-2 flex-wrap\">\n {task.priority && (\n <span className={`px-1.5 py-0.5 text-[10px] rounded ${getPriorityColor(task.priority)}`}>\n {task.priority}\n </span>\n )}\n {task.assignee && (\n <span className=\"px-1.5 py-0.5 text-[10px] rounded bg-action-primary-bg/10 text-action-primary-text\">\n {task.assignee}\n </span>\n )}\n </div>\n </div>\n ))}\n\n {columnTasks.length === 0 && (\n <p className=\"text-[10px] text-text-muted text-center py-4\">\n {t('bigconsole.widget.kanban.noTasks', 'No tasks')}\n </p>\n )}\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n});\n\nexport default KanbanView;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"KanbanView.js","names":[],"sources":["../../../../../src/bigconsole/components/widgets/kanban/KanbanView.tsx"],"sourcesContent":["/**\n * KanbanWidget Component\n *\n * Simple kanban board view with columns and tasks.\n */\n\nimport { type FC, memo, useMemo, useRef, useState } from 'react';\nimport {\n normalizeKanban,\n applyKanbanMoves,\n validKanbanMoves,\n type KanbanData,\n type KanbanTask,\n type KanbanColumnMove,\n} from './model';\nexport type { KanbanData, KanbanTask, KanbanColumn } from './model';\nimport type { Widget } from '../../../types';\nimport type { WidgetTranslateFn } from '../utils/translate';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface KanbanViewProps extends KanbanWidgetProps {\n /** Translator — the app passes useI18n().t; the public embed passes a static fallback translator. */\n t: WidgetTranslateFn;\n interactive?: boolean;\n onSaveMoves?: (moves: KanbanColumnMove[]) => Promise<boolean>;\n}\n\nexport interface KanbanWidgetProps {\n widget: Widget;\n data?: KanbanData;\n onClick?: (task: KanbanTask) => void;\n}\n\nfunction getPriorityColor(priority?: string): string {\n switch (priority) {\n case 'high':\n return 'bg-status-error-bg/20 text-status-error-text';\n case 'medium':\n return 'bg-status-warning-bg/20 text-[var(--color-status-warning-text)]';\n case 'low':\n return 'bg-status-success-bg/20 text-status-success-text';\n default:\n return 'bg-bg-sunken text-text-secondary';\n }\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const KanbanView: FC<KanbanViewProps> = memo(function KanbanView({\n widget,\n data,\n onClick,\n t,\n onSaveMoves,\n interactive = false,\n}) {\n const config = widget.config as Record<string, unknown> | undefined;\n const { columns, tasks: sourceTasks } = useMemo(() => normalizeKanban(data, config), [data, config]);\n const [local, setLocal] = useState<{ data: unknown; widgetId: string; moves: KanbanColumnMove[] } | null>(null);\n const [saving, setSaving] = useState(false);\n const [announcement, setAnnouncement] = useState('');\n const dragging = useRef<string | null>(null);\n const moves =\n local && local.data === data && local.widgetId === widget.id\n ? local.moves\n : validKanbanMoves(config?.kanbanColumnMoves);\n const tasks = useMemo(() => applyKanbanMoves(sourceTasks, columns, moves), [sourceTasks, columns, moves]);\n const moveTask = async (taskId: string, targetColumn: string) => {\n if (!interactive || saving || !columns.some((column) => column.id === targetColumn)) return;\n const task = sourceTasks.find((item) => item.id === taskId);\n if (!task || tasks.find((item) => item.id === taskId)?.column === targetColumn) return;\n const previous = validKanbanMoves(moves);\n const next = [\n ...previous.filter((move) => move.taskId !== taskId),\n { taskId, sourceColumn: task.column, targetColumn },\n ];\n setLocal({ data, widgetId: widget.id, moves: next });\n if (!onSaveMoves || !task.stableId) {\n setAnnouncement(\n t('bigconsole.widget.kanban.move.temporary', '{{title}} moved to {{column}} for this view.', {\n title: task.title,\n column: targetColumn,\n })\n );\n return;\n }\n setSaving(true);\n let saved: boolean;\n try {\n saved = await onSaveMoves(\n next.filter((move) => sourceTasks.some((source) => source.id === move.taskId && source.stableId))\n );\n } catch {\n saved = false;\n }\n setSaving(false);\n if (!saved) {\n setLocal({ data, widgetId: widget.id, moves: previous });\n setAnnouncement(\n t(\n 'bigconsole.widget.kanban.move.failed',\n 'Could not save the move. The card was returned to its previous column.'\n )\n );\n } else {\n setAnnouncement(\n t('bigconsole.widget.kanban.move.saved', '{{title}} moved to {{column}} and saved.', {\n title: task.title,\n column: targetColumn,\n })\n );\n }\n };\n\n // Group tasks by column\n const tasksByColumn = useMemo(() => {\n const grouped = new Map<string, KanbanTask[]>();\n columns.forEach((col) => {\n grouped.set(\n col.id,\n tasks.filter((t) => t.column === col.id)\n );\n });\n return grouped;\n }, [columns, tasks]);\n\n if (!columns.length) {\n return (\n <div className=\"flex items-center justify-center h-full text-text-secondary text-sm\">\n <div className=\"text-center\">\n <svg className=\"w-12 h-12 mx-auto mb-2 text-text-muted\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2\"\n />\n </svg>\n <p>{t('bigconsole.widget.kanban.emptyState', 'No board data')}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex h-full flex-col\">\n {interactive && (\n <p role=\"status\" className=\"px-2 pt-2 text-xs text-text-secondary\">\n {announcement ||\n (onSaveMoves\n ? t('bigconsole.widget.kanban.move.editorHint', 'Moves are saved to this widget.')\n : t('bigconsole.widget.kanban.move.viewerHint', 'Moves are temporary in this view.'))}\n </p>\n )}\n <div className=\"flex min-h-0 flex-1 p-2 gap-2 overflow-x-auto\">\n {columns.map((column) => {\n const columnTasks = tasksByColumn.get(column.id) || [];\n\n return (\n <div\n key={column.id}\n aria-label={`Column ${column.title}`}\n className=\"flex-shrink-0 w-48 flex flex-col bg-bg-sunken/50 rounded-lg\"\n onDragOver={(event) => {\n if (dragging.current && !saving) {\n // The dashboard's palette drop zone uses a copy effect; task moves must stay local.\n event.stopPropagation();\n event.preventDefault();\n event.dataTransfer.dropEffect = 'move';\n }\n }}\n onDrop={(event) => {\n event.preventDefault();\n event.stopPropagation();\n const id = dragging.current;\n dragging.current = null;\n if (id) void moveTask(id, column.id);\n }}\n >\n {/* Column Header */}\n <div className=\"flex items-center gap-2 p-2 border-b border-border-default\">\n <div\n className=\"w-2 h-2 rounded-full\"\n style={{ backgroundColor: column.color || 'var(--color-text-muted)' }}\n />\n <span className=\"text-xs font-medium text-text-primary truncate\">{column.title}</span>\n <span className=\"ml-auto text-xs text-text-muted\">{columnTasks.length}</span>\n </div>\n\n {/* Tasks */}\n <div className=\"flex-1 p-2 space-y-2 overflow-y-auto\">\n {columnTasks.map((task) => (\n <div\n key={task.id}\n draggable={interactive && !saving}\n onDragStart={(event) => {\n event.stopPropagation();\n dragging.current = task.id;\n event.dataTransfer.effectAllowed = 'move';\n event.dataTransfer.setData('text/plain', task.id);\n }}\n onDragEnd={() => {\n dragging.current = null;\n }}\n className={`\n p-2 bg-bg-surface rounded border border-border-default\n ${onClick ? 'cursor-pointer hover:border-action-primary-bg' : ''}\n transition-colors\n `}\n onClick={() => onClick?.(task)}\n >\n <p className=\"text-xs font-medium text-text-primary line-clamp-2\">{task.title}</p>\n {task.description && (\n <p className=\"mt-1 text-xs text-text-secondary line-clamp-3\">{task.description}</p>\n )}\n {interactive && (\n <select\n aria-label={`Move ${task.title} to column`}\n value={task.column}\n disabled={saving}\n onClick={(event) => event.stopPropagation()}\n onChange={(event) => {\n void moveTask(task.id, event.target.value);\n }}\n className=\"mt-2 w-full rounded border border-border-default bg-bg-surface text-xs text-text-secondary\"\n >\n {columns.map((target) => (\n <option key={target.id} value={target.id}>\n {target.title}\n </option>\n ))}\n </select>\n )}\n\n <div className=\"flex items-center gap-1 mt-2 flex-wrap\">\n {task.priority && (\n <span className={`px-1.5 py-0.5 text-[10px] rounded ${getPriorityColor(task.priority)}`}>\n {task.priority}\n </span>\n )}\n {task.assignee && (\n <span className=\"px-1.5 py-0.5 text-[10px] rounded bg-action-primary-bg/10 text-action-primary-text\">\n {task.assignee}\n </span>\n )}\n </div>\n </div>\n ))}\n\n {columnTasks.length === 0 && (\n <p className=\"text-[10px] text-text-muted text-center py-4\">\n {t('bigconsole.widget.kanban.noTasks', 'No tasks')}\n </p>\n )}\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n});\n\nexport default KanbanView;\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/microfe-bigconsole",
|
|
3
|
-
"version": "2026.1004.
|
|
3
|
+
"version": "2026.1004.7",
|
|
4
4
|
"description": "BigConsole - AI-powered analytics and dashboard platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"@apollo/client": "^4.0.11",
|
|
53
|
-
"@burdenoff/fe-libs": "2026.1004.
|
|
53
|
+
"@burdenoff/fe-libs": "2026.1004.6",
|
|
54
54
|
"@burdenoff/fluidgrids-fe-sdk": "2026.731.4",
|
|
55
55
|
"@iconify/react": "^6.0.2",
|
|
56
56
|
"@monaco-editor/react": "^4.7.0",
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
"zustand": "^5.0.3"
|
|
86
86
|
},
|
|
87
87
|
"devDependencies": {
|
|
88
|
-
"@burdenoff/fe-libs": "2026.1004.
|
|
88
|
+
"@burdenoff/fe-libs": "2026.1004.6",
|
|
89
89
|
"@burdenoff/fluidgrids-fe-sdk": "2026.731.4",
|
|
90
90
|
"@eslint/js": "^10.0.1",
|
|
91
91
|
"@graphql-codegen/add": "^5.0.0",
|