@blinkk/root-cms 3.0.6 → 3.1.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/README.md +77 -0
- package/dist/app.js +6 -4
- package/dist/browser-client/browser-client.d.ts +148 -0
- package/dist/browser-client/embed-window.d.ts +66 -0
- package/dist/browser-client/emitter.d.ts +11 -0
- package/dist/browser-client.js +377 -0
- package/dist/{chunk-RXWDB3K4.js → chunk-4VZTYUQ7.js} +1 -1
- package/dist/{chunk-N4K6ICFR.js → chunk-AFBSITEO.js} +4 -6
- package/dist/{chunk-PNLLZXVY.js → chunk-AJDMNTZQ.js} +2 -2
- package/dist/{chunk-7L5OI5ES.js → chunk-GXV4UQ6Z.js} +8 -4
- package/dist/chunk-J72JK4KR.js +8 -0
- package/dist/cli.js +2 -1
- package/dist/client.js +2 -1
- package/dist/core/client.d.ts +5 -0
- package/dist/core.js +4 -2
- package/dist/functions.js +4 -3
- package/dist/plugin.js +5 -4
- package/dist/shared/embed-protocol.d.ts +72 -0
- package/dist/ui/AIPage-EL6DQYII.js +1 -0
- package/dist/ui/AssetsPage-5S6PNMF6.js +1 -0
- package/dist/ui/CollectionPage-CU3VDEXA.js +1 -0
- package/dist/ui/ComparePage-FTZLYO2O.js +1 -0
- package/dist/ui/DataPage-XIXFKXDN.js +1 -0
- package/dist/ui/DataSourcePage-ORIEQH3Y.js +1 -0
- package/dist/ui/DocTranslationsPage-4OVBIPSG.js +1 -0
- package/dist/ui/DocumentPage-3JPFJF3E.js +1 -0
- package/dist/ui/EditDataSourcePage-HIGZZQJC.js +1 -0
- package/dist/ui/EditReleasePage-KUHBU2HQ.js +1 -0
- package/dist/ui/EmbeddedAIPage-CJWZE5FC.js +1 -0
- package/dist/ui/EmbeddedDocumentPage-6XQHYIAO.js +1 -0
- package/dist/ui/{ImageEditorDialog-QEULJAT2.js → ImageEditorDialog-GGS4VFEA.js} +2 -2
- package/dist/ui/LogsPage-4DVGYXZY.js +1 -0
- package/dist/ui/NewDataSourcePage-7TUUE6ZL.js +1 -0
- package/dist/ui/NewReleasePage-6UT36HDW.js +1 -0
- package/dist/ui/NotFoundPage-AW6UC6II.js +1 -0
- package/dist/ui/ProjectPage-US5FJGFK.js +1 -0
- package/dist/ui/ReleasePage-W2R3DIFX.js +1 -0
- package/dist/ui/ReleasesPage-HBBUGE7D.js +1 -0
- package/dist/ui/SettingsPage-7JQQILUV.js +1 -0
- package/dist/ui/SidebarToolsPage-MIYXKHF2.js +1 -0
- package/dist/ui/TaskPage-JYUQEGRB.js +1 -0
- package/dist/ui/TasksPage-4VFQF243.js +1 -0
- package/dist/ui/TranslationsArbPage-AJLM5VSD.js +2 -0
- package/dist/ui/TranslationsEditPage-RTTGTIGI.js +1 -0
- package/dist/ui/{TranslationsPage-OBN6CQZZ.js → TranslationsPage-HPYAJQ4Q.js} +2 -2
- package/dist/ui/{chunk-WKOX3VFN.js → chunk-2KSMCQ6H.js} +2 -2
- package/dist/ui/{chunk-V7RAXP2W.js → chunk-3E6CASIN.js} +1 -1
- package/dist/ui/{chunk-N4DFAIC5.js → chunk-3T4ZWQR4.js} +1 -1
- package/dist/ui/chunk-4ISFTE2G.js +5 -0
- package/dist/ui/chunk-5AVRMJVW.js +1 -0
- package/dist/ui/chunk-764W6634.js +1 -0
- package/dist/ui/chunk-76ZGLKLT.js +1 -0
- package/dist/ui/{chunk-SKEP5WYH.js → chunk-7SK47HHZ.js} +3 -3
- package/dist/ui/chunk-AZCGXQTL.js +1 -0
- package/dist/ui/{chunk-KYKFNAX4.js → chunk-B6M55OFE.js} +1 -1
- package/dist/ui/{chunk-2225WAJ2.js → chunk-CAY5NM4Z.js} +1 -1
- package/dist/ui/{chunk-4KE2SZKH.js → chunk-D3UIZHRK.js} +1 -1
- package/dist/ui/{chunk-NMBXHKIJ.js → chunk-E76ECIOX.js} +1 -1
- package/dist/ui/chunk-FBSBL476.js +1 -0
- package/dist/ui/chunk-FFHV5S6A.js +1 -0
- package/dist/ui/{chunk-NQB37NMX.js → chunk-FJLNXXE3.js} +1 -1
- package/dist/ui/chunk-FSVNOZ6F.js +1 -0
- package/dist/ui/{chunk-3IDOZ4MG.js → chunk-GDXNSFLE.js} +1 -1
- package/dist/ui/{chunk-EMYXSVTD.js → chunk-GQ5IRK43.js} +1 -1
- package/dist/ui/{chunk-UHWNLNP4.js → chunk-GU24U5RM.js} +1 -1
- package/dist/ui/{chunk-KPJ53X55.js → chunk-HARRKJFZ.js} +1 -1
- package/dist/ui/{chunk-6E7PGMZX.js → chunk-HO3W4RVG.js} +1 -1
- package/dist/ui/{chunk-CVGYBXVH.js → chunk-J5E457OI.js} +1 -1
- package/dist/ui/{chunk-W3HIZQ4Z.js → chunk-JS6TK4OP.js} +1 -1
- package/dist/ui/{chunk-BEDUTYQP.js → chunk-JTIQBW33.js} +1 -1
- package/dist/ui/{chunk-ORXEMIQC.js → chunk-KRNQ6L35.js} +1 -1
- package/dist/ui/chunk-LROR6N3B.js +7 -0
- package/dist/ui/{chunk-4CUWZQXT.js.LEGAL.txt → chunk-LROR6N3B.js.LEGAL.txt} +6 -1
- package/dist/ui/{chunk-AOCBDKLV.js → chunk-M3T56ZRP.js} +1 -1
- package/dist/ui/chunk-MXGHX55S.js +141 -0
- package/dist/ui/{chunk-HYARD7BK.js → chunk-MZTOPPWQ.js} +1 -1
- package/dist/ui/{chunk-RQKL4KXY.js → chunk-N3JSLTMV.js} +1 -1
- package/dist/ui/{chunk-D37DCENS.js → chunk-NSOTG64N.js} +1 -1
- package/dist/ui/{chunk-N5Y5OWTV.js → chunk-O5P3CPJ4.js} +1 -1
- package/dist/ui/chunk-OWQL5DVE.js +1 -0
- package/dist/ui/{chunk-SEUH7LN2.js → chunk-OXVYTSIZ.js} +1 -1
- package/dist/ui/chunk-P2Z66DHV.js +1 -0
- package/dist/ui/{chunk-TZEZEMRQ.js → chunk-QEE7XS6O.js} +1 -1
- package/dist/ui/{chunk-AXETBZ6T.js → chunk-QHJOTXYB.js} +1 -1
- package/dist/ui/{chunk-4IXGYXA2.js → chunk-R6B3W5AJ.js} +1 -1
- package/dist/ui/{chunk-T47V6AGW.js → chunk-RAXWL656.js} +1 -1
- package/dist/ui/chunk-SRX7EWL4.js +1 -0
- package/dist/ui/{chunk-OVRTVMO5.js → chunk-TDUBSLEC.js} +1 -1
- package/dist/ui/chunk-TFB3VGWP.js +1 -0
- package/dist/ui/{chunk-6MOPIV5T.js → chunk-U7PWJV6F.js} +1 -1
- package/dist/ui/{chunk-GDSSFO5R.js → chunk-UUVAD4U4.js} +1 -1
- package/dist/ui/chunk-V4CTOC6E.js +1 -0
- package/dist/ui/{chunk-EGEB6N4J.js → chunk-VD6G5NV4.js} +11 -11
- package/dist/ui/chunk-W5DOO6ID.js +1 -0
- package/dist/ui/{chunk-3XYCOR6Z.js → chunk-WFQU7V3W.js} +1 -1
- package/dist/ui/{chunk-XYBHH5L4.js → chunk-WKF7CSWS.js} +1 -1
- package/dist/ui/{chunk-DXKEDMEI.js → chunk-WXT7LTQM.js} +1 -1
- package/dist/ui/{chunk-6GPTGBA7.js → chunk-XT5FNJCX.js} +1 -1
- package/dist/ui/chunk-YLSRRNSE.js +1 -0
- package/dist/ui/{chunk-UFQSZ6J2.js → chunk-ZN2Y5OUF.js} +1 -1
- package/dist/ui/gcs-ECSDFCIU.js +1 -0
- package/dist/ui/ui.css +1 -1
- package/dist/ui/ui.js +1 -1
- package/package.json +7 -3
- package/dist/ui/AIPage-JPZ4QUB4.js +0 -1
- package/dist/ui/AssetsPage-GDJMKS3M.js +0 -1
- package/dist/ui/CollectionPage-5DVXJEET.js +0 -1
- package/dist/ui/ComparePage-LIXA6G66.js +0 -1
- package/dist/ui/DataPage-AP4Z5JPS.js +0 -1
- package/dist/ui/DataSourcePage-WO3ZKMFI.js +0 -1
- package/dist/ui/DocTranslationsPage-QKYFIVHP.js +0 -1
- package/dist/ui/DocumentPage-ON43I5KM.js +0 -1
- package/dist/ui/EditDataSourcePage-XVMEV2LJ.js +0 -1
- package/dist/ui/EditReleasePage-A2NB5TFG.js +0 -1
- package/dist/ui/LogsPage-4LZJX3O4.js +0 -1
- package/dist/ui/NewDataSourcePage-4YWX7IOG.js +0 -1
- package/dist/ui/NewReleasePage-HWLVTEXX.js +0 -1
- package/dist/ui/NotFoundPage-72AXQAYX.js +0 -1
- package/dist/ui/ProjectPage-L4GYDIA5.js +0 -1
- package/dist/ui/ReleasePage-43BSWL5B.js +0 -1
- package/dist/ui/ReleasesPage-CJXAZBP6.js +0 -1
- package/dist/ui/SettingsPage-SYXAMKSF.js +0 -1
- package/dist/ui/SidebarToolsPage-OFF5BOXP.js +0 -1
- package/dist/ui/TaskPage-HBDLHFI5.js +0 -1
- package/dist/ui/TasksPage-OLCDTQNB.js +0 -1
- package/dist/ui/TranslationsArbPage-E3NCMAMS.js +0 -2
- package/dist/ui/TranslationsEditPage-IWOI7Y5G.js +0 -1
- package/dist/ui/chunk-32LRQ5MJ.js +0 -1
- package/dist/ui/chunk-3HVDIPSS.js +0 -1
- package/dist/ui/chunk-4CUWZQXT.js +0 -7
- package/dist/ui/chunk-DUJYIOLE.js +0 -5
- package/dist/ui/chunk-IDYKCAAL.js +0 -1
- package/dist/ui/chunk-IKED2IGU.js +0 -1
- package/dist/ui/chunk-J3EGGI57.js +0 -1
- package/dist/ui/chunk-MZP6RIG2.js +0 -1
- package/dist/ui/chunk-NQ5ARARP.js +0 -1
- package/dist/ui/chunk-RI2JWWU3.js +0 -141
- package/dist/ui/chunk-RPOP6MVJ.js +0 -1
- package/dist/ui/chunk-TDKVKTW4.js +0 -1
- package/dist/ui/chunk-UA7UCTX5.js +0 -1
- package/dist/ui/gcs-L33FIRZU.js +0 -1
- /package/dist/ui/{ImageEditorDialog-QEULJAT2.js.LEGAL.txt → ImageEditorDialog-GGS4VFEA.js.LEGAL.txt} +0 -0
- /package/dist/ui/{chunk-SKEP5WYH.js.LEGAL.txt → chunk-7SK47HHZ.js.LEGAL.txt} +0 -0
- /package/dist/ui/{chunk-NMBXHKIJ.js.LEGAL.txt → chunk-E76ECIOX.js.LEGAL.txt} +0 -0
- /package/dist/ui/{chunk-RI2JWWU3.js.LEGAL.txt → chunk-MXGHX55S.js.LEGAL.txt} +0 -0
- /package/dist/ui/{chunk-EGEB6N4J.js.LEGAL.txt → chunk-VD6G5NV4.js.LEGAL.txt} +0 -0
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import {
|
|
2
|
+
normalizeSlug
|
|
3
|
+
} from "./chunk-J72JK4KR.js";
|
|
4
|
+
import "./chunk-MLKGABMK.js";
|
|
5
|
+
|
|
6
|
+
// shared/embed-protocol.ts
|
|
7
|
+
var SaveState = /* @__PURE__ */ ((SaveState3) => {
|
|
8
|
+
SaveState3["NO_CHANGES"] = "NO_CHANGES";
|
|
9
|
+
SaveState3["UPDATES_PENDING"] = "UPDATE_PENDING";
|
|
10
|
+
SaveState3["SAVING"] = "SAVING";
|
|
11
|
+
SaveState3["SAVED"] = "SAVED";
|
|
12
|
+
SaveState3["ERROR"] = "ERROR";
|
|
13
|
+
return SaveState3;
|
|
14
|
+
})(SaveState || {});
|
|
15
|
+
var EMBED_MESSAGE_TYPES = ["ready", "saved", "published", "error"];
|
|
16
|
+
function isRootEmbedMessage(data) {
|
|
17
|
+
const root = data?.root;
|
|
18
|
+
return typeof root === "object" && root !== null && EMBED_MESSAGE_TYPES.includes(root.type);
|
|
19
|
+
}
|
|
20
|
+
function isHighlightNodeMessage(data) {
|
|
21
|
+
const req = data?.highlightNode;
|
|
22
|
+
return typeof req === "object" && req !== null && (typeof req.deepKey === "string" || req.deepKey === null);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// browser-client/emitter.ts
|
|
26
|
+
var Emitter = class {
|
|
27
|
+
constructor() {
|
|
28
|
+
this.listeners = /* @__PURE__ */ new Map();
|
|
29
|
+
}
|
|
30
|
+
/** Subscribes to an event. Returns an unsubscribe function. */
|
|
31
|
+
on(type, cb) {
|
|
32
|
+
let set = this.listeners.get(type);
|
|
33
|
+
if (!set) {
|
|
34
|
+
set = /* @__PURE__ */ new Set();
|
|
35
|
+
this.listeners.set(type, set);
|
|
36
|
+
}
|
|
37
|
+
set.add(cb);
|
|
38
|
+
return () => this.off(type, cb);
|
|
39
|
+
}
|
|
40
|
+
off(type, cb) {
|
|
41
|
+
this.listeners.get(type)?.delete(cb);
|
|
42
|
+
}
|
|
43
|
+
emit(type, payload) {
|
|
44
|
+
this.listeners.get(type)?.forEach((cb) => cb(payload));
|
|
45
|
+
}
|
|
46
|
+
removeAll() {
|
|
47
|
+
this.listeners.clear();
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// browser-client/embed-window.ts
|
|
52
|
+
var POPUP_POLL_INTERVAL = 500;
|
|
53
|
+
var DEFAULT_POPUP_WIDTH = 480;
|
|
54
|
+
var DEFAULT_POPUP_HEIGHT = 720;
|
|
55
|
+
var EmbedWindow = class {
|
|
56
|
+
constructor(url, cmsOrigin, options) {
|
|
57
|
+
/** The iframe element (iframe mode only). */
|
|
58
|
+
this.element = null;
|
|
59
|
+
/** The pop-up window (popup mode only). */
|
|
60
|
+
this.window = null;
|
|
61
|
+
this.emitter = new Emitter();
|
|
62
|
+
this.ready = false;
|
|
63
|
+
this.closed = false;
|
|
64
|
+
this.outbox = [];
|
|
65
|
+
this.pollTimer = null;
|
|
66
|
+
this.onMessage = (event) => {
|
|
67
|
+
if (event.origin !== this.cmsOrigin) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (!event.source || event.source !== this.contentWindow()) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (!isRootEmbedMessage(event.data)) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const root = event.data.root;
|
|
77
|
+
if (root.type === "ready") {
|
|
78
|
+
this.ready = true;
|
|
79
|
+
const outbox = this.outbox;
|
|
80
|
+
this.outbox = [];
|
|
81
|
+
outbox.forEach((message) => this.post(message));
|
|
82
|
+
}
|
|
83
|
+
this.emitter.emit(root.type, root);
|
|
84
|
+
};
|
|
85
|
+
this.url = url;
|
|
86
|
+
this.cmsOrigin = cmsOrigin;
|
|
87
|
+
window.addEventListener("message", this.onMessage);
|
|
88
|
+
const mode = options?.mode || "popup";
|
|
89
|
+
if (mode === "iframe") {
|
|
90
|
+
if (!options?.container) {
|
|
91
|
+
throw new Error('`container` is required when mode is "iframe"');
|
|
92
|
+
}
|
|
93
|
+
const iframe = document.createElement("iframe");
|
|
94
|
+
iframe.className = "root-cms-embed";
|
|
95
|
+
iframe.src = url;
|
|
96
|
+
options.container.appendChild(iframe);
|
|
97
|
+
this.element = iframe;
|
|
98
|
+
} else {
|
|
99
|
+
const width = options?.width ?? DEFAULT_POPUP_WIDTH;
|
|
100
|
+
const height = options?.height ?? DEFAULT_POPUP_HEIGHT;
|
|
101
|
+
const popup = window.open(
|
|
102
|
+
url,
|
|
103
|
+
"_blank",
|
|
104
|
+
`popup,width=${width},height=${height}`
|
|
105
|
+
);
|
|
106
|
+
if (!popup) {
|
|
107
|
+
queueMicrotask(() => {
|
|
108
|
+
this.emitter.emit("error", {
|
|
109
|
+
error: "popup blocked (open the editor from a user gesture, e.g. a click handler)"
|
|
110
|
+
});
|
|
111
|
+
this.close();
|
|
112
|
+
});
|
|
113
|
+
} else {
|
|
114
|
+
this.window = popup;
|
|
115
|
+
this.pollTimer = setInterval(() => {
|
|
116
|
+
if (popup.closed) {
|
|
117
|
+
this.close();
|
|
118
|
+
}
|
|
119
|
+
}, POPUP_POLL_INTERVAL);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
on(type, cb) {
|
|
124
|
+
return this.emitter.on(type, cb);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Posts a message to the embedded window, targeted at the CMS origin.
|
|
128
|
+
* Messages are buffered until the embedded page signals `ready`.
|
|
129
|
+
*/
|
|
130
|
+
post(message) {
|
|
131
|
+
if (this.closed) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (!this.ready) {
|
|
135
|
+
this.outbox.push(message);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
this.contentWindow()?.postMessage(message, this.cmsOrigin);
|
|
139
|
+
}
|
|
140
|
+
/** Reloads the embedded page. */
|
|
141
|
+
reload() {
|
|
142
|
+
if (this.closed) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
this.ready = false;
|
|
146
|
+
if (this.element) {
|
|
147
|
+
this.element.src = this.url;
|
|
148
|
+
} else if (this.window) {
|
|
149
|
+
this.window.location.href = this.url;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/** Closes the embedded window. Safe to call multiple times. */
|
|
153
|
+
close() {
|
|
154
|
+
if (this.closed) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
this.closed = true;
|
|
158
|
+
window.removeEventListener("message", this.onMessage);
|
|
159
|
+
if (this.pollTimer !== null) {
|
|
160
|
+
clearInterval(this.pollTimer);
|
|
161
|
+
this.pollTimer = null;
|
|
162
|
+
}
|
|
163
|
+
this.element?.remove();
|
|
164
|
+
if (this.window && !this.window.closed) {
|
|
165
|
+
this.window.close();
|
|
166
|
+
}
|
|
167
|
+
this.emitter.emit("close", void 0);
|
|
168
|
+
this.emitter.removeAll();
|
|
169
|
+
}
|
|
170
|
+
contentWindow() {
|
|
171
|
+
return this.element ? this.element.contentWindow : this.window;
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
// browser-client/browser-client.ts
|
|
176
|
+
function isDotSegment(segment) {
|
|
177
|
+
return segment === "." || segment === "..";
|
|
178
|
+
}
|
|
179
|
+
var EmbeddedEditor = class {
|
|
180
|
+
constructor(docId, embedWindow) {
|
|
181
|
+
this.docId = docId;
|
|
182
|
+
this.embedWindow = embedWindow;
|
|
183
|
+
}
|
|
184
|
+
/** The iframe element (iframe mode only). */
|
|
185
|
+
get element() {
|
|
186
|
+
return this.embedWindow.element;
|
|
187
|
+
}
|
|
188
|
+
/** The pop-up window (popup mode only). */
|
|
189
|
+
get window() {
|
|
190
|
+
return this.embedWindow.window;
|
|
191
|
+
}
|
|
192
|
+
/** Subscribes to an editor event. Returns an unsubscribe function. */
|
|
193
|
+
on(type, cb) {
|
|
194
|
+
return this.embedWindow.on(type, cb);
|
|
195
|
+
}
|
|
196
|
+
/** Scrolls the editor to (focuses) a field, e.g. `hero.title`. */
|
|
197
|
+
focusField(deepKey) {
|
|
198
|
+
const message = { scrollToDeeplink: { deepKey } };
|
|
199
|
+
this.embedWindow.post(message);
|
|
200
|
+
}
|
|
201
|
+
/** Reloads the embedded editor. */
|
|
202
|
+
reload() {
|
|
203
|
+
this.embedWindow.reload();
|
|
204
|
+
}
|
|
205
|
+
/** Closes the embedded editor, discarding any unsaved changes. */
|
|
206
|
+
close() {
|
|
207
|
+
this.embedWindow.close();
|
|
208
|
+
}
|
|
209
|
+
/** Closes the embedded editor and reloads the host page. */
|
|
210
|
+
closeAndReload() {
|
|
211
|
+
this.close();
|
|
212
|
+
window.location.reload();
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
var EmbeddedAI = class {
|
|
216
|
+
constructor(embedWindow) {
|
|
217
|
+
this.embedWindow = embedWindow;
|
|
218
|
+
}
|
|
219
|
+
/** The iframe element (iframe mode only). */
|
|
220
|
+
get element() {
|
|
221
|
+
return this.embedWindow.element;
|
|
222
|
+
}
|
|
223
|
+
/** The pop-up window (popup mode only). */
|
|
224
|
+
get window() {
|
|
225
|
+
return this.embedWindow.window;
|
|
226
|
+
}
|
|
227
|
+
/** Subscribes to an event. Returns an unsubscribe function. */
|
|
228
|
+
on(type, cb) {
|
|
229
|
+
return this.embedWindow.on(type, cb);
|
|
230
|
+
}
|
|
231
|
+
/** Reloads the embedded chat (starts a fresh chat). */
|
|
232
|
+
reload() {
|
|
233
|
+
this.embedWindow.reload();
|
|
234
|
+
}
|
|
235
|
+
/** Closes the embedded chat. */
|
|
236
|
+
close() {
|
|
237
|
+
this.embedWindow.close();
|
|
238
|
+
}
|
|
239
|
+
/** Closes the embedded chat and reloads the host page. */
|
|
240
|
+
closeAndReload() {
|
|
241
|
+
this.close();
|
|
242
|
+
window.location.reload();
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
var PreviewConnection = class {
|
|
246
|
+
constructor() {
|
|
247
|
+
this.emitter = new Emitter();
|
|
248
|
+
this.onMessage = (event) => {
|
|
249
|
+
if (event.origin !== window.location.origin) {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
if (!isHighlightNodeMessage(event.data)) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
const req = event.data.highlightNode;
|
|
256
|
+
this.emitter.emit("highlight", {
|
|
257
|
+
deepKey: req.deepKey,
|
|
258
|
+
scroll: req.options?.scroll ?? false
|
|
259
|
+
});
|
|
260
|
+
};
|
|
261
|
+
this.isEmbedded = RootCMSBrowserClient.isInPreviewIframe();
|
|
262
|
+
window.addEventListener("message", this.onMessage);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Requests that the doc editor scroll to (focus) a field, e.g.
|
|
266
|
+
* `hero.title`. Used to implement "click to edit".
|
|
267
|
+
*/
|
|
268
|
+
focusField(deepKey) {
|
|
269
|
+
if (window.parent === window) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
const message = { scrollToDeeplink: { deepKey } };
|
|
273
|
+
window.parent.postMessage(message, window.location.origin);
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Subscribes to field highlight requests from the doc editor (sent when the
|
|
277
|
+
* user hovers/focuses a field). Returns an unsubscribe function.
|
|
278
|
+
*/
|
|
279
|
+
on(type, cb) {
|
|
280
|
+
return this.emitter.on(type, cb);
|
|
281
|
+
}
|
|
282
|
+
/** Removes the message listener and all subscriptions. */
|
|
283
|
+
disconnect() {
|
|
284
|
+
window.removeEventListener("message", this.onMessage);
|
|
285
|
+
this.emitter.removeAll();
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
var RootCMSBrowserClient = class {
|
|
289
|
+
constructor(options) {
|
|
290
|
+
let url;
|
|
291
|
+
try {
|
|
292
|
+
url = new URL(options.cmsOrigin);
|
|
293
|
+
} catch {
|
|
294
|
+
throw new Error(
|
|
295
|
+
`invalid cmsOrigin: "${options?.cmsOrigin}" (expected e.g. "https://cms.example.com")`
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
299
|
+
throw new Error(
|
|
300
|
+
`invalid cmsOrigin: "${options?.cmsOrigin}" (expected an http(s) origin, e.g. "https://cms.example.com")`
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
this.cmsOrigin = url.origin;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Opens the headless doc editor for a doc (e.g. `Pages/about`) in a pop-up
|
|
307
|
+
* or iframe. In popup mode, call from a user gesture (e.g. a click handler)
|
|
308
|
+
* to avoid pop-up blockers.
|
|
309
|
+
*
|
|
310
|
+
* The slug portion of the docId is normalized the same way the CMS
|
|
311
|
+
* normalizes slugs, so a URL-like path also works, e.g. `Pages/about/foo`
|
|
312
|
+
* -> `Pages/about--foo`.
|
|
313
|
+
*/
|
|
314
|
+
openEditor(docId, options) {
|
|
315
|
+
const [collection, ...slugParts] = docId.split("/");
|
|
316
|
+
const slug = normalizeSlug(slugParts.join("/"));
|
|
317
|
+
if (!collection || !slug || isDotSegment(collection) || isDotSegment(slug)) {
|
|
318
|
+
throw new Error(
|
|
319
|
+
`invalid docId: "${docId}" (expected "<collection>/<slug>")`
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
const normalizedDocId = `${collection}/${slug}`;
|
|
323
|
+
const url = new URL(
|
|
324
|
+
`${this.cmsOrigin}/cms/embed/content/${encodeURIComponent(
|
|
325
|
+
collection
|
|
326
|
+
)}/${encodeURIComponent(slug)}`
|
|
327
|
+
);
|
|
328
|
+
if (options?.deeplink) {
|
|
329
|
+
url.searchParams.set("deeplink", options.deeplink);
|
|
330
|
+
}
|
|
331
|
+
const embedWindow = new EmbedWindow(
|
|
332
|
+
url.toString(),
|
|
333
|
+
this.cmsOrigin,
|
|
334
|
+
options
|
|
335
|
+
);
|
|
336
|
+
return new EmbeddedEditor(normalizedDocId, embedWindow);
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Opens the headless Root AI chat in a pop-up or iframe, optionally with a
|
|
340
|
+
* doc as context. In popup mode, call from a user gesture (e.g. a click
|
|
341
|
+
* handler) to avoid pop-up blockers.
|
|
342
|
+
*/
|
|
343
|
+
openRootAI(options) {
|
|
344
|
+
const url = new URL(`${this.cmsOrigin}/cms/embed/ai`);
|
|
345
|
+
if (options?.docId) {
|
|
346
|
+
url.searchParams.set("docId", options.docId);
|
|
347
|
+
}
|
|
348
|
+
const embedWindow = new EmbedWindow(
|
|
349
|
+
url.toString(),
|
|
350
|
+
this.cmsOrigin,
|
|
351
|
+
options
|
|
352
|
+
);
|
|
353
|
+
return new EmbeddedAI(embedWindow);
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Connects to the doc editor from a site rendered inside the in-CMS preview
|
|
357
|
+
* pane, enabling "click to edit" ({@link PreviewConnection.focusField}) and
|
|
358
|
+
* field highlighting (`on('highlight', ...)`).
|
|
359
|
+
*/
|
|
360
|
+
static connectPreview() {
|
|
361
|
+
return new PreviewConnection();
|
|
362
|
+
}
|
|
363
|
+
/** Returns whether this page is rendered inside the in-CMS preview pane. */
|
|
364
|
+
static isInPreviewIframe() {
|
|
365
|
+
if (window.parent === window) {
|
|
366
|
+
return false;
|
|
367
|
+
}
|
|
368
|
+
return document.referrer.startsWith(`${window.location.origin}/cms`);
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
export {
|
|
372
|
+
EmbeddedAI,
|
|
373
|
+
EmbeddedEditor,
|
|
374
|
+
PreviewConnection,
|
|
375
|
+
RootCMSBrowserClient,
|
|
376
|
+
SaveState
|
|
377
|
+
};
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
normalizeSlug
|
|
3
|
+
} from "./chunk-J72JK4KR.js";
|
|
4
|
+
|
|
1
5
|
// core/client.ts
|
|
2
6
|
import crypto from "node:crypto";
|
|
3
7
|
import {
|
|
@@ -5,11 +9,6 @@ import {
|
|
|
5
9
|
Timestamp as Timestamp2
|
|
6
10
|
} from "firebase-admin/firestore";
|
|
7
11
|
|
|
8
|
-
// shared/slug.ts
|
|
9
|
-
function normalizeSlug(slug) {
|
|
10
|
-
return slug.replace(/^[\s/]*/g, "").replace(/[\s/]*$/g, "").replace(/^\/+|\/+$/g, "").replaceAll("/", "--");
|
|
11
|
-
}
|
|
12
|
-
|
|
13
12
|
// core/translations-manager.ts
|
|
14
13
|
import {
|
|
15
14
|
FieldValue,
|
|
@@ -2432,7 +2431,6 @@ var BatchResponse = class {
|
|
|
2432
2431
|
};
|
|
2433
2432
|
|
|
2434
2433
|
export {
|
|
2435
|
-
normalizeSlug,
|
|
2436
2434
|
TranslationsManager,
|
|
2437
2435
|
buildTranslationsDbPath,
|
|
2438
2436
|
buildTranslationsLocaleDocDbPath,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SearchIndexService
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4VZTYUQ7.js";
|
|
4
4
|
import {
|
|
5
5
|
RootCMSClient,
|
|
6
6
|
getCmsPlugin
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-AFBSITEO.js";
|
|
8
8
|
|
|
9
9
|
// core/cron.ts
|
|
10
10
|
import { Timestamp as Timestamp2 } from "firebase-admin/firestore";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SearchIndexService
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4VZTYUQ7.js";
|
|
4
4
|
import {
|
|
5
5
|
normalizeSlug
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-J72JK4KR.js";
|
|
7
7
|
|
|
8
8
|
// core/ai.ts
|
|
9
9
|
import crypto from "node:crypto";
|
|
@@ -1198,7 +1198,7 @@ function extractJsonFromResponse(responseText) {
|
|
|
1198
1198
|
// package.json
|
|
1199
1199
|
var package_default = {
|
|
1200
1200
|
name: "@blinkk/root-cms",
|
|
1201
|
-
version: "3.
|
|
1201
|
+
version: "3.1.1",
|
|
1202
1202
|
author: "s@blinkk.com",
|
|
1203
1203
|
license: "MIT",
|
|
1204
1204
|
engines: {
|
|
@@ -1223,6 +1223,10 @@ var package_default = {
|
|
|
1223
1223
|
types: "./dist/core/core.d.ts",
|
|
1224
1224
|
import: "./dist/core.js"
|
|
1225
1225
|
},
|
|
1226
|
+
"./browser-client": {
|
|
1227
|
+
types: "./dist/browser-client/browser-client.d.ts",
|
|
1228
|
+
import: "./dist/browser-client.js"
|
|
1229
|
+
},
|
|
1226
1230
|
"./client": {
|
|
1227
1231
|
types: "./dist/core/client.d.ts",
|
|
1228
1232
|
import: "./dist/client.js"
|
|
@@ -1369,7 +1373,7 @@ var package_default = {
|
|
|
1369
1373
|
yjs: "13.6.27"
|
|
1370
1374
|
},
|
|
1371
1375
|
peerDependencies: {
|
|
1372
|
-
"@blinkk/root": "3.
|
|
1376
|
+
"@blinkk/root": "3.1.1",
|
|
1373
1377
|
"firebase-admin": ">=11",
|
|
1374
1378
|
"firebase-functions": ">=4"
|
|
1375
1379
|
},
|
package/dist/cli.js
CHANGED
package/dist/client.js
CHANGED
package/dist/core/client.d.ts
CHANGED
|
@@ -27,6 +27,11 @@ export interface Doc<Fields = any> {
|
|
|
27
27
|
until?: Timestamp;
|
|
28
28
|
};
|
|
29
29
|
locales?: string[];
|
|
30
|
+
/**
|
|
31
|
+
* Reverse index of asset library ids embedded in the doc's fields,
|
|
32
|
+
* (re)computed whenever the doc draft is saved in the CMS UI.
|
|
33
|
+
*/
|
|
34
|
+
assets?: string[];
|
|
30
35
|
};
|
|
31
36
|
fields: Fields;
|
|
32
37
|
}
|
package/dist/core.js
CHANGED
|
@@ -10,13 +10,15 @@ import {
|
|
|
10
10
|
marshalArray,
|
|
11
11
|
marshalData,
|
|
12
12
|
normalizeData,
|
|
13
|
-
normalizeSlug,
|
|
14
13
|
parseDocId,
|
|
15
14
|
toArrayObject,
|
|
16
15
|
translationsForLocale,
|
|
17
16
|
unmarshalArray,
|
|
18
17
|
unmarshalData
|
|
19
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-AFBSITEO.js";
|
|
19
|
+
import {
|
|
20
|
+
normalizeSlug
|
|
21
|
+
} from "./chunk-J72JK4KR.js";
|
|
20
22
|
import {
|
|
21
23
|
__export
|
|
22
24
|
} from "./chunk-MLKGABMK.js";
|
package/dist/functions.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runCronJobs
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-AJDMNTZQ.js";
|
|
4
|
+
import "./chunk-4VZTYUQ7.js";
|
|
5
|
+
import "./chunk-AFBSITEO.js";
|
|
6
|
+
import "./chunk-J72JK4KR.js";
|
|
6
7
|
import "./chunk-MLKGABMK.js";
|
|
7
8
|
|
|
8
9
|
// core/functions.ts
|
package/dist/plugin.js
CHANGED
|
@@ -13,18 +13,19 @@ import {
|
|
|
13
13
|
serializeAiConfig,
|
|
14
14
|
summarizeDiff,
|
|
15
15
|
translateString
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-GXV4UQ6Z.js";
|
|
17
17
|
import {
|
|
18
18
|
runCronJobs
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-AJDMNTZQ.js";
|
|
20
20
|
import {
|
|
21
21
|
SearchIndexService
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-4VZTYUQ7.js";
|
|
23
23
|
import {
|
|
24
24
|
RootCMSClient,
|
|
25
25
|
parseDocId,
|
|
26
26
|
unmarshalData
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-AFBSITEO.js";
|
|
28
|
+
import "./chunk-J72JK4KR.js";
|
|
28
29
|
import "./chunk-MLKGABMK.js";
|
|
29
30
|
|
|
30
31
|
// core/plugin.ts
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire protocol for the postMessage channels between the Root CMS UI and
|
|
3
|
+
* pages that embed it (or are embedded by it). This file IS the wire
|
|
4
|
+
* protocol: any change here must remain compatible with already-deployed CMS
|
|
5
|
+
* servers and published versions of `@blinkk/root-cms/browser-client`.
|
|
6
|
+
*
|
|
7
|
+
* Channels:
|
|
8
|
+
* - Embedded ("headless") pages -> parent window: lifecycle messages,
|
|
9
|
+
* namespaced under `root` ({@link RootEmbedMessage}).
|
|
10
|
+
* - Parent window -> doc editor: field focus requests
|
|
11
|
+
* ({@link ScrollToDeeplinkMessage}).
|
|
12
|
+
* - Doc editor -> in-CMS preview iframe: field highlight requests
|
|
13
|
+
* ({@link HighlightNodeMessage}).
|
|
14
|
+
*
|
|
15
|
+
* The `scrollToDeeplink` / `highlightNode` messages predate the `root`
|
|
16
|
+
* namespace and are intentionally left un-namespaced for compatibility.
|
|
17
|
+
*/
|
|
18
|
+
/** Save state of the draft doc. */
|
|
19
|
+
export declare enum SaveState {
|
|
20
|
+
NO_CHANGES = "NO_CHANGES",
|
|
21
|
+
UPDATES_PENDING = "UPDATE_PENDING",
|
|
22
|
+
SAVING = "SAVING",
|
|
23
|
+
SAVED = "SAVED",
|
|
24
|
+
ERROR = "ERROR"
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Lifecycle messages posted from the headless (embedded) pages (the doc
|
|
28
|
+
* editor and the Root AI panel) to the parent window that frames them. All
|
|
29
|
+
* messages are namespaced under `root` to avoid colliding with the
|
|
30
|
+
* un-namespaced `{scrollToDeeplink}` / `{highlightNode}` messages used by the
|
|
31
|
+
* in-CMS preview channel.
|
|
32
|
+
*/
|
|
33
|
+
export interface RootEmbedMessage {
|
|
34
|
+
root: {
|
|
35
|
+
/** The lifecycle event type. */
|
|
36
|
+
type: 'ready' | 'saved' | 'published' | 'error';
|
|
37
|
+
/** The doc being edited, e.g. "Pages/about" (when applicable). */
|
|
38
|
+
docId?: string;
|
|
39
|
+
/** Current save state (included on `saved`). */
|
|
40
|
+
saveState?: SaveState;
|
|
41
|
+
/** Epoch millis the doc was published (included on `published`). */
|
|
42
|
+
publishedAt?: number;
|
|
43
|
+
/** Error message (included on `error`). */
|
|
44
|
+
error?: string;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/** Requests that the doc editor scroll to (focus) a specific field. */
|
|
48
|
+
export interface ScrollToDeeplinkMessage {
|
|
49
|
+
scrollToDeeplink: {
|
|
50
|
+
/** The deep key of the field to scroll to, e.g. "hero.title". */
|
|
51
|
+
deepKey: string;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Requests that the preview page highlight the node associated with a field.
|
|
56
|
+
* A `null` deepKey clears all highlights.
|
|
57
|
+
*/
|
|
58
|
+
export interface HighlightNodeMessage {
|
|
59
|
+
highlightNode: {
|
|
60
|
+
deepKey: string | null;
|
|
61
|
+
options?: {
|
|
62
|
+
/** Whether to scroll to the node in the preview. */
|
|
63
|
+
scroll: boolean;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/** Returns whether a postMessage payload is a {@link RootEmbedMessage}. */
|
|
68
|
+
export declare function isRootEmbedMessage(data: unknown): data is RootEmbedMessage;
|
|
69
|
+
/** Returns whether a postMessage payload is a {@link ScrollToDeeplinkMessage}. */
|
|
70
|
+
export declare function isScrollToDeeplinkMessage(data: unknown): data is ScrollToDeeplinkMessage;
|
|
71
|
+
/** Returns whether a postMessage payload is a {@link HighlightNodeMessage}. */
|
|
72
|
+
export declare function isHighlightNodeMessage(data: unknown): data is HighlightNodeMessage;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as o}from"./chunk-2KSMCQ6H.js";import"./chunk-HO3W4RVG.js";import"./chunk-3T4ZWQR4.js";import"./chunk-E76ECIOX.js";import"./chunk-344GZOGG.js";import"./chunk-YDO2EDVY.js";import"./chunk-5MV6XVGA.js";import{a as i}from"./chunk-FFHV5S6A.js";import{a}from"./chunk-P2Z66DHV.js";import"./chunk-FSVNOZ6F.js";import"./chunk-VD6G5NV4.js";import"./chunk-YLSRRNSE.js";import{Ga as t}from"./chunk-LROR6N3B.js";import"./chunk-KUCVLANF.js";import"./chunk-7SK47HHZ.js";import"./chunk-DTMZLUNY.js";import"./chunk-PVAE643M.js";function n(r){return a("AI"),t(i,{children:t(o,{variant:"page",initialChatId:r.chatId})})}export{n as AIPage};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as p}from"./chunk-U7PWJV6F.js";import{a as i}from"./chunk-5AVRMJVW.js";import"./chunk-MZTOPPWQ.js";import"./chunk-CAY5NM4Z.js";import{a as n}from"./chunk-XT5FNJCX.js";import"./chunk-TFB3VGWP.js";import"./chunk-ZN2Y5OUF.js";import"./chunk-W5DOO6ID.js";import"./chunk-NSOTG64N.js";import"./chunk-J5E457OI.js";import"./chunk-QHJOTXYB.js";import{a as d}from"./chunk-O5P3CPJ4.js";import"./chunk-KRNQ6L35.js";import{a as g}from"./chunk-FFHV5S6A.js";import{a as m}from"./chunk-P2Z66DHV.js";import"./chunk-FSVNOZ6F.js";import"./chunk-VD6G5NV4.js";import{d as o}from"./chunk-YLSRRNSE.js";import{Ga as e,a as t,c as r,j as h}from"./chunk-LROR6N3B.js";import"./chunk-KUCVLANF.js";import"./chunk-7SK47HHZ.js";import"./chunk-DTMZLUNY.js";import"./chunk-PVAE643M.js";h();function k(){m("Asset Library");let[l,u]=p("folder",""),{query:c,route:f}=o(),[a]=t(c.asset||"");return r(()=>{if(a){let s=new URL(window.location.href);s.searchParams.delete("asset"),f(s.pathname+s.search,!0)}},[]),e(g,{children:e("div",{className:"AssetsPage","data-testid":"assets-page",children:[e("div",{className:"AssetsPage__header",children:[e(n,{size:"h1",children:"Asset Library"}),e(d,{as:"p",children:"The asset library can be used to store and organize files used throughout the project. Replacing a file in the asset library automatically updates all draft docs that use it (requires re-publishing)."})]}),e(i,{className:"AssetsPage__browser",mode:"manage",folder:l,onFolderChange:u,initialAssetId:a})]})})}export{k as AssetsPage};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as j}from"./chunk-B6M55OFE.js";import{a as U}from"./chunk-SRX7EWL4.js";import{h as B}from"./chunk-TDUBSLEC.js";import{a as z,e as A,j as E}from"./chunk-OWQL5DVE.js";import"./chunk-JTIQBW33.js";import{c as O,e as I}from"./chunk-R6B3W5AJ.js";import"./chunk-AZCGXQTL.js";import{a as w}from"./chunk-FJLNXXE3.js";import{a as P}from"./chunk-76ZGLKLT.js";import"./chunk-D3UIZHRK.js";import"./chunk-HARRKJFZ.js";import"./chunk-JS6TK4OP.js";import"./chunk-JDW4UORS.js";import"./chunk-YDO2EDVY.js";import{b as h}from"./chunk-5MV6XVGA.js";import"./chunk-TFB3VGWP.js";import"./chunk-ZN2Y5OUF.js";import{b as S}from"./chunk-W5DOO6ID.js";import{a as D}from"./chunk-NSOTG64N.js";import"./chunk-J5E457OI.js";import"./chunk-QHJOTXYB.js";import"./chunk-O5P3CPJ4.js";import"./chunk-KRNQ6L35.js";import{a as $}from"./chunk-FFHV5S6A.js";import{a as R}from"./chunk-P2Z66DHV.js";import"./chunk-FSVNOZ6F.js";import"./chunk-VD6G5NV4.js";import{d as k}from"./chunk-YLSRRNSE.js";import{Ca as L,Ga as o,V as y,a as x,c as T,cb as u,da as C,j as M,za as N}from"./chunk-LROR6N3B.js";import{d as f}from"./chunk-KUCVLANF.js";import"./chunk-7SK47HHZ.js";import"./chunk-DTMZLUNY.js";import"./chunk-PVAE643M.js";M();function p(e){let{route:i}=k(),l=window.__ROOT_CTX.rootConfig.projectId;R(e.collection?e.collection:"Content"),T(()=>{let a=window.__ROOT_CTX.collections,s=`root-cms::${l}::last_collection`;if(e.collection)window.localStorage.setItem(s,e.collection);else{let t=window.localStorage.getItem(s);if(t&&a[t]){i(`/cms/content/${t}`);return}if(window.__ROOT_CTX.collections.Pages){i("/cms/content/Pages");return}let _=Object.keys(window.__ROOT_CTX.collections)||[];if(_.length>0){let d=_[0];i(`/cms/content/${d}`);return}console.warn("no collections")}},[e.collection,l]);let n=window.__ROOT_CTX.collections;return o($,{children:o("div",{className:"CollectionPage",children:o("div",{className:"CollectionPage__layout",children:[o("div",{className:"CollectionPage__side",children:o(j,{collections:n,activeCollectionId:e.collection,projectId:l})}),o("div",{className:"CollectionPage__main",children:e.collection&&o(p.Collection,{collection:e.collection},e.collection)})]})})})}p.Collection=e=>{let{roles:i}=D(),l=window.firebase.user.email||"",n=S(i,l),[a,s]=w(`root::CollectionPage:${e.collection}:orderBy`,"modifiedAt"),[t,_]=w(`root::CollectionPage:${e.collection}:showArchived`,!1),[d,r]=x(!1),m=window.__ROOT_CTX.collections[e.collection];if(!m)return route("/cms/content"),o(f,{});let v=[{value:"slug",label:"A-Z"},{value:"slugDesc",label:"Z-A"},{value:"newest",label:"Newest"},{value:"oldest",label:"Oldest"},{value:"modifiedAt",label:"Last modified"},...m.sortOptions?.map(g=>({value:g.id,label:g.label}))||[]],[c,X,b]=A(e.collection,{orderBy:a,includeArchived:t});return o(f,{children:[o(E,{collection:e.collection,opened:d,onClose:()=>r(!1)}),o("div",{className:"CollectionPage__collection",children:o("div",{className:"CollectionPage__collection__docsTab",children:[!c&&o("div",{className:"CollectionPage__collection__docsTab__header",children:[o("div",{className:"CollectionPage__collection__docsTab__header__title",children:m.name||e.collection}),o("div",{className:"CollectionPage__collection__docsTab__controls",children:[o("div",{className:"CollectionPage__collection__docsTab__controls__showArchived",children:o(L,{size:"sm",color:"dark",label:"Show archived:",checked:t,onChange:g=>_(!!g.currentTarget.checked)})}),o("div",{className:"CollectionPage__collection__docsTab__controls__sort",children:[o("div",{className:"CollectionPage__collection__docsTab__controls__sort__label",children:"Sort:"}),o(N,{size:"xs",value:a,onChange:g=>s(g||"modifiedAt"),data:v})]}),o("div",{className:"CollectionPage__collection__docsTab__controls__newDoc",children:o(P,{label:"You don't have access to create new documents",condition:!n,children:o(C,{color:"dark",size:"xs",leftIcon:o(u,{size:16}),onClick:()=>r(!0),disabled:!n,children:"New"})})})]})]}),o(U,{className:"CollectionPage__collection__docsTab__content",children:c?o("div",{className:"CollectionPage__collection__docsTab__content__loading",children:o(y,{color:"gray",size:"xl"})}):b.length===0?o("div",{class:"CollectionPage__collection__docsEmpty",children:[o("div",{class:"CollectionPage__collection__docsEmpty__title",children:"Collection is empty."}),o("div",{class:"CollectionPage__collection__docsEmpty__button",children:o(P,{label:"You don't have access to create new documents",condition:!n,children:o(C,{color:"dark",size:"xs",leftIcon:o(u,{size:16}),onClick:()=>r(!0),disabled:!n,children:"New"})})})]}):o(p.DocsList,{collection:e.collection,docs:b,reloadDocs:()=>X()})})]})})]})};p.DocsList=e=>{let i=e.collection,l=window.__ROOT_CTX.collections[e.collection];if(!l)throw new Error(`could not find collection: ${i}`);let n=!!l.url,a=e.docs||[];function s(t){return n?z({collectionId:i,slug:t}):""}return o("div",{className:"CollectionPage__collection__docsList",children:a.map(t=>{let _=`/cms/content/${i}/${t.slug}`,d=s(t.slug),r=t.fields||{},m=h(r,l.preview?.title||"meta.title"),v=h(r,l.preview?.image||"meta.image")||l.preview?.defaultImage;return o("div",{className:"CollectionPage__collection__docsList__doc",children:[o("div",{className:"CollectionPage__collection__docsList__doc__image",children:o("a",{href:_,children:o(I,{file:v,width:120,height:90,withPlaceholder:!v?.src})})}),o("a",{className:"CollectionPage__collection__docsList__doc__content",href:_,children:[o("div",{className:"CollectionPage__collection__docsList__doc__content__header",children:[o("div",{className:"CollectionPage__collection__docsList__doc__content__header__docId",children:t.id}),o(O,{doc:t})]}),o("div",{className:"CollectionPage__collection__docsList__doc__content__title",children:m||"[UNTITLED]"}),n&&d&&o("div",{className:"CollectionPage__collection__docsList__doc__content__url",children:d})]}),o("div",{className:"CollectionPage__collection__docsList__doc__controls",children:o(B,{docId:t.id,data:t,onAction:c=>{(c.action==="archive"||c.action==="copy"||c.action==="unarchive"||c.action==="delete"||c.action==="unpublish"||c.action==="locked"||c.action==="unlocked")&&e.reloadDocs()}})})]},t.id)})})};export{p as CollectionPage};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{b as s}from"./chunk-QEE7XS6O.js";import"./chunk-3T4ZWQR4.js";import"./chunk-E76ECIOX.js";import"./chunk-5MV6XVGA.js";import"./chunk-TFB3VGWP.js";import"./chunk-ZN2Y5OUF.js";import"./chunk-O5P3CPJ4.js";import"./chunk-KRNQ6L35.js";import{a as m}from"./chunk-FFHV5S6A.js";import{a as d}from"./chunk-P2Z66DHV.js";import"./chunk-FSVNOZ6F.js";import"./chunk-VD6G5NV4.js";import{d as t}from"./chunk-YLSRRNSE.js";import{Ga as a,g as i,j as p}from"./chunk-LROR6N3B.js";import"./chunk-KUCVLANF.js";import"./chunk-7SK47HHZ.js";import"./chunk-DTMZLUNY.js";import"./chunk-PVAE643M.js";p();function h(){let{query:r}=t();d("Compare");let o=i(()=>n(r.left||""),[r.left]),e=i(()=>n(r.right||""),[r.right]);return a(m,{children:a("div",{className:"ComparePage",children:o&&e?a(s,{className:"ComparePage__diff",left:o,right:e}):a("div",{className:"ComparePage__error",children:"Invalid params, double check query params."})})})}function n(r){let[o,e]=String(r).split("@");return o&&e?{docId:o,versionId:e}:null}export{h as ComparePage};
|