@simmalugnt-se/payload-editor-assistant 0.11.0 → 0.11.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.11.2
4
+
5
+ - Translating a page whose text is all inside blocks or rows now works. The assistant left the
6
+ source language out of its context when it compared it with nothing, so it answered that there
7
+ was no English text to translate from. It now compares with the open form.
8
+ - A batch link from the work list starts again after Cancel. It was remembered as taken for the
9
+ whole session, so the second click did nothing until the page was reloaded.
10
+
11
+ ## 0.11.1
12
+
13
+ - The batch panel shows Start and Cancel right under the text that explains the batch, instead of
14
+ at the bottom of the panel, where they were easy to miss on a tall screen. "New chat" is hidden
15
+ while a batch is open.
16
+ - Saved batch cards keep the assistant's accent blue, like proposals and selections, instead of
17
+ Payload's success colour.
18
+
3
19
  ## 0.11.0
4
20
 
5
21
  - Batches: fix many saved documents at once from content health's work list. The new
@@ -135,10 +135,10 @@ export function BatchPanel({ batch, onClose }) {
135
135
  const selected = cards.filter((card) => card.status === "proposed" && card.checked).length;
136
136
  const waiting = waitingKeys(cards).length;
137
137
  const savedCount = cards.filter((card) => card.status === "saved" || card.status === "draft").length;
138
- return (_jsxs("div", { className: "ea-batch", children: [_jsxs("div", { className: "ea-batch__head", children: [_jsx("h3", { children: copy.title(batch.targets.length) }), _jsxs("p", { className: "ea-batch__task", children: [_jsxs("span", { children: [copy.task, ":"] }), " ", batch.prompt] }), phase === "ready" ? _jsx("p", { children: copy.intro(waiting) }) : null, phase === "running" || phase === "saving" ? (_jsx("p", { "aria-live": "polite", children: phase === "saving" ? copy.saving : copy.progress(finished, total) })) : null, phase === "review" && selected > 0 ? _jsx("p", { children: copy.review }) : null, phase === "done" ? (_jsx("p", { "aria-live": "polite", children: copy.summary(savedCount, total - savedCount) })) : null] }), _jsx("ul", { className: "ea-batch__cards", children: cards.map((card) => (_jsx(BatchCardItem, { adminRoute: config.routes.admin, card: card, copy: copy, editable: phase === "review" || phase === "done", onCheck: (checked) => update(card.key, (current) => ({ ...current, checked })), onEdit: (path, value) => update(card.key, (current) => ({
138
+ return (_jsxs("div", { className: "ea-batch", children: [_jsxs("div", { className: "ea-batch__head", children: [_jsx("h3", { children: copy.title(batch.targets.length) }), _jsxs("p", { className: "ea-batch__task", children: [_jsxs("span", { children: [copy.task, ":"] }), " ", batch.prompt] }), phase === "ready" ? (_jsxs(_Fragment, { children: [_jsx("p", { children: copy.intro(waiting) }), _jsxs("div", { className: "ea-actions", children: [_jsx(Button, { buttonStyle: "primary", disabled: waiting === 0, margin: false, onClick: () => void run(), size: "medium", children: copy.start }), _jsx(Button, { buttonStyle: "secondary", margin: false, onClick: onClose, size: "medium", children: copy.cancel })] })] })) : null, phase === "running" || phase === "saving" ? (_jsx("p", { "aria-live": "polite", children: phase === "saving" ? copy.saving : copy.progress(finished, total) })) : null, phase === "review" && selected > 0 ? _jsx("p", { children: copy.review }) : null, phase === "done" ? (_jsx("p", { "aria-live": "polite", children: copy.summary(savedCount, total - savedCount) })) : null] }), _jsx("ul", { className: "ea-batch__cards", children: cards.map((card) => (_jsx(BatchCardItem, { adminRoute: config.routes.admin, card: card, copy: copy, editable: phase === "review" || phase === "done", onCheck: (checked) => update(card.key, (current) => ({ ...current, checked })), onEdit: (path, value) => update(card.key, (current) => ({
139
139
  ...current,
140
140
  edits: { ...current.edits, [path]: value },
141
- })), onRetry: (instruction) => void retry(card, instruction) }, card.key))) }), _jsxs("div", { className: "ea-actions ea-batch__actions", children: [phase === "ready" ? (_jsxs(_Fragment, { children: [_jsx(Button, { buttonStyle: "primary", disabled: waiting === 0, margin: false, onClick: () => void run(), size: "medium", children: copy.start }), _jsx(Button, { buttonStyle: "secondary", margin: false, onClick: onClose, size: "medium", children: copy.cancel })] })) : null, phase === "running" ? (_jsx(Button, { buttonStyle: "secondary", margin: false, onClick: stop, size: "medium", children: copy.stop })) : null, phase === "review" ? (_jsxs(_Fragment, { children: [_jsx(Button, { buttonStyle: "primary", disabled: selected === 0, margin: false, onClick: () => void save(), size: "medium", children: copy.save(selected) }), waiting > 0 ? (_jsx(Button, { buttonStyle: "secondary", margin: false, onClick: () => void run(), size: "medium", children: copy.continue })) : null, _jsx(Button, { buttonStyle: "secondary", margin: false, onClick: () => void close(), size: "medium", children: copy.cancel })] })) : null, phase === "done" ? (_jsx(Button, { buttonStyle: "primary", margin: false, onClick: onClose, size: "medium", children: copy.close })) : null] })] }));
141
+ })), onRetry: (instruction) => void retry(card, instruction) }, card.key))) }), phase === "ready" ? null : (_jsxs("div", { className: "ea-actions ea-batch__actions", children: [phase === "running" ? (_jsx(Button, { buttonStyle: "secondary", margin: false, onClick: stop, size: "medium", children: copy.stop })) : null, phase === "review" ? (_jsxs(_Fragment, { children: [_jsx(Button, { buttonStyle: "primary", disabled: selected === 0, margin: false, onClick: () => void save(), size: "medium", children: copy.save(selected) }), waiting > 0 ? (_jsx(Button, { buttonStyle: "secondary", margin: false, onClick: () => void run(), size: "medium", children: copy.continue })) : null, _jsx(Button, { buttonStyle: "secondary", margin: false, onClick: () => void close(), size: "medium", children: copy.cancel })] })) : null, phase === "done" ? (_jsx(Button, { buttonStyle: "primary", margin: false, onClick: onClose, size: "medium", children: copy.close })) : null] }))] }));
142
142
  }
143
143
  function BatchCardItem({ adminRoute, card, copy, editable, onCheck, onEdit, onRetry, }) {
144
144
  const [retrying, setRetrying] = useState(false);
@@ -8,6 +8,7 @@ import { parseAdminView } from "../view.js";
8
8
  import { assistantRequest, assistantStream } from "./assistant-api.js";
9
9
  import { useAssistantState, } from "./assistant-context.js";
10
10
  import { BatchPanel } from "./BatchPanel.js";
11
+ import { releaseTakenBatches } from "./batch-link.js";
11
12
  import { COPY, translateAction, uiLanguage } from "./copy.js";
12
13
  import { isFormProposal, proposalSteps, refineProposal, replaceLatestStep, } from "./proposal-chain.js";
13
14
  import { ReplyText } from "./ReplyText.js";
@@ -443,7 +444,10 @@ export function EditorAssistantAside() {
443
444
  if (!open) {
444
445
  return null;
445
446
  }
446
- return (_jsxs("aside", { className: "ea-aside", "aria-label": copy.assistant, [KEEP_SELECTION_ATTR]: "", children: [_jsxs("div", { className: "ea-aside__head", children: [_jsxs("div", { className: "ea-aside__title", children: [_jsx("h2", { children: copy.assistant }), bridge ? _jsx("p", { className: "ea-aside__context", children: contextLine(bridge, config) }) : null] }), (messages.length > 0 || pendingApproval) && !pendingApproval?.applied ? (_jsx(Button, { buttonStyle: "subtle", margin: false, onClick: () => resetConversation(), size: "medium", children: copy.newChat })) : null, _jsx(Button, { "aria-label": copy.collapseLabel, buttonStyle: "icon-label", className: "ea-aside__collapse", icon: _jsx(ChevronIcon, { direction: "right" }), margin: false, onClick: () => setOpen(false), tooltip: copy.collapse })] }), batch ? (_jsx("div", { className: "ea-aside__body", children: _jsx(BatchPanel, { batch: batch, onClose: () => setBatch(null) }, batch.id) })) : (_jsxs("div", { className: "ea-aside__body", children: [_jsxs("div", { className: "ea-messages", ref: threadRef, onScroll: onThreadScroll, children: [messages.length === 0 ? (_jsx("div", { className: "ea-msg ea-msg--assistant", children: introText(view, bridge, collections, config, copy) })) : null, messages.map((message) => (_jsxs("div", { className: `ea-msg ea-msg--${message.role}`, children: [message.role === "assistant" ? _jsx(ReplyText, { text: message.text }) : message.text, message.candidates?.length ? (_jsx("div", { className: "ea-actions", children: message.candidates.map((candidate) => (_jsx(Button, { buttonStyle: "pill", margin: false, onClick: () => {
447
+ return (_jsxs("aside", { className: "ea-aside", "aria-label": copy.assistant, [KEEP_SELECTION_ATTR]: "", children: [_jsxs("div", { className: "ea-aside__head", children: [_jsxs("div", { className: "ea-aside__title", children: [_jsx("h2", { children: copy.assistant }), bridge ? _jsx("p", { className: "ea-aside__context", children: contextLine(bridge, config) }) : null] }), !batch && (messages.length > 0 || pendingApproval) && !pendingApproval?.applied ? (_jsx(Button, { buttonStyle: "subtle", margin: false, onClick: () => resetConversation(), size: "medium", children: copy.newChat })) : null, _jsx(Button, { "aria-label": copy.collapseLabel, buttonStyle: "icon-label", className: "ea-aside__collapse", icon: _jsx(ChevronIcon, { direction: "right" }), margin: false, onClick: () => setOpen(false), tooltip: copy.collapse })] }), batch ? (_jsx("div", { className: "ea-aside__body", children: _jsx(BatchPanel, { batch: batch, onClose: () => {
448
+ releaseTakenBatches();
449
+ setBatch(null);
450
+ } }, batch.id) })) : (_jsxs("div", { className: "ea-aside__body", children: [_jsxs("div", { className: "ea-messages", ref: threadRef, onScroll: onThreadScroll, children: [messages.length === 0 ? (_jsx("div", { className: "ea-msg ea-msg--assistant", children: introText(view, bridge, collections, config, copy) })) : null, messages.map((message) => (_jsxs("div", { className: `ea-msg ea-msg--${message.role}`, children: [message.role === "assistant" ? _jsx(ReplyText, { text: message.text }) : message.text, message.candidates?.length ? (_jsx("div", { className: "ea-actions", children: message.candidates.map((candidate) => (_jsx(Button, { buttonStyle: "pill", margin: false, onClick: () => {
447
451
  router.push(candidate.href);
448
452
  }, size: "small", children: candidate.label }, candidate.href))) })) : null] }, message.id))), status === "streaming" ? (_jsxs("div", { className: "ea-msg ea-msg--working", children: [_jsxs("span", { className: "ea-dots", "aria-hidden": "true", children: [_jsx("span", {}), _jsx("span", {}), _jsx("span", {})] }), _jsx("span", { children: step ? talk.steps[step] : talk.working })] })) : null] }), pendingApproval ? (_jsxs("div", { className: "ea-approval", children: [_jsx("h3", { children: pendingApproval.title }), pendingApproval.applied ? (_jsxs("p", { className: "ea-approval__hint", children: [autosave ? copy.previewHintAutosave : copy.previewHint, pendingApproval.earlier?.length ? ` ${copy.refinedHint}` : ""] })) : null, _jsx("ul", { className: "ea-approval__diff", children: pendingApproval.summary.split("\n").map((line, index) => line.startsWith(" ") ? (
449
453
  // biome-ignore lint/suspicious/noArrayIndexKey: lines are static for one approval
@@ -1,3 +1,5 @@
1
+ /** Once the editor leaves a batch, the same link may start it again. */
2
+ export declare function releaseTakenBatches(): void;
1
3
  /**
2
4
  * Opens the panel in batch mode when the address carries a batch from content health's work list,
3
5
  * and takes the parameters out of it, so a reload does not start the batch again.
@@ -6,6 +6,10 @@ import { useAssistantState } from "./assistant-context.js";
6
6
  import { ASK_PARAM } from "./selection-dom.js";
7
7
  /** Batches already taken this session: a view that writes its old address back must not repeat one. */
8
8
  const taken = new Set();
9
+ /** Once the editor leaves a batch, the same link may start it again. */
10
+ export function releaseTakenBatches() {
11
+ taken.clear();
12
+ }
9
13
  /**
10
14
  * Opens the panel in batch mode when the address carries a batch from content health's work list,
11
15
  * and takes the parameters out of it, so a reload does not start the batch again.
@@ -28,7 +28,9 @@ export async function loadTurnContext(req, options, bridge, formData) {
28
28
  query: "",
29
29
  locale: bridge.locale,
30
30
  });
31
- const otherLanguages = open ? await readOtherLanguages(req, options, bridge, fields) : undefined;
31
+ const otherLanguages = open
32
+ ? await readOtherLanguages(req, options, bridge, fields, form)
33
+ : undefined;
32
34
  const translation = form ? translationFor(req, bridge, fields, form, otherLanguages) : undefined;
33
35
  return {
34
36
  allowlist: schema.map(compactEntity),
@@ -62,7 +64,7 @@ async function readSavedDocument(req, options, bridge) {
62
64
  }
63
65
  return result.data;
64
66
  }
65
- async function readOtherLanguages(req, options, bridge, fields) {
67
+ async function readOtherLanguages(req, options, bridge, fields, form) {
66
68
  const locales = configuredLocales(req).filter((code) => code !== bridge.locale);
67
69
  if (locales.length === 0) {
68
70
  return undefined;
@@ -75,9 +77,13 @@ async function readOtherLanguages(req, options, bridge, fields) {
75
77
  documentId: bridge.documentId,
76
78
  locale,
77
79
  });
78
- // A language nobody wrote in yet is left out: it has nothing to translate from.
79
- if (result.ok && translationPaths(fields, {}, result.data).empty.length > 0) {
80
- otherLanguages[locale] = result.data;
80
+ // A language nobody wrote in yet is left out: it has nothing to translate from. Compared with
81
+ // the open form, since blocks and rows are matched one by one and never against nothing.
82
+ if (result.ok) {
83
+ const paths = translationPaths(fields, form ?? {}, result.data);
84
+ if (paths.empty.length + paths.translated.length > 0) {
85
+ otherLanguages[locale] = result.data;
86
+ }
81
87
  }
82
88
  }
83
89
  return Object.keys(otherLanguages).length > 0 ? otherLanguages : undefined;
@@ -484,13 +484,11 @@ html[data-theme="dark"] .ea-trigger--open .ea-trigger__icon {
484
484
  line-height: 1.45;
485
485
  }
486
486
 
487
- .ea-batch__card--proposed {
488
- border-inline-start: 3px solid var(--ea-accent);
489
- }
490
-
487
+ /* The accent, as for selections and changed fields; saved cards keep it. */
488
+ .ea-batch__card--proposed,
491
489
  .ea-batch__card--saved,
492
490
  .ea-batch__card--draft {
493
- border-inline-start: 3px solid var(--theme-success-500, #16a34a);
491
+ border-inline-start: 3px solid var(--ea-accent);
494
492
  }
495
493
 
496
494
  .ea-batch__card--failed,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simmalugnt-se/payload-editor-assistant",
3
- "version": "0.11.0",
3
+ "version": "0.11.2",
4
4
  "description": "Context-aware editor assistant plugin for Payload Admin",
5
5
  "keywords": [
6
6
  "payload",