teraprox-core-sdk 0.3.10 → 0.3.14

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/dist/index.js CHANGED
@@ -30,63 +30,135 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ CONTADOR_DEFAULT_KEY: () => DEFAULT_KEY4,
33
34
  CoreServiceBuilder: () => CoreServiceBuilder,
34
35
  CoreServiceContext: () => CoreServiceContext,
35
36
  DevAutoLogin: () => DevAutoLogin,
37
+ FILTER_COMBINE_MODES: () => FILTER_COMBINE_MODES,
36
38
  FederatedBridge: () => FederatedBridge,
37
39
  FetchHttpAdapter: () => FetchHttpAdapter,
40
+ INSPECAO_MODAL_DEFAULT_KEY: () => DEFAULT_KEY2,
38
41
  NullCoreService: () => NullCoreService,
39
42
  NullHttpController: () => NullHttpController,
40
43
  NullObservabilityAdapter: () => NullObservabilityAdapter,
41
44
  NullToastService: () => NullToastService,
42
- RecursoDisplayer: () => RecursoDisplayer_default,
45
+ RECORRENCIA_DEFAULT_KEY: () => DEFAULT_KEY3,
43
46
  StandaloneProvider: () => StandaloneProvider,
44
47
  TracingHttpAdapter: () => TracingHttpAdapter,
48
+ UNIDADE_MATERIAL_DEFAULT_KEY: () => DEFAULT_KEY,
49
+ addContadorLimite: () => addContadorLimite,
45
50
  addDays: () => addDays,
46
51
  branchLevelReducer: () => branchLevelReducer_default,
47
52
  buildTraceparent: () => buildTraceparent,
48
53
  capitalize: () => capitalize,
49
54
  clearBranchLevelForm: () => clearBranchLevelForm,
55
+ clearContador: () => clearContador,
56
+ clearInspecaoModal: () => clearInspecaoModal,
57
+ clearMantenedorSlot: () => clearMantenedorSlot,
50
58
  clearPicker: () => clearPicker,
59
+ clearRecorrencia: () => clearRecorrencia,
60
+ clearUnidadeMaterial: () => clearUnidadeMaterial,
61
+ contadorReducer: () => contadorSlice_default,
51
62
  createReducersBundle: () => createReducersBundle,
63
+ createReducersFromManifest: () => createReducersFromManifest,
52
64
  daysBetween: () => daysBetween,
53
65
  formatDate: () => formatDate,
54
66
  formatDateTime: () => formatDateTime,
55
67
  generateSpanId: () => generateSpanId,
56
68
  generateTraceId: () => generateTraceId,
69
+ groupMenuSections: () => groupMenuSections,
70
+ hmsToSeconds: () => hmsToSeconds,
57
71
  initWebVitals: () => initWebVitals,
72
+ inspecaoModalReducer: () => inspecaoModalSlice_default,
58
73
  isBlank: () => isBlank,
59
74
  isDateAfter: () => isDateAfter,
60
75
  isDateBefore: () => isDateBefore,
76
+ isHostedByCore: () => isHostedByCore,
77
+ mantenedorPickerReducer: () => mantenedorPickerSlice_default,
78
+ pickMantenedorTipoReducer: () => pickMantenedorTipoSlice_default,
61
79
  pickTextColorBasedOnBgColorAdvanced: () => pickTextColorBasedOnBgColorAdvanced,
62
80
  pickerReducer: () => pickerReducer_default,
81
+ populateContador: () => populateContador,
82
+ populateInspecaoModal: () => populateInspecaoModal,
83
+ populateRecorrencia: () => populateRecorrencia,
63
84
  populateToEdit: () => populateToEdit,
85
+ populateUnidadeMaterial: () => populateUnidadeMaterial,
86
+ recorrenciaReducer: () => recorrenciaSlice_default,
64
87
  removeAccents: () => removeAccents,
88
+ removeContadorLimiteAt: () => removeContadorLimiteAt,
89
+ removeInspecaoLimiteAt: () => removeInspecaoLimiteAt,
90
+ resetPickMantenedorTipo: () => resetPickMantenedorTipo,
91
+ secondsToHms: () => secondsToHms,
92
+ selectContador: () => selectContador,
93
+ selectInspecaoModal: () => selectInspecaoModal,
94
+ selectRecorrencia: () => selectRecorrencia,
95
+ selectUnidadeMaterial: () => selectUnidadeMaterial,
65
96
  setColor: () => setColor,
97
+ setContadorParametro: () => setContadorParametro,
98
+ setContadorUnidade: () => setContadorUnidade,
99
+ setContadorValor: () => setContadorValor,
66
100
  setExcludeLevels: () => setExcludeLevels,
67
101
  setHaveComponente: () => setHaveComponente,
102
+ setInspecaoLimites: () => setInspecaoLimites,
103
+ setInspecaoNomeParametro: () => setInspecaoNomeParametro,
104
+ setInspecaoParametro: () => setInspecaoParametro,
105
+ setInspecaoTipo: () => setInspecaoTipo,
106
+ setInspecaoUnidadeParametro: () => setInspecaoUnidadeParametro,
68
107
  setLevel: () => setLevel,
69
108
  setLevels: () => setLevels,
109
+ setMantenedorError: () => setMantenedorError,
110
+ setMantenedorLoading: () => setMantenedorLoading,
111
+ setMantenedorOptions: () => setMantenedorOptions,
112
+ setMantenedorPendingConfirm: () => setMantenedorPendingConfirm,
113
+ setMantenedorSearchTerm: () => setMantenedorSearchTerm,
70
114
  setNome: () => setNome,
115
+ setPickMantenedorTipoAssigning: () => setPickMantenedorTipoAssigning,
116
+ setPickMantenedorTipoError: () => setPickMantenedorTipoError,
117
+ setPickMantenedorTipoLoading: () => setPickMantenedorTipoLoading,
118
+ setPickMantenedorTipoOptions: () => setPickMantenedorTipoOptions,
71
119
  setPickerContext: () => setPickerContext,
72
120
  setPickerItems: () => setPickerItems,
73
121
  setPickerSelected: () => setPickerSelected,
74
122
  setPickerVisible: () => setPickerVisible,
123
+ setRecorrenciaDataInicio: () => setRecorrenciaDataInicio,
124
+ setRecorrenciaEscala: () => setRecorrenciaEscala,
125
+ setRecorrenciaValor: () => setRecorrenciaValor,
126
+ setUnidadeMaterialMaterial: () => setMaterial,
127
+ setUnidadeMaterialQuantidade: () => setQuantidade,
128
+ setUnidadeMaterialUnidade: () => setUnidade,
75
129
  slugify: () => slugify,
76
130
  toISOString: () => toISOString,
77
131
  truncate: () => truncate,
132
+ unidadeMaterialReducer: () => unidadeMaterialSlice_default,
133
+ updateContadorLimiteAt: () => updateContadorLimiteAt,
134
+ useAnexoManager: () => useAnexoManager,
135
+ useAnexoManagerViewModel: () => useAnexoManagerViewModel,
78
136
  useAnexoUpload: () => useAnexoUpload,
137
+ useContadorViewModel: () => useContadorViewModel,
79
138
  useCoreService: () => useCoreService,
80
139
  useFetchData: () => useFetchData,
140
+ useFilterCombineMode: () => useFilterCombineMode,
141
+ useFindRecursoByTagViewModel: () => useFindRecursoByTagViewModel,
81
142
  useFormStorage: () => useFormStorage,
82
143
  useHttpController: () => useHttpController,
144
+ useInspecaoModalViewModel: () => useInspecaoModalViewModel,
145
+ useJustificativaModalViewModel: () => useJustificativaModalViewModel,
146
+ useMantenedorPickerViewModel: () => useMantenedorPickerViewModel,
83
147
  useMatchingObject: () => useMatchingObject,
84
148
  useNavigator: () => useNavigator,
85
149
  useNotifications: () => useNotifications,
86
150
  useObservability: () => useObservability,
151
+ useObservacoesTarefaViewModel: () => useObservacoesTarefaViewModel,
152
+ usePickMantenedorTipoViewModel: () => usePickMantenedorTipoViewModel,
87
153
  usePostData: () => usePostData,
154
+ useRecorrenciaViewModel: () => useRecorrenciaViewModel,
155
+ useRecursoDisplayerViewModel: () => useRecursoDisplayerViewModel,
88
156
  useSmartSearch: () => useSmartSearch,
157
+ useTarefaItemViewModel: () => useTarefaItemViewModel,
158
+ useTarefaStatusViewModel: () => useTarefaStatusViewModel,
159
+ useTimeFormat: () => useTimeFormat,
89
160
  useToast: () => useToast,
161
+ useUnidadeMaterialViewModel: () => useUnidadeMaterialViewModel,
90
162
  useValidation: () => useValidation
91
163
  });
92
164
  module.exports = __toCommonJS(index_exports);
@@ -180,6 +252,7 @@ var NullCoreService = {
180
252
  unsubscribeEvent: (evt) => console.log(`[CoreService Fallback] Desinscri\xE7\xE3o Evento: ${evt}`),
181
253
  handleLogout: () => console.log(`[CoreService Fallback] Realizando logout...`),
182
254
  hostedByCore: false,
255
+ rateLimits: {},
183
256
  observability: new NullObservabilityAdapter()
184
257
  };
185
258
 
@@ -274,60 +347,118 @@ var TracingHttpAdapter = class {
274
347
 
275
348
  // src/factories/CoreServiceBuilder.ts
276
349
  var FetchHttpAdapter = class {
277
- constructor(endpoint, extraHeaders) {
350
+ constructor(endpoint, extraHeaders, interceptors) {
278
351
  this.endpoint = endpoint;
279
352
  this.extraHeaders = extraHeaders;
353
+ this.interceptors = interceptors;
354
+ }
355
+ mergeHeaders(extraReqHeaders, hasJsonBody) {
356
+ return {
357
+ ...this.extraHeaders,
358
+ ...hasJsonBody ? { "Content-Type": "application/json" } : {},
359
+ ...extraReqHeaders
360
+ };
361
+ }
362
+ /** Join non-empty path segments, avoiding double slashes. */
363
+ joinPath(...parts) {
364
+ return parts.filter((p) => p != null && p !== "").map(String).join("/");
280
365
  }
281
- async request(method, extraPath, data) {
366
+ async request(method, extraPath, data, extraHeaders) {
282
367
  const url = extraPath ? `${this.endpoint}/${extraPath}` : this.endpoint;
368
+ const isFormData = typeof FormData !== "undefined" && data instanceof FormData;
369
+ const body = data !== void 0 ? isFormData ? data : JSON.stringify(data) : void 0;
370
+ const buildHeaders = async () => {
371
+ var _a;
372
+ let h = this.mergeHeaders(extraHeaders, data !== void 0 && !isFormData);
373
+ if ((_a = this.interceptors) == null ? void 0 : _a.onBeforeRequest) {
374
+ h = await this.interceptors.onBeforeRequest(h);
375
+ }
376
+ return h;
377
+ };
378
+ let interceptorRetryConsumed = false;
379
+ const doFetch = async () => {
380
+ var _a, _b;
381
+ const headers = await buildHeaders();
382
+ const res = await fetch(url, { method, headers, body });
383
+ if (!res.ok) {
384
+ const errorData = await res.json().catch(() => ({}));
385
+ if ((_a = this.interceptors) == null ? void 0 : _a.onError) {
386
+ return this.interceptors.onError(
387
+ { status: res.status, headers: res.headers, data: errorData, message: `HTTP ${res.status}` },
388
+ async () => {
389
+ if (interceptorRetryConsumed) {
390
+ const e = new Error(`HTTP ${res.status} (retry limit)`);
391
+ e.status = res.status;
392
+ e.data = errorData;
393
+ throw e;
394
+ }
395
+ interceptorRetryConsumed = true;
396
+ return doFetch();
397
+ }
398
+ );
399
+ }
400
+ throw new Error(`HTTP ${res.status}`);
401
+ }
402
+ const responseData = await res.json().catch(() => ({}));
403
+ if ((_b = this.interceptors) == null ? void 0 : _b.onResponse) {
404
+ return this.interceptors.onResponse(
405
+ { status: res.status, headers: res.headers, data: responseData },
406
+ method
407
+ );
408
+ }
409
+ return responseData;
410
+ };
411
+ if (this.interceptors) {
412
+ return await doFetch();
413
+ }
283
414
  try {
284
- const res = await fetch(url, {
285
- method,
286
- headers: {
287
- ...this.extraHeaders,
288
- ...data ? { "Content-Type": "application/json" } : {}
289
- },
290
- body: data ? JSON.stringify(data) : void 0
291
- });
292
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
293
- return await res.json();
415
+ return await doFetch();
294
416
  } catch (e) {
295
- console.warn(`[FetchHttpAdapter] Falha ao fazer ${method} para ${url}:`, e);
417
+ console.warn(`[FetchHttpAdapter] ${method} ${url}:`, e);
296
418
  return [];
297
419
  }
298
420
  }
299
- get(path) {
300
- return this.request("GET", path || "");
421
+ qs(query) {
422
+ return query ? `?${query}` : "";
301
423
  }
302
- post(path, data) {
303
- return this.request("POST", path || "", data);
424
+ get(path, query) {
425
+ return this.request("GET", `${this.joinPath(path)}${this.qs(query)}`);
304
426
  }
305
- put(path, data) {
306
- return this.request("PUT", path || "", data);
427
+ post(path, data, extraHeaders, query) {
428
+ return this.request("POST", `${this.joinPath(path)}${this.qs(query)}`, data, extraHeaders);
307
429
  }
308
- patch(path, data) {
309
- return this.request("PATCH", path || "", data);
430
+ put(path, data, extraHeaders, query) {
431
+ return this.request("PUT", `${this.joinPath(path)}${this.qs(query)}`, data, extraHeaders);
310
432
  }
311
- delete(path, id) {
312
- return this.request("DELETE", `${path || ""}/${id}`);
433
+ patch(path, data, extraHeaders, query) {
434
+ return this.request("PATCH", `${this.joinPath(path)}${this.qs(query)}`, data, extraHeaders);
313
435
  }
314
- deleteSimple(path) {
315
- return this.request("DELETE", path || "");
436
+ delete(path, id, extraHeaders, query) {
437
+ return this.request("DELETE", `${this.joinPath(path, id)}${this.qs(query)}`, void 0, extraHeaders);
316
438
  }
317
- save(path, data) {
318
- return this.request("POST", path || "", data);
439
+ deleteSimple(path, extraHeaders, query) {
440
+ return this.request("DELETE", `${this.joinPath(path)}${this.qs(query)}`, void 0, extraHeaders);
319
441
  }
320
- read(path, id) {
321
- return this.request("GET", `${path || ""}/${id}`);
442
+ save(path, data, extraHeaders, query) {
443
+ if (data && (data.id || data._id)) {
444
+ const id = data.id || data._id;
445
+ return this.request("PUT", `${this.joinPath(path, id)}${this.qs(query)}`, data, extraHeaders);
446
+ }
447
+ return this.request("POST", `${this.joinPath(path)}${this.qs(query)}`, data, extraHeaders);
322
448
  }
323
- readAll(path) {
324
- return this.request("GET", path || "");
449
+ read(path, id, extraHeaders, query) {
450
+ return this.request("GET", `${this.joinPath(path, id)}${this.qs(query)}`, void 0, extraHeaders);
325
451
  }
326
- readAllwithPage(path) {
327
- return this.request("GET", path || "");
452
+ readAll(path, extraHeaders, query) {
453
+ return this.request("GET", `${this.joinPath(path)}${this.qs(query)}`, void 0, extraHeaders);
328
454
  }
329
- bulkDelete(path) {
330
- return this.request("DELETE", path || "");
455
+ readAllwithPage(path, page, size) {
456
+ return this.request("GET", `${this.joinPath(path)}?page=${page}&size=${size}`);
457
+ }
458
+ bulkDelete(path, ids, extraHeaders, query) {
459
+ const bulkParam = ids ? `ids=${ids.join(",")}` : "";
460
+ const fullQuery = query ? `${query}&${bulkParam}` : bulkParam;
461
+ return this.request("DELETE", `${this.joinPath(path)}?${fullQuery}`, void 0, extraHeaders);
331
462
  }
332
463
  };
333
464
  var CoreServiceBuilder = class {
@@ -376,13 +507,15 @@ var CoreServiceBuilder = class {
376
507
  return this;
377
508
  }
378
509
  build() {
510
+ const subscriptions = [];
379
511
  return {
380
512
  toast: this._toast,
381
513
  createController: (context, baseEndPoint) => {
382
514
  if (this._fallbackControllers[context]) {
383
515
  return this._fallbackControllers[context];
384
516
  }
385
- const endpoint = baseEndPoint != null ? baseEndPoint : this._httpEndpoint ? `${this._httpEndpoint}/${context}` : null;
517
+ const endpointStr = this._httpEndpoint ? context ? `${this._httpEndpoint}/${context}` : this._httpEndpoint : null;
518
+ const endpoint = baseEndPoint != null ? baseEndPoint : endpointStr;
386
519
  if (!endpoint) {
387
520
  console.warn(`[CoreServiceBuilder] HttpEndpoint nulo para "${context}". Usando NullHttpController.`);
388
521
  const controller = new NullHttpController();
@@ -396,19 +529,27 @@ var CoreServiceBuilder = class {
396
529
  const extraHeaders = { "x-teraprox-host": hostHeader };
397
530
  return this._tracing ? new TracingHttpAdapter(endpoint, extraHeaders) : new FetchHttpAdapter(endpoint, extraHeaders);
398
531
  },
532
+ // Subscriptions are properly managed so that:
533
+ // 1. Components using useMatchingObject() have their registrations tracked.
534
+ // 2. An external RtdbBridge / StandaloneProvider can dispatch to them.
535
+ // 3. Tests can inspect which subscriptions are active.
399
536
  subscribe: (mo) => {
400
- console.log(`[CoreServiceBuilder RTDB] Subscribe > ${mo.context}`);
537
+ subscriptions.push(mo);
401
538
  },
402
539
  unsubscribe: (mo) => {
403
- console.log(`[CoreServiceBuilder RTDB] Unsubscribe > ${mo.context}`);
540
+ const idx = subscriptions.findIndex(
541
+ (s) => s.context === mo.context && s.location === mo.location
542
+ );
543
+ if (idx >= 0) subscriptions.splice(idx, 1);
404
544
  },
405
- subscribeEvent: (evt) => {
545
+ subscribeEvent: (_evt) => {
406
546
  },
407
- unsubscribeEvent: (evt) => {
547
+ unsubscribeEvent: (_evt) => {
408
548
  },
409
- handleLogout: () => console.log("Logout invocado no Standalone mode"),
549
+ handleLogout: () => console.log("[CoreServiceBuilder] Logout invocado no Standalone mode"),
410
550
  hostedByCore: this._hostedByCore,
411
- observability: this._observability
551
+ observability: this._observability,
552
+ rateLimits: {}
412
553
  };
413
554
  }
414
555
  };
@@ -529,15 +670,207 @@ function useObservability() {
529
670
  return useCoreService().observability;
530
671
  }
531
672
 
532
- // src/hooks/useFetchData.ts
673
+ // src/hooks/useAnexoManager.ts
533
674
  var import_react6 = require("react");
534
- function useFetchData() {
675
+ function generateLocalId() {
676
+ return `local_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
677
+ }
678
+ function mapRowToPersistido(raw) {
679
+ var _a, _b, _c, _d;
680
+ const r = (raw == null ? void 0 : raw.dataValues) != null ? { ...raw.dataValues, id: (_b = raw.id) != null ? _b : (_a = raw.dataValues) == null ? void 0 : _a.id } : raw;
681
+ if (!r || typeof r !== "object") {
682
+ return { id: "unknown", nome: "Anexo", tipo: "application/octet-stream" };
683
+ }
684
+ const nome = typeof r.nome === "string" && r.nome || typeof r.originalName === "string" && r.originalName || typeof r.fileName === "string" && r.fileName || typeof r.key === "string" && r.key.split("/").pop() || "Anexo";
685
+ const tipo = typeof r.contentType === "string" && r.contentType || typeof r.tipo === "string" && r.tipo || "application/octet-stream";
686
+ const id = (_d = (_c = r.id) != null ? _c : r.anexoId) != null ? _d : String(nome);
687
+ const tamanho = typeof r.size === "number" ? r.size : typeof r.tamanho === "number" ? r.tamanho : void 0;
688
+ return {
689
+ id,
690
+ nome,
691
+ tipo,
692
+ tamanho,
693
+ url: r.url,
694
+ signedUrl: r.signedUrl,
695
+ key: r.key,
696
+ createdAt: r.createdAt
697
+ };
698
+ }
699
+ function useAnexoManager({ context, entityId, port }) {
535
700
  const { createController } = useCoreService();
536
- const [data, setData] = (0, import_react6.useState)(null);
701
+ const [persistidos, setPersistidos] = (0, import_react6.useState)([]);
702
+ const [locais, setLocais] = (0, import_react6.useState)([]);
537
703
  const [loading, setLoading] = (0, import_react6.useState)(false);
538
- const [error, setError] = (0, import_react6.useState)(null);
539
- const activeRef = (0, import_react6.useRef)(true);
540
- const fetchData = (0, import_react6.useCallback)(
704
+ const anexoController = (0, import_react6.useMemo)(() => createController("anexo"), [createController]);
705
+ const getPort = (0, import_react6.useCallback)(() => {
706
+ if (port && typeof port === "object" && "readByEntity" in port) return port;
707
+ const ctrl = anexoController;
708
+ return {
709
+ intent: (params) => ctrl.post("intent", {
710
+ fileName: params.nome,
711
+ contentType: params.tipo,
712
+ size: params.tamanho,
713
+ dataId: String(params.entityId),
714
+ dataContext: params.context
715
+ }),
716
+ confirm: (params) => {
717
+ var _a, _b;
718
+ return ctrl.post("confirm", {
719
+ key: params.key,
720
+ fileName: (_a = params.fileName) != null ? _a : "",
721
+ contentType: (_b = params.contentType) != null ? _b : "",
722
+ dataId: String(params.entityId),
723
+ dataContext: params.context
724
+ });
725
+ },
726
+ uploadDirect: async ({ file, context: ctx, entityId: eid }) => {
727
+ const targetCtrl = createController(ctx);
728
+ return targetCtrl.put(`anexo/${eid}`, {
729
+ anexos: [{ nome: file.name, tipo: file.type, tamanho: file.size }]
730
+ });
731
+ },
732
+ readByEntity: (ctx, eid) => ctrl.post("readByData", { dataId: String(eid), dataContext: ctx }),
733
+ getSignedUrl: (anexoId, key) => key ? ctrl.post("signedUrl", { key }).then((r) => (r == null ? void 0 : r.signedUrl) || (r == null ? void 0 : r.url) || "") : ctrl.post("signedUrl", { anexoId }).then((r) => (r == null ? void 0 : r.url) || (r == null ? void 0 : r.signedUrl) || ""),
734
+ remove: (anexoId) => ctrl.delete("", anexoId)
735
+ };
736
+ }, [port, anexoController, createController]);
737
+ const loadAnexos = (0, import_react6.useCallback)(async () => {
738
+ setLoading(true);
739
+ try {
740
+ const data = await getPort().readByEntity(context, entityId);
741
+ setPersistidos((Array.isArray(data) ? data : []).map(mapRowToPersistido));
742
+ } catch (e) {
743
+ setPersistidos([]);
744
+ } finally {
745
+ setLoading(false);
746
+ }
747
+ }, [context, entityId, getPort]);
748
+ const addFiles = (0, import_react6.useCallback)((files) => {
749
+ const newLocais = files.map((file) => ({
750
+ localId: generateLocalId(),
751
+ file,
752
+ nome: file.name,
753
+ tipo: file.type,
754
+ tamanho: file.size,
755
+ progress: 0,
756
+ status: "pending"
757
+ }));
758
+ setLocais((prev) => [...prev, ...newLocais]);
759
+ }, []);
760
+ const removeLocal = (0, import_react6.useCallback)((localId2) => {
761
+ setLocais((prev) => prev.filter((a) => a.localId !== localId2));
762
+ }, []);
763
+ const uploadAll = (0, import_react6.useCallback)(async (overrideEntityId) => {
764
+ var _a, _b;
765
+ const pending = locais.filter((a) => a.status === "pending" || a.status === "error");
766
+ if (!pending.length) return [];
767
+ const eid = overrideEntityId != null ? overrideEntityId : entityId;
768
+ const results = [];
769
+ const p = getPort();
770
+ for (const anexo of pending) {
771
+ setLocais(
772
+ (prev) => prev.map((a) => a.localId === anexo.localId ? { ...a, status: "uploading", progress: 10 } : a)
773
+ );
774
+ try {
775
+ let intent = null;
776
+ try {
777
+ intent = await p.intent({
778
+ nome: anexo.nome,
779
+ tipo: anexo.tipo,
780
+ tamanho: anexo.tamanho,
781
+ context,
782
+ entityId: eid
783
+ });
784
+ } catch (e) {
785
+ }
786
+ setLocais(
787
+ (prev) => prev.map((a) => a.localId === anexo.localId ? { ...a, progress: 40 } : a)
788
+ );
789
+ let result;
790
+ const intentUrl = (intent == null ? void 0 : intent.uploadUrl) || (intent == null ? void 0 : intent.signedUrl);
791
+ if (intentUrl) {
792
+ const putRes = await fetch(intentUrl, {
793
+ method: "PUT",
794
+ body: anexo.file,
795
+ headers: { "Content-Type": anexo.tipo || "application/octet-stream" }
796
+ });
797
+ if (!putRes.ok) {
798
+ const hint = await putRes.text().catch(() => "");
799
+ throw new Error(
800
+ `Falha ao enviar ficheiro para o armazenamento (HTTP ${putRes.status}). ${hint ? hint.slice(0, 180) : ""}`.trim()
801
+ );
802
+ }
803
+ setLocais(
804
+ (prev) => prev.map((a) => a.localId === anexo.localId ? { ...a, progress: 80 } : a)
805
+ );
806
+ result = await p.confirm({
807
+ context,
808
+ entityId: eid,
809
+ key: intent.key,
810
+ fileName: (_a = intent.fileName) != null ? _a : anexo.nome,
811
+ contentType: (_b = intent.contentType) != null ? _b : anexo.tipo
812
+ });
813
+ } else {
814
+ result = await p.uploadDirect({ file: anexo.file, context, entityId: eid });
815
+ }
816
+ setLocais(
817
+ (prev) => prev.map((a) => a.localId === anexo.localId ? { ...a, status: "done", progress: 100 } : a)
818
+ );
819
+ results.push(mapRowToPersistido(result));
820
+ } catch (err) {
821
+ setLocais(
822
+ (prev) => prev.map(
823
+ (a) => a.localId === anexo.localId ? { ...a, status: "error", progress: 0, errorMessage: (err == null ? void 0 : err.message) || "Falha no upload" } : a
824
+ )
825
+ );
826
+ }
827
+ }
828
+ if (results.length) {
829
+ setPersistidos((prev) => [...prev, ...results]);
830
+ setLocais((prev) => prev.filter((a) => a.status !== "done"));
831
+ }
832
+ return results;
833
+ }, [locais, getPort, context, entityId]);
834
+ const removePersistido = (0, import_react6.useCallback)(async (anexoId) => {
835
+ try {
836
+ await getPort().remove(anexoId);
837
+ setPersistidos((prev) => prev.filter((a) => a.id !== anexoId));
838
+ } catch (e) {
839
+ }
840
+ }, [getPort]);
841
+ const getUrl = (0, import_react6.useCallback)(
842
+ async (anexoId, key) => {
843
+ let k = key;
844
+ if (k == null || k === "") {
845
+ const p = persistidos.find((a) => String(a.id) === String(anexoId));
846
+ k = p == null ? void 0 : p.key;
847
+ }
848
+ return getPort().getSignedUrl(anexoId, k);
849
+ },
850
+ [getPort, persistidos]
851
+ );
852
+ return {
853
+ persistidos,
854
+ locais,
855
+ loading,
856
+ loadAnexos,
857
+ addFiles,
858
+ removeLocal,
859
+ uploadAll,
860
+ removePersistido,
861
+ getUrl
862
+ };
863
+ }
864
+
865
+ // src/hooks/useFetchData.ts
866
+ var import_react7 = require("react");
867
+ function useFetchData() {
868
+ const { createController } = useCoreService();
869
+ const [data, setData] = (0, import_react7.useState)(null);
870
+ const [loading, setLoading] = (0, import_react7.useState)(false);
871
+ const [error, setError] = (0, import_react7.useState)(null);
872
+ const activeRef = (0, import_react7.useRef)(true);
873
+ const fetchData = (0, import_react7.useCallback)(
541
874
  async (context, path, endpoint) => {
542
875
  const controller = createController(context, endpoint);
543
876
  setLoading(true);
@@ -555,7 +888,7 @@ function useFetchData() {
555
888
  },
556
889
  [createController]
557
890
  );
558
- const reset = (0, import_react6.useCallback)(() => {
891
+ const reset = (0, import_react7.useCallback)(() => {
559
892
  setData(null);
560
893
  setLoading(false);
561
894
  setError(null);
@@ -564,13 +897,13 @@ function useFetchData() {
564
897
  }
565
898
 
566
899
  // src/hooks/usePostData.ts
567
- var import_react7 = require("react");
900
+ var import_react8 = require("react");
568
901
  function usePostData() {
569
902
  const { createController } = useCoreService();
570
- const [result, setResult] = (0, import_react7.useState)(null);
571
- const [loading, setLoading] = (0, import_react7.useState)(false);
572
- const [error, setError] = (0, import_react7.useState)(null);
573
- const postData = (0, import_react7.useCallback)(
903
+ const [result, setResult] = (0, import_react8.useState)(null);
904
+ const [loading, setLoading] = (0, import_react8.useState)(false);
905
+ const [error, setError] = (0, import_react8.useState)(null);
906
+ const postData = (0, import_react8.useCallback)(
574
907
  async (context, path, payload, endpoint) => {
575
908
  const controller = createController(context, endpoint);
576
909
  setLoading(true);
@@ -592,13 +925,13 @@ function usePostData() {
592
925
  }
593
926
 
594
927
  // src/hooks/useAnexoUpload.ts
595
- var import_react8 = require("react");
928
+ var import_react9 = require("react");
596
929
  function useAnexoUpload() {
597
930
  const { createController } = useCoreService();
598
931
  const toast = useToast();
599
- const [uploading, setUploading] = (0, import_react8.useState)(false);
600
- const [progress, setProgress] = (0, import_react8.useState)(0);
601
- const upload = (0, import_react8.useCallback)(
932
+ const [uploading, setUploading] = (0, import_react9.useState)(false);
933
+ const [progress, setProgress] = (0, import_react9.useState)(0);
934
+ const upload = (0, import_react9.useCallback)(
602
935
  async (context, path, file, extraHeaders) => {
603
936
  const controller = createController(context);
604
937
  setUploading(true);
@@ -621,7 +954,7 @@ function useAnexoUpload() {
621
954
  },
622
955
  [createController, toast]
623
956
  );
624
- const uploadMultiple = (0, import_react8.useCallback)(
957
+ const uploadMultiple = (0, import_react9.useCallback)(
625
958
  async (context, path, files, extraHeaders) => {
626
959
  const fileArray = Array.from(files);
627
960
  const results = [];
@@ -639,10 +972,10 @@ function useAnexoUpload() {
639
972
  }
640
973
 
641
974
  // src/hooks/useFormStorage.ts
642
- var import_react9 = require("react");
975
+ var import_react10 = require("react");
643
976
  function useFormStorage(key, initialValue) {
644
977
  const storageKey = `teraprox_form_${key}`;
645
- const [value, setValue] = (0, import_react9.useState)(() => {
978
+ const [value, setValue] = (0, import_react10.useState)(() => {
646
979
  try {
647
980
  const stored = localStorage.getItem(storageKey);
648
981
  return stored ? JSON.parse(stored) : initialValue;
@@ -650,13 +983,13 @@ function useFormStorage(key, initialValue) {
650
983
  return initialValue;
651
984
  }
652
985
  });
653
- (0, import_react9.useEffect)(() => {
986
+ (0, import_react10.useEffect)(() => {
654
987
  try {
655
988
  localStorage.setItem(storageKey, JSON.stringify(value));
656
989
  } catch (e) {
657
990
  }
658
991
  }, [value, storageKey]);
659
- const clear = (0, import_react9.useCallback)(() => {
992
+ const clear = (0, import_react10.useCallback)(() => {
660
993
  localStorage.removeItem(storageKey);
661
994
  setValue(initialValue);
662
995
  }, [storageKey, initialValue]);
@@ -664,11 +997,11 @@ function useFormStorage(key, initialValue) {
664
997
  }
665
998
 
666
999
  // src/hooks/useSmartSearch.ts
667
- var import_react10 = require("react");
1000
+ var import_react11 = require("react");
668
1001
  function useSmartSearch(data, searchFields, options) {
669
- const [searchTerm, setSearchTerm] = (0, import_react10.useState)("");
1002
+ const [searchTerm, setSearchTerm] = (0, import_react11.useState)("");
670
1003
  const { caseSensitive = false, minLength = 1 } = options || {};
671
- const filteredData = (0, import_react10.useMemo)(() => {
1004
+ const filteredData = (0, import_react11.useMemo)(() => {
672
1005
  if (!searchTerm || searchTerm.length < minLength) return data;
673
1006
  const term = caseSensitive ? searchTerm : searchTerm.toLowerCase();
674
1007
  return data.filter(
@@ -680,16 +1013,16 @@ function useSmartSearch(data, searchFields, options) {
680
1013
  })
681
1014
  );
682
1015
  }, [data, searchTerm, searchFields, caseSensitive, minLength]);
683
- const clearSearch = (0, import_react10.useCallback)(() => setSearchTerm(""), []);
1016
+ const clearSearch = (0, import_react11.useCallback)(() => setSearchTerm(""), []);
684
1017
  return { searchTerm, setSearchTerm, filteredData, clearSearch };
685
1018
  }
686
1019
 
687
1020
  // src/hooks/useValidation.ts
688
- var import_react11 = require("react");
1021
+ var import_react12 = require("react");
689
1022
  function useValidation(rules) {
690
1023
  const toast = useToast();
691
- const [errors, setErrors] = (0, import_react11.useState)({});
692
- const validate = (0, import_react11.useCallback)(
1024
+ const [errors, setErrors] = (0, import_react12.useState)({});
1025
+ const validate = (0, import_react12.useCallback)(
693
1026
  (form) => {
694
1027
  const newErrors = {};
695
1028
  let valid = true;
@@ -708,22 +1041,523 @@ function useValidation(rules) {
708
1041
  },
709
1042
  [rules, toast]
710
1043
  );
711
- const clearErrors = (0, import_react11.useCallback)(() => setErrors({}), []);
712
- const setFieldError = (0, import_react11.useCallback)(
1044
+ const clearErrors = (0, import_react12.useCallback)(() => setErrors({}), []);
1045
+ const setFieldError = (0, import_react12.useCallback)(
713
1046
  (field, message) => setErrors((prev) => ({ ...prev, [field]: message })),
714
1047
  []
715
1048
  );
716
1049
  return { errors, validate, clearErrors, setFieldError };
717
1050
  }
718
1051
 
719
- // src/components/recurso/RecursoDisplayer.tsx
720
- var import_react17 = require("react");
721
- var import_react_bootstrap2 = require("react-bootstrap");
1052
+ // src/hooks/useTimeFormat.ts
1053
+ var import_dayjs = __toESM(require("dayjs"));
1054
+ var import_duration = __toESM(require("dayjs/plugin/duration.js"));
1055
+ import_dayjs.default.extend(import_duration.default);
1056
+ var secondsToHms = (seconds) => {
1057
+ const s = typeof seconds === "number" && !Number.isNaN(seconds) ? seconds : 0;
1058
+ return import_dayjs.default.duration(s, "seconds").format("HH:mm:ss");
1059
+ };
1060
+ var hmsToSeconds = (value) => {
1061
+ if (!value) return null;
1062
+ const parts = value.split(":").map(Number);
1063
+ const [h = 0, m = 0, s = 0] = parts;
1064
+ if ([h, m, s].some(Number.isNaN)) return null;
1065
+ return h * 3600 + m * 60 + s;
1066
+ };
1067
+ var useTimeFormat = () => ({
1068
+ secondsToHms,
1069
+ hmsToSeconds
1070
+ });
1071
+
1072
+ // src/hooks/useFilterCombineMode.ts
1073
+ var import_react13 = require("react");
1074
+ var FILTER_COMBINE_MODES = [
1075
+ "union",
1076
+ "intersection",
1077
+ "xor"
1078
+ ];
1079
+ var nextMode = {
1080
+ union: "intersection",
1081
+ intersection: "xor",
1082
+ xor: "union"
1083
+ };
1084
+ function useFilterCombineMode(initialMode = "union") {
1085
+ const [mode, setMode] = (0, import_react13.useState)(initialMode);
1086
+ const cycleMode = (0, import_react13.useCallback)(() => {
1087
+ setMode((prev) => nextMode[prev]);
1088
+ }, []);
1089
+ const matches = (0, import_react13.useCallback)(
1090
+ (predicates, item) => {
1091
+ if (!predicates || predicates.length === 0) return true;
1092
+ if (mode === "union") {
1093
+ for (let i = 0; i < predicates.length; i++) {
1094
+ if (predicates[i](item)) return true;
1095
+ }
1096
+ return false;
1097
+ }
1098
+ if (mode === "intersection") {
1099
+ for (let i = 0; i < predicates.length; i++) {
1100
+ if (!predicates[i](item)) return false;
1101
+ }
1102
+ return true;
1103
+ }
1104
+ let hits = 0;
1105
+ for (let i = 0; i < predicates.length; i++) {
1106
+ if (predicates[i](item)) hits++;
1107
+ }
1108
+ return hits % 2 === 1;
1109
+ },
1110
+ [mode]
1111
+ );
1112
+ return (0, import_react13.useMemo)(
1113
+ () => ({ mode, setMode, cycleMode, matches }),
1114
+ [mode, cycleMode, matches]
1115
+ );
1116
+ }
1117
+
1118
+ // src/viewmodels/ReduxUnidadeMaterialAdapter.ts
1119
+ var import_react14 = require("react");
722
1120
  var import_react_redux3 = require("react-redux");
723
1121
 
724
- // src/reducers/branchLevelReducer.ts
1122
+ // src/viewmodels/unidadeMaterialSlice.ts
725
1123
  var import_toolkit = require("@reduxjs/toolkit");
1124
+ var DEFAULT_KEY = "__default__";
1125
+ var emptyValue = {
1126
+ material: null,
1127
+ quantidade: "",
1128
+ unidade: null
1129
+ };
726
1130
  var initialState = {
1131
+ byTarefa: {}
1132
+ };
1133
+ var keyOf = (tarefaId) => tarefaId === void 0 || tarefaId === null || tarefaId === "" ? DEFAULT_KEY : String(tarefaId);
1134
+ var ensure = (state, key) => {
1135
+ if (!state.byTarefa[key]) {
1136
+ state.byTarefa[key] = { ...emptyValue };
1137
+ }
1138
+ return state.byTarefa[key];
1139
+ };
1140
+ var unidadeMaterialSlice = (0, import_toolkit.createSlice)({
1141
+ name: "unidadeMaterialVm",
1142
+ initialState,
1143
+ reducers: {
1144
+ setMaterial(state, action) {
1145
+ const key = keyOf(action.payload.tarefaId);
1146
+ ensure(state, key).material = action.payload.value;
1147
+ },
1148
+ setQuantidade(state, action) {
1149
+ const key = keyOf(action.payload.tarefaId);
1150
+ ensure(state, key).quantidade = action.payload.value;
1151
+ },
1152
+ setUnidade(state, action) {
1153
+ const key = keyOf(action.payload.tarefaId);
1154
+ ensure(state, key).unidade = action.payload.value;
1155
+ },
1156
+ populate(state, action) {
1157
+ const key = keyOf(action.payload.tarefaId);
1158
+ state.byTarefa[key] = { ...emptyValue, ...action.payload.value };
1159
+ },
1160
+ clearUnidadeMaterial(state, action) {
1161
+ var _a;
1162
+ const key = keyOf((_a = action.payload) == null ? void 0 : _a.tarefaId);
1163
+ state.byTarefa[key] = { ...emptyValue };
1164
+ }
1165
+ }
1166
+ });
1167
+ var {
1168
+ setMaterial,
1169
+ setQuantidade,
1170
+ setUnidade,
1171
+ populate: populateUnidadeMaterial,
1172
+ clearUnidadeMaterial
1173
+ } = unidadeMaterialSlice.actions;
1174
+ var selectUnidadeMaterial = (state, tarefaId) => {
1175
+ var _a, _b, _c;
1176
+ const key = keyOf(tarefaId);
1177
+ const slice3 = (_a = state == null ? void 0 : state.unidadeMaterialVm) != null ? _a : state == null ? void 0 : state.unidadeMaterial;
1178
+ return (_c = (_b = slice3 == null ? void 0 : slice3.byTarefa) == null ? void 0 : _b[key]) != null ? _c : emptyValue;
1179
+ };
1180
+ var unidadeMaterialSlice_default = unidadeMaterialSlice.reducer;
1181
+
1182
+ // src/viewmodels/ReduxUnidadeMaterialAdapter.ts
1183
+ function runValidate(value) {
1184
+ const errors = {};
1185
+ if (!(value == null ? void 0 : value.material)) {
1186
+ errors.material = "O material \xE9 obrigat\xF3rio.";
1187
+ }
1188
+ if (!(value == null ? void 0 : value.unidade)) {
1189
+ errors.unidade = "A unidade \xE9 obrigat\xF3ria.";
1190
+ }
1191
+ const qtd = value == null ? void 0 : value.quantidade;
1192
+ const qtdNum = typeof qtd === "number" ? qtd : Number(qtd);
1193
+ if (qtd === "" || qtd === null || qtd === void 0 || isNaN(qtdNum) || qtdNum <= 0) {
1194
+ errors.quantidade = "A quantidade deve ser um n\xFAmero maior que zero.";
1195
+ }
1196
+ return { ok: Object.keys(errors).length === 0, errors };
1197
+ }
1198
+ function useUnidadeMaterialViewModel(tarefaId) {
1199
+ const dispatch = (0, import_react_redux3.useDispatch)();
1200
+ const toast = useToast();
1201
+ const materialCtrl = useHttpController("material");
1202
+ const unidadeCtrl = useHttpController("unidade");
1203
+ const tarefaUnidadeMaterialCtrl = useHttpController("tarefaUnidadeMaterial");
1204
+ const value = (0, import_react_redux3.useSelector)(
1205
+ (state) => selectUnidadeMaterial(state, tarefaId)
1206
+ );
1207
+ const [isSubmitting, setIsSubmitting] = (0, import_react14.useState)(false);
1208
+ const onMaterialSelected = (0, import_react14.useCallback)(
1209
+ (material) => {
1210
+ dispatch(setMaterial({ tarefaId, value: material != null ? material : null }));
1211
+ },
1212
+ [dispatch, tarefaId]
1213
+ );
1214
+ const onQuantidadeUpdate = (0, import_react14.useCallback)(
1215
+ (qtd) => {
1216
+ dispatch(setQuantidade({ tarefaId, value: qtd }));
1217
+ },
1218
+ [dispatch, tarefaId]
1219
+ );
1220
+ const onUnidadeSelected = (0, import_react14.useCallback)(
1221
+ (unidade) => {
1222
+ dispatch(setUnidade({ tarefaId, value: unidade != null ? unidade : null }));
1223
+ },
1224
+ [dispatch, tarefaId]
1225
+ );
1226
+ const loadMaterials = (0, import_react14.useCallback)(async () => {
1227
+ var _a;
1228
+ const res = await materialCtrl.readAll();
1229
+ return Array.isArray(res) ? res : (_a = res == null ? void 0 : res.data) != null ? _a : [];
1230
+ }, [materialCtrl]);
1231
+ const loadUnidades = (0, import_react14.useCallback)(async () => {
1232
+ var _a;
1233
+ const res = await unidadeCtrl.readAll();
1234
+ return Array.isArray(res) ? res : (_a = res == null ? void 0 : res.data) != null ? _a : [];
1235
+ }, [unidadeCtrl]);
1236
+ const clear = (0, import_react14.useCallback)(() => {
1237
+ dispatch(clearUnidadeMaterial({ tarefaId }));
1238
+ }, [dispatch, tarefaId]);
1239
+ const populate = (0, import_react14.useCallback)(
1240
+ (next) => {
1241
+ dispatch(populateUnidadeMaterial({ tarefaId, value: next }));
1242
+ },
1243
+ [dispatch, tarefaId]
1244
+ );
1245
+ const validate = (0, import_react14.useCallback)(() => {
1246
+ return runValidate(value);
1247
+ }, [value]);
1248
+ const reset = (0, import_react14.useCallback)(() => {
1249
+ dispatch(clearUnidadeMaterial({ tarefaId }));
1250
+ }, [dispatch, tarefaId]);
1251
+ const submit = (0, import_react14.useCallback)(async () => {
1252
+ var _a;
1253
+ setIsSubmitting(true);
1254
+ try {
1255
+ const result = runValidate(value);
1256
+ if (!result.ok) {
1257
+ const firstErr = (_a = Object.values(result.errors)[0]) != null ? _a : "Dados invalidos.";
1258
+ throw new Error(firstErr);
1259
+ }
1260
+ return value;
1261
+ } finally {
1262
+ setIsSubmitting(false);
1263
+ }
1264
+ }, [value]);
1265
+ const updateQuantidade = (0, import_react14.useCallback)(
1266
+ async (tumId, quantidade) => {
1267
+ try {
1268
+ const body = {
1269
+ quantidade
1270
+ };
1271
+ if (tarefaId !== void 0 && tarefaId !== null) {
1272
+ body.tarefaId = tarefaId;
1273
+ }
1274
+ await tarefaUnidadeMaterialCtrl.put(String(tumId), body);
1275
+ } catch (err) {
1276
+ const msg = (err == null ? void 0 : err.message) || "Nao foi possivel atualizar a quantidade do material.";
1277
+ try {
1278
+ toast.warning(msg);
1279
+ } catch (e) {
1280
+ }
1281
+ throw err;
1282
+ }
1283
+ },
1284
+ [tarefaUnidadeMaterialCtrl, tarefaId, toast]
1285
+ );
1286
+ const isValid = (0, import_react14.useMemo)(() => runValidate(value).ok, [value]);
1287
+ return (0, import_react14.useMemo)(
1288
+ () => ({
1289
+ value,
1290
+ isValid,
1291
+ isSubmitting,
1292
+ onMaterialSelected,
1293
+ onQuantidadeUpdate,
1294
+ onUnidadeSelected,
1295
+ loadMaterials,
1296
+ loadUnidades,
1297
+ clear,
1298
+ populate,
1299
+ validate,
1300
+ submit,
1301
+ reset,
1302
+ updateQuantidade
1303
+ }),
1304
+ [
1305
+ value,
1306
+ isValid,
1307
+ isSubmitting,
1308
+ onMaterialSelected,
1309
+ onQuantidadeUpdate,
1310
+ onUnidadeSelected,
1311
+ loadMaterials,
1312
+ loadUnidades,
1313
+ clear,
1314
+ populate,
1315
+ validate,
1316
+ submit,
1317
+ reset,
1318
+ updateQuantidade
1319
+ ]
1320
+ );
1321
+ }
1322
+
1323
+ // src/viewmodels/ReduxInspecaoModalAdapter.ts
1324
+ var import_react15 = require("react");
1325
+ var import_react_redux4 = require("react-redux");
1326
+
1327
+ // src/viewmodels/inspecaoModalSlice.ts
1328
+ var import_toolkit2 = require("@reduxjs/toolkit");
1329
+ var DEFAULT_KEY2 = "__default__";
1330
+ var emptyValue2 = {
1331
+ tipo: "",
1332
+ nomeParametro: "",
1333
+ unidadeParametro: "",
1334
+ parametroId: "",
1335
+ limitesDeControle: []
1336
+ };
1337
+ var initialState2 = {
1338
+ byTarefa: {}
1339
+ };
1340
+ var keyOf2 = (tarefaId) => tarefaId === void 0 || tarefaId === null || tarefaId === "" ? DEFAULT_KEY2 : String(tarefaId);
1341
+ var ensure2 = (state, key) => {
1342
+ if (!state.byTarefa[key]) {
1343
+ state.byTarefa[key] = { ...emptyValue2, limitesDeControle: [] };
1344
+ }
1345
+ return state.byTarefa[key];
1346
+ };
1347
+ var inspecaoModalSlice = (0, import_toolkit2.createSlice)({
1348
+ name: "inspecaoModalVm",
1349
+ initialState: initialState2,
1350
+ reducers: {
1351
+ setTipo(state, action) {
1352
+ const key = keyOf2(action.payload.tarefaId);
1353
+ ensure2(state, key).tipo = action.payload.value;
1354
+ },
1355
+ setNomeParametro(state, action) {
1356
+ const key = keyOf2(action.payload.tarefaId);
1357
+ ensure2(state, key).nomeParametro = action.payload.value;
1358
+ },
1359
+ setUnidadeParametro(state, action) {
1360
+ const key = keyOf2(action.payload.tarefaId);
1361
+ ensure2(state, key).unidadeParametro = action.payload.value;
1362
+ },
1363
+ setParametro(state, action) {
1364
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1365
+ const key = keyOf2(action.payload.tarefaId);
1366
+ const slot = ensure2(state, key);
1367
+ const p = (_a = action.payload.value) != null ? _a : {};
1368
+ slot.nomeParametro = (_c = (_b = p.nome) != null ? _b : p.nomeParametro) != null ? _c : "";
1369
+ slot.unidadeParametro = (_f = (_e = (_d = p.labelUnidade) != null ? _d : p.unidade) != null ? _e : p.unidadeParametro) != null ? _f : "";
1370
+ slot.parametroId = (_h = (_g = p.id) != null ? _g : p.parametroId) != null ? _h : "";
1371
+ },
1372
+ setLimites(state, action) {
1373
+ var _a;
1374
+ const key = keyOf2(action.payload.tarefaId);
1375
+ ensure2(state, key).limitesDeControle = (_a = action.payload.value) != null ? _a : [];
1376
+ },
1377
+ removeLimiteAt(state, action) {
1378
+ var _a;
1379
+ const key = keyOf2(action.payload.tarefaId);
1380
+ const slot = ensure2(state, key);
1381
+ const { idx } = action.payload;
1382
+ if ((_a = slot.limitesDeControle) == null ? void 0 : _a[idx]) {
1383
+ slot.limitesDeControle[idx] = {
1384
+ ...slot.limitesDeControle[idx],
1385
+ removed: true
1386
+ };
1387
+ }
1388
+ },
1389
+ populate(state, action) {
1390
+ var _a, _b;
1391
+ const key = keyOf2(action.payload.tarefaId);
1392
+ state.byTarefa[key] = {
1393
+ ...emptyValue2,
1394
+ ...action.payload.value,
1395
+ limitesDeControle: (_b = (_a = action.payload.value) == null ? void 0 : _a.limitesDeControle) != null ? _b : []
1396
+ };
1397
+ },
1398
+ clearInspecaoModal(state, action) {
1399
+ var _a;
1400
+ const key = keyOf2((_a = action.payload) == null ? void 0 : _a.tarefaId);
1401
+ state.byTarefa[key] = { ...emptyValue2, limitesDeControle: [] };
1402
+ }
1403
+ }
1404
+ });
1405
+ var {
1406
+ setTipo: setInspecaoTipo,
1407
+ setNomeParametro: setInspecaoNomeParametro,
1408
+ setUnidadeParametro: setInspecaoUnidadeParametro,
1409
+ setParametro: setInspecaoParametro,
1410
+ setLimites: setInspecaoLimites,
1411
+ removeLimiteAt: removeInspecaoLimiteAt,
1412
+ populate: populateInspecaoModal,
1413
+ clearInspecaoModal
1414
+ } = inspecaoModalSlice.actions;
1415
+ var selectInspecaoModal = (state, tarefaId) => {
1416
+ var _a, _b, _c;
1417
+ const key = keyOf2(tarefaId);
1418
+ const slice3 = (_a = state == null ? void 0 : state.inspecaoModalVm) != null ? _a : state == null ? void 0 : state.inspecaoModal;
1419
+ return (_c = (_b = slice3 == null ? void 0 : slice3.byTarefa) == null ? void 0 : _b[key]) != null ? _c : { ...emptyValue2, limitesDeControle: [] };
1420
+ };
1421
+ var inspecaoModalSlice_default = inspecaoModalSlice.reducer;
1422
+
1423
+ // src/viewmodels/ReduxInspecaoModalAdapter.ts
1424
+ var TIPO_NUMERICO = "Numerico";
1425
+ var TIPO_NUMERICO_ACENTUADO = "Num\xE9rico";
1426
+ function isNumericoTipo(tipo) {
1427
+ if (!tipo) return false;
1428
+ const normalized = tipo.trim();
1429
+ return normalized === TIPO_NUMERICO || normalized === TIPO_NUMERICO_ACENTUADO || normalized.toLowerCase() === "numerico" || normalized.toLowerCase() === "num\xE9rico";
1430
+ }
1431
+ function runValidate2(value) {
1432
+ var _a;
1433
+ const errors = {};
1434
+ if (!(value == null ? void 0 : value.tipo) || String(value.tipo).trim() === "") {
1435
+ errors.tipo = "O tipo de dado \xE9 obrigat\xF3rio.";
1436
+ }
1437
+ if (isNumericoTipo(value == null ? void 0 : value.tipo)) {
1438
+ const ativos = ((_a = value == null ? void 0 : value.limitesDeControle) != null ? _a : []).filter(
1439
+ (l) => l && l.removed !== true
1440
+ );
1441
+ if (ativos.length === 0) {
1442
+ errors.limitesDeControle = "Adicione ao menos um limite de controle para par\xE2metros num\xE9ricos.";
1443
+ }
1444
+ }
1445
+ return { ok: Object.keys(errors).length === 0, errors };
1446
+ }
1447
+ function useInspecaoModalViewModel(tarefaId) {
1448
+ const dispatch = (0, import_react_redux4.useDispatch)();
1449
+ const value = (0, import_react_redux4.useSelector)(
1450
+ (state) => selectInspecaoModal(state, tarefaId)
1451
+ );
1452
+ const [isSubmitting, setIsSubmitting] = (0, import_react15.useState)(false);
1453
+ const onTipoDeDado = (0, import_react15.useCallback)(
1454
+ (tipo) => {
1455
+ dispatch(setInspecaoTipo({ tarefaId, value: tipo }));
1456
+ },
1457
+ [dispatch, tarefaId]
1458
+ );
1459
+ const onNomeParametro = (0, import_react15.useCallback)(
1460
+ (nome) => {
1461
+ dispatch(setInspecaoNomeParametro({ tarefaId, value: nome }));
1462
+ },
1463
+ [dispatch, tarefaId]
1464
+ );
1465
+ const onParametroSelected = (0, import_react15.useCallback)(
1466
+ (parametro) => {
1467
+ dispatch(setInspecaoParametro({ tarefaId, value: parametro }));
1468
+ },
1469
+ [dispatch, tarefaId]
1470
+ );
1471
+ const onUnidadeParametro = (0, import_react15.useCallback)(
1472
+ (unidade) => {
1473
+ dispatch(setInspecaoUnidadeParametro({ tarefaId, value: unidade }));
1474
+ },
1475
+ [dispatch, tarefaId]
1476
+ );
1477
+ const onLimitesChange = (0, import_react15.useCallback)(
1478
+ (limites) => {
1479
+ dispatch(setInspecaoLimites({ tarefaId, value: limites }));
1480
+ },
1481
+ [dispatch, tarefaId]
1482
+ );
1483
+ const removeLimite = (0, import_react15.useCallback)(
1484
+ (idx) => {
1485
+ dispatch(removeInspecaoLimiteAt({ tarefaId, idx }));
1486
+ },
1487
+ [dispatch, tarefaId]
1488
+ );
1489
+ const editLimite = (0, import_react15.useCallback)((_limite) => {
1490
+ }, []);
1491
+ const validate = (0, import_react15.useCallback)(() => {
1492
+ return runValidate2(value);
1493
+ }, [value]);
1494
+ const reset = (0, import_react15.useCallback)(() => {
1495
+ dispatch(clearInspecaoModal({ tarefaId }));
1496
+ }, [dispatch, tarefaId]);
1497
+ const populateFromExisting = (0, import_react15.useCallback)(
1498
+ (inspecao) => {
1499
+ dispatch(populateInspecaoModal({ tarefaId, value: inspecao }));
1500
+ },
1501
+ [dispatch, tarefaId]
1502
+ );
1503
+ const submit = (0, import_react15.useCallback)(async () => {
1504
+ var _a;
1505
+ setIsSubmitting(true);
1506
+ try {
1507
+ const result = runValidate2(value);
1508
+ if (!result.ok) {
1509
+ const firstErr = (_a = Object.values(result.errors)[0]) != null ? _a : "Dados invalidos.";
1510
+ throw new Error(firstErr);
1511
+ }
1512
+ return value;
1513
+ } finally {
1514
+ setIsSubmitting(false);
1515
+ }
1516
+ }, [value]);
1517
+ const isValid = (0, import_react15.useMemo)(() => runValidate2(value).ok, [value]);
1518
+ return (0, import_react15.useMemo)(
1519
+ () => ({
1520
+ value,
1521
+ isValid,
1522
+ isSubmitting,
1523
+ onTipoDeDado,
1524
+ onNomeParametro,
1525
+ onParametroSelected,
1526
+ onUnidadeParametro,
1527
+ onLimitesChange,
1528
+ removeLimite,
1529
+ editLimite,
1530
+ validate,
1531
+ submit,
1532
+ reset,
1533
+ populateFromExisting
1534
+ }),
1535
+ [
1536
+ value,
1537
+ isValid,
1538
+ isSubmitting,
1539
+ onTipoDeDado,
1540
+ onNomeParametro,
1541
+ onParametroSelected,
1542
+ onUnidadeParametro,
1543
+ onLimitesChange,
1544
+ removeLimite,
1545
+ editLimite,
1546
+ validate,
1547
+ submit,
1548
+ reset,
1549
+ populateFromExisting
1550
+ ]
1551
+ );
1552
+ }
1553
+
1554
+ // src/viewmodels/ReduxRecursoDisplayerAdapter.ts
1555
+ var import_react16 = require("react");
1556
+ var import_react_redux5 = require("react-redux");
1557
+
1558
+ // src/reducers/branchLevelReducer.ts
1559
+ var import_toolkit3 = require("@reduxjs/toolkit");
1560
+ var initialState3 = {
727
1561
  form: {
728
1562
  nome: "",
729
1563
  level: 0,
@@ -733,9 +1567,9 @@ var initialState = {
733
1567
  },
734
1568
  levels: []
735
1569
  };
736
- var branchLevelSlice = (0, import_toolkit.createSlice)({
1570
+ var branchLevelSlice = (0, import_toolkit3.createSlice)({
737
1571
  name: "branchLevelReducer",
738
- initialState,
1572
+ initialState: initialState3,
739
1573
  reducers: {
740
1574
  setNome(state, action) {
741
1575
  state.form.nome = action.payload;
@@ -759,7 +1593,7 @@ var branchLevelSlice = (0, import_toolkit.createSlice)({
759
1593
  state.form = action.payload;
760
1594
  },
761
1595
  clear(state) {
762
- state.form = initialState.form;
1596
+ state.form = initialState3.form;
763
1597
  }
764
1598
  }
765
1599
  });
@@ -775,788 +1609,1282 @@ var {
775
1609
  } = branchLevelSlice.actions;
776
1610
  var branchLevelReducer_default = branchLevelSlice.reducer;
777
1611
 
778
- // src/components/recurso/BranchDropDisplay.tsx
779
- var import_react12 = require("react");
780
- var import_fa = require("react-icons/fa");
781
- var import_md = require("react-icons/md");
782
-
783
- // src/utils/colorUtils.ts
784
- function pickTextColorBasedOnBgColorAdvanced(bgColor, lightColor, darkColor) {
785
- const color = bgColor.charAt(0) === "#" ? bgColor.substring(1, 7) : bgColor;
786
- const r = parseInt(color.substring(0, 2), 16);
787
- const g = parseInt(color.substring(2, 4), 16);
788
- const b = parseInt(color.substring(4, 6), 16);
789
- const uicolors = [r / 255, g / 255, b / 255];
790
- const c = uicolors.map(
791
- (col) => col <= 0.03928 ? col / 12.92 : Math.pow((col + 0.055) / 1.055, 2.4)
792
- );
793
- const L = 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2];
794
- return L > 0.179 ? darkColor : lightColor;
795
- }
796
-
797
- // src/components/recurso/BranchDropDisplay.tsx
798
- var import_jsx_runtime = require("react/jsx-runtime");
799
- var BranchDropDisplay = ({
800
- branch,
801
- addBranch,
802
- multiMode,
803
- setMultiMode,
804
- onSaveRecurso,
805
- backOnBranch,
806
- branches,
807
- singleReturn
808
- }) => {
809
- const [fontColor, setFontColor] = (0, import_react12.useState)("#000");
810
- const [searchTerm, setSearchTerm] = (0, import_react12.useState)("");
811
- const [show, setShow] = (0, import_react12.useState)(false);
812
- const [multiSelected, setMultiSelected] = (0, import_react12.useState)([]);
813
- const dropdownRef = (0, import_react12.useRef)(null);
814
- (0, import_react12.useEffect)(() => {
815
- setFontColor(
816
- pickTextColorBasedOnBgColorAdvanced(branch.branchLevel.color, "#FFFFFF", "#000000")
817
- );
818
- }, [branch.branchLevel.color]);
819
- (0, import_react12.useEffect)(() => {
820
- const handleClickOutside = (event) => {
821
- if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
822
- setShow(false);
1612
+ // src/viewmodels/ReduxRecursoDisplayerAdapter.ts
1613
+ function useRecursoDisplayerViewModel(overrides = {}) {
1614
+ var _a, _b;
1615
+ const dispatch = (0, import_react_redux5.useDispatch)();
1616
+ const defaultArvore = useHttpController("");
1617
+ const defaultBranchLevel = useHttpController("branchLevel");
1618
+ const arvoreCtrl = (_a = overrides.arvoreEstruturalController) != null ? _a : defaultArvore;
1619
+ const branchLevelCtrl = (_b = overrides.branchLevelController) != null ? _b : defaultBranchLevel;
1620
+ const [branches, setBranches] = (0, import_react16.useState)([]);
1621
+ const [isLoading, setIsLoading] = (0, import_react16.useState)(false);
1622
+ const branchesRef = (0, import_react16.useRef)(branches);
1623
+ (0, import_react16.useEffect)(() => {
1624
+ branchesRef.current = branches;
1625
+ }, [branches]);
1626
+ const loadInitialBranches = (0, import_react16.useCallback)(async () => {
1627
+ setIsLoading(true);
1628
+ try {
1629
+ try {
1630
+ const b = await arvoreCtrl.get("branchByBranchLevel/1");
1631
+ setBranches(Array.isArray(b) ? b : []);
1632
+ } catch (err) {
1633
+ console.warn("[RecursoDisplayerVM] branchByBranchLevel/1 failed:", err);
1634
+ setBranches([]);
823
1635
  }
824
- };
825
- document.addEventListener("mousedown", handleClickOutside);
826
- return () => document.removeEventListener("mousedown", handleClickOutside);
827
- }, [backOnBranch, branch]);
828
- const handleItemClick = (bn) => {
829
- const rec = bn.recurso;
830
- if (multiMode) {
831
- setMultiSelected(
832
- (prev) => prev.some((r) => r.id === rec.id) ? prev.filter((r) => r.id !== rec.id) : [...prev, rec]
833
- );
834
- } else {
835
- onSaveRecurso([rec]);
836
- addBranch(bn);
837
- setShow(false);
1636
+ try {
1637
+ const lv = await branchLevelCtrl.readAll();
1638
+ dispatch(setLevels(Array.isArray(lv) ? lv : []));
1639
+ } catch (err) {
1640
+ console.warn("[RecursoDisplayerVM] branchLevel.readAll failed:", err);
1641
+ }
1642
+ } finally {
1643
+ setIsLoading(false);
838
1644
  }
839
- };
840
- const startMulti = () => {
841
- setMultiSelected([]);
842
- setMultiMode(true);
843
- setShow(true);
844
- };
845
- const handleConfirm = () => {
846
- setMultiMode(false);
847
- onSaveRecurso(multiSelected);
848
- setMultiSelected([]);
849
- setShow(false);
850
- };
851
- const cancelMulti = () => {
852
- setMultiMode(false);
853
- setMultiSelected([]);
854
- };
855
- const isLastBranchClicked = () => branches.length > 0 && branches[branches.length - 1].id === branch.id;
856
- const visibleNodes = (branch.branchNodes || []).filter(
857
- (bn) => bn.recurso.nome.toLowerCase().includes(searchTerm.toLowerCase())
858
- );
859
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
860
- "div",
861
- {
862
- ref: dropdownRef,
863
- style: {
864
- position: "relative",
865
- marginBottom: "0.5rem",
866
- width: "100%",
867
- fontFamily: "Arial, sans-serif"
868
- },
869
- children: [
870
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
871
- "button",
872
- {
873
- onClick: () => setShow((s) => !s),
874
- style: {
875
- width: "100%",
876
- display: "flex",
877
- alignItems: "center",
878
- justifyContent: "space-between",
879
- padding: "0.5rem 1rem",
880
- borderRadius: "9999px",
881
- boxShadow: "0 1px 3px rgba(0, 0, 0, 0.1)",
882
- border: `1px solid ${branch.branchLevel.color}`,
883
- background: branch.branchLevel.color,
884
- color: fontColor,
885
- cursor: "pointer",
886
- outline: "none",
887
- textAlign: "left",
888
- fontSize: "1rem"
889
- },
890
- children: [
891
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: [
892
- branch.nomeRecurso || branch.branchLevel.nome,
893
- branch.nomeRecurso && !multiMode && isLastBranchClicked() && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("em", { style: { fontStyle: "italic", opacity: 0.8, marginLeft: "0.5rem" }, children: "(Selecionado)" })
894
- ] }),
895
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaChevronDown, {})
896
- ]
1645
+ }, [arvoreCtrl, branchLevelCtrl, dispatch]);
1646
+ const advanceBranch = (0, import_react16.useCallback)(
1647
+ async (bn) => {
1648
+ var _a2, _b2, _c, _d;
1649
+ setIsLoading(true);
1650
+ try {
1651
+ const current = branchesRef.current;
1652
+ const parentBranch = current.find((b) => b.id === bn.branchId);
1653
+ const currentLevel = (_b2 = (_a2 = parentBranch == null ? void 0 : parentBranch.branchLevel) == null ? void 0 : _a2.level) != null ? _b2 : 1;
1654
+ const branchsToStay = current.filter((b) => {
1655
+ var _a3, _b3;
1656
+ return ((_b3 = (_a3 = b.branchLevel) == null ? void 0 : _a3.level) != null ? _b3 : 0) <= currentLevel;
1657
+ }).map(
1658
+ (b) => {
1659
+ var _a3;
1660
+ return ((_a3 = b.branchLevel) == null ? void 0 : _a3.level) === currentLevel ? { ...b, nomeRecurso: bn.recurso.nome } : b;
897
1661
  }
898
- ),
899
- show && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
900
- "div",
901
- {
902
- style: {
903
- position: "absolute",
904
- top: "100%",
905
- left: 0,
906
- width: "100%",
907
- background: "#f0f0f0",
908
- borderRadius: "8px",
909
- boxShadow: "0 2px 6px rgba(0, 0, 0, 0.15)",
910
- marginTop: "0.25rem",
911
- zIndex: 100,
912
- maxHeight: "300px",
913
- overflow: "auto"
914
- },
915
- children: [
916
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
917
- "div",
918
- {
919
- style: {
920
- display: "flex",
921
- alignItems: "center",
922
- padding: "0.5rem",
923
- borderBottom: "1px solid #ddd"
924
- },
925
- children: [
926
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaSearch, { style: { marginRight: "0.5rem", color: "#555" } }),
927
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
928
- "input",
929
- {
930
- type: "text",
931
- placeholder: "Pesquisar recurso...",
932
- value: searchTerm,
933
- onChange: (e) => setSearchTerm(e.target.value),
934
- style: {
935
- flex: 1,
936
- padding: "0.5rem",
937
- border: "1px solid #ccc",
938
- borderRadius: "9999px",
939
- outline: "none",
940
- fontSize: "0.95rem"
941
- }
942
- }
943
- )
944
- ]
945
- }
946
- ),
947
- !multiMode && !singleReturn ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
948
- "button",
949
- {
950
- onClick: startMulti,
951
- style: {
952
- display: "flex",
953
- alignItems: "center",
954
- justifyContent: "center",
955
- width: "100%",
956
- padding: "0.5rem",
957
- borderRadius: "9999px",
958
- border: "none",
959
- background: "#ffc107",
960
- color: "#000",
961
- fontSize: "0.95rem",
962
- cursor: "pointer",
963
- margin: "0.5rem 0"
964
- },
965
- children: [
966
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaCheckSquare, { style: { marginRight: "0.5rem" } }),
967
- "Selecionar m\xFAltiplos"
968
- ]
969
- }
970
- ) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", gap: "0.5rem", margin: "0.5rem 0" }, children: [
971
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
972
- "button",
973
- {
974
- onClick: handleConfirm,
975
- style: {
976
- flex: 1,
977
- display: "flex",
978
- alignItems: "center",
979
- justifyContent: "center",
980
- padding: "0.5rem",
981
- borderRadius: "9999px",
982
- border: "none",
983
- background: "#28a745",
984
- color: "#fff",
985
- fontSize: "0.95rem",
986
- cursor: "pointer"
987
- },
988
- children: [
989
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaCheck, { style: { marginRight: "0.5rem" } }),
990
- "Confirmar sele\xE7\xE3o"
991
- ]
992
- }
993
- ),
994
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
995
- "button",
996
- {
997
- onClick: cancelMulti,
998
- style: {
999
- flex: 1,
1000
- display: "flex",
1001
- alignItems: "center",
1002
- justifyContent: "center",
1003
- padding: "0.5rem",
1004
- borderRadius: "9999px",
1005
- border: "none",
1006
- background: "#6c757d",
1007
- color: "#fff",
1008
- fontSize: "0.95rem",
1009
- cursor: "pointer"
1010
- },
1011
- children: [
1012
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_md.MdClose, { style: { marginRight: "0.5rem" } }),
1013
- "Cancelar"
1014
- ]
1015
- }
1016
- )
1017
- ] }),
1018
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { padding: "0.5rem" }, children: visibleNodes.map((bn) => {
1019
- const selected = multiMode ? multiSelected.some((r) => r.id === bn.recurso.id) : false;
1020
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1021
- "div",
1022
- {
1023
- onClick: () => handleItemClick(bn),
1024
- style: {
1025
- display: "flex",
1026
- justifyContent: "space-between",
1027
- alignItems: "center",
1028
- padding: "0.5rem",
1029
- borderBottom: "1px solid #ddd",
1030
- background: selected ? "#e9ecef" : "transparent",
1031
- cursor: "pointer",
1032
- transition: "background 0.1s"
1033
- },
1034
- onMouseEnter: (e) => {
1035
- if (!selected) e.currentTarget.style.background = "#e2e6ea";
1036
- },
1037
- onMouseLeave: (e) => {
1038
- e.currentTarget.style.background = selected ? "#e9ecef" : "transparent";
1039
- },
1040
- children: [
1041
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: bn.recurso.nome }),
1042
- selected && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaCheck, {})
1043
- ]
1044
- },
1045
- bn.recurso.id
1046
- );
1047
- }) })
1048
- ]
1662
+ );
1663
+ const nextBranchId = (_d = bn.recurso.branchId) != null ? _d : (_c = bn.recurso.branch) == null ? void 0 : _c.id;
1664
+ if (nextBranchId) {
1665
+ try {
1666
+ const nextBranch = await arvoreCtrl.read("branch", nextBranchId);
1667
+ if (nextBranch && nextBranch.branchLevel) {
1668
+ branchsToStay.push(nextBranch);
1669
+ }
1670
+ } catch (e) {
1671
+ console.warn(
1672
+ "[RecursoDisplayerVM] Failed to fetch child branch:",
1673
+ e
1674
+ );
1049
1675
  }
1050
- )
1051
- ]
1052
- }
1676
+ }
1677
+ setBranches([...branchsToStay]);
1678
+ } finally {
1679
+ setIsLoading(false);
1680
+ }
1681
+ },
1682
+ [arvoreCtrl]
1053
1683
  );
1054
- };
1055
- var BranchDropDisplay_default = BranchDropDisplay;
1684
+ const backToBranch = (0, import_react16.useCallback)((branch) => {
1685
+ setBranches(
1686
+ (prev) => prev.filter(
1687
+ (b) => {
1688
+ var _a2, _b2, _c, _d;
1689
+ return ((_b2 = (_a2 = b.branchLevel) == null ? void 0 : _a2.level) != null ? _b2 : 0) <= ((_d = (_c = branch.branchLevel) == null ? void 0 : _c.level) != null ? _d : 0);
1690
+ }
1691
+ )
1692
+ );
1693
+ }, []);
1694
+ const reset = (0, import_react16.useCallback)(() => {
1695
+ setBranches([]);
1696
+ }, []);
1697
+ return (0, import_react16.useMemo)(
1698
+ () => ({
1699
+ branches,
1700
+ isLoading,
1701
+ loadInitialBranches,
1702
+ advanceBranch,
1703
+ backToBranch,
1704
+ reset
1705
+ }),
1706
+ [branches, isLoading, loadInitialBranches, advanceBranch, backToBranch, reset]
1707
+ );
1708
+ }
1056
1709
 
1057
- // src/components/recurso/FindRecursoByTagField.tsx
1058
- var import_react16 = require("react");
1059
- var import_gr = require("react-icons/gr");
1710
+ // src/viewmodels/ReduxFindRecursoByTagAdapter.ts
1711
+ var import_react17 = require("react");
1712
+ function useFindRecursoByTagViewModel(overrides = {}) {
1713
+ var _a;
1714
+ const defaultRecurso = useHttpController("recurso");
1715
+ const recursoCtrl = (_a = overrides.recursoController) != null ? _a : defaultRecurso;
1716
+ const [isSearching, setIsSearching] = (0, import_react17.useState)(false);
1717
+ const loadActiveTags = (0, import_react17.useCallback)(async () => {
1718
+ try {
1719
+ const res = await recursoCtrl.get("findActiveRecursosTags");
1720
+ return Array.isArray(res) ? res : [];
1721
+ } catch (err) {
1722
+ console.warn("[FindRecursoByTagVM] loadActiveTags failed:", err);
1723
+ return [];
1724
+ }
1725
+ }, [recursoCtrl]);
1726
+ const searchByTagId = (0, import_react17.useCallback)(
1727
+ async (tagId) => {
1728
+ setIsSearching(true);
1729
+ try {
1730
+ const r = await recursoCtrl.read("findRecursoByTagId", tagId);
1731
+ return r != null ? r : null;
1732
+ } catch (err) {
1733
+ console.error("[FindRecursoByTagVM] searchByTagId failed:", err);
1734
+ return null;
1735
+ } finally {
1736
+ setIsSearching(false);
1737
+ }
1738
+ },
1739
+ [recursoCtrl]
1740
+ );
1741
+ const searchByTag = (0, import_react17.useCallback)(
1742
+ async (description) => {
1743
+ setIsSearching(true);
1744
+ try {
1745
+ const formatted = description.replace(/\s/g, "");
1746
+ const r = await recursoCtrl.read(
1747
+ "recurso/findByTagDescription",
1748
+ formatted
1749
+ );
1750
+ return r != null ? r : null;
1751
+ } catch (err) {
1752
+ console.error("[FindRecursoByTagVM] searchByTag failed:", err);
1753
+ return null;
1754
+ } finally {
1755
+ setIsSearching(false);
1756
+ }
1757
+ },
1758
+ [recursoCtrl]
1759
+ );
1760
+ return (0, import_react17.useMemo)(
1761
+ () => ({
1762
+ isSearching,
1763
+ loadActiveTags,
1764
+ searchByTagId,
1765
+ searchByTag
1766
+ }),
1767
+ [isSearching, loadActiveTags, searchByTagId, searchByTag]
1768
+ );
1769
+ }
1060
1770
 
1061
- // src/components/recurso/AutoComplete.tsx
1062
- var import_react13 = require("react");
1063
- var import_react_bootstrap = require("react-bootstrap");
1064
- var import_jsx_runtime2 = require("react/jsx-runtime");
1065
- var AutoComplete = ({
1066
- className,
1067
- ops,
1068
- sortKey,
1069
- displayKey,
1070
- displayKeys,
1071
- onValueChanged,
1072
- selectedKey,
1073
- onSelectedClick,
1074
- value,
1075
- actionButton,
1076
- actionButton2,
1077
- placeH,
1078
- title,
1079
- filter,
1080
- filterField,
1081
- loadFunc,
1082
- loadCondition,
1083
- isBold,
1084
- onBlurEvent,
1085
- formatationFunc,
1086
- onEscKeyDown,
1087
- margT,
1088
- hideComponent,
1089
- disableComponent = false,
1090
- disableSelect = false,
1091
- margB,
1092
- autoFocusConfig,
1093
- onLoad,
1094
- onMouseLv,
1095
- useStandardLabel = false,
1096
- isRequired = false,
1097
- ty = "text"
1098
- }) => {
1099
- const [liItem, setListItem] = (0, import_react13.useState)([]);
1100
- const [options, setOptions] = (0, import_react13.useState)([]);
1101
- const [input, setInput] = (0, import_react13.useState)("");
1102
- const [hide, setHide] = (0, import_react13.useState)(true);
1103
- const [onLoaded, setOnLoaded] = (0, import_react13.useState)(false);
1104
- const sortOptions = (opts, key) => {
1105
- if (!key || !Array.isArray(opts)) return opts != null ? opts : [];
1106
- return [...opts].sort((a, b) => String(a[key]).localeCompare(String(b[key])));
1107
- };
1108
- (0, import_react13.useEffect)(() => {
1109
- if (value) setInput(value);
1110
- else setInput("");
1111
- }, [value]);
1112
- (0, import_react13.useEffect)(() => {
1113
- const sortedOptions = sortOptions(ops, sortKey);
1114
- setListItem(sortedOptions);
1115
- setOptions(sortedOptions);
1116
- }, [ops, sortKey]);
1117
- (0, import_react13.useEffect)(() => {
1118
- const loadFunction = async () => {
1119
- if (loadCondition && loadFunc) {
1120
- try {
1121
- const res = await loadFunc();
1122
- let newOps = res.content ? res.content : res;
1123
- newOps = newOps.filter((c) => c != null);
1124
- if (Array.isArray(newOps)) {
1125
- if (filter) {
1126
- newOps = newOps.filter((op) => op[filterField] === filter);
1127
- }
1128
- const sortedOptions = sortOptions(newOps, sortKey);
1129
- setListItem(sortedOptions);
1130
- setOptions(sortedOptions);
1131
- }
1132
- if (onLoad) {
1133
- if (onLoaded) return;
1134
- setOnLoaded(true);
1135
- onLoad(newOps);
1136
- }
1137
- } catch (e) {
1138
- setListItem([]);
1771
+ // src/viewmodels/ReduxJustificativaModalAdapter.ts
1772
+ var import_react18 = require("react");
1773
+ function localId() {
1774
+ return `local_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
1775
+ }
1776
+ function runValidate3(draft) {
1777
+ const errors = {};
1778
+ if (!draft || !draft.trim()) {
1779
+ errors.draft = "Descreva o motivo antes de adicionar.";
1780
+ }
1781
+ return { ok: Object.keys(errors).length === 0, errors };
1782
+ }
1783
+ function useJustificativaModalViewModel(opts) {
1784
+ const { initialJustificativas = [], currentUser, onUpdate } = opts;
1785
+ const [justificativas, setJustificativas] = (0, import_react18.useState)(
1786
+ initialJustificativas
1787
+ );
1788
+ const [draft, setDraft] = (0, import_react18.useState)("");
1789
+ const [editingId, setEditingId] = (0, import_react18.useState)(null);
1790
+ const [isSubmitting, setIsSubmitting] = (0, import_react18.useState)(false);
1791
+ const initialRef = (0, import_react18.useRef)(initialJustificativas);
1792
+ (0, import_react18.useEffect)(() => {
1793
+ initialRef.current = initialJustificativas;
1794
+ setJustificativas(initialJustificativas);
1795
+ }, [initialJustificativas]);
1796
+ const commit = (0, import_react18.useCallback)(
1797
+ async (next) => {
1798
+ setJustificativas(next);
1799
+ if (!onUpdate) return next;
1800
+ try {
1801
+ const maybe = await Promise.resolve(onUpdate(next));
1802
+ if (Array.isArray(maybe)) {
1803
+ setJustificativas(maybe);
1804
+ return maybe;
1139
1805
  }
1806
+ } catch (e) {
1807
+ }
1808
+ return next;
1809
+ },
1810
+ [onUpdate]
1811
+ );
1812
+ const startEdit = (0, import_react18.useCallback)(
1813
+ (id) => {
1814
+ var _a;
1815
+ const target = justificativas.find((j) => j.id === id);
1816
+ if (!target || target.removed) return;
1817
+ setEditingId(id);
1818
+ setDraft((_a = target.descricao) != null ? _a : "");
1819
+ },
1820
+ [justificativas]
1821
+ );
1822
+ const cancelEdit = (0, import_react18.useCallback)(() => {
1823
+ setEditingId(null);
1824
+ setDraft("");
1825
+ }, []);
1826
+ const addOrEdit = (0, import_react18.useCallback)(async () => {
1827
+ const result = runValidate3(draft);
1828
+ if (!result.ok) return justificativas;
1829
+ setIsSubmitting(true);
1830
+ try {
1831
+ let next;
1832
+ if (editingId != null) {
1833
+ next = justificativas.map(
1834
+ (j) => j.id === editingId ? { ...j, descricao: draft } : j
1835
+ );
1836
+ } else {
1837
+ const nova = {
1838
+ id: localId(),
1839
+ descricao: draft,
1840
+ user: currentUser,
1841
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1842
+ isNew: true
1843
+ };
1844
+ next = [...justificativas, nova];
1140
1845
  }
1846
+ const committed = await commit(next);
1847
+ setDraft("");
1848
+ setEditingId(null);
1849
+ return committed;
1850
+ } finally {
1851
+ setIsSubmitting(false);
1852
+ }
1853
+ }, [draft, editingId, justificativas, currentUser, commit]);
1854
+ const remove = (0, import_react18.useCallback)(
1855
+ async (id) => {
1856
+ const next = justificativas.map(
1857
+ (j) => j.id === id ? { ...j, removed: true } : j
1858
+ );
1859
+ return commit(next);
1860
+ },
1861
+ [justificativas, commit]
1862
+ );
1863
+ const undoRemove = (0, import_react18.useCallback)(
1864
+ async (id) => {
1865
+ const next = justificativas.map(
1866
+ (j) => j.id === id ? { ...j, removed: false } : j
1867
+ );
1868
+ return commit(next);
1869
+ },
1870
+ [justificativas, commit]
1871
+ );
1872
+ const validate = (0, import_react18.useCallback)(
1873
+ () => runValidate3(draft),
1874
+ [draft]
1875
+ );
1876
+ const reset = (0, import_react18.useCallback)(() => {
1877
+ setJustificativas(initialRef.current);
1878
+ setDraft("");
1879
+ setEditingId(null);
1880
+ }, []);
1881
+ const populateFromExisting = (0, import_react18.useCallback)((list) => {
1882
+ initialRef.current = list;
1883
+ setJustificativas(list);
1884
+ setDraft("");
1885
+ setEditingId(null);
1886
+ }, []);
1887
+ return (0, import_react18.useMemo)(
1888
+ () => ({
1889
+ justificativas,
1890
+ draft,
1891
+ editingId,
1892
+ isSubmitting,
1893
+ setDraft,
1894
+ startEdit,
1895
+ cancelEdit,
1896
+ addOrEdit,
1897
+ remove,
1898
+ undoRemove,
1899
+ validate,
1900
+ reset,
1901
+ populateFromExisting
1902
+ }),
1903
+ [
1904
+ justificativas,
1905
+ draft,
1906
+ editingId,
1907
+ isSubmitting,
1908
+ startEdit,
1909
+ cancelEdit,
1910
+ addOrEdit,
1911
+ remove,
1912
+ undoRemove,
1913
+ validate,
1914
+ reset,
1915
+ populateFromExisting
1916
+ ]
1917
+ );
1918
+ }
1919
+
1920
+ // src/viewmodels/ReduxAnexoManagerAdapter.ts
1921
+ var import_react19 = require("react");
1922
+ function useAnexoManagerViewModel(opts) {
1923
+ const base = useAnexoManager(opts);
1924
+ return (0, import_react19.useMemo)(
1925
+ () => ({
1926
+ persistidos: base.persistidos,
1927
+ locais: base.locais,
1928
+ loading: base.loading,
1929
+ loadAnexos: base.loadAnexos,
1930
+ addFiles: base.addFiles,
1931
+ removeLocal: base.removeLocal,
1932
+ uploadAll: base.uploadAll,
1933
+ removePersistido: base.removePersistido,
1934
+ getUrl: base.getUrl
1935
+ }),
1936
+ [
1937
+ base.persistidos,
1938
+ base.locais,
1939
+ base.loading,
1940
+ base.loadAnexos,
1941
+ base.addFiles,
1942
+ base.removeLocal,
1943
+ base.uploadAll,
1944
+ base.removePersistido,
1945
+ base.getUrl
1946
+ ]
1947
+ );
1948
+ }
1949
+
1950
+ // src/viewmodels/useRecorrenciaViewModel.ts
1951
+ var import_react20 = require("react");
1952
+ var import_react_redux6 = require("react-redux");
1953
+
1954
+ // src/viewmodels/recorrenciaSlice.ts
1955
+ var import_toolkit4 = require("@reduxjs/toolkit");
1956
+ var DEFAULT_KEY3 = "__default__";
1957
+ var initialState4 = {
1958
+ byEntity: {}
1959
+ };
1960
+ var keyOf3 = (entityId) => entityId === void 0 || entityId === null || entityId === "" ? DEFAULT_KEY3 : String(entityId);
1961
+ var ensureSlot = (state, key) => {
1962
+ const existing = state.byEntity[key];
1963
+ if (!existing) {
1964
+ const fresh = {
1965
+ valor: 1,
1966
+ escala: "day",
1967
+ dataInicio: void 0
1141
1968
  };
1142
- loadFunction();
1143
- }, [loadCondition, filter, filterField, sortKey, onLoad]);
1144
- const onFieldUpdate = (val) => {
1145
- let newListItem;
1146
- if (val && val.length > 0) {
1147
- const regex = new RegExp(`${val}`, "i");
1148
- newListItem = options.filter((liI) => {
1149
- let textToTest;
1150
- if (formatationFunc) {
1151
- textToTest = formatationFunc(liI);
1152
- } else if (displayKey) {
1153
- textToTest = liI[displayKey];
1154
- } else if (displayKeys) {
1155
- textToTest = keysJoinner(liI);
1156
- } else {
1157
- textToTest = liI;
1158
- }
1159
- return regex.test(textToTest);
1160
- });
1161
- setListItem(newListItem);
1162
- } else {
1163
- setListItem(options);
1969
+ state.byEntity[key] = fresh;
1970
+ return fresh;
1971
+ }
1972
+ return existing;
1973
+ };
1974
+ var recorrenciaSlice = (0, import_toolkit4.createSlice)({
1975
+ name: "recorrenciaVm",
1976
+ initialState: initialState4,
1977
+ reducers: {
1978
+ setValor(state, action) {
1979
+ const key = keyOf3(action.payload.entityId);
1980
+ ensureSlot(state, key).valor = action.payload.value;
1981
+ },
1982
+ setEscala(state, action) {
1983
+ const key = keyOf3(action.payload.entityId);
1984
+ ensureSlot(state, key).escala = action.payload.value;
1985
+ },
1986
+ setDataInicio(state, action) {
1987
+ const key = keyOf3(action.payload.entityId);
1988
+ const next = action.payload.value;
1989
+ ensureSlot(state, key).dataInicio = next === null || next === void 0 || next === "" ? void 0 : next;
1990
+ },
1991
+ populate(state, action) {
1992
+ const key = keyOf3(action.payload.entityId);
1993
+ state.byEntity[key] = action.payload.value ? { ...action.payload.value } : null;
1994
+ },
1995
+ clearRecorrencia(state, action) {
1996
+ var _a;
1997
+ const key = keyOf3((_a = action.payload) == null ? void 0 : _a.entityId);
1998
+ state.byEntity[key] = null;
1164
1999
  }
1165
- onValueChanged && onValueChanged(val);
1166
- setInput(val);
1167
- setHide(false);
1168
- };
1169
- const clear = () => {
1170
- setInput("");
1171
- };
1172
- const onOpSelected = (li, index, lItem) => {
1173
- if (formatationFunc) {
1174
- setInput(formatationFunc(li));
1175
- } else if (displayKey) {
1176
- setInput(li[displayKey]);
1177
- } else if (displayKeys) {
1178
- setInput(keysJoinner(li));
1179
- } else {
1180
- setInput(li);
2000
+ }
2001
+ });
2002
+ var {
2003
+ setValor: setRecorrenciaValor,
2004
+ setEscala: setRecorrenciaEscala,
2005
+ setDataInicio: setRecorrenciaDataInicio,
2006
+ populate: populateRecorrencia,
2007
+ clearRecorrencia
2008
+ } = recorrenciaSlice.actions;
2009
+ var selectRecorrencia = (state, entityId) => {
2010
+ var _a, _b;
2011
+ const key = keyOf3(entityId);
2012
+ const slice3 = (_a = state == null ? void 0 : state.recorrenciaVm) != null ? _a : state == null ? void 0 : state.recorrencia;
2013
+ const slot = (_b = slice3 == null ? void 0 : slice3.byEntity) == null ? void 0 : _b[key];
2014
+ return slot === void 0 ? null : slot;
2015
+ };
2016
+ var recorrenciaSlice_default = recorrenciaSlice.reducer;
2017
+
2018
+ // src/viewmodels/useRecorrenciaViewModel.ts
2019
+ function runValidate4(value) {
2020
+ const errors = {};
2021
+ if (value === null) {
2022
+ errors._absent = "Sem recorrencia definida.";
2023
+ return { ok: false, errors };
2024
+ }
2025
+ const valor = Number(value.valor);
2026
+ if (!Number.isFinite(valor) || valor < 1) {
2027
+ errors.valor = "O valor da recorrencia deve ser >= 1.";
2028
+ }
2029
+ if (!value.escala) {
2030
+ errors.escala = "A escala eh obrigatoria.";
2031
+ }
2032
+ return { ok: Object.keys(errors).length === 0, errors };
2033
+ }
2034
+ function useRecorrenciaViewModel(entityId) {
2035
+ const dispatch = (0, import_react_redux6.useDispatch)();
2036
+ const value = (0, import_react_redux6.useSelector)(
2037
+ (state) => selectRecorrencia(state, entityId)
2038
+ );
2039
+ const [isSubmitting, setIsSubmitting] = (0, import_react20.useState)(false);
2040
+ const onValorChange = (0, import_react20.useCallback)(
2041
+ (valor) => {
2042
+ dispatch(setRecorrenciaValor({ entityId, value: valor }));
2043
+ },
2044
+ [dispatch, entityId]
2045
+ );
2046
+ const onEscalaChange = (0, import_react20.useCallback)(
2047
+ (escala) => {
2048
+ dispatch(setRecorrenciaEscala({ entityId, value: escala }));
2049
+ },
2050
+ [dispatch, entityId]
2051
+ );
2052
+ const onDataInicioChange = (0, import_react20.useCallback)(
2053
+ (dataInicio) => {
2054
+ dispatch(setRecorrenciaDataInicio({ entityId, value: dataInicio }));
2055
+ },
2056
+ [dispatch, entityId]
2057
+ );
2058
+ const clear = (0, import_react20.useCallback)(() => {
2059
+ dispatch(clearRecorrencia({ entityId }));
2060
+ }, [dispatch, entityId]);
2061
+ const populateFromExisting = (0, import_react20.useCallback)(
2062
+ (next) => {
2063
+ dispatch(populateRecorrencia({ entityId, value: next }));
2064
+ },
2065
+ [dispatch, entityId]
2066
+ );
2067
+ const validate = (0, import_react20.useCallback)(
2068
+ () => runValidate4(value),
2069
+ [value]
2070
+ );
2071
+ const submit = (0, import_react20.useCallback)(async () => {
2072
+ var _a;
2073
+ setIsSubmitting(true);
2074
+ try {
2075
+ if (value === null) return null;
2076
+ const result = runValidate4(value);
2077
+ if (!result.ok) {
2078
+ const firstErr = (_a = Object.values(result.errors)[0]) != null ? _a : "Dados invalidos.";
2079
+ throw new Error(firstErr);
2080
+ }
2081
+ return value;
2082
+ } finally {
2083
+ setIsSubmitting(false);
1181
2084
  }
1182
- onSelectedClick(li, index, lItem);
1183
- setHide(true);
1184
- };
1185
- const keysJoinner = (li) => {
1186
- if (!displayKeys || !Array.isArray(displayKeys)) return "";
1187
- const textToRender = displayKeys.map((key) => `${li[key]} `);
1188
- return textToRender.join("").trim();
1189
- };
1190
- const renderMoreThanOneKey = (li, index) => {
1191
- const buildedString = keysJoinner(li);
1192
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("li", { children: buildedString }, index);
1193
- };
1194
- const boldedPart = (text, key) => {
1195
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("li", { children: text }, key);
2085
+ }, [value]);
2086
+ const isValid = (0, import_react20.useMemo)(() => runValidate4(value).ok, [value]);
2087
+ return (0, import_react20.useMemo)(
2088
+ () => ({
2089
+ value,
2090
+ isValid,
2091
+ isSubmitting,
2092
+ onValorChange,
2093
+ onEscalaChange,
2094
+ onDataInicioChange,
2095
+ clear,
2096
+ populateFromExisting,
2097
+ validate,
2098
+ submit,
2099
+ reset: clear
2100
+ }),
2101
+ [
2102
+ value,
2103
+ isValid,
2104
+ isSubmitting,
2105
+ onValorChange,
2106
+ onEscalaChange,
2107
+ onDataInicioChange,
2108
+ clear,
2109
+ populateFromExisting,
2110
+ validate,
2111
+ submit
2112
+ ]
2113
+ );
2114
+ }
2115
+
2116
+ // src/viewmodels/useContadorViewModel.ts
2117
+ var import_react21 = require("react");
2118
+ var import_react_redux7 = require("react-redux");
2119
+
2120
+ // src/viewmodels/contadorSlice.ts
2121
+ var import_toolkit5 = require("@reduxjs/toolkit");
2122
+ var DEFAULT_KEY4 = "__default__";
2123
+ var emptyValue3 = {
2124
+ valor: null,
2125
+ unidade: null,
2126
+ parametro: null,
2127
+ limitesDeControle: []
2128
+ };
2129
+ var initialState5 = {
2130
+ byEntity: {}
2131
+ };
2132
+ var keyOf4 = (entityId) => entityId === void 0 || entityId === null || entityId === "" ? DEFAULT_KEY4 : String(entityId);
2133
+ var ensure3 = (state, key) => {
2134
+ if (!state.byEntity[key]) {
2135
+ state.byEntity[key] = { ...emptyValue3, limitesDeControle: [] };
2136
+ }
2137
+ return state.byEntity[key];
2138
+ };
2139
+ var contadorSlice = (0, import_toolkit5.createSlice)({
2140
+ name: "contadorVm",
2141
+ initialState: initialState5,
2142
+ reducers: {
2143
+ setValor(state, action) {
2144
+ ensure3(state, keyOf4(action.payload.entityId)).valor = action.payload.value;
2145
+ },
2146
+ setUnidade(state, action) {
2147
+ ensure3(state, keyOf4(action.payload.entityId)).unidade = action.payload.value;
2148
+ },
2149
+ setParametro(state, action) {
2150
+ ensure3(state, keyOf4(action.payload.entityId)).parametro = action.payload.value;
2151
+ },
2152
+ addLimite(state, action) {
2153
+ var _a;
2154
+ const slot = ensure3(state, keyOf4(action.payload.entityId));
2155
+ slot.limitesDeControle = [
2156
+ ...(_a = slot.limitesDeControle) != null ? _a : [],
2157
+ action.payload.value
2158
+ ];
2159
+ },
2160
+ removeLimiteAt(state, action) {
2161
+ var _a;
2162
+ const slot = ensure3(state, keyOf4(action.payload.entityId));
2163
+ const list = (_a = slot.limitesDeControle) != null ? _a : [];
2164
+ slot.limitesDeControle = list.filter(
2165
+ (_, i) => i !== action.payload.index
2166
+ );
2167
+ },
2168
+ updateLimiteAt(state, action) {
2169
+ var _a;
2170
+ const slot = ensure3(state, keyOf4(action.payload.entityId));
2171
+ const list = [...(_a = slot.limitesDeControle) != null ? _a : []];
2172
+ if (action.payload.index >= 0 && action.payload.index < list.length) {
2173
+ list[action.payload.index] = action.payload.value;
2174
+ slot.limitesDeControle = list;
2175
+ }
2176
+ },
2177
+ populate(state, action) {
2178
+ var _a;
2179
+ const key = keyOf4(action.payload.entityId);
2180
+ const v = (_a = action.payload.value) != null ? _a : emptyValue3;
2181
+ state.byEntity[key] = {
2182
+ ...emptyValue3,
2183
+ ...v,
2184
+ limitesDeControle: Array.isArray(v.limitesDeControle) ? [...v.limitesDeControle] : []
2185
+ };
2186
+ },
2187
+ clearContador(state, action) {
2188
+ var _a;
2189
+ const key = keyOf4((_a = action.payload) == null ? void 0 : _a.entityId);
2190
+ state.byEntity[key] = { ...emptyValue3, limitesDeControle: [] };
2191
+ }
2192
+ }
2193
+ });
2194
+ var {
2195
+ setValor: setContadorValor,
2196
+ setUnidade: setContadorUnidade,
2197
+ setParametro: setContadorParametro,
2198
+ addLimite: addContadorLimite,
2199
+ removeLimiteAt: removeContadorLimiteAt,
2200
+ updateLimiteAt: updateContadorLimiteAt,
2201
+ populate: populateContador,
2202
+ clearContador
2203
+ } = contadorSlice.actions;
2204
+ var selectContador = (state, entityId) => {
2205
+ var _a, _b, _c;
2206
+ const key = keyOf4(entityId);
2207
+ const slice3 = (_a = state == null ? void 0 : state.contadorVm) != null ? _a : state == null ? void 0 : state.contador;
2208
+ return (_c = (_b = slice3 == null ? void 0 : slice3.byEntity) == null ? void 0 : _b[key]) != null ? _c : {
2209
+ ...emptyValue3,
2210
+ limitesDeControle: []
1196
2211
  };
1197
- const displayListItens = (li, index) => {
1198
- if (formatationFunc) {
1199
- return boldedPart(formatationFunc(li), index);
2212
+ };
2213
+ var contadorSlice_default = contadorSlice.reducer;
2214
+
2215
+ // src/viewmodels/useContadorViewModel.ts
2216
+ function runValidate5(value) {
2217
+ var _a;
2218
+ const errors = {};
2219
+ if ((value == null ? void 0 : value.valor) !== null && (value == null ? void 0 : value.valor) !== void 0) {
2220
+ if (!Number.isFinite(Number(value.valor))) {
2221
+ errors.valor = "O valor deve ser um n\xFAmero finito.";
1200
2222
  }
1201
- if (displayKey) {
1202
- return boldedPart(li[displayKey], index);
2223
+ }
2224
+ if ((value == null ? void 0 : value.valor) !== null && (value == null ? void 0 : value.valor) !== void 0 && (!value.unidade || String(value.unidade).trim() === "")) {
2225
+ errors.unidade = "Informe a unidade de medida.";
2226
+ }
2227
+ const limites = (_a = value == null ? void 0 : value.limitesDeControle) != null ? _a : [];
2228
+ limites.forEach((l, idx) => {
2229
+ if (!(l == null ? void 0 : l.nome) || String(l.nome).trim() === "") {
2230
+ errors[`limitesDeControle[${idx}].nome`] = "Nome do limite \xE9 obrigat\xF3rio.";
1203
2231
  }
1204
- if (displayKeys) {
1205
- return renderMoreThanOneKey(li, index);
2232
+ if (!(l == null ? void 0 : l.boundRule)) {
2233
+ errors[`limitesDeControle[${idx}].boundRule`] = "Regra de compara\xE7\xE3o \xE9 obrigat\xF3ria.";
1206
2234
  }
1207
- return boldedPart(li, index);
1208
- };
1209
- const onKeyDownHandler = (event) => {
1210
- if (event.key === "Escape") {
1211
- setHide(true);
1212
- onEscKeyDown && onEscKeyDown();
2235
+ const v = Number(l == null ? void 0 : l.valor);
2236
+ if (!Number.isFinite(v)) {
2237
+ errors[`limitesDeControle[${idx}].valor`] = "Valor do limite deve ser num\xE9rico.";
1213
2238
  }
1214
- };
1215
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1216
- "div",
1217
- {
1218
- className: `${className}`,
1219
- style: { marginTop: margT || 4, marginBottom: margB || 4, position: "relative" },
1220
- onBlur: (e) => {
1221
- setTimeout(() => {
1222
- if (onBlurEvent) onBlurEvent(e, input);
1223
- setHide(true);
1224
- }, 200);
1225
- },
1226
- onKeyDown: (event) => onKeyDownHandler(event),
1227
- onMouseLeave: () => {
1228
- setHide(true);
1229
- },
1230
- children: [
1231
- !hideComponent && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
1232
- useStandardLabel && title && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_bootstrap.Form.Label, { children: [
1233
- title,
1234
- isRequired && " *"
1235
- ] }),
1236
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_bootstrap.InputGroup, { children: [
1237
- useStandardLabel ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1238
- import_react_bootstrap.Form.Control,
1239
- {
1240
- autoFocus: autoFocusConfig,
1241
- disabled: disableComponent || disableSelect,
1242
- placeholder: placeH,
1243
- autoComplete: "off",
1244
- value: input,
1245
- onClickCapture: () => {
1246
- setHide(false);
1247
- if (!input) {
1248
- onFieldUpdate("");
1249
- }
1250
- },
1251
- onChange: (event) => onFieldUpdate(event.currentTarget.value),
1252
- type: "text"
1253
- }
1254
- ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_bootstrap.FloatingLabel, { style: { zIndex: 0 }, label: title, controlId: "floatingInput", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1255
- import_react_bootstrap.Form.Control,
1256
- {
1257
- autoFocus: autoFocusConfig,
1258
- disabled: disableComponent || disableSelect,
1259
- placeholder: placeH,
1260
- autoComplete: "off",
1261
- value: input,
1262
- onClickCapture: () => {
1263
- setHide(false);
1264
- if (!input) {
1265
- onFieldUpdate("");
1266
- }
1267
- },
1268
- onChange: (event) => onFieldUpdate(event.currentTarget.value),
1269
- type: "text"
1270
- }
1271
- ) }),
1272
- !disableComponent && actionButton && actionButton(clear),
1273
- !disableComponent && actionButton2 && actionButton2(input)
1274
- ] })
1275
- ] }),
1276
- liItem && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_bootstrap.ListGroup, { className: "listgroup-autocomplete", hidden: hide, children: liItem.map((li, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_bootstrap.ListGroup.Item, { action: true, onClick: () => onOpSelected(li, index, liItem), children: displayListItens(li, index) }, index)) })
1277
- ]
2239
+ });
2240
+ return { ok: Object.keys(errors).length === 0, errors };
2241
+ }
2242
+ function useContadorViewModel(entityId) {
2243
+ const dispatch = (0, import_react_redux7.useDispatch)();
2244
+ const value = (0, import_react_redux7.useSelector)(
2245
+ (state) => selectContador(state, entityId)
2246
+ );
2247
+ const [isSubmitting, setIsSubmitting] = (0, import_react21.useState)(false);
2248
+ const onValorChange = (0, import_react21.useCallback)(
2249
+ (v) => {
2250
+ dispatch(setContadorValor({ entityId, value: v }));
2251
+ },
2252
+ [dispatch, entityId]
2253
+ );
2254
+ const onUnidadeChange = (0, import_react21.useCallback)(
2255
+ (u) => {
2256
+ dispatch(setContadorUnidade({ entityId, value: u }));
2257
+ },
2258
+ [dispatch, entityId]
2259
+ );
2260
+ const onParametroChange = (0, import_react21.useCallback)(
2261
+ (p) => {
2262
+ dispatch(setContadorParametro({ entityId, value: p }));
2263
+ },
2264
+ [dispatch, entityId]
2265
+ );
2266
+ const onLimiteAdd = (0, import_react21.useCallback)(
2267
+ (limite) => {
2268
+ dispatch(addContadorLimite({ entityId, value: limite }));
2269
+ },
2270
+ [dispatch, entityId]
2271
+ );
2272
+ const onLimiteRemove = (0, import_react21.useCallback)(
2273
+ (index) => {
2274
+ dispatch(removeContadorLimiteAt({ entityId, index }));
2275
+ },
2276
+ [dispatch, entityId]
2277
+ );
2278
+ const onLimiteUpdate = (0, import_react21.useCallback)(
2279
+ (index, limite) => {
2280
+ dispatch(updateContadorLimiteAt({ entityId, index, value: limite }));
2281
+ },
2282
+ [dispatch, entityId]
2283
+ );
2284
+ const validate = (0, import_react21.useCallback)(
2285
+ () => runValidate5(value),
2286
+ [value]
2287
+ );
2288
+ const reset = (0, import_react21.useCallback)(() => {
2289
+ dispatch(clearContador({ entityId }));
2290
+ }, [dispatch, entityId]);
2291
+ const populateFromExisting = (0, import_react21.useCallback)(
2292
+ (next) => {
2293
+ dispatch(populateContador({ entityId, value: next }));
2294
+ },
2295
+ [dispatch, entityId]
2296
+ );
2297
+ const submit = (0, import_react21.useCallback)(async () => {
2298
+ var _a;
2299
+ setIsSubmitting(true);
2300
+ try {
2301
+ const result = runValidate5(value);
2302
+ if (!result.ok) {
2303
+ const firstErr = (_a = Object.values(result.errors)[0]) != null ? _a : "Dados inv\xE1lidos.";
2304
+ throw new Error(firstErr);
2305
+ }
2306
+ return value;
2307
+ } finally {
2308
+ setIsSubmitting(false);
1278
2309
  }
2310
+ }, [value]);
2311
+ const isValid = (0, import_react21.useMemo)(() => runValidate5(value).ok, [value]);
2312
+ return (0, import_react21.useMemo)(
2313
+ () => ({
2314
+ value,
2315
+ isValid,
2316
+ isSubmitting,
2317
+ onValorChange,
2318
+ onUnidadeChange,
2319
+ onParametroChange,
2320
+ onLimiteAdd,
2321
+ onLimiteRemove,
2322
+ onLimiteUpdate,
2323
+ validate,
2324
+ submit,
2325
+ reset,
2326
+ populateFromExisting
2327
+ }),
2328
+ [
2329
+ value,
2330
+ isValid,
2331
+ isSubmitting,
2332
+ onValorChange,
2333
+ onUnidadeChange,
2334
+ onParametroChange,
2335
+ onLimiteAdd,
2336
+ onLimiteRemove,
2337
+ onLimiteUpdate,
2338
+ validate,
2339
+ submit,
2340
+ reset,
2341
+ populateFromExisting
2342
+ ]
1279
2343
  );
1280
- };
1281
- var AutoComplete_default = AutoComplete;
2344
+ }
1282
2345
 
1283
- // src/components/recurso/QrCodeScanButton.tsx
1284
- var import_react15 = require("react");
1285
- var import_bs = require("react-icons/bs");
2346
+ // src/viewmodels/useMantenedorPickerViewModel.ts
2347
+ var import_react22 = require("react");
2348
+ var import_react_redux8 = require("react-redux");
1286
2349
 
1287
- // src/components/recurso/QrReader.tsx
1288
- var import_qr_scanner = __toESM(require("qr-scanner"));
1289
- var import_react14 = require("react");
1290
- var import_jsx_runtime3 = require("react/jsx-runtime");
1291
- var QrReader = ({ callback }) => {
1292
- const scanner = (0, import_react14.useRef)(null);
1293
- const videoEl = (0, import_react14.useRef)(null);
1294
- const qrBoxEl = (0, import_react14.useRef)(null);
1295
- const [qrOn, setQrOn] = (0, import_react14.useState)(true);
1296
- const [scannedResult, setScannedResult] = (0, import_react14.useState)("");
1297
- const onScanSuccess = (result) => {
1298
- setScannedResult(result == null ? void 0 : result.data);
1299
- callback(result == null ? void 0 : result.data);
1300
- };
1301
- const onScanFail = (err) => {
1302
- console.error(err);
1303
- };
1304
- (0, import_react14.useEffect)(() => {
1305
- if ((videoEl == null ? void 0 : videoEl.current) && !scanner.current) {
1306
- scanner.current = new import_qr_scanner.default(videoEl.current, onScanSuccess, {
1307
- onDecodeError: onScanFail,
1308
- preferredCamera: "environment",
1309
- highlightScanRegion: true,
1310
- highlightCodeOutline: true,
1311
- overlay: (qrBoxEl == null ? void 0 : qrBoxEl.current) || void 0
1312
- });
1313
- scanner.current.start().then(() => setQrOn(true)).catch((err) => {
1314
- if (err) setQrOn(false);
1315
- });
2350
+ // src/viewmodels/mantenedorPickerSlice.ts
2351
+ var import_toolkit6 = require("@reduxjs/toolkit");
2352
+ var initialState6 = { byEntity: {} };
2353
+ function ensureSlot2(state, key) {
2354
+ if (!state.byEntity[key]) {
2355
+ state.byEntity[key] = {
2356
+ options: [],
2357
+ searchTerm: "",
2358
+ isLoading: false,
2359
+ error: null,
2360
+ pendingConfirm: null
2361
+ };
2362
+ }
2363
+ return state.byEntity[key];
2364
+ }
2365
+ var slice = (0, import_toolkit6.createSlice)({
2366
+ name: "mantenedorPicker",
2367
+ initialState: initialState6,
2368
+ reducers: {
2369
+ setOptions(state, action) {
2370
+ ensureSlot2(state, action.payload.key).options = action.payload.options;
2371
+ },
2372
+ setSearchTerm(state, action) {
2373
+ ensureSlot2(state, action.payload.key).searchTerm = action.payload.term;
2374
+ },
2375
+ setLoading(state, action) {
2376
+ ensureSlot2(state, action.payload.key).isLoading = action.payload.loading;
2377
+ },
2378
+ setError(state, action) {
2379
+ ensureSlot2(state, action.payload.key).error = action.payload.error;
2380
+ },
2381
+ setPendingConfirm(state, action) {
2382
+ ensureSlot2(state, action.payload.key).pendingConfirm = action.payload.item;
2383
+ },
2384
+ clearSlot(state, action) {
2385
+ delete state.byEntity[action.payload.key];
1316
2386
  }
1317
- return () => {
1318
- var _a;
1319
- if (!(videoEl == null ? void 0 : videoEl.current)) {
1320
- (_a = scanner == null ? void 0 : scanner.current) == null ? void 0 : _a.stop();
2387
+ }
2388
+ });
2389
+ var {
2390
+ setOptions: setMantenedorOptions,
2391
+ setSearchTerm: setMantenedorSearchTerm,
2392
+ setLoading: setMantenedorLoading,
2393
+ setError: setMantenedorError,
2394
+ setPendingConfirm: setMantenedorPendingConfirm,
2395
+ clearSlot: clearMantenedorSlot
2396
+ } = slice.actions;
2397
+ var mantenedorPickerSlice_default = slice.reducer;
2398
+
2399
+ // src/viewmodels/useMantenedorPickerViewModel.ts
2400
+ var DEFAULT_KEY5 = "__default__";
2401
+ function useMantenedorPickerViewModel(entityId) {
2402
+ var _a, _b, _c, _d, _e;
2403
+ const key = entityId != null && entityId !== "" ? String(entityId) : DEFAULT_KEY5;
2404
+ const dispatch = (0, import_react_redux8.useDispatch)();
2405
+ const core = useCoreService();
2406
+ const slot = (0, import_react_redux8.useSelector)(
2407
+ (s) => {
2408
+ var _a2, _b2;
2409
+ return (_b2 = (_a2 = s.mantenedorPicker) == null ? void 0 : _a2.byEntity[key]) != null ? _b2 : null;
2410
+ }
2411
+ );
2412
+ const options = (_a = slot == null ? void 0 : slot.options) != null ? _a : [];
2413
+ const searchTerm = (_b = slot == null ? void 0 : slot.searchTerm) != null ? _b : "";
2414
+ const isLoading = (_c = slot == null ? void 0 : slot.isLoading) != null ? _c : false;
2415
+ const error = (_d = slot == null ? void 0 : slot.error) != null ? _d : null;
2416
+ const pendingConfirm = (_e = slot == null ? void 0 : slot.pendingConfirm) != null ? _e : null;
2417
+ const refresh = (0, import_react22.useCallback)(async () => {
2418
+ var _a2;
2419
+ dispatch(setMantenedorLoading({ key, loading: true }));
2420
+ dispatch(setMantenedorError({ key, error: null }));
2421
+ try {
2422
+ const controller = core.createController("mantenedor");
2423
+ const raw = await controller.get("mantenedorDashboard");
2424
+ const list = Array.isArray(raw) ? raw : Array.isArray(raw == null ? void 0 : raw.content) ? raw.content : Array.isArray(raw == null ? void 0 : raw.data) ? raw.data : Array.isArray(raw == null ? void 0 : raw.items) ? raw.items : [];
2425
+ if (typeof window !== "undefined" && window.__DEV__ !== false) {
2426
+ console.debug(
2427
+ `[MantenedorPickerVM] refresh key="${key}" \u2192 ${list.length} options`,
2428
+ { rawType: Array.isArray(raw) ? "array" : typeof raw }
2429
+ );
1321
2430
  }
1322
- };
1323
- }, []);
1324
- (0, import_react14.useEffect)(() => {
1325
- if (!qrOn)
1326
- alert(
1327
- "Camera est\xE1 bloqueada ou inacess\xEDvel. Por Favor habilite a camera nas permiss\xF5es do seu navegador e recarregue a p\xE1gina."
2431
+ dispatch(setMantenedorOptions({ key, options: list }));
2432
+ } catch (e) {
2433
+ if (typeof window !== "undefined" && window.__DEV__ !== false) {
2434
+ console.error("[MantenedorPickerVM] refresh failed", e);
2435
+ }
2436
+ dispatch(
2437
+ setMantenedorError({ key, error: (_a2 = e == null ? void 0 : e.message) != null ? _a2 : "fetch error" })
1328
2438
  );
1329
- }, [qrOn]);
1330
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qr-reader", children: [
1331
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("video", { ref: videoEl }),
1332
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: qrBoxEl, className: "qr-box" }),
1333
- scannedResult && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1334
- "p",
1335
- {
1336
- style: {
1337
- position: "absolute",
1338
- top: 0,
1339
- left: 0,
1340
- zIndex: 99999,
1341
- color: "white"
1342
- },
1343
- children: [
1344
- "Scanned Result: ",
1345
- scannedResult
1346
- ]
2439
+ } finally {
2440
+ dispatch(setMantenedorLoading({ key, loading: false }));
2441
+ }
2442
+ }, [dispatch, key, core]);
2443
+ (0, import_react22.useEffect)(() => {
2444
+ refresh();
2445
+ }, [key]);
2446
+ const search = (0, import_react22.useCallback)(
2447
+ (term) => {
2448
+ dispatch(setMantenedorSearchTerm({ key, term }));
2449
+ },
2450
+ [dispatch, key]
2451
+ );
2452
+ const requestSelect = (0, import_react22.useCallback)(
2453
+ (item, currentOsId) => {
2454
+ if (item._busy && item.osId != null && item.osId !== currentOsId) {
2455
+ dispatch(setMantenedorPendingConfirm({ key, item }));
2456
+ return "confirm";
1347
2457
  }
1348
- )
1349
- ] });
1350
- };
1351
- var QrReader_default = QrReader;
2458
+ return "immediate";
2459
+ },
2460
+ [dispatch, key]
2461
+ );
2462
+ const confirmSelect = (0, import_react22.useCallback)(() => {
2463
+ const item = pendingConfirm;
2464
+ dispatch(setMantenedorPendingConfirm({ key, item: null }));
2465
+ return item;
2466
+ }, [dispatch, key, pendingConfirm]);
2467
+ const cancelConfirm = (0, import_react22.useCallback)(() => {
2468
+ dispatch(setMantenedorPendingConfirm({ key, item: null }));
2469
+ }, [dispatch, key]);
2470
+ const reset = (0, import_react22.useCallback)(() => {
2471
+ dispatch(clearMantenedorSlot({ key }));
2472
+ }, [dispatch, key]);
2473
+ const filteredOptions = (0, import_react22.useMemo)(() => {
2474
+ const term = searchTerm.toLowerCase();
2475
+ return [...options].filter(
2476
+ (o) => {
2477
+ var _a2;
2478
+ return ((_a2 = o.nomeUsuario) != null ? _a2 : "").toLowerCase().includes(term);
2479
+ }
2480
+ ).sort(
2481
+ (a, b) => {
2482
+ var _a2, _b2;
2483
+ return ((_a2 = a.nomeUsuario) != null ? _a2 : "").toLowerCase().localeCompare(((_b2 = b.nomeUsuario) != null ? _b2 : "").toLowerCase());
2484
+ }
2485
+ );
2486
+ }, [options, searchTerm]);
2487
+ return (0, import_react22.useMemo)(
2488
+ () => ({
2489
+ options,
2490
+ filteredOptions,
2491
+ searchTerm,
2492
+ isLoading,
2493
+ error,
2494
+ pendingConfirm,
2495
+ search,
2496
+ refresh,
2497
+ requestSelect,
2498
+ confirmSelect,
2499
+ cancelConfirm,
2500
+ reset
2501
+ }),
2502
+ [
2503
+ options,
2504
+ filteredOptions,
2505
+ searchTerm,
2506
+ isLoading,
2507
+ error,
2508
+ pendingConfirm,
2509
+ search,
2510
+ refresh,
2511
+ requestSelect,
2512
+ confirmSelect,
2513
+ cancelConfirm,
2514
+ reset
2515
+ ]
2516
+ );
2517
+ }
1352
2518
 
1353
- // src/components/recurso/QrCodeScanButton.tsx
1354
- var import_jsx_runtime4 = require("react/jsx-runtime");
1355
- var QrCodeScanButton = ({ callback }) => {
1356
- const [showQr, setShowQr] = (0, import_react15.useState)(false);
1357
- const qrShowHandler = () => {
1358
- setShowQr((prev) => !prev);
1359
- };
1360
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1361
- "div",
1362
- {
1363
- className: "hoverable-div",
1364
- style: {
1365
- border: "solid",
1366
- borderTopRightRadius: "3px",
1367
- borderBottomRightRadius: "3px",
1368
- padding: "8px",
1369
- borderLeft: "none",
1370
- borderColor: "#ccc",
1371
- borderWidth: "1px"
1372
- },
1373
- children: [
1374
- showQr && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1375
- QrReader_default,
1376
- {
1377
- callback: (v) => {
1378
- qrShowHandler();
1379
- callback(v);
1380
- }
1381
- }
1382
- ),
1383
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1384
- import_bs.BsQrCode,
1385
- {
1386
- size: 25,
1387
- onClick: () => {
1388
- qrShowHandler();
1389
- }
1390
- }
1391
- )
1392
- ]
2519
+ // src/viewmodels/ReduxTarefaStatusAdapter.ts
2520
+ var import_react23 = require("react");
2521
+ function useTarefaStatusViewModel(opts) {
2522
+ const { tarefaId, fatherId, initialStatus = "PENDENTE" } = opts;
2523
+ const { createController } = useCoreService();
2524
+ const toast = useToast();
2525
+ const [current, setCurrent] = (0, import_react23.useState)(initialStatus);
2526
+ const [saving, setSaving] = (0, import_react23.useState)(false);
2527
+ const tarefaCtrl = (0, import_react23.useMemo)(
2528
+ () => createController("tarefa"),
2529
+ [createController]
2530
+ );
2531
+ const toggle = (0, import_react23.useCallback)(async () => {
2532
+ if (saving) return;
2533
+ const previous = current;
2534
+ const next = previous === "ENCERRADO" ? "PENDENTE" : "ENCERRADO";
2535
+ setCurrent(next);
2536
+ setSaving(true);
2537
+ try {
2538
+ const body = {
2539
+ status: next
2540
+ };
2541
+ if (fatherId !== void 0 && fatherId !== null) {
2542
+ body.fatherId = fatherId;
2543
+ }
2544
+ await tarefaCtrl.put(String(tarefaId), body);
2545
+ } catch (err) {
2546
+ setCurrent(previous);
2547
+ const msg = (err == null ? void 0 : err.message) || "Nao foi possivel atualizar o status da tarefa.";
2548
+ try {
2549
+ toast.warning(msg);
2550
+ } catch (e) {
2551
+ }
2552
+ } finally {
2553
+ setSaving(false);
1393
2554
  }
2555
+ }, [saving, current, tarefaCtrl, tarefaId, fatherId, toast]);
2556
+ return (0, import_react23.useMemo)(
2557
+ () => ({ current, toggle, saving }),
2558
+ [current, toggle, saving]
1394
2559
  );
1395
- };
1396
- var QrCodeScanButton_default = QrCodeScanButton;
2560
+ }
1397
2561
 
1398
- // src/components/recurso/FindRecursoByTagField.tsx
1399
- var import_jsx_runtime5 = require("react/jsx-runtime");
1400
- var FindRecursoByTagField = ({ callback }) => {
1401
- const recursoController = useHttpController("recurso");
1402
- const [selectedTag, setSelectedTag] = (0, import_react16.useState)(null);
1403
- const [reachedRecurso, setReachedRecurso] = (0, import_react16.useState)(null);
1404
- const findRecursoByTagIdHandler = async (tagId) => {
1405
- const r = await recursoController.read("findRecursoByTagId", tagId);
1406
- setReachedRecurso(r);
1407
- };
1408
- const findRecursoByTagDescriptionHandler = async (description) => {
1409
- const recurso = await recursoController.read(
1410
- "recurso/findByTagDescription",
1411
- description.replace(" ", "")
1412
- );
1413
- if (!callback) {
1414
- console.log(recurso);
1415
- } else {
1416
- callback(recurso, true);
1417
- }
1418
- };
1419
- const confirmRecursoSelectionButton = () => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1420
- "div",
1421
- {
1422
- className: "hoverable-div",
1423
- style: {
1424
- border: "solid",
1425
- borderTopRightRadius: "3px",
1426
- borderBottomRightRadius: "3px",
1427
- padding: "8px",
1428
- borderLeft: "none",
1429
- borderColor: "#ccc",
1430
- borderWidth: "1px"
1431
- },
1432
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_gr.GrCheckmark, { size: 25, onClick: () => callback(reachedRecurso, true) })
1433
- }
2562
+ // src/viewmodels/ReduxObservacoesTarefaAdapter.ts
2563
+ var import_react24 = require("react");
2564
+ function useObservacoesTarefaViewModel(opts) {
2565
+ const { tarefaId } = opts;
2566
+ const { createController } = useCoreService();
2567
+ const toast = useToast();
2568
+ const [list, setList] = (0, import_react24.useState)([]);
2569
+ const [loading, setLoading] = (0, import_react24.useState)(false);
2570
+ const tarefaCtrl = (0, import_react24.useMemo)(
2571
+ () => createController("tarefa"),
2572
+ [createController]
1434
2573
  );
1435
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1436
- AutoComplete_default,
1437
- {
1438
- sortKey: "id",
1439
- loadCondition: true,
1440
- loadFunc: () => recursoController.get("findActiveRecursosTags"),
1441
- displayKey: "descricao",
1442
- title: "Selecione ou Digite a TAG",
1443
- isBold: true,
1444
- actionButton: confirmRecursoSelectionButton,
1445
- actionButton2: () => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1446
- QrCodeScanButton_default,
1447
- {
1448
- callback: (description) => findRecursoByTagDescriptionHandler(description)
1449
- }
1450
- ),
1451
- onSelectedClick: (v) => {
1452
- setSelectedTag(v);
1453
- findRecursoByTagIdHandler(v.id);
1454
- },
1455
- value: selectedTag == null ? void 0 : selectedTag.descricao
2574
+ const load = (0, import_react24.useCallback)(async () => {
2575
+ var _a;
2576
+ setLoading(true);
2577
+ try {
2578
+ const res = await tarefaCtrl.get(
2579
+ `readObservacoesTarefa/${tarefaId}`
2580
+ );
2581
+ setList(Array.isArray(res) ? res : (_a = res == null ? void 0 : res.data) != null ? _a : []);
2582
+ } catch (err) {
2583
+ setList([]);
2584
+ const msg = (err == null ? void 0 : err.message) || "Nao foi possivel carregar as observacoes.";
2585
+ try {
2586
+ toast.warning(msg);
2587
+ } catch (e) {
2588
+ }
2589
+ } finally {
2590
+ setLoading(false);
1456
2591
  }
1457
- ) });
2592
+ }, [tarefaCtrl, tarefaId, toast]);
2593
+ const add = (0, import_react24.useCallback)(
2594
+ async (obs) => {
2595
+ setLoading(true);
2596
+ try {
2597
+ await tarefaCtrl.post(
2598
+ `addObservacaoTarefa/${tarefaId}`,
2599
+ obs
2600
+ );
2601
+ await load();
2602
+ } catch (err) {
2603
+ const msg = (err == null ? void 0 : err.message) || "Nao foi possivel adicionar a observacao.";
2604
+ try {
2605
+ toast.warning(msg);
2606
+ } catch (e) {
2607
+ }
2608
+ } finally {
2609
+ setLoading(false);
2610
+ }
2611
+ },
2612
+ [tarefaCtrl, tarefaId, load, toast]
2613
+ );
2614
+ return (0, import_react24.useMemo)(
2615
+ () => ({ list, loading, load, add }),
2616
+ [list, loading, load, add]
2617
+ );
2618
+ }
2619
+
2620
+ // src/viewmodels/usePickMantenedorTipoViewModel.ts
2621
+ var import_react25 = require("react");
2622
+ var import_react_redux9 = require("react-redux");
2623
+
2624
+ // src/viewmodels/pickMantenedorTipoSlice.ts
2625
+ var import_toolkit7 = require("@reduxjs/toolkit");
2626
+ var initialState7 = {
2627
+ mantenedores: [],
2628
+ tiposDeOrdem: [],
2629
+ loading: false,
2630
+ assigning: false,
2631
+ error: null
1458
2632
  };
1459
- var FindRecursoByTagField_default = FindRecursoByTagField;
2633
+ var slice2 = (0, import_toolkit7.createSlice)({
2634
+ name: "pickMantenedorTipo",
2635
+ initialState: initialState7,
2636
+ reducers: {
2637
+ setOptions(state, action) {
2638
+ state.mantenedores = action.payload.mantenedores;
2639
+ state.tiposDeOrdem = action.payload.tiposDeOrdem;
2640
+ },
2641
+ setLoading(state, action) {
2642
+ state.loading = action.payload;
2643
+ },
2644
+ setAssigning(state, action) {
2645
+ state.assigning = action.payload;
2646
+ },
2647
+ setError(state, action) {
2648
+ state.error = action.payload;
2649
+ },
2650
+ reset() {
2651
+ return initialState7;
2652
+ }
2653
+ }
2654
+ });
2655
+ var {
2656
+ setOptions: setPickMantenedorTipoOptions,
2657
+ setLoading: setPickMantenedorTipoLoading,
2658
+ setAssigning: setPickMantenedorTipoAssigning,
2659
+ setError: setPickMantenedorTipoError,
2660
+ reset: resetPickMantenedorTipo
2661
+ } = slice2.actions;
2662
+ var pickMantenedorTipoSlice_default = slice2.reducer;
1460
2663
 
1461
- // src/components/recurso/RecursoDisplayer.tsx
1462
- var import_jsx_runtime6 = require("react/jsx-runtime");
1463
- var RecursoDisplayer = ({
1464
- selectedList = [],
1465
- onSaveRecurso,
1466
- singleReturn = false
1467
- }) => {
1468
- const arvoreEstruturalController = useHttpController("arvoreEstrutural");
1469
- const branchLevelController = useHttpController("branchLevel");
1470
- const [branches, setBranches] = (0, import_react17.useState)([]);
1471
- const dispatch = (0, import_react_redux3.useDispatch)();
1472
- const [localSelected, setLocalSelected] = (0, import_react17.useState)(selectedList);
1473
- const [selectorDisplay, setSelectorDisplay] = (0, import_react17.useState)("");
1474
- const [multiMode, setMultiMode] = (0, import_react17.useState)(false);
1475
- (0, import_react17.useEffect)(() => {
1476
- const init = async () => {
1477
- const b = await arvoreEstruturalController.get("branchByBranchLevel/1");
1478
- setBranches(b);
1479
- const lv = await branchLevelController.readAll();
1480
- dispatch(setLevels(lv));
1481
- };
1482
- init();
1483
- }, []);
1484
- const branchSetter = async (bn) => {
1485
- const copy = [...branches];
1486
- const branch = await arvoreEstruturalController.read("branch", bn.recurso.branch.id);
1487
- copy[bn.recurso.branch.branchLevel.level - 1] = {
1488
- ...branch,
1489
- nomeRecurso: bn.recurso.nome
1490
- };
1491
- setBranches(copy);
1492
- };
1493
- const backOnBranch = (branch) => {
1494
- const branchsToStay = branches.filter(
1495
- (bArray) => bArray.branchLevel.level <= branch.branchLevel.level
1496
- );
1497
- setBranches(branchsToStay);
1498
- };
1499
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { width: "100%", padding: 0 }, children: [
1500
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "d-flex justify-content-between align-items-center mb-3", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
1501
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("label", { className: "me-2", children: "Selecionar Recurso Por:" }),
1502
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1503
- import_react_bootstrap2.Button,
1504
- {
1505
- size: "sm",
1506
- onClick: () => setSelectorDisplay("branch"),
1507
- variant: selectorDisplay === "branch" ? "primary" : "outline-primary",
1508
- className: "me-1",
1509
- children: "\xC1rvore"
2664
+ // src/viewmodels/usePickMantenedorTipoViewModel.ts
2665
+ var unwrapList = (raw) => {
2666
+ if (Array.isArray(raw)) return raw;
2667
+ const r = raw;
2668
+ if (Array.isArray(r == null ? void 0 : r.content)) return r.content;
2669
+ if (Array.isArray(r == null ? void 0 : r.data)) return r.data;
2670
+ if (Array.isArray(r == null ? void 0 : r.items)) return r.items;
2671
+ return [];
2672
+ };
2673
+ function usePickMantenedorTipoViewModel() {
2674
+ var _a, _b, _c, _d, _e;
2675
+ const dispatch = (0, import_react_redux9.useDispatch)();
2676
+ const core = useCoreService();
2677
+ const state = (0, import_react_redux9.useSelector)(
2678
+ (s) => s.pickMantenedorTipo
2679
+ );
2680
+ const mantenedores = (_a = state == null ? void 0 : state.mantenedores) != null ? _a : [];
2681
+ const tiposDeOrdem = (_b = state == null ? void 0 : state.tiposDeOrdem) != null ? _b : [];
2682
+ const loading = (_c = state == null ? void 0 : state.loading) != null ? _c : false;
2683
+ const assigning = (_d = state == null ? void 0 : state.assigning) != null ? _d : false;
2684
+ const error = (_e = state == null ? void 0 : state.error) != null ? _e : null;
2685
+ const loadOptions = (0, import_react25.useCallback)(async () => {
2686
+ dispatch(setPickMantenedorTipoLoading(true));
2687
+ dispatch(setPickMantenedorTipoError(null));
2688
+ try {
2689
+ const mantenedorCtl = core.createController("mantenedor");
2690
+ const tipoCtl = core.createController("tipoDeOrdem");
2691
+ const [mRaw, tRaw] = await Promise.all([
2692
+ mantenedorCtl.get("mantenedorDashboard"),
2693
+ tipoCtl.readAll()
2694
+ ]);
2695
+ const mantenedoresList = unwrapList(mRaw);
2696
+ const tiposList = unwrapList(tRaw);
2697
+ dispatch(
2698
+ setPickMantenedorTipoOptions({
2699
+ mantenedores: mantenedoresList,
2700
+ tiposDeOrdem: tiposList
2701
+ })
2702
+ );
2703
+ } catch (e) {
2704
+ const msg = e instanceof Error ? e.message : "fetch error";
2705
+ dispatch(setPickMantenedorTipoError(msg));
2706
+ } finally {
2707
+ dispatch(setPickMantenedorTipoLoading(false));
2708
+ }
2709
+ }, [dispatch, core]);
2710
+ const assignMantenedores = (0, import_react25.useCallback)(
2711
+ async (osId, items) => {
2712
+ if (!items || items.length === 0) return;
2713
+ dispatch(setPickMantenedorTipoAssigning(true));
2714
+ try {
2715
+ const ctl = core.createController("ordemDeServico");
2716
+ for (const m of items) {
2717
+ await ctl.post(`atribuirMantenedor/${osId}`, {
2718
+ mantenedorId: m.id,
2719
+ id: null,
2720
+ userId: m.userId
2721
+ });
1510
2722
  }
1511
- ),
1512
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1513
- import_react_bootstrap2.Button,
1514
- {
1515
- size: "sm",
1516
- onClick: () => setSelectorDisplay("TAG"),
1517
- variant: selectorDisplay === "TAG" ? "primary" : "outline-primary",
1518
- children: "TAG"
2723
+ } finally {
2724
+ dispatch(setPickMantenedorTipoAssigning(false));
2725
+ }
2726
+ },
2727
+ [dispatch, core]
2728
+ );
2729
+ const assignTipo = (0, import_react25.useCallback)(
2730
+ async (osId, tipoId) => {
2731
+ dispatch(setPickMantenedorTipoAssigning(true));
2732
+ try {
2733
+ const ctl = core.createController("ordemDeServico");
2734
+ await ctl.put(`updateTipoDeOrdem/${osId}`, { tipoOs: tipoId });
2735
+ } finally {
2736
+ dispatch(setPickMantenedorTipoAssigning(false));
2737
+ }
2738
+ },
2739
+ [dispatch, core]
2740
+ );
2741
+ const assignMantenedoresMultiOs = (0, import_react25.useCallback)(
2742
+ async (osIds, items) => {
2743
+ if (!osIds.length || !items.length) return;
2744
+ dispatch(setPickMantenedorTipoAssigning(true));
2745
+ try {
2746
+ const ctl = core.createController("ordemDeServico");
2747
+ for (const m of items) {
2748
+ await ctl.post("atribuirMantenedorBulk", {
2749
+ osIds,
2750
+ mantenedorId: m.id,
2751
+ userId: m.userId
2752
+ });
1519
2753
  }
1520
- )
1521
- ] }) }),
1522
- selectorDisplay === "branch" && branches.map((branch, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1523
- BranchDropDisplay_default,
1524
- {
1525
- branch,
1526
- addBranch: branchSetter,
1527
- multiMode,
1528
- setMultiMode,
1529
- onSaveRecurso,
1530
- backOnBranch,
1531
- branches,
1532
- singleReturn
1533
- },
1534
- branch.id || i
1535
- )),
1536
- selectorDisplay === "TAG" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1537
- FindRecursoByTagField_default,
1538
- {
1539
- callback: (rec, checked) => {
1540
- setLocalSelected([rec]);
1541
- onSaveRecurso([rec], checked);
2754
+ } finally {
2755
+ dispatch(setPickMantenedorTipoAssigning(false));
2756
+ }
2757
+ },
2758
+ [dispatch, core]
2759
+ );
2760
+ const assignTipoMultiOs = (0, import_react25.useCallback)(
2761
+ async (osIds, tipoId) => {
2762
+ if (!osIds.length) return;
2763
+ dispatch(setPickMantenedorTipoAssigning(true));
2764
+ try {
2765
+ const ctl = core.createController("ordemDeServico");
2766
+ await ctl.post("updateTipoBulk", { osIds, tipoId });
2767
+ } finally {
2768
+ dispatch(setPickMantenedorTipoAssigning(false));
2769
+ }
2770
+ },
2771
+ [dispatch, core]
2772
+ );
2773
+ const reset = (0, import_react25.useCallback)(() => {
2774
+ dispatch(resetPickMantenedorTipo());
2775
+ }, [dispatch]);
2776
+ return (0, import_react25.useMemo)(
2777
+ () => ({
2778
+ mantenedores,
2779
+ tiposDeOrdem,
2780
+ loading,
2781
+ assigning,
2782
+ error,
2783
+ loadOptions,
2784
+ assignMantenedores,
2785
+ assignTipo,
2786
+ assignMantenedoresMultiOs,
2787
+ assignTipoMultiOs,
2788
+ reset
2789
+ }),
2790
+ [mantenedores, tiposDeOrdem, loading, assigning, error, loadOptions, assignMantenedores, assignTipo, assignMantenedoresMultiOs, assignTipoMultiOs, reset]
2791
+ );
2792
+ }
2793
+
2794
+ // src/viewmodels/ReduxTarefaItemAdapter.ts
2795
+ var import_react26 = require("react");
2796
+ function useTarefaItemViewModel(opts) {
2797
+ const { tarefaId, mode, fatherId, initialStatus } = opts;
2798
+ const { createController, subscribe, unsubscribe } = useCoreService();
2799
+ const toast = useToast();
2800
+ const tarefaCtrl = (0, import_react26.useMemo)(
2801
+ () => createController("tarefa"),
2802
+ [createController]
2803
+ );
2804
+ const status = useTarefaStatusViewModel({ tarefaId, fatherId, initialStatus });
2805
+ const observacoes = useObservacoesTarefaViewModel({ tarefaId });
2806
+ const inspecao = useInspecaoModalViewModel(tarefaId);
2807
+ const unidadeMaterial = useUnidadeMaterialViewModel(tarefaId);
2808
+ const anexos = useAnexoManagerViewModel({
2809
+ context: "tarefa",
2810
+ entityId: tarefaId
2811
+ });
2812
+ const observacoesRef = (0, import_react26.useRef)(observacoes);
2813
+ observacoesRef.current = observacoes;
2814
+ const anexosRef = (0, import_react26.useRef)(anexos);
2815
+ anexosRef.current = anexos;
2816
+ const updateDescricao = (0, import_react26.useCallback)(
2817
+ async (texto) => {
2818
+ try {
2819
+ await tarefaCtrl.put(String(tarefaId), { descricao: texto });
2820
+ } catch (err) {
2821
+ const msg = (err == null ? void 0 : err.message) || "Nao foi possivel atualizar a descricao da tarefa.";
2822
+ try {
2823
+ toast.warning(msg);
2824
+ } catch (e) {
1542
2825
  }
2826
+ throw err;
1543
2827
  }
1544
- )
1545
- ] });
1546
- };
1547
- var RecursoDisplayer_default = RecursoDisplayer;
2828
+ },
2829
+ [tarefaCtrl, tarefaId, toast]
2830
+ );
2831
+ const subscribeLive = (0, import_react26.useCallback)(() => {
2832
+ if (mode !== "execute") {
2833
+ return () => {
2834
+ };
2835
+ }
2836
+ const refresher = () => {
2837
+ };
2838
+ const moTarefa = {
2839
+ context: `tarefa${tarefaId}`,
2840
+ location: "*",
2841
+ refresher
2842
+ };
2843
+ const moTarefaJus = {
2844
+ context: `tarefaJus${tarefaId}`,
2845
+ location: "*",
2846
+ refresher
2847
+ };
2848
+ subscribe(moTarefa);
2849
+ subscribe(moTarefaJus);
2850
+ return () => {
2851
+ unsubscribe(moTarefa);
2852
+ unsubscribe(moTarefaJus);
2853
+ };
2854
+ }, [mode, tarefaId, subscribe, unsubscribe]);
2855
+ return (0, import_react26.useMemo)(
2856
+ () => ({
2857
+ status,
2858
+ observacoes,
2859
+ inspecao,
2860
+ unidadeMaterial,
2861
+ anexos,
2862
+ updateDescricao,
2863
+ subscribeLive
2864
+ }),
2865
+ [
2866
+ status,
2867
+ observacoes,
2868
+ inspecao,
2869
+ unidadeMaterial,
2870
+ anexos,
2871
+ updateDescricao,
2872
+ subscribeLive
2873
+ ]
2874
+ );
2875
+ }
1548
2876
 
1549
2877
  // src/reducers/pickerReducer.ts
1550
- var import_toolkit2 = require("@reduxjs/toolkit");
1551
- var initialState2 = {
2878
+ var import_toolkit8 = require("@reduxjs/toolkit");
2879
+ var initialState8 = {
1552
2880
  selected: null,
1553
2881
  items: [],
1554
2882
  visible: false,
1555
2883
  context: ""
1556
2884
  };
1557
- var pickerSlice = (0, import_toolkit2.createSlice)({
2885
+ var pickerSlice = (0, import_toolkit8.createSlice)({
1558
2886
  name: "picker",
1559
- initialState: initialState2,
2887
+ initialState: initialState8,
1560
2888
  reducers: {
1561
2889
  setPickerSelected(state, action) {
1562
2890
  state.selected = action.payload;
@@ -1571,7 +2899,7 @@ var pickerSlice = (0, import_toolkit2.createSlice)({
1571
2899
  state.context = action.payload;
1572
2900
  },
1573
2901
  clearPicker() {
1574
- return initialState2;
2902
+ return initialState8;
1575
2903
  }
1576
2904
  }
1577
2905
  });
@@ -1584,6 +2912,20 @@ var {
1584
2912
  } = pickerSlice.actions;
1585
2913
  var pickerReducer_default = pickerSlice.reducer;
1586
2914
 
2915
+ // src/utils/colorUtils.ts
2916
+ function pickTextColorBasedOnBgColorAdvanced(bgColor, lightColor, darkColor) {
2917
+ const color = bgColor.charAt(0) === "#" ? bgColor.substring(1, 7) : bgColor;
2918
+ const r = parseInt(color.substring(0, 2), 16);
2919
+ const g = parseInt(color.substring(2, 4), 16);
2920
+ const b = parseInt(color.substring(4, 6), 16);
2921
+ const uicolors = [r / 255, g / 255, b / 255];
2922
+ const c = uicolors.map(
2923
+ (col) => col <= 0.03928 ? col / 12.92 : Math.pow((col + 0.055) / 1.055, 2.4)
2924
+ );
2925
+ const L = 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2];
2926
+ return L > 0.179 ? darkColor : lightColor;
2927
+ }
2928
+
1587
2929
  // src/utils/webVitals.ts
1588
2930
  function initWebVitals(observability) {
1589
2931
  if (typeof PerformanceObserver === "undefined") return;
@@ -1618,28 +2960,28 @@ function initWebVitals(observability) {
1618
2960
  }
1619
2961
 
1620
2962
  // src/utils/dateUtils.ts
1621
- var import_dayjs = __toESM(require("dayjs"));
2963
+ var import_dayjs2 = __toESM(require("dayjs"));
1622
2964
  function formatDate(date, format = "DD/MM/YYYY") {
1623
2965
  if (!date) return "";
1624
- return (0, import_dayjs.default)(date).format(format);
2966
+ return (0, import_dayjs2.default)(date).format(format);
1625
2967
  }
1626
2968
  function formatDateTime(date) {
1627
2969
  return formatDate(date, "DD/MM/YYYY HH:mm");
1628
2970
  }
1629
2971
  function isDateBefore(date1, date2) {
1630
- return (0, import_dayjs.default)(date1).isBefore((0, import_dayjs.default)(date2));
2972
+ return (0, import_dayjs2.default)(date1).isBefore((0, import_dayjs2.default)(date2));
1631
2973
  }
1632
2974
  function isDateAfter(date1, date2) {
1633
- return (0, import_dayjs.default)(date1).isAfter((0, import_dayjs.default)(date2));
2975
+ return (0, import_dayjs2.default)(date1).isAfter((0, import_dayjs2.default)(date2));
1634
2976
  }
1635
2977
  function daysBetween(start, end) {
1636
- return (0, import_dayjs.default)(end).diff((0, import_dayjs.default)(start), "day");
2978
+ return (0, import_dayjs2.default)(end).diff((0, import_dayjs2.default)(start), "day");
1637
2979
  }
1638
2980
  function addDays(date, days) {
1639
- return (0, import_dayjs.default)(date).add(days, "day").toDate();
2981
+ return (0, import_dayjs2.default)(date).add(days, "day").toDate();
1640
2982
  }
1641
2983
  function toISOString(date) {
1642
- return (0, import_dayjs.default)(date).toISOString();
2984
+ return (0, import_dayjs2.default)(date).toISOString();
1643
2985
  }
1644
2986
 
1645
2987
  // src/utils/stringUtils.ts
@@ -1662,10 +3004,10 @@ function isBlank(str) {
1662
3004
  }
1663
3005
 
1664
3006
  // src/federation/FederatedBridge.tsx
1665
- var import_react18 = require("react");
1666
- var import_jsx_runtime7 = require("react/jsx-runtime");
3007
+ var import_react27 = require("react");
3008
+ var import_jsx_runtime = require("react/jsx-runtime");
1667
3009
  function FederatedBridge({ coreService, children }) {
1668
- (0, import_react18.useEffect)(() => {
3010
+ (0, import_react27.useEffect)(() => {
1669
3011
  if (typeof window === "undefined") return;
1670
3012
  window.__TERAPROX_HOSTED_BY_CORE__ = true;
1671
3013
  return () => {
@@ -1673,28 +3015,81 @@ function FederatedBridge({ coreService, children }) {
1673
3015
  window.__TERAPROX_HOSTED_BY_CORE__ = false;
1674
3016
  };
1675
3017
  }, []);
1676
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CoreServiceContext.Provider, { value: coreService, children });
3018
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CoreServiceContext.Provider, { value: coreService, children });
3019
+ }
3020
+
3021
+ // src/federation/isHostedByCore.ts
3022
+ function isHostedByCore() {
3023
+ if (typeof window === "undefined") return false;
3024
+ return !!window.__TERAPROX_HOSTED_BY_CORE__;
1677
3025
  }
1678
3026
 
1679
3027
  // src/federation/createReducersBundle.ts
3028
+ function buildGetReducersForKeys(reducers) {
3029
+ return async (keys = []) => {
3030
+ const uniqueKeys = [...new Set(keys)].filter((key) => !!reducers[key]);
3031
+ const loaded = await Promise.all(
3032
+ uniqueKeys.map(async (key) => {
3033
+ const mod = await reducers[key]();
3034
+ return [key, mod.default || mod];
3035
+ })
3036
+ );
3037
+ return Object.fromEntries(loaded);
3038
+ };
3039
+ }
3040
+ function createReducersFromManifest(manifest, reducerMap, defaultReducerKeys = []) {
3041
+ var _a, _b, _c, _d, _e, _f;
3042
+ const allKeys = Object.keys(reducerMap);
3043
+ const getReducersForKeys = buildGetReducersForKeys(reducerMap);
3044
+ const allRoutes = [];
3045
+ for (const section of (_a = manifest.menuSections) != null ? _a : []) {
3046
+ allRoutes.push(...(_b = section.items) != null ? _b : []);
3047
+ }
3048
+ allRoutes.push(...(_c = manifest.formRoutes) != null ? _c : []);
3049
+ const derivedContextMap = {};
3050
+ for (const route of allRoutes) {
3051
+ if (!route.context) continue;
3052
+ const routeReducers = (_d = route.reducers) != null ? _d : [];
3053
+ const existing = (_e = derivedContextMap[route.context]) != null ? _e : [];
3054
+ derivedContextMap[route.context] = [.../* @__PURE__ */ new Set([...existing, ...routeReducers])];
3055
+ }
3056
+ const mergedDefaults = [
3057
+ .../* @__PURE__ */ new Set([...defaultReducerKeys, ...(_f = manifest.defaultReducers) != null ? _f : []])
3058
+ ];
3059
+ const getReducerKeysByContext = (context) => {
3060
+ const contextKeys = derivedContextMap[context];
3061
+ if (!contextKeys || contextKeys.length === 0) return allKeys;
3062
+ return [.../* @__PURE__ */ new Set([...mergedDefaults, ...contextKeys])];
3063
+ };
3064
+ const getReducersForModule = async ({
3065
+ context,
3066
+ reducerKeys
3067
+ } = {}) => {
3068
+ if (reducerKeys && reducerKeys.length > 0) {
3069
+ const keys2 = [.../* @__PURE__ */ new Set([...mergedDefaults, ...reducerKeys])];
3070
+ return getReducersForKeys(keys2);
3071
+ }
3072
+ const keys = getReducerKeysByContext(context || "");
3073
+ return getReducersForKeys(keys);
3074
+ };
3075
+ const loadAllReducers = () => getReducersForKeys(allKeys);
3076
+ return {
3077
+ getReducerKeysByContext,
3078
+ getReducersForKeys,
3079
+ getReducersForModule,
3080
+ loadAllReducers,
3081
+ baseReducers: {}
3082
+ };
3083
+ }
1680
3084
  function createReducersBundle(config) {
1681
3085
  const { reducers, contextMap, defaults = [] } = config;
1682
3086
  const allKeys = Object.keys(reducers);
3087
+ const getReducersForKeys = buildGetReducersForKeys(reducers);
1683
3088
  const getReducerKeysByContext = (context) => {
1684
3089
  const contextKeys = contextMap[context];
1685
3090
  if (!contextKeys) return allKeys;
1686
3091
  return [.../* @__PURE__ */ new Set([...defaults, ...contextKeys])];
1687
3092
  };
1688
- const getReducersForKeys = async (keys = []) => {
1689
- const uniqueKeys = [...new Set(keys)].filter((key) => !!reducers[key]);
1690
- const loaded = await Promise.all(
1691
- uniqueKeys.map(async (key) => {
1692
- const module2 = await reducers[key]();
1693
- return [key, module2.default || module2];
1694
- })
1695
- );
1696
- return Object.fromEntries(loaded);
1697
- };
1698
3093
  const getReducersForModule = async ({
1699
3094
  context
1700
3095
  } = {}) => {
@@ -1712,8 +3107,8 @@ function createReducersBundle(config) {
1712
3107
  }
1713
3108
 
1714
3109
  // src/federation/StandaloneProvider.tsx
1715
- var import_react19 = require("react");
1716
- var import_jsx_runtime8 = require("react/jsx-runtime");
3110
+ var import_react28 = require("react");
3111
+ var import_jsx_runtime2 = require("react/jsx-runtime");
1717
3112
  async function probeEmulator(host, port) {
1718
3113
  try {
1719
3114
  const res = await fetch(`http://${host}:${port}/.json`, {
@@ -1752,7 +3147,7 @@ async function resolveRtdbStrategy(firebaseConfig, emulator) {
1752
3147
  }
1753
3148
  var _emulatorConnected = /* @__PURE__ */ new Set();
1754
3149
  function RtdbConfigWarning({ onDismiss }) {
1755
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
3150
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1756
3151
  "div",
1757
3152
  {
1758
3153
  style: {
@@ -1772,28 +3167,28 @@ function RtdbConfigWarning({ onDismiss }) {
1772
3167
  lineHeight: 1.6
1773
3168
  },
1774
3169
  children: [
1775
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { fontWeight: "bold", marginBottom: 8, color: "#f59e0b", fontSize: 14 }, children: "\u26A0 RTDB n\xE3o configurado" }),
1776
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
3170
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { fontWeight: "bold", marginBottom: 8, color: "#f59e0b", fontSize: 14 }, children: "\u26A0 RTDB n\xE3o configurado" }),
3171
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
1777
3172
  "Matching Objects em tempo real desativados.",
1778
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("br", {}),
3173
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("br", {}),
1779
3174
  "Configure no ",
1780
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("code", { children: ".env.dev" }),
3175
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("code", { children: ".env.dev" }),
1781
3176
  ":",
1782
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("br", {}),
1783
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("code", { style: { color: "#86efac" }, children: "REACT_APP_RTDB_EMULATOR_HOST=localhost:9000" }),
1784
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("br", {}),
1785
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { style: { color: "#94a3b8", fontSize: 11 }, children: [
3177
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("br", {}),
3178
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("code", { style: { color: "#86efac" }, children: "REACT_APP_RTDB_EMULATOR_HOST=localhost:9000" }),
3179
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("br", {}),
3180
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { color: "#94a3b8", fontSize: 11 }, children: [
1786
3181
  "ou inicie o backend com ",
1787
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("code", { children: "RtdbEmulatorPlugin" }),
3182
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("code", { children: "RtdbEmulatorPlugin" }),
1788
3183
  " do @onroad/core"
1789
3184
  ] }),
1790
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("br", {}),
1791
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { style: { color: "#94a3b8", fontSize: 11 }, children: [
3185
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("br", {}),
3186
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { color: "#94a3b8", fontSize: 11 }, children: [
1792
3187
  "e rode o emulator com ",
1793
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("code", { children: "firebase emulators:start --only database" })
3188
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("code", { children: "firebase emulators:start --only database" })
1794
3189
  ] })
1795
3190
  ] }),
1796
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3191
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1797
3192
  "button",
1798
3193
  {
1799
3194
  onClick: onDismiss,
@@ -1814,27 +3209,45 @@ function RtdbConfigWarning({ onDismiss }) {
1814
3209
  }
1815
3210
  );
1816
3211
  }
1817
- function StandaloneProvider({ createController, addToast, firebaseConfig, emulator, tenant, children }) {
1818
- const [subscriptions] = (0, import_react19.useState)([]);
1819
- const subscriptionsRef = (0, import_react19.useRef)(subscriptions);
3212
+ function StandaloneProvider({
3213
+ createController,
3214
+ toast: toastProp,
3215
+ addToast,
3216
+ firebaseConfig,
3217
+ emulator,
3218
+ tenant,
3219
+ children
3220
+ }) {
3221
+ const [subscriptions] = (0, import_react28.useState)([]);
3222
+ const subscriptionsRef = (0, import_react28.useRef)(subscriptions);
1820
3223
  subscriptionsRef.current = subscriptions;
1821
- const [rtdbWarning, setRtdbWarning] = (0, import_react19.useState)(false);
1822
- const toast = (0, import_react19.useMemo)(
1823
- () => ({
1824
- success: (msg, opts) => addToast(msg, { appearance: "success", autoDismiss: true, ...opts }),
1825
- warning: (msg, opts) => addToast(msg, { appearance: "warning", autoDismiss: true, ...opts }),
1826
- error: (msg, opts) => addToast(msg, { appearance: "error", autoDismiss: true, ...opts }),
1827
- info: (msg, opts) => addToast(msg, { appearance: "info", autoDismiss: true, ...opts })
1828
- }),
1829
- [addToast]
1830
- );
1831
- const subscribe = (0, import_react19.useCallback)(
3224
+ const [rtdbWarning, setRtdbWarning] = (0, import_react28.useState)(false);
3225
+ const _envTenant = typeof process !== "undefined" ? process.env.REACT_APP_RTDB_TENANT : void 0;
3226
+ const resolvedTenant = tenant || _envTenant || (process.env.NODE_ENV !== "production" ? "dev-local" : void 0);
3227
+ const toast = (0, import_react28.useMemo)(() => {
3228
+ if (toastProp) return toastProp;
3229
+ if (addToast) {
3230
+ return {
3231
+ success: (msg, opts) => addToast(msg, { appearance: "success", autoDismiss: true, ...opts }),
3232
+ warning: (msg, opts) => addToast(msg, { appearance: "warning", autoDismiss: true, ...opts }),
3233
+ error: (msg, opts) => addToast(msg, { appearance: "error", autoDismiss: true, ...opts }),
3234
+ info: (msg, opts) => addToast(msg, { appearance: "info", autoDismiss: true, ...opts })
3235
+ };
3236
+ }
3237
+ const noop = (msg) => {
3238
+ if (process.env.NODE_ENV !== "production") {
3239
+ console.warn("[StandaloneProvider] Toast called but no toast/addToast prop provided:", msg);
3240
+ }
3241
+ };
3242
+ return { success: noop, warning: noop, error: noop, info: noop };
3243
+ }, [toastProp, addToast]);
3244
+ const subscribe = (0, import_react28.useCallback)(
1832
3245
  (mo) => {
1833
3246
  subscriptions.push(mo);
1834
3247
  },
1835
3248
  [subscriptions]
1836
3249
  );
1837
- const unsubscribe = (0, import_react19.useCallback)(
3250
+ const unsubscribe = (0, import_react28.useCallback)(
1838
3251
  (mo) => {
1839
3252
  const idx = subscriptions.findIndex(
1840
3253
  (s) => s.context === mo.context && s.location === mo.location
@@ -1843,8 +3256,17 @@ function StandaloneProvider({ createController, addToast, firebaseConfig, emulat
1843
3256
  },
1844
3257
  [subscriptions]
1845
3258
  );
1846
- (0, import_react19.useEffect)(() => {
1847
- if (!tenant) return;
3259
+ (0, import_react28.useEffect)(() => {
3260
+ if (resolvedTenant || process.env.NODE_ENV === "production") return;
3261
+ const timer = setTimeout(() => {
3262
+ console.warn(
3263
+ '[StandaloneProvider] RTDB listener deferred: tenant could not be resolved after 5 s.\nFix with any of:\n \u2022 Pass `tenant` prop (e.g. from Redux state.global.companyId)\n \u2022 Set REACT_APP_RTDB_TENANT=<companyId> in your .env\n \u2022 Run in NODE_ENV=development (auto-falls back to "dev-local")'
3264
+ );
3265
+ }, 5e3);
3266
+ return () => clearTimeout(timer);
3267
+ }, [resolvedTenant]);
3268
+ (0, import_react28.useEffect)(() => {
3269
+ if (!resolvedTenant) return;
1848
3270
  let cleanup;
1849
3271
  let cancelled = false;
1850
3272
  (async () => {
@@ -1887,7 +3309,7 @@ function StandaloneProvider({ createController, addToast, firebaseConfig, emulat
1887
3309
  const cloudApp = existingApp != null ? existingApp : initializeApp(strategy.config);
1888
3310
  db = getDatabase(cloudApp);
1889
3311
  }
1890
- const moRef = ref(db, `${tenant}/matchingObjects`);
3312
+ const moRef = ref(db, `${resolvedTenant}/matchingObjects`);
1891
3313
  const unsub = onChildAdded(moRef, (snapshot) => {
1892
3314
  const data = snapshot.val();
1893
3315
  if (!data) return;
@@ -1917,8 +3339,8 @@ function StandaloneProvider({ createController, addToast, firebaseConfig, emulat
1917
3339
  cancelled = true;
1918
3340
  cleanup == null ? void 0 : cleanup();
1919
3341
  };
1920
- }, [firebaseConfig, emulator, tenant]);
1921
- const value = (0, import_react19.useMemo)(
3342
+ }, [firebaseConfig, emulator, resolvedTenant]);
3343
+ const value = (0, import_react28.useMemo)(
1922
3344
  () => ({
1923
3345
  createController,
1924
3346
  toast,
@@ -1931,20 +3353,21 @@ function StandaloneProvider({ createController, addToast, firebaseConfig, emulat
1931
3353
  handleLogout: () => {
1932
3354
  },
1933
3355
  hostedByCore: false,
1934
- observability: new NullObservabilityAdapter()
3356
+ observability: new NullObservabilityAdapter(),
3357
+ rateLimits: {}
1935
3358
  }),
1936
3359
  [createController, toast, subscribe, unsubscribe]
1937
3360
  );
1938
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(CoreServiceContext.Provider, { value, children: [
3361
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(CoreServiceContext.Provider, { value, children: [
1939
3362
  children,
1940
- rtdbWarning && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(RtdbConfigWarning, { onDismiss: () => setRtdbWarning(false) })
3363
+ rtdbWarning && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RtdbConfigWarning, { onDismiss: () => setRtdbWarning(false) })
1941
3364
  ] });
1942
3365
  }
1943
3366
 
1944
3367
  // src/federation/DevAutoLogin.tsx
1945
- var import_react20 = require("react");
1946
- var import_react_redux4 = require("react-redux");
1947
- var import_jsx_runtime9 = require("react/jsx-runtime");
3368
+ var import_react29 = require("react");
3369
+ var import_react_redux10 = require("react-redux");
3370
+ var import_jsx_runtime3 = require("react/jsx-runtime");
1948
3371
  var DEFAULT_DEV_USER = {
1949
3372
  firstName: "Dev",
1950
3373
  lastName: "User",
@@ -1961,79 +3384,237 @@ var DEFAULT_DEV_USER = {
1961
3384
  filters: []
1962
3385
  };
1963
3386
  function DevAutoLogin({ actions, devUser, children }) {
1964
- const dispatch = (0, import_react_redux4.useDispatch)();
1965
- const token = (0, import_react_redux4.useSelector)((state) => {
3387
+ const dispatch = (0, import_react_redux10.useDispatch)();
3388
+ const token = (0, import_react_redux10.useSelector)((state) => {
1966
3389
  var _a;
1967
3390
  return (_a = state.global) == null ? void 0 : _a.token;
1968
3391
  });
1969
3392
  const hostedByCore = typeof window !== "undefined" && window.__TERAPROX_HOSTED_BY_CORE__ === true;
1970
- (0, import_react20.useEffect)(() => {
3393
+ (0, import_react29.useEffect)(() => {
1971
3394
  if (process.env.NODE_ENV === "development" && !hostedByCore && !token) {
1972
3395
  const user = { ...DEFAULT_DEV_USER, ...devUser };
1973
3396
  dispatch(actions.setCompany(user.companyId));
1974
3397
  dispatch(actions.logIn(user));
1975
3398
  }
1976
3399
  }, [dispatch, hostedByCore, token, actions, devUser]);
1977
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children });
3400
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children });
3401
+ }
3402
+
3403
+ // src/federation/groupMenuSections.ts
3404
+ function groupMenuSections(manifests) {
3405
+ var _a, _b, _c, _d, _e, _f, _g;
3406
+ const groupMap = /* @__PURE__ */ new Map();
3407
+ const topLevel = [];
3408
+ for (const manifest of manifests) {
3409
+ const fallbackGroup = manifest.menuGroup;
3410
+ for (const section of (_a = manifest.menuSections) != null ? _a : []) {
3411
+ const groupName = (_b = section.group) != null ? _b : fallbackGroup == null ? void 0 : fallbackGroup.name;
3412
+ if (!groupName) {
3413
+ topLevel.push({
3414
+ key: `${manifest.name}:${section.label}`,
3415
+ label: section.label,
3416
+ icon: section.icon,
3417
+ order: (_c = section.order) != null ? _c : 999,
3418
+ children: section.items.map((item) => ({ kind: "item", item }))
3419
+ });
3420
+ continue;
3421
+ }
3422
+ let groupNode = groupMap.get(groupName);
3423
+ if (!groupNode) {
3424
+ groupNode = {
3425
+ key: `group:${groupName}`,
3426
+ label: groupName,
3427
+ icon: (_d = fallbackGroup == null ? void 0 : fallbackGroup.icon) != null ? _d : section.icon,
3428
+ order: (_f = (_e = fallbackGroup == null ? void 0 : fallbackGroup.order) != null ? _e : section.order) != null ? _f : 999,
3429
+ children: []
3430
+ };
3431
+ groupMap.set(groupName, groupNode);
3432
+ } else if (!groupNode.icon) {
3433
+ const candidate = (_g = fallbackGroup == null ? void 0 : fallbackGroup.icon) != null ? _g : section.icon;
3434
+ if (candidate) groupNode.icon = candidate;
3435
+ }
3436
+ if (section.flatten) {
3437
+ for (const item of section.items) {
3438
+ groupNode.children.push({ kind: "item", item, order: section.order });
3439
+ }
3440
+ } else {
3441
+ const existing = groupNode.children.find(
3442
+ (c) => c.kind === "section" && c.label === section.label
3443
+ );
3444
+ if (existing) {
3445
+ existing.items = [...existing.items, ...section.items];
3446
+ if (!existing.icon && section.icon) existing.icon = section.icon;
3447
+ if (section.order != null && (existing.order == null || section.order < existing.order)) {
3448
+ existing.order = section.order;
3449
+ }
3450
+ } else {
3451
+ groupNode.children.push({
3452
+ kind: "section",
3453
+ label: section.label,
3454
+ icon: section.icon,
3455
+ items: [...section.items],
3456
+ order: section.order
3457
+ });
3458
+ }
3459
+ }
3460
+ }
3461
+ }
3462
+ for (const node of groupMap.values()) {
3463
+ node.children.sort((a, b) => {
3464
+ var _a2, _b2, _c2, _d2;
3465
+ const oa = (_a2 = a.order) != null ? _a2 : 999;
3466
+ const ob = (_b2 = b.order) != null ? _b2 : 999;
3467
+ if (oa !== ob) return oa - ob;
3468
+ const la = a.kind === "section" ? a.label : (_c2 = a.item.label) != null ? _c2 : "";
3469
+ const lb = b.kind === "section" ? b.label : (_d2 = b.item.label) != null ? _d2 : "";
3470
+ return la.localeCompare(lb);
3471
+ });
3472
+ for (const child of node.children) {
3473
+ if (child.kind === "section") {
3474
+ child.items.sort((a, b) => {
3475
+ var _a2, _b2, _c2, _d2;
3476
+ const oa = (_a2 = a.order) != null ? _a2 : 999;
3477
+ const ob = (_b2 = b.order) != null ? _b2 : 999;
3478
+ if (oa !== ob) return oa - ob;
3479
+ return ((_c2 = a.label) != null ? _c2 : "").localeCompare((_d2 = b.label) != null ? _d2 : "");
3480
+ });
3481
+ }
3482
+ }
3483
+ }
3484
+ const all = [...topLevel, ...groupMap.values()];
3485
+ all.sort((a, b) => a.order - b.order || a.label.localeCompare(b.label));
3486
+ return all;
1978
3487
  }
1979
3488
  // Annotate the CommonJS export names for ESM import in node:
1980
3489
  0 && (module.exports = {
3490
+ CONTADOR_DEFAULT_KEY,
1981
3491
  CoreServiceBuilder,
1982
3492
  CoreServiceContext,
1983
3493
  DevAutoLogin,
3494
+ FILTER_COMBINE_MODES,
1984
3495
  FederatedBridge,
1985
3496
  FetchHttpAdapter,
3497
+ INSPECAO_MODAL_DEFAULT_KEY,
1986
3498
  NullCoreService,
1987
3499
  NullHttpController,
1988
3500
  NullObservabilityAdapter,
1989
3501
  NullToastService,
1990
- RecursoDisplayer,
3502
+ RECORRENCIA_DEFAULT_KEY,
1991
3503
  StandaloneProvider,
1992
3504
  TracingHttpAdapter,
3505
+ UNIDADE_MATERIAL_DEFAULT_KEY,
3506
+ addContadorLimite,
1993
3507
  addDays,
1994
3508
  branchLevelReducer,
1995
3509
  buildTraceparent,
1996
3510
  capitalize,
1997
3511
  clearBranchLevelForm,
3512
+ clearContador,
3513
+ clearInspecaoModal,
3514
+ clearMantenedorSlot,
1998
3515
  clearPicker,
3516
+ clearRecorrencia,
3517
+ clearUnidadeMaterial,
3518
+ contadorReducer,
1999
3519
  createReducersBundle,
3520
+ createReducersFromManifest,
2000
3521
  daysBetween,
2001
3522
  formatDate,
2002
3523
  formatDateTime,
2003
3524
  generateSpanId,
2004
3525
  generateTraceId,
3526
+ groupMenuSections,
3527
+ hmsToSeconds,
2005
3528
  initWebVitals,
3529
+ inspecaoModalReducer,
2006
3530
  isBlank,
2007
3531
  isDateAfter,
2008
3532
  isDateBefore,
3533
+ isHostedByCore,
3534
+ mantenedorPickerReducer,
3535
+ pickMantenedorTipoReducer,
2009
3536
  pickTextColorBasedOnBgColorAdvanced,
2010
3537
  pickerReducer,
3538
+ populateContador,
3539
+ populateInspecaoModal,
3540
+ populateRecorrencia,
2011
3541
  populateToEdit,
3542
+ populateUnidadeMaterial,
3543
+ recorrenciaReducer,
2012
3544
  removeAccents,
3545
+ removeContadorLimiteAt,
3546
+ removeInspecaoLimiteAt,
3547
+ resetPickMantenedorTipo,
3548
+ secondsToHms,
3549
+ selectContador,
3550
+ selectInspecaoModal,
3551
+ selectRecorrencia,
3552
+ selectUnidadeMaterial,
2013
3553
  setColor,
3554
+ setContadorParametro,
3555
+ setContadorUnidade,
3556
+ setContadorValor,
2014
3557
  setExcludeLevels,
2015
3558
  setHaveComponente,
3559
+ setInspecaoLimites,
3560
+ setInspecaoNomeParametro,
3561
+ setInspecaoParametro,
3562
+ setInspecaoTipo,
3563
+ setInspecaoUnidadeParametro,
2016
3564
  setLevel,
2017
3565
  setLevels,
3566
+ setMantenedorError,
3567
+ setMantenedorLoading,
3568
+ setMantenedorOptions,
3569
+ setMantenedorPendingConfirm,
3570
+ setMantenedorSearchTerm,
2018
3571
  setNome,
3572
+ setPickMantenedorTipoAssigning,
3573
+ setPickMantenedorTipoError,
3574
+ setPickMantenedorTipoLoading,
3575
+ setPickMantenedorTipoOptions,
2019
3576
  setPickerContext,
2020
3577
  setPickerItems,
2021
3578
  setPickerSelected,
2022
3579
  setPickerVisible,
3580
+ setRecorrenciaDataInicio,
3581
+ setRecorrenciaEscala,
3582
+ setRecorrenciaValor,
3583
+ setUnidadeMaterialMaterial,
3584
+ setUnidadeMaterialQuantidade,
3585
+ setUnidadeMaterialUnidade,
2023
3586
  slugify,
2024
3587
  toISOString,
2025
3588
  truncate,
3589
+ unidadeMaterialReducer,
3590
+ updateContadorLimiteAt,
3591
+ useAnexoManager,
3592
+ useAnexoManagerViewModel,
2026
3593
  useAnexoUpload,
3594
+ useContadorViewModel,
2027
3595
  useCoreService,
2028
3596
  useFetchData,
3597
+ useFilterCombineMode,
3598
+ useFindRecursoByTagViewModel,
2029
3599
  useFormStorage,
2030
3600
  useHttpController,
3601
+ useInspecaoModalViewModel,
3602
+ useJustificativaModalViewModel,
3603
+ useMantenedorPickerViewModel,
2031
3604
  useMatchingObject,
2032
3605
  useNavigator,
2033
3606
  useNotifications,
2034
3607
  useObservability,
3608
+ useObservacoesTarefaViewModel,
3609
+ usePickMantenedorTipoViewModel,
2035
3610
  usePostData,
3611
+ useRecorrenciaViewModel,
3612
+ useRecursoDisplayerViewModel,
2036
3613
  useSmartSearch,
3614
+ useTarefaItemViewModel,
3615
+ useTarefaStatusViewModel,
3616
+ useTimeFormat,
2037
3617
  useToast,
3618
+ useUnidadeMaterialViewModel,
2038
3619
  useValidation
2039
3620
  });