@things-factory/ai-assistant 10.1.88 → 10.1.91

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.
Files changed (93) hide show
  1. package/client/components/assistant-chat.ts +45 -5
  2. package/client/components/assistant-dock.ts +30 -2
  3. package/client/components/entry-review.ts +246 -0
  4. package/client/components/workspace-view.ts +428 -0
  5. package/client/pages/assistant-workspace-page.ts +237 -0
  6. package/client/route.ts +9 -0
  7. package/client/utils/assistant-proposals.ts +11 -1
  8. package/client/utils/entry-proposal.ts +103 -0
  9. package/client/utils/workspace.ts +89 -0
  10. package/dist-client/components/assistant-chat.d.ts +3 -0
  11. package/dist-client/components/assistant-chat.js +46 -5
  12. package/dist-client/components/assistant-chat.js.map +1 -1
  13. package/dist-client/components/assistant-dock.d.ts +1 -0
  14. package/dist-client/components/assistant-dock.js +25 -2
  15. package/dist-client/components/assistant-dock.js.map +1 -1
  16. package/dist-client/components/entry-review.d.ts +9 -0
  17. package/dist-client/components/entry-review.js +247 -0
  18. package/dist-client/components/entry-review.js.map +1 -0
  19. package/dist-client/components/workspace-view.d.ts +19 -0
  20. package/dist-client/components/workspace-view.js +416 -0
  21. package/dist-client/components/workspace-view.js.map +1 -0
  22. package/dist-client/pages/assistant-workspace-page.d.ts +27 -0
  23. package/dist-client/pages/assistant-workspace-page.js +263 -0
  24. package/dist-client/pages/assistant-workspace-page.js.map +1 -0
  25. package/dist-client/route.d.ts +1 -0
  26. package/dist-client/route.js +10 -0
  27. package/dist-client/route.js.map +1 -0
  28. package/dist-client/tsconfig.tsbuildinfo +1 -1
  29. package/dist-client/utils/assistant-proposals.d.ts +1 -0
  30. package/dist-client/utils/assistant-proposals.js +9 -1
  31. package/dist-client/utils/assistant-proposals.js.map +1 -1
  32. package/dist-client/utils/entry-proposal.d.ts +55 -0
  33. package/dist-client/utils/entry-proposal.js +52 -0
  34. package/dist-client/utils/entry-proposal.js.map +1 -0
  35. package/dist-client/utils/workspace.d.ts +40 -0
  36. package/dist-client/utils/workspace.js +68 -0
  37. package/dist-client/utils/workspace.js.map +1 -0
  38. package/dist-server/service/assistant-mode/registry.js +13 -0
  39. package/dist-server/service/assistant-mode/registry.js.map +1 -1
  40. package/dist-server/service/assistant-mode/resolve.d.ts +11 -0
  41. package/dist-server/service/assistant-mode/resolve.js +15 -3
  42. package/dist-server/service/assistant-mode/resolve.js.map +1 -1
  43. package/dist-server/service/assistant-mode/types.d.ts +7 -1
  44. package/dist-server/service/assistant-mode/types.js.map +1 -1
  45. package/dist-server/service/data-entry/entry-apply.d.ts +46 -0
  46. package/dist-server/service/data-entry/entry-apply.js +102 -0
  47. package/dist-server/service/data-entry/entry-apply.js.map +1 -0
  48. package/dist-server/service/data-entry/entry-resolver.d.ts +4 -0
  49. package/dist-server/service/data-entry/entry-resolver.js +80 -0
  50. package/dist-server/service/data-entry/entry-resolver.js.map +1 -0
  51. package/dist-server/service/data-entry/entry-sources.d.ts +1 -0
  52. package/dist-server/service/data-entry/entry-sources.js +41 -0
  53. package/dist-server/service/data-entry/entry-sources.js.map +1 -0
  54. package/dist-server/service/data-entry/entry-target.d.ts +157 -0
  55. package/dist-server/service/data-entry/entry-target.js +343 -0
  56. package/dist-server/service/data-entry/entry-target.js.map +1 -0
  57. package/dist-server/service/data-entry/entry-tools.d.ts +43 -0
  58. package/dist-server/service/data-entry/entry-tools.js +185 -0
  59. package/dist-server/service/data-entry/entry-tools.js.map +1 -0
  60. package/dist-server/service/index.d.ts +6 -1
  61. package/dist-server/service/index.js +13 -2
  62. package/dist-server/service/index.js.map +1 -1
  63. package/dist-server/service/workspace/workspace-blocks.d.ts +24 -0
  64. package/dist-server/service/workspace/workspace-blocks.js +118 -0
  65. package/dist-server/service/workspace/workspace-blocks.js.map +1 -0
  66. package/dist-server/service/workspace/workspace-tools.d.ts +24 -0
  67. package/dist-server/service/workspace/workspace-tools.js +65 -0
  68. package/dist-server/service/workspace/workspace-tools.js.map +1 -0
  69. package/dist-server/tsconfig.tsbuildinfo +1 -1
  70. package/package.json +2 -2
  71. package/server/service/assistant-mode/registry.ts +13 -0
  72. package/server/service/assistant-mode/resolve.test.ts +2 -1
  73. package/server/service/assistant-mode/resolve.ts +15 -3
  74. package/server/service/assistant-mode/types.ts +7 -1
  75. package/server/service/data-entry/data-entry.test.ts +311 -0
  76. package/server/service/data-entry/entry-apply.ts +134 -0
  77. package/server/service/data-entry/entry-resolver.ts +74 -0
  78. package/server/service/data-entry/entry-sources.ts +35 -0
  79. package/server/service/data-entry/entry-target.ts +442 -0
  80. package/server/service/data-entry/entry-tools.ts +174 -0
  81. package/server/service/index.ts +10 -1
  82. package/server/service/workspace/workspace-blocks.ts +127 -0
  83. package/server/service/workspace/workspace-tools.ts +66 -0
  84. package/server/service/workspace/workspace.test.ts +58 -0
  85. package/test/entry-proposal.test.ts +67 -0
  86. package/test/open-doors.test.ts +2 -1
  87. package/test/workspace.test.ts +54 -0
  88. package/things-factory.config.js +6 -1
  89. package/translations/en.json +56 -1
  90. package/translations/ja.json +56 -1
  91. package/translations/ko.json +56 -1
  92. package/translations/ms.json +56 -1
  93. package/translations/zh.json +56 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry-review.js","sourceRoot":"","sources":["../../client/components/entry-review.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The rows of a data entry proposal, as the person reviews them (operato-application/design/ai/data-entry.md §5).\n *\n * Read-only on purpose: a correction is said in the conversation (\"row 2 is 12,000\", \"drop the last one\")\n * and the model proposes again. What is wrong in a cell is marked on the cell - blocking in the error\n * colour, a note in the outline - and where each row came from is on the row.\n */\nimport '@material/web/icon/icon.js'\n\nimport { LitElement, css, html, nothing } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { i18next } from '@operato/i18n'\n\nimport { entryCellIssues, entryIssueKey, type EntryIssueView, type EntryRowView, type EntryTotalView } from '../utils/entry-proposal.js'\n\nconst SHOWN = 50\n\nconst t = (key: string, defaultValue: string, options: Record<string, unknown> = {}) =>\n i18next.t(`ai-assistant.entry.${key}`, { defaultValue, ...options })\n\nfunction issueText(issue: EntryIssueView): string {\n const params = { ...(issue.params ?? {}) } as any\n if (Array.isArray(params.values)) params.values = params.values.join(', ')\n return String(i18next.t(entryIssueKey(issue), { defaultValue: issue.code, ...params }))\n}\n\nfunction shown(value: unknown): string {\n if (value === undefined || value === null) return ''\n if (typeof value === 'number') return value.toLocaleString(i18next.language || undefined)\n if (typeof value === 'boolean') return value ? '✓' : '—'\n return String(value)\n}\n\n@customElement('ox-assistant-entry-review')\nexport class AssistantEntryReview extends LitElement {\n static styles = css`\n :host {\n display: block;\n margin: 4px 0 2px;\n font-size: 12px;\n color: var(--md-sys-color-on-surface);\n }\n\n .summary {\n display: flex;\n flex-wrap: wrap;\n gap: 4px 10px;\n margin-bottom: 6px;\n color: var(--md-sys-color-on-surface-variant);\n }\n\n .summary .blocked {\n color: var(--md-sys-color-error);\n font-weight: 600;\n }\n\n .scroll {\n max-height: 320px;\n overflow: auto;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 6px;\n }\n\n table {\n width: 100%;\n border-collapse: collapse;\n }\n\n th,\n td {\n padding: 4px 6px;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n text-align: start;\n vertical-align: top;\n white-space: nowrap;\n }\n\n th {\n position: sticky;\n top: 0;\n background: var(--md-sys-color-surface-container);\n font-weight: 600;\n }\n\n td.num {\n text-align: end;\n font-variant-numeric: tabular-nums;\n }\n\n tr.blocked td {\n background: color-mix(in srgb, var(--md-sys-color-error) 6%, transparent);\n }\n\n td.bad {\n color: var(--md-sys-color-error);\n text-decoration: underline wavy var(--md-sys-color-error);\n text-underline-offset: 3px;\n }\n\n td.note {\n text-decoration: underline dotted var(--md-sys-color-outline);\n text-underline-offset: 3px;\n }\n\n .missing {\n color: var(--md-sys-color-error);\n font-style: italic;\n }\n\n .source {\n color: var(--md-sys-color-on-surface-variant);\n max-width: 180px;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .row-issue {\n display: block;\n color: var(--md-sys-color-on-surface-variant);\n white-space: normal;\n }\n\n .row-issue.blocking {\n color: var(--md-sys-color-error);\n }\n\n .verified {\n color: var(--md-sys-color-primary);\n }\n\n .verified md-icon,\n .totals md-icon {\n --md-icon-size: 14px;\n vertical-align: -2px;\n }\n\n .totals {\n display: flex;\n flex-wrap: wrap;\n gap: 2px 12px;\n margin: 6px 0 0;\n font-variant-numeric: tabular-nums;\n }\n\n .totals .differs {\n color: var(--md-sys-color-error);\n font-weight: 600;\n }\n\n .totals .matches {\n color: var(--md-sys-color-primary);\n }\n\n .more,\n .check-failed {\n margin-top: 4px;\n color: var(--md-sys-color-on-surface-variant);\n }\n `\n\n @property({ attribute: false }) proposal: any\n\n /** The sum of each totalled field, beside the total the material prints - a missing row shows here without reading every row. */\n private renderTotals(totals: EntryTotalView[], columns: { name: string; labelKey?: string }[]) {\n if (!totals.length) return nothing\n const name = (field: string) => {\n const column = columns.find(one => one.name === field)\n return column?.labelKey ? i18next.t(column.labelKey) : field\n }\n return html`<div class=\"totals\" role=\"status\">\n ${totals.map(total => html`\n <span>${t('total', '{field} total {sum}', { field: name(total.field), sum: shown(total.all) })}</span>\n ${total.ready !== total.all ? html`<span>${t('total-ready', 'entered {sum}', { sum: shown(total.ready) })}</span>` : nothing}\n ${total.declared !== undefined\n ? html`<span>${t('total-declared', 'the material says {sum}', { sum: shown(total.declared) })}${total.declaredFound === false ? ` (${t('total-not-found', 'not found in the file')})` : ''}</span>\n ${total.difference\n ? html`<span class=\"differs\">${t('total-differs', 'differs by {sum}', { sum: shown(total.difference) })}</span>`\n : html`<span class=\"matches\"><md-icon>task_alt</md-icon> ${t('total-matches', 'matches')}</span>`}`\n : nothing}\n `)}\n </div>`\n }\n\n render() {\n const p = this.proposal ?? {}\n const columns: { name: string; type: string; required?: boolean; labelKey?: string }[] = p.columns ?? []\n const rows: EntryRowView[] = p.rows ?? []\n const counts = p.counts ?? {}\n return html`\n <div class=\"summary\" role=\"status\">\n <span>${t('rows', '{count} rows', { count: counts.rows ?? rows.length })}</span>\n <span>${t('ready', '{count} ready', { count: counts.ready ?? 0 })}</span>\n ${counts.blocked ? html`<span class=\"blocked\">${t('blocked', '{count} will not be entered', { count: counts.blocked })}</span>` : nothing}\n ${counts.cut ? html`<span class=\"blocked\">${t('cut', '{count} left out over the limit', { count: counts.cut })}</span>` : nothing}\n ${counts.verified ? html`<span class=\"verified\"><md-icon>task_alt</md-icon> ${t('verified', '{count} found in their file', { count: counts.verified })}</span>` : nothing}\n ${counts.unmatched ? html`<span class=\"blocked\">${t('unmatched', '{count} with a value their file does not have', { count: counts.unmatched })}</span>` : nothing}\n </div>\n <div class=\"scroll\">\n <table>\n <thead>\n <tr>\n <th>#</th>\n ${columns.map(column => html`<th>${column.labelKey ? i18next.t(column.labelKey) : column.name}${column.required ? ' *' : ''}</th>`)}\n <th>${t('source', 'from')}</th>\n </tr>\n </thead>\n <tbody>\n ${rows.slice(0, SHOWN).map(row => {\n const blocked = (row.issues ?? []).some(issue => issue.blocking)\n const whole = entryCellIssues(row)\n return html`\n <tr class=${blocked ? 'blocked' : ''}>\n <td class=\"num\">${row.index + 1}</td>\n ${columns.map(column => {\n const issues = entryCellIssues(row, column.name)\n const bad = issues.some(issue => issue.blocking)\n const value = row.values?.[column.name]\n const text = shown(value)\n return html`<td\n class=\"${column.type === 'number' || column.type === 'integer' ? 'num' : ''} ${bad ? 'bad' : issues.length ? 'note' : ''}\"\n title=${issues.map(issueText).join('\\n')}\n >\n ${text || (issues.some(issue => issue.code === 'required') ? html`<span class=\"missing\">${t('missing', 'missing')}</span>` : '')}\n </td>`\n })}\n <td class=\"source\" title=${(row.sources ?? []).map(source => source.where || source.attachmentId).join(' · ')}>\n ${row.evidence ? html`<span class=\"verified\" title=${t('evidence', 'found on line {line} of the file', { line: row.evidence.line })}><md-icon>task_alt</md-icon></span> ` : nothing}\n ${(row.sources ?? []).map(source => source.where || source.attachmentId).join(' · ')}\n ${whole\n .filter(issue => issue.code !== 'no-source')\n .map(issue => html`<span class=\"row-issue ${issue.blocking ? 'blocking' : ''}\">${issueText(issue)}</span>`)}\n ${whole.some(issue => issue.code === 'no-source') ? html`<span class=\"row-issue\">${issueText({ code: 'no-source', blocking: false })}</span>` : nothing}\n </td>\n </tr>\n `\n })}\n </tbody>\n </table>\n </div>\n ${this.renderTotals(p.totals ?? [], columns)}\n ${rows.length > SHOWN ? html`<div class=\"more\">${t('more-rows', '{count} more rows are not shown - they are entered too.', { count: rows.length - SHOWN })}</div>` : nothing}\n ${p.checkFailed ? html`<div class=\"check-failed\">${t('check-failed', 'the application could not check these rows; they are checked again when entered.')}</div>` : nothing}\n `\n }\n}\n"]}
@@ -0,0 +1,19 @@
1
+ import '@material/web/icon/icon.js';
2
+ import { LitElement, type TemplateResult } from 'lit';
3
+ import { type WorkspaceView } from '../utils/workspace.js';
4
+ export declare class AssistantWorkspaceView extends LitElement {
5
+ static styles: import("lit").CSSResult;
6
+ workspace?: WorkspaceView;
7
+ private sorts;
8
+ private asTable;
9
+ private dark;
10
+ private themeWatch?;
11
+ connectedCallback(): void;
12
+ disconnectedCallback(): void;
13
+ render(): TemplateResult<1>;
14
+ private block;
15
+ private table;
16
+ private tableOf;
17
+ private chart;
18
+ private download;
19
+ }
@@ -0,0 +1,416 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ /*
3
+ * The blocks of an AI 작업판, drawn (operato-application/design/ai/workspace.md §3).
4
+ *
5
+ * Every kind is drawn here - the model writes no HTML. Charts use the eight validated categorical colours in
6
+ * a fixed order (dataviz reference palette, light and dark each checked); three of the light ones sit under
7
+ * 3:1 against the surface, so every chart carries its legend (two series or more) and a table view.
8
+ */
9
+ import '@material/web/icon/icon.js';
10
+ import { LitElement, css, html, nothing, svg } from 'lit';
11
+ import { customElement, property, state } from 'lit/decorators.js';
12
+ import { unsafeHTML } from 'lit/directives/unsafe-html.js';
13
+ import { i18next } from '@operato/i18n';
14
+ import { renderMarkdown } from './markdown.js';
15
+ import { sortRows, tableCsv } from '../utils/workspace.js';
16
+ const LIGHT = ['#2a78d6', '#eb6834', '#1baf7a', '#eda100', '#e87ba4', '#008300', '#4a3aa7', '#e34948'];
17
+ const DARK = ['#3987e5', '#d95926', '#199e70', '#c98500', '#d55181', '#008300', '#9085e9', '#e66767'];
18
+ const t = (key, defaultValue, options = {}) => String(i18next.t(`ai-assistant.workspace.${key}`, { defaultValue, ...options }));
19
+ const shown = (value) => value === null || value === undefined ? '' : typeof value === 'number' ? value.toLocaleString(i18next.language || undefined) : String(value);
20
+ /** Four round steps from zero to above the largest value. */
21
+ function ticksFor(max) {
22
+ if (!(max > 0))
23
+ return [0, 1];
24
+ const raw = max / 4;
25
+ const power = 10 ** Math.floor(Math.log10(raw));
26
+ const step = [1, 2, 2.5, 5, 10].map(one => one * power).find(one => one >= raw) ?? raw;
27
+ return Array.from({ length: Math.ceil(max / step) + 1 }, (_, i) => Math.round(i * step * 1e6) / 1e6);
28
+ }
29
+ let AssistantWorkspaceView = class AssistantWorkspaceView extends LitElement {
30
+ constructor() {
31
+ super(...arguments);
32
+ this.sorts = {};
33
+ this.asTable = new Set();
34
+ this.dark = false;
35
+ }
36
+ static { this.styles = css `
37
+ :host {
38
+ display: block;
39
+ color: var(--md-sys-color-on-surface);
40
+ font-size: 14px;
41
+ line-height: 1.5;
42
+ }
43
+
44
+ section {
45
+ margin: 0 0 20px;
46
+ }
47
+
48
+ h1,
49
+ h2,
50
+ h3 {
51
+ margin: 24px 0 8px;
52
+ line-height: 1.3;
53
+ }
54
+
55
+ h1 {
56
+ font-size: 22px;
57
+ }
58
+
59
+ h2 {
60
+ font-size: 18px;
61
+ }
62
+
63
+ h3 {
64
+ font-size: 15px;
65
+ }
66
+
67
+ .metrics {
68
+ display: grid;
69
+ grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
70
+ gap: 10px;
71
+ }
72
+
73
+ .metric {
74
+ padding: 12px 14px;
75
+ border: 1px solid var(--md-sys-color-outline-variant);
76
+ border-radius: 10px;
77
+ background: var(--md-sys-color-surface-container-lowest);
78
+ }
79
+
80
+ .metric .label {
81
+ color: var(--md-sys-color-on-surface-variant);
82
+ font-size: 12px;
83
+ }
84
+
85
+ .metric .value {
86
+ font-size: 22px;
87
+ font-weight: 650;
88
+ font-variant-numeric: tabular-nums;
89
+ }
90
+
91
+ .metric .note {
92
+ color: var(--md-sys-color-on-surface-variant);
93
+ font-size: 12px;
94
+ }
95
+
96
+ .bar {
97
+ display: flex;
98
+ align-items: center;
99
+ gap: 8px;
100
+ margin-bottom: 6px;
101
+ color: var(--md-sys-color-on-surface-variant);
102
+ font-size: 12px;
103
+ }
104
+
105
+ .bar .caption {
106
+ flex: 1;
107
+ }
108
+
109
+ .bar button {
110
+ display: inline-flex;
111
+ align-items: center;
112
+ gap: 4px;
113
+ padding: 3px 8px;
114
+ border: 1px solid var(--md-sys-color-outline-variant);
115
+ border-radius: 6px;
116
+ background: transparent;
117
+ color: inherit;
118
+ font: inherit;
119
+ cursor: pointer;
120
+ }
121
+
122
+ .bar md-icon {
123
+ --md-icon-size: 16px;
124
+ }
125
+
126
+ .scroll {
127
+ max-height: 560px;
128
+ overflow: auto;
129
+ border: 1px solid var(--md-sys-color-outline-variant);
130
+ border-radius: 8px;
131
+ }
132
+
133
+ table {
134
+ width: 100%;
135
+ border-collapse: collapse;
136
+ font-size: 13px;
137
+ }
138
+
139
+ th,
140
+ td {
141
+ padding: 6px 10px;
142
+ border-bottom: 1px solid var(--md-sys-color-outline-variant);
143
+ text-align: start;
144
+ white-space: nowrap;
145
+ }
146
+
147
+ th {
148
+ position: sticky;
149
+ top: 0;
150
+ background: var(--md-sys-color-surface-container);
151
+ font-weight: 600;
152
+ }
153
+
154
+ th button {
155
+ border: 0;
156
+ padding: 0;
157
+ background: none;
158
+ color: inherit;
159
+ font: inherit;
160
+ cursor: pointer;
161
+ }
162
+
163
+ td.num,
164
+ th.num {
165
+ text-align: end;
166
+ font-variant-numeric: tabular-nums;
167
+ }
168
+
169
+ .chart svg {
170
+ width: 100%;
171
+ height: auto;
172
+ display: block;
173
+ }
174
+
175
+ .chart .grid {
176
+ stroke: var(--md-sys-color-outline-variant);
177
+ stroke-width: 1;
178
+ }
179
+
180
+ .chart .tick {
181
+ fill: var(--md-sys-color-on-surface-variant);
182
+ font-size: 11px;
183
+ }
184
+
185
+ .legend {
186
+ display: flex;
187
+ flex-wrap: wrap;
188
+ gap: 4px 14px;
189
+ margin-top: 6px;
190
+ font-size: 12px;
191
+ }
192
+
193
+ .legend .swatch {
194
+ display: inline-block;
195
+ width: 10px;
196
+ height: 10px;
197
+ margin-inline-end: 5px;
198
+ border-radius: 3px;
199
+ vertical-align: -1px;
200
+ }
201
+
202
+ .steps {
203
+ list-style: none;
204
+ margin: 0;
205
+ padding: 0;
206
+ }
207
+
208
+ .steps li {
209
+ display: flex;
210
+ gap: 8px;
211
+ padding: 4px 0;
212
+ }
213
+
214
+ .steps md-icon {
215
+ --md-icon-size: 18px;
216
+ }
217
+
218
+ .steps .done md-icon {
219
+ color: var(--md-sys-color-primary);
220
+ }
221
+
222
+ .steps .failed md-icon {
223
+ color: var(--md-sys-color-error);
224
+ }
225
+
226
+ .steps .note {
227
+ display: block;
228
+ color: var(--md-sys-color-on-surface-variant);
229
+ font-size: 12px;
230
+ }
231
+
232
+ .unreadable,
233
+ .cut {
234
+ color: var(--md-sys-color-on-surface-variant);
235
+ font-size: 12px;
236
+ font-style: italic;
237
+ }
238
+
239
+ .markdown :first-child {
240
+ margin-top: 0;
241
+ }
242
+ `; }
243
+ connectedCallback() {
244
+ super.connectedCallback();
245
+ this.dark = document.body.classList.contains('dark');
246
+ this.themeWatch = new MutationObserver(() => (this.dark = document.body.classList.contains('dark')));
247
+ this.themeWatch.observe(document.body, { attributes: true, attributeFilter: ['class'] });
248
+ }
249
+ disconnectedCallback() {
250
+ this.themeWatch?.disconnect();
251
+ super.disconnectedCallback();
252
+ }
253
+ render() {
254
+ const blocks = this.workspace?.blocks ?? [];
255
+ return html `${blocks.map((block, i) => this.block(block, i))}`;
256
+ }
257
+ block(block, i) {
258
+ switch (block.kind) {
259
+ case 'heading':
260
+ return block.level === 1 ? html `<h1>${block.text}</h1>` : block.level === 3 ? html `<h3>${block.text}</h3>` : html `<h2>${block.text}</h2>`;
261
+ case 'text':
262
+ return html `<section class="markdown">${unsafeHTML(renderMarkdown(block.markdown))}</section>`;
263
+ case 'metrics':
264
+ return html `<section class="metrics">
265
+ ${(block.items ?? []).map((one) => html `<div class="metric">
266
+ <div class="label">${one.label}</div>
267
+ <div class="value">${shown(one.value)}${one.unit ? html ` <small>${one.unit}</small>` : nothing}</div>
268
+ ${one.note ? html `<div class="note">${one.note}</div>` : nothing}
269
+ </div>`)}
270
+ </section>`;
271
+ case 'table':
272
+ return this.table(block, i);
273
+ case 'chart':
274
+ return this.chart(block, i);
275
+ case 'steps':
276
+ return html `<section>
277
+ <ol class="steps">
278
+ ${(block.items ?? []).map((one) => html `<li class=${one.state}>
279
+ <md-icon>${{ done: 'check_circle', doing: 'progress_activity', failed: 'error', todo: 'radio_button_unchecked' }[one.state] ?? 'radio_button_unchecked'}</md-icon>
280
+ <span>${one.label}${one.note ? html `<span class="note">${one.note}</span>` : nothing}</span>
281
+ </li>`)}
282
+ </ol>
283
+ </section>`;
284
+ default:
285
+ return html `<section class="unreadable">${t('unreadable', 'a block that cannot be drawn ({reason})', { reason: block.reason ?? block.kind })}</section>`;
286
+ }
287
+ }
288
+ table(block, i) {
289
+ const columns = block.columns ?? [];
290
+ const sort = this.sorts[i];
291
+ const rows = sort ? sortRows(block.rows ?? [], sort.column, sort.direction, i18next.language) : block.rows ?? [];
292
+ const toggle = (column) => (this.sorts = { ...this.sorts, [i]: { column, direction: sort?.column === column && sort.direction === 'asc' ? 'desc' : 'asc' } });
293
+ return html `<section>
294
+ <div class="bar">
295
+ <span class="caption">${block.caption ?? ''} · ${t('rows', '{count} rows', { count: rows.length })}</span>
296
+ <button @click=${() => this.download(block.caption || this.workspace?.title || 'table', columns, rows)}>
297
+ <md-icon>download</md-icon>${t('csv', 'CSV')}
298
+ </button>
299
+ </div>
300
+ ${this.tableOf(columns, rows, sort, toggle)}
301
+ ${block.cut ? html `<div class="cut">${t('cut', '{count} more rows were left out over the limit.', { count: block.cut })}</div>` : nothing}
302
+ </section>`;
303
+ }
304
+ tableOf(columns, rows, sort, toggle) {
305
+ return html `<div class="scroll">
306
+ <table>
307
+ <thead>
308
+ <tr>
309
+ ${columns.map(column => html `<th class=${column.type === 'number' ? 'num' : ''} aria-sort=${sort?.column === column.name ? (sort.direction === 'asc' ? 'ascending' : 'descending') : 'none'}>
310
+ ${toggle
311
+ ? html `<button @click=${() => toggle(column.name)}>${column.label || column.name}${sort?.column === column.name ? (sort.direction === 'asc' ? ' ▲' : ' ▼') : ''}</button>`
312
+ : column.label || column.name}
313
+ </th>`)}
314
+ </tr>
315
+ </thead>
316
+ <tbody>
317
+ ${rows.map(row => html `<tr>${columns.map(column => html `<td class=${column.type === 'number' || typeof row[column.name] === 'number' ? 'num' : ''}>${shown(row[column.name])}</td>`)}</tr>`)}
318
+ </tbody>
319
+ </table>
320
+ </div>`;
321
+ }
322
+ chart(block, i) {
323
+ const colours = this.dark ? DARK : LIGHT;
324
+ const x = block.x ?? [];
325
+ const series = block.series ?? [];
326
+ const name = (one) => (one.other ? t('other', 'other') : one.name);
327
+ const showingTable = this.asTable.has(i);
328
+ const flip = () => {
329
+ const next = new Set(this.asTable);
330
+ next.has(i) ? next.delete(i) : next.add(i);
331
+ this.asTable = next;
332
+ };
333
+ const bar = html `<div class="bar">
334
+ <span class="caption">${block.caption ?? ''}${block.unit ? ` (${block.unit})` : ''}</span>
335
+ <button @click=${flip}><md-icon>${showingTable ? 'bar_chart' : 'table_rows'}</md-icon>${showingTable ? t('as-chart', 'chart') : t('as-table', 'table')}</button>
336
+ </div>`;
337
+ if (showingTable) {
338
+ const columns = [{ name: '_x', label: '' }, ...series.map((one, s) => ({ name: `s${s}`, label: name(one), type: 'number' }))];
339
+ const rows = x.map((label, j) => Object.fromEntries([['_x', label], ...series.map((one, s) => [`s${s}`, one.values[j]])]));
340
+ return html `<section class="chart">${bar}${this.tableOf(columns, rows)}</section>`;
341
+ }
342
+ const W = 640;
343
+ const H = 240;
344
+ const left = 56;
345
+ const bottom = 28;
346
+ const plotW = W - left - 8;
347
+ const plotH = H - bottom - 10;
348
+ const values = series.flatMap(one => one.values).filter((v) => typeof v === 'number');
349
+ const min = Math.min(0, ...values);
350
+ const ticks = ticksFor(Math.max(...values, 0) - min).map(tick => tick + min);
351
+ const top = ticks[ticks.length - 1] || 1;
352
+ const y = (v) => 10 + plotH - ((v - min) / (top - min || 1)) * plotH;
353
+ const band = plotW / Math.max(1, x.length);
354
+ const everyNth = Math.max(1, Math.ceil(x.length / 12));
355
+ const marks = block.chart === 'line'
356
+ ? series.map((one, s) => {
357
+ const points = one.values.map((v, j) => (typeof v === 'number' ? [left + band * (j + 0.5), y(v)] : null));
358
+ const path = points.reduce((d, p, j) => (p ? `${d}${d && points[j - 1] ? 'L' : 'M'}${p[0]},${p[1]}` : d), '');
359
+ return svg `<path d=${path} fill="none" stroke=${colours[s % 8]} stroke-width="2" stroke-linejoin="round" stroke-linecap="round"></path>
360
+ ${points.map((p, j) => p ? svg `<circle cx=${p[0]} cy=${p[1]} r="4" fill=${colours[s % 8]} stroke="var(--md-sys-color-surface)" stroke-width="2"><title>${name(one)} · ${x[j]}: ${shown(one.values[j])}</title></circle>` : nothing)}`;
361
+ })
362
+ : series.map((one, s) => {
363
+ const inner = band * 0.7;
364
+ const width = Math.max(2, inner / series.length - 2);
365
+ return one.values.map((v, j) => {
366
+ if (typeof v !== 'number')
367
+ return nothing;
368
+ const x0 = left + band * j + (band - inner) / 2 + s * (width + 2);
369
+ const y0 = Math.min(y(v), y(0));
370
+ const h = Math.max(1, Math.abs(y(v) - y(0)));
371
+ return svg `<rect x=${x0} y=${y0} width=${width} height=${h} rx="3" fill=${colours[s % 8]}><title>${name(one)} · ${x[j]}: ${shown(v)}</title></rect>`;
372
+ });
373
+ });
374
+ return html `<section class="chart" role="img" aria-label=${block.caption || series.map(name).join(', ')}>
375
+ ${bar}
376
+ <svg viewBox="0 0 ${W} ${H}">
377
+ ${ticks.map(tick => svg `<line class="grid" x1=${left} x2=${W - 8} y1=${y(tick)} y2=${y(tick)}></line><text class="tick" x=${left - 6} y=${y(tick) + 4} text-anchor="end">${shown(tick)}</text>`)}
378
+ ${marks}
379
+ ${x.map((label, j) => (j % everyNth ? nothing : svg `<text class="tick" x=${left + band * (j + 0.5)} y=${H - 8} text-anchor="middle">${label}</text>`))}
380
+ </svg>
381
+ ${series.length > 1
382
+ ? html `<div class="legend">${series.map((one, s) => html `<span><span class="swatch" style="background:${colours[s % 8]}"></span>${name(one)}</span>`)}</div>`
383
+ : nothing}
384
+ </section>`;
385
+ }
386
+ download(title, columns, rows) {
387
+ const blob = new Blob([tableCsv(columns, rows)], { type: 'text/csv;charset=utf-8' });
388
+ const url = URL.createObjectURL(blob);
389
+ const link = document.createElement('a');
390
+ link.href = url;
391
+ link.download = `${title.replace(/[\\/:*?"<>|]+/g, '-').slice(0, 80)}.csv`;
392
+ link.click();
393
+ setTimeout(() => URL.revokeObjectURL(url), 1000);
394
+ }
395
+ };
396
+ __decorate([
397
+ property({ attribute: false }),
398
+ __metadata("design:type", Object)
399
+ ], AssistantWorkspaceView.prototype, "workspace", void 0);
400
+ __decorate([
401
+ state(),
402
+ __metadata("design:type", Object)
403
+ ], AssistantWorkspaceView.prototype, "sorts", void 0);
404
+ __decorate([
405
+ state(),
406
+ __metadata("design:type", Object)
407
+ ], AssistantWorkspaceView.prototype, "asTable", void 0);
408
+ __decorate([
409
+ state(),
410
+ __metadata("design:type", Object)
411
+ ], AssistantWorkspaceView.prototype, "dark", void 0);
412
+ AssistantWorkspaceView = __decorate([
413
+ customElement('ox-assistant-workspace-view')
414
+ ], AssistantWorkspaceView);
415
+ export { AssistantWorkspaceView };
416
+ //# sourceMappingURL=workspace-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-view.js","sourceRoot":"","sources":["../../client/components/workspace-view.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The blocks of an AI 작업판, drawn (operato-application/design/ai/workspace.md §3).\n *\n * Every kind is drawn here - the model writes no HTML. Charts use the eight validated categorical colours in\n * a fixed order (dataviz reference palette, light and dark each checked); three of the light ones sit under\n * 3:1 against the surface, so every chart carries its legend (two series or more) and a table view.\n */\nimport '@material/web/icon/icon.js'\n\nimport { LitElement, css, html, nothing, svg, type TemplateResult } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js'\n\nimport { i18next } from '@operato/i18n'\n\nimport { renderMarkdown } from './markdown.js'\nimport { sortRows, tableCsv, type WorkspaceBlockView, type WorkspaceView } from '../utils/workspace.js'\n\nconst LIGHT = ['#2a78d6', '#eb6834', '#1baf7a', '#eda100', '#e87ba4', '#008300', '#4a3aa7', '#e34948']\nconst DARK = ['#3987e5', '#d95926', '#199e70', '#c98500', '#d55181', '#008300', '#9085e9', '#e66767']\n\nconst t = (key: string, defaultValue: string, options: Record<string, unknown> = {}) =>\n String(i18next.t(`ai-assistant.workspace.${key}`, { defaultValue, ...options }))\n\nconst shown = (value: unknown) =>\n value === null || value === undefined ? '' : typeof value === 'number' ? value.toLocaleString(i18next.language || undefined) : String(value)\n\n/** Four round steps from zero to above the largest value. */\nfunction ticksFor(max: number): number[] {\n if (!(max > 0)) return [0, 1]\n const raw = max / 4\n const power = 10 ** Math.floor(Math.log10(raw))\n const step = [1, 2, 2.5, 5, 10].map(one => one * power).find(one => one >= raw) ?? raw\n return Array.from({ length: Math.ceil(max / step) + 1 }, (_, i) => Math.round(i * step * 1e6) / 1e6)\n}\n\n@customElement('ox-assistant-workspace-view')\nexport class AssistantWorkspaceView extends LitElement {\n static styles = css`\n :host {\n display: block;\n color: var(--md-sys-color-on-surface);\n font-size: 14px;\n line-height: 1.5;\n }\n\n section {\n margin: 0 0 20px;\n }\n\n h1,\n h2,\n h3 {\n margin: 24px 0 8px;\n line-height: 1.3;\n }\n\n h1 {\n font-size: 22px;\n }\n\n h2 {\n font-size: 18px;\n }\n\n h3 {\n font-size: 15px;\n }\n\n .metrics {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));\n gap: 10px;\n }\n\n .metric {\n padding: 12px 14px;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 10px;\n background: var(--md-sys-color-surface-container-lowest);\n }\n\n .metric .label {\n color: var(--md-sys-color-on-surface-variant);\n font-size: 12px;\n }\n\n .metric .value {\n font-size: 22px;\n font-weight: 650;\n font-variant-numeric: tabular-nums;\n }\n\n .metric .note {\n color: var(--md-sys-color-on-surface-variant);\n font-size: 12px;\n }\n\n .bar {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n color: var(--md-sys-color-on-surface-variant);\n font-size: 12px;\n }\n\n .bar .caption {\n flex: 1;\n }\n\n .bar button {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 6px;\n background: transparent;\n color: inherit;\n font: inherit;\n cursor: pointer;\n }\n\n .bar md-icon {\n --md-icon-size: 16px;\n }\n\n .scroll {\n max-height: 560px;\n overflow: auto;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 8px;\n }\n\n table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n }\n\n th,\n td {\n padding: 6px 10px;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n text-align: start;\n white-space: nowrap;\n }\n\n th {\n position: sticky;\n top: 0;\n background: var(--md-sys-color-surface-container);\n font-weight: 600;\n }\n\n th button {\n border: 0;\n padding: 0;\n background: none;\n color: inherit;\n font: inherit;\n cursor: pointer;\n }\n\n td.num,\n th.num {\n text-align: end;\n font-variant-numeric: tabular-nums;\n }\n\n .chart svg {\n width: 100%;\n height: auto;\n display: block;\n }\n\n .chart .grid {\n stroke: var(--md-sys-color-outline-variant);\n stroke-width: 1;\n }\n\n .chart .tick {\n fill: var(--md-sys-color-on-surface-variant);\n font-size: 11px;\n }\n\n .legend {\n display: flex;\n flex-wrap: wrap;\n gap: 4px 14px;\n margin-top: 6px;\n font-size: 12px;\n }\n\n .legend .swatch {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin-inline-end: 5px;\n border-radius: 3px;\n vertical-align: -1px;\n }\n\n .steps {\n list-style: none;\n margin: 0;\n padding: 0;\n }\n\n .steps li {\n display: flex;\n gap: 8px;\n padding: 4px 0;\n }\n\n .steps md-icon {\n --md-icon-size: 18px;\n }\n\n .steps .done md-icon {\n color: var(--md-sys-color-primary);\n }\n\n .steps .failed md-icon {\n color: var(--md-sys-color-error);\n }\n\n .steps .note {\n display: block;\n color: var(--md-sys-color-on-surface-variant);\n font-size: 12px;\n }\n\n .unreadable,\n .cut {\n color: var(--md-sys-color-on-surface-variant);\n font-size: 12px;\n font-style: italic;\n }\n\n .markdown :first-child {\n margin-top: 0;\n }\n `\n\n @property({ attribute: false }) workspace?: WorkspaceView\n\n @state() private sorts: Record<number, { column: string; direction: 'asc' | 'desc' }> = {}\n @state() private asTable = new Set<number>()\n @state() private dark = false\n\n private themeWatch?: MutationObserver\n\n connectedCallback() {\n super.connectedCallback()\n this.dark = document.body.classList.contains('dark')\n this.themeWatch = new MutationObserver(() => (this.dark = document.body.classList.contains('dark')))\n this.themeWatch.observe(document.body, { attributes: true, attributeFilter: ['class'] })\n }\n\n disconnectedCallback() {\n this.themeWatch?.disconnect()\n super.disconnectedCallback()\n }\n\n render() {\n const blocks = this.workspace?.blocks ?? []\n return html`${blocks.map((block, i) => this.block(block, i))}`\n }\n\n private block(block: WorkspaceBlockView, i: number): TemplateResult {\n switch (block.kind) {\n case 'heading':\n return block.level === 1 ? html`<h1>${block.text}</h1>` : block.level === 3 ? html`<h3>${block.text}</h3>` : html`<h2>${block.text}</h2>`\n case 'text':\n return html`<section class=\"markdown\">${unsafeHTML(renderMarkdown(block.markdown))}</section>`\n case 'metrics':\n return html`<section class=\"metrics\">\n ${(block.items ?? []).map(\n (one: any) => html`<div class=\"metric\">\n <div class=\"label\">${one.label}</div>\n <div class=\"value\">${shown(one.value)}${one.unit ? html` <small>${one.unit}</small>` : nothing}</div>\n ${one.note ? html`<div class=\"note\">${one.note}</div>` : nothing}\n </div>`\n )}\n </section>`\n case 'table':\n return this.table(block, i)\n case 'chart':\n return this.chart(block, i)\n case 'steps':\n return html`<section>\n <ol class=\"steps\">\n ${(block.items ?? []).map(\n (one: any) => html`<li class=${one.state}>\n <md-icon>${{ done: 'check_circle', doing: 'progress_activity', failed: 'error', todo: 'radio_button_unchecked' }[one.state as string] ?? 'radio_button_unchecked'}</md-icon>\n <span>${one.label}${one.note ? html`<span class=\"note\">${one.note}</span>` : nothing}</span>\n </li>`\n )}\n </ol>\n </section>`\n default:\n return html`<section class=\"unreadable\">${t('unreadable', 'a block that cannot be drawn ({reason})', { reason: block.reason ?? block.kind })}</section>`\n }\n }\n\n private table(block: WorkspaceBlockView, i: number): TemplateResult {\n const columns: { name: string; label?: string; type?: string }[] = block.columns ?? []\n const sort = this.sorts[i]\n const rows = sort ? sortRows(block.rows ?? [], sort.column, sort.direction, i18next.language) : block.rows ?? []\n const toggle = (column: string) =>\n (this.sorts = { ...this.sorts, [i]: { column, direction: sort?.column === column && sort.direction === 'asc' ? 'desc' : 'asc' } })\n return html`<section>\n <div class=\"bar\">\n <span class=\"caption\">${block.caption ?? ''} · ${t('rows', '{count} rows', { count: rows.length })}</span>\n <button @click=${() => this.download(block.caption || this.workspace?.title || 'table', columns, rows)}>\n <md-icon>download</md-icon>${t('csv', 'CSV')}\n </button>\n </div>\n ${this.tableOf(columns, rows, sort, toggle)}\n ${block.cut ? html`<div class=\"cut\">${t('cut', '{count} more rows were left out over the limit.', { count: block.cut })}</div>` : nothing}\n </section>`\n }\n\n private tableOf(columns: { name: string; label?: string; type?: string }[], rows: Record<string, any>[], sort?: { column: string; direction: string }, toggle?: (column: string) => void) {\n return html`<div class=\"scroll\">\n <table>\n <thead>\n <tr>\n ${columns.map(\n column => html`<th class=${column.type === 'number' ? 'num' : ''} aria-sort=${sort?.column === column.name ? (sort.direction === 'asc' ? 'ascending' : 'descending') : 'none'}>\n ${toggle\n ? html`<button @click=${() => toggle(column.name)}>${column.label || column.name}${sort?.column === column.name ? (sort.direction === 'asc' ? ' ▲' : ' ▼') : ''}</button>`\n : column.label || column.name}\n </th>`\n )}\n </tr>\n </thead>\n <tbody>\n ${rows.map(row => html`<tr>${columns.map(column => html`<td class=${column.type === 'number' || typeof row[column.name] === 'number' ? 'num' : ''}>${shown(row[column.name])}</td>`)}</tr>`)}\n </tbody>\n </table>\n </div>`\n }\n\n private chart(block: WorkspaceBlockView, i: number): TemplateResult {\n const colours = this.dark ? DARK : LIGHT\n const x: string[] = block.x ?? []\n const series: { name: string; other?: boolean; values: (number | null)[] }[] = block.series ?? []\n const name = (one: { name: string; other?: boolean }) => (one.other ? t('other', 'other') : one.name)\n const showingTable = this.asTable.has(i)\n const flip = () => {\n const next = new Set(this.asTable)\n next.has(i) ? next.delete(i) : next.add(i)\n this.asTable = next\n }\n\n const bar = html`<div class=\"bar\">\n <span class=\"caption\">${block.caption ?? ''}${block.unit ? ` (${block.unit})` : ''}</span>\n <button @click=${flip}><md-icon>${showingTable ? 'bar_chart' : 'table_rows'}</md-icon>${showingTable ? t('as-chart', 'chart') : t('as-table', 'table')}</button>\n </div>`\n\n if (showingTable) {\n const columns = [{ name: '_x', label: '' }, ...series.map((one, s) => ({ name: `s${s}`, label: name(one), type: 'number' }))]\n const rows = x.map((label, j) => Object.fromEntries([['_x', label], ...series.map((one, s) => [`s${s}`, one.values[j]])]))\n return html`<section class=\"chart\">${bar}${this.tableOf(columns, rows)}</section>`\n }\n\n const W = 640\n const H = 240\n const left = 56\n const bottom = 28\n const plotW = W - left - 8\n const plotH = H - bottom - 10\n const values = series.flatMap(one => one.values).filter((v): v is number => typeof v === 'number')\n const min = Math.min(0, ...values)\n const ticks = ticksFor(Math.max(...values, 0) - min).map(tick => tick + min)\n const top = ticks[ticks.length - 1] || 1\n const y = (v: number) => 10 + plotH - ((v - min) / (top - min || 1)) * plotH\n const band = plotW / Math.max(1, x.length)\n const everyNth = Math.max(1, Math.ceil(x.length / 12))\n\n const marks =\n block.chart === 'line'\n ? series.map((one, s) => {\n const points = one.values.map((v, j) => (typeof v === 'number' ? [left + band * (j + 0.5), y(v)] : null))\n const path = points.reduce((d, p, j) => (p ? `${d}${d && points[j - 1] ? 'L' : 'M'}${p[0]},${p[1]}` : d), '')\n return svg`<path d=${path} fill=\"none\" stroke=${colours[s % 8]} stroke-width=\"2\" stroke-linejoin=\"round\" stroke-linecap=\"round\"></path>\n ${points.map((p, j) =>\n p ? svg`<circle cx=${p[0]} cy=${p[1]} r=\"4\" fill=${colours[s % 8]} stroke=\"var(--md-sys-color-surface)\" stroke-width=\"2\"><title>${name(one)} · ${x[j]}: ${shown(one.values[j])}</title></circle>` : nothing\n )}`\n })\n : series.map((one, s) => {\n const inner = band * 0.7\n const width = Math.max(2, inner / series.length - 2)\n return one.values.map((v, j) => {\n if (typeof v !== 'number') return nothing\n const x0 = left + band * j + (band - inner) / 2 + s * (width + 2)\n const y0 = Math.min(y(v), y(0))\n const h = Math.max(1, Math.abs(y(v) - y(0)))\n return svg`<rect x=${x0} y=${y0} width=${width} height=${h} rx=\"3\" fill=${colours[s % 8]}><title>${name(one)} · ${x[j]}: ${shown(v)}</title></rect>`\n })\n })\n\n return html`<section class=\"chart\" role=\"img\" aria-label=${block.caption || series.map(name).join(', ')}>\n ${bar}\n <svg viewBox=\"0 0 ${W} ${H}\">\n ${ticks.map(tick => svg`<line class=\"grid\" x1=${left} x2=${W - 8} y1=${y(tick)} y2=${y(tick)}></line><text class=\"tick\" x=${left - 6} y=${y(tick) + 4} text-anchor=\"end\">${shown(tick)}</text>`)}\n ${marks}\n ${x.map((label, j) => (j % everyNth ? nothing : svg`<text class=\"tick\" x=${left + band * (j + 0.5)} y=${H - 8} text-anchor=\"middle\">${label}</text>`))}\n </svg>\n ${series.length > 1\n ? html`<div class=\"legend\">${series.map((one, s) => html`<span><span class=\"swatch\" style=\"background:${colours[s % 8]}\"></span>${name(one)}</span>`)}</div>`\n : nothing}\n </section>`\n }\n\n private download(title: string, columns: { name: string; label?: string }[], rows: Record<string, any>[]) {\n const blob = new Blob([tableCsv(columns, rows)], { type: 'text/csv;charset=utf-8' })\n const url = URL.createObjectURL(blob)\n const link = document.createElement('a')\n link.href = url\n link.download = `${title.replace(/[\\\\/:*?\"<>|]+/g, '-').slice(0, 80)}.csv`\n link.click()\n setTimeout(() => URL.revokeObjectURL(url), 1000)\n }\n}\n"]}
@@ -0,0 +1,27 @@
1
+ import '@material/web/icon/icon.js';
2
+ import '../components/workspace-view.js';
3
+ import { PageView } from '@operato/shell';
4
+ declare const AssistantWorkspacePage_base: (new (...args: any[]) => import("lit").LitElement) & typeof PageView;
5
+ export declare class AssistantWorkspacePage extends AssistantWorkspacePage_base {
6
+ static styles: import("lit").CSSResult[];
7
+ private sessionId;
8
+ private name;
9
+ private wanted;
10
+ private versions;
11
+ private loading;
12
+ private failure;
13
+ /** A version that arrived after the page was drawn - announced, not shown until asked. */
14
+ private newer;
15
+ private unsubscribe?;
16
+ get context(): {
17
+ title: string;
18
+ };
19
+ private get shown();
20
+ connectedCallback(): void;
21
+ disconnectedCallback(): void;
22
+ pageUpdated(_changes: any, lifecycle: any): Promise<void>;
23
+ private load;
24
+ private go;
25
+ render(): import("lit-html").TemplateResult<1>;
26
+ }
27
+ export {};