@neovici/cosmoz-queue 3.9.1 → 3.9.3

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.
@@ -3,7 +3,7 @@ import type { Dialogable, Resolvable } from '@neovici/cosmoz-form';
3
3
  import { nothing } from 'lit-html';
4
4
  export declare const actionCount: <T>(items: T[], applicableItems?: T[]) => import("lit-html").TemplateResult<1> | undefined;
5
5
  export type SyncOpenFn = <T extends object>(dialog: Dialogable<T>) => void;
6
- export type AsyncOpenFn = <T extends object>(dialog: Resolvable<Dialogable<T>>) => void;
6
+ export type AsyncOpenFn = <T extends object>(dialog: Resolvable<Dialogable<T>>) => void | Promise<void>;
7
7
  export interface ActionOpts<TItem extends object, TOpen extends SyncOpenFn | AsyncOpenFn = AsyncOpenFn> {
8
8
  items: TItem[];
9
9
  open: TOpen;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/actions/index.ts"],"names":[],"mappings":"AAAA,OAAO,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAQ,OAAO,EAAE,MAAM,UAAU,CAAC;AAIzC,eAAO,MAAM,WAAW,GAAI,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE,kBAAiB,CAAC,EAAU,qDASrE,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;AAC3E,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,SAAS,MAAM,EAC1C,MAAM,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAC7B,IAAI,CAAC;AAEV,MAAM,WAAW,UAAU,CAC1B,KAAK,SAAS,MAAM,EACpB,KAAK,SAAS,UAAU,GAAG,WAAW,GAAG,WAAW;IAEpD,KAAK,EAAE,KAAK,EAAE,CAAC;IACf,IAAI,EAAE,KAAK,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU,CAAC,KAAK,SAAS,MAAM;IAC/C,KAAK,EAAE,KAAK,EAAE,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,MAAM,CAAC,KAAK,SAAS,MAAM,EAAE,OAAO,SAAS,MAAM,GAAG,MAAM;IAC5E,KAAK,EAAE,MAAM,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,CACR,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAAC,KACtE,OAAO,CAAC;IACb,MAAM,EAAE,CACP,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,KAC3D,UAAU,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;CACxD;AAED,eAAO,MAAM,aAAa,GACzB,KAAK,SAAS,MAAM,EACpB,OAAO,SAAS,MAAM,GAAG,MAAM,EAC/B,KAAK,SAAS,UAAU,GAAG,WAAW,GAAG,WAAW,EAEpD,MAAM,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,0DAevD,CAAC;AAEF,eAAO,MAAM,MAAM,GAAI,KAAK,SAAS,MAAM,EAAE,OAAO,SAAS,MAAM,EAClE,QAAQ,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,2BACpB,CAAC;AAEZ,eAAO,MAAM,aAAa,GAExB,KAAK,SAAS,MAAM,EACpB,OAAO,SAAS,MAAM,GAAG,MAAM,EAC/B,KAAK,SAAS,UAAU,GAAG,WAAW,GAAG,WAAW,EAEpD,MAAM,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,MAE9B,SAAS,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,cAK/B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/actions/index.ts"],"names":[],"mappings":"AAAA,OAAO,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEnE,OAAO,EAAQ,OAAO,EAAE,MAAM,UAAU,CAAC;AAIzC,eAAO,MAAM,WAAW,GAAI,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE,kBAAiB,CAAC,EAAU,qDASrE,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;AAC3E,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,SAAS,MAAM,EAC1C,MAAM,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAC7B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B,MAAM,WAAW,UAAU,CAC1B,KAAK,SAAS,MAAM,EACpB,KAAK,SAAS,UAAU,GAAG,WAAW,GAAG,WAAW;IAEpD,KAAK,EAAE,KAAK,EAAE,CAAC;IACf,IAAI,EAAE,KAAK,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU,CAAC,KAAK,SAAS,MAAM;IAC/C,KAAK,EAAE,KAAK,EAAE,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,MAAM,CAAC,KAAK,SAAS,MAAM,EAAE,OAAO,SAAS,MAAM,GAAG,MAAM;IAC5E,KAAK,EAAE,MAAM,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,CACR,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAAC,KACtE,OAAO,CAAC;IACb,MAAM,EAAE,CACP,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,KAC3D,UAAU,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;CACxD;AAED,eAAO,MAAM,aAAa,GACzB,KAAK,SAAS,MAAM,EACpB,OAAO,SAAS,MAAM,GAAG,MAAM,EAC/B,KAAK,SAAS,UAAU,GAAG,WAAW,GAAG,WAAW,EAEpD,MAAM,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,0DAmCvD,CAAC;AAEF,eAAO,MAAM,MAAM,GAAI,KAAK,SAAS,MAAM,EAAE,OAAO,SAAS,MAAM,EAClE,QAAQ,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,2BACpB,CAAC;AAEZ,eAAO,MAAM,aAAa,GAExB,KAAK,SAAS,MAAM,EACpB,OAAO,SAAS,MAAM,GAAG,MAAM,EAC/B,KAAK,SAAS,UAAU,GAAG,WAAW,GAAG,WAAW,EAEpD,MAAM,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,MAE9B,SAAS,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,cAK/B,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import '@neovici/cosmoz-button';
2
+ import { t } from 'i18next';
2
3
  import { html, nothing } from 'lit-html';
3
4
  import { ifDefined } from 'lit-html/directives/if-defined.js';
4
5
  import { when } from 'lit-html/directives/when.js';
@@ -13,9 +14,30 @@ export const defaultButton = (opts) => {
13
14
  slot="${ifDefined(slot)}"
14
15
  title="${title}"
15
16
  data-priority="${ifDefined(opts.priority)}"
16
- @click=${() => open(dialog({ ...opts, items: applicableItems, title }))}
17
+ @click=${async (event) => {
18
+ const button = event.currentTarget;
19
+ if (button.disabled)
20
+ return;
21
+ const progress = button.querySelector('[data-action-progress]');
22
+ button.disabled = true;
23
+ button.setAttribute('aria-busy', 'true');
24
+ if (progress)
25
+ progress.hidden = false;
26
+ try {
27
+ await open(dialog({ ...opts, items: applicableItems, title }));
28
+ }
29
+ finally {
30
+ button.disabled = false;
31
+ button.removeAttribute('aria-busy');
32
+ if (progress)
33
+ progress.hidden = true;
34
+ }
35
+ }}
17
36
  >
18
37
  ${title} ${actionCount(items, applicableItems)}
38
+ <span slot="suffix" data-action-progress hidden role="status"
39
+ >${t('Working...')}</span
40
+ >
19
41
  </cosmoz-button>`;
20
42
  };
21
43
  export const action = (action) => action;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../src/actions/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,42 @@
1
+ import { render } from 'lit-html';
2
+ import { afterEach, describe, expect, it, vi } from 'vitest';
3
+ import { defaultButton } from './index';
4
+ vi.mock('@neovici/cosmoz-button', () => ({}));
5
+ vi.mock('i18next', () => ({ t: (key) => key }));
6
+ afterEach(() => {
7
+ document.body.replaceChildren();
8
+ });
9
+ describe('default action button', () => {
10
+ it('shows progress and deduplicates clicks through resolution and saving', async () => {
11
+ const container = document.createElement('div');
12
+ document.body.append(container);
13
+ let finish;
14
+ const dialog = vi.fn(() => ({
15
+ heading: 'Approve',
16
+ initial: {},
17
+ fields: [],
18
+ }));
19
+ const open = vi.fn(() => new Promise((resolve) => (finish = resolve)));
20
+ render(defaultButton({
21
+ items: [{ id: 'invoice' }],
22
+ title: () => 'Approve',
23
+ dialog,
24
+ open,
25
+ }), container);
26
+ const button = container.querySelector('cosmoz-button');
27
+ const progress = button.querySelector('[data-action-progress]');
28
+ expect(progress.hidden).toBe(true);
29
+ button.click();
30
+ button.click();
31
+ expect(open).toHaveBeenCalledTimes(1);
32
+ expect(dialog).toHaveBeenCalledTimes(1);
33
+ expect(button.disabled).toBe(true);
34
+ expect(button.getAttribute('aria-busy')).toBe('true');
35
+ expect(progress.hidden).toBe(false);
36
+ finish();
37
+ await Promise.resolve();
38
+ expect(button.disabled).toBe(false);
39
+ expect(button.hasAttribute('aria-busy')).toBe(false);
40
+ expect(progress.hidden).toBe(true);
41
+ });
42
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"use-list-sse.d.ts","sourceRoot":"","sources":["../../src/queue/use-list-sse.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,GAAG,EAAE,MAAM,8BAA8B,CAAC;AAInD,MAAM,WAAW,oBAAoB;IACpC,kBAAkB,EAAE,WAAW,CAAC;QAC/B,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,OAAO,CAAC;QACd,MAAM,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;KAC7B,CAAC,CAAC;IACH,kBAAkB,EAAE,WAAW,CAAC;QAC/B,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,OAAO,CAAC;QACd,MAAM,EAAE,MAAM,IAAI,CAAC;KACnB,CAAC,CAAC;CACH;AAED,UAAU,IAAK,SAAQ,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;CACX;AAED,UAAU,SAAS,CAAC,CAAC,SAAS,GAAG,CAAE,SAAQ,WAAW;IACrD,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;IACX,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;IACvD,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC;CAC3B;AAED,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;IACnB,CAAC,MAAM,EAAE,CAAC,GAAG;QAAE,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,WAAW,CAAC,CAAC,EAAE,GAAG;QAAE,KAAK,EAAE,CAAC,EAAE,CAAA;KAAE,CAAC,CAAC;CACzE;AA4DD,UAAU,IAAI,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,SAAS,GAAG;IAC3C,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,EAAE,CAAC,CAAC;IACV,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AA6BD,UAAU,IAAI,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,SAAS,GAAG,CAC3C,SAAQ,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;CACzB;AAED,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,IAAI,EAAE,CAAC,SAAS,GAAG,EAAE,qBAGvD,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,SAsCZ,CAAC"}
1
+ {"version":3,"file":"use-list-sse.d.ts","sourceRoot":"","sources":["../../src/queue/use-list-sse.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,8BAA8B,CAAC;AAInD,MAAM,WAAW,oBAAoB;IACpC,kBAAkB,EAAE,WAAW,CAAC;QAC/B,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,OAAO,CAAC;QACd,MAAM,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;KAC7B,CAAC,CAAC;IACH,kBAAkB,EAAE,WAAW,CAAC;QAC/B,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,OAAO,CAAC;QACd,MAAM,EAAE,MAAM,IAAI,CAAC;KACnB,CAAC,CAAC;CACH;AAED,UAAU,IAAK,SAAQ,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;CACX;AAED,UAAU,SAAS,CAAC,CAAC,SAAS,GAAG,CAAE,SAAQ,WAAW;IACrD,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;IACX,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;IACvD,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC;CAC3B;AAED,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;IACnB,CAAC,MAAM,EAAE,CAAC,GAAG;QAAE,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,WAAW,CAAC,CAAC,EAAE,GAAG;QAAE,KAAK,EAAE,CAAC,EAAE,CAAA;KAAE,CAAC,CAAC;CACzE;AA4DD,UAAU,IAAI,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,SAAS,GAAG;IAC3C,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,EAAE,CAAC,CAAC;IACV,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AA+BD,UAAU,IAAI,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,SAAS,GAAG,CAAE,SAAQ,IAAI,CACzD,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EACV,WAAW,CACX;IACA,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;CACzB;AAED,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,IAAI,EAAE,CAAC,SAAS,GAAG,EAAE,qBAGvD,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,SAuCZ,CAAC"}
@@ -1,7 +1,6 @@
1
- import { useMemo, useEffect } from '@pionjs/pion';
2
1
  import { useHost } from '@neovici/cosmoz-utils/hooks/use-host';
3
2
  import { useMeta } from '@neovici/cosmoz-utils/hooks/use-meta';
4
- import { debounce$ } from '@neovici/cosmoz-utils/promise';
3
+ import { useEffect } from '@pionjs/pion';
5
4
  import { get } from '../util/path';
6
5
  const process$ = ({ updates, objectIds, omnitable, host, idProperty, }) => {
7
6
  for (const id of objectIds) {
@@ -59,27 +58,35 @@ const check$$ = async (opts) => {
59
58
  if (objectIds.length === 0)
60
59
  return;
61
60
  const res = await list$({ ...params, objectIds });
62
- const updates = Array.isArray(res) ? res : res.items ?? [];
61
+ if (opts.signal.aborted)
62
+ return;
63
+ const updates = Array.isArray(res) ? res : (res.items ?? []);
63
64
  return process$({ ...opts, idProperty, objectIds, updates });
64
65
  };
65
66
  export const useListSSE = ({ entity, ...thru }) => {
66
- const host = useHost(), ids = useMemo(() => new Set(), []), meta = useMeta(thru), check$ = useMemo(() => debounce$(() => check$$({
67
- ...meta,
68
- host,
69
- ids,
70
- omnitable: meta.omnitable ??
71
- host.shadowRoot.querySelector('cosmoz-omnitable'),
72
- }), 600), []);
67
+ const host = useHost(), meta = useMeta(thru);
73
68
  useEffect(() => {
69
+ const controller = new AbortController(), ids = new Set();
70
+ let timer;
74
71
  const ev = `cosmoz-${entity}-updated`, evc = `cosmoz-${entity}-check`, onUpdate = (e) => {
75
72
  ids.add(e.detail.id);
76
- check$();
73
+ clearTimeout(timer);
74
+ timer = setTimeout(() => check$$({
75
+ ...meta,
76
+ host,
77
+ ids,
78
+ signal: controller.signal,
79
+ omnitable: meta.omnitable ??
80
+ host.shadowRoot.querySelector('cosmoz-omnitable'),
81
+ }), 600);
77
82
  };
78
83
  window.addEventListener(ev, onUpdate);
79
84
  host.addEventListener(evc, onUpdate);
80
85
  return () => {
86
+ clearTimeout(timer);
87
+ controller.abort();
81
88
  window.removeEventListener(ev, onUpdate);
82
89
  host.removeEventListener(evc, onUpdate);
83
90
  };
84
- }, [entity, check$]);
91
+ }, [entity]);
85
92
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neovici/cosmoz-queue",
3
- "version": "3.9.1",
3
+ "version": "3.9.3",
4
4
  "description": "A reusable queue component for master-detail views with list, split, and queue modes",
5
5
  "keywords": [
6
6
  "web-components",