@v1ct0rbr/minivault-web 0.4.1 → 0.4.3

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.
@@ -37,7 +37,9 @@ var h = class extends Error {
37
37
  let r = await n.text().catch(() => void 0) ?? "";
38
38
  throw new h(`Minivault API ${t.method ?? "GET"} ${e} falhou (HTTP ${n.status})${r ? `: ${_(r)}` : ""}`, n.status, r);
39
39
  }
40
- return await n.json();
40
+ if (n.status === 204 || n.headers.get("content-length") === "0") return;
41
+ let r = await n.text();
42
+ return r ? JSON.parse(r) : void 0;
41
43
  } catch (t) {
42
44
  throw t instanceof h || console.error(`[minivault-web] erro em ${this.baseUrl}${e}`, t), t;
43
45
  } finally {
@@ -847,7 +849,7 @@ function K() {
847
849
  busy: b.isPending,
848
850
  onCancel: () => c(null),
849
851
  onConfirm: () => {
850
- b.mutate(s.id), c(null);
852
+ b.mutate(s.id, { onSettled: () => c(null) });
851
853
  }
852
854
  })
853
855
  ] });
@@ -1533,43 +1535,43 @@ function te(e) {
1533
1535
  //#endregion
1534
1536
  //#region src/components/StorageExplorerTab.tsx
1535
1537
  function X({ storageType: e = "LOCAL", storageConfig: n }) {
1536
- let i = b(), a = d(), [s, c] = o(""), [h, g] = o([]), [_, v] = o(/* @__PURE__ */ new Set()), [y, x] = o(null), S = n?.type ?? e, { data: C, isLoading: w } = u({
1538
+ 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({
1537
1539
  queryKey: [
1538
1540
  "storage-files",
1539
- S,
1540
- s,
1541
+ C,
1542
+ c,
1541
1543
  n
1542
1544
  ],
1543
- queryFn: () => i.listStorageFiles(S, s || void 0, n)
1544
- }), T = l({
1545
- mutationFn: (e) => i.deleteStorageFile(e, S, n),
1545
+ queryFn: () => i.listStorageFiles(C, c || void 0, n)
1546
+ }), E = l({
1547
+ mutationFn: (e) => i.deleteStorageFile(e, C, n),
1546
1548
  onSuccess: () => {
1547
- a.invalidateQueries({ queryKey: ["storage-files"] }), x(null);
1549
+ s.invalidateQueries({ queryKey: ["storage-files"] }), S(null);
1548
1550
  }
1549
- }), E = t((e) => {
1550
- c(e), g(e ? e.split("/").filter(Boolean) : []), v(/* @__PURE__ */ new Set());
1551
- }, []), D = t((e) => {
1552
- let t = h.slice(0, e + 1).join("/");
1553
- E(t);
1554
- }, [h, E]);
1551
+ }), D = a(!1), O = t((e) => {
1552
+ h(e), _(e ? e.split("/").filter(Boolean) : []), y(/* @__PURE__ */ new Set());
1553
+ }, []), k = t((e) => {
1554
+ let t = g.slice(0, e + 1).join("/");
1555
+ O(t);
1556
+ }, [g, O]);
1555
1557
  r(() => {
1556
- g(s ? s.split("/").filter(Boolean) : []);
1557
- }, [s]);
1558
- let O = (e) => {
1559
- v((t) => {
1558
+ _(c ? c.split("/").filter(Boolean) : []);
1559
+ }, [c]);
1560
+ let A = (e) => {
1561
+ y((t) => {
1560
1562
  let n = new Set(t);
1561
1563
  return n.has(e) ? n.delete(e) : n.add(e), n;
1562
1564
  });
1563
- }, k = () => {
1564
- C && (_.size === C.length ? v(/* @__PURE__ */ new Set()) : v(new Set(C.map((e) => e.path))));
1565
- }, A = async (e) => {
1565
+ }, j = () => {
1566
+ w && (v.size === w.length ? y(/* @__PURE__ */ new Set()) : y(new Set(w.map((e) => e.path))));
1567
+ }, M = async (e) => {
1566
1568
  try {
1567
- let t = await i.downloadStorageFile(e, S, n), r = e.split("/").pop() ?? e, a = window.URL.createObjectURL(t), o = document.createElement("a");
1569
+ let t = await i.downloadStorageFile(e, C, n), r = e.split("/").pop() ?? e, a = window.URL.createObjectURL(t), o = document.createElement("a");
1568
1570
  o.href = a, o.download = r, document.body.appendChild(o), o.click(), o.remove(), window.URL.revokeObjectURL(a);
1569
1571
  } catch {}
1570
- }, j = async () => {
1571
- for (let e of _) await A(e);
1572
- }, M = (e) => e ? R(e) : "-";
1572
+ }, N = async () => {
1573
+ for (let e of v) await M(e);
1574
+ }, P = (e) => e ? R(e) : "-";
1573
1575
  return /* @__PURE__ */ m("div", {
1574
1576
  className: "space-y-3",
1575
1577
  children: [
@@ -1582,27 +1584,27 @@ function X({ storageType: e = "LOCAL", storageConfig: n }) {
1582
1584
  "Explorador de Storage",
1583
1585
  /* @__PURE__ */ p("span", {
1584
1586
  className: "badge bg-secondary ms-2",
1585
- children: S
1587
+ children: C
1586
1588
  })
1587
1589
  ]
1588
1590
  }), /* @__PURE__ */ p("div", {
1589
1591
  className: "d-flex gap-2",
1590
- children: _.size > 0 && /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ m("button", {
1592
+ children: v.size > 0 && /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ m("button", {
1591
1593
  className: "btn btn-sm btn-outline-primary",
1592
- onClick: j,
1594
+ onClick: N,
1593
1595
  children: [
1594
1596
  /* @__PURE__ */ p("i", { className: "bi bi-download me-1" }),
1595
1597
  "Baixar (",
1596
- _.size,
1598
+ v.size,
1597
1599
  ")"
1598
1600
  ]
1599
1601
  }), /* @__PURE__ */ m("button", {
1600
1602
  className: "btn btn-sm btn-outline-danger",
1601
- onClick: () => x("multiple"),
1603
+ onClick: () => S("multiple"),
1602
1604
  children: [
1603
1605
  /* @__PURE__ */ p("i", { className: "bi bi-trash me-1" }),
1604
1606
  "Excluir (",
1605
- _.size,
1607
+ v.size,
1606
1608
  ")"
1607
1609
  ]
1608
1610
  })] })
@@ -1613,19 +1615,19 @@ function X({ storageType: e = "LOCAL", storageConfig: n }) {
1613
1615
  children: /* @__PURE__ */ m("ol", {
1614
1616
  className: "breadcrumb mb-0 small",
1615
1617
  children: [/* @__PURE__ */ p("li", {
1616
- className: `breadcrumb-item ${h.length === 0 ? "active" : ""}`,
1617
- style: { cursor: h.length > 0 ? "pointer" : "default" },
1618
- onClick: () => E(""),
1618
+ className: `breadcrumb-item ${g.length === 0 ? "active" : ""}`,
1619
+ style: { cursor: g.length > 0 ? "pointer" : "default" },
1620
+ onClick: () => O(""),
1619
1621
  children: /* @__PURE__ */ p("i", { className: "bi bi-house" })
1620
- }), h.map((e, t) => /* @__PURE__ */ p("li", {
1621
- className: `breadcrumb-item ${t === h.length - 1 ? "active" : ""}`,
1622
- style: { cursor: t < h.length - 1 ? "pointer" : "default" },
1623
- onClick: () => t < h.length - 1 && D(t),
1622
+ }), g.map((e, t) => /* @__PURE__ */ p("li", {
1623
+ className: `breadcrumb-item ${t === g.length - 1 ? "active" : ""}`,
1624
+ style: { cursor: t < g.length - 1 ? "pointer" : "default" },
1625
+ onClick: () => t < g.length - 1 && k(t),
1624
1626
  children: e
1625
1627
  }, t))]
1626
1628
  })
1627
1629
  }),
1628
- w ? /* @__PURE__ */ m("div", {
1630
+ T ? /* @__PURE__ */ m("div", {
1629
1631
  className: "text-center py-5",
1630
1632
  children: [/* @__PURE__ */ p("div", {
1631
1633
  className: "spinner-border text-primary",
@@ -1634,14 +1636,14 @@ function X({ storageType: e = "LOCAL", storageConfig: n }) {
1634
1636
  className: "mt-2 small text-muted",
1635
1637
  children: "Carregando arquivos..."
1636
1638
  })]
1637
- }) : !C || C.length === 0 ? /* @__PURE__ */ m("div", {
1639
+ }) : !w || w.length === 0 ? /* @__PURE__ */ m("div", {
1638
1640
  className: "text-center py-5 text-muted",
1639
1641
  children: [
1640
1642
  /* @__PURE__ */ p("i", { className: "bi bi-folder-x fs-1 d-block mb-2" }),
1641
1643
  "Nenhum arquivo encontrado",
1642
- s && /* @__PURE__ */ p("button", {
1644
+ c && /* @__PURE__ */ p("button", {
1643
1645
  className: "btn btn-sm btn-link mt-2",
1644
- onClick: () => E(""),
1646
+ onClick: () => O(""),
1645
1647
  children: "Voltar ao inicio"
1646
1648
  })
1647
1649
  ]
@@ -1649,11 +1651,11 @@ function X({ storageType: e = "LOCAL", storageConfig: n }) {
1649
1651
  className: "d-flex align-items-center gap-2 mb-2",
1650
1652
  children: [/* @__PURE__ */ m("button", {
1651
1653
  className: "btn btn-sm btn-outline-secondary",
1652
- onClick: k,
1653
- children: [_.size === C.length ? "Desmarcar" : "Selecionar", " Todos"]
1654
+ onClick: j,
1655
+ children: [v.size === w.length ? "Desmarcar" : "Selecionar", " Todos"]
1654
1656
  }), /* @__PURE__ */ m("span", {
1655
1657
  className: "small text-muted",
1656
- children: [C.length, " item(ns)"]
1658
+ children: [w.length, " item(ns)"]
1657
1659
  })]
1658
1660
  }), /* @__PURE__ */ p("div", {
1659
1661
  className: "table-responsive",
@@ -1677,18 +1679,18 @@ function X({ storageType: e = "LOCAL", storageConfig: n }) {
1677
1679
  children: "Acoes"
1678
1680
  })
1679
1681
  ] })
1680
- }), /* @__PURE__ */ p("tbody", { children: C.map((e) => /* @__PURE__ */ m("tr", {
1681
- className: _.has(e.path) ? "table-active" : "",
1682
+ }), /* @__PURE__ */ p("tbody", { children: w.map((e) => /* @__PURE__ */ m("tr", {
1683
+ className: v.has(e.path) ? "table-active" : "",
1682
1684
  children: [
1683
1685
  /* @__PURE__ */ p("td", { children: /* @__PURE__ */ p("input", {
1684
1686
  type: "checkbox",
1685
1687
  className: "form-check-input",
1686
- checked: _.has(e.path),
1687
- onChange: () => O(e.path)
1688
+ checked: v.has(e.path),
1689
+ onChange: () => A(e.path)
1688
1690
  }) }),
1689
1691
  /* @__PURE__ */ p("td", { children: e.directory ? /* @__PURE__ */ m("button", {
1690
1692
  className: "btn btn-sm btn-link text-decoration-none p-0 text-start",
1691
- onClick: () => E(e.path),
1693
+ onClick: () => O(e.path),
1692
1694
  children: [/* @__PURE__ */ p("i", { className: "bi bi-folder-fill text-warning me-2" }), /* @__PURE__ */ p("span", {
1693
1695
  className: "font-monospace",
1694
1696
  children: e.name
@@ -1703,19 +1705,19 @@ function X({ storageType: e = "LOCAL", storageConfig: n }) {
1703
1705
  }),
1704
1706
  /* @__PURE__ */ p("td", {
1705
1707
  className: "text-muted small",
1706
- children: M(e.lastModified)
1708
+ children: P(e.lastModified)
1707
1709
  }),
1708
1710
  /* @__PURE__ */ p("td", { children: !e.directory && /* @__PURE__ */ m("div", {
1709
1711
  className: "d-flex gap-1",
1710
1712
  children: [/* @__PURE__ */ p("button", {
1711
1713
  className: "btn btn-sm btn-outline-primary py-0",
1712
1714
  title: "Baixar",
1713
- onClick: () => A(e.path),
1715
+ onClick: () => M(e.path),
1714
1716
  children: /* @__PURE__ */ p("i", { className: "bi bi-download" })
1715
1717
  }), /* @__PURE__ */ p("button", {
1716
1718
  className: "btn btn-sm btn-outline-danger py-0",
1717
1719
  title: "Excluir",
1718
- onClick: () => x(e.path),
1720
+ onClick: () => S(e.path),
1719
1721
  children: /* @__PURE__ */ p("i", { className: "bi bi-trash" })
1720
1722
  })]
1721
1723
  }) })
@@ -1723,7 +1725,7 @@ function X({ storageType: e = "LOCAL", storageConfig: n }) {
1723
1725
  }, e.path)) })]
1724
1726
  })
1725
1727
  })] }),
1726
- y && /* @__PURE__ */ p("div", {
1728
+ x && /* @__PURE__ */ p("div", {
1727
1729
  className: "modal d-block",
1728
1730
  tabIndex: -1,
1729
1731
  style: { background: "rgba(0,0,0,.5)" },
@@ -1739,38 +1741,60 @@ function X({ storageType: e = "LOCAL", storageConfig: n }) {
1739
1741
  children: "Confirmar exclusao"
1740
1742
  }), /* @__PURE__ */ p("button", {
1741
1743
  className: "btn-close",
1742
- onClick: () => x(null)
1744
+ onClick: () => S(null)
1743
1745
  })]
1744
1746
  }),
1745
1747
  /* @__PURE__ */ m("div", {
1746
1748
  className: "modal-body",
1747
- children: [y === "multiple" ? /* @__PURE__ */ m("p", { children: [
1748
- "Excluir ",
1749
- _.size,
1750
- " arquivo(s) selecionado(s)?"
1751
- ] }) : /* @__PURE__ */ m("p", { children: [
1752
- "Excluir ",
1753
- /* @__PURE__ */ p("code", { children: y.split("/").pop() }),
1754
- "?"
1755
- ] }), /* @__PURE__ */ p("p", {
1756
- className: "text-danger small mb-0",
1757
- children: "Esta acao nao pode ser desfeita."
1758
- })]
1749
+ children: [
1750
+ x === "multiple" ? /* @__PURE__ */ m("p", { children: [
1751
+ "Excluir ",
1752
+ v.size,
1753
+ " arquivo(s) selecionado(s)?"
1754
+ ] }) : /* @__PURE__ */ m("p", { children: [
1755
+ "Excluir ",
1756
+ /* @__PURE__ */ p("code", { children: x.split("/").pop() }),
1757
+ "?"
1758
+ ] }),
1759
+ /* @__PURE__ */ p("p", {
1760
+ className: "text-danger small mb-0",
1761
+ children: "Esta acao nao pode ser desfeita."
1762
+ }),
1763
+ E.isError && /* @__PURE__ */ m("div", {
1764
+ className: "alert alert-danger small mt-2 mb-0 py-1",
1765
+ children: [
1766
+ /* @__PURE__ */ p("i", {
1767
+ className: "bi bi-exclamation-triangle me-1",
1768
+ "aria-hidden": !0
1769
+ }),
1770
+ "Falha ao excluir:",
1771
+ " ",
1772
+ E.error instanceof Error ? E.error.message : String(E.error)
1773
+ ]
1774
+ })
1775
+ ]
1759
1776
  }),
1760
1777
  /* @__PURE__ */ m("div", {
1761
1778
  className: "modal-footer",
1762
1779
  children: [/* @__PURE__ */ p("button", {
1763
1780
  className: "btn btn-sm btn-secondary",
1764
- onClick: () => x(null),
1781
+ onClick: () => S(null),
1765
1782
  children: "Cancelar"
1766
1783
  }), /* @__PURE__ */ p("button", {
1767
1784
  className: "btn btn-sm btn-danger",
1768
- disabled: T.isPending,
1785
+ disabled: E.isPending,
1769
1786
  onClick: async () => {
1770
- if (y === "multiple") for (let e of _) await T.mutateAsync(e);
1771
- else await T.mutateAsync(y);
1787
+ if (!D.current) {
1788
+ D.current = !0;
1789
+ try {
1790
+ if (x === "multiple") for (let e of v) await E.mutateAsync(e);
1791
+ else await E.mutateAsync(x);
1792
+ } finally {
1793
+ D.current = !1;
1794
+ }
1795
+ }
1772
1796
  },
1773
- children: T.isPending ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p("span", { className: "spinner-border spinner-border-sm me-1" }), "Excluindo..."] }) : "Excluir"
1797
+ children: E.isPending ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p("span", { className: "spinner-border spinner-border-sm me-1" }), "Excluindo..."] }) : "Excluir"
1774
1798
  })]
1775
1799
  })
1776
1800
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@v1ct0rbr/minivault-web",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
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",