teraprox-core-sdk 0.3.11 → 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,6 +507,7 @@ 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) => {
@@ -397,19 +529,27 @@ var CoreServiceBuilder = class {
397
529
  const extraHeaders = { "x-teraprox-host": hostHeader };
398
530
  return this._tracing ? new TracingHttpAdapter(endpoint, extraHeaders) : new FetchHttpAdapter(endpoint, extraHeaders);
399
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.
400
536
  subscribe: (mo) => {
401
- console.log(`[CoreServiceBuilder RTDB] Subscribe > ${mo.context}`);
537
+ subscriptions.push(mo);
402
538
  },
403
539
  unsubscribe: (mo) => {
404
- 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);
405
544
  },
406
- subscribeEvent: (evt) => {
545
+ subscribeEvent: (_evt) => {
407
546
  },
408
- unsubscribeEvent: (evt) => {
547
+ unsubscribeEvent: (_evt) => {
409
548
  },
410
- handleLogout: () => console.log("Logout invocado no Standalone mode"),
549
+ handleLogout: () => console.log("[CoreServiceBuilder] Logout invocado no Standalone mode"),
411
550
  hostedByCore: this._hostedByCore,
412
- observability: this._observability
551
+ observability: this._observability,
552
+ rateLimits: {}
413
553
  };
414
554
  }
415
555
  };
@@ -530,15 +670,207 @@ function useObservability() {
530
670
  return useCoreService().observability;
531
671
  }
532
672
 
533
- // src/hooks/useFetchData.ts
673
+ // src/hooks/useAnexoManager.ts
534
674
  var import_react6 = require("react");
535
- 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 }) {
536
700
  const { createController } = useCoreService();
537
- const [data, setData] = (0, import_react6.useState)(null);
701
+ const [persistidos, setPersistidos] = (0, import_react6.useState)([]);
702
+ const [locais, setLocais] = (0, import_react6.useState)([]);
538
703
  const [loading, setLoading] = (0, import_react6.useState)(false);
539
- const [error, setError] = (0, import_react6.useState)(null);
540
- const activeRef = (0, import_react6.useRef)(true);
541
- 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)(
542
874
  async (context, path, endpoint) => {
543
875
  const controller = createController(context, endpoint);
544
876
  setLoading(true);
@@ -556,7 +888,7 @@ function useFetchData() {
556
888
  },
557
889
  [createController]
558
890
  );
559
- const reset = (0, import_react6.useCallback)(() => {
891
+ const reset = (0, import_react7.useCallback)(() => {
560
892
  setData(null);
561
893
  setLoading(false);
562
894
  setError(null);
@@ -565,13 +897,13 @@ function useFetchData() {
565
897
  }
566
898
 
567
899
  // src/hooks/usePostData.ts
568
- var import_react7 = require("react");
900
+ var import_react8 = require("react");
569
901
  function usePostData() {
570
902
  const { createController } = useCoreService();
571
- const [result, setResult] = (0, import_react7.useState)(null);
572
- const [loading, setLoading] = (0, import_react7.useState)(false);
573
- const [error, setError] = (0, import_react7.useState)(null);
574
- 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)(
575
907
  async (context, path, payload, endpoint) => {
576
908
  const controller = createController(context, endpoint);
577
909
  setLoading(true);
@@ -593,13 +925,13 @@ function usePostData() {
593
925
  }
594
926
 
595
927
  // src/hooks/useAnexoUpload.ts
596
- var import_react8 = require("react");
928
+ var import_react9 = require("react");
597
929
  function useAnexoUpload() {
598
930
  const { createController } = useCoreService();
599
931
  const toast = useToast();
600
- const [uploading, setUploading] = (0, import_react8.useState)(false);
601
- const [progress, setProgress] = (0, import_react8.useState)(0);
602
- 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)(
603
935
  async (context, path, file, extraHeaders) => {
604
936
  const controller = createController(context);
605
937
  setUploading(true);
@@ -622,7 +954,7 @@ function useAnexoUpload() {
622
954
  },
623
955
  [createController, toast]
624
956
  );
625
- const uploadMultiple = (0, import_react8.useCallback)(
957
+ const uploadMultiple = (0, import_react9.useCallback)(
626
958
  async (context, path, files, extraHeaders) => {
627
959
  const fileArray = Array.from(files);
628
960
  const results = [];
@@ -640,10 +972,10 @@ function useAnexoUpload() {
640
972
  }
641
973
 
642
974
  // src/hooks/useFormStorage.ts
643
- var import_react9 = require("react");
975
+ var import_react10 = require("react");
644
976
  function useFormStorage(key, initialValue) {
645
977
  const storageKey = `teraprox_form_${key}`;
646
- const [value, setValue] = (0, import_react9.useState)(() => {
978
+ const [value, setValue] = (0, import_react10.useState)(() => {
647
979
  try {
648
980
  const stored = localStorage.getItem(storageKey);
649
981
  return stored ? JSON.parse(stored) : initialValue;
@@ -651,13 +983,13 @@ function useFormStorage(key, initialValue) {
651
983
  return initialValue;
652
984
  }
653
985
  });
654
- (0, import_react9.useEffect)(() => {
986
+ (0, import_react10.useEffect)(() => {
655
987
  try {
656
988
  localStorage.setItem(storageKey, JSON.stringify(value));
657
989
  } catch (e) {
658
990
  }
659
991
  }, [value, storageKey]);
660
- const clear = (0, import_react9.useCallback)(() => {
992
+ const clear = (0, import_react10.useCallback)(() => {
661
993
  localStorage.removeItem(storageKey);
662
994
  setValue(initialValue);
663
995
  }, [storageKey, initialValue]);
@@ -665,11 +997,11 @@ function useFormStorage(key, initialValue) {
665
997
  }
666
998
 
667
999
  // src/hooks/useSmartSearch.ts
668
- var import_react10 = require("react");
1000
+ var import_react11 = require("react");
669
1001
  function useSmartSearch(data, searchFields, options) {
670
- const [searchTerm, setSearchTerm] = (0, import_react10.useState)("");
1002
+ const [searchTerm, setSearchTerm] = (0, import_react11.useState)("");
671
1003
  const { caseSensitive = false, minLength = 1 } = options || {};
672
- const filteredData = (0, import_react10.useMemo)(() => {
1004
+ const filteredData = (0, import_react11.useMemo)(() => {
673
1005
  if (!searchTerm || searchTerm.length < minLength) return data;
674
1006
  const term = caseSensitive ? searchTerm : searchTerm.toLowerCase();
675
1007
  return data.filter(
@@ -681,16 +1013,16 @@ function useSmartSearch(data, searchFields, options) {
681
1013
  })
682
1014
  );
683
1015
  }, [data, searchTerm, searchFields, caseSensitive, minLength]);
684
- const clearSearch = (0, import_react10.useCallback)(() => setSearchTerm(""), []);
1016
+ const clearSearch = (0, import_react11.useCallback)(() => setSearchTerm(""), []);
685
1017
  return { searchTerm, setSearchTerm, filteredData, clearSearch };
686
1018
  }
687
1019
 
688
1020
  // src/hooks/useValidation.ts
689
- var import_react11 = require("react");
1021
+ var import_react12 = require("react");
690
1022
  function useValidation(rules) {
691
1023
  const toast = useToast();
692
- const [errors, setErrors] = (0, import_react11.useState)({});
693
- const validate = (0, import_react11.useCallback)(
1024
+ const [errors, setErrors] = (0, import_react12.useState)({});
1025
+ const validate = (0, import_react12.useCallback)(
694
1026
  (form) => {
695
1027
  const newErrors = {};
696
1028
  let valid = true;
@@ -709,22 +1041,523 @@ function useValidation(rules) {
709
1041
  },
710
1042
  [rules, toast]
711
1043
  );
712
- const clearErrors = (0, import_react11.useCallback)(() => setErrors({}), []);
713
- const setFieldError = (0, import_react11.useCallback)(
1044
+ const clearErrors = (0, import_react12.useCallback)(() => setErrors({}), []);
1045
+ const setFieldError = (0, import_react12.useCallback)(
714
1046
  (field, message) => setErrors((prev) => ({ ...prev, [field]: message })),
715
1047
  []
716
1048
  );
717
1049
  return { errors, validate, clearErrors, setFieldError };
718
1050
  }
719
1051
 
720
- // src/components/recurso/RecursoDisplayer.tsx
721
- var import_react17 = require("react");
722
- 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");
723
1120
  var import_react_redux3 = require("react-redux");
724
1121
 
725
- // src/reducers/branchLevelReducer.ts
1122
+ // src/viewmodels/unidadeMaterialSlice.ts
726
1123
  var import_toolkit = require("@reduxjs/toolkit");
1124
+ var DEFAULT_KEY = "__default__";
1125
+ var emptyValue = {
1126
+ material: null,
1127
+ quantidade: "",
1128
+ unidade: null
1129
+ };
727
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 = {
728
1561
  form: {
729
1562
  nome: "",
730
1563
  level: 0,
@@ -734,9 +1567,9 @@ var initialState = {
734
1567
  },
735
1568
  levels: []
736
1569
  };
737
- var branchLevelSlice = (0, import_toolkit.createSlice)({
1570
+ var branchLevelSlice = (0, import_toolkit3.createSlice)({
738
1571
  name: "branchLevelReducer",
739
- initialState,
1572
+ initialState: initialState3,
740
1573
  reducers: {
741
1574
  setNome(state, action) {
742
1575
  state.form.nome = action.payload;
@@ -760,7 +1593,7 @@ var branchLevelSlice = (0, import_toolkit.createSlice)({
760
1593
  state.form = action.payload;
761
1594
  },
762
1595
  clear(state) {
763
- state.form = initialState.form;
1596
+ state.form = initialState3.form;
764
1597
  }
765
1598
  }
766
1599
  });
@@ -776,788 +1609,1282 @@ var {
776
1609
  } = branchLevelSlice.actions;
777
1610
  var branchLevelReducer_default = branchLevelSlice.reducer;
778
1611
 
779
- // src/components/recurso/BranchDropDisplay.tsx
780
- var import_react12 = require("react");
781
- var import_fa = require("react-icons/fa");
782
- var import_md = require("react-icons/md");
783
-
784
- // src/utils/colorUtils.ts
785
- function pickTextColorBasedOnBgColorAdvanced(bgColor, lightColor, darkColor) {
786
- const color = bgColor.charAt(0) === "#" ? bgColor.substring(1, 7) : bgColor;
787
- const r = parseInt(color.substring(0, 2), 16);
788
- const g = parseInt(color.substring(2, 4), 16);
789
- const b = parseInt(color.substring(4, 6), 16);
790
- const uicolors = [r / 255, g / 255, b / 255];
791
- const c = uicolors.map(
792
- (col) => col <= 0.03928 ? col / 12.92 : Math.pow((col + 0.055) / 1.055, 2.4)
793
- );
794
- const L = 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2];
795
- return L > 0.179 ? darkColor : lightColor;
796
- }
797
-
798
- // src/components/recurso/BranchDropDisplay.tsx
799
- var import_jsx_runtime = require("react/jsx-runtime");
800
- var BranchDropDisplay = ({
801
- branch,
802
- addBranch,
803
- multiMode,
804
- setMultiMode,
805
- onSaveRecurso,
806
- backOnBranch,
807
- branches,
808
- singleReturn
809
- }) => {
810
- const [fontColor, setFontColor] = (0, import_react12.useState)("#000");
811
- const [searchTerm, setSearchTerm] = (0, import_react12.useState)("");
812
- const [show, setShow] = (0, import_react12.useState)(false);
813
- const [multiSelected, setMultiSelected] = (0, import_react12.useState)([]);
814
- const dropdownRef = (0, import_react12.useRef)(null);
815
- (0, import_react12.useEffect)(() => {
816
- setFontColor(
817
- pickTextColorBasedOnBgColorAdvanced(branch.branchLevel.color, "#FFFFFF", "#000000")
818
- );
819
- }, [branch.branchLevel.color]);
820
- (0, import_react12.useEffect)(() => {
821
- const handleClickOutside = (event) => {
822
- if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
823
- 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([]);
824
1635
  }
825
- };
826
- document.addEventListener("mousedown", handleClickOutside);
827
- return () => document.removeEventListener("mousedown", handleClickOutside);
828
- }, [backOnBranch, branch]);
829
- const handleItemClick = (bn) => {
830
- const rec = bn.recurso;
831
- if (multiMode) {
832
- setMultiSelected(
833
- (prev) => prev.some((r) => r.id === rec.id) ? prev.filter((r) => r.id !== rec.id) : [...prev, rec]
834
- );
835
- } else {
836
- onSaveRecurso([rec]);
837
- addBranch(bn);
838
- 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);
839
1644
  }
840
- };
841
- const startMulti = () => {
842
- setMultiSelected([]);
843
- setMultiMode(true);
844
- setShow(true);
845
- };
846
- const handleConfirm = () => {
847
- setMultiMode(false);
848
- onSaveRecurso(multiSelected);
849
- setMultiSelected([]);
850
- setShow(false);
851
- };
852
- const cancelMulti = () => {
853
- setMultiMode(false);
854
- setMultiSelected([]);
855
- };
856
- const isLastBranchClicked = () => branches.length > 0 && branches[branches.length - 1].id === branch.id;
857
- const visibleNodes = (branch.branchNodes || []).filter(
858
- (bn) => bn.recurso.nome.toLowerCase().includes(searchTerm.toLowerCase())
859
- );
860
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
861
- "div",
862
- {
863
- ref: dropdownRef,
864
- style: {
865
- position: "relative",
866
- marginBottom: "0.5rem",
867
- width: "100%",
868
- fontFamily: "Arial, sans-serif"
869
- },
870
- children: [
871
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
872
- "button",
873
- {
874
- onClick: () => setShow((s) => !s),
875
- style: {
876
- width: "100%",
877
- display: "flex",
878
- alignItems: "center",
879
- justifyContent: "space-between",
880
- padding: "0.5rem 1rem",
881
- borderRadius: "9999px",
882
- boxShadow: "0 1px 3px rgba(0, 0, 0, 0.1)",
883
- border: `1px solid ${branch.branchLevel.color}`,
884
- background: branch.branchLevel.color,
885
- color: fontColor,
886
- cursor: "pointer",
887
- outline: "none",
888
- textAlign: "left",
889
- fontSize: "1rem"
890
- },
891
- children: [
892
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: [
893
- branch.nomeRecurso || branch.branchLevel.nome,
894
- branch.nomeRecurso && !multiMode && isLastBranchClicked() && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("em", { style: { fontStyle: "italic", opacity: 0.8, marginLeft: "0.5rem" }, children: "(Selecionado)" })
895
- ] }),
896
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaChevronDown, {})
897
- ]
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;
898
1661
  }
899
- ),
900
- show && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
901
- "div",
902
- {
903
- style: {
904
- position: "absolute",
905
- top: "100%",
906
- left: 0,
907
- width: "100%",
908
- background: "#f0f0f0",
909
- borderRadius: "8px",
910
- boxShadow: "0 2px 6px rgba(0, 0, 0, 0.15)",
911
- marginTop: "0.25rem",
912
- zIndex: 100,
913
- maxHeight: "300px",
914
- overflow: "auto"
915
- },
916
- children: [
917
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
918
- "div",
919
- {
920
- style: {
921
- display: "flex",
922
- alignItems: "center",
923
- padding: "0.5rem",
924
- borderBottom: "1px solid #ddd"
925
- },
926
- children: [
927
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaSearch, { style: { marginRight: "0.5rem", color: "#555" } }),
928
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
929
- "input",
930
- {
931
- type: "text",
932
- placeholder: "Pesquisar recurso...",
933
- value: searchTerm,
934
- onChange: (e) => setSearchTerm(e.target.value),
935
- style: {
936
- flex: 1,
937
- padding: "0.5rem",
938
- border: "1px solid #ccc",
939
- borderRadius: "9999px",
940
- outline: "none",
941
- fontSize: "0.95rem"
942
- }
943
- }
944
- )
945
- ]
946
- }
947
- ),
948
- !multiMode && !singleReturn ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
949
- "button",
950
- {
951
- onClick: startMulti,
952
- style: {
953
- display: "flex",
954
- alignItems: "center",
955
- justifyContent: "center",
956
- width: "100%",
957
- padding: "0.5rem",
958
- borderRadius: "9999px",
959
- border: "none",
960
- background: "#ffc107",
961
- color: "#000",
962
- fontSize: "0.95rem",
963
- cursor: "pointer",
964
- margin: "0.5rem 0"
965
- },
966
- children: [
967
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaCheckSquare, { style: { marginRight: "0.5rem" } }),
968
- "Selecionar m\xFAltiplos"
969
- ]
970
- }
971
- ) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", gap: "0.5rem", margin: "0.5rem 0" }, children: [
972
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
973
- "button",
974
- {
975
- onClick: handleConfirm,
976
- style: {
977
- flex: 1,
978
- display: "flex",
979
- alignItems: "center",
980
- justifyContent: "center",
981
- padding: "0.5rem",
982
- borderRadius: "9999px",
983
- border: "none",
984
- background: "#28a745",
985
- color: "#fff",
986
- fontSize: "0.95rem",
987
- cursor: "pointer"
988
- },
989
- children: [
990
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaCheck, { style: { marginRight: "0.5rem" } }),
991
- "Confirmar sele\xE7\xE3o"
992
- ]
993
- }
994
- ),
995
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
996
- "button",
997
- {
998
- onClick: cancelMulti,
999
- style: {
1000
- flex: 1,
1001
- display: "flex",
1002
- alignItems: "center",
1003
- justifyContent: "center",
1004
- padding: "0.5rem",
1005
- borderRadius: "9999px",
1006
- border: "none",
1007
- background: "#6c757d",
1008
- color: "#fff",
1009
- fontSize: "0.95rem",
1010
- cursor: "pointer"
1011
- },
1012
- children: [
1013
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_md.MdClose, { style: { marginRight: "0.5rem" } }),
1014
- "Cancelar"
1015
- ]
1016
- }
1017
- )
1018
- ] }),
1019
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { padding: "0.5rem" }, children: visibleNodes.map((bn) => {
1020
- const selected = multiMode ? multiSelected.some((r) => r.id === bn.recurso.id) : false;
1021
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1022
- "div",
1023
- {
1024
- onClick: () => handleItemClick(bn),
1025
- style: {
1026
- display: "flex",
1027
- justifyContent: "space-between",
1028
- alignItems: "center",
1029
- padding: "0.5rem",
1030
- borderBottom: "1px solid #ddd",
1031
- background: selected ? "#e9ecef" : "transparent",
1032
- cursor: "pointer",
1033
- transition: "background 0.1s"
1034
- },
1035
- onMouseEnter: (e) => {
1036
- if (!selected) e.currentTarget.style.background = "#e2e6ea";
1037
- },
1038
- onMouseLeave: (e) => {
1039
- e.currentTarget.style.background = selected ? "#e9ecef" : "transparent";
1040
- },
1041
- children: [
1042
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: bn.recurso.nome }),
1043
- selected && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaCheck, {})
1044
- ]
1045
- },
1046
- bn.recurso.id
1047
- );
1048
- }) })
1049
- ]
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
+ );
1050
1675
  }
1051
- )
1052
- ]
1053
- }
1676
+ }
1677
+ setBranches([...branchsToStay]);
1678
+ } finally {
1679
+ setIsLoading(false);
1680
+ }
1681
+ },
1682
+ [arvoreCtrl]
1054
1683
  );
1055
- };
1056
- 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
+ }
1057
1709
 
1058
- // src/components/recurso/FindRecursoByTagField.tsx
1059
- var import_react16 = require("react");
1060
- 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
+ }
1061
1770
 
1062
- // src/components/recurso/AutoComplete.tsx
1063
- var import_react13 = require("react");
1064
- var import_react_bootstrap = require("react-bootstrap");
1065
- var import_jsx_runtime2 = require("react/jsx-runtime");
1066
- var AutoComplete = ({
1067
- className,
1068
- ops,
1069
- sortKey,
1070
- displayKey,
1071
- displayKeys,
1072
- onValueChanged,
1073
- selectedKey,
1074
- onSelectedClick,
1075
- value,
1076
- actionButton,
1077
- actionButton2,
1078
- placeH,
1079
- title,
1080
- filter,
1081
- filterField,
1082
- loadFunc,
1083
- loadCondition,
1084
- isBold,
1085
- onBlurEvent,
1086
- formatationFunc,
1087
- onEscKeyDown,
1088
- margT,
1089
- hideComponent,
1090
- disableComponent = false,
1091
- disableSelect = false,
1092
- margB,
1093
- autoFocusConfig,
1094
- onLoad,
1095
- onMouseLv,
1096
- useStandardLabel = false,
1097
- isRequired = false,
1098
- ty = "text"
1099
- }) => {
1100
- const [liItem, setListItem] = (0, import_react13.useState)([]);
1101
- const [options, setOptions] = (0, import_react13.useState)([]);
1102
- const [input, setInput] = (0, import_react13.useState)("");
1103
- const [hide, setHide] = (0, import_react13.useState)(true);
1104
- const [onLoaded, setOnLoaded] = (0, import_react13.useState)(false);
1105
- const sortOptions = (opts, key) => {
1106
- if (!key || !Array.isArray(opts)) return opts != null ? opts : [];
1107
- return [...opts].sort((a, b) => String(a[key]).localeCompare(String(b[key])));
1108
- };
1109
- (0, import_react13.useEffect)(() => {
1110
- if (value) setInput(value);
1111
- else setInput("");
1112
- }, [value]);
1113
- (0, import_react13.useEffect)(() => {
1114
- const sortedOptions = sortOptions(ops, sortKey);
1115
- setListItem(sortedOptions);
1116
- setOptions(sortedOptions);
1117
- }, [ops, sortKey]);
1118
- (0, import_react13.useEffect)(() => {
1119
- const loadFunction = async () => {
1120
- if (loadCondition && loadFunc) {
1121
- try {
1122
- const res = await loadFunc();
1123
- let newOps = res.content ? res.content : res;
1124
- newOps = newOps.filter((c) => c != null);
1125
- if (Array.isArray(newOps)) {
1126
- if (filter) {
1127
- newOps = newOps.filter((op) => op[filterField] === filter);
1128
- }
1129
- const sortedOptions = sortOptions(newOps, sortKey);
1130
- setListItem(sortedOptions);
1131
- setOptions(sortedOptions);
1132
- }
1133
- if (onLoad) {
1134
- if (onLoaded) return;
1135
- setOnLoaded(true);
1136
- onLoad(newOps);
1137
- }
1138
- } catch (e) {
1139
- 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;
1140
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];
1141
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
1142
1968
  };
1143
- loadFunction();
1144
- }, [loadCondition, filter, filterField, sortKey, onLoad]);
1145
- const onFieldUpdate = (val) => {
1146
- let newListItem;
1147
- if (val && val.length > 0) {
1148
- const regex = new RegExp(`${val}`, "i");
1149
- newListItem = options.filter((liI) => {
1150
- let textToTest;
1151
- if (formatationFunc) {
1152
- textToTest = formatationFunc(liI);
1153
- } else if (displayKey) {
1154
- textToTest = liI[displayKey];
1155
- } else if (displayKeys) {
1156
- textToTest = keysJoinner(liI);
1157
- } else {
1158
- textToTest = liI;
1159
- }
1160
- return regex.test(textToTest);
1161
- });
1162
- setListItem(newListItem);
1163
- } else {
1164
- 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;
1165
1999
  }
1166
- onValueChanged && onValueChanged(val);
1167
- setInput(val);
1168
- setHide(false);
1169
- };
1170
- const clear = () => {
1171
- setInput("");
1172
- };
1173
- const onOpSelected = (li, index, lItem) => {
1174
- if (formatationFunc) {
1175
- setInput(formatationFunc(li));
1176
- } else if (displayKey) {
1177
- setInput(li[displayKey]);
1178
- } else if (displayKeys) {
1179
- setInput(keysJoinner(li));
1180
- } else {
1181
- 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);
1182
2084
  }
1183
- onSelectedClick(li, index, lItem);
1184
- setHide(true);
1185
- };
1186
- const keysJoinner = (li) => {
1187
- if (!displayKeys || !Array.isArray(displayKeys)) return "";
1188
- const textToRender = displayKeys.map((key) => `${li[key]} `);
1189
- return textToRender.join("").trim();
1190
- };
1191
- const renderMoreThanOneKey = (li, index) => {
1192
- const buildedString = keysJoinner(li);
1193
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("li", { children: buildedString }, index);
1194
- };
1195
- const boldedPart = (text, key) => {
1196
- 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: []
1197
2211
  };
1198
- const displayListItens = (li, index) => {
1199
- if (formatationFunc) {
1200
- 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.";
1201
2222
  }
1202
- if (displayKey) {
1203
- 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.";
1204
2231
  }
1205
- if (displayKeys) {
1206
- 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.";
1207
2234
  }
1208
- return boldedPart(li, index);
1209
- };
1210
- const onKeyDownHandler = (event) => {
1211
- if (event.key === "Escape") {
1212
- setHide(true);
1213
- 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.";
1214
2238
  }
1215
- };
1216
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1217
- "div",
1218
- {
1219
- className: `${className}`,
1220
- style: { marginTop: margT || 4, marginBottom: margB || 4, position: "relative" },
1221
- onBlur: (e) => {
1222
- setTimeout(() => {
1223
- if (onBlurEvent) onBlurEvent(e, input);
1224
- setHide(true);
1225
- }, 200);
1226
- },
1227
- onKeyDown: (event) => onKeyDownHandler(event),
1228
- onMouseLeave: () => {
1229
- setHide(true);
1230
- },
1231
- children: [
1232
- !hideComponent && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
1233
- useStandardLabel && title && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_bootstrap.Form.Label, { children: [
1234
- title,
1235
- isRequired && " *"
1236
- ] }),
1237
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_bootstrap.InputGroup, { children: [
1238
- useStandardLabel ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1239
- import_react_bootstrap.Form.Control,
1240
- {
1241
- autoFocus: autoFocusConfig,
1242
- disabled: disableComponent || disableSelect,
1243
- placeholder: placeH,
1244
- autoComplete: "off",
1245
- value: input,
1246
- onClickCapture: () => {
1247
- setHide(false);
1248
- if (!input) {
1249
- onFieldUpdate("");
1250
- }
1251
- },
1252
- onChange: (event) => onFieldUpdate(event.currentTarget.value),
1253
- type: "text"
1254
- }
1255
- ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_bootstrap.FloatingLabel, { style: { zIndex: 0 }, label: title, controlId: "floatingInput", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1256
- import_react_bootstrap.Form.Control,
1257
- {
1258
- autoFocus: autoFocusConfig,
1259
- disabled: disableComponent || disableSelect,
1260
- placeholder: placeH,
1261
- autoComplete: "off",
1262
- value: input,
1263
- onClickCapture: () => {
1264
- setHide(false);
1265
- if (!input) {
1266
- onFieldUpdate("");
1267
- }
1268
- },
1269
- onChange: (event) => onFieldUpdate(event.currentTarget.value),
1270
- type: "text"
1271
- }
1272
- ) }),
1273
- !disableComponent && actionButton && actionButton(clear),
1274
- !disableComponent && actionButton2 && actionButton2(input)
1275
- ] })
1276
- ] }),
1277
- 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)) })
1278
- ]
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);
1279
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
+ ]
1280
2343
  );
1281
- };
1282
- var AutoComplete_default = AutoComplete;
2344
+ }
1283
2345
 
1284
- // src/components/recurso/QrCodeScanButton.tsx
1285
- var import_react15 = require("react");
1286
- 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");
1287
2349
 
1288
- // src/components/recurso/QrReader.tsx
1289
- var import_qr_scanner = __toESM(require("qr-scanner"));
1290
- var import_react14 = require("react");
1291
- var import_jsx_runtime3 = require("react/jsx-runtime");
1292
- var QrReader = ({ callback }) => {
1293
- const scanner = (0, import_react14.useRef)(null);
1294
- const videoEl = (0, import_react14.useRef)(null);
1295
- const qrBoxEl = (0, import_react14.useRef)(null);
1296
- const [qrOn, setQrOn] = (0, import_react14.useState)(true);
1297
- const [scannedResult, setScannedResult] = (0, import_react14.useState)("");
1298
- const onScanSuccess = (result) => {
1299
- setScannedResult(result == null ? void 0 : result.data);
1300
- callback(result == null ? void 0 : result.data);
1301
- };
1302
- const onScanFail = (err) => {
1303
- console.error(err);
1304
- };
1305
- (0, import_react14.useEffect)(() => {
1306
- if ((videoEl == null ? void 0 : videoEl.current) && !scanner.current) {
1307
- scanner.current = new import_qr_scanner.default(videoEl.current, onScanSuccess, {
1308
- onDecodeError: onScanFail,
1309
- preferredCamera: "environment",
1310
- highlightScanRegion: true,
1311
- highlightCodeOutline: true,
1312
- overlay: (qrBoxEl == null ? void 0 : qrBoxEl.current) || void 0
1313
- });
1314
- scanner.current.start().then(() => setQrOn(true)).catch((err) => {
1315
- if (err) setQrOn(false);
1316
- });
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];
1317
2386
  }
1318
- return () => {
1319
- var _a;
1320
- if (!(videoEl == null ? void 0 : videoEl.current)) {
1321
- (_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
+ );
1322
2430
  }
1323
- };
1324
- }, []);
1325
- (0, import_react14.useEffect)(() => {
1326
- if (!qrOn)
1327
- alert(
1328
- "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" })
1329
2438
  );
1330
- }, [qrOn]);
1331
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "qr-reader", children: [
1332
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("video", { ref: videoEl }),
1333
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: qrBoxEl, className: "qr-box" }),
1334
- scannedResult && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1335
- "p",
1336
- {
1337
- style: {
1338
- position: "absolute",
1339
- top: 0,
1340
- left: 0,
1341
- zIndex: 99999,
1342
- color: "white"
1343
- },
1344
- children: [
1345
- "Scanned Result: ",
1346
- scannedResult
1347
- ]
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";
1348
2457
  }
1349
- )
1350
- ] });
1351
- };
1352
- 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
+ }
1353
2518
 
1354
- // src/components/recurso/QrCodeScanButton.tsx
1355
- var import_jsx_runtime4 = require("react/jsx-runtime");
1356
- var QrCodeScanButton = ({ callback }) => {
1357
- const [showQr, setShowQr] = (0, import_react15.useState)(false);
1358
- const qrShowHandler = () => {
1359
- setShowQr((prev) => !prev);
1360
- };
1361
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1362
- "div",
1363
- {
1364
- className: "hoverable-div",
1365
- style: {
1366
- border: "solid",
1367
- borderTopRightRadius: "3px",
1368
- borderBottomRightRadius: "3px",
1369
- padding: "8px",
1370
- borderLeft: "none",
1371
- borderColor: "#ccc",
1372
- borderWidth: "1px"
1373
- },
1374
- children: [
1375
- showQr && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1376
- QrReader_default,
1377
- {
1378
- callback: (v) => {
1379
- qrShowHandler();
1380
- callback(v);
1381
- }
1382
- }
1383
- ),
1384
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1385
- import_bs.BsQrCode,
1386
- {
1387
- size: 25,
1388
- onClick: () => {
1389
- qrShowHandler();
1390
- }
1391
- }
1392
- )
1393
- ]
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);
1394
2554
  }
2555
+ }, [saving, current, tarefaCtrl, tarefaId, fatherId, toast]);
2556
+ return (0, import_react23.useMemo)(
2557
+ () => ({ current, toggle, saving }),
2558
+ [current, toggle, saving]
1395
2559
  );
1396
- };
1397
- var QrCodeScanButton_default = QrCodeScanButton;
2560
+ }
1398
2561
 
1399
- // src/components/recurso/FindRecursoByTagField.tsx
1400
- var import_jsx_runtime5 = require("react/jsx-runtime");
1401
- var FindRecursoByTagField = ({ callback }) => {
1402
- const recursoController = useHttpController("recurso");
1403
- const [selectedTag, setSelectedTag] = (0, import_react16.useState)(null);
1404
- const [reachedRecurso, setReachedRecurso] = (0, import_react16.useState)(null);
1405
- const findRecursoByTagIdHandler = async (tagId) => {
1406
- const r = await recursoController.read("findRecursoByTagId", tagId);
1407
- setReachedRecurso(r);
1408
- };
1409
- const findRecursoByTagDescriptionHandler = async (description) => {
1410
- const recurso = await recursoController.read(
1411
- "recurso/findByTagDescription",
1412
- description.replace(" ", "")
1413
- );
1414
- if (!callback) {
1415
- console.log(recurso);
1416
- } else {
1417
- callback(recurso, true);
1418
- }
1419
- };
1420
- const confirmRecursoSelectionButton = () => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1421
- "div",
1422
- {
1423
- className: "hoverable-div",
1424
- style: {
1425
- border: "solid",
1426
- borderTopRightRadius: "3px",
1427
- borderBottomRightRadius: "3px",
1428
- padding: "8px",
1429
- borderLeft: "none",
1430
- borderColor: "#ccc",
1431
- borderWidth: "1px"
1432
- },
1433
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_gr.GrCheckmark, { size: 25, onClick: () => callback(reachedRecurso, true) })
1434
- }
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]
1435
2573
  );
1436
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1437
- AutoComplete_default,
1438
- {
1439
- sortKey: "id",
1440
- loadCondition: true,
1441
- loadFunc: () => recursoController.get("findActiveRecursosTags"),
1442
- displayKey: "descricao",
1443
- title: "Selecione ou Digite a TAG",
1444
- isBold: true,
1445
- actionButton: confirmRecursoSelectionButton,
1446
- actionButton2: () => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1447
- QrCodeScanButton_default,
1448
- {
1449
- callback: (description) => findRecursoByTagDescriptionHandler(description)
1450
- }
1451
- ),
1452
- onSelectedClick: (v) => {
1453
- setSelectedTag(v);
1454
- findRecursoByTagIdHandler(v.id);
1455
- },
1456
- 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);
1457
2591
  }
1458
- ) });
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
1459
2632
  };
1460
- 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;
1461
2663
 
1462
- // src/components/recurso/RecursoDisplayer.tsx
1463
- var import_jsx_runtime6 = require("react/jsx-runtime");
1464
- var RecursoDisplayer = ({
1465
- selectedList = [],
1466
- onSaveRecurso,
1467
- singleReturn = false
1468
- }) => {
1469
- const arvoreEstruturalController = useHttpController("");
1470
- const branchLevelController = useHttpController("branchLevel");
1471
- const [branches, setBranches] = (0, import_react17.useState)([]);
1472
- const dispatch = (0, import_react_redux3.useDispatch)();
1473
- const [localSelected, setLocalSelected] = (0, import_react17.useState)(selectedList);
1474
- const [selectorDisplay, setSelectorDisplay] = (0, import_react17.useState)("");
1475
- const [multiMode, setMultiMode] = (0, import_react17.useState)(false);
1476
- (0, import_react17.useEffect)(() => {
1477
- const init = async () => {
1478
- const b = await arvoreEstruturalController.get("branchByBranchLevel/1");
1479
- setBranches(b);
1480
- const lv = await branchLevelController.readAll();
1481
- dispatch(setLevels(lv));
1482
- };
1483
- init();
1484
- }, []);
1485
- const branchSetter = async (bn) => {
1486
- const copy = [...branches];
1487
- const branch = await arvoreEstruturalController.read("branch", bn.recurso.branch.id);
1488
- copy[bn.recurso.branch.branchLevel.level - 1] = {
1489
- ...branch,
1490
- nomeRecurso: bn.recurso.nome
1491
- };
1492
- setBranches(copy);
1493
- };
1494
- const backOnBranch = (branch) => {
1495
- const branchsToStay = branches.filter(
1496
- (bArray) => bArray.branchLevel.level <= branch.branchLevel.level
1497
- );
1498
- setBranches(branchsToStay);
1499
- };
1500
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { width: "100%", padding: 0 }, children: [
1501
- /* @__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: [
1502
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("label", { className: "me-2", children: "Selecionar Recurso Por:" }),
1503
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1504
- import_react_bootstrap2.Button,
1505
- {
1506
- size: "sm",
1507
- onClick: () => setSelectorDisplay("branch"),
1508
- variant: selectorDisplay === "branch" ? "primary" : "outline-primary",
1509
- className: "me-1",
1510
- 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
+ });
1511
2722
  }
1512
- ),
1513
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1514
- import_react_bootstrap2.Button,
1515
- {
1516
- size: "sm",
1517
- onClick: () => setSelectorDisplay("TAG"),
1518
- variant: selectorDisplay === "TAG" ? "primary" : "outline-primary",
1519
- 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
+ });
1520
2753
  }
1521
- )
1522
- ] }) }),
1523
- selectorDisplay === "branch" && branches.map((branch, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1524
- BranchDropDisplay_default,
1525
- {
1526
- branch,
1527
- addBranch: branchSetter,
1528
- multiMode,
1529
- setMultiMode,
1530
- onSaveRecurso,
1531
- backOnBranch,
1532
- branches,
1533
- singleReturn
1534
- },
1535
- branch.id || i
1536
- )),
1537
- selectorDisplay === "TAG" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1538
- FindRecursoByTagField_default,
1539
- {
1540
- callback: (rec, checked) => {
1541
- setLocalSelected([rec]);
1542
- 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) {
1543
2825
  }
2826
+ throw err;
1544
2827
  }
1545
- )
1546
- ] });
1547
- };
1548
- 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
+ }
1549
2876
 
1550
2877
  // src/reducers/pickerReducer.ts
1551
- var import_toolkit2 = require("@reduxjs/toolkit");
1552
- var initialState2 = {
2878
+ var import_toolkit8 = require("@reduxjs/toolkit");
2879
+ var initialState8 = {
1553
2880
  selected: null,
1554
2881
  items: [],
1555
2882
  visible: false,
1556
2883
  context: ""
1557
2884
  };
1558
- var pickerSlice = (0, import_toolkit2.createSlice)({
2885
+ var pickerSlice = (0, import_toolkit8.createSlice)({
1559
2886
  name: "picker",
1560
- initialState: initialState2,
2887
+ initialState: initialState8,
1561
2888
  reducers: {
1562
2889
  setPickerSelected(state, action) {
1563
2890
  state.selected = action.payload;
@@ -1572,7 +2899,7 @@ var pickerSlice = (0, import_toolkit2.createSlice)({
1572
2899
  state.context = action.payload;
1573
2900
  },
1574
2901
  clearPicker() {
1575
- return initialState2;
2902
+ return initialState8;
1576
2903
  }
1577
2904
  }
1578
2905
  });
@@ -1585,6 +2912,20 @@ var {
1585
2912
  } = pickerSlice.actions;
1586
2913
  var pickerReducer_default = pickerSlice.reducer;
1587
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
+
1588
2929
  // src/utils/webVitals.ts
1589
2930
  function initWebVitals(observability) {
1590
2931
  if (typeof PerformanceObserver === "undefined") return;
@@ -1619,28 +2960,28 @@ function initWebVitals(observability) {
1619
2960
  }
1620
2961
 
1621
2962
  // src/utils/dateUtils.ts
1622
- var import_dayjs = __toESM(require("dayjs"));
2963
+ var import_dayjs2 = __toESM(require("dayjs"));
1623
2964
  function formatDate(date, format = "DD/MM/YYYY") {
1624
2965
  if (!date) return "";
1625
- return (0, import_dayjs.default)(date).format(format);
2966
+ return (0, import_dayjs2.default)(date).format(format);
1626
2967
  }
1627
2968
  function formatDateTime(date) {
1628
2969
  return formatDate(date, "DD/MM/YYYY HH:mm");
1629
2970
  }
1630
2971
  function isDateBefore(date1, date2) {
1631
- 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));
1632
2973
  }
1633
2974
  function isDateAfter(date1, date2) {
1634
- 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));
1635
2976
  }
1636
2977
  function daysBetween(start, end) {
1637
- 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");
1638
2979
  }
1639
2980
  function addDays(date, days) {
1640
- return (0, import_dayjs.default)(date).add(days, "day").toDate();
2981
+ return (0, import_dayjs2.default)(date).add(days, "day").toDate();
1641
2982
  }
1642
2983
  function toISOString(date) {
1643
- return (0, import_dayjs.default)(date).toISOString();
2984
+ return (0, import_dayjs2.default)(date).toISOString();
1644
2985
  }
1645
2986
 
1646
2987
  // src/utils/stringUtils.ts
@@ -1663,10 +3004,10 @@ function isBlank(str) {
1663
3004
  }
1664
3005
 
1665
3006
  // src/federation/FederatedBridge.tsx
1666
- var import_react18 = require("react");
1667
- var import_jsx_runtime7 = require("react/jsx-runtime");
3007
+ var import_react27 = require("react");
3008
+ var import_jsx_runtime = require("react/jsx-runtime");
1668
3009
  function FederatedBridge({ coreService, children }) {
1669
- (0, import_react18.useEffect)(() => {
3010
+ (0, import_react27.useEffect)(() => {
1670
3011
  if (typeof window === "undefined") return;
1671
3012
  window.__TERAPROX_HOSTED_BY_CORE__ = true;
1672
3013
  return () => {
@@ -1674,28 +3015,81 @@ function FederatedBridge({ coreService, children }) {
1674
3015
  window.__TERAPROX_HOSTED_BY_CORE__ = false;
1675
3016
  };
1676
3017
  }, []);
1677
- 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__;
1678
3025
  }
1679
3026
 
1680
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
+ }
1681
3084
  function createReducersBundle(config) {
1682
3085
  const { reducers, contextMap, defaults = [] } = config;
1683
3086
  const allKeys = Object.keys(reducers);
3087
+ const getReducersForKeys = buildGetReducersForKeys(reducers);
1684
3088
  const getReducerKeysByContext = (context) => {
1685
3089
  const contextKeys = contextMap[context];
1686
3090
  if (!contextKeys) return allKeys;
1687
3091
  return [.../* @__PURE__ */ new Set([...defaults, ...contextKeys])];
1688
3092
  };
1689
- const getReducersForKeys = async (keys = []) => {
1690
- const uniqueKeys = [...new Set(keys)].filter((key) => !!reducers[key]);
1691
- const loaded = await Promise.all(
1692
- uniqueKeys.map(async (key) => {
1693
- const module2 = await reducers[key]();
1694
- return [key, module2.default || module2];
1695
- })
1696
- );
1697
- return Object.fromEntries(loaded);
1698
- };
1699
3093
  const getReducersForModule = async ({
1700
3094
  context
1701
3095
  } = {}) => {
@@ -1713,8 +3107,8 @@ function createReducersBundle(config) {
1713
3107
  }
1714
3108
 
1715
3109
  // src/federation/StandaloneProvider.tsx
1716
- var import_react19 = require("react");
1717
- var import_jsx_runtime8 = require("react/jsx-runtime");
3110
+ var import_react28 = require("react");
3111
+ var import_jsx_runtime2 = require("react/jsx-runtime");
1718
3112
  async function probeEmulator(host, port) {
1719
3113
  try {
1720
3114
  const res = await fetch(`http://${host}:${port}/.json`, {
@@ -1753,7 +3147,7 @@ async function resolveRtdbStrategy(firebaseConfig, emulator) {
1753
3147
  }
1754
3148
  var _emulatorConnected = /* @__PURE__ */ new Set();
1755
3149
  function RtdbConfigWarning({ onDismiss }) {
1756
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
3150
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1757
3151
  "div",
1758
3152
  {
1759
3153
  style: {
@@ -1773,28 +3167,28 @@ function RtdbConfigWarning({ onDismiss }) {
1773
3167
  lineHeight: 1.6
1774
3168
  },
1775
3169
  children: [
1776
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { fontWeight: "bold", marginBottom: 8, color: "#f59e0b", fontSize: 14 }, children: "\u26A0 RTDB n\xE3o configurado" }),
1777
- /* @__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: [
1778
3172
  "Matching Objects em tempo real desativados.",
1779
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("br", {}),
3173
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("br", {}),
1780
3174
  "Configure no ",
1781
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("code", { children: ".env.dev" }),
3175
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("code", { children: ".env.dev" }),
1782
3176
  ":",
1783
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("br", {}),
1784
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("code", { style: { color: "#86efac" }, children: "REACT_APP_RTDB_EMULATOR_HOST=localhost:9000" }),
1785
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("br", {}),
1786
- /* @__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: [
1787
3181
  "ou inicie o backend com ",
1788
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("code", { children: "RtdbEmulatorPlugin" }),
3182
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("code", { children: "RtdbEmulatorPlugin" }),
1789
3183
  " do @onroad/core"
1790
3184
  ] }),
1791
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("br", {}),
1792
- /* @__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: [
1793
3187
  "e rode o emulator com ",
1794
- /* @__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" })
1795
3189
  ] })
1796
3190
  ] }),
1797
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3191
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1798
3192
  "button",
1799
3193
  {
1800
3194
  onClick: onDismiss,
@@ -1815,27 +3209,45 @@ function RtdbConfigWarning({ onDismiss }) {
1815
3209
  }
1816
3210
  );
1817
3211
  }
1818
- function StandaloneProvider({ createController, addToast, firebaseConfig, emulator, tenant, children }) {
1819
- const [subscriptions] = (0, import_react19.useState)([]);
1820
- 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);
1821
3223
  subscriptionsRef.current = subscriptions;
1822
- const [rtdbWarning, setRtdbWarning] = (0, import_react19.useState)(false);
1823
- const toast = (0, import_react19.useMemo)(
1824
- () => ({
1825
- success: (msg, opts) => addToast(msg, { appearance: "success", autoDismiss: true, ...opts }),
1826
- warning: (msg, opts) => addToast(msg, { appearance: "warning", autoDismiss: true, ...opts }),
1827
- error: (msg, opts) => addToast(msg, { appearance: "error", autoDismiss: true, ...opts }),
1828
- info: (msg, opts) => addToast(msg, { appearance: "info", autoDismiss: true, ...opts })
1829
- }),
1830
- [addToast]
1831
- );
1832
- 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)(
1833
3245
  (mo) => {
1834
3246
  subscriptions.push(mo);
1835
3247
  },
1836
3248
  [subscriptions]
1837
3249
  );
1838
- const unsubscribe = (0, import_react19.useCallback)(
3250
+ const unsubscribe = (0, import_react28.useCallback)(
1839
3251
  (mo) => {
1840
3252
  const idx = subscriptions.findIndex(
1841
3253
  (s) => s.context === mo.context && s.location === mo.location
@@ -1844,8 +3256,17 @@ function StandaloneProvider({ createController, addToast, firebaseConfig, emulat
1844
3256
  },
1845
3257
  [subscriptions]
1846
3258
  );
1847
- (0, import_react19.useEffect)(() => {
1848
- 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;
1849
3270
  let cleanup;
1850
3271
  let cancelled = false;
1851
3272
  (async () => {
@@ -1888,7 +3309,7 @@ function StandaloneProvider({ createController, addToast, firebaseConfig, emulat
1888
3309
  const cloudApp = existingApp != null ? existingApp : initializeApp(strategy.config);
1889
3310
  db = getDatabase(cloudApp);
1890
3311
  }
1891
- const moRef = ref(db, `${tenant}/matchingObjects`);
3312
+ const moRef = ref(db, `${resolvedTenant}/matchingObjects`);
1892
3313
  const unsub = onChildAdded(moRef, (snapshot) => {
1893
3314
  const data = snapshot.val();
1894
3315
  if (!data) return;
@@ -1918,8 +3339,8 @@ function StandaloneProvider({ createController, addToast, firebaseConfig, emulat
1918
3339
  cancelled = true;
1919
3340
  cleanup == null ? void 0 : cleanup();
1920
3341
  };
1921
- }, [firebaseConfig, emulator, tenant]);
1922
- const value = (0, import_react19.useMemo)(
3342
+ }, [firebaseConfig, emulator, resolvedTenant]);
3343
+ const value = (0, import_react28.useMemo)(
1923
3344
  () => ({
1924
3345
  createController,
1925
3346
  toast,
@@ -1932,20 +3353,21 @@ function StandaloneProvider({ createController, addToast, firebaseConfig, emulat
1932
3353
  handleLogout: () => {
1933
3354
  },
1934
3355
  hostedByCore: false,
1935
- observability: new NullObservabilityAdapter()
3356
+ observability: new NullObservabilityAdapter(),
3357
+ rateLimits: {}
1936
3358
  }),
1937
3359
  [createController, toast, subscribe, unsubscribe]
1938
3360
  );
1939
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(CoreServiceContext.Provider, { value, children: [
3361
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(CoreServiceContext.Provider, { value, children: [
1940
3362
  children,
1941
- rtdbWarning && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(RtdbConfigWarning, { onDismiss: () => setRtdbWarning(false) })
3363
+ rtdbWarning && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RtdbConfigWarning, { onDismiss: () => setRtdbWarning(false) })
1942
3364
  ] });
1943
3365
  }
1944
3366
 
1945
3367
  // src/federation/DevAutoLogin.tsx
1946
- var import_react20 = require("react");
1947
- var import_react_redux4 = require("react-redux");
1948
- 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");
1949
3371
  var DEFAULT_DEV_USER = {
1950
3372
  firstName: "Dev",
1951
3373
  lastName: "User",
@@ -1962,79 +3384,237 @@ var DEFAULT_DEV_USER = {
1962
3384
  filters: []
1963
3385
  };
1964
3386
  function DevAutoLogin({ actions, devUser, children }) {
1965
- const dispatch = (0, import_react_redux4.useDispatch)();
1966
- 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) => {
1967
3389
  var _a;
1968
3390
  return (_a = state.global) == null ? void 0 : _a.token;
1969
3391
  });
1970
3392
  const hostedByCore = typeof window !== "undefined" && window.__TERAPROX_HOSTED_BY_CORE__ === true;
1971
- (0, import_react20.useEffect)(() => {
3393
+ (0, import_react29.useEffect)(() => {
1972
3394
  if (process.env.NODE_ENV === "development" && !hostedByCore && !token) {
1973
3395
  const user = { ...DEFAULT_DEV_USER, ...devUser };
1974
3396
  dispatch(actions.setCompany(user.companyId));
1975
3397
  dispatch(actions.logIn(user));
1976
3398
  }
1977
3399
  }, [dispatch, hostedByCore, token, actions, devUser]);
1978
- 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;
1979
3487
  }
1980
3488
  // Annotate the CommonJS export names for ESM import in node:
1981
3489
  0 && (module.exports = {
3490
+ CONTADOR_DEFAULT_KEY,
1982
3491
  CoreServiceBuilder,
1983
3492
  CoreServiceContext,
1984
3493
  DevAutoLogin,
3494
+ FILTER_COMBINE_MODES,
1985
3495
  FederatedBridge,
1986
3496
  FetchHttpAdapter,
3497
+ INSPECAO_MODAL_DEFAULT_KEY,
1987
3498
  NullCoreService,
1988
3499
  NullHttpController,
1989
3500
  NullObservabilityAdapter,
1990
3501
  NullToastService,
1991
- RecursoDisplayer,
3502
+ RECORRENCIA_DEFAULT_KEY,
1992
3503
  StandaloneProvider,
1993
3504
  TracingHttpAdapter,
3505
+ UNIDADE_MATERIAL_DEFAULT_KEY,
3506
+ addContadorLimite,
1994
3507
  addDays,
1995
3508
  branchLevelReducer,
1996
3509
  buildTraceparent,
1997
3510
  capitalize,
1998
3511
  clearBranchLevelForm,
3512
+ clearContador,
3513
+ clearInspecaoModal,
3514
+ clearMantenedorSlot,
1999
3515
  clearPicker,
3516
+ clearRecorrencia,
3517
+ clearUnidadeMaterial,
3518
+ contadorReducer,
2000
3519
  createReducersBundle,
3520
+ createReducersFromManifest,
2001
3521
  daysBetween,
2002
3522
  formatDate,
2003
3523
  formatDateTime,
2004
3524
  generateSpanId,
2005
3525
  generateTraceId,
3526
+ groupMenuSections,
3527
+ hmsToSeconds,
2006
3528
  initWebVitals,
3529
+ inspecaoModalReducer,
2007
3530
  isBlank,
2008
3531
  isDateAfter,
2009
3532
  isDateBefore,
3533
+ isHostedByCore,
3534
+ mantenedorPickerReducer,
3535
+ pickMantenedorTipoReducer,
2010
3536
  pickTextColorBasedOnBgColorAdvanced,
2011
3537
  pickerReducer,
3538
+ populateContador,
3539
+ populateInspecaoModal,
3540
+ populateRecorrencia,
2012
3541
  populateToEdit,
3542
+ populateUnidadeMaterial,
3543
+ recorrenciaReducer,
2013
3544
  removeAccents,
3545
+ removeContadorLimiteAt,
3546
+ removeInspecaoLimiteAt,
3547
+ resetPickMantenedorTipo,
3548
+ secondsToHms,
3549
+ selectContador,
3550
+ selectInspecaoModal,
3551
+ selectRecorrencia,
3552
+ selectUnidadeMaterial,
2014
3553
  setColor,
3554
+ setContadorParametro,
3555
+ setContadorUnidade,
3556
+ setContadorValor,
2015
3557
  setExcludeLevels,
2016
3558
  setHaveComponente,
3559
+ setInspecaoLimites,
3560
+ setInspecaoNomeParametro,
3561
+ setInspecaoParametro,
3562
+ setInspecaoTipo,
3563
+ setInspecaoUnidadeParametro,
2017
3564
  setLevel,
2018
3565
  setLevels,
3566
+ setMantenedorError,
3567
+ setMantenedorLoading,
3568
+ setMantenedorOptions,
3569
+ setMantenedorPendingConfirm,
3570
+ setMantenedorSearchTerm,
2019
3571
  setNome,
3572
+ setPickMantenedorTipoAssigning,
3573
+ setPickMantenedorTipoError,
3574
+ setPickMantenedorTipoLoading,
3575
+ setPickMantenedorTipoOptions,
2020
3576
  setPickerContext,
2021
3577
  setPickerItems,
2022
3578
  setPickerSelected,
2023
3579
  setPickerVisible,
3580
+ setRecorrenciaDataInicio,
3581
+ setRecorrenciaEscala,
3582
+ setRecorrenciaValor,
3583
+ setUnidadeMaterialMaterial,
3584
+ setUnidadeMaterialQuantidade,
3585
+ setUnidadeMaterialUnidade,
2024
3586
  slugify,
2025
3587
  toISOString,
2026
3588
  truncate,
3589
+ unidadeMaterialReducer,
3590
+ updateContadorLimiteAt,
3591
+ useAnexoManager,
3592
+ useAnexoManagerViewModel,
2027
3593
  useAnexoUpload,
3594
+ useContadorViewModel,
2028
3595
  useCoreService,
2029
3596
  useFetchData,
3597
+ useFilterCombineMode,
3598
+ useFindRecursoByTagViewModel,
2030
3599
  useFormStorage,
2031
3600
  useHttpController,
3601
+ useInspecaoModalViewModel,
3602
+ useJustificativaModalViewModel,
3603
+ useMantenedorPickerViewModel,
2032
3604
  useMatchingObject,
2033
3605
  useNavigator,
2034
3606
  useNotifications,
2035
3607
  useObservability,
3608
+ useObservacoesTarefaViewModel,
3609
+ usePickMantenedorTipoViewModel,
2036
3610
  usePostData,
3611
+ useRecorrenciaViewModel,
3612
+ useRecursoDisplayerViewModel,
2037
3613
  useSmartSearch,
3614
+ useTarefaItemViewModel,
3615
+ useTarefaStatusViewModel,
3616
+ useTimeFormat,
2038
3617
  useToast,
3618
+ useUnidadeMaterialViewModel,
2039
3619
  useValidation
2040
3620
  });