@things-factory/ai-assistant 10.1.88 → 10.1.90
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/client/components/assistant-chat.ts +19 -5
- package/client/components/assistant-dock.ts +21 -1
- package/client/components/entry-review.ts +246 -0
- package/client/utils/assistant-proposals.ts +11 -1
- package/client/utils/entry-proposal.ts +103 -0
- package/dist-client/components/assistant-chat.d.ts +1 -0
- package/dist-client/components/assistant-chat.js +19 -5
- package/dist-client/components/assistant-chat.js.map +1 -1
- package/dist-client/components/assistant-dock.js +16 -1
- package/dist-client/components/assistant-dock.js.map +1 -1
- package/dist-client/components/entry-review.d.ts +9 -0
- package/dist-client/components/entry-review.js +247 -0
- package/dist-client/components/entry-review.js.map +1 -0
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/utils/assistant-proposals.d.ts +1 -0
- package/dist-client/utils/assistant-proposals.js +9 -1
- package/dist-client/utils/assistant-proposals.js.map +1 -1
- package/dist-client/utils/entry-proposal.d.ts +55 -0
- package/dist-client/utils/entry-proposal.js +52 -0
- package/dist-client/utils/entry-proposal.js.map +1 -0
- package/dist-server/service/assistant-mode/registry.js +13 -0
- package/dist-server/service/assistant-mode/registry.js.map +1 -1
- package/dist-server/service/assistant-mode/resolve.d.ts +11 -0
- package/dist-server/service/assistant-mode/resolve.js +13 -3
- package/dist-server/service/assistant-mode/resolve.js.map +1 -1
- package/dist-server/service/assistant-mode/types.d.ts +7 -1
- package/dist-server/service/assistant-mode/types.js.map +1 -1
- package/dist-server/service/data-entry/entry-apply.d.ts +46 -0
- package/dist-server/service/data-entry/entry-apply.js +102 -0
- package/dist-server/service/data-entry/entry-apply.js.map +1 -0
- package/dist-server/service/data-entry/entry-resolver.d.ts +4 -0
- package/dist-server/service/data-entry/entry-resolver.js +80 -0
- package/dist-server/service/data-entry/entry-resolver.js.map +1 -0
- package/dist-server/service/data-entry/entry-sources.d.ts +1 -0
- package/dist-server/service/data-entry/entry-sources.js +41 -0
- package/dist-server/service/data-entry/entry-sources.js.map +1 -0
- package/dist-server/service/data-entry/entry-target.d.ts +157 -0
- package/dist-server/service/data-entry/entry-target.js +343 -0
- package/dist-server/service/data-entry/entry-target.js.map +1 -0
- package/dist-server/service/data-entry/entry-tools.d.ts +43 -0
- package/dist-server/service/data-entry/entry-tools.js +185 -0
- package/dist-server/service/data-entry/entry-tools.js.map +1 -0
- package/dist-server/service/index.d.ts +4 -1
- package/dist-server/service/index.js +10 -2
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/server/service/assistant-mode/registry.ts +13 -0
- package/server/service/assistant-mode/resolve.ts +13 -3
- package/server/service/assistant-mode/types.ts +7 -1
- package/server/service/data-entry/data-entry.test.ts +311 -0
- package/server/service/data-entry/entry-apply.ts +134 -0
- package/server/service/data-entry/entry-resolver.ts +74 -0
- package/server/service/data-entry/entry-sources.ts +35 -0
- package/server/service/data-entry/entry-target.ts +442 -0
- package/server/service/data-entry/entry-tools.ts +174 -0
- package/server/service/index.ts +7 -1
- package/test/entry-proposal.test.ts +67 -0
- package/test/open-doors.test.ts +2 -1
- package/translations/en.json +36 -1
- package/translations/ja.json +36 -1
- package/translations/ko.json +36 -1
- package/translations/ms.json +36 -1
- package/translations/zh.json +36 -1
|
@@ -19,11 +19,26 @@ import { assistantSessionTransport } from '../utils/assistant-session-transport.
|
|
|
19
19
|
import { readAiCapability } from '../utils/assistant-capability-read.js';
|
|
20
20
|
import { setOpenSession, subscribeSessionActivity } from '../utils/assistant-activity.js';
|
|
21
21
|
import { assistantHomeSurface, currentAssistantSurface, isAnchor, subscribeAssistantSurface } from '../utils/assistant-surface.js';
|
|
22
|
-
import { runProposal } from '../utils/assistant-proposals.js';
|
|
22
|
+
import { runProposal, setEntryProposalHandler } from '../utils/assistant-proposals.js';
|
|
23
|
+
import { entryProposalHandler } from '../utils/entry-proposal.js';
|
|
23
24
|
import { holdAssistantAsk, subscribeAssistantAsk, takeAssistantAsk } from '../utils/assistant-ask.js';
|
|
24
25
|
import { surfaceTransition } from '../utils/assistant-navigation.js';
|
|
25
26
|
export const ASSISTANT_DOCK_VIEWPART = 'assistant-dock';
|
|
26
27
|
const t = (key, defaultValue, options = {}) => i18next.t(`ai-assistant.dock.${key}`, { defaultValue, ...options });
|
|
28
|
+
/* Pressing a data entry card asks the server to enter the rows it stored - the screen sends none (design/ai/data-entry.md §4). */
|
|
29
|
+
setEntryProposalHandler(entryProposalHandler(async (sessionId, proposalKey) => {
|
|
30
|
+
const result = await client.mutate({
|
|
31
|
+
mutation: gql `
|
|
32
|
+
mutation ($id: String!, $key: String!) {
|
|
33
|
+
applyEntryProposal(sessionId: $id, proposalKey: $key)
|
|
34
|
+
}
|
|
35
|
+
`,
|
|
36
|
+
variables: { id: sessionId, key: proposalKey }
|
|
37
|
+
});
|
|
38
|
+
if (result.errors?.length)
|
|
39
|
+
throw new Error(result.errors[0].message);
|
|
40
|
+
return result.data?.applyEntryProposal;
|
|
41
|
+
}, (key, options) => String(i18next.t(key, options))));
|
|
27
42
|
const MODES_QUERY = gql `
|
|
28
43
|
query ($subject: String!) {
|
|
29
44
|
assistantModes(subject: $subject) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assistant-dock.js","sourceRoot":"","sources":["../../client/components/assistant-dock.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport './assistant-chat.js'\nimport './assistant-session-toolbar.js'\nimport './assistant-session-manager.js'\n\nimport gql from 'graphql-tag'\nimport { LitElement, css, html, nothing, type TemplateResult } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { keyed } from 'lit/directives/keyed.js'\n\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { closeOverlay, notify } from '@operato/layout'\nimport { OxPrompt } from '@operato/popup'\nimport { AppController, store } from '@operato/shell'\nimport { ScrollbarStyles } from '@operato/styles'\n\nimport { followPickedConversation, type AssistantMode } from './assistant-mode.js'\nimport { AssistantSessionController, type AssistantSession, type AssistantSessionTarget } from '../utils/assistant-session-controller.js'\nimport { assistantSessionTransport } from '../utils/assistant-session-transport.js'\nimport { readAiCapability } from '../utils/assistant-capability-read.js'\nimport type { AiCapability } from '../utils/assistant-capability.js'\nimport { setOpenSession, subscribeSessionActivity } from '../utils/assistant-activity.js'\nimport {\n assistantHomeSurface,\n currentAssistantSurface,\n isAnchor,\n subscribeAssistantSurface,\n type AnchorResult,\n type AssistantSurface\n} from '../utils/assistant-surface.js'\nimport { runProposal, type ProposalContext, type ProposalOutcome } from '../utils/assistant-proposals.js'\nimport { holdAssistantAsk, subscribeAssistantAsk, takeAssistantAsk, type AssistantAsk } from '../utils/assistant-ask.js'\nimport { surfaceTransition } from '../utils/assistant-navigation.js'\n\nexport const ASSISTANT_DOCK_VIEWPART = 'assistant-dock'\n\nconst t = (key: string, defaultValue: string, options: Record<string, unknown> = {}) =>\n i18next.t(`ai-assistant.dock.${key}`, { defaultValue, ...options })\n\nconst MODES_QUERY = gql`\n query ($subject: String!) {\n assistantModes(subject: $subject) {\n kind\n label\n isDefault\n }\n }\n`\n\nasync function modesFor(subject: string): Promise<{ kind: string; label?: string; isDefault?: boolean }[]> {\n const response = await client.query({ query: MODES_QUERY, variables: { subject }, fetchPolicy: 'network-only' })\n if (response.errors?.length) throw new Error(response.errors[0].message)\n return response.data?.assistantModes ?? []\n}\n\n/**\n * The AI dock - the same in every operato application (design/ai/shared-dock.md).\n *\n * ── What is here and what is not ────────────────────────────────────────────────\n * here where it stands, whether an AI answers, which surface and anchor, which conversation (mode),\n * sessions and their management, unread, proposals and their outcome, asks from other screens\n * the app what its screens show (surfaces, assistant-surface.ts), how its proposal kinds apply\n * (assistant-proposals.ts), and on the server its modes and tools\n *\n * Nothing in this file names an application or a proposal kind. A behaviour one app needs and another does\n * not is a surface field or a handler, never a branch here.\n */\n@customElement('ox-assistant-dock')\nexport class AssistantDock extends localize(i18next)(LitElement) {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n width: 420px;\n max-width: 100vw;\n box-sizing: border-box;\n height: 100%;\n min-height: 0;\n background: var(--md-sys-color-surface-container-lowest);\n border-left: 1px solid var(--md-sys-color-outline-variant);\n color: var(--md-sys-color-on-surface);\n font-size: 13px;\n }\n\n /* Below 1440px the page keeps its full width and only the dock floats. The DOM stays - the chat does not reconnect. */\n @media (max-width: 1439.98px) {\n :host {\n position: fixed;\n inset: 0 0 0 auto;\n height: 100vh;\n height: 100dvh;\n z-index: 10;\n box-shadow: var(--md-sys-elevation-shadow-3, -4px 0 16px rgb(0 0 0 / 20%));\n }\n }\n\n @media (max-width: 599.98px) {\n :host {\n width: 100vw;\n }\n }\n\n .scope {\n display: flex;\n align-items: center;\n gap: 6px;\n min-height: 40px;\n padding: 5px 8px;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n }\n\n .scope > md-icon {\n --md-icon-size: 18px;\n flex: none;\n color: var(--md-sys-color-primary);\n }\n\n .what {\n display: grid;\n flex: 1;\n min-width: 0;\n font-size: 12px;\n font-weight: 650;\n line-height: 1.25;\n }\n\n .what span {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .detail {\n color: var(--md-sys-color-on-surface-variant);\n font-size: 10.5px;\n font-weight: 400;\n }\n\n .sbtn {\n display: inline-flex;\n align-items: center;\n flex: none;\n padding: 4px;\n border: none;\n border-radius: 8px;\n background: none;\n color: var(--md-sys-color-on-surface-variant);\n cursor: pointer;\n }\n\n .sbtn:hover {\n background: var(--md-sys-color-surface-container-high);\n color: var(--md-sys-color-on-surface);\n }\n\n .sbtn md-icon {\n --md-icon-size: 18px;\n }\n\n /*\n * An open conversation is read by everyone in the domain - the dock says so on every screen of it, not\n * only in the list (2026-09-30: open and private were one grey word apart, and an owner's question about\n * the books sat in every employee's list). A private one draws nothing extra: it is the default.\n */\n /*\n * One warning colour in every application (2026-09-30, product owner): the theme's tertiary was a pale\n * lavender in figure and something else in each app, so \"everyone reads this\" was as loud as the theme\n * happened to be. Amber with near-black ink reads on light and dark themes alike - ink on amber 8.2:1, the edge 3.3:1 on white and 5.1:1 on a dark surface.\n */\n :host {\n --assistant-open-edge: #c47f00;\n --assistant-open-surface: #f2b01e;\n --assistant-open-ink: #2e2100;\n }\n\n :host([audience='open']) {\n border-left: 4px solid var(--assistant-open-edge);\n }\n\n .audience {\n display: flex;\n align-items: center;\n gap: 6px;\n flex: none;\n padding: 6px 10px;\n background: var(--assistant-open-surface);\n color: var(--assistant-open-ink);\n border-bottom: 1px solid var(--assistant-open-edge);\n font-size: 12px;\n font-weight: 600;\n line-height: 1.35;\n }\n\n .audience md-icon {\n --md-icon-size: 16px;\n flex: none;\n }\n\n ox-assistant-session-toolbar {\n flex: none;\n min-width: 0;\n padding: 3px 8px;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n --border-color: var(--md-sys-color-outline-variant);\n --main-section-background-color: var(--md-sys-color-surface-container);\n --primary-color: var(--md-sys-color-primary);\n font: inherit;\n font-size: 12px;\n }\n\n ox-assistant-chat,\n ox-assistant-session-manager {\n flex: 1;\n min-height: 0;\n }\n\n /* No conversation could stand - say what stopped it, never an empty panel. */\n .stuck {\n margin: auto;\n padding: 20px;\n text-align: center;\n line-height: 1.7;\n color: var(--md-sys-color-on-surface-variant);\n }\n\n .stuck .sbtn {\n margin-top: 6px;\n gap: 4px;\n font: inherit;\n }\n\n .next-step {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 10px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n background: var(--md-sys-color-surface-container-low);\n color: var(--md-sys-color-on-surface-variant);\n font-size: 12px;\n line-height: 1.4;\n }\n\n .next-step a {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n flex: none;\n color: var(--md-sys-color-primary);\n font-weight: 650;\n text-decoration: none;\n }\n\n .next-step a:hover { text-decoration: underline; }\n .next-step md-icon { --md-icon-size: 16px; }\n ox-assistant-chat[hidden] { display: none; }\n .transition { padding: 10px 12px; font-size: 13px; line-height: 1.5; border-bottom: 1px solid var(--md-sys-color-outline-variant); background: var(--md-sys-color-surface-container-low); }\n .transition button { display: block; margin-top: 6px; font: inherit; }\n `\n ]\n\n /** The viewpart this dock lives in - for closing it. */\n @property({ type: String }) viewpart = ASSISTANT_DOCK_VIEWPART\n\n @state() private capability: AiCapability = 'unknown'\n @state() private asked = false\n @state() private surface?: AssistantSurface\n @state() private anchor?: AnchorResult\n @state() private kind = ''\n /** kind → its label, for the manager's rows. */\n @state() private kindLabels: Record<string, string> = {}\n @state() private sessions: AssistantSession[] = []\n @state() private sessionId = ''\n @state() private loading = false\n @state() private failure = ''\n @state() private showingHistory = false\n @state() private conversationView = 0\n @state() private asking?: { ask?: string; draft?: string; requestId: string }\n @state() private screenChanged = false\n @state() private navigationNotice = ''\n private openedIdentity = ''\n\n private app = new AppController(this)\n /** The kind the person picked; kept while the surface stays the same. */\n private chosenKind = ''\n private revision = 0\n /** What the conversation was opened for - a send is refused when the screen moved on. */\n private openedFor = ''\n private unsubscribers: (() => void)[] = []\n private controller = new AssistantSessionController(\n assistantSessionTransport,\n next => {\n if (next.sessionId !== this.sessionId) {\n setOpenSession(next.sessionId)\n this.surface?.sessionChanged?.(next.sessionId)\n }\n this.sessions = next.sessions\n this.sessionId = next.sessionId\n this.loading = next.loading\n this.failure = next.error\n },\n { getItem: key => sessionStorage.getItem(key), setItem: (key, value) => sessionStorage.setItem(key, value) },\n { lazy: true }\n )\n\n private onStartNewSession = () => void this.newConversation()\n\n /** Who reads the open conversation - absent until the list or the create answer says. */\n private get audience(): string | undefined {\n return this.sessions.find(session => session.id === this.sessionId)?.visibility || undefined\n }\n\n protected updated(changed: Map<PropertyKey, unknown>) {\n super.updated?.(changed as any)\n const audience = !this.showingHistory && this.audience === 'open' ? 'open' : null\n if (audience) this.setAttribute('audience', audience)\n else this.removeAttribute('audience')\n }\n\n connectedCallback() {\n super.connectedCallback()\n this.addEventListener('assistant-start-new-session', this.onStartNewSession)\n this.unsubscribers.push(\n subscribeAssistantSurface(() => this.follow()),\n store.subscribe(() => { if (this.openedIdentity !== this.identityKey()) this.follow() }),\n subscribeAssistantAsk(() => void this.takeAsk()),\n subscribeSessionActivity(activity => {\n /* A rename or a new conversation elsewhere on this anchor - the tabs read again. */\n if (activity.kind === 'meta' && isAnchor(this.anchor) && activity.anchorId === this.anchor.anchorId) void this.reloadSessions()\n })\n )\n this.follow(true)\n }\n\n disconnectedCallback() {\n this.revision++\n this.removeEventListener('assistant-start-new-session', this.onStartNewSession)\n this.unsubscribers.splice(0).forEach(unsubscribe => unsubscribe())\n setOpenSession('')\n this.controller.clear()\n super.disconnectedCallback()\n }\n\n private scopeKey(surface: AssistantSurface | undefined) {\n return JSON.stringify([this.app.contextPath, surface?.key ?? ''])\n }\n\n private identityKey() {\n const user = (store.getState() as any).auth?.user\n return JSON.stringify([this.app.contextPath, user?.id || user?.email || ''])\n }\n\n private get navigationState() {\n return (this.renderRoot.querySelector('ox-assistant-chat') as any)?.navigationState ?? { busy: false, draft: false }\n }\n\n private async mayLeaveConversation(): Promise<boolean> {\n if (this.navigationState.busy) {\n notify({ level: 'info', message: t('wait-before-switch', 'Wait for the current response before changing conversations.') })\n return false\n }\n if (!this.navigationState.draft) return true\n const identity = this.identityKey()\n const accepted = await OxPrompt.open({\n type: 'warning', title: t('switch-title', 'Change conversation?'),\n text: t('switch-draft', 'Your unsent text and attachments will not move to the other conversation.'),\n confirmButton: { text: t('switch-confirm', 'Discard draft and switch') },\n cancelButton: { text: t('stay', 'Keep writing') }\n })\n return !!accepted && identity === this.identityKey()\n }\n\n private async requestSurface(surface: AssistantSurface | undefined) {\n if (!(await this.mayLeaveConversation())) return\n this.chosenKind = ''\n this.surface = surface\n this.navigationNotice = surface ? t('now-about', 'Conversation subject: {name}', { name: surface.label() }) : ''\n await this.open()\n }\n\n /** The screen changed - a different surface or domain is a different conversation. */\n private follow(force = false) {\n const next = currentAssistantSurface()\n const transition = surfaceTransition({\n identityChanged: this.openedIdentity !== this.identityKey(),\n sameSubject: this.scopeKey(next) === this.openedFor,\n active: isAnchor(this.anchor) && (!!this.sessionId || this.navigationState.draft || this.navigationState.busy)\n })\n if (!force && transition === 'refresh') {\n this.surface = next\n this.screenChanged = false\n this.requestUpdate()\n return\n }\n if (!force && transition === 'offer') {\n this.screenChanged = true\n return\n }\n if (transition === 'reset') {\n this.asking = undefined\n this.capability = 'unknown'\n if (this.openedIdentity) takeAssistantAsk()\n }\n this.navigationNotice = transition === 'follow' && next ? t('now-about', 'Conversation subject: {name}', { name: next.label() }) : ''\n if (next?.key !== this.surface?.key) this.chosenKind = ''\n this.surface = next\n void this.open()\n }\n\n private async open(): Promise<void> {\n this.openedIdentity = this.identityKey()\n this.screenChanged = false\n const ticket = ++this.revision\n this.conversationView++\n this.showingHistory = false\n void this.controller.open(undefined)\n this.loading = true\n this.failure = ''\n this.anchor = undefined\n this.openedFor = this.scopeKey(this.surface)\n\n try {\n if (this.capability !== 'configured') {\n this.capability = await readAiCapability()\n this.asked = true\n }\n if (ticket !== this.revision || this.capability !== 'configured') return\n\n const surface = this.surface\n if (!surface) return\n\n const anchor = await surface.anchor()\n if (ticket !== this.revision) return\n this.anchor = anchor\n if (!isAnchor(anchor)) return\n\n const modes = await modesFor(surface.subject)\n if (ticket !== this.revision) return\n this.kindLabels = Object.fromEntries(modes.map(mode => [mode.kind, mode.label || mode.kind]))\n const chosen = modes.find(mode => mode.kind === this.chosenKind) ?? modes.find(mode => mode.isDefault) ?? modes[0]\n this.kind = chosen?.kind ?? ''\n if (!this.kind) {\n this.anchor = { stuck: 'no-conversation', message: t('no-conversation', 'there is no conversation for this screen.') }\n return\n }\n\n const user = (store.getState() as any).auth?.user\n const userId = user?.id || user?.email\n if (!userId) throw new Error(t('no-user', 'your sign-in could not be read. sign in again.'))\n\n await this.controller.open(this.target(userId, anchor))\n await this.takeAsk()\n } catch (error) {\n if (ticket === this.revision) this.failure = (error as Error).message\n } finally {\n if (ticket === this.revision) {\n this.loading = false\n /* No conversation can stand here - an ask waiting for one is answered now, not sent later somewhere else. */\n if (this.anchor && !isAnchor(this.anchor)) void this.takeAsk()\n }\n }\n }\n\n private target(userId: string, anchor: { anchorType: string; anchorId: string }): AssistantSessionTarget {\n /* The conversation kind is part of the key: two conversations on one anchor never share a session (ADR-0072 decision 3). */\n return { scope: JSON.stringify([this.app.contextPath, userId, this.kind]), anchorType: anchor.anchorType, anchorId: anchor.anchorId, kind: this.kind }\n }\n\n private async reloadSessions() {\n const target = this.controller.state.target\n if (target) await this.controller.open(target, true)\n }\n\n private async newConversation() {\n if (this.loading || !isAnchor(this.anchor)) return\n if (!(await this.mayLeaveConversation())) return\n this.showingHistory = false\n const revision = this.controller.state.revision\n await this.controller.reset()\n if (revision !== this.controller.state.revision) this.conversationView++\n }\n\n private async selectSession(id: string, pickedKind?: string) {\n if (id !== this.sessionId && !(await this.mayLeaveConversation())) return\n this.showingHistory = false\n const follow = followPickedConversation(pickedKind, this.kind)\n if (follow) {\n /* A conversation of another kind on this anchor - the dock follows it rather than refusing it. */\n this.chosenKind = follow\n void this.open().then(() => this.controller.select(id) && this.conversationView++)\n return\n }\n const previous = this.sessionId\n if (this.controller.select(id) && previous !== id) this.conversationView++\n }\n\n private onModeChange = async (event: CustomEvent) => {\n const kind = event.detail?.kind\n if (!kind || kind === this.kind) return\n if (!(await this.mayLeaveConversation())) return\n this.chosenKind = kind\n void this.open()\n }\n\n /* ── asks from other screens ────────────────────────────────────────────────────── */\n\n private async takeAsk() {\n if (this.loading || !this.anchor) return\n if (this.screenChanged || this.navigationState.busy || this.navigationState.draft) {\n const waiting = takeAssistantAsk()\n if (waiting) notify({ level: 'info', message: t('ask-kept-current', 'The current conversation was kept. Switch to the intended subject before asking again.') })\n return\n }\n if (!isAnchor(this.anchor)) {\n /*\n A question is not sent later on its own, once some conversation happens to stand - by then the person is looking\n at something else. It is said now why it was not sent. A draft only fills the input, so it waits.\n */\n const waiting = takeAssistantAsk()\n if (!waiting) return\n if (waiting.ask) notify({ level: 'info', message: `${t('ask-needs-conversation', 'the question was not sent.')} ${this.anchor.message}` })\n else holdAssistantAsk(waiting)\n return\n }\n const ask: AssistantAsk | undefined = takeAssistantAsk()\n if (!ask) return\n\n if (!ask.continueCurrent && (ask.name || ask.context || ask.transcript?.length)) {\n const id = await this.startCarried(ask).catch(error => {\n notify({ level: 'error', message: (error as Error).message })\n return undefined\n })\n if (id) {\n await this.reloadSessions()\n this.controller.select(id)\n }\n } else if (!ask.continueCurrent) {\n await this.newConversation()\n }\n this.conversationView++\n this.asking = { ask: ask.ask, draft: ask.draft, requestId: String(Date.now()) }\n }\n\n /** A new conversation carrying what the other screen had - its name, a note, earlier turns. */\n private async startCarried(ask: AssistantAsk): Promise<string | undefined> {\n const anchor = this.anchor as { anchorType: string; anchorId: string }\n const created = await client.mutate({\n mutation: gql`\n mutation ($t: String!, $i: String!, $n: String) {\n createAISession(anchorType: $t, anchorId: $i, name: $n) {\n id\n }\n }\n `,\n variables: { t: anchor.anchorType, i: anchor.anchorId, n: ask.name || null }\n })\n const id = created.data?.createAISession?.id\n if (!id) return undefined\n if (ask.context) {\n await client.mutate({\n mutation: gql`\n mutation ($id: String!, $c: String!) {\n appendSessionNote(sessionId: $id, content: $c)\n }\n `,\n variables: { id, c: ask.context }\n })\n }\n if (ask.transcript?.length) {\n await client.mutate({\n mutation: gql`\n mutation ($id: String!, $turns: JSON!) {\n appendSessionTurns(sessionId: $id, turns: $turns)\n }\n `,\n variables: { id, turns: ask.transcript.map(turn => ({ role: turn.role === 'ai' ? 'assistant' : 'user', content: turn.content })) }\n })\n }\n return id\n }\n\n /* ── proposals ───────────────────────────────────────────────────────────────────── */\n\n private proposalContext(sessionId?: string): ProposalContext {\n const identity = this.identityKey()\n const scope = this.openedFor\n return {\n sessionId,\n surface: this.surface,\n confirm: async ({ title, text, confirmText, cancelText, type }) =>\n !!(await OxPrompt.open({\n type: type ?? 'warning',\n title,\n text,\n confirmButton: { text: confirmText ?? t('confirm', 'OK') },\n cancelButton: { text: cancelText ?? t('cancel', 'Cancel') }\n })) && identity === this.identityKey() && scope === this.scopeKey(currentAssistantSurface()),\n notify: (level, message) => notify({ level, message })\n }\n }\n\n private async report(sessionId: string | undefined, proposalKey: string | undefined, outcome: ProposalOutcome) {\n if (!sessionId || !proposalKey) return\n try {\n await client.mutate({\n mutation: gql`\n mutation ($id: String!, $key: String!, $outcome: JSON!) {\n reportProposalOutcome(sessionId: $id, proposalKey: $key, outcome: $outcome)\n }\n `,\n variables: { id: sessionId, key: proposalKey, outcome }\n })\n } catch {\n /* the card then says it heard nothing - never \"done\" */\n }\n }\n\n /** Every proposal ends in exactly one reported outcome - a kind nobody handles is `unavailable`. */\n private onProposal = async (event: CustomEvent) => {\n const { proposal, sessionId, proposalKey } = event.detail ?? {}\n const outcome: ProposalOutcome = this.openedFor !== this.scopeKey(currentAssistantSurface()) || this.openedIdentity !== this.identityKey()\n ? { verdict: 'unavailable', errorCode: 'conversation-screen-changed', note: t('return-to-subject', 'Return to the conversation subject before applying this proposal.') }\n : await runProposal(proposal, this.proposalContext(sessionId))\n if (outcome.verdict === 'unavailable' && outcome.errorCode === 'unknown-proposal-kind') {\n notify({ level: 'error', message: t('proposal-not-runnable', 'this proposal cannot be run on this screen.') })\n }\n await this.report(sessionId, proposalKey, outcome)\n /* What the handler did, in the person's words, stays in the conversation - what was created, why it did not run. */\n if (outcome.note && sessionId) await this.appendNote(sessionId, outcome.note)\n }\n\n /**\n * \"Check result\" - asks the surface what became of a requested proposal and reports only what it learns.\n * Nothing is run: a lost answer never turns into a second application (ADR-0097 Q-D4 ④).\n */\n private onProposalCheck = async (event: CustomEvent) => {\n const { proposal, sessionId, proposalKey } = event.detail ?? {}\n const ask = this.surface?.proposalOutcome\n if (!ask) {\n notify({ level: 'info', message: t('proposal-result-uncheckable', 'this screen cannot check that result. open the screen where it was applied.') })\n return\n }\n\n let outcome: ProposalOutcome | undefined\n try {\n outcome = await ask.call(this.surface, proposalKey, proposal)\n } catch {\n outcome = undefined\n }\n if (!outcome?.verdict) {\n notify({ level: 'info', message: t('proposal-result-unknown', 'the result is still unknown. it was not applied again.') })\n return\n }\n\n await this.report(sessionId, proposalKey, outcome)\n if (outcome.note && sessionId) await this.appendNote(sessionId, outcome.note)\n }\n\n private async appendNote(sessionId: string, note: string) {\n try {\n await client.mutate({\n mutation: gql`\n mutation ($id: String!, $c: String!) {\n appendSessionNote(sessionId: $id, content: $c)\n }\n `,\n variables: { id: sessionId, c: note }\n })\n } catch {\n /* the outcome is already reported; a lost note is not a lost outcome */\n }\n }\n\n /* ── board surfaces: the chat's scene edits land on the open board ───────────────── */\n\n private onScenePatch = async (event: CustomEvent) => {\n if (!this.mayApplyOnScreen()) return\n const board = this.surface?.board\n if (!board) return\n const result = await board.applyPatch(event.detail)\n if (result?.missed) notify({ level: 'info', message: t('patch-missed', '{missed} of the changes could not be applied.', { missed: result.missed }) })\n }\n\n private mayApplyOnScreen() {\n if (this.openedFor === this.scopeKey(currentAssistantSurface()) && this.openedIdentity === this.identityKey()) return true\n notify({ level: 'info', message: t('return-to-subject', 'Return to the conversation subject before applying this proposal.') })\n return false\n }\n\n private onBoardRevert = (event: CustomEvent) => { if (this.mayApplyOnScreen()) void this.surface?.board?.revertPatch?.(event.detail?.patchId) }\n\n private onSceneAction = (event: CustomEvent) => { if (this.mayApplyOnScreen()) void this.surface?.board?.applyAction?.(event.detail) }\n\n /* ── drawing ─────────────────────────────────────────────────────────────────────── */\n\n private stuckLine(): string {\n if (this.capability === 'not-configured') return t('not-configured', 'no AI is set up for this site. an administrator can set one up in the AI settings.')\n if (this.capability === 'unknown' && this.asked && !this.loading && !this.failure) return t('capability-unknown', 'whether AI is set up here could not be read.')\n if (this.capability === 'configured' && !this.surface && !this.loading) return t('no-surface', 'this screen has no conversation.')\n const anchor = this.anchor\n if (anchor && !isAnchor(anchor)) return anchor.message\n return ''\n }\n\n private header(): TemplateResult {\n const surface = this.surface\n const home = assistantHomeSurface()\n const ready = this.capability === 'configured' && isAnchor(this.anchor)\n return html`\n <div class=\"scope\">\n <md-icon>${surface?.icon || 'forum'}</md-icon>\n <span class=\"what\">\n <span>${surface?.label() || t('title', 'Assistant')}</span>\n ${surface?.detail ? html`<span class=\"detail\">${surface.detail()}</span>` : nothing}\n </span>\n ${home && surface && home !== surface\n ? html`<button class=\"sbtn\" title=${t('to-home', \"back to this application's conversation\")} @click=${() => this.useSurface(home)}>\n <md-icon>home</md-icon>\n </button>`\n : nothing}\n ${ready && this.showingHistory\n ? html`<button\n class=\"sbtn\"\n title=${this.showingHistory ? t('back-to-conversation', 'back to the conversation') : t('conversations', 'conversations')}\n @click=${() => (this.showingHistory = !this.showingHistory)}\n >\n <md-icon>arrow_back</md-icon>${t('back-to-conversation', 'back to the conversation')}\n </button>`\n : nothing}\n <button class=\"sbtn\" title=${t('rebind', 'follow this screen again')} @click=${() => this.requestSurface(currentAssistantSurface())}>\n <md-icon>refresh</md-icon>\n </button>\n <button class=\"sbtn\" title=${t('close', 'close')} @click=${() => closeOverlay(this.viewpart)}>\n <md-icon>close</md-icon>\n </button>\n </div>\n `\n }\n\n /** The home button: talk about the application instead of this screen, until the screen changes. */\n private useSurface(surface: AssistantSurface) {\n void this.requestSurface(surface)\n }\n\n render(): TemplateResult {\n const anchor = this.anchor\n const ready = this.capability === 'configured' && isAnchor(anchor)\n const stuck = this.stuckLine()\n const surface = this.surface\n const openedFor = this.openedFor\n const board = surface?.board\n\n const mode: AssistantMode | undefined = ready ? { kind: this.kind, target: (anchor as any).anchorId, hostContext: {} } : undefined\n\n return html`\n ${this.header()}\n ${surface?.nextStep ? html`<div class=\"next-step\" role=\"status\">\n <span>${surface.nextStep.description?.() || ''}</span>\n <a href=${surface.nextStep.href}>${surface.nextStep.label()}<md-icon>arrow_forward</md-icon></a>\n </div>` : nothing}\n ${this.screenChanged ? html`<div class=\"transition\" role=\"status\">\n ${t('screen-and-conversation', 'Screen: {screen}. Conversation: {conversation}. Your conversation has been kept.', { screen: currentAssistantSurface()?.label() || t('no-subject', 'No subject'), conversation: surface?.label() || '' })}\n <button class=\"sbtn\" @click=${() => this.requestSurface(currentAssistantSurface())}>${t('switch-to-screen', 'Talk about this screen')}</button>\n </div>` : this.navigationNotice ? html`<div class=\"transition\" role=\"status\">${this.navigationNotice}</div>` : nothing}\n ${ready && this.showingHistory\n ? html`<ox-assistant-session-manager\n .anchorType=${(anchor as any).anchorType}\n .anchorId=${(anchor as any).anchorId}\n .sessionId=${this.sessionId}\n .kind=${this.kind}\n .kindLabels=${this.kindLabels}\n .scopeLabel=${t('conversation-scope', 'Conversations · {name}', { name: surface?.label() || '' })}\n @assistant-session-select=${(event: CustomEvent) => this.selectSession(event.detail.sessionId, event.detail.kind)}\n @assistant-session-reset=${() => this.newConversation()}\n @assistant-session-changed=${() => this.reloadSessions()}\n ></ox-assistant-session-manager>`\n : nothing}\n ${ready && !this.showingHistory\n ? html`<ox-assistant-session-toolbar\n .sessions=${this.sessions}\n .sessionId=${this.sessionId}\n .loading=${this.loading}\n .error=${this.failure}\n historyEnabled\n singleConversation\n @assistant-session-select=${(event: CustomEvent) => this.selectSession(event.detail.sessionId)}\n @assistant-session-reset=${() => this.newConversation()}\n @assistant-session-history=${() => (this.showingHistory = true)}\n @assistant-session-retry=${() => this.open()}\n ></ox-assistant-session-toolbar>`\n : nothing}\n ${ready && !this.showingHistory && this.audience === 'open'\n ? html`<div class=\"audience\" role=\"status\">\n <md-icon>public</md-icon>\n <span>${t('audience-open-band', 'Public conversation - everyone in this domain can read and write here.')}</span>\n </div>`\n : nothing}\n ${ready && !this.loading && !this.failure\n ? keyed(\n this.conversationView,\n html`<ox-assistant-chat\n ?hidden=${this.showingHistory}\n .sendBlocked=${this.screenChanged ? t('return-to-subject', 'Return to the conversation subject before sending or applying changes.') : ''}\n .sessionId=${this.sessionId}\n .prepareSession=${(adopt: (id: string) => void) => this.controller.prepareSession(adopt)}\n .contextProvider=${() => {\n /* The screen moved on between writing and sending - do not answer about the old one. */\n if (openedFor !== this.scopeKey(currentAssistantSurface()) || this.openedIdentity !== this.identityKey()) throw new Error(t('return-to-subject', 'Return to the conversation subject before applying this proposal.'))\n return { hostContext: surface?.hostContext?.() ?? {} }\n }}\n .mode=${mode}\n .subject=${surface?.subject}\n .chatEndpoint=${board?.chatEndpoint ?? 'assistantChat'}\n ?board-tools=${!!board}\n .currentBoard=${board?.currentBoard?.()}\n .boardProvider=${board?.boardProvider}\n .selectedRefids=${board?.selectedRefids?.() ?? []}\n .knownTypes=${board?.knownTypes?.()}\n .categories=${board?.categories?.()}\n .componentSchemas=${board?.componentSchemas?.()}\n .searchProvider=${board?.searchProvider}\n .autoAsk=${this.asking?.ask}\n .autoAskRequestId=${this.asking?.requestId}\n .draft=${this.asking?.draft}\n .draftRequestId=${this.asking?.requestId}\n @assistant-mode-change=${this.onModeChange}\n @assistant-proposal-execute=${this.onProposal}\n @assistant-proposal-check=${this.onProposalCheck}\n @scene-edit-patch=${this.onScenePatch}\n @board-edit-revert=${this.onBoardRevert}\n @scene-action-execute=${this.onSceneAction}\n ></ox-assistant-chat>`\n )\n : nothing}\n ${stuck\n ? html`<div class=\"stuck\">\n ${stuck}\n ${this.capability === 'unknown'\n ? html`<div><button class=\"sbtn\" @click=${() => this.open()}><md-icon>refresh</md-icon>${t('retry', 'try again')}</button></div>`\n : nothing}\n </div>`\n : nothing}\n ${this.failure && !stuck && !ready\n ? html`<div class=\"stuck\">\n ${this.failure}\n <div><button class=\"sbtn\" @click=${() => this.open()}><md-icon>refresh</md-icon>${t('retry', 'try again')}</button></div>\n </div>`\n : nothing}\n `\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"assistant-dock.js","sourceRoot":"","sources":["../../client/components/assistant-dock.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport './assistant-chat.js'\nimport './assistant-session-toolbar.js'\nimport './assistant-session-manager.js'\n\nimport gql from 'graphql-tag'\nimport { LitElement, css, html, nothing, type TemplateResult } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { keyed } from 'lit/directives/keyed.js'\n\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { closeOverlay, notify } from '@operato/layout'\nimport { OxPrompt } from '@operato/popup'\nimport { AppController, store } from '@operato/shell'\nimport { ScrollbarStyles } from '@operato/styles'\n\nimport { followPickedConversation, type AssistantMode } from './assistant-mode.js'\nimport { AssistantSessionController, type AssistantSession, type AssistantSessionTarget } from '../utils/assistant-session-controller.js'\nimport { assistantSessionTransport } from '../utils/assistant-session-transport.js'\nimport { readAiCapability } from '../utils/assistant-capability-read.js'\nimport type { AiCapability } from '../utils/assistant-capability.js'\nimport { setOpenSession, subscribeSessionActivity } from '../utils/assistant-activity.js'\nimport {\n assistantHomeSurface,\n currentAssistantSurface,\n isAnchor,\n subscribeAssistantSurface,\n type AnchorResult,\n type AssistantSurface\n} from '../utils/assistant-surface.js'\nimport { runProposal, setEntryProposalHandler, type ProposalContext, type ProposalOutcome } from '../utils/assistant-proposals.js'\nimport { entryProposalHandler, type EntryApplyAnswer } from '../utils/entry-proposal.js'\nimport { holdAssistantAsk, subscribeAssistantAsk, takeAssistantAsk, type AssistantAsk } from '../utils/assistant-ask.js'\nimport { surfaceTransition } from '../utils/assistant-navigation.js'\n\nexport const ASSISTANT_DOCK_VIEWPART = 'assistant-dock'\n\nconst t = (key: string, defaultValue: string, options: Record<string, unknown> = {}) =>\n i18next.t(`ai-assistant.dock.${key}`, { defaultValue, ...options })\n\n/* Pressing a data entry card asks the server to enter the rows it stored - the screen sends none (design/ai/data-entry.md §4). */\nsetEntryProposalHandler(\n entryProposalHandler(\n async (sessionId, proposalKey) => {\n const result = await client.mutate({\n mutation: gql`\n mutation ($id: String!, $key: String!) {\n applyEntryProposal(sessionId: $id, proposalKey: $key)\n }\n `,\n variables: { id: sessionId, key: proposalKey }\n })\n if (result.errors?.length) throw new Error(result.errors[0].message)\n return result.data?.applyEntryProposal as EntryApplyAnswer\n },\n (key, options) => String(i18next.t(key, options))\n )\n)\n\nconst MODES_QUERY = gql`\n query ($subject: String!) {\n assistantModes(subject: $subject) {\n kind\n label\n isDefault\n }\n }\n`\n\nasync function modesFor(subject: string): Promise<{ kind: string; label?: string; isDefault?: boolean }[]> {\n const response = await client.query({ query: MODES_QUERY, variables: { subject }, fetchPolicy: 'network-only' })\n if (response.errors?.length) throw new Error(response.errors[0].message)\n return response.data?.assistantModes ?? []\n}\n\n/**\n * The AI dock - the same in every operato application (design/ai/shared-dock.md).\n *\n * ── What is here and what is not ────────────────────────────────────────────────\n * here where it stands, whether an AI answers, which surface and anchor, which conversation (mode),\n * sessions and their management, unread, proposals and their outcome, asks from other screens\n * the app what its screens show (surfaces, assistant-surface.ts), how its proposal kinds apply\n * (assistant-proposals.ts), and on the server its modes and tools\n *\n * Nothing in this file names an application or a proposal kind. A behaviour one app needs and another does\n * not is a surface field or a handler, never a branch here.\n */\n@customElement('ox-assistant-dock')\nexport class AssistantDock extends localize(i18next)(LitElement) {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n width: 420px;\n max-width: 100vw;\n box-sizing: border-box;\n height: 100%;\n min-height: 0;\n background: var(--md-sys-color-surface-container-lowest);\n border-left: 1px solid var(--md-sys-color-outline-variant);\n color: var(--md-sys-color-on-surface);\n font-size: 13px;\n }\n\n /* Below 1440px the page keeps its full width and only the dock floats. The DOM stays - the chat does not reconnect. */\n @media (max-width: 1439.98px) {\n :host {\n position: fixed;\n inset: 0 0 0 auto;\n height: 100vh;\n height: 100dvh;\n z-index: 10;\n box-shadow: var(--md-sys-elevation-shadow-3, -4px 0 16px rgb(0 0 0 / 20%));\n }\n }\n\n @media (max-width: 599.98px) {\n :host {\n width: 100vw;\n }\n }\n\n .scope {\n display: flex;\n align-items: center;\n gap: 6px;\n min-height: 40px;\n padding: 5px 8px;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n }\n\n .scope > md-icon {\n --md-icon-size: 18px;\n flex: none;\n color: var(--md-sys-color-primary);\n }\n\n .what {\n display: grid;\n flex: 1;\n min-width: 0;\n font-size: 12px;\n font-weight: 650;\n line-height: 1.25;\n }\n\n .what span {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .detail {\n color: var(--md-sys-color-on-surface-variant);\n font-size: 10.5px;\n font-weight: 400;\n }\n\n .sbtn {\n display: inline-flex;\n align-items: center;\n flex: none;\n padding: 4px;\n border: none;\n border-radius: 8px;\n background: none;\n color: var(--md-sys-color-on-surface-variant);\n cursor: pointer;\n }\n\n .sbtn:hover {\n background: var(--md-sys-color-surface-container-high);\n color: var(--md-sys-color-on-surface);\n }\n\n .sbtn md-icon {\n --md-icon-size: 18px;\n }\n\n /*\n * An open conversation is read by everyone in the domain - the dock says so on every screen of it, not\n * only in the list (2026-09-30: open and private were one grey word apart, and an owner's question about\n * the books sat in every employee's list). A private one draws nothing extra: it is the default.\n */\n /*\n * One warning colour in every application (2026-09-30, product owner): the theme's tertiary was a pale\n * lavender in figure and something else in each app, so \"everyone reads this\" was as loud as the theme\n * happened to be. Amber with near-black ink reads on light and dark themes alike - ink on amber 8.2:1, the edge 3.3:1 on white and 5.1:1 on a dark surface.\n */\n :host {\n --assistant-open-edge: #c47f00;\n --assistant-open-surface: #f2b01e;\n --assistant-open-ink: #2e2100;\n }\n\n :host([audience='open']) {\n border-left: 4px solid var(--assistant-open-edge);\n }\n\n .audience {\n display: flex;\n align-items: center;\n gap: 6px;\n flex: none;\n padding: 6px 10px;\n background: var(--assistant-open-surface);\n color: var(--assistant-open-ink);\n border-bottom: 1px solid var(--assistant-open-edge);\n font-size: 12px;\n font-weight: 600;\n line-height: 1.35;\n }\n\n .audience md-icon {\n --md-icon-size: 16px;\n flex: none;\n }\n\n ox-assistant-session-toolbar {\n flex: none;\n min-width: 0;\n padding: 3px 8px;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n --border-color: var(--md-sys-color-outline-variant);\n --main-section-background-color: var(--md-sys-color-surface-container);\n --primary-color: var(--md-sys-color-primary);\n font: inherit;\n font-size: 12px;\n }\n\n ox-assistant-chat,\n ox-assistant-session-manager {\n flex: 1;\n min-height: 0;\n }\n\n /* No conversation could stand - say what stopped it, never an empty panel. */\n .stuck {\n margin: auto;\n padding: 20px;\n text-align: center;\n line-height: 1.7;\n color: var(--md-sys-color-on-surface-variant);\n }\n\n .stuck .sbtn {\n margin-top: 6px;\n gap: 4px;\n font: inherit;\n }\n\n .next-step {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 10px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n background: var(--md-sys-color-surface-container-low);\n color: var(--md-sys-color-on-surface-variant);\n font-size: 12px;\n line-height: 1.4;\n }\n\n .next-step a {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n flex: none;\n color: var(--md-sys-color-primary);\n font-weight: 650;\n text-decoration: none;\n }\n\n .next-step a:hover { text-decoration: underline; }\n .next-step md-icon { --md-icon-size: 16px; }\n ox-assistant-chat[hidden] { display: none; }\n .transition { padding: 10px 12px; font-size: 13px; line-height: 1.5; border-bottom: 1px solid var(--md-sys-color-outline-variant); background: var(--md-sys-color-surface-container-low); }\n .transition button { display: block; margin-top: 6px; font: inherit; }\n `\n ]\n\n /** The viewpart this dock lives in - for closing it. */\n @property({ type: String }) viewpart = ASSISTANT_DOCK_VIEWPART\n\n @state() private capability: AiCapability = 'unknown'\n @state() private asked = false\n @state() private surface?: AssistantSurface\n @state() private anchor?: AnchorResult\n @state() private kind = ''\n /** kind → its label, for the manager's rows. */\n @state() private kindLabels: Record<string, string> = {}\n @state() private sessions: AssistantSession[] = []\n @state() private sessionId = ''\n @state() private loading = false\n @state() private failure = ''\n @state() private showingHistory = false\n @state() private conversationView = 0\n @state() private asking?: { ask?: string; draft?: string; requestId: string }\n @state() private screenChanged = false\n @state() private navigationNotice = ''\n private openedIdentity = ''\n\n private app = new AppController(this)\n /** The kind the person picked; kept while the surface stays the same. */\n private chosenKind = ''\n private revision = 0\n /** What the conversation was opened for - a send is refused when the screen moved on. */\n private openedFor = ''\n private unsubscribers: (() => void)[] = []\n private controller = new AssistantSessionController(\n assistantSessionTransport,\n next => {\n if (next.sessionId !== this.sessionId) {\n setOpenSession(next.sessionId)\n this.surface?.sessionChanged?.(next.sessionId)\n }\n this.sessions = next.sessions\n this.sessionId = next.sessionId\n this.loading = next.loading\n this.failure = next.error\n },\n { getItem: key => sessionStorage.getItem(key), setItem: (key, value) => sessionStorage.setItem(key, value) },\n { lazy: true }\n )\n\n private onStartNewSession = () => void this.newConversation()\n\n /** Who reads the open conversation - absent until the list or the create answer says. */\n private get audience(): string | undefined {\n return this.sessions.find(session => session.id === this.sessionId)?.visibility || undefined\n }\n\n protected updated(changed: Map<PropertyKey, unknown>) {\n super.updated?.(changed as any)\n const audience = !this.showingHistory && this.audience === 'open' ? 'open' : null\n if (audience) this.setAttribute('audience', audience)\n else this.removeAttribute('audience')\n }\n\n connectedCallback() {\n super.connectedCallback()\n this.addEventListener('assistant-start-new-session', this.onStartNewSession)\n this.unsubscribers.push(\n subscribeAssistantSurface(() => this.follow()),\n store.subscribe(() => { if (this.openedIdentity !== this.identityKey()) this.follow() }),\n subscribeAssistantAsk(() => void this.takeAsk()),\n subscribeSessionActivity(activity => {\n /* A rename or a new conversation elsewhere on this anchor - the tabs read again. */\n if (activity.kind === 'meta' && isAnchor(this.anchor) && activity.anchorId === this.anchor.anchorId) void this.reloadSessions()\n })\n )\n this.follow(true)\n }\n\n disconnectedCallback() {\n this.revision++\n this.removeEventListener('assistant-start-new-session', this.onStartNewSession)\n this.unsubscribers.splice(0).forEach(unsubscribe => unsubscribe())\n setOpenSession('')\n this.controller.clear()\n super.disconnectedCallback()\n }\n\n private scopeKey(surface: AssistantSurface | undefined) {\n return JSON.stringify([this.app.contextPath, surface?.key ?? ''])\n }\n\n private identityKey() {\n const user = (store.getState() as any).auth?.user\n return JSON.stringify([this.app.contextPath, user?.id || user?.email || ''])\n }\n\n private get navigationState() {\n return (this.renderRoot.querySelector('ox-assistant-chat') as any)?.navigationState ?? { busy: false, draft: false }\n }\n\n private async mayLeaveConversation(): Promise<boolean> {\n if (this.navigationState.busy) {\n notify({ level: 'info', message: t('wait-before-switch', 'Wait for the current response before changing conversations.') })\n return false\n }\n if (!this.navigationState.draft) return true\n const identity = this.identityKey()\n const accepted = await OxPrompt.open({\n type: 'warning', title: t('switch-title', 'Change conversation?'),\n text: t('switch-draft', 'Your unsent text and attachments will not move to the other conversation.'),\n confirmButton: { text: t('switch-confirm', 'Discard draft and switch') },\n cancelButton: { text: t('stay', 'Keep writing') }\n })\n return !!accepted && identity === this.identityKey()\n }\n\n private async requestSurface(surface: AssistantSurface | undefined) {\n if (!(await this.mayLeaveConversation())) return\n this.chosenKind = ''\n this.surface = surface\n this.navigationNotice = surface ? t('now-about', 'Conversation subject: {name}', { name: surface.label() }) : ''\n await this.open()\n }\n\n /** The screen changed - a different surface or domain is a different conversation. */\n private follow(force = false) {\n const next = currentAssistantSurface()\n const transition = surfaceTransition({\n identityChanged: this.openedIdentity !== this.identityKey(),\n sameSubject: this.scopeKey(next) === this.openedFor,\n active: isAnchor(this.anchor) && (!!this.sessionId || this.navigationState.draft || this.navigationState.busy)\n })\n if (!force && transition === 'refresh') {\n this.surface = next\n this.screenChanged = false\n this.requestUpdate()\n return\n }\n if (!force && transition === 'offer') {\n this.screenChanged = true\n return\n }\n if (transition === 'reset') {\n this.asking = undefined\n this.capability = 'unknown'\n if (this.openedIdentity) takeAssistantAsk()\n }\n this.navigationNotice = transition === 'follow' && next ? t('now-about', 'Conversation subject: {name}', { name: next.label() }) : ''\n if (next?.key !== this.surface?.key) this.chosenKind = ''\n this.surface = next\n void this.open()\n }\n\n private async open(): Promise<void> {\n this.openedIdentity = this.identityKey()\n this.screenChanged = false\n const ticket = ++this.revision\n this.conversationView++\n this.showingHistory = false\n void this.controller.open(undefined)\n this.loading = true\n this.failure = ''\n this.anchor = undefined\n this.openedFor = this.scopeKey(this.surface)\n\n try {\n if (this.capability !== 'configured') {\n this.capability = await readAiCapability()\n this.asked = true\n }\n if (ticket !== this.revision || this.capability !== 'configured') return\n\n const surface = this.surface\n if (!surface) return\n\n const anchor = await surface.anchor()\n if (ticket !== this.revision) return\n this.anchor = anchor\n if (!isAnchor(anchor)) return\n\n const modes = await modesFor(surface.subject)\n if (ticket !== this.revision) return\n this.kindLabels = Object.fromEntries(modes.map(mode => [mode.kind, mode.label || mode.kind]))\n const chosen = modes.find(mode => mode.kind === this.chosenKind) ?? modes.find(mode => mode.isDefault) ?? modes[0]\n this.kind = chosen?.kind ?? ''\n if (!this.kind) {\n this.anchor = { stuck: 'no-conversation', message: t('no-conversation', 'there is no conversation for this screen.') }\n return\n }\n\n const user = (store.getState() as any).auth?.user\n const userId = user?.id || user?.email\n if (!userId) throw new Error(t('no-user', 'your sign-in could not be read. sign in again.'))\n\n await this.controller.open(this.target(userId, anchor))\n await this.takeAsk()\n } catch (error) {\n if (ticket === this.revision) this.failure = (error as Error).message\n } finally {\n if (ticket === this.revision) {\n this.loading = false\n /* No conversation can stand here - an ask waiting for one is answered now, not sent later somewhere else. */\n if (this.anchor && !isAnchor(this.anchor)) void this.takeAsk()\n }\n }\n }\n\n private target(userId: string, anchor: { anchorType: string; anchorId: string }): AssistantSessionTarget {\n /* The conversation kind is part of the key: two conversations on one anchor never share a session (ADR-0072 decision 3). */\n return { scope: JSON.stringify([this.app.contextPath, userId, this.kind]), anchorType: anchor.anchorType, anchorId: anchor.anchorId, kind: this.kind }\n }\n\n private async reloadSessions() {\n const target = this.controller.state.target\n if (target) await this.controller.open(target, true)\n }\n\n private async newConversation() {\n if (this.loading || !isAnchor(this.anchor)) return\n if (!(await this.mayLeaveConversation())) return\n this.showingHistory = false\n const revision = this.controller.state.revision\n await this.controller.reset()\n if (revision !== this.controller.state.revision) this.conversationView++\n }\n\n private async selectSession(id: string, pickedKind?: string) {\n if (id !== this.sessionId && !(await this.mayLeaveConversation())) return\n this.showingHistory = false\n const follow = followPickedConversation(pickedKind, this.kind)\n if (follow) {\n /* A conversation of another kind on this anchor - the dock follows it rather than refusing it. */\n this.chosenKind = follow\n void this.open().then(() => this.controller.select(id) && this.conversationView++)\n return\n }\n const previous = this.sessionId\n if (this.controller.select(id) && previous !== id) this.conversationView++\n }\n\n private onModeChange = async (event: CustomEvent) => {\n const kind = event.detail?.kind\n if (!kind || kind === this.kind) return\n if (!(await this.mayLeaveConversation())) return\n this.chosenKind = kind\n void this.open()\n }\n\n /* ── asks from other screens ────────────────────────────────────────────────────── */\n\n private async takeAsk() {\n if (this.loading || !this.anchor) return\n if (this.screenChanged || this.navigationState.busy || this.navigationState.draft) {\n const waiting = takeAssistantAsk()\n if (waiting) notify({ level: 'info', message: t('ask-kept-current', 'The current conversation was kept. Switch to the intended subject before asking again.') })\n return\n }\n if (!isAnchor(this.anchor)) {\n /*\n A question is not sent later on its own, once some conversation happens to stand - by then the person is looking\n at something else. It is said now why it was not sent. A draft only fills the input, so it waits.\n */\n const waiting = takeAssistantAsk()\n if (!waiting) return\n if (waiting.ask) notify({ level: 'info', message: `${t('ask-needs-conversation', 'the question was not sent.')} ${this.anchor.message}` })\n else holdAssistantAsk(waiting)\n return\n }\n const ask: AssistantAsk | undefined = takeAssistantAsk()\n if (!ask) return\n\n if (!ask.continueCurrent && (ask.name || ask.context || ask.transcript?.length)) {\n const id = await this.startCarried(ask).catch(error => {\n notify({ level: 'error', message: (error as Error).message })\n return undefined\n })\n if (id) {\n await this.reloadSessions()\n this.controller.select(id)\n }\n } else if (!ask.continueCurrent) {\n await this.newConversation()\n }\n this.conversationView++\n this.asking = { ask: ask.ask, draft: ask.draft, requestId: String(Date.now()) }\n }\n\n /** A new conversation carrying what the other screen had - its name, a note, earlier turns. */\n private async startCarried(ask: AssistantAsk): Promise<string | undefined> {\n const anchor = this.anchor as { anchorType: string; anchorId: string }\n const created = await client.mutate({\n mutation: gql`\n mutation ($t: String!, $i: String!, $n: String) {\n createAISession(anchorType: $t, anchorId: $i, name: $n) {\n id\n }\n }\n `,\n variables: { t: anchor.anchorType, i: anchor.anchorId, n: ask.name || null }\n })\n const id = created.data?.createAISession?.id\n if (!id) return undefined\n if (ask.context) {\n await client.mutate({\n mutation: gql`\n mutation ($id: String!, $c: String!) {\n appendSessionNote(sessionId: $id, content: $c)\n }\n `,\n variables: { id, c: ask.context }\n })\n }\n if (ask.transcript?.length) {\n await client.mutate({\n mutation: gql`\n mutation ($id: String!, $turns: JSON!) {\n appendSessionTurns(sessionId: $id, turns: $turns)\n }\n `,\n variables: { id, turns: ask.transcript.map(turn => ({ role: turn.role === 'ai' ? 'assistant' : 'user', content: turn.content })) }\n })\n }\n return id\n }\n\n /* ── proposals ───────────────────────────────────────────────────────────────────── */\n\n private proposalContext(sessionId?: string): ProposalContext {\n const identity = this.identityKey()\n const scope = this.openedFor\n return {\n sessionId,\n surface: this.surface,\n confirm: async ({ title, text, confirmText, cancelText, type }) =>\n !!(await OxPrompt.open({\n type: type ?? 'warning',\n title,\n text,\n confirmButton: { text: confirmText ?? t('confirm', 'OK') },\n cancelButton: { text: cancelText ?? t('cancel', 'Cancel') }\n })) && identity === this.identityKey() && scope === this.scopeKey(currentAssistantSurface()),\n notify: (level, message) => notify({ level, message })\n }\n }\n\n private async report(sessionId: string | undefined, proposalKey: string | undefined, outcome: ProposalOutcome) {\n if (!sessionId || !proposalKey) return\n try {\n await client.mutate({\n mutation: gql`\n mutation ($id: String!, $key: String!, $outcome: JSON!) {\n reportProposalOutcome(sessionId: $id, proposalKey: $key, outcome: $outcome)\n }\n `,\n variables: { id: sessionId, key: proposalKey, outcome }\n })\n } catch {\n /* the card then says it heard nothing - never \"done\" */\n }\n }\n\n /** Every proposal ends in exactly one reported outcome - a kind nobody handles is `unavailable`. */\n private onProposal = async (event: CustomEvent) => {\n const { proposal, sessionId, proposalKey } = event.detail ?? {}\n const outcome: ProposalOutcome = this.openedFor !== this.scopeKey(currentAssistantSurface()) || this.openedIdentity !== this.identityKey()\n ? { verdict: 'unavailable', errorCode: 'conversation-screen-changed', note: t('return-to-subject', 'Return to the conversation subject before applying this proposal.') }\n : await runProposal(proposal, this.proposalContext(sessionId))\n if (outcome.verdict === 'unavailable' && outcome.errorCode === 'unknown-proposal-kind') {\n notify({ level: 'error', message: t('proposal-not-runnable', 'this proposal cannot be run on this screen.') })\n }\n await this.report(sessionId, proposalKey, outcome)\n /* What the handler did, in the person's words, stays in the conversation - what was created, why it did not run. */\n if (outcome.note && sessionId) await this.appendNote(sessionId, outcome.note)\n }\n\n /**\n * \"Check result\" - asks the surface what became of a requested proposal and reports only what it learns.\n * Nothing is run: a lost answer never turns into a second application (ADR-0097 Q-D4 ④).\n */\n private onProposalCheck = async (event: CustomEvent) => {\n const { proposal, sessionId, proposalKey } = event.detail ?? {}\n const ask = this.surface?.proposalOutcome\n if (!ask) {\n notify({ level: 'info', message: t('proposal-result-uncheckable', 'this screen cannot check that result. open the screen where it was applied.') })\n return\n }\n\n let outcome: ProposalOutcome | undefined\n try {\n outcome = await ask.call(this.surface, proposalKey, proposal)\n } catch {\n outcome = undefined\n }\n if (!outcome?.verdict) {\n notify({ level: 'info', message: t('proposal-result-unknown', 'the result is still unknown. it was not applied again.') })\n return\n }\n\n await this.report(sessionId, proposalKey, outcome)\n if (outcome.note && sessionId) await this.appendNote(sessionId, outcome.note)\n }\n\n private async appendNote(sessionId: string, note: string) {\n try {\n await client.mutate({\n mutation: gql`\n mutation ($id: String!, $c: String!) {\n appendSessionNote(sessionId: $id, content: $c)\n }\n `,\n variables: { id: sessionId, c: note }\n })\n } catch {\n /* the outcome is already reported; a lost note is not a lost outcome */\n }\n }\n\n /* ── board surfaces: the chat's scene edits land on the open board ───────────────── */\n\n private onScenePatch = async (event: CustomEvent) => {\n if (!this.mayApplyOnScreen()) return\n const board = this.surface?.board\n if (!board) return\n const result = await board.applyPatch(event.detail)\n if (result?.missed) notify({ level: 'info', message: t('patch-missed', '{missed} of the changes could not be applied.', { missed: result.missed }) })\n }\n\n private mayApplyOnScreen() {\n if (this.openedFor === this.scopeKey(currentAssistantSurface()) && this.openedIdentity === this.identityKey()) return true\n notify({ level: 'info', message: t('return-to-subject', 'Return to the conversation subject before applying this proposal.') })\n return false\n }\n\n private onBoardRevert = (event: CustomEvent) => { if (this.mayApplyOnScreen()) void this.surface?.board?.revertPatch?.(event.detail?.patchId) }\n\n private onSceneAction = (event: CustomEvent) => { if (this.mayApplyOnScreen()) void this.surface?.board?.applyAction?.(event.detail) }\n\n /* ── drawing ─────────────────────────────────────────────────────────────────────── */\n\n private stuckLine(): string {\n if (this.capability === 'not-configured') return t('not-configured', 'no AI is set up for this site. an administrator can set one up in the AI settings.')\n if (this.capability === 'unknown' && this.asked && !this.loading && !this.failure) return t('capability-unknown', 'whether AI is set up here could not be read.')\n if (this.capability === 'configured' && !this.surface && !this.loading) return t('no-surface', 'this screen has no conversation.')\n const anchor = this.anchor\n if (anchor && !isAnchor(anchor)) return anchor.message\n return ''\n }\n\n private header(): TemplateResult {\n const surface = this.surface\n const home = assistantHomeSurface()\n const ready = this.capability === 'configured' && isAnchor(this.anchor)\n return html`\n <div class=\"scope\">\n <md-icon>${surface?.icon || 'forum'}</md-icon>\n <span class=\"what\">\n <span>${surface?.label() || t('title', 'Assistant')}</span>\n ${surface?.detail ? html`<span class=\"detail\">${surface.detail()}</span>` : nothing}\n </span>\n ${home && surface && home !== surface\n ? html`<button class=\"sbtn\" title=${t('to-home', \"back to this application's conversation\")} @click=${() => this.useSurface(home)}>\n <md-icon>home</md-icon>\n </button>`\n : nothing}\n ${ready && this.showingHistory\n ? html`<button\n class=\"sbtn\"\n title=${this.showingHistory ? t('back-to-conversation', 'back to the conversation') : t('conversations', 'conversations')}\n @click=${() => (this.showingHistory = !this.showingHistory)}\n >\n <md-icon>arrow_back</md-icon>${t('back-to-conversation', 'back to the conversation')}\n </button>`\n : nothing}\n <button class=\"sbtn\" title=${t('rebind', 'follow this screen again')} @click=${() => this.requestSurface(currentAssistantSurface())}>\n <md-icon>refresh</md-icon>\n </button>\n <button class=\"sbtn\" title=${t('close', 'close')} @click=${() => closeOverlay(this.viewpart)}>\n <md-icon>close</md-icon>\n </button>\n </div>\n `\n }\n\n /** The home button: talk about the application instead of this screen, until the screen changes. */\n private useSurface(surface: AssistantSurface) {\n void this.requestSurface(surface)\n }\n\n render(): TemplateResult {\n const anchor = this.anchor\n const ready = this.capability === 'configured' && isAnchor(anchor)\n const stuck = this.stuckLine()\n const surface = this.surface\n const openedFor = this.openedFor\n const board = surface?.board\n\n const mode: AssistantMode | undefined = ready ? { kind: this.kind, target: (anchor as any).anchorId, hostContext: {} } : undefined\n\n return html`\n ${this.header()}\n ${surface?.nextStep ? html`<div class=\"next-step\" role=\"status\">\n <span>${surface.nextStep.description?.() || ''}</span>\n <a href=${surface.nextStep.href}>${surface.nextStep.label()}<md-icon>arrow_forward</md-icon></a>\n </div>` : nothing}\n ${this.screenChanged ? html`<div class=\"transition\" role=\"status\">\n ${t('screen-and-conversation', 'Screen: {screen}. Conversation: {conversation}. Your conversation has been kept.', { screen: currentAssistantSurface()?.label() || t('no-subject', 'No subject'), conversation: surface?.label() || '' })}\n <button class=\"sbtn\" @click=${() => this.requestSurface(currentAssistantSurface())}>${t('switch-to-screen', 'Talk about this screen')}</button>\n </div>` : this.navigationNotice ? html`<div class=\"transition\" role=\"status\">${this.navigationNotice}</div>` : nothing}\n ${ready && this.showingHistory\n ? html`<ox-assistant-session-manager\n .anchorType=${(anchor as any).anchorType}\n .anchorId=${(anchor as any).anchorId}\n .sessionId=${this.sessionId}\n .kind=${this.kind}\n .kindLabels=${this.kindLabels}\n .scopeLabel=${t('conversation-scope', 'Conversations · {name}', { name: surface?.label() || '' })}\n @assistant-session-select=${(event: CustomEvent) => this.selectSession(event.detail.sessionId, event.detail.kind)}\n @assistant-session-reset=${() => this.newConversation()}\n @assistant-session-changed=${() => this.reloadSessions()}\n ></ox-assistant-session-manager>`\n : nothing}\n ${ready && !this.showingHistory\n ? html`<ox-assistant-session-toolbar\n .sessions=${this.sessions}\n .sessionId=${this.sessionId}\n .loading=${this.loading}\n .error=${this.failure}\n historyEnabled\n singleConversation\n @assistant-session-select=${(event: CustomEvent) => this.selectSession(event.detail.sessionId)}\n @assistant-session-reset=${() => this.newConversation()}\n @assistant-session-history=${() => (this.showingHistory = true)}\n @assistant-session-retry=${() => this.open()}\n ></ox-assistant-session-toolbar>`\n : nothing}\n ${ready && !this.showingHistory && this.audience === 'open'\n ? html`<div class=\"audience\" role=\"status\">\n <md-icon>public</md-icon>\n <span>${t('audience-open-band', 'Public conversation - everyone in this domain can read and write here.')}</span>\n </div>`\n : nothing}\n ${ready && !this.loading && !this.failure\n ? keyed(\n this.conversationView,\n html`<ox-assistant-chat\n ?hidden=${this.showingHistory}\n .sendBlocked=${this.screenChanged ? t('return-to-subject', 'Return to the conversation subject before sending or applying changes.') : ''}\n .sessionId=${this.sessionId}\n .prepareSession=${(adopt: (id: string) => void) => this.controller.prepareSession(adopt)}\n .contextProvider=${() => {\n /* The screen moved on between writing and sending - do not answer about the old one. */\n if (openedFor !== this.scopeKey(currentAssistantSurface()) || this.openedIdentity !== this.identityKey()) throw new Error(t('return-to-subject', 'Return to the conversation subject before applying this proposal.'))\n return { hostContext: surface?.hostContext?.() ?? {} }\n }}\n .mode=${mode}\n .subject=${surface?.subject}\n .chatEndpoint=${board?.chatEndpoint ?? 'assistantChat'}\n ?board-tools=${!!board}\n .currentBoard=${board?.currentBoard?.()}\n .boardProvider=${board?.boardProvider}\n .selectedRefids=${board?.selectedRefids?.() ?? []}\n .knownTypes=${board?.knownTypes?.()}\n .categories=${board?.categories?.()}\n .componentSchemas=${board?.componentSchemas?.()}\n .searchProvider=${board?.searchProvider}\n .autoAsk=${this.asking?.ask}\n .autoAskRequestId=${this.asking?.requestId}\n .draft=${this.asking?.draft}\n .draftRequestId=${this.asking?.requestId}\n @assistant-mode-change=${this.onModeChange}\n @assistant-proposal-execute=${this.onProposal}\n @assistant-proposal-check=${this.onProposalCheck}\n @scene-edit-patch=${this.onScenePatch}\n @board-edit-revert=${this.onBoardRevert}\n @scene-action-execute=${this.onSceneAction}\n ></ox-assistant-chat>`\n )\n : nothing}\n ${stuck\n ? html`<div class=\"stuck\">\n ${stuck}\n ${this.capability === 'unknown'\n ? html`<div><button class=\"sbtn\" @click=${() => this.open()}><md-icon>refresh</md-icon>${t('retry', 'try again')}</button></div>`\n : nothing}\n </div>`\n : nothing}\n ${this.failure && !stuck && !ready\n ? html`<div class=\"stuck\">\n ${this.failure}\n <div><button class=\"sbtn\" @click=${() => this.open()}><md-icon>refresh</md-icon>${t('retry', 'try again')}</button></div>\n </div>`\n : nothing}\n `\n }\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import '@material/web/icon/icon.js';
|
|
2
|
+
import { LitElement } from 'lit';
|
|
3
|
+
export declare class AssistantEntryReview extends LitElement {
|
|
4
|
+
static styles: import("lit").CSSResult;
|
|
5
|
+
proposal: any;
|
|
6
|
+
/** The sum of each totalled field, beside the total the material prints - a missing row shows here without reading every row. */
|
|
7
|
+
private renderTotals;
|
|
8
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { __decorate, __metadata } from "tslib";
|
|
2
|
+
/*
|
|
3
|
+
* The rows of a data entry proposal, as the person reviews them (operato-application/design/ai/data-entry.md §5).
|
|
4
|
+
*
|
|
5
|
+
* Read-only on purpose: a correction is said in the conversation ("row 2 is 12,000", "drop the last one")
|
|
6
|
+
* and the model proposes again. What is wrong in a cell is marked on the cell - blocking in the error
|
|
7
|
+
* colour, a note in the outline - and where each row came from is on the row.
|
|
8
|
+
*/
|
|
9
|
+
import '@material/web/icon/icon.js';
|
|
10
|
+
import { LitElement, css, html, nothing } from 'lit';
|
|
11
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
12
|
+
import { i18next } from '@operato/i18n';
|
|
13
|
+
import { entryCellIssues, entryIssueKey } from '../utils/entry-proposal.js';
|
|
14
|
+
const SHOWN = 50;
|
|
15
|
+
const t = (key, defaultValue, options = {}) => i18next.t(`ai-assistant.entry.${key}`, { defaultValue, ...options });
|
|
16
|
+
function issueText(issue) {
|
|
17
|
+
const params = { ...(issue.params ?? {}) };
|
|
18
|
+
if (Array.isArray(params.values))
|
|
19
|
+
params.values = params.values.join(', ');
|
|
20
|
+
return String(i18next.t(entryIssueKey(issue), { defaultValue: issue.code, ...params }));
|
|
21
|
+
}
|
|
22
|
+
function shown(value) {
|
|
23
|
+
if (value === undefined || value === null)
|
|
24
|
+
return '';
|
|
25
|
+
if (typeof value === 'number')
|
|
26
|
+
return value.toLocaleString(i18next.language || undefined);
|
|
27
|
+
if (typeof value === 'boolean')
|
|
28
|
+
return value ? '✓' : '—';
|
|
29
|
+
return String(value);
|
|
30
|
+
}
|
|
31
|
+
let AssistantEntryReview = class AssistantEntryReview extends LitElement {
|
|
32
|
+
static { this.styles = css `
|
|
33
|
+
:host {
|
|
34
|
+
display: block;
|
|
35
|
+
margin: 4px 0 2px;
|
|
36
|
+
font-size: 12px;
|
|
37
|
+
color: var(--md-sys-color-on-surface);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.summary {
|
|
41
|
+
display: flex;
|
|
42
|
+
flex-wrap: wrap;
|
|
43
|
+
gap: 4px 10px;
|
|
44
|
+
margin-bottom: 6px;
|
|
45
|
+
color: var(--md-sys-color-on-surface-variant);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.summary .blocked {
|
|
49
|
+
color: var(--md-sys-color-error);
|
|
50
|
+
font-weight: 600;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.scroll {
|
|
54
|
+
max-height: 320px;
|
|
55
|
+
overflow: auto;
|
|
56
|
+
border: 1px solid var(--md-sys-color-outline-variant);
|
|
57
|
+
border-radius: 6px;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
table {
|
|
61
|
+
width: 100%;
|
|
62
|
+
border-collapse: collapse;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
th,
|
|
66
|
+
td {
|
|
67
|
+
padding: 4px 6px;
|
|
68
|
+
border-bottom: 1px solid var(--md-sys-color-outline-variant);
|
|
69
|
+
text-align: start;
|
|
70
|
+
vertical-align: top;
|
|
71
|
+
white-space: nowrap;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
th {
|
|
75
|
+
position: sticky;
|
|
76
|
+
top: 0;
|
|
77
|
+
background: var(--md-sys-color-surface-container);
|
|
78
|
+
font-weight: 600;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
td.num {
|
|
82
|
+
text-align: end;
|
|
83
|
+
font-variant-numeric: tabular-nums;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
tr.blocked td {
|
|
87
|
+
background: color-mix(in srgb, var(--md-sys-color-error) 6%, transparent);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
td.bad {
|
|
91
|
+
color: var(--md-sys-color-error);
|
|
92
|
+
text-decoration: underline wavy var(--md-sys-color-error);
|
|
93
|
+
text-underline-offset: 3px;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
td.note {
|
|
97
|
+
text-decoration: underline dotted var(--md-sys-color-outline);
|
|
98
|
+
text-underline-offset: 3px;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.missing {
|
|
102
|
+
color: var(--md-sys-color-error);
|
|
103
|
+
font-style: italic;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.source {
|
|
107
|
+
color: var(--md-sys-color-on-surface-variant);
|
|
108
|
+
max-width: 180px;
|
|
109
|
+
overflow: hidden;
|
|
110
|
+
text-overflow: ellipsis;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.row-issue {
|
|
114
|
+
display: block;
|
|
115
|
+
color: var(--md-sys-color-on-surface-variant);
|
|
116
|
+
white-space: normal;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.row-issue.blocking {
|
|
120
|
+
color: var(--md-sys-color-error);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.verified {
|
|
124
|
+
color: var(--md-sys-color-primary);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.verified md-icon,
|
|
128
|
+
.totals md-icon {
|
|
129
|
+
--md-icon-size: 14px;
|
|
130
|
+
vertical-align: -2px;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.totals {
|
|
134
|
+
display: flex;
|
|
135
|
+
flex-wrap: wrap;
|
|
136
|
+
gap: 2px 12px;
|
|
137
|
+
margin: 6px 0 0;
|
|
138
|
+
font-variant-numeric: tabular-nums;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.totals .differs {
|
|
142
|
+
color: var(--md-sys-color-error);
|
|
143
|
+
font-weight: 600;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.totals .matches {
|
|
147
|
+
color: var(--md-sys-color-primary);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.more,
|
|
151
|
+
.check-failed {
|
|
152
|
+
margin-top: 4px;
|
|
153
|
+
color: var(--md-sys-color-on-surface-variant);
|
|
154
|
+
}
|
|
155
|
+
`; }
|
|
156
|
+
/** The sum of each totalled field, beside the total the material prints - a missing row shows here without reading every row. */
|
|
157
|
+
renderTotals(totals, columns) {
|
|
158
|
+
if (!totals.length)
|
|
159
|
+
return nothing;
|
|
160
|
+
const name = (field) => {
|
|
161
|
+
const column = columns.find(one => one.name === field);
|
|
162
|
+
return column?.labelKey ? i18next.t(column.labelKey) : field;
|
|
163
|
+
};
|
|
164
|
+
return html `<div class="totals" role="status">
|
|
165
|
+
${totals.map(total => html `
|
|
166
|
+
<span>${t('total', '{field} total {sum}', { field: name(total.field), sum: shown(total.all) })}</span>
|
|
167
|
+
${total.ready !== total.all ? html `<span>${t('total-ready', 'entered {sum}', { sum: shown(total.ready) })}</span>` : nothing}
|
|
168
|
+
${total.declared !== undefined
|
|
169
|
+
? 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>
|
|
170
|
+
${total.difference
|
|
171
|
+
? html `<span class="differs">${t('total-differs', 'differs by {sum}', { sum: shown(total.difference) })}</span>`
|
|
172
|
+
: html `<span class="matches"><md-icon>task_alt</md-icon> ${t('total-matches', 'matches')}</span>`}`
|
|
173
|
+
: nothing}
|
|
174
|
+
`)}
|
|
175
|
+
</div>`;
|
|
176
|
+
}
|
|
177
|
+
render() {
|
|
178
|
+
const p = this.proposal ?? {};
|
|
179
|
+
const columns = p.columns ?? [];
|
|
180
|
+
const rows = p.rows ?? [];
|
|
181
|
+
const counts = p.counts ?? {};
|
|
182
|
+
return html `
|
|
183
|
+
<div class="summary" role="status">
|
|
184
|
+
<span>${t('rows', '{count} rows', { count: counts.rows ?? rows.length })}</span>
|
|
185
|
+
<span>${t('ready', '{count} ready', { count: counts.ready ?? 0 })}</span>
|
|
186
|
+
${counts.blocked ? html `<span class="blocked">${t('blocked', '{count} will not be entered', { count: counts.blocked })}</span>` : nothing}
|
|
187
|
+
${counts.cut ? html `<span class="blocked">${t('cut', '{count} left out over the limit', { count: counts.cut })}</span>` : nothing}
|
|
188
|
+
${counts.verified ? html `<span class="verified"><md-icon>task_alt</md-icon> ${t('verified', '{count} found in their file', { count: counts.verified })}</span>` : nothing}
|
|
189
|
+
${counts.unmatched ? html `<span class="blocked">${t('unmatched', '{count} with a value their file does not have', { count: counts.unmatched })}</span>` : nothing}
|
|
190
|
+
</div>
|
|
191
|
+
<div class="scroll">
|
|
192
|
+
<table>
|
|
193
|
+
<thead>
|
|
194
|
+
<tr>
|
|
195
|
+
<th>#</th>
|
|
196
|
+
${columns.map(column => html `<th>${column.labelKey ? i18next.t(column.labelKey) : column.name}${column.required ? ' *' : ''}</th>`)}
|
|
197
|
+
<th>${t('source', 'from')}</th>
|
|
198
|
+
</tr>
|
|
199
|
+
</thead>
|
|
200
|
+
<tbody>
|
|
201
|
+
${rows.slice(0, SHOWN).map(row => {
|
|
202
|
+
const blocked = (row.issues ?? []).some(issue => issue.blocking);
|
|
203
|
+
const whole = entryCellIssues(row);
|
|
204
|
+
return html `
|
|
205
|
+
<tr class=${blocked ? 'blocked' : ''}>
|
|
206
|
+
<td class="num">${row.index + 1}</td>
|
|
207
|
+
${columns.map(column => {
|
|
208
|
+
const issues = entryCellIssues(row, column.name);
|
|
209
|
+
const bad = issues.some(issue => issue.blocking);
|
|
210
|
+
const value = row.values?.[column.name];
|
|
211
|
+
const text = shown(value);
|
|
212
|
+
return html `<td
|
|
213
|
+
class="${column.type === 'number' || column.type === 'integer' ? 'num' : ''} ${bad ? 'bad' : issues.length ? 'note' : ''}"
|
|
214
|
+
title=${issues.map(issueText).join('\n')}
|
|
215
|
+
>
|
|
216
|
+
${text || (issues.some(issue => issue.code === 'required') ? html `<span class="missing">${t('missing', 'missing')}</span>` : '')}
|
|
217
|
+
</td>`;
|
|
218
|
+
})}
|
|
219
|
+
<td class="source" title=${(row.sources ?? []).map(source => source.where || source.attachmentId).join(' · ')}>
|
|
220
|
+
${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}
|
|
221
|
+
${(row.sources ?? []).map(source => source.where || source.attachmentId).join(' · ')}
|
|
222
|
+
${whole
|
|
223
|
+
.filter(issue => issue.code !== 'no-source')
|
|
224
|
+
.map(issue => html `<span class="row-issue ${issue.blocking ? 'blocking' : ''}">${issueText(issue)}</span>`)}
|
|
225
|
+
${whole.some(issue => issue.code === 'no-source') ? html `<span class="row-issue">${issueText({ code: 'no-source', blocking: false })}</span>` : nothing}
|
|
226
|
+
</td>
|
|
227
|
+
</tr>
|
|
228
|
+
`;
|
|
229
|
+
})}
|
|
230
|
+
</tbody>
|
|
231
|
+
</table>
|
|
232
|
+
</div>
|
|
233
|
+
${this.renderTotals(p.totals ?? [], columns)}
|
|
234
|
+
${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}
|
|
235
|
+
${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}
|
|
236
|
+
`;
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
__decorate([
|
|
240
|
+
property({ attribute: false }),
|
|
241
|
+
__metadata("design:type", Object)
|
|
242
|
+
], AssistantEntryReview.prototype, "proposal", void 0);
|
|
243
|
+
AssistantEntryReview = __decorate([
|
|
244
|
+
customElement('ox-assistant-entry-review')
|
|
245
|
+
], AssistantEntryReview);
|
|
246
|
+
export { AssistantEntryReview };
|
|
247
|
+
//# sourceMappingURL=entry-review.js.map
|
|
@@ -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"]}
|