@crvouga/mockingbird-service-google-calendar 1.6.0 → 1.6.1
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/CHANGELOG.md +9 -1
- package/dist/{chunk-UFHN47JF.js → chunk-JTIBRMC6.js} +2 -2
- package/dist/{chunk-ABVGQK6B.js → chunk-UFM3RECQ.js} +89 -10
- package/dist/chunk-UFM3RECQ.js.map +7 -0
- package/dist/cli.js +2 -2
- package/dist/index.js +1 -1
- package/dist/server.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-ABVGQK6B.js.map +0 -7
- /package/dist/{chunk-UFHN47JF.js.map → chunk-JTIBRMC6.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# Changelog — @crvouga/mockingbird-service-google-calendar
|
|
2
2
|
|
|
3
|
-
## 1.6.
|
|
3
|
+
## 1.6.1 (2026-09-30)
|
|
4
|
+
|
|
5
|
+
### Fixes and improvements
|
|
6
|
+
|
|
7
|
+
- keep admin buttons pressed until the action finishes ([0aabfcb](https://github.com/crvouga/mockingbird/commit/0aabfcb5f392aa51e193f9c3f817d5877d92bc6a))
|
|
8
|
+
- size admin select fields like the text inputs beside them ([0fb3ef2](https://github.com/crvouga/mockingbird/commit/0fb3ef2ddbf43376c93a2ae6d87c6c9bf890dafc))
|
|
9
|
+
- keep admin section tabs wired when boot is renamed ([4eda25e](https://github.com/crvouga/mockingbird/commit/4eda25eacd59da048d196f7cc8369d7a02b47bfc))
|
|
10
|
+
|
|
11
|
+
## 1.6.0 (2026-09-29)
|
|
4
12
|
|
|
5
13
|
### Features
|
|
6
14
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createRuntime
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-UFM3RECQ.js";
|
|
4
4
|
|
|
5
5
|
// ../../adapters/node/dist/cli.js
|
|
6
6
|
import { readFile } from "node:fs/promises";
|
|
@@ -361,4 +361,4 @@ export {
|
|
|
361
361
|
createServer2 as createServer,
|
|
362
362
|
serveTarget
|
|
363
363
|
};
|
|
364
|
-
//# sourceMappingURL=chunk-
|
|
364
|
+
//# sourceMappingURL=chunk-JTIBRMC6.js.map
|
|
@@ -2323,6 +2323,50 @@ function bootAdmin(config) {
|
|
|
2323
2323
|
if (render)
|
|
2324
2324
|
await render();
|
|
2325
2325
|
}
|
|
2326
|
+
const delay = (ms) => new Promise((resolve) => {
|
|
2327
|
+
window.setTimeout(resolve, ms);
|
|
2328
|
+
});
|
|
2329
|
+
const confirmAction = async (button, pending, done, work) => {
|
|
2330
|
+
if (button.dataset.pending === "1")
|
|
2331
|
+
return;
|
|
2332
|
+
const label = button.textContent ?? "";
|
|
2333
|
+
const width = button.offsetWidth;
|
|
2334
|
+
button.dataset.pending = "1";
|
|
2335
|
+
button.classList.add("pressed");
|
|
2336
|
+
button.setAttribute("aria-busy", "true");
|
|
2337
|
+
button.style.minWidth = `${width}px`;
|
|
2338
|
+
button.textContent = pending;
|
|
2339
|
+
try {
|
|
2340
|
+
await work();
|
|
2341
|
+
button.textContent = done;
|
|
2342
|
+
await delay(1e3);
|
|
2343
|
+
} catch (error) {
|
|
2344
|
+
showError(error);
|
|
2345
|
+
} finally {
|
|
2346
|
+
button.textContent = label;
|
|
2347
|
+
button.style.minWidth = "";
|
|
2348
|
+
button.classList.remove("pressed");
|
|
2349
|
+
button.removeAttribute("aria-busy");
|
|
2350
|
+
delete button.dataset.pending;
|
|
2351
|
+
}
|
|
2352
|
+
};
|
|
2353
|
+
document.addEventListener("click", (event) => {
|
|
2354
|
+
const target = event.target;
|
|
2355
|
+
if (!(target instanceof Element))
|
|
2356
|
+
return;
|
|
2357
|
+
const button = target.closest("button");
|
|
2358
|
+
if (!(button instanceof HTMLButtonElement) || button.dataset.pending === "1")
|
|
2359
|
+
return;
|
|
2360
|
+
button.classList.add("pressed");
|
|
2361
|
+
const token = String(Date.now());
|
|
2362
|
+
button.dataset.press = token;
|
|
2363
|
+
window.setTimeout(() => {
|
|
2364
|
+
if (button.dataset.press !== token || button.dataset.pending === "1")
|
|
2365
|
+
return;
|
|
2366
|
+
button.classList.remove("pressed");
|
|
2367
|
+
delete button.dataset.press;
|
|
2368
|
+
}, 450);
|
|
2369
|
+
});
|
|
2326
2370
|
el("namespace", HTMLSelectElement).addEventListener("change", () => {
|
|
2327
2371
|
state.namespace = el("namespace", HTMLSelectElement).value;
|
|
2328
2372
|
refresh().catch(showError);
|
|
@@ -2333,7 +2377,7 @@ function bootAdmin(config) {
|
|
|
2333
2377
|
refresh().catch(showError);
|
|
2334
2378
|
});
|
|
2335
2379
|
el("refresh", HTMLButtonElement).addEventListener("click", () => {
|
|
2336
|
-
refresh().catch(showError);
|
|
2380
|
+
confirmAction(el("refresh", HTMLButtonElement), "Refreshing...", "Updated", () => refresh()).catch(showError);
|
|
2337
2381
|
});
|
|
2338
2382
|
el("collections", HTMLElement).addEventListener("click", (event) => {
|
|
2339
2383
|
const target = event.target;
|
|
@@ -2456,10 +2500,10 @@ function bootAdmin(config) {
|
|
|
2456
2500
|
}).then(() => renderFaults()).catch(showError);
|
|
2457
2501
|
});
|
|
2458
2502
|
el("fault-clear", HTMLButtonElement).addEventListener("click", () => {
|
|
2459
|
-
api("DELETE", "/faults").then(() => renderFaults()).catch(showError);
|
|
2503
|
+
confirmAction(el("fault-clear", HTMLButtonElement), "Clearing...", "Cleared", () => api("DELETE", "/faults").then(() => renderFaults())).catch(showError);
|
|
2460
2504
|
});
|
|
2461
2505
|
el("journal-clear", HTMLButtonElement).addEventListener("click", () => {
|
|
2462
|
-
api("DELETE", "/requests").then(() => renderJournal()).catch(showError);
|
|
2506
|
+
confirmAction(el("journal-clear", HTMLButtonElement), "Clearing...", "Cleared", () => api("DELETE", "/requests").then(() => renderJournal())).catch(showError);
|
|
2463
2507
|
});
|
|
2464
2508
|
el("route-list", HTMLElement).addEventListener("click", (event) => {
|
|
2465
2509
|
const target = event.target;
|
|
@@ -2574,9 +2618,13 @@ function bootAdmin(config) {
|
|
|
2574
2618
|
var clientPrelude = [isRecord2, mountAdminBrand, startAdminBrand, faultPresetList, bootAdmin].map((fn) => fn.toString()).join("\n");
|
|
2575
2619
|
var adminClientSource = (config) => {
|
|
2576
2620
|
const payload = JSON.stringify(config).replace(/</g, "\\u003c");
|
|
2621
|
+
const entry = bootAdmin.name;
|
|
2622
|
+
if (!/^[A-Za-z_$][\w$]*$/.test(entry)) {
|
|
2623
|
+
throw new Error("admin client cannot call its boot function");
|
|
2624
|
+
}
|
|
2577
2625
|
return `<script>
|
|
2578
2626
|
${clientPrelude}
|
|
2579
|
-
|
|
2627
|
+
${entry}(${payload});
|
|
2580
2628
|
</script>`;
|
|
2581
2629
|
};
|
|
2582
2630
|
|
|
@@ -2790,9 +2838,24 @@ var renderAdminDocument = (service) => {
|
|
|
2790
2838
|
.controls { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
|
|
2791
2839
|
label.field { display: flex; flex-direction: column; gap: 2px; font-size: 11px; color: var(--faint); }
|
|
2792
2840
|
label.field input, label.field select, .controls input[type="password"] {
|
|
2793
|
-
background: var(--bg-inset); border: 1px solid var(--line); border-radius: 8px;
|
|
2794
|
-
padding: 7px 8px; min-height: 36px;
|
|
2795
|
-
}
|
|
2841
|
+
background-color: var(--bg-inset); border: 1px solid var(--line); border-radius: 8px;
|
|
2842
|
+
padding: 7px 8px; min-height: 36px; line-height: 1.2;
|
|
2843
|
+
}
|
|
2844
|
+
/* A native menu ignores min-height, so Preset rendered about half as tall as
|
|
2845
|
+
the text fields in the same form. Paint it like those fields. */
|
|
2846
|
+
label.field select {
|
|
2847
|
+
-webkit-appearance: none; appearance: none;
|
|
2848
|
+
padding-right: 28px;
|
|
2849
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='none' stroke='%2371717a' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' d='M2.5 4.5 6 8l3.5-3.5'/%3E%3C/svg%3E");
|
|
2850
|
+
background-repeat: no-repeat; background-position: right 10px center; background-size: 12px 12px;
|
|
2851
|
+
}
|
|
2852
|
+
.stack > .field > input,
|
|
2853
|
+
.stack > .field > select,
|
|
2854
|
+
.stack > .field > textarea,
|
|
2855
|
+
dialog .field > input,
|
|
2856
|
+
dialog .field > select,
|
|
2857
|
+
dialog .field > textarea { width: 100%; }
|
|
2858
|
+
.icon-btn, .btn, .btn-primary, .btn-quiet, .btn-danger, nav.side button { cursor: pointer; }
|
|
2796
2859
|
.icon-btn, .btn, .btn-primary, .btn-quiet, .btn-danger {
|
|
2797
2860
|
border-radius: 9px; min-height: 36px; padding: 0 12px; border: 1px solid var(--line);
|
|
2798
2861
|
background: var(--bg-elev);
|
|
@@ -2800,6 +2863,14 @@ var renderAdminDocument = (service) => {
|
|
|
2800
2863
|
.btn-primary { background: var(--accent); color: var(--accent-ink); border-color: transparent; }
|
|
2801
2864
|
.btn-quiet { background: transparent; }
|
|
2802
2865
|
.btn-danger { color: var(--err); }
|
|
2866
|
+
/* Held after mouseup. Clearing an empty journal changes nothing on screen,
|
|
2867
|
+
so the press itself has to stay visible. */
|
|
2868
|
+
.icon-btn:active, .btn:active, .btn-quiet:active, .btn-danger:active, nav.side button:active,
|
|
2869
|
+
.icon-btn.pressed, .btn.pressed, .btn-quiet.pressed, .btn-danger.pressed, nav.side button.pressed {
|
|
2870
|
+
background: var(--bg-inset); border-color: var(--line-strong); color: var(--ink);
|
|
2871
|
+
}
|
|
2872
|
+
.btn-danger:active, .btn-danger.pressed { background: var(--err-soft); color: var(--err); }
|
|
2873
|
+
.btn-primary:active, .btn-primary.pressed { filter: brightness(0.88); color: var(--accent-ink); }
|
|
2803
2874
|
/* minmax(0, 1fr): a 1fr column will not shrink below its content, so a long
|
|
2804
2875
|
record or the full nav row would widen the page past the viewport. */
|
|
2805
2876
|
.layout {
|
|
@@ -2888,8 +2959,16 @@ var renderAdminDocument = (service) => {
|
|
|
2888
2959
|
input, select, textarea { font-size: 16px; }
|
|
2889
2960
|
.brand, .vendor, .controls { width: 100%; }
|
|
2890
2961
|
label.field, label.field select, label.field input { flex: 1; min-width: 0; }
|
|
2891
|
-
|
|
2962
|
+
/* The layout fills the screen. A single-column grid stretches every auto
|
|
2963
|
+
row, so the tab bar grew with the leftover height and the buttons floated
|
|
2964
|
+
in the middle of it. The bar stays one row; the page below takes the rest. */
|
|
2965
|
+
.layout {
|
|
2966
|
+
grid-template-columns: minmax(0, 1fr);
|
|
2967
|
+
grid-template-rows: auto minmax(0, 1fr);
|
|
2968
|
+
align-content: start;
|
|
2969
|
+
}
|
|
2892
2970
|
nav.side {
|
|
2971
|
+
align-self: start; height: auto;
|
|
2893
2972
|
flex-direction: row; align-items: center; overflow-x: auto; min-width: 0;
|
|
2894
2973
|
border-right: 0; border-bottom: 1px solid var(--line);
|
|
2895
2974
|
padding: 8px;
|
|
@@ -3757,7 +3836,7 @@ var stateAdminRoutes = (routes) => {
|
|
|
3757
3836
|
};
|
|
3758
3837
|
|
|
3759
3838
|
// ../core/dist/version.js
|
|
3760
|
-
var PACKAGE_VERSION = true ? "1.6.
|
|
3839
|
+
var PACKAGE_VERSION = true ? "1.6.1" : UNRELEASED_VERSION;
|
|
3761
3840
|
|
|
3762
3841
|
// ../core/dist/signing.js
|
|
3763
3842
|
var encoder = new TextEncoder();
|
|
@@ -5842,4 +5921,4 @@ export {
|
|
|
5842
5921
|
emailFromCode,
|
|
5843
5922
|
GoogleCalendarAPI
|
|
5844
5923
|
};
|
|
5845
|
-
//# sourceMappingURL=chunk-
|
|
5924
|
+
//# sourceMappingURL=chunk-UFM3RECQ.js.map
|