@cancia/toolbar 0.13.0 → 0.14.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.
- package/dist/cancia.iife.js +123 -114
- package/dist/cancia.js +95 -2
- package/dist/cancia.js.map +1 -1
- package/package.json +2 -2
package/dist/cancia.js
CHANGED
|
@@ -388,9 +388,9 @@ async function reorderList(listName, ids) {
|
|
|
388
388
|
const { apiUrl, site } = state.config;
|
|
389
389
|
const res = await fetch(
|
|
390
390
|
`${apiUrl}/api/cancia/lists/${encodeURIComponent(listName)}/reorder?site=${encodeURIComponent(site)}${routeParam()}`,
|
|
391
|
-
{ method: "POST", headers: headers(), body: JSON.stringify({ ids }) }
|
|
391
|
+
{ method: "POST", headers: headers(), body: JSON.stringify({ ids, knownCount: ids.length }) }
|
|
392
392
|
);
|
|
393
|
-
if (!res.ok) throw
|
|
393
|
+
if (!res.ok) throw await toApiError(res, "Could not save the new order. Check your connection and try again.");
|
|
394
394
|
}
|
|
395
395
|
async function flushEdits(edits, save) {
|
|
396
396
|
const results = await Promise.allSettled(edits.map((edit) => save(edit)));
|
|
@@ -2740,6 +2740,99 @@ function renderField(field, initial, depth = 0) {
|
|
|
2740
2740
|
getValue2 = () => sel.value === "" ? void 0 : sel.value;
|
|
2741
2741
|
break;
|
|
2742
2742
|
}
|
|
2743
|
+
case "file": {
|
|
2744
|
+
let currentUrl = typeof initial === "string" ? initial : "";
|
|
2745
|
+
const box = document.createElement("div");
|
|
2746
|
+
box.style.cssText = `
|
|
2747
|
+
display: flex; flex-direction: column; gap: 8px;
|
|
2748
|
+
background: ${v("surface-raised")};
|
|
2749
|
+
border: 1px dashed ${v("border-strong")};
|
|
2750
|
+
border-radius: ${v("radius")};
|
|
2751
|
+
padding: 10px;
|
|
2752
|
+
`;
|
|
2753
|
+
const nameRow = document.createElement("div");
|
|
2754
|
+
nameRow.style.cssText = `display:flex; align-items:center; gap:8px; min-width:0;`;
|
|
2755
|
+
const nameLink = document.createElement("a");
|
|
2756
|
+
nameLink.target = "_blank";
|
|
2757
|
+
nameLink.rel = "noopener";
|
|
2758
|
+
nameLink.style.cssText = `
|
|
2759
|
+
font-size: ${v("text-sm")}; color: ${v("fg")}; text-decoration: underline;
|
|
2760
|
+
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
|
|
2761
|
+
`;
|
|
2762
|
+
const renderName = (url) => {
|
|
2763
|
+
if (!url) {
|
|
2764
|
+
nameLink.removeAttribute("href");
|
|
2765
|
+
nameLink.textContent = "No file attached";
|
|
2766
|
+
nameLink.style.color = v("fg-faint");
|
|
2767
|
+
nameLink.style.textDecoration = "none";
|
|
2768
|
+
return;
|
|
2769
|
+
}
|
|
2770
|
+
let label2 = url;
|
|
2771
|
+
try {
|
|
2772
|
+
label2 = decodeURIComponent(new URL(url, location.href).pathname.split("/").pop() || url);
|
|
2773
|
+
} catch {
|
|
2774
|
+
}
|
|
2775
|
+
nameLink.href = url;
|
|
2776
|
+
nameLink.textContent = label2;
|
|
2777
|
+
nameLink.style.color = v("fg");
|
|
2778
|
+
nameLink.style.textDecoration = "underline";
|
|
2779
|
+
};
|
|
2780
|
+
renderName(currentUrl);
|
|
2781
|
+
nameRow.appendChild(nameLink);
|
|
2782
|
+
box.appendChild(nameRow);
|
|
2783
|
+
const btnRow = document.createElement("div");
|
|
2784
|
+
btnRow.style.cssText = `display:flex; gap:8px; align-items:center;`;
|
|
2785
|
+
const fileInput = document.createElement("input");
|
|
2786
|
+
fileInput.type = "file";
|
|
2787
|
+
fileInput.accept = "application/pdf";
|
|
2788
|
+
fileInput.style.display = "none";
|
|
2789
|
+
const uploadBtn = document.createElement("button");
|
|
2790
|
+
uploadBtn.type = "button";
|
|
2791
|
+
uploadBtn.textContent = "Upload\u2026";
|
|
2792
|
+
uploadBtn.style.cssText = `${button("ghost")} font-size: ${v("text-xs")};`;
|
|
2793
|
+
attachHover(uploadBtn, { bg: v("surface-active") });
|
|
2794
|
+
uploadBtn.addEventListener("click", () => fileInput.click());
|
|
2795
|
+
const clearBtn = document.createElement("button");
|
|
2796
|
+
clearBtn.type = "button";
|
|
2797
|
+
clearBtn.textContent = "Clear";
|
|
2798
|
+
clearBtn.style.cssText = `${button("ghost")} font-size: ${v("text-xs")};`;
|
|
2799
|
+
attachHover(clearBtn, { bg: v("surface-active") });
|
|
2800
|
+
clearBtn.addEventListener("click", () => {
|
|
2801
|
+
currentUrl = "";
|
|
2802
|
+
renderName("");
|
|
2803
|
+
progressEl.textContent = "";
|
|
2804
|
+
});
|
|
2805
|
+
const progressEl = document.createElement("span");
|
|
2806
|
+
progressEl.style.cssText = `font-size: ${v("text-xs")}; color: ${v("fg-muted")};`;
|
|
2807
|
+
fileInput.addEventListener("change", async () => {
|
|
2808
|
+
const f = fileInput.files?.[0];
|
|
2809
|
+
if (!f) return;
|
|
2810
|
+
uploadBtn.disabled = true;
|
|
2811
|
+
try {
|
|
2812
|
+
const url = await uploadImage(f, (pct) => {
|
|
2813
|
+
progressEl.textContent = `Uploading\u2026 ${pct}%`;
|
|
2814
|
+
});
|
|
2815
|
+
currentUrl = url;
|
|
2816
|
+
renderName(url);
|
|
2817
|
+
progressEl.textContent = "Uploaded";
|
|
2818
|
+
} catch (err) {
|
|
2819
|
+
const msg = err instanceof Error && err.message.includes("(413)") ? "That file is too large." : "Upload failed \u2014 try again.";
|
|
2820
|
+
progressEl.textContent = msg;
|
|
2821
|
+
progressEl.style.color = v("danger");
|
|
2822
|
+
} finally {
|
|
2823
|
+
uploadBtn.disabled = false;
|
|
2824
|
+
fileInput.value = "";
|
|
2825
|
+
}
|
|
2826
|
+
});
|
|
2827
|
+
btnRow.appendChild(uploadBtn);
|
|
2828
|
+
btnRow.appendChild(clearBtn);
|
|
2829
|
+
btnRow.appendChild(progressEl);
|
|
2830
|
+
box.appendChild(btnRow);
|
|
2831
|
+
box.appendChild(fileInput);
|
|
2832
|
+
wrapper.appendChild(box);
|
|
2833
|
+
getValue2 = () => currentUrl === "" ? void 0 : currentUrl;
|
|
2834
|
+
break;
|
|
2835
|
+
}
|
|
2743
2836
|
case "image": {
|
|
2744
2837
|
const initialUrl = typeof initial === "string" ? initial : "";
|
|
2745
2838
|
let currentUrl = initialUrl;
|