@v1ct0rbr/minivault-web 0.7.0 → 0.8.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.
|
@@ -33,7 +33,7 @@ export declare class MinivaultApi {
|
|
|
33
33
|
private request;
|
|
34
34
|
listBackups(page?: number, size?: number): Promise<PageResponse<Backup>>;
|
|
35
35
|
getBackup(id: number): Promise<Backup>;
|
|
36
|
-
createBackup(database?: DatabaseCredentials, originStorage?: OriginStorageConfig, dumpOptions?: DumpOptions, backupType?: BackupType): Promise<Backup>;
|
|
36
|
+
createBackup(database?: DatabaseCredentials, originStorage?: OriginStorageConfig, dumpOptions?: DumpOptions, backupType?: BackupType, scheduled?: boolean): Promise<Backup>;
|
|
37
37
|
restoreBackup(id: number, database?: DatabaseCredentials, originStorage?: OriginStorageConfig): Promise<void>;
|
|
38
38
|
deleteBackup(id: number): Promise<void>;
|
|
39
39
|
verifyBackup(id: number): Promise<VerifyResult>;
|
|
@@ -15,6 +15,7 @@ export declare function useCreateBackup(): import('@tanstack/react-query').UseMu
|
|
|
15
15
|
originStorage?: OriginStorageConfig;
|
|
16
16
|
dumpOptions?: DumpOptions;
|
|
17
17
|
backupType?: BackupType;
|
|
18
|
+
scheduled?: boolean;
|
|
18
19
|
}, unknown>;
|
|
19
20
|
export declare function useRestoreBackup(): import('@tanstack/react-query').UseMutationResult<void, Error, {
|
|
20
21
|
id: number;
|
package/dist/minivault-web.js
CHANGED
|
@@ -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, r) {
|
|
60
|
-
let
|
|
61
|
-
return r && (
|
|
59
|
+
createBackup(e, t, n, r, i) {
|
|
60
|
+
let a = {};
|
|
61
|
+
return r && (a.backupType = r), i && (a.scheduled = !0), e && (a.database = e), t && (a.originStorage = t), n && (a.dumpOptions = n), this.request("/api/backups", {
|
|
62
62
|
method: "POST",
|
|
63
|
-
body: JSON.stringify(
|
|
63
|
+
body: JSON.stringify(a)
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
66
|
restoreBackup(e, t, n) {
|
|
@@ -298,7 +298,7 @@ function A(e = !0) {
|
|
|
298
298
|
function j() {
|
|
299
299
|
let e = b(), t = d();
|
|
300
300
|
return l({
|
|
301
|
-
mutationFn: (t) => e.createBackup(t.database, t.originStorage, t.dumpOptions, t.backupType),
|
|
301
|
+
mutationFn: (t) => e.createBackup(t.database, t.originStorage, t.dumpOptions, t.backupType, t.scheduled),
|
|
302
302
|
onSuccess: () => t.invalidateQueries({ queryKey: S.all })
|
|
303
303
|
});
|
|
304
304
|
}
|
|
@@ -828,10 +828,21 @@ function Z() {
|
|
|
828
828
|
className: "text-truncate",
|
|
829
829
|
style: { maxWidth: 260 },
|
|
830
830
|
title: e.filename,
|
|
831
|
-
children: [
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
831
|
+
children: [
|
|
832
|
+
/* @__PURE__ */ p("i", {
|
|
833
|
+
className: "bi bi-archive me-1 text-primary",
|
|
834
|
+
"aria-hidden": !0
|
|
835
|
+
}),
|
|
836
|
+
e.filename,
|
|
837
|
+
e.scheduled && /* @__PURE__ */ m("span", {
|
|
838
|
+
className: "badge text-bg-info ms-2",
|
|
839
|
+
title: "O scheduler re-executa este backup automaticamente no horário configurado",
|
|
840
|
+
children: [/* @__PURE__ */ p("i", {
|
|
841
|
+
className: "bi bi-clock-history me-1",
|
|
842
|
+
"aria-hidden": !0
|
|
843
|
+
}), "agendado"]
|
|
844
|
+
})
|
|
845
|
+
]
|
|
835
846
|
}),
|
|
836
847
|
/* @__PURE__ */ p("td", { children: e.backupType ? /* @__PURE__ */ p("span", {
|
|
837
848
|
className: `badge ${K[e.backupType] ?? "text-bg-secondary"}`,
|
|
@@ -1055,15 +1066,15 @@ function te() {
|
|
|
1055
1066
|
includeIndexes: !0,
|
|
1056
1067
|
includeConstraints: !0,
|
|
1057
1068
|
includeRelatedTables: !1
|
|
1058
|
-
}), [l, u] = o(() => /* @__PURE__ */ new Set()), [d, f] = o(null), [h, g] = o({}), [_, v] = o(""), y = k(d, t.data?.configured),
|
|
1069
|
+
}), [l, u] = o(() => /* @__PURE__ */ new Set()), [d, f] = o(null), [h, g] = o({}), [_, v] = o(""), [y, b] = o(!1), x = k(d, t.data?.configured), S = i(() => new Set((t.data?.exportExcludedTables ?? []).map(re)), [t.data?.exportExcludedTables]), C = i(() => {
|
|
1059
1070
|
let e = n.data ?? [], t = _.trim().toLowerCase();
|
|
1060
1071
|
return t ? e.filter((e) => e.fullName.toLowerCase().includes(t)) : e;
|
|
1061
|
-
}, [n.data, _]),
|
|
1072
|
+
}, [n.data, _]), w = i(() => Object.values(h).reduce((e, t) => e + t.length, 0), [h]), T = (e) => {
|
|
1062
1073
|
u((t) => {
|
|
1063
1074
|
let n = new Set(t);
|
|
1064
1075
|
return n.has(e) ? n.delete(e) : n.add(e), n;
|
|
1065
1076
|
});
|
|
1066
|
-
},
|
|
1077
|
+
}, E = (e, t) => {
|
|
1067
1078
|
g((n) => {
|
|
1068
1079
|
let r = n[e] ?? [], i = r.includes(t) ? r.filter((e) => e !== t) : [...r, t];
|
|
1069
1080
|
return {
|
|
@@ -1071,7 +1082,7 @@ function te() {
|
|
|
1071
1082
|
[e]: i
|
|
1072
1083
|
};
|
|
1073
1084
|
});
|
|
1074
|
-
},
|
|
1085
|
+
}, A = () => {
|
|
1075
1086
|
let t;
|
|
1076
1087
|
if (r) {
|
|
1077
1088
|
t = { ...s }, l.size > 0 && (t.tables = [...l]);
|
|
@@ -1082,9 +1093,10 @@ function te() {
|
|
|
1082
1093
|
}
|
|
1083
1094
|
e.mutate({
|
|
1084
1095
|
backupType: "DATABASE",
|
|
1085
|
-
dumpOptions: t
|
|
1096
|
+
dumpOptions: t,
|
|
1097
|
+
scheduled: y
|
|
1086
1098
|
});
|
|
1087
|
-
},
|
|
1099
|
+
}, M = e.isPending, N = t.data?.configured && !M;
|
|
1088
1100
|
return /* @__PURE__ */ m("div", { children: [
|
|
1089
1101
|
/* @__PURE__ */ m("div", {
|
|
1090
1102
|
className: "mb-3",
|
|
@@ -1115,7 +1127,7 @@ function te() {
|
|
|
1115
1127
|
"aria-hidden": !0
|
|
1116
1128
|
}),
|
|
1117
1129
|
"Tabelas do banco (",
|
|
1118
|
-
n.data?.filter((e) => !
|
|
1130
|
+
n.data?.filter((e) => !S.has(e.fullName)).length ?? 0,
|
|
1119
1131
|
" disponíveis)"
|
|
1120
1132
|
]
|
|
1121
1133
|
}), /* @__PURE__ */ m("div", {
|
|
@@ -1158,7 +1170,7 @@ function te() {
|
|
|
1158
1170
|
X(n.error)
|
|
1159
1171
|
]
|
|
1160
1172
|
}),
|
|
1161
|
-
|
|
1173
|
+
C.length === 0 && !n.isLoading && /* @__PURE__ */ p("div", {
|
|
1162
1174
|
className: "p-3 text-muted small",
|
|
1163
1175
|
children: "Nenhuma tabela encontrada."
|
|
1164
1176
|
}),
|
|
@@ -1171,16 +1183,16 @@ function te() {
|
|
|
1171
1183
|
maxHeight: 420,
|
|
1172
1184
|
overflow: "auto"
|
|
1173
1185
|
},
|
|
1174
|
-
children:
|
|
1186
|
+
children: C.map((e) => /* @__PURE__ */ p(ne, {
|
|
1175
1187
|
table: e,
|
|
1176
|
-
disabled:
|
|
1188
|
+
disabled: S.has(e.fullName),
|
|
1177
1189
|
selected: l.has(e.fullName),
|
|
1178
1190
|
expanded: d === e.fullName,
|
|
1179
1191
|
excluded: h[e.fullName] ?? [],
|
|
1180
|
-
onToggleTable: () =>
|
|
1192
|
+
onToggleTable: () => T(e.fullName),
|
|
1181
1193
|
onToggleExpand: () => f(d === e.fullName ? null : e.fullName),
|
|
1182
|
-
onToggleColumn: (t) =>
|
|
1183
|
-
detail: d === e.fullName ?
|
|
1194
|
+
onToggleColumn: (t) => E(e.fullName, t),
|
|
1195
|
+
detail: d === e.fullName ? x : void 0
|
|
1184
1196
|
}, e.fullName))
|
|
1185
1197
|
}),
|
|
1186
1198
|
/* @__PURE__ */ m("div", {
|
|
@@ -1191,14 +1203,14 @@ function te() {
|
|
|
1191
1203
|
className: "bi bi-info-circle me-1",
|
|
1192
1204
|
"aria-hidden": !0
|
|
1193
1205
|
}), "Deixe tudo desmarcado para incluir todas as tabelas (exceto as bloqueadas por segurança)."]
|
|
1194
|
-
}),
|
|
1206
|
+
}), w > 0 && s.format !== "plain" && /* @__PURE__ */ m("span", {
|
|
1195
1207
|
className: "badge text-bg-warning ms-auto text-wrap text-start",
|
|
1196
1208
|
children: [
|
|
1197
1209
|
/* @__PURE__ */ p("i", {
|
|
1198
1210
|
className: "bi bi-exclamation-triangle me-1",
|
|
1199
1211
|
"aria-hidden": !0
|
|
1200
1212
|
}),
|
|
1201
|
-
|
|
1213
|
+
w,
|
|
1202
1214
|
" coluna(s) marcada(s) serão nulificadas apenas com formato Plain SQL (texto)"
|
|
1203
1215
|
]
|
|
1204
1216
|
})]
|
|
@@ -1349,15 +1361,36 @@ function te() {
|
|
|
1349
1361
|
"). O progresso é exibido na aba Backups."
|
|
1350
1362
|
]
|
|
1351
1363
|
}),
|
|
1364
|
+
/* @__PURE__ */ m("div", {
|
|
1365
|
+
className: "form-check form-switch mb-3 d-flex align-items-center gap-2",
|
|
1366
|
+
children: [/* @__PURE__ */ p("input", {
|
|
1367
|
+
className: "form-check-input",
|
|
1368
|
+
type: "checkbox",
|
|
1369
|
+
role: "switch",
|
|
1370
|
+
id: "minivault-scheduled",
|
|
1371
|
+
checked: y,
|
|
1372
|
+
onChange: (e) => b(e.target.checked)
|
|
1373
|
+
}), /* @__PURE__ */ m("label", {
|
|
1374
|
+
className: "form-check-label",
|
|
1375
|
+
htmlFor: "minivault-scheduled",
|
|
1376
|
+
children: ["Executar em agendamento", /* @__PURE__ */ m("span", {
|
|
1377
|
+
className: "text-muted small ms-2",
|
|
1378
|
+
children: [/* @__PURE__ */ p("i", {
|
|
1379
|
+
className: "bi bi-clock-history me-1",
|
|
1380
|
+
"aria-hidden": !0
|
|
1381
|
+
}), "O scheduler re-executa este backup automaticamente no horário configurado."]
|
|
1382
|
+
})]
|
|
1383
|
+
})]
|
|
1384
|
+
}),
|
|
1352
1385
|
/* @__PURE__ */ p("div", {
|
|
1353
1386
|
className: "d-flex justify-content-end",
|
|
1354
1387
|
children: /* @__PURE__ */ m("button", {
|
|
1355
1388
|
type: "button",
|
|
1356
1389
|
className: "btn btn-primary",
|
|
1357
|
-
onClick:
|
|
1358
|
-
disabled: !
|
|
1390
|
+
onClick: A,
|
|
1391
|
+
disabled: !N,
|
|
1359
1392
|
children: [
|
|
1360
|
-
|
|
1393
|
+
M && /* @__PURE__ */ p("span", {
|
|
1361
1394
|
className: "spinner-border spinner-border-sm me-2",
|
|
1362
1395
|
"aria-hidden": !0
|
|
1363
1396
|
}),
|
|
@@ -1780,7 +1813,7 @@ function $({ target: e = "origin", title: n = "Explorador de Storage", storageTy
|
|
|
1780
1813
|
}, t))]
|
|
1781
1814
|
})
|
|
1782
1815
|
}),
|
|
1783
|
-
R ? /* @__PURE__ */ m("div", {
|
|
1816
|
+
R || N ? /* @__PURE__ */ m("div", {
|
|
1784
1817
|
className: "text-center py-5",
|
|
1785
1818
|
children: [/* @__PURE__ */ p("div", {
|
|
1786
1819
|
className: "spinner-border text-primary",
|
|
@@ -2289,7 +2322,7 @@ function se() {
|
|
|
2289
2322
|
//#endregion
|
|
2290
2323
|
//#region src/components/StorageBackupTab.tsx
|
|
2291
2324
|
function ce() {
|
|
2292
|
-
let e = j(), t = T(), n = t.data?.find((e) => e.name === "ORIGIN_STORAGE"), r = t.data?.find((e) => e.name === "OUTPUT_STORAGE"), i = e.isPending;
|
|
2325
|
+
let e = j(), t = T(), n = t.data?.find((e) => e.name === "ORIGIN_STORAGE"), r = t.data?.find((e) => e.name === "OUTPUT_STORAGE"), i = e.isPending, [a, s] = o(!1);
|
|
2293
2326
|
return /* @__PURE__ */ m("div", { children: [
|
|
2294
2327
|
/* @__PURE__ */ m("div", {
|
|
2295
2328
|
className: "mb-3",
|
|
@@ -2371,13 +2404,37 @@ function ce() {
|
|
|
2371
2404
|
"). O progresso é exibido na aba Backups."
|
|
2372
2405
|
]
|
|
2373
2406
|
}),
|
|
2407
|
+
/* @__PURE__ */ m("div", {
|
|
2408
|
+
className: "form-check form-switch mb-3 d-flex align-items-center gap-2",
|
|
2409
|
+
children: [/* @__PURE__ */ p("input", {
|
|
2410
|
+
className: "form-check-input",
|
|
2411
|
+
type: "checkbox",
|
|
2412
|
+
role: "switch",
|
|
2413
|
+
id: "minivault-storage-scheduled",
|
|
2414
|
+
checked: a,
|
|
2415
|
+
onChange: (e) => s(e.target.checked)
|
|
2416
|
+
}), /* @__PURE__ */ m("label", {
|
|
2417
|
+
className: "form-check-label",
|
|
2418
|
+
htmlFor: "minivault-storage-scheduled",
|
|
2419
|
+
children: ["Executar em agendamento", /* @__PURE__ */ m("span", {
|
|
2420
|
+
className: "text-muted small ms-2",
|
|
2421
|
+
children: [/* @__PURE__ */ p("i", {
|
|
2422
|
+
className: "bi bi-clock-history me-1",
|
|
2423
|
+
"aria-hidden": !0
|
|
2424
|
+
}), "O scheduler re-executa este backup automaticamente no horário configurado."]
|
|
2425
|
+
})]
|
|
2426
|
+
})]
|
|
2427
|
+
}),
|
|
2374
2428
|
/* @__PURE__ */ p("div", {
|
|
2375
2429
|
className: "d-flex justify-content-end",
|
|
2376
2430
|
children: /* @__PURE__ */ m("button", {
|
|
2377
2431
|
type: "button",
|
|
2378
2432
|
className: "btn btn-primary",
|
|
2379
2433
|
onClick: () => {
|
|
2380
|
-
e.mutate({
|
|
2434
|
+
e.mutate({
|
|
2435
|
+
backupType: "STORAGE",
|
|
2436
|
+
scheduled: a
|
|
2437
|
+
});
|
|
2381
2438
|
},
|
|
2382
2439
|
disabled: i || t.data != null && n?.configured === !1,
|
|
2383
2440
|
children: [
|
|
@@ -15,6 +15,8 @@ export interface Backup {
|
|
|
15
15
|
errorMessage: string | null;
|
|
16
16
|
createdAt: string | null;
|
|
17
17
|
completedAt: string | null;
|
|
18
|
+
/** Quando true, o scheduler re-executa este backup (definição) no agendamento. */
|
|
19
|
+
scheduled: boolean;
|
|
18
20
|
}
|
|
19
21
|
export interface VerifyResult {
|
|
20
22
|
valid: boolean;
|
|
@@ -72,6 +74,8 @@ export interface DumpOptions {
|
|
|
72
74
|
export interface BackupRequest {
|
|
73
75
|
/** Tipo do backup: DATABASE (apenas banco), STORAGE (apenas arquivos) ou FULL (padrão legado). */
|
|
74
76
|
backupType?: BackupType;
|
|
77
|
+
/** Quando true, o scheduler re-executa este backup no agendamento. */
|
|
78
|
+
scheduled?: boolean;
|
|
75
79
|
/** Opcional: usa o banco padrão configurado no servidor (env) quando ausente. */
|
|
76
80
|
database?: DatabaseCredentials;
|
|
77
81
|
originStorage?: OriginStorageConfig;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@v1ct0rbr/minivault-web",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Módulo independente de gerenciamento de backups (minivault). Consumível como pacote npm em qualquer app React. Cliente do minivault REST API (acesso tipicamente via proxy autenticado).",
|
|
5
5
|
"author": "Victor Queiroga (https://www.linkedin.com/in/victor-queiroga)",
|
|
6
6
|
"license": "MIT",
|