@v1ct0rbr/minivault-web 0.4.3 → 0.6.0

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.
@@ -56,11 +56,11 @@ var h = class extends Error {
56
56
  getBackup(e) {
57
57
  return this.request(`/api/backups/${e}`);
58
58
  }
59
- createBackup(e, t, n) {
60
- let r = {};
61
- return e && (r.database = e), t && (r.originStorage = t), n && (r.dumpOptions = n), this.request("/api/backups", {
59
+ createBackup(e, t, n, r) {
60
+ let i = {};
61
+ return r && (i.backupType = r), e && (i.database = e), t && (i.originStorage = t), n && (i.dumpOptions = n), this.request("/api/backups", {
62
62
  method: "POST",
63
- body: JSON.stringify(r)
63
+ body: JSON.stringify(i)
64
64
  });
65
65
  }
66
66
  restoreBackup(e, t, n) {
@@ -135,6 +135,9 @@ var h = class extends Error {
135
135
  listDbRelationships() {
136
136
  return this.request("/api/db/relationships");
137
137
  }
138
+ getDiagnostics() {
139
+ return this.request("/api/diagnostics");
140
+ }
138
141
  listStorageFiles(e, t, n) {
139
142
  let r = new URLSearchParams({ type: e });
140
143
  return t && r.set("prefix", t), n && (n.endpoint && r.set("endpoint", n.endpoint), n.bucketName && r.set("bucketName", n.bucketName), n.accessKey && r.set("accessKey", n.accessKey), n.secretKey && r.set("secretKey", n.secretKey), n.region && r.set("region", n.region), n.pathStyleEnabled && r.set("pathStyleEnabled", "true"), n.localPath && r.set("localPath", n.localPath)), this.request(`/api/storage/files?${r.toString()}`);
@@ -202,9 +205,18 @@ function x() {
202
205
  //#region src/hooks/useBackups.ts
203
206
  var S = {
204
207
  all: ["minivault", "backups"],
205
- db: ["minivault", "db"]
208
+ db: ["minivault", "db"],
209
+ diagnostics: ["minivault", "diagnostics"]
206
210
  };
207
- function C(e = 0, t = 10, n = !0) {
211
+ function C(e = !0) {
212
+ let t = x();
213
+ return u({
214
+ queryKey: S.diagnostics,
215
+ queryFn: () => t.getDiagnostics(),
216
+ enabled: e && !!t
217
+ });
218
+ }
219
+ function w(e = 0, t = 10, n = !0) {
208
220
  let r = x();
209
221
  return u({
210
222
  queryKey: [
@@ -216,7 +228,7 @@ function C(e = 0, t = 10, n = !0) {
216
228
  enabled: n && !!r
217
229
  });
218
230
  }
219
- function w(e = !0) {
231
+ function T(e = !0) {
220
232
  let t = x();
221
233
  return u({
222
234
  queryKey: [...S.db, "info"],
@@ -224,7 +236,7 @@ function w(e = !0) {
224
236
  enabled: e && !!t
225
237
  });
226
238
  }
227
- function T(e = !0) {
239
+ function E(e = !0) {
228
240
  let t = x();
229
241
  return u({
230
242
  queryKey: [...S.db, "tables"],
@@ -232,7 +244,7 @@ function T(e = !0) {
232
244
  enabled: e && !!t
233
245
  });
234
246
  }
235
- function E(e, t = !0) {
247
+ function D(e, t = !0) {
236
248
  let n = x();
237
249
  return u({
238
250
  queryKey: [
@@ -244,7 +256,7 @@ function E(e, t = !0) {
244
256
  enabled: t && !!n && !!e
245
257
  });
246
258
  }
247
- function D(e = !0) {
259
+ function O(e = !0) {
248
260
  let t = x();
249
261
  return u({
250
262
  queryKey: [...S.db, "relationships"],
@@ -252,49 +264,49 @@ function D(e = !0) {
252
264
  enabled: e && !!t
253
265
  });
254
266
  }
255
- function O() {
267
+ function k() {
256
268
  let e = b(), t = d();
257
269
  return l({
258
- mutationFn: (t) => e.createBackup(t.database, t.originStorage, t.dumpOptions),
270
+ mutationFn: (t) => e.createBackup(t.database, t.originStorage, t.dumpOptions, t.backupType),
259
271
  onSuccess: () => t.invalidateQueries({ queryKey: S.all })
260
272
  });
261
273
  }
262
- function k() {
274
+ function A() {
263
275
  let e = b(), t = d();
264
276
  return l({
265
277
  mutationFn: (t) => e.restoreBackup(t.id, t.database, t.originStorage),
266
278
  onSuccess: () => t.invalidateQueries({ queryKey: S.all })
267
279
  });
268
280
  }
269
- function A() {
281
+ function j() {
270
282
  let e = b(), t = d();
271
283
  return l({
272
284
  mutationFn: (t) => e.deleteBackup(t),
273
285
  onSuccess: () => t.invalidateQueries({ queryKey: S.all })
274
286
  });
275
287
  }
276
- function j() {
288
+ function M() {
277
289
  let e = b(), t = d();
278
290
  return l({
279
291
  mutationFn: (t) => e.verifyBackup(t),
280
292
  onSuccess: () => t.invalidateQueries({ queryKey: S.all })
281
293
  });
282
294
  }
283
- function M() {
295
+ function N() {
284
296
  let e = b();
285
297
  return l({ mutationFn: (t) => e.downloadBackup(t.id) });
286
298
  }
287
- function N() {
299
+ function P() {
288
300
  let e = b();
289
301
  return l({ mutationFn: (t) => e.importDump(t.file, t.database) });
290
302
  }
291
- function P() {
303
+ function F() {
292
304
  let e = b();
293
305
  return l({ mutationFn: (t) => e.importFromStorage(t.storageType, t.storagePath, t.database, t.storageConfig) });
294
306
  }
295
307
  //#endregion
296
308
  //#region src/utils/format.ts
297
- var F = new Intl.DateTimeFormat("pt-BR", {
309
+ var ee = new Intl.DateTimeFormat("pt-BR", {
298
310
  day: "2-digit",
299
311
  month: "2-digit",
300
312
  year: "numeric",
@@ -317,7 +329,7 @@ function L(e) {
317
329
  function R(e) {
318
330
  if (!e) return "—";
319
331
  let t = new Date(e);
320
- return Number.isNaN(t.getTime()) ? "—" : F.format(t);
332
+ return Number.isNaN(t.getTime()) ? "—" : ee.format(t);
321
333
  }
322
334
  var z = {
323
335
  PENDING: "Pendente",
@@ -353,7 +365,7 @@ function H({ status: e }) {
353
365
  }
354
366
  //#endregion
355
367
  //#region src/components/DatabaseBanner.tsx
356
- function U({ dbInfo: e, isLoading: t, error: n, label: r }) {
368
+ function U({ dbInfo: e, isLoading: t, error: n, label: r, compact: i = !1 }) {
357
369
  if (t) return /* @__PURE__ */ p("div", {
358
370
  className: "mb-3",
359
371
  children: /* @__PURE__ */ m("small", {
@@ -375,7 +387,13 @@ function U({ dbInfo: e, isLoading: t, error: n, label: r }) {
375
387
  G(n)
376
388
  ]
377
389
  });
378
- if (!e || !e.configured) return /* @__PURE__ */ m("div", {
390
+ if (!e || !e.configured) return i ? /* @__PURE__ */ m("div", {
391
+ className: "alert alert-danger mb-3 py-2 small",
392
+ children: [/* @__PURE__ */ p("i", {
393
+ className: "bi bi-x-octagon me-2",
394
+ "aria-hidden": !0
395
+ }), "Banco do servidor não configurado. Não é possível criar backups."]
396
+ }) : /* @__PURE__ */ m("div", {
379
397
  className: "alert alert-danger mb-3 py-2 small",
380
398
  children: [
381
399
  /* @__PURE__ */ p("i", {
@@ -388,8 +406,57 @@ function U({ dbInfo: e, isLoading: t, error: n, label: r }) {
388
406
  "). A criação e a importação usam esse banco."
389
407
  ]
390
408
  });
391
- let i = V[e.databaseType ?? ""] ?? e.databaseType ?? "postgresql";
392
- return /* @__PURE__ */ m("div", {
409
+ let a = V[e.databaseType ?? ""] ?? e.databaseType ?? "postgresql";
410
+ return i ? /* @__PURE__ */ m("div", {
411
+ className: "mb-3",
412
+ children: [
413
+ /* @__PURE__ */ m("div", {
414
+ className: "d-flex flex-wrap align-items-center gap-2 small text-body-secondary",
415
+ children: [/* @__PURE__ */ p("i", {
416
+ className: "bi bi-database-check text-success",
417
+ "aria-hidden": !0
418
+ }), /* @__PURE__ */ m("span", { children: [
419
+ r,
420
+ ": ",
421
+ /* @__PURE__ */ p("strong", { children: "banco do servidor disponível" })
422
+ ] })]
423
+ }),
424
+ e.exportExcludedTables.length > 0 && /* @__PURE__ */ m("div", {
425
+ className: "mt-1 small",
426
+ children: [
427
+ /* @__PURE__ */ p("i", {
428
+ className: "bi bi-shield-lock me-1",
429
+ "aria-hidden": !0
430
+ }),
431
+ /* @__PURE__ */ p("span", {
432
+ className: "text-body-secondary",
433
+ children: "Exportação sempre ignora: "
434
+ }),
435
+ e.exportExcludedTables.map((e) => /* @__PURE__ */ p("span", {
436
+ className: "badge text-bg-secondary me-1",
437
+ children: e
438
+ }, `ex-${e}`))
439
+ ]
440
+ }),
441
+ e.importExcludedTables.length > 0 && /* @__PURE__ */ m("div", {
442
+ className: "mt-1 small",
443
+ children: [
444
+ /* @__PURE__ */ p("i", {
445
+ className: "bi bi-shield-lock me-1",
446
+ "aria-hidden": !0
447
+ }),
448
+ /* @__PURE__ */ p("span", {
449
+ className: "text-body-secondary",
450
+ children: "Importação sempre ignora: "
451
+ }),
452
+ e.importExcludedTables.map((e) => /* @__PURE__ */ p("span", {
453
+ className: "badge text-bg-secondary me-1",
454
+ children: e
455
+ }, `im-${e}`))
456
+ ]
457
+ })
458
+ ]
459
+ }) : /* @__PURE__ */ m("div", {
393
460
  className: "mb-3",
394
461
  children: [
395
462
  /* @__PURE__ */ m("div", {
@@ -402,7 +469,7 @@ function U({ dbInfo: e, isLoading: t, error: n, label: r }) {
402
469
  /* @__PURE__ */ m("span", { children: [
403
470
  r,
404
471
  ": ",
405
- /* @__PURE__ */ p("strong", { children: i }),
472
+ /* @__PURE__ */ p("strong", { children: a }),
406
473
  " em ",
407
474
  /* @__PURE__ */ m("code", { children: [
408
475
  e.host,
@@ -458,7 +525,7 @@ function U({ dbInfo: e, isLoading: t, error: n, label: r }) {
458
525
  //#endregion
459
526
  //#region src/components/RestoreModal.tsx
460
527
  function W({ backup: e, onClose: t }) {
461
- let n = k(), r = w(), i = () => {
528
+ let n = A(), r = T(), i = () => {
462
529
  n.mutate({ id: e.id });
463
530
  }, a = n.isPending;
464
531
  return /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p("div", { className: "modal-backdrop show" }), /* @__PURE__ */ p("div", {
@@ -556,13 +623,13 @@ function G(e) {
556
623
  //#endregion
557
624
  //#region src/components/BackupsTab.tsx
558
625
  function K() {
559
- let [e, t] = o(0), [n, a] = o(null), [s, c] = o(null), [l, u] = o({}), { data: d, isLoading: f, isError: h, error: g, refetch: _, isFetching: v } = C(e, 10, !0), y = M(), b = A(), x = j();
626
+ let [e, t] = o(0), [n, a] = o(null), [s, c] = o(null), [l, u] = o({}), { data: d, isLoading: f, isError: h, error: g, refetch: _, isFetching: v } = w(e, 10, !0), y = N(), b = j(), x = M();
560
627
  r(() => {
561
628
  if (!y.data || !y.variables) return;
562
629
  let e = URL.createObjectURL(y.data), t = document.createElement("a");
563
630
  t.href = e, t.download = y.variables.filename, document.body.appendChild(t), t.click(), t.remove(), setTimeout(() => URL.revokeObjectURL(e), 1e4);
564
631
  }, [y.data, y.variables]);
565
- let S = i(() => d?.content ?? [], [d]), w = d?.totalPages ?? 0;
632
+ let S = i(() => d?.content ?? [], [d]), C = d?.totalPages ?? 0;
566
633
  return /* @__PURE__ */ m("div", { children: [
567
634
  /* @__PURE__ */ m("div", {
568
635
  className: "d-flex align-items-center justify-content-between flex-wrap gap-2 mb-3",
@@ -598,7 +665,7 @@ function K() {
598
665
  "aria-hidden": !0
599
666
  }),
600
667
  "Não foi possível carregar os backups: ",
601
- J(g)
668
+ q(g)
602
669
  ]
603
670
  }),
604
671
  y.isError && /* @__PURE__ */ m("div", {
@@ -609,7 +676,7 @@ function K() {
609
676
  "aria-hidden": !0
610
677
  }),
611
678
  "Falha no download: ",
612
- J(y.error)
679
+ q(y.error)
613
680
  ]
614
681
  }),
615
682
  b.isError && /* @__PURE__ */ m("div", {
@@ -620,7 +687,7 @@ function K() {
620
687
  "aria-hidden": !0
621
688
  }),
622
689
  "Falha ao excluir: ",
623
- J(b.error)
690
+ q(b.error)
624
691
  ]
625
692
  }),
626
693
  x.isError && /* @__PURE__ */ m("div", {
@@ -631,7 +698,7 @@ function K() {
631
698
  "aria-hidden": !0
632
699
  }),
633
700
  "Falha ao verificar: ",
634
- J(x.error)
701
+ q(x.error)
635
702
  ]
636
703
  }),
637
704
  Object.entries(l).map(([e, t]) => /* @__PURE__ */ m("div", {
@@ -815,7 +882,7 @@ function K() {
815
882
  "Página ",
816
883
  e + 1,
817
884
  " de ",
818
- Math.max(w, 1)
885
+ Math.max(C, 1)
819
886
  ]
820
887
  }), /* @__PURE__ */ m("div", {
821
888
  className: "btn-group",
@@ -831,7 +898,7 @@ function K() {
831
898
  }), /* @__PURE__ */ p("button", {
832
899
  type: "button",
833
900
  className: "btn btn-outline-secondary btn-sm",
834
- disabled: e + 1 >= w,
901
+ disabled: e + 1 >= C,
835
902
  onClick: () => t((e) => e + 1),
836
903
  children: /* @__PURE__ */ p("i", {
837
904
  className: "bi bi-chevron-right",
@@ -844,7 +911,7 @@ function K() {
844
911
  backup: n,
845
912
  onClose: () => a(null)
846
913
  }),
847
- s && /* @__PURE__ */ p(q, {
914
+ s && /* @__PURE__ */ p(te, {
848
915
  backup: s,
849
916
  busy: b.isPending,
850
917
  onCancel: () => c(null),
@@ -854,7 +921,7 @@ function K() {
854
921
  })
855
922
  ] });
856
923
  }
857
- function q(e) {
924
+ function te(e) {
858
925
  let { backup: t, busy: n, onCancel: r, onConfirm: i } = e;
859
926
  return /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p("div", { className: "modal-backdrop show" }), /* @__PURE__ */ p("div", {
860
927
  className: "modal show d-block",
@@ -920,16 +987,13 @@ function q(e) {
920
987
  })
921
988
  })] });
922
989
  }
923
- function J(e) {
990
+ function q(e) {
924
991
  return e instanceof Error ? e.message : String(e);
925
992
  }
926
993
  //#endregion
927
994
  //#region src/components/CreateBackupTab.tsx
928
- function Y() {
929
- let e = O(), t = w(), n = T(t.data?.configured), [r, a] = o(!1), [s, c] = o(() => ({
930
- type: "LOCAL",
931
- localPath: ""
932
- })), [l, u] = o(!0), [d, h] = o({
995
+ function J() {
996
+ let e = k(), t = T(), n = E(t.data?.configured), [r, a] = o(!0), [s, c] = o({
933
997
  format: "plain",
934
998
  includeData: !0,
935
999
  includeDropTable: !1,
@@ -937,52 +1001,53 @@ function Y() {
937
1001
  includeIndexes: !0,
938
1002
  includeConstraints: !0,
939
1003
  includeRelatedTables: !1
940
- }), [g, _] = o(() => /* @__PURE__ */ new Set()), [v, y] = o(null), [b, x] = o({}), [S, C] = o(""), D = E(v, t.data?.configured), k = i(() => new Set((t.data?.exportExcludedTables ?? []).map(te)), [t.data?.exportExcludedTables]), A = i(() => {
941
- let e = n.data ?? [], t = S.trim().toLowerCase();
1004
+ }), [l, u] = o(() => /* @__PURE__ */ new Set()), [d, f] = o(null), [h, g] = o({}), [_, v] = o(""), y = D(d, t.data?.configured), b = i(() => new Set((t.data?.exportExcludedTables ?? []).map(re)), [t.data?.exportExcludedTables]), x = i(() => {
1005
+ let e = n.data ?? [], t = _.trim().toLowerCase();
942
1006
  return t ? e.filter((e) => e.fullName.toLowerCase().includes(t)) : e;
943
- }, [n.data, S]), j = i(() => Object.values(b).reduce((e, t) => e + t.length, 0), [b]), M = (e) => {
944
- _((t) => {
1007
+ }, [n.data, _]), S = i(() => Object.values(h).reduce((e, t) => e + t.length, 0), [h]), C = (e) => {
1008
+ u((t) => {
945
1009
  let n = new Set(t);
946
1010
  return n.has(e) ? n.delete(e) : n.add(e), n;
947
1011
  });
948
- }, N = (e, t) => {
949
- x((n) => {
1012
+ }, w = (e, t) => {
1013
+ g((n) => {
950
1014
  let r = n[e] ?? [], i = r.includes(t) ? r.filter((e) => e !== t) : [...r, t];
951
1015
  return {
952
1016
  ...n,
953
1017
  [e]: i
954
1018
  };
955
1019
  });
956
- }, P = () => {
1020
+ }, O = () => {
957
1021
  let t;
958
- if (l) {
959
- t = { ...d }, g.size > 0 && (t.tables = [...g]);
1022
+ if (r) {
1023
+ t = { ...s }, l.size > 0 && (t.tables = [...l]);
960
1024
  let e = {};
961
- Object.entries(b).forEach(([t, n]) => {
1025
+ Object.entries(h).forEach(([t, n]) => {
962
1026
  n.length > 0 && (e[t] = n);
963
1027
  }), Object.keys(e).length > 0 && (t.excludeColumnsPerTable = e);
964
1028
  }
965
1029
  e.mutate({
966
- originStorage: r ? s : void 0,
1030
+ backupType: "DATABASE",
967
1031
  dumpOptions: t
968
1032
  });
969
- }, F = e.isPending, I = t.data?.configured && !F;
1033
+ }, A = e.isPending, j = t.data?.configured && !A;
970
1034
  return /* @__PURE__ */ m("div", { children: [
971
1035
  /* @__PURE__ */ m("div", {
972
1036
  className: "mb-3",
973
1037
  children: [/* @__PURE__ */ p("h5", {
974
1038
  className: "mb-1",
975
- children: "Criar novo backup"
1039
+ children: "Backup de banco de dados"
976
1040
  }), /* @__PURE__ */ p("p", {
977
1041
  className: "text-muted small mb-0",
978
- children: "O minivault usa o banco configurado no servidor (via variáveis de ambiente). Selecione as tabelas no grid e expanda um card para marcar colunas cujo conteúdo será nulificado na exportação."
1042
+ children: "Selecione as tabelas no grid e expanda um card para marcar colunas cujo conteúdo será nulificado na exportação. Apenas o dump do banco é enviado ao storage de destino."
979
1043
  })]
980
1044
  }),
981
1045
  /* @__PURE__ */ p(U, {
982
- label: "Banco de origem",
1046
+ label: "Banco de destino",
983
1047
  dbInfo: t.data,
984
1048
  isLoading: t.isLoading,
985
- error: t.error
1049
+ error: t.error,
1050
+ compact: !0
986
1051
  }),
987
1052
  /* @__PURE__ */ m("div", {
988
1053
  className: "card mb-3",
@@ -996,7 +1061,7 @@ function Y() {
996
1061
  "aria-hidden": !0
997
1062
  }),
998
1063
  "Tabelas do banco (",
999
- n.data?.filter((e) => !k.has(e.fullName)).length ?? 0,
1064
+ n.data?.filter((e) => !b.has(e.fullName)).length ?? 0,
1000
1065
  " disponíveis)"
1001
1066
  ]
1002
1067
  }), /* @__PURE__ */ m("div", {
@@ -1004,16 +1069,16 @@ function Y() {
1004
1069
  children: [/* @__PURE__ */ p("input", {
1005
1070
  className: "form-control form-control-sm",
1006
1071
  placeholder: "Filtrar tabelas...",
1007
- value: S,
1008
- onChange: (e) => C(e.target.value),
1072
+ value: _,
1073
+ onChange: (e) => v(e.target.value),
1009
1074
  style: { width: 200 }
1010
- }), g.size > 0 && /* @__PURE__ */ m("button", {
1075
+ }), l.size > 0 && /* @__PURE__ */ m("button", {
1011
1076
  type: "button",
1012
1077
  className: "btn btn-sm btn-outline-secondary",
1013
- onClick: () => _(/* @__PURE__ */ new Set()),
1078
+ onClick: () => u(/* @__PURE__ */ new Set()),
1014
1079
  children: [
1015
1080
  "Limpar seleção (",
1016
- g.size,
1081
+ l.size,
1017
1082
  ")"
1018
1083
  ]
1019
1084
  })]
@@ -1039,7 +1104,7 @@ function Y() {
1039
1104
  G(n.error)
1040
1105
  ]
1041
1106
  }),
1042
- A.length === 0 && !n.isLoading && /* @__PURE__ */ p("div", {
1107
+ x.length === 0 && !n.isLoading && /* @__PURE__ */ p("div", {
1043
1108
  className: "p-3 text-muted small",
1044
1109
  children: "Nenhuma tabela encontrada."
1045
1110
  }),
@@ -1052,16 +1117,16 @@ function Y() {
1052
1117
  maxHeight: 420,
1053
1118
  overflow: "auto"
1054
1119
  },
1055
- children: A.map((e) => /* @__PURE__ */ p(ee, {
1120
+ children: x.map((e) => /* @__PURE__ */ p(ne, {
1056
1121
  table: e,
1057
- disabled: k.has(e.fullName),
1058
- selected: g.has(e.fullName),
1059
- expanded: v === e.fullName,
1060
- excluded: b[e.fullName] ?? [],
1061
- onToggleTable: () => M(e.fullName),
1062
- onToggleExpand: () => y(v === e.fullName ? null : e.fullName),
1063
- onToggleColumn: (t) => N(e.fullName, t),
1064
- detail: v === e.fullName ? D : void 0
1122
+ disabled: b.has(e.fullName),
1123
+ selected: l.has(e.fullName),
1124
+ expanded: d === e.fullName,
1125
+ excluded: h[e.fullName] ?? [],
1126
+ onToggleTable: () => C(e.fullName),
1127
+ onToggleExpand: () => f(d === e.fullName ? null : e.fullName),
1128
+ onToggleColumn: (t) => w(e.fullName, t),
1129
+ detail: d === e.fullName ? y : void 0
1065
1130
  }, e.fullName))
1066
1131
  }),
1067
1132
  /* @__PURE__ */ m("div", {
@@ -1072,14 +1137,14 @@ function Y() {
1072
1137
  className: "bi bi-info-circle me-1",
1073
1138
  "aria-hidden": !0
1074
1139
  }), "Deixe tudo desmarcado para incluir todas as tabelas (exceto as bloqueadas por segurança)."]
1075
- }), j > 0 && d.format !== "plain" && /* @__PURE__ */ m("span", {
1140
+ }), S > 0 && s.format !== "plain" && /* @__PURE__ */ m("span", {
1076
1141
  className: "badge text-bg-warning ms-auto text-wrap text-start",
1077
1142
  children: [
1078
1143
  /* @__PURE__ */ p("i", {
1079
1144
  className: "bi bi-exclamation-triangle me-1",
1080
1145
  "aria-hidden": !0
1081
1146
  }),
1082
- j,
1147
+ S,
1083
1148
  " coluna(s) marcada(s) serão nulificadas apenas com formato Plain SQL (texto)"
1084
1149
  ]
1085
1150
  })]
@@ -1094,15 +1159,15 @@ function Y() {
1094
1159
  type: "checkbox",
1095
1160
  role: "switch",
1096
1161
  id: "minivault-with-dump-options",
1097
- checked: l,
1098
- onChange: (e) => u(e.target.checked)
1162
+ checked: r,
1163
+ onChange: (e) => a(e.target.checked)
1099
1164
  }), /* @__PURE__ */ p("label", {
1100
1165
  className: "form-check-label",
1101
1166
  htmlFor: "minivault-with-dump-options",
1102
1167
  children: "Configurar opcoes do dump (formato, dados, indices) — desmarcar envia sem opcoes (formato padrão custom/binary no servidor)"
1103
1168
  })]
1104
1169
  }),
1105
- l && /* @__PURE__ */ m("div", {
1170
+ r && /* @__PURE__ */ m("div", {
1106
1171
  className: "card mb-3",
1107
1172
  children: [/* @__PURE__ */ m("div", {
1108
1173
  className: "card-header d-flex align-items-center gap-2",
@@ -1123,8 +1188,8 @@ function Y() {
1123
1188
  }),
1124
1189
  /* @__PURE__ */ m("select", {
1125
1190
  className: "form-select",
1126
- value: d.format,
1127
- onChange: (e) => h((t) => ({
1191
+ value: s.format,
1192
+ onChange: (e) => c((t) => ({
1128
1193
  ...t,
1129
1194
  format: e.target.value
1130
1195
  })),
@@ -1190,8 +1255,8 @@ function Y() {
1190
1255
  className: "form-check-input",
1191
1256
  type: "checkbox",
1192
1257
  id: `dump-opt-${e}`,
1193
- checked: !!d[e],
1194
- onChange: (t) => h((n) => ({
1258
+ checked: !!s[e],
1259
+ onChange: (t) => c((n) => ({
1195
1260
  ...n,
1196
1261
  [e]: t.target.checked
1197
1262
  }))
@@ -1205,167 +1270,6 @@ function Y() {
1205
1270
  })]
1206
1271
  })]
1207
1272
  }),
1208
- /* @__PURE__ */ m("div", {
1209
- className: "form-check form-switch mb-3",
1210
- children: [/* @__PURE__ */ p("input", {
1211
- className: "form-check-input",
1212
- type: "checkbox",
1213
- role: "switch",
1214
- id: "minivault-with-origin",
1215
- checked: r,
1216
- onChange: (e) => a(e.target.checked)
1217
- }), /* @__PURE__ */ p("label", {
1218
- className: "form-check-label",
1219
- htmlFor: "minivault-with-origin",
1220
- children: "Incluir arquivos de origem no backup (armazenamento do sistema)"
1221
- })]
1222
- }),
1223
- r && /* @__PURE__ */ m("div", {
1224
- className: "card mb-3",
1225
- children: [/* @__PURE__ */ m("div", {
1226
- className: "card-header d-flex align-items-center gap-2",
1227
- children: [/* @__PURE__ */ p("i", {
1228
- className: "bi bi-folder2-open",
1229
- "aria-hidden": !0
1230
- }), "Origem dos arquivos"]
1231
- }), /* @__PURE__ */ p("div", {
1232
- className: "card-body",
1233
- children: /* @__PURE__ */ m("div", {
1234
- className: "row g-3",
1235
- children: [/* @__PURE__ */ m("div", {
1236
- className: "col-md-4",
1237
- children: [/* @__PURE__ */ p("label", {
1238
- className: "form-label",
1239
- children: "Tipo"
1240
- }), /* @__PURE__ */ m("select", {
1241
- className: "form-select",
1242
- value: s.type,
1243
- onChange: (e) => c((t) => ({
1244
- ...t,
1245
- type: e.target.value
1246
- })),
1247
- children: [/* @__PURE__ */ p("option", {
1248
- value: "LOCAL",
1249
- children: "Local (diretorio)"
1250
- }), /* @__PURE__ */ p("option", {
1251
- value: "S3",
1252
- children: "S3 (MinIO/S3)"
1253
- })]
1254
- })]
1255
- }), s.type === "LOCAL" ? /* @__PURE__ */ m("div", {
1256
- className: "col-md-8",
1257
- children: [/* @__PURE__ */ p("label", {
1258
- className: "form-label",
1259
- children: "Caminho local"
1260
- }), /* @__PURE__ */ p("input", {
1261
- className: "form-control",
1262
- value: s.localPath,
1263
- placeholder: "/dados/sistema",
1264
- onChange: (e) => c((t) => ({
1265
- ...t,
1266
- localPath: e.target.value
1267
- }))
1268
- })]
1269
- }) : /* @__PURE__ */ m(f, { children: [
1270
- /* @__PURE__ */ m("div", {
1271
- className: "col-md-6",
1272
- children: [/* @__PURE__ */ p("label", {
1273
- className: "form-label",
1274
- children: "Endpoint"
1275
- }), /* @__PURE__ */ p("input", {
1276
- className: "form-control",
1277
- value: s.endpoint,
1278
- placeholder: "http://192.168.0.10:9000",
1279
- onChange: (e) => c((t) => ({
1280
- ...t,
1281
- endpoint: e.target.value
1282
- }))
1283
- })]
1284
- }),
1285
- /* @__PURE__ */ m("div", {
1286
- className: "col-md-6",
1287
- children: [/* @__PURE__ */ p("label", {
1288
- className: "form-label",
1289
- children: "Bucket"
1290
- }), /* @__PURE__ */ p("input", {
1291
- className: "form-control",
1292
- value: s.bucketName,
1293
- placeholder: "storage",
1294
- onChange: (e) => c((t) => ({
1295
- ...t,
1296
- bucketName: e.target.value
1297
- }))
1298
- })]
1299
- }),
1300
- /* @__PURE__ */ m("div", {
1301
- className: "col-md-6",
1302
- children: [/* @__PURE__ */ p("label", {
1303
- className: "form-label",
1304
- children: "Access key"
1305
- }), /* @__PURE__ */ p("input", {
1306
- className: "form-control",
1307
- value: s.accessKey,
1308
- onChange: (e) => c((t) => ({
1309
- ...t,
1310
- accessKey: e.target.value
1311
- }))
1312
- })]
1313
- }),
1314
- /* @__PURE__ */ m("div", {
1315
- className: "col-md-6",
1316
- children: [/* @__PURE__ */ p("label", {
1317
- className: "form-label",
1318
- children: "Secret key"
1319
- }), /* @__PURE__ */ p("input", {
1320
- className: "form-control",
1321
- type: "password",
1322
- value: s.secretKey,
1323
- onChange: (e) => c((t) => ({
1324
- ...t,
1325
- secretKey: e.target.value
1326
- }))
1327
- })]
1328
- }),
1329
- /* @__PURE__ */ m("div", {
1330
- className: "col-md-6",
1331
- children: [/* @__PURE__ */ p("label", {
1332
- className: "form-label",
1333
- children: "Regiao"
1334
- }), /* @__PURE__ */ p("input", {
1335
- className: "form-control",
1336
- value: s.region,
1337
- placeholder: "us-east-1",
1338
- onChange: (e) => c((t) => ({
1339
- ...t,
1340
- region: e.target.value
1341
- }))
1342
- })]
1343
- }),
1344
- /* @__PURE__ */ p("div", {
1345
- className: "col-md-6 d-flex align-items-end pb-1",
1346
- children: /* @__PURE__ */ m("div", {
1347
- className: "form-check form-switch",
1348
- children: [/* @__PURE__ */ p("input", {
1349
- className: "form-check-input",
1350
- type: "checkbox",
1351
- role: "switch",
1352
- id: "minivault-origin-pathstyle",
1353
- checked: !!s.pathStyleEnabled,
1354
- onChange: (e) => c((t) => ({
1355
- ...t,
1356
- pathStyleEnabled: e.target.checked
1357
- }))
1358
- }), /* @__PURE__ */ p("label", {
1359
- className: "form-check-label",
1360
- htmlFor: "minivault-origin-pathstyle",
1361
- children: "Path-style (MinIO)"
1362
- })]
1363
- })
1364
- })
1365
- ] })]
1366
- })
1367
- })]
1368
- }),
1369
1273
  e.isError && /* @__PURE__ */ m("div", {
1370
1274
  className: "alert alert-danger",
1371
1275
  children: [
@@ -1396,10 +1300,10 @@ function Y() {
1396
1300
  children: /* @__PURE__ */ m("button", {
1397
1301
  type: "button",
1398
1302
  className: "btn btn-primary",
1399
- onClick: P,
1400
- disabled: !I,
1303
+ onClick: O,
1304
+ disabled: !j,
1401
1305
  children: [
1402
- F && /* @__PURE__ */ p("span", {
1306
+ A && /* @__PURE__ */ p("span", {
1403
1307
  className: "spinner-border spinner-border-sm me-2",
1404
1308
  "aria-hidden": !0
1405
1309
  }),
@@ -1407,13 +1311,13 @@ function Y() {
1407
1311
  className: "bi bi-plus-lg me-1",
1408
1312
  "aria-hidden": !0
1409
1313
  }),
1410
- "Iniciar backup"
1314
+ "Iniciar backup de banco"
1411
1315
  ]
1412
1316
  })
1413
1317
  })
1414
1318
  ] });
1415
1319
  }
1416
- function ee({ table: e, disabled: t, selected: n, expanded: r, excluded: i, detail: a, onToggleTable: o, onToggleExpand: s, onToggleColumn: c }) {
1320
+ function ne({ table: e, disabled: t, selected: n, expanded: r, excluded: i, detail: a, onToggleTable: o, onToggleExpand: s, onToggleColumn: c }) {
1417
1321
  return /* @__PURE__ */ p("div", {
1418
1322
  className: `card h-100 ${n ? "border-primary" : ""}`,
1419
1323
  style: { minWidth: 0 },
@@ -1528,11 +1432,133 @@ function ee({ table: e, disabled: t, selected: n, expanded: r, excluded: i, deta
1528
1432
  })
1529
1433
  });
1530
1434
  }
1531
- function te(e) {
1435
+ function re(e) {
1532
1436
  let t = e.trim();
1533
1437
  return t.includes(".") ? t : `public.${t}`;
1534
1438
  }
1535
1439
  //#endregion
1440
+ //#region src/components/DiagnosticsTab.tsx
1441
+ function Y() {
1442
+ let { data: e, isLoading: t, isError: n, error: r, refetch: a, isFetching: o } = C(), s = i(() => e ? {
1443
+ total: e.length,
1444
+ okCount: e.filter((e) => e.ok).length,
1445
+ notConfigured: e.filter((e) => !e.configured).length
1446
+ } : null, [e]);
1447
+ return /* @__PURE__ */ m("div", { children: [
1448
+ /* @__PURE__ */ m("div", {
1449
+ className: "d-flex align-items-center justify-content-between flex-wrap gap-2 mb-3",
1450
+ children: [/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("h5", {
1451
+ className: "mb-0",
1452
+ children: "Diagnóstico do servidor"
1453
+ }), /* @__PURE__ */ p("span", {
1454
+ className: "text-muted small",
1455
+ children: "Verifica conexões de banco, storages e servidor de e-mail configurados."
1456
+ })] }), /* @__PURE__ */ m("button", {
1457
+ type: "button",
1458
+ className: "btn btn-outline-secondary btn-sm",
1459
+ onClick: () => a(),
1460
+ disabled: o,
1461
+ children: [
1462
+ o && /* @__PURE__ */ p("span", {
1463
+ className: "spinner-border spinner-border-sm me-2",
1464
+ "aria-hidden": !0
1465
+ }),
1466
+ /* @__PURE__ */ p("i", {
1467
+ className: "bi bi-arrow-repeat me-1",
1468
+ "aria-hidden": !0
1469
+ }),
1470
+ "Executar testes novamente"
1471
+ ]
1472
+ })]
1473
+ }),
1474
+ n && /* @__PURE__ */ m("div", {
1475
+ className: "alert alert-danger",
1476
+ children: [
1477
+ /* @__PURE__ */ p("i", {
1478
+ className: "bi bi-exclamation-triangle me-2",
1479
+ "aria-hidden": !0
1480
+ }),
1481
+ "Não foi possível executar as checagens: ",
1482
+ G(r)
1483
+ ]
1484
+ }),
1485
+ s && /* @__PURE__ */ m("div", {
1486
+ className: "d-flex flex-wrap gap-2 mb-3",
1487
+ children: [
1488
+ /* @__PURE__ */ m("span", {
1489
+ className: "badge text-bg-success",
1490
+ children: [
1491
+ /* @__PURE__ */ p("i", {
1492
+ className: "bi bi-check-circle me-1",
1493
+ "aria-hidden": !0
1494
+ }),
1495
+ s.okCount,
1496
+ " OK"
1497
+ ]
1498
+ }),
1499
+ /* @__PURE__ */ m("span", {
1500
+ className: "badge text-bg-warning",
1501
+ children: [s.total - s.okCount - s.notConfigured, " com falha"]
1502
+ }),
1503
+ /* @__PURE__ */ m("span", {
1504
+ className: "badge text-bg-secondary",
1505
+ children: [s.notConfigured, " não configurado(s)"]
1506
+ })
1507
+ ]
1508
+ }),
1509
+ t && !e ? /* @__PURE__ */ m("div", {
1510
+ className: "text-center py-5 text-muted",
1511
+ children: [/* @__PURE__ */ p("div", {
1512
+ className: "spinner-border mb-2",
1513
+ "aria-hidden": !0
1514
+ }), /* @__PURE__ */ p("div", { children: "Executando checagens…" })]
1515
+ }) : /* @__PURE__ */ p("div", {
1516
+ className: "card",
1517
+ children: /* @__PURE__ */ m("ul", {
1518
+ className: "list-group list-group-flush",
1519
+ children: [(e ?? []).map((e) => /* @__PURE__ */ p(ie, { check: e }, e.name)), e && e.length === 0 && /* @__PURE__ */ p("li", {
1520
+ className: "list-group-item text-center text-muted py-4",
1521
+ children: "Nenhuma checagem retornada."
1522
+ })]
1523
+ })
1524
+ })
1525
+ ] });
1526
+ }
1527
+ function ie({ check: e }) {
1528
+ let t = e.configured ? e.ok ? "bi-check-circle-fill text-success" : "bi-x-octagon-fill text-danger" : "bi-dash-circle text-secondary", n = e.configured ? e.ok ? "text-bg-success" : "text-bg-danger" : "text-bg-secondary", r = e.configured ? e.ok ? "OK" : "Falha" : "Não configurado";
1529
+ return /* @__PURE__ */ m("li", {
1530
+ className: "list-group-item d-flex align-items-start gap-3",
1531
+ children: [/* @__PURE__ */ p("i", {
1532
+ className: `bi ${t} fs-4 mt-1`,
1533
+ "aria-hidden": !0
1534
+ }), /* @__PURE__ */ m("div", {
1535
+ className: "flex-grow-1",
1536
+ style: { minWidth: 0 },
1537
+ children: [/* @__PURE__ */ m("div", {
1538
+ className: "d-flex align-items-center flex-wrap gap-2",
1539
+ children: [
1540
+ /* @__PURE__ */ p("strong", { children: e.label }),
1541
+ /* @__PURE__ */ p("span", {
1542
+ className: "badge text-bg-light border",
1543
+ children: e.type
1544
+ }),
1545
+ /* @__PURE__ */ p("span", {
1546
+ className: `badge ${n}`,
1547
+ children: r
1548
+ }),
1549
+ /* @__PURE__ */ m("small", {
1550
+ className: "text-muted",
1551
+ children: [e.latencyMs, " ms"]
1552
+ })
1553
+ ]
1554
+ }), /* @__PURE__ */ p("div", {
1555
+ className: "small text-muted mt-1",
1556
+ children: e.message
1557
+ })]
1558
+ })]
1559
+ });
1560
+ }
1561
+ //#endregion
1536
1562
  //#region src/components/StorageExplorerTab.tsx
1537
1563
  function X({ storageType: e = "LOCAL", storageConfig: n }) {
1538
1564
  let i = b(), s = d(), [c, h] = o(""), [g, _] = o([]), [v, y] = o(/* @__PURE__ */ new Set()), [x, S] = o(null), C = n?.type ?? e, { data: w, isLoading: T } = u({
@@ -1807,7 +1833,7 @@ function X({ storageType: e = "LOCAL", storageConfig: n }) {
1807
1833
  //#endregion
1808
1834
  //#region src/components/ImportDumpTab.tsx
1809
1835
  function Z() {
1810
- let e = N(), t = P(), n = w(), r = a(null), [i, s] = o("upload"), [c, l] = o(null), [u, d] = o(""), [f, h] = o(!1), g = () => {
1836
+ let e = P(), t = F(), n = T(), r = a(null), [i, s] = o("upload"), [c, l] = o(null), [u, d] = o(""), [f, h] = o(!1), g = () => {
1811
1837
  i === "upload" && c ? e.mutate({ file: c }) : i === "storage" && u && t.mutate({
1812
1838
  storageType: "LOCAL",
1813
1839
  storagePath: u
@@ -2009,14 +2035,142 @@ function Z() {
2009
2035
  ] });
2010
2036
  }
2011
2037
  //#endregion
2012
- //#region src/hooks/useAutoTheme.ts
2038
+ //#region src/components/StorageBackupTab.tsx
2013
2039
  function Q() {
2040
+ let e = k(), t = C(), n = t.data?.find((e) => e.name === "ORIGIN_STORAGE"), r = t.data?.find((e) => e.name === "OUTPUT_STORAGE"), i = e.isPending;
2041
+ return /* @__PURE__ */ m("div", { children: [
2042
+ /* @__PURE__ */ m("div", {
2043
+ className: "mb-3",
2044
+ children: [/* @__PURE__ */ p("h5", {
2045
+ className: "mb-1",
2046
+ children: "Backup de storage"
2047
+ }), /* @__PURE__ */ m("p", {
2048
+ className: "text-muted small mb-0",
2049
+ children: [
2050
+ "Faz backup dos arquivos do storage de origem para o storage de destino. Origem e destino são configurados no servidor via variáveis de ambiente (",
2051
+ /* @__PURE__ */ p("code", { children: "ORIGIN_STORAGE_*" }),
2052
+ " e ",
2053
+ /* @__PURE__ */ p("code", { children: "OUTPUT_STORAGE_*" }),
2054
+ ")."
2055
+ ]
2056
+ })]
2057
+ }),
2058
+ /* @__PURE__ */ m("div", {
2059
+ className: "card mb-3",
2060
+ children: [/* @__PURE__ */ m("div", {
2061
+ className: "card-header d-flex align-items-center gap-2",
2062
+ children: [/* @__PURE__ */ p("i", {
2063
+ className: "bi bi-heart-pulse",
2064
+ "aria-hidden": !0
2065
+ }), "Status das conexões"]
2066
+ }), /* @__PURE__ */ m("div", {
2067
+ className: "card-body",
2068
+ children: [
2069
+ t.isLoading && /* @__PURE__ */ m("div", {
2070
+ className: "text-muted small",
2071
+ children: [/* @__PURE__ */ p("span", {
2072
+ className: "spinner-border spinner-border-sm me-2",
2073
+ "aria-hidden": !0
2074
+ }), "Verificando conexões..."]
2075
+ }),
2076
+ t.isError && /* @__PURE__ */ p("div", {
2077
+ className: "text-muted small",
2078
+ children: "Não foi possível verificar o status. O backup pode ser executado mesmo assim."
2079
+ }),
2080
+ t.data && /* @__PURE__ */ m("div", {
2081
+ className: "d-flex flex-column gap-2",
2082
+ children: [/* @__PURE__ */ p($, {
2083
+ label: n?.label ?? "Storage de origem",
2084
+ configured: n?.configured,
2085
+ ok: n?.ok,
2086
+ message: n?.message
2087
+ }), /* @__PURE__ */ p($, {
2088
+ label: r?.label ?? "Storage de destino",
2089
+ configured: r?.configured,
2090
+ ok: r?.ok,
2091
+ message: r?.message
2092
+ })]
2093
+ })
2094
+ ]
2095
+ })]
2096
+ }),
2097
+ e.isError && /* @__PURE__ */ m("div", {
2098
+ className: "alert alert-danger",
2099
+ children: [
2100
+ /* @__PURE__ */ p("i", {
2101
+ className: "bi bi-x-circle me-2",
2102
+ "aria-hidden": !0
2103
+ }),
2104
+ "Falha ao criar backup de storage: ",
2105
+ G(e.error)
2106
+ ]
2107
+ }),
2108
+ e.isSuccess && /* @__PURE__ */ m("div", {
2109
+ className: "alert alert-success",
2110
+ children: [
2111
+ /* @__PURE__ */ p("i", {
2112
+ className: "bi bi-check-circle me-2",
2113
+ "aria-hidden": !0
2114
+ }),
2115
+ "Backup de storage #",
2116
+ e.data.id,
2117
+ " criado (",
2118
+ e.data.filename,
2119
+ ")."
2120
+ ]
2121
+ }),
2122
+ /* @__PURE__ */ p("div", {
2123
+ className: "d-flex justify-content-end",
2124
+ children: /* @__PURE__ */ m("button", {
2125
+ type: "button",
2126
+ className: "btn btn-primary",
2127
+ onClick: () => {
2128
+ e.mutate({ backupType: "STORAGE" });
2129
+ },
2130
+ disabled: i || t.data != null && n?.configured === !1,
2131
+ children: [
2132
+ i && /* @__PURE__ */ p("span", {
2133
+ className: "spinner-border spinner-border-sm me-2",
2134
+ "aria-hidden": !0
2135
+ }),
2136
+ /* @__PURE__ */ p("i", {
2137
+ className: "bi bi-plus-lg me-1",
2138
+ "aria-hidden": !0
2139
+ }),
2140
+ "Iniciar backup de storage"
2141
+ ]
2142
+ })
2143
+ })
2144
+ ] });
2145
+ }
2146
+ function $({ label: e, configured: t, ok: n, message: r }) {
2147
+ return t === !1 ? /* @__PURE__ */ m("div", {
2148
+ className: "d-flex align-items-center gap-2 small text-muted",
2149
+ children: [/* @__PURE__ */ p("i", {
2150
+ className: "bi bi-dash-circle text-secondary",
2151
+ "aria-hidden": !0
2152
+ }), /* @__PURE__ */ m("span", { children: [/* @__PURE__ */ m("strong", { children: [e, ":"] }), " não configurado no servidor"] })]
2153
+ }) : /* @__PURE__ */ m("div", {
2154
+ className: `d-flex align-items-center gap-2 small ${n ? "text-success" : "text-danger"}`,
2155
+ children: [/* @__PURE__ */ p("i", {
2156
+ className: `bi ${n ? "bi-check-circle-fill" : "bi-x-circle-fill"}`,
2157
+ "aria-hidden": !0
2158
+ }), /* @__PURE__ */ m("span", { children: [
2159
+ /* @__PURE__ */ m("strong", { children: [e, ":"] }),
2160
+ " ",
2161
+ r ?? (n ? "ok" : "falha")
2162
+ ] })]
2163
+ });
2164
+ }
2165
+ //#endregion
2166
+ //#region src/hooks/useAutoTheme.ts
2167
+ function ae() {
2014
2168
  return typeof document < "u" && document.documentElement.classList.contains("dark");
2015
2169
  }
2016
- function ne(e) {
2017
- let [t, n] = o(Q), [i, a] = o(() => typeof window < "u" && window.matchMedia?.("(prefers-color-scheme: dark)")?.matches === !0);
2170
+ function oe(e) {
2171
+ let [t, n] = o(ae), [i, a] = o(() => typeof window < "u" && window.matchMedia?.("(prefers-color-scheme: dark)")?.matches === !0);
2018
2172
  return r(() => {
2019
- let e = document.documentElement, t = new MutationObserver(() => n(Q()));
2173
+ let e = document.documentElement, t = new MutationObserver(() => n(ae()));
2020
2174
  return t.observe(e, {
2021
2175
  attributes: !0,
2022
2176
  attributeFilter: ["class"]
@@ -2029,8 +2183,8 @@ function ne(e) {
2029
2183
  }
2030
2184
  //#endregion
2031
2185
  //#region src/components/MinivaultModule.tsx
2032
- function re(e) {
2033
- let { companyAcronym: t = "Minivault", theme: n, refetchIntervalMs: r = 15e3, storageType: i = "LOCAL", ...a } = e, l = ne(n), [u] = o(() => new s({ defaultOptions: { queries: {
2186
+ function se(e) {
2187
+ let { companyAcronym: t = "Minivault", theme: n, refetchIntervalMs: r = 15e3, storageType: i = "LOCAL", ...a } = e, l = oe(n), [u] = o(() => new s({ defaultOptions: { queries: {
2034
2188
  refetchInterval: r,
2035
2189
  retry: 1
2036
2190
  } } }));
@@ -2041,15 +2195,15 @@ function re(e) {
2041
2195
  children: /* @__PURE__ */ m("div", {
2042
2196
  className: "minivault-module h-full w-full overflow-auto",
2043
2197
  "data-minivault-theme": l,
2044
- children: [/* @__PURE__ */ p(ie, {
2198
+ children: [/* @__PURE__ */ p(ce, {
2045
2199
  companyAcronym: t,
2046
2200
  theme: l
2047
- }), /* @__PURE__ */ p(ae, { storageType: i })]
2201
+ }), /* @__PURE__ */ p(le, { storageType: i })]
2048
2202
  })
2049
2203
  })
2050
2204
  });
2051
2205
  }
2052
- function ie({ companyAcronym: e, theme: t }) {
2206
+ function ce({ companyAcronym: e, theme: t }) {
2053
2207
  return /* @__PURE__ */ m("div", {
2054
2208
  className: "d-flex align-items-center justify-content-between flex-wrap gap-2 px-3 py-2 border-bottom",
2055
2209
  style: {
@@ -2067,7 +2221,7 @@ function ie({ companyAcronym: e, theme: t }) {
2067
2221
  })
2068
2222
  }), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ m("strong", { children: [e, " · Backups"] }), /* @__PURE__ */ p("div", {
2069
2223
  className: "small text-muted",
2070
- children: "Gerenciamento de backups de banco de dados"
2224
+ children: "Gerenciamento de backups de banco de dados e storage"
2071
2225
  })] })]
2072
2226
  }), /* @__PURE__ */ p("div", {
2073
2227
  className: "d-flex align-items-center gap-2",
@@ -2078,7 +2232,7 @@ function ie({ companyAcronym: e, theme: t }) {
2078
2232
  })]
2079
2233
  });
2080
2234
  }
2081
- function ae({ storageType: e }) {
2235
+ function le({ storageType: e }) {
2082
2236
  let [t, n] = o("backups");
2083
2237
  return /* @__PURE__ */ m("div", {
2084
2238
  className: "p-3",
@@ -2107,7 +2261,19 @@ function ae({ storageType: e }) {
2107
2261
  children: [/* @__PURE__ */ p("i", {
2108
2262
  className: "bi bi-plus-circle me-1",
2109
2263
  "aria-hidden": !0
2110
- }), "Novo backup"]
2264
+ }), "Backup de BD"]
2265
+ })
2266
+ }),
2267
+ /* @__PURE__ */ p("li", {
2268
+ className: "nav-item",
2269
+ children: /* @__PURE__ */ m("button", {
2270
+ type: "button",
2271
+ className: `nav-link ${t === "createStorage" ? "active" : ""}`,
2272
+ onClick: () => n("createStorage"),
2273
+ children: [/* @__PURE__ */ p("i", {
2274
+ className: "bi bi-plus-circle me-1",
2275
+ "aria-hidden": !0
2276
+ }), "Backup de storage"]
2111
2277
  })
2112
2278
  }),
2113
2279
  /* @__PURE__ */ p("li", {
@@ -2133,24 +2299,38 @@ function ae({ storageType: e }) {
2133
2299
  "aria-hidden": !0
2134
2300
  }), "Storage"]
2135
2301
  })
2302
+ }),
2303
+ /* @__PURE__ */ p("li", {
2304
+ className: "nav-item",
2305
+ children: /* @__PURE__ */ m("button", {
2306
+ type: "button",
2307
+ className: `nav-link ${t === "diagnostics" ? "active" : ""}`,
2308
+ onClick: () => n("diagnostics"),
2309
+ children: [/* @__PURE__ */ p("i", {
2310
+ className: "bi bi-heart-pulse me-1",
2311
+ "aria-hidden": !0
2312
+ }), "Diagnóstico"]
2313
+ })
2136
2314
  })
2137
2315
  ]
2138
2316
  }),
2139
2317
  t === "backups" && /* @__PURE__ */ p(K, {}),
2140
- t === "create" && /* @__PURE__ */ p(Y, {}),
2318
+ t === "create" && /* @__PURE__ */ p(J, {}),
2319
+ t === "createStorage" && /* @__PURE__ */ p(Q, {}),
2141
2320
  t === "import" && /* @__PURE__ */ p(Z, {}),
2142
- t === "storage" && /* @__PURE__ */ p(X, { storageType: e })
2321
+ t === "storage" && /* @__PURE__ */ p(X, { storageType: e }),
2322
+ t === "diagnostics" && /* @__PURE__ */ p(Y, {})
2143
2323
  ]
2144
2324
  });
2145
2325
  }
2146
2326
  //#endregion
2147
2327
  //#region src/components/CredentialsFields.tsx
2148
- var oe = [
2328
+ var ue = [
2149
2329
  "postgresql",
2150
2330
  "mysql",
2151
2331
  "sqlserver"
2152
2332
  ];
2153
- function se() {
2333
+ function de() {
2154
2334
  return {
2155
2335
  host: "localhost",
2156
2336
  port: 5432,
@@ -2160,19 +2340,19 @@ function se() {
2160
2340
  databaseType: "postgresql"
2161
2341
  };
2162
2342
  }
2163
- function $(e) {
2343
+ function fe(e) {
2164
2344
  return e === "postgresql" || e === "postgres" ? 5432 : e === "mysql" ? 3306 : 1433;
2165
2345
  }
2166
- function ce({ value: e, onChange: t, onValidatedChange: n }) {
2346
+ function pe({ value: e, onChange: t, onValidatedChange: n }) {
2167
2347
  let r = {
2168
- ...se(),
2348
+ ...de(),
2169
2349
  ...e
2170
2350
  }, i = (e) => {
2171
2351
  let n = {
2172
2352
  ...r,
2173
2353
  databaseType: e
2174
2354
  };
2175
- (r.port === $(r.databaseType) || !r.port) && (n.port = $(e)), t(n);
2355
+ (r.port === fe(r.databaseType) || !r.port) && (n.port = fe(e)), t(n);
2176
2356
  }, a = (e) => {
2177
2357
  let i = {
2178
2358
  ...r,
@@ -2194,7 +2374,7 @@ function ce({ value: e, onChange: t, onValidatedChange: n }) {
2194
2374
  className: "form-select",
2195
2375
  value: r.databaseType,
2196
2376
  onChange: (e) => i(e.target.value),
2197
- children: oe.map((e) => /* @__PURE__ */ p("option", {
2377
+ children: ue.map((e) => /* @__PURE__ */ p("option", {
2198
2378
  value: e,
2199
2379
  children: V[e] ?? e
2200
2380
  }, e))
@@ -2268,4 +2448,4 @@ function ce({ value: e, onChange: t, onValidatedChange: n }) {
2268
2448
  });
2269
2449
  }
2270
2450
  //#endregion
2271
- export { K as BackupsTab, Y as CreateBackupTab, ce as CredentialsFields, V as DATABASE_TYPE_LABELS, U as DatabaseBanner, Z as ImportDumpTab, g as MinivaultApi, h as MinivaultApiError, y as MinivaultApiProvider, re as MinivaultModule, W as RestoreModal, B as STATUS_BADGE, z as STATUS_LABELS, H as StatusBadge, X as StorageExplorerTab, R as formatDate, L as formatFileSize, C as useBackups, O as useCreateBackup, w as useDbInfo, D as useDbRelationships, E as useDbTableDetail, T as useDbTables, A as useDeleteBackup, M as useDownloadBackup, N as useImportDump, P as useImportFromStorage, b as useMinivaultApi, k as useRestoreBackup };
2451
+ export { K as BackupsTab, J as CreateBackupTab, pe as CredentialsFields, V as DATABASE_TYPE_LABELS, U as DatabaseBanner, Y as DiagnosticsTab, Z as ImportDumpTab, g as MinivaultApi, h as MinivaultApiError, y as MinivaultApiProvider, se as MinivaultModule, W as RestoreModal, B as STATUS_BADGE, z as STATUS_LABELS, H as StatusBadge, Q as StorageBackupTab, X as StorageExplorerTab, R as formatDate, L as formatFileSize, w as useBackups, k as useCreateBackup, T as useDbInfo, O as useDbRelationships, D as useDbTableDetail, E as useDbTables, j as useDeleteBackup, C as useDiagnostics, N as useDownloadBackup, P as useImportDump, F as useImportFromStorage, b as useMinivaultApi, A as useRestoreBackup };