@operato/app 10.29.41 → 10.29.43

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
@@ -3,6 +3,24 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ### [10.29.43](https://github.com/hatiolab/operato/compare/v10.29.42...v10.29.43) (2026-10-18)
7
+
8
+ **Note:** Version bump only for package @operato/app
9
+
10
+
11
+
12
+
13
+
14
+ ### [10.29.42](https://github.com/hatiolab/operato/compare/v10.29.41...v10.29.42) (2026-10-18)
15
+
16
+
17
+ ### :bug: Bug Fix
18
+
19
+ * **app:** a code chosen in a code cell reaches the grid ([9fe9aa5](https://github.com/hatiolab/operato/commit/9fe9aa58ed87e9ca8f5a21243cea67e8de8ff570))
20
+ * **app:** the code cell is an inline editor, not a popup one ([4b81d35](https://github.com/hatiolab/operato/commit/4b81d3587b984ecfb40950544d13f41cae26f38c))
21
+
22
+
23
+
6
24
  ### [10.29.41](https://github.com/hatiolab/operato/compare/v10.29.40...v10.29.41) (2026-10-18)
7
25
 
8
26
  **Note:** Version bump only for package @operato/app
@@ -1,6 +1,5 @@
1
1
  import '@material/web/icon/icon.js';
2
2
  import { OxGristEditor } from '@operato/data-grist';
3
3
  export declare class OxGristEditorResourceCode extends OxGristEditor {
4
- static opensPopup: boolean;
5
4
  get editorTemplate(): import("lit-html").TemplateResult<1>;
6
5
  }
@@ -4,6 +4,12 @@ import { OxGristEditor } from '@operato/data-grist';
4
4
  import { customElement } from 'lit/decorators.js';
5
5
  import { html } from 'lit';
6
6
  let OxGristEditorResourceCode = class OxGristEditorResourceCode extends OxGristEditor {
7
+ /*
8
+ * It edits in place with a <select>, as data-grist's select editor does — it opens no popup. So it is not
9
+ * `opensPopup`: the cell gets the inline mark (gone while the select and its arrow are open), and the value is
10
+ * committed on blur like every inline editor. Flagged as a popup, it was committed by nothing once the base editor
11
+ * left popup editors to their own confirmation (10-17).
12
+ */
7
13
  get editorTemplate() {
8
14
  var { codes, selectDispOpt = 'code-name' } = this.column.record || {};
9
15
  return html `
@@ -17,8 +23,6 @@ let OxGristEditorResourceCode = class OxGristEditorResourceCode extends OxGristE
17
23
  `;
18
24
  }
19
25
  };
20
- /* 팝업으로 고친다 — 칸에 표식이 붙는다(OxGristEditor.opensPopup). */
21
- OxGristEditorResourceCode.opensPopup = true;
22
26
  OxGristEditorResourceCode = __decorate([
23
27
  customElement('ox-grist-editor-resource-code')
24
28
  ], OxGristEditorResourceCode);
@@ -1 +1 @@
1
- {"version":3,"file":"ox-grist-editor-resource-code.js","sourceRoot":"","sources":["../../../src/grist-editor/ox-grist-editor-resource-code.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AACnC,OAAO,EAAE,aAAa,EAAgB,MAAM,qBAAqB,CAAA;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AASnB,IAAM,yBAAyB,GAA/B,MAAM,yBAA0B,SAAQ,aAAa;IAI1D,IAAI,cAAc;QAChB,IAAI,EAAE,KAAK,EAAE,aAAa,GAAG,WAAW,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAA;QAErE,OAAO,IAAI,CAAA;;UAEL,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CACjB,CAAC,IAAsB,EAAE,EAAE,CAAC,IAAI,CAAA;gCACV,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,UAAU,IAAI,CAAC,IAAI;gBAC1D,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC;;WAEtG,CACF;;KAEJ,CAAA;IACH,CAAC;;AAjBD,sDAAsD;AAC/C,oCAAU,GAAG,IAAI,AAAP,CAAO;AAFb,yBAAyB;IADrC,aAAa,CAAC,+BAA+B,CAAC;GAClC,yBAAyB,CAmBrC","sourcesContent":["import '@material/web/icon/icon.js'\nimport { OxGristEditor, RecordConfig } from '@operato/data-grist'\n\nimport { customElement } from 'lit/decorators.js'\nimport { html } from 'lit'\n\ntype CommonCodeDetail = {\n name: string\n description: string\n rank: number\n}\n\n@customElement('ox-grist-editor-resource-code')\nexport class OxGristEditorResourceCode extends OxGristEditor {\n /* 팝업으로 고친다 — 칸에 표식이 붙는다(OxGristEditor.opensPopup). */\n static opensPopup = true\n\n get editorTemplate() {\n var { codes, selectDispOpt = 'code-name' } = this.column.record || {}\n\n return html`\n <select>\n ${(codes || []).map(\n (code: CommonCodeDetail) => html`\n <option ?selected=${code.name == this.value} value=${code.name}>\n ${code.name == '' ? '' : selectDispOpt.replace('name', code.description).replace('code', code.name)}\n </option>\n `\n )}\n </select>\n `\n }\n}\n"]}
1
+ {"version":3,"file":"ox-grist-editor-resource-code.js","sourceRoot":"","sources":["../../../src/grist-editor/ox-grist-editor-resource-code.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AACnC,OAAO,EAAE,aAAa,EAAgB,MAAM,qBAAqB,CAAA;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AASnB,IAAM,yBAAyB,GAA/B,MAAM,yBAA0B,SAAQ,aAAa;IAC1D;;;;;OAKG;IACH,IAAI,cAAc;QAChB,IAAI,EAAE,KAAK,EAAE,aAAa,GAAG,WAAW,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAA;QAErE,OAAO,IAAI,CAAA;;UAEL,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CACjB,CAAC,IAAsB,EAAE,EAAE,CAAC,IAAI,CAAA;gCACV,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,UAAU,IAAI,CAAC,IAAI;gBAC1D,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC;;WAEtG,CACF;;KAEJ,CAAA;IACH,CAAC;CACF,CAAA;AAtBY,yBAAyB;IADrC,aAAa,CAAC,+BAA+B,CAAC;GAClC,yBAAyB,CAsBrC","sourcesContent":["import '@material/web/icon/icon.js'\nimport { OxGristEditor, RecordConfig } from '@operato/data-grist'\n\nimport { customElement } from 'lit/decorators.js'\nimport { html } from 'lit'\n\ntype CommonCodeDetail = {\n name: string\n description: string\n rank: number\n}\n\n@customElement('ox-grist-editor-resource-code')\nexport class OxGristEditorResourceCode extends OxGristEditor {\n /*\n * It edits in place with a <select>, as data-grist's select editor does — it opens no popup. So it is not\n * `opensPopup`: the cell gets the inline mark (gone while the select and its arrow are open), and the value is\n * committed on blur like every inline editor. Flagged as a popup, it was committed by nothing once the base editor\n * left popup editors to their own confirmation (10-17).\n */\n get editorTemplate() {\n var { codes, selectDispOpt = 'code-name' } = this.column.record || {}\n\n return html`\n <select>\n ${(codes || []).map(\n (code: CommonCodeDetail) => html`\n <option ?selected=${code.name == this.value} value=${code.name}>\n ${code.name == '' ? '' : selectDispOpt.replace('name', code.description).replace('code', code.name)}\n </option>\n `\n )}\n </select>\n `\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ import '../src/grist-editor/ox-grist-editor-resource-code.js';
@@ -0,0 +1,63 @@
1
+ import { expect, fixture, oneEvent } from '@open-wc/testing';
2
+ import { html } from 'lit';
3
+ import '../src/grist-editor/ox-grist-editor-resource-code.js';
4
+ /**
5
+ * A code chosen in a code cell reaches the grid.
6
+ *
7
+ * ## Why this test is here (2026-10-19)
8
+ *
9
+ * The code cell edits in place with a `<select>`, but it said `opensPopup`. On 10-17 the base editor stopped
10
+ * committing popup editors on blur — they commit through their own confirmation — and the code cell has none, so from
11
+ * then on nothing committed it: the select changed, the row did not, and saving kept the old 직책 · 직급 (every
12
+ * editable code column in every app). It is an inline editor like data-grist's select editor: it commits on blur, and
13
+ * its cell gets the inline mark, which is gone while the select is open.
14
+ */
15
+ const column = {
16
+ name: 'jobPosition',
17
+ type: 'code',
18
+ record: {
19
+ editable: true,
20
+ selectDispOpt: 'name',
21
+ codes: [
22
+ { name: '', description: '' },
23
+ { name: '이사', description: '이사' },
24
+ { name: '프로', description: '프로' }
25
+ ]
26
+ }
27
+ };
28
+ async function editorOn(value) {
29
+ const record = { id: 'e1', jobPosition: value };
30
+ const editor = await fixture(html `<ox-grist-editor-resource-code .column=${column} .record=${record} .row=${3}></ox-grist-editor-resource-code>`);
31
+ await editor.updateComplete;
32
+ /* firstUpdated is async and fills the editor's value on the next frame. */
33
+ await new Promise(resolve => requestAnimationFrame(() => resolve(undefined)));
34
+ return { editor, select: editor.shadowRoot.querySelector('select') };
35
+ }
36
+ const pick = (select, value) => {
37
+ select.value = value;
38
+ select.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
39
+ select.dispatchEvent(new FocusEvent('focusout', { bubbles: true, composed: true }));
40
+ };
41
+ describe('code cell · a chosen code reaches the grid', () => {
42
+ it('choosing another code and leaving the cell sends field-change with the old and the new code', async () => {
43
+ const { editor, select } = await editorOn('프로');
44
+ setTimeout(() => pick(select, '이사'));
45
+ const event = await oneEvent(editor, 'field-change');
46
+ expect(event.detail.before).to.equal('프로');
47
+ expect(event.detail.after).to.equal('이사');
48
+ expect(event.detail.row).to.equal(3);
49
+ });
50
+ it('choosing the code the cell already has sends nothing', async () => {
51
+ const { editor, select } = await editorOn('프로');
52
+ let sent = 0;
53
+ editor.addEventListener('field-change', () => sent++);
54
+ pick(select, '프로');
55
+ await new Promise(resolve => setTimeout(resolve, 50));
56
+ expect(sent).to.equal(0);
57
+ });
58
+ it('it is an inline editor, not a popup one — so its mark is gone while the select is open', async () => {
59
+ const { editor } = await editorOn('프로');
60
+ expect(editor.constructor.opensPopup).to.equal(false);
61
+ });
62
+ });
63
+ //# sourceMappingURL=resource-code-editor-commits.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-code-editor-commits.test.js","sourceRoot":"","sources":["../../test/resource-code-editor-commits.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAE1B,OAAO,sDAAsD,CAAA;AAE7D;;;;;;;;;;GAUG;AACH,MAAM,MAAM,GAAQ;IAClB,IAAI,EAAE,aAAa;IACnB,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE;QACN,QAAQ,EAAE,IAAI;QACd,aAAa,EAAE,MAAM;QACrB,KAAK,EAAE;YACL,EAAE,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE;YAC7B,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;YACjC,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;SAClC;KACF;CACF,CAAA;AAED,KAAK,UAAU,QAAQ,CAAC,KAAa;IACnC,MAAM,MAAM,GAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAA;IACpD,MAAM,MAAM,GAAQ,MAAM,OAAO,CAC/B,IAAI,CAAA,0CAA0C,MAAM,YAAY,MAAM,SAAS,CAAC,mCAAmC,CACpH,CAAA;IACD,MAAM,MAAM,CAAC,cAAc,CAAA;IAC3B,2EAA2E;IAC3E,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,qBAAqB,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;IAC7E,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,QAAQ,CAAsB,EAAE,CAAA;AAC3F,CAAC;AAED,MAAM,IAAI,GAAG,CAAC,MAAyB,EAAE,KAAa,EAAE,EAAE;IACxD,MAAM,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,MAAM,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IAC5E,MAAM,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,UAAU,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;AACrF,CAAC,CAAA;AAED,QAAQ,CAAC,4CAA4C,EAAE,GAAG,EAAE;IAC1D,EAAE,CAAC,6FAA6F,EAAE,KAAK,IAAI,EAAE;QAC3G,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAA;QAC/C,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAA;QACpC,MAAM,KAAK,GAAQ,MAAM,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;QACzD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC1C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACzC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IACtC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAA;QAC/C,IAAI,IAAI,GAAG,CAAC,CAAA;QACZ,MAAM,CAAC,gBAAgB,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,CAAA;QACrD,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QAClB,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;QACrD,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAC1B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wFAAwF,EAAE,KAAK,IAAI,EAAE;QACtG,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAA;QACvC,MAAM,CAAE,MAAM,CAAC,WAAmB,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAChE,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import { expect, fixture, oneEvent } from '@open-wc/testing'\nimport { html } from 'lit'\n\nimport '../src/grist-editor/ox-grist-editor-resource-code.js'\n\n/**\n * A code chosen in a code cell reaches the grid.\n *\n * ## Why this test is here (2026-10-19)\n *\n * The code cell edits in place with a `<select>`, but it said `opensPopup`. On 10-17 the base editor stopped\n * committing popup editors on blur — they commit through their own confirmation — and the code cell has none, so from\n * then on nothing committed it: the select changed, the row did not, and saving kept the old 직책 · 직급 (every\n * editable code column in every app). It is an inline editor like data-grist's select editor: it commits on blur, and\n * its cell gets the inline mark, which is gone while the select is open.\n */\nconst column: any = {\n name: 'jobPosition',\n type: 'code',\n record: {\n editable: true,\n selectDispOpt: 'name',\n codes: [\n { name: '', description: '' },\n { name: '이사', description: '이사' },\n { name: '프로', description: '프로' }\n ]\n }\n}\n\nasync function editorOn(value: string) {\n const record: any = { id: 'e1', jobPosition: value }\n const editor: any = await fixture(\n html`<ox-grist-editor-resource-code .column=${column} .record=${record} .row=${3}></ox-grist-editor-resource-code>`\n )\n await editor.updateComplete\n /* firstUpdated is async and fills the editor's value on the next frame. */\n await new Promise(resolve => requestAnimationFrame(() => resolve(undefined)))\n return { editor, select: editor.shadowRoot.querySelector('select') as HTMLSelectElement }\n}\n\nconst pick = (select: HTMLSelectElement, value: string) => {\n select.value = value\n select.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n select.dispatchEvent(new FocusEvent('focusout', { bubbles: true, composed: true }))\n}\n\ndescribe('code cell · a chosen code reaches the grid', () => {\n it('choosing another code and leaving the cell sends field-change with the old and the new code', async () => {\n const { editor, select } = await editorOn('프로')\n setTimeout(() => pick(select, '이사'))\n const event: any = await oneEvent(editor, 'field-change')\n expect(event.detail.before).to.equal('프로')\n expect(event.detail.after).to.equal('이사')\n expect(event.detail.row).to.equal(3)\n })\n\n it('choosing the code the cell already has sends nothing', async () => {\n const { editor, select } = await editorOn('프로')\n let sent = 0\n editor.addEventListener('field-change', () => sent++)\n pick(select, '프로')\n await new Promise(resolve => setTimeout(resolve, 50))\n expect(sent).to.equal(0)\n })\n\n it('it is an inline editor, not a popup one — so its mark is gone while the select is open', async () => {\n const { editor } = await editorOn('프로')\n expect((editor.constructor as any).opensPopup).to.equal(false)\n })\n})\n"]}