@ynput/ayon-frontend-shared 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/dist/ContextMenu.es.js +34 -16
  2. package/dist/DetailsPanel.es.js +292 -298
  3. package/dist/Feed.es.js +179 -50
  4. package/dist/ListTable.es.js +32 -35
  5. package/dist/NewEntity.es.js +1256 -11
  6. package/dist/ProjectTreeTable.es.js +4451 -2965
  7. package/dist/SimpleTable.es.js +8 -7
  8. package/dist/Slicer.es.js +451 -147
  9. package/dist/Views.es.js +918 -310
  10. package/dist/chunks/Actions.es.js +9 -4
  11. package/dist/chunks/ColumnDropIndicator.es.js +174 -328
  12. package/dist/chunks/ColumnDropIndicator.styled.es.js +281 -0
  13. package/dist/chunks/ColumnHeaderMenuUI.es.js +52 -0
  14. package/dist/chunks/ContextMenuContextInstance.es.js +12 -0
  15. package/dist/chunks/DeleteEntitiesConfirmDialog.es.js +229 -0
  16. package/dist/chunks/DeleteEntitiesContextInstance.es.js +827 -0
  17. package/dist/chunks/EmptyPlaceholder.es.js +4 -4
  18. package/dist/chunks/EntityPath.es.js +58 -53
  19. package/dist/chunks/EntityPickerDialog.es.js +24 -20
  20. package/dist/chunks/EntityTooltip.es.js +20 -13
  21. package/dist/chunks/EntityUpdatesContext.es.js +38 -96
  22. package/dist/chunks/Feed.es.js +1495 -1439
  23. package/dist/chunks/FilterErrorActions.es.js +25 -229
  24. package/dist/chunks/Menu.es.js +21 -17
  25. package/dist/chunks/MenuContext.es.js +14 -65
  26. package/dist/chunks/MenuItem.es.js +34 -24
  27. package/dist/chunks/MetaWidget.es.js +2835 -4301
  28. package/dist/chunks/NewEntityContextInstance.es.js +11 -0
  29. package/dist/chunks/PlayableIcon.es.js +1532 -1594
  30. package/dist/chunks/ProjectContext.es.js +102 -66
  31. package/dist/chunks/RepresentationsList.es.js +1 -1
  32. package/dist/chunks/ReviewablesSelector.es.js +457 -458
  33. package/dist/chunks/SimpleForm.es.js +9 -9
  34. package/dist/chunks/SimpleTable.es.js +15 -13
  35. package/dist/chunks/Slicer.es.js +163 -154
  36. package/dist/chunks/TableSettingsFallback.es.js +25 -13
  37. package/dist/chunks/ThumbnailSimple.es.js +150 -261
  38. package/dist/chunks/VersionUploadContextInstance.es.js +12 -0
  39. package/dist/chunks/VideoPlayer.es.js +24 -28
  40. package/dist/chunks/Watchers.es.js +384 -389
  41. package/dist/chunks/entityDefinitions.es.js +2 -350
  42. package/dist/chunks/extractVersionFromFilename.es.js +28 -0
  43. package/dist/chunks/getBundleMode.es.js +61 -16
  44. package/dist/chunks/getUris.es.js +737 -712
  45. package/dist/chunks/searchTerms.es.js +57 -56
  46. package/dist/chunks/useAttributeEnums.es.js +4 -4
  47. package/dist/chunks/useCreateContextMenu.es.js +66 -90
  48. package/dist/chunks/useHierarchySelection.es.js +24 -0
  49. package/dist/chunks/useLoadModule.es.js +74 -0
  50. package/dist/chunks/useQueryArgumentChangeLoading.es.js +11 -0
  51. package/dist/chunks/versionUploadHelpers.es.js +16 -42
  52. package/dist/chunks/viewUpdateHelper.es.js +67 -50
  53. package/dist/components.es.js +1425 -999
  54. package/dist/context.es.js +791 -80
  55. package/dist/hooks.es.js +115 -120
  56. package/dist/index.es.js +19 -23
  57. package/dist/types/Actions.d.ts +7 -7
  58. package/dist/types/ContextMenu.d.ts +11 -8
  59. package/dist/types/DetailsPanel.d.ts +102 -9
  60. package/dist/types/EntityPickerDialog.d.ts +7 -7
  61. package/dist/types/Feed.d.ts +11 -8
  62. package/dist/types/ListTable.d.ts +7 -7
  63. package/dist/types/NewEntity.d.ts +16 -10
  64. package/dist/types/ProjectTreeTable.d.ts +22 -115
  65. package/dist/types/RepresentationsList.d.ts +7 -7
  66. package/dist/types/SimpleTable.d.ts +11 -8
  67. package/dist/types/Slicer.d.ts +10 -7
  68. package/dist/types/Views.d.ts +10 -7
  69. package/dist/types/api.d.ts +132 -120
  70. package/dist/types/components.d.ts +13 -8
  71. package/dist/types/context.d.ts +56 -16
  72. package/dist/types/hooks.d.ts +7 -7
  73. package/dist/types/index.d.ts +7 -7
  74. package/dist/types/util.d.ts +12 -7
  75. package/dist/util.es.js +72 -71
  76. package/package.json +1 -1
  77. package/dist/chunks/DeleteEntitiesContext.es.js +0 -748
  78. package/dist/chunks/DetailsPanelContext.es.js +0 -155
  79. package/dist/chunks/GlobalContext.es.js +0 -52
  80. package/dist/chunks/NewEntityContext.es.js +0 -1242
  81. package/dist/chunks/ProjectFoldersContext.es.js +0 -134
  82. package/dist/chunks/ProjectFoldersContextInstance.es.js +0 -7
  83. package/dist/chunks/VersionUploadContext.es.js +0 -232
  84. package/dist/chunks/ViewsContext.es.js +0 -878
  85. package/dist/chunks/uriUtils.es.js +0 -48
  86. package/dist/chunks/useColumnDragRestriction.es.js +0 -158
  87. package/dist/chunks/useLocalStorage.es.js +0 -355
  88. package/dist/chunks/useSessionStorage.es.js +0 -61
  89. /package/dist/{useCreateContextMenu.css → ContextMenuContextInstance.css} +0 -0
@@ -1,748 +0,0 @@
1
- import X, { useState as x, useMemo as U, createContext as $, useContext as F, useCallback as M, useEffect as A, useRef as G } from "react";
2
- import { jsxs as I, jsx as c, Fragment as Z } from "react/jsx-runtime";
3
- import { a as fe } from "./useCreateContextMenu.es.js";
4
- import { v4 as Q } from "uuid";
5
- import { createPortal as he } from "react-dom";
6
- import { Dialog as me } from "primereact/dialog";
7
- import { Dialog as ge, InputText as re, Button as z } from "@ynput/ayon-react-components";
8
- import v from "styled-components";
9
- import { c2 as we, cL as ye, dl as Ce, cI as xe } from "./getUris.es.js";
10
- import { u as ve } from "./GlobalContext.es.js";
11
- import { toast as O } from "react-toastify";
12
- import { debounce as ee, isEqual as be } from "lodash";
13
- import "primereact/confirmdialog";
14
- import { bf as _, a as Pe, ay as Ee, be as Se } from "./searchTerms.es.js";
15
- import Te, { ReadyState as ke } from "react-use-websocket";
16
- import { p as j } from "./pluralize.es.js";
17
- const J = [
18
- "folder",
19
- "task",
20
- "product",
21
- "version",
22
- "representation",
23
- "workfile"
24
- ], te = 1, De = (e) => e.length <= 1 ? e.join("") : `${e.slice(0, -1).join(", ")} and ${e[e.length - 1]}`, Ie = (e) => {
25
- if (e.length === 1) {
26
- const t = e[0];
27
- return `${t.entityType} "${t.label || t.name || t.id}"`;
28
- }
29
- const s = {};
30
- for (const t of e) s[t.entityType] = (s[t.entityType] || 0) + 1;
31
- const i = J.filter((t) => s[t] > 0).map(
32
- (t) => j(s[t], t)
33
- );
34
- return De(i);
35
- }, Re = (e, s) => {
36
- const i = {}, t = (o, n) => {
37
- n > 0 && (i[o] = (i[o] || 0) + n);
38
- };
39
- for (const o of e) t(o.entityType, 1);
40
- for (const o of s)
41
- t("folder", o.totalFolderCount), t("task", o.totalTaskCount), t("product", o.totalProductCount), t("version", o.totalVersionCount);
42
- return i;
43
- }, $e = (e) => J.reduce((s, i) => s + (e[i] || 0), 0), Y = 8, Le = (e, s) => {
44
- if (e.length === 0) return [];
45
- const i = new Map(s.map((n) => [n.id, n])), t = e.length > 1, o = [];
46
- for (const n of e) {
47
- const r = i.get(n.id), y = n.label || n.name || n.id, m = t ? `"${y}" contains ` : "Contains ";
48
- if (r && (r.totalFolderCount > 0 || r.totalTaskCount > 0 || r.totalProductCount > 0 || r.totalVersionCount > 0)) {
49
- const u = [];
50
- r.totalFolderCount > 0 && u.push(j(r.totalFolderCount, "child folder")), r.totalTaskCount > 0 && u.push(j(r.totalTaskCount, "task")), r.totalProductCount > 0 && u.push(j(r.totalProductCount, "product")), r.totalVersionCount > 0 && u.push(j(r.totalVersionCount, "version")), o.push(`${m}${u.join(", ")}`);
51
- } else
52
- n.hasChildren && o.push(`${m}child folders`), n.taskNames && n.taskNames.length > 0 && o.push(`${m}${j(n.taskNames.length, "task")}`);
53
- }
54
- return o.length > Y ? [
55
- ...o.slice(0, Y),
56
- `…and ${o.length - Y} more`
57
- ] : o;
58
- }, Oe = v.div`
59
- min-width: 350px;
60
- `, Fe = v.div`
61
- margin-top: 12px;
62
- min-height: 60px;
63
- min-width: 350px;
64
- `, Ne = v.p`
65
- font-weight: 600;
66
- margin-bottom: 4px;
67
- `, Ae = v.p`
68
- margin-top: 12px;
69
- font-weight: 600;
70
- color: var(--md-sys-color-error);
71
- `, je = ({
72
- entityLabel: e,
73
- childrenDetails: s,
74
- totalLine: i,
75
- message: t
76
- }) => /* @__PURE__ */ I(Oe, { children: [
77
- /* @__PURE__ */ c("p", { children: t || `Are you sure you want to delete ${e}? This action cannot be undone.` }),
78
- s.length > 0 && /* @__PURE__ */ I(Fe, { children: [
79
- /* @__PURE__ */ c(Ne, { children: "The following will also be affected:" }),
80
- s.map((o, n) => /* @__PURE__ */ c("p", { children: o }, n))
81
- ] }),
82
- i && /* @__PURE__ */ c(Ae, { children: i })
83
- ] }), Me = v(ge)`
84
- max-height: min(600px, 90vh);
85
- `, We = v.div`
86
- display: flex;
87
- flex-direction: column;
88
- width: 100%;
89
- `, oe = v.label`
90
- margin: 2px 0 14px 0;
91
- `, _e = v.div`
92
- display: flex;
93
- padding-top: 14px;
94
- gap: 8px;
95
- justify-content: flex-end;
96
- `, Ue = v.div`
97
- display: flex;
98
- flex-direction: column;
99
- gap: 8px;
100
- max-height: 30vh;
101
- overflow-y: auto;
102
- /* scroll container clips the inputs' 2px focus outline — inset it, then pull back to keep alignment */
103
- padding: 4px;
104
- margin: -4px;
105
- `, qe = v.label`
106
- display: flex;
107
- align-items: center;
108
- justify-content: space-between;
109
- gap: 12px;
110
- `, Ve = v(re)`
111
- width: 180px;
112
- `, ze = v(re)`
113
- width: 100%;
114
- /* room for the 2px focus outline */
115
- margin: 2px 0;
116
- `, Be = (e, s) => {
117
- const i = (e ?? "").trim();
118
- return i !== "" && Number(i) === s;
119
- }, ne = ({
120
- payload: e,
121
- onConfirm: s,
122
- onCancel: i
123
- }) => {
124
- const {
125
- entityLabel: t,
126
- childrenDetails: o,
127
- expectedCounts: n,
128
- expectedName: r,
129
- deleteLabel: y = "Delete forever",
130
- message: m
131
- } = e, [C, u] = x(""), [p, a] = x({}), g = U(
132
- () => J.filter((d) => (n[d] || 0) > 0),
133
- [n]
134
- ), f = U(() => $e(n), [n]), b = f > te, h = !!r && !b, S = b ? g.every((d) => Be(p[d], n[d])) : h ? C.trim() === r : !0, T = (d) => {
135
- d.key === "Enter" && S && (d.preventDefault(), s());
136
- };
137
- return /* @__PURE__ */ c(
138
- Me,
139
- {
140
- size: "md",
141
- isOpen: !0,
142
- header: `${y} ${t}`,
143
- onClose: i,
144
- footer: (
145
- // keydown lives here, not on the dialog — dialog spreads rest props over its own
146
- // handler and would lose escape-to-close
147
- /* @__PURE__ */ I(We, { onKeyDown: T, children: [
148
- h && /* @__PURE__ */ I(Z, { children: [
149
- /* @__PURE__ */ I(oe, { htmlFor: "delete-confirm-name-input", children: [
150
- "To confirm delete action, type '",
151
- r,
152
- "' in the box below"
153
- ] }),
154
- /* @__PURE__ */ c(
155
- ze,
156
- {
157
- id: "delete-confirm-name-input",
158
- "data-testid": "delete-confirm-name-input",
159
- autoFocus: !0,
160
- value: C,
161
- placeholder: r,
162
- onChange: (d) => u(d.target.value)
163
- }
164
- )
165
- ] }),
166
- b && /* @__PURE__ */ I(Z, { children: [
167
- /* @__PURE__ */ c(oe, { as: "p", children: "To confirm, type how many of each will be deleted, children included" }),
168
- /* @__PURE__ */ c(Ue, { children: g.map((d, P) => /* @__PURE__ */ I(qe, { children: [
169
- /* @__PURE__ */ c("span", { children: `${d[0].toUpperCase()}${d.slice(1)}s - ${n[d]}` }),
170
- /* @__PURE__ */ c(
171
- Ve,
172
- {
173
- "data-testid": `delete-confirm-count-${d}`,
174
- autoFocus: P === 0,
175
- inputMode: "numeric",
176
- value: p[d] ?? "",
177
- placeholder: `Number of ${d}s`,
178
- onChange: (k) => a((N) => ({ ...N, [d]: k.target.value }))
179
- }
180
- )
181
- ] }, d)) })
182
- ] }),
183
- /* @__PURE__ */ I(_e, { children: [
184
- /* @__PURE__ */ c(z, { label: "Cancel", onClick: i }),
185
- /* @__PURE__ */ c(
186
- z,
187
- {
188
- "data-testid": "delete-confirm-submit",
189
- variant: "danger",
190
- label: y,
191
- onClick: s,
192
- disabled: !S
193
- }
194
- )
195
- ] })
196
- ] })
197
- ),
198
- children: /* @__PURE__ */ c(
199
- je,
200
- {
201
- entityLabel: t,
202
- childrenDetails: o,
203
- message: m,
204
- totalLine: f > te ? (
205
- // versions cascaded from products are not countable, so the total is a floor
206
- `This deletes ${(n.product || 0) > 0 ? "at least " : ""}${f} entities in total.`
207
- ) : void 0
208
- }
209
- )
210
- }
211
- );
212
- }, wt = $(
213
- void 0
214
- ), ie = $({}), yt = ({
215
- children: e,
216
- thumbnailInputRef: s,
217
- versionsInputRef: i,
218
- canUploadVersion: t = !1
219
- }) => {
220
- const [, o] = x(!1), [n] = fe(), r = () => o(!1), y = () => {
221
- s?.current && (s.current.click(), o(!0));
222
- }, m = () => {
223
- i?.current && (i.current.click(), o(!0));
224
- }, C = (u) => {
225
- const p = [
226
- {
227
- label: "Upload thumbnail",
228
- icon: "add_photo_alternate",
229
- command: y
230
- },
231
- ...t ? [
232
- {
233
- label: "Upload version",
234
- icon: "upload",
235
- command: m
236
- }
237
- ] : []
238
- ];
239
- n(u, p);
240
- };
241
- return /* @__PURE__ */ c(
242
- ie.Provider,
243
- {
244
- value: {
245
- resetFileUploadState: r,
246
- triggerThumbnailUpload: y,
247
- triggerVersionUpload: m,
248
- canUploadVersion: t,
249
- onContextMenu: C
250
- },
251
- children: e
252
- }
253
- );
254
- }, Ct = () => {
255
- const e = ie;
256
- if (!e)
257
- throw new Error("useThumbnailUploadContext must be used within a ThumbnailUploadProvider");
258
- return e;
259
- }, le = $(void 0), xt = ({ children: e }) => {
260
- const [s, i] = x(!1), [t, o] = x(null), [n, r] = x(null), y = () => {
261
- i(!0), o(null);
262
- }, m = () => {
263
- i(!1), o(null);
264
- }, C = (a, g = null) => {
265
- i((f) => !f), a && !s ? (o(a), r(g)) : (o(null), r(null));
266
- }, u = (a, g = null) => {
267
- o(a), r(g);
268
- }, p = () => {
269
- o(null), r(null);
270
- };
271
- return /* @__PURE__ */ c(
272
- le.Provider,
273
- {
274
- value: {
275
- isPanelOpen: s,
276
- selectedSetting: t,
277
- highlightedSetting: n,
278
- setHighlightedSetting: r,
279
- openPanel: y,
280
- closePanel: m,
281
- togglePanel: C,
282
- selectSetting: u,
283
- backToMainMenu: p
284
- },
285
- children: e
286
- }
287
- );
288
- }, vt = () => {
289
- const e = F(le);
290
- if (e === void 0)
291
- throw new Error("useSettingsPanel must be used within a SettingsPanelProvider");
292
- return e;
293
- }, ae = $(void 0);
294
- function bt({ children: e }) {
295
- const s = window.location.protocol === "https:" || window.location.hostname === "localhost", i = "documentPictureInPicture" in window && s, [t, o] = x(null), [n, r] = x(null), y = M(() => {
296
- r(null), t != null && (t.close(), o(null));
297
- }, [t, n]), m = M(
298
- async (u, p) => {
299
- if (!i) {
300
- r(Q());
301
- return;
302
- }
303
- if (t != null) {
304
- console.log("pipWindow is already open"), r(Q());
305
- return;
306
- }
307
- const a = await window.documentPictureInPicture.requestWindow({
308
- width: u,
309
- height: p
310
- });
311
- a.addEventListener("pagehide", () => {
312
- o(null), r(null);
313
- }), o(a), r(Q());
314
- },
315
- [t, n]
316
- );
317
- A(() => {
318
- [...document.styleSheets].forEach((u) => {
319
- try {
320
- const p = [...u.cssRules].map((f) => f.cssText).join(""), a = document.createElement("style");
321
- a.textContent = p, t?.document.head.appendChild(a);
322
- const g = document.createElement("style");
323
- g.textContent = `
324
- html, body, .pipRoot {
325
- height: 100%;
326
- margin: 0;
327
- padding: 0;
328
- overflow: hidden;
329
- }`, t?.document.head.appendChild(g);
330
- } catch {
331
- const a = document.createElement("link");
332
- if (u.href == null)
333
- return;
334
- a.rel = "stylesheet", a.type = u.type, a.media = u.media.toString(), a.href = u.href, t?.document.head.appendChild(a);
335
- }
336
- });
337
- }, [t]);
338
- const C = U(() => ({
339
- isSupported: i,
340
- pipWindow: t,
341
- pipId: n,
342
- requestPipWindow: m,
343
- closePipWindow: y
344
- }), [y, i, t, m]);
345
- return /* @__PURE__ */ c(ae.Provider, { value: C, children: e });
346
- }
347
- function He() {
348
- const e = F(ae);
349
- if (e === void 0)
350
- throw new Error("usePiPWindow must be used within a PiPContext");
351
- return e;
352
- }
353
- function Ge({ pipWindow: e, children: s }) {
354
- return he(s, e.document.body);
355
- }
356
- const Qe = v(me)`
357
- width: 25vw;
358
- height: 70vh;
359
- border: solid 1px var(--md-sys-color-outline-variant);
360
- border-radius: 10px;
361
- overflow: hidden;
362
- box-shadow: 0 0 1px 1px #000, 0 11px 15px -7px #0003, 0 24px 38px 3px #00000024,
363
- 0 9px 46px 8px #0000001f;
364
- &:hover {
365
- .close {
366
- opacity: 1;
367
- }
368
- }
369
- `, Ye = v(z)`
370
- width: 26px;
371
- height: 26px;
372
- margin-left: auto;
373
-
374
- .icon {
375
- font-size: 15px;
376
- font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 200, 'opsz' 20;
377
- }
378
- background-color: unset !important;
379
- opacity: 0;
380
- border-radius: 100%;
381
- transition: opacity 400ms, background-color 400ms;
382
- &:hover {
383
- background-color: #3d3e40;
384
- }
385
- `, Pt = ({ children: e }) => {
386
- const { pipWindow: s, pipId: i, isSupported: t, closePipWindow: o } = He(), n = i && X.isValidElement(e) ? X.cloneElement(e, { id: i }) : e;
387
- return !t && i ? /* @__PURE__ */ c(
388
- Qe,
389
- {
390
- header: /* @__PURE__ */ c(Ye, { icon: "close", className: "close", onClick: o }),
391
- headerStyle: {
392
- padding: 4,
393
- backgroundColor: "#202124",
394
- border: "none",
395
- height: 33
396
- },
397
- contentStyle: { overflow: "hidden", height: "revert-layer", padding: 8, border: "none" },
398
- maskStyle: { pointerEvents: "none", userSelect: "none", backgroundColor: "unset" },
399
- visible: !0,
400
- closeOnEscape: !1,
401
- pt: {
402
- closeButton: {
403
- style: { display: "none" }
404
- },
405
- footer: {
406
- style: { padding: 0, border: "none" }
407
- }
408
- },
409
- onHide: o,
410
- position: "right",
411
- children: n
412
- }
413
- ) : s && /* @__PURE__ */ c(Ge, { pipWindow: s, children: /* @__PURE__ */ c("div", { className: "pipRoot", children: n }) });
414
- }, ce = $(void 0), Et = ({
415
- children: e,
416
- projectName: s,
417
- // utils
418
- toast: i,
419
- ...t
420
- }) => {
421
- const { data: o } = we(
422
- { projectName: s },
423
- { skip: !s }
424
- ), { user: n } = ve();
425
- return /* @__PURE__ */ c(
426
- ce.Provider,
427
- {
428
- value: {
429
- ...t,
430
- projectName: s,
431
- project: o,
432
- user: n,
433
- toast: i
434
- },
435
- children: e
436
- }
437
- );
438
- }, St = () => {
439
- const e = F(ce);
440
- if (!e)
441
- throw new Error("useAddonProjectContext must be used within a AddonProjectContext");
442
- return e;
443
- }, de = $(void 0), Tt = ({ children: e, ...s }) => /* @__PURE__ */ c(de.Provider, { value: { ...s }, children: e }), kt = () => {
444
- const e = F(de);
445
- if (!e)
446
- throw new Error("useAddonContext must be used within a AddonContext");
447
- return e;
448
- }, Je = () => /* @__PURE__ */ I("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
449
- "Refresh to see latest changes.",
450
- /* @__PURE__ */ c(z, { onClick: () => window.location.reload(), variant: "filled", children: "Refresh" })
451
- ] }), ue = $(void 0), Ke = window.location.protocol.replace("http", "ws"), Xe = `${Ke}//${window.location.host}/ws`, Dt = ({
452
- children: e,
453
- userName: s,
454
- projectName: i,
455
- dispatch: t
456
- }) => {
457
- const [o, n] = x(!1), [r, y] = x([]), [m] = ye(), C = G(!1);
458
- A(() => {
459
- C.current = o;
460
- }, [o]);
461
- const u = {
462
- shouldReconnect: () => !s || !localStorage.getItem("accessToken") ? !1 : (m({ full: !1 }).unwrap(), !0)
463
- }, { sendMessage: p, readyState: a, getWebSocket: g } = Te(
464
- Xe,
465
- u,
466
- !!s
467
- ), f = () => {
468
- p(
469
- JSON.stringify({
470
- topic: "auth",
471
- token: localStorage.getItem("accessToken"),
472
- subscribe: r,
473
- project: i
474
- })
475
- );
476
- };
477
- A(() => {
478
- console.debug("Topics changed", r), f();
479
- }, [r, i]);
480
- const b = G(r);
481
- b.current = r;
482
- const h = U(
483
- () => ee((E) => {
484
- be(b.current, E) || (console.log("WS: Subscriptions changed"), y(E));
485
- }, 200),
486
- []
487
- );
488
- A(() => (_.setOnSubscriptionsChange((E) => h(E)), h(_.getSubscriptions("")), () => {
489
- _.setOnSubscriptionsChange(null), h.cancel();
490
- }), [h]);
491
- const [S, T] = x(!1), [d, P] = x(!1);
492
- A(() => {
493
- S && !d && (O.warning(/* @__PURE__ */ c(Je, {}), {
494
- autoClose: !1,
495
- closeButton: !1
496
- }), P(!0));
497
- }, [S, d]);
498
- const k = G({ callCount: 0, lastCall: Date.now() }), N = ee(() => {
499
- console.log("Resetting API state due to server restart"), n(!1), t(Pe.util.resetApiState());
500
- }, 1e3), q = M(
501
- (E) => {
502
- if (k.current.callCount > 1e3)
503
- return T(!0), console.log(
504
- "Overload: Over 1000 messages per second. Ignoring subsequent messages."
505
- );
506
- let l;
507
- try {
508
- l = JSON.parse(E.data);
509
- } catch (H) {
510
- console.error("Failed to parse websocket message:", H, E.data);
511
- return;
512
- }
513
- const { topic: w, sender: D, summary: R, status: L } = l || {};
514
- if (C.current && (w === "heartbeat" || w === "server.started" && L === "finished")) {
515
- console.log("Server replica booted"), N();
516
- return;
517
- }
518
- if (w === "heartbeat") return;
519
- if (w === "server.restart_requested" && (console.log("Server restart requested"), n(!0)), ["import.data"].includes(w)) {
520
- if (D !== window.senderId) return;
521
- } else if (D === window.senderId)
522
- return;
523
- const B = Date.now();
524
- B - k.current.lastCall < 1e3 ? k.current.callCount += 1 : k.current.callCount = 0, console.log("Event RX", l), k.current.lastCall = B, w === "shout" && l?.summary?.text && O.info(R.text), _.publish(w, l);
525
- },
526
- [n]
527
- );
528
- return A(() => {
529
- a === ke.OPEN && (g().onmessage = q, f(), _.publish("client.connected", {
530
- topic: "client.connected"
531
- }));
532
- }, [a, g]), /* @__PURE__ */ c(
533
- ue.Provider,
534
- {
535
- value: {
536
- getWebSocket: g,
537
- readyState: a,
538
- serverRestartingVisible: o
539
- },
540
- children: e
541
- }
542
- );
543
- }, It = () => {
544
- const e = F(ue);
545
- if (e === void 0)
546
- throw new Error("useSocketContext must be used within a SocketProvider");
547
- return e;
548
- }, Rt = $(void 0), Ze = /* @__PURE__ */ new Set([
549
- "folder",
550
- "task",
551
- "product",
552
- "version",
553
- "representation",
554
- "workfile"
555
- ]), $t = (e) => !!e && Ze.has(e), K = $(null), se = [
556
- "representation",
557
- "version",
558
- "workfile",
559
- "product",
560
- "task",
561
- "folder"
562
- ], et = "delete-folder-with-children", Lt = ({ children: e }) => {
563
- const [s] = Ce(), [i] = xe(), [t, o] = x(null), [n, r] = x(null), y = M(
564
- (p) => new Promise((a) => r({ payload: p, resolve: a })),
565
- []
566
- ), m = M(
567
- async (p, a) => {
568
- if (!p || p.length === 0) {
569
- O.error("No entities selected");
570
- return;
571
- }
572
- const g = /* @__PURE__ */ new Set(), f = p.filter((l) => !l?.id || g.has(l.id) ? !1 : (g.add(l.id), !0));
573
- if (f.length === 0) {
574
- O.error("No entities found");
575
- return;
576
- }
577
- const b = new Set(f.map((l) => l.id)), h = f.filter((l) => l.entityType === "folder" && l.parentId ? !b.has(l.parentId) : (l.entityType === "task" || l.entityType === "product") && l.folderId ? !b.has(l.folderId) : !0), S = async (l, w) => {
578
- if (l.length === 0) return;
579
- const D = /* @__PURE__ */ new Map();
580
- for (const R of l) {
581
- const L = D.get(R.projectName) || [];
582
- L.push(R), D.set(R.projectName, L);
583
- }
584
- await Promise.all(
585
- Array.from(D.entries()).map(([R, L]) => {
586
- const H = [...L].sort(
587
- (V, pe) => se.indexOf(V.entityType) - se.indexOf(pe.entityType)
588
- ).map((V) => ({
589
- type: "delete",
590
- entityType: V.entityType,
591
- entityId: V.id,
592
- force: w
593
- }));
594
- return s({
595
- operationsRequestModel: { operations: H },
596
- projectName: R
597
- }).unwrap();
598
- })
599
- );
600
- }, T = async () => {
601
- try {
602
- await S(h, !1), a?.onSuccess?.();
603
- } catch (l) {
604
- throw { message: Se(l) || "Failed to delete entities", ...l };
605
- }
606
- }, d = () => S(
607
- h.filter((l) => l.entityType === "folder" || l.entityType === "task"),
608
- !0
609
- ), P = h.filter((l) => l.entityType === "folder");
610
- let k = [];
611
- if (P.length > 0) {
612
- const l = /* @__PURE__ */ new Map();
613
- for (const w of P) {
614
- const D = l.get(w.projectName) || [];
615
- D.push(w), l.set(w.projectName, D);
616
- }
617
- try {
618
- k = (await Promise.all(
619
- Array.from(l.entries()).map(
620
- ([D, R]) => i({
621
- projectName: D,
622
- folderIds: R.map((L) => L.id)
623
- }).unwrap()
624
- )
625
- )).flat();
626
- } catch (w) {
627
- console.warn("Failed to fetch folder delete info, falling back to local data", w);
628
- }
629
- }
630
- const N = Le(P, k), q = h.filter((l) => l.entityType === "product").length;
631
- q > 0 && N.push(
632
- q > 1 ? "Deleting these products also deletes all their versions" : "Deleting this product also deletes all its versions"
633
- );
634
- const E = Ie(h), W = h.length === 1 ? h[0] : void 0;
635
- o({
636
- payload: {
637
- entityLabel: E,
638
- childrenDetails: N,
639
- expectedCounts: Re(h, k),
640
- expectedName: W && (W.label || W.name || W.id)
641
- },
642
- accept: T,
643
- recover: async (l) => Ee(l).includes(et) ? await y({
644
- entityLabel: E,
645
- message: `Are you really sure you want to delete ${E} and all of its dependencies? This cannot be undone. (NOT RECOMMENDED)`,
646
- childrenDetails: [],
647
- expectedCounts: {},
648
- deleteLabel: "Force delete"
649
- }) ? (await d(), a?.onSuccess?.(), "recovered") : "cancelled" : "unhandled"
650
- });
651
- },
652
- [s, i, y]
653
- ), C = M(async () => {
654
- if (!t) return;
655
- const { payload: p, accept: a, recover: g } = t;
656
- o(null);
657
- const f = p.entityLabel, b = O.loading(`Deleting ${f}...`, { autoClose: !1 }), h = () => O.update(b, {
658
- render: `${f} deleted`,
659
- type: "success",
660
- autoClose: 5e3,
661
- isLoading: !1
662
- });
663
- try {
664
- await a(), h();
665
- } catch (S) {
666
- let T = S;
667
- try {
668
- const P = await g(S);
669
- if (P === "recovered") return h();
670
- if (P === "cancelled")
671
- return O.update(b, {
672
- render: `${f} was not deleted`,
673
- type: "info",
674
- autoClose: 5e3,
675
- isLoading: !1
676
- });
677
- } catch (P) {
678
- T = P;
679
- }
680
- const d = typeof T == "string" ? T : T?.message || T?.error || `Error deleting ${f}`;
681
- O.update(b, {
682
- render: d,
683
- type: "error",
684
- autoClose: 5e3,
685
- isLoading: !1
686
- });
687
- }
688
- }, [t]), u = U(() => ({ deleteEntities: m }), [m]);
689
- return /* @__PURE__ */ I(K.Provider, { value: u, children: [
690
- e,
691
- t && /* @__PURE__ */ c(
692
- ne,
693
- {
694
- payload: t.payload,
695
- onConfirm: C,
696
- onCancel: () => o(null)
697
- }
698
- ),
699
- n && /* @__PURE__ */ c(
700
- ne,
701
- {
702
- payload: n.payload,
703
- onConfirm: () => {
704
- r(null), n.resolve(!0);
705
- },
706
- onCancel: () => {
707
- r(null), n.resolve(!1);
708
- }
709
- }
710
- )
711
- ] });
712
- }, Ot = () => {
713
- const e = F(K);
714
- if (!e)
715
- throw new Error("useDeleteEntitiesContext must be used within a DeleteEntitiesProvider");
716
- return e;
717
- }, Ft = () => F(K);
718
- export {
719
- Et as A,
720
- Lt as D,
721
- Rt as E,
722
- bt as P,
723
- Je as R,
724
- wt as S,
725
- ie as T,
726
- Tt as a,
727
- Pt as b,
728
- xt as c,
729
- Dt as d,
730
- yt as e,
731
- St as f,
732
- Ot as g,
733
- Ft as h,
734
- $t as i,
735
- He as j,
736
- vt as k,
737
- It as l,
738
- Ct as m,
739
- te as n,
740
- J as o,
741
- je as p,
742
- ne as q,
743
- Le as r,
744
- Ie as s,
745
- Re as t,
746
- kt as u,
747
- $e as v
748
- };