@webx-ui/module-press 0.1.16 → 0.2.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/dist/PressPage-9Ghxpuqd.js +327 -0
- package/dist/PressPage-9Ghxpuqd.js.map +1 -0
- package/dist/index-C6NYJ0-x.js +349 -0
- package/dist/index-C6NYJ0-x.js.map +1 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.js +8 -654
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
import { defineComponent as Q, ref as h, computed as p, onMounted as X, onBeforeUnmount as Z, openBlock as x, createElementBlock as C, createBlock as R, unref as u, Fragment as ee, createVNode as y, createSlots as te, withCtx as b, createTextVNode as K, toDisplayString as U, createCommentVNode as ae, defineAsyncComponent as oe } from "vue";
|
|
2
|
+
import { reorderItems as le, useAdmin as z, useTranslate as ne, useErrorText as se, provideRecordAddress as re, useBodyKeys as ie, WxScreenHead as ue, WxScreen as ce, WxSaveState as de } from "@webx-ui/module-admin";
|
|
3
|
+
import { onBeforeRouteUpdate as he, onBeforeRouteLeave as pe } from "vue-router";
|
|
4
|
+
import { useLocales as ve, localizedValue as fe, WxSkeleton as me, WxBadge as ge, WxActionBar as we, WxButton as ye, toast as f, confirm as V } from "@webx-ui/core";
|
|
5
|
+
function Be(o = {}) {
|
|
6
|
+
const s = o.path ?? "/press";
|
|
7
|
+
return {
|
|
8
|
+
id: "press",
|
|
9
|
+
path: s,
|
|
10
|
+
// One route: the open outlet is in the address (`?outlet=`), beside the list it was opened
|
|
11
|
+
// from, so a link to it is a link to both.
|
|
12
|
+
routes: [
|
|
13
|
+
{
|
|
14
|
+
path: s,
|
|
15
|
+
name: "webx.press",
|
|
16
|
+
component: () => import("./PressPage-9Ghxpuqd.js"),
|
|
17
|
+
props: { base: s }
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const M = "press";
|
|
23
|
+
function be(o) {
|
|
24
|
+
const s = `${o.apiPath}/${M}`, l = (t) => t.data;
|
|
25
|
+
return {
|
|
26
|
+
list: (t = {}) => {
|
|
27
|
+
const i = new URLSearchParams();
|
|
28
|
+
return t.search && i.set("search", t.search), t.trashed && i.set("trashed", "1"), o.http.get(i.size > 0 ? `${s}?${i}` : s);
|
|
29
|
+
},
|
|
30
|
+
get: (t) => o.http.get(`${s}/${t}`).then(l),
|
|
31
|
+
create: (t) => o.http.post(s, { values: t }).then(l),
|
|
32
|
+
save: (t, i) => o.http.put(`${s}/${t}`, { values: i }).then(l),
|
|
33
|
+
remove: (t) => o.http.delete(`${s}/${t}`).then(() => {
|
|
34
|
+
}),
|
|
35
|
+
// The resource of the list line, and not the form's answer: a restored outlet stays closed.
|
|
36
|
+
restore: (t) => o.http.post(`${s}/${t}/restore`, {}).then(l),
|
|
37
|
+
reorder: (t) => le(o, M, t, null)
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
const ke = {
|
|
41
|
+
module: {
|
|
42
|
+
press: "Press"
|
|
43
|
+
},
|
|
44
|
+
outlet: {
|
|
45
|
+
new: "New outlet",
|
|
46
|
+
untitled: "Untitled",
|
|
47
|
+
search: "Search the outlets",
|
|
48
|
+
empty: "No outlets yet.",
|
|
49
|
+
"empty-help": "An outlet is a magazine, a paper or a site that wrote about you; its articles are added on its form.",
|
|
50
|
+
"empty-search": "Nothing matches that.",
|
|
51
|
+
"empty-bin": "The bin is empty.",
|
|
52
|
+
all: "All",
|
|
53
|
+
trashed: "Bin",
|
|
54
|
+
"not-published": "Not published",
|
|
55
|
+
"visible-nowhere": "Published, but seen in no language: none of its articles has a title yet.",
|
|
56
|
+
"articles-count": "Articles: :count",
|
|
57
|
+
"no-articles": "No articles yet",
|
|
58
|
+
featured: "In the logo strip",
|
|
59
|
+
"seen-in": "Seen in: :locales",
|
|
60
|
+
choose: "Choose an outlet",
|
|
61
|
+
"choose-help": "Or add a new one: the first line of the list.",
|
|
62
|
+
save: "Save",
|
|
63
|
+
saved: "The outlet is saved.",
|
|
64
|
+
"save-failed": "The outlet was not saved.",
|
|
65
|
+
cancel: "Cancel",
|
|
66
|
+
delete: "Delete",
|
|
67
|
+
"delete-title": "Delete “:name”?",
|
|
68
|
+
"delete-text": "It goes to the bin with its articles and leaves the site and every block. Restored, it comes back with them.",
|
|
69
|
+
deleted: "The outlet is in the bin.",
|
|
70
|
+
restore: "Restore",
|
|
71
|
+
restored: "The outlet is back.",
|
|
72
|
+
"reorder-failed": "The new order was not saved.",
|
|
73
|
+
"leave-title": "Leave without saving?",
|
|
74
|
+
"leave-text": "What you wrote in this outlet is not on the server.",
|
|
75
|
+
leave: "Leave",
|
|
76
|
+
back: "Back to the list",
|
|
77
|
+
open: "Open on the site",
|
|
78
|
+
"address-moving": "The page of the outlet moves to the new address when you save."
|
|
79
|
+
},
|
|
80
|
+
screen: {
|
|
81
|
+
general: "General",
|
|
82
|
+
outlet: "Outlet",
|
|
83
|
+
logo: "Logo",
|
|
84
|
+
"logo-help": "Without a logo the site prints the name.",
|
|
85
|
+
title: "Name",
|
|
86
|
+
"title-help": "Where it is not written in a language, the name from another one is shown.",
|
|
87
|
+
slug: "Address",
|
|
88
|
+
"slug-help": "The outlet's page. A language with articles and no address of its own takes this one.",
|
|
89
|
+
"website-url": "Website",
|
|
90
|
+
"website-url-help": "An address that starts with http:// or https://.",
|
|
91
|
+
summary: "About the outlet",
|
|
92
|
+
"summary-help": "A few words under the name on its page, and its description for search engines.",
|
|
93
|
+
settings: "Settings",
|
|
94
|
+
published: "Published",
|
|
95
|
+
"published-help": "On the site at once — in the languages it has articles in.",
|
|
96
|
+
featured: "In the strip of logos",
|
|
97
|
+
"featured-help": "Shown by the logos block set to the marked outlets only.",
|
|
98
|
+
articles: "Articles",
|
|
99
|
+
"articles-help": "In the order they are shown on the outlet's page. Saved with the outlet.",
|
|
100
|
+
"article-label": "#:number · :title",
|
|
101
|
+
"article-untitled": "Untitled",
|
|
102
|
+
"article-title": "Title",
|
|
103
|
+
"article-title-help": "An article is shown in a language only when it has a title in it.",
|
|
104
|
+
excerpt: "Excerpt",
|
|
105
|
+
kind: "Kind",
|
|
106
|
+
"kind-none": "No kind",
|
|
107
|
+
"published-on": "Date",
|
|
108
|
+
"date-precision": "Known to",
|
|
109
|
+
"date-precision-help": "How much of the date is printed: the day, the month, or the year only.",
|
|
110
|
+
precision: {
|
|
111
|
+
day: "Day",
|
|
112
|
+
month: "Month",
|
|
113
|
+
year: "Year"
|
|
114
|
+
},
|
|
115
|
+
url: "Link",
|
|
116
|
+
"url-help": "The article on the outlet's site. Without it the title leads to the PDF.",
|
|
117
|
+
file: "PDF",
|
|
118
|
+
"file-help": "A PDF from the library — a scan of the page, say.",
|
|
119
|
+
hidden: "Do not show",
|
|
120
|
+
"hidden-help": "Kept here, and shown nowhere on the site.",
|
|
121
|
+
seo: "SEO",
|
|
122
|
+
"seo-empty": "The SEO card appears here when module-seo is installed."
|
|
123
|
+
},
|
|
124
|
+
kinds: {
|
|
125
|
+
mention: "Mention",
|
|
126
|
+
interview: "Interview",
|
|
127
|
+
expert_comment: "Expert comment",
|
|
128
|
+
authored: "Authored article"
|
|
129
|
+
}
|
|
130
|
+
}, F = /* @__PURE__ */ new WeakSet();
|
|
131
|
+
function xe() {
|
|
132
|
+
try {
|
|
133
|
+
const { i18n: o } = z();
|
|
134
|
+
F.has(o) || (o.defaults("webx-press", ke), F.add(o));
|
|
135
|
+
} catch {
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const Se = /* @__PURE__ */ Q({
|
|
139
|
+
name: "WxOutletPane",
|
|
140
|
+
__name: "OutletPane",
|
|
141
|
+
props: {
|
|
142
|
+
id: {},
|
|
143
|
+
inline: { type: Boolean, default: !0 }
|
|
144
|
+
},
|
|
145
|
+
emits: ["back", "saved", "created", "removed"],
|
|
146
|
+
setup(o, { emit: s }) {
|
|
147
|
+
const l = o, t = s, i = z(), k = be(i), S = ve();
|
|
148
|
+
xe();
|
|
149
|
+
const n = ne("webx-press"), A = se(), d = h(null), c = h({}), B = h(null), m = h(""), P = h(l.id !== null), v = h(!1), T = h({}), g = p(() => i.can("press.manage")), O = p(() => JSON.stringify(c.value)), w = p(() => m.value !== "" && O.value !== m.value), J = p(() => v.value ? "saving" : w.value || l.id === null ? "unsaved" : "saved"), G = p(() => {
|
|
150
|
+
const e = c.value.title, a = l.id === null ? n("outlet.new") : d.value?.title ?? "";
|
|
151
|
+
return fe(e, S.active.value, a) || n("outlet.untitled");
|
|
152
|
+
});
|
|
153
|
+
re({
|
|
154
|
+
values: c,
|
|
155
|
+
prefix: B,
|
|
156
|
+
path: p(() => H(d.value?.url ?? null, S.active.value)),
|
|
157
|
+
moving: () => n("outlet.address-moving")
|
|
158
|
+
});
|
|
159
|
+
function H(e, a) {
|
|
160
|
+
if (e === null) return null;
|
|
161
|
+
let r;
|
|
162
|
+
try {
|
|
163
|
+
r = new URL(e, "http://site.invalid").pathname.split("/").filter((W) => W !== "");
|
|
164
|
+
} catch {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
const _ = S.list.value.map((W) => W.code), I = _.includes(r[0] ?? "") && r[0] !== _[0] ? r.shift() : _[0];
|
|
168
|
+
return I === void 0 || I === a ? r.join("/") : void 0;
|
|
169
|
+
}
|
|
170
|
+
function N(e) {
|
|
171
|
+
d.value = e.outlet, c.value = e.values, B.value = e.prefix, m.value = JSON.stringify(e.values);
|
|
172
|
+
}
|
|
173
|
+
if (l.id === null) {
|
|
174
|
+
const e = {
|
|
175
|
+
title: {},
|
|
176
|
+
slug: {},
|
|
177
|
+
summary: {},
|
|
178
|
+
published: !1,
|
|
179
|
+
featured: !1,
|
|
180
|
+
articles: []
|
|
181
|
+
};
|
|
182
|
+
c.value = e, m.value = JSON.stringify(e);
|
|
183
|
+
}
|
|
184
|
+
async function j() {
|
|
185
|
+
if (l.id !== null) {
|
|
186
|
+
P.value = !0;
|
|
187
|
+
try {
|
|
188
|
+
N(await k.get(l.id));
|
|
189
|
+
} catch (e) {
|
|
190
|
+
f.danger(A(e)), t("back");
|
|
191
|
+
} finally {
|
|
192
|
+
P.value = !1;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
async function $() {
|
|
197
|
+
if (!(v.value || !g.value)) {
|
|
198
|
+
v.value = !0, T.value = {};
|
|
199
|
+
try {
|
|
200
|
+
const e = l.id === null, a = e ? await k.create(c.value) : await k.save(l.id, c.value);
|
|
201
|
+
N(a), f.success(n("outlet.saved")), t(e ? "created" : "saved", a.outlet);
|
|
202
|
+
} catch (e) {
|
|
203
|
+
const a = e.body;
|
|
204
|
+
a?.errors ? (T.value = a.errors, f.danger(n("outlet.save-failed"))) : f.danger(A(e));
|
|
205
|
+
} finally {
|
|
206
|
+
v.value = !1;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
async function Y() {
|
|
211
|
+
const e = d.value;
|
|
212
|
+
if (!(!e || !await V({
|
|
213
|
+
title: n("outlet.delete-title", { name: e.title }),
|
|
214
|
+
message: n("outlet.delete-text"),
|
|
215
|
+
confirmText: n("outlet.delete"),
|
|
216
|
+
cancelText: n("outlet.cancel"),
|
|
217
|
+
tone: "danger"
|
|
218
|
+
})))
|
|
219
|
+
try {
|
|
220
|
+
await k.remove(e.id), f.success(n("outlet.deleted")), m.value = O.value, t("removed", e.id);
|
|
221
|
+
} catch (r) {
|
|
222
|
+
f.danger(A(r));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
function L(e) {
|
|
226
|
+
w.value && e.preventDefault();
|
|
227
|
+
}
|
|
228
|
+
function D(e) {
|
|
229
|
+
(e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "s" && (e.preventDefault(), (w.value || l.id === null) && $());
|
|
230
|
+
}
|
|
231
|
+
ie(D), X(() => {
|
|
232
|
+
j(), window.addEventListener("beforeunload", L);
|
|
233
|
+
}), Z(() => {
|
|
234
|
+
window.removeEventListener("beforeunload", L);
|
|
235
|
+
});
|
|
236
|
+
async function E() {
|
|
237
|
+
return !w.value || !g.value ? !0 : await V({
|
|
238
|
+
title: n("outlet.leave-title"),
|
|
239
|
+
message: n("outlet.leave-text"),
|
|
240
|
+
confirmText: n("outlet.leave"),
|
|
241
|
+
cancelText: n("outlet.cancel"),
|
|
242
|
+
tone: "danger"
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
he(
|
|
246
|
+
async (e, a) => e.query.outlet === a.query.outlet ? !0 : await E()
|
|
247
|
+
), pe(E);
|
|
248
|
+
const q = p(() => {
|
|
249
|
+
const e = d.value, a = [];
|
|
250
|
+
if (e?.url) {
|
|
251
|
+
const r = e.url;
|
|
252
|
+
a.push({
|
|
253
|
+
key: "open",
|
|
254
|
+
label: n("outlet.open"),
|
|
255
|
+
icon: "external-link",
|
|
256
|
+
run: () => {
|
|
257
|
+
window.open(r, "_blank", "noopener");
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
return g.value && e !== null && a.push({
|
|
262
|
+
key: "delete",
|
|
263
|
+
label: n("outlet.delete"),
|
|
264
|
+
icon: "trash",
|
|
265
|
+
danger: !0,
|
|
266
|
+
menu: !0,
|
|
267
|
+
run: () => {
|
|
268
|
+
Y();
|
|
269
|
+
}
|
|
270
|
+
}), a;
|
|
271
|
+
});
|
|
272
|
+
return (e, a) => (x(), C("div", {
|
|
273
|
+
class: "wx-outlet",
|
|
274
|
+
onKeydown: D
|
|
275
|
+
}, [
|
|
276
|
+
P.value ? (x(), R(u(me), {
|
|
277
|
+
key: 0,
|
|
278
|
+
class: "wx-outlet__ghost",
|
|
279
|
+
title: "",
|
|
280
|
+
rows: 6
|
|
281
|
+
})) : (x(), C(ee, { key: 1 }, [
|
|
282
|
+
y(u(ue), {
|
|
283
|
+
level: 3,
|
|
284
|
+
back: !l.inline,
|
|
285
|
+
"back-label": u(n)("outlet.back"),
|
|
286
|
+
title: G.value,
|
|
287
|
+
actions: q.value,
|
|
288
|
+
"collapse-below": 480,
|
|
289
|
+
onBack: a[0] || (a[0] = (r) => t("back"))
|
|
290
|
+
}, te({ _: 2 }, [
|
|
291
|
+
d.value && !d.value.published ? {
|
|
292
|
+
name: "title-after",
|
|
293
|
+
fn: b(() => [
|
|
294
|
+
y(u(ge), { dot: "" }, {
|
|
295
|
+
default: b(() => [
|
|
296
|
+
K(U(u(n)("outlet.not-published")), 1)
|
|
297
|
+
]),
|
|
298
|
+
_: 1
|
|
299
|
+
})
|
|
300
|
+
]),
|
|
301
|
+
key: "0"
|
|
302
|
+
} : void 0
|
|
303
|
+
]), 1032, ["back", "back-label", "title", "actions"]),
|
|
304
|
+
y(u(ce), {
|
|
305
|
+
modelValue: c.value,
|
|
306
|
+
"onUpdate:modelValue": a[1] || (a[1] = (r) => c.value = r),
|
|
307
|
+
name: "press.outlet-form",
|
|
308
|
+
errors: T.value,
|
|
309
|
+
disabled: !g.value || v.value
|
|
310
|
+
}, null, 8, ["modelValue", "errors", "disabled"]),
|
|
311
|
+
g.value ? (x(), R(u(we), { key: 0 }, {
|
|
312
|
+
state: b(() => [
|
|
313
|
+
y(u(de), { state: J.value }, null, 8, ["state"])
|
|
314
|
+
]),
|
|
315
|
+
default: b(() => [
|
|
316
|
+
y(u(ye), {
|
|
317
|
+
type: "primary",
|
|
318
|
+
loading: v.value,
|
|
319
|
+
disabled: !w.value && l.id !== null,
|
|
320
|
+
onClick: $
|
|
321
|
+
}, {
|
|
322
|
+
default: b(() => [
|
|
323
|
+
K(U(u(n)("outlet.save")), 1)
|
|
324
|
+
]),
|
|
325
|
+
_: 1
|
|
326
|
+
}, 8, ["loading", "disabled"])
|
|
327
|
+
]),
|
|
328
|
+
_: 1
|
|
329
|
+
})) : ae("", !0)
|
|
330
|
+
], 64))
|
|
331
|
+
], 32));
|
|
332
|
+
}
|
|
333
|
+
}), Ae = (o, s) => {
|
|
334
|
+
const l = o.__vccOpts || o;
|
|
335
|
+
for (const [t, i] of s)
|
|
336
|
+
l[t] = i;
|
|
337
|
+
return l;
|
|
338
|
+
}, Oe = /* @__PURE__ */ Ae(Se, [["__scopeId", "data-v-b6ea9c8f"]]), Ne = oe(() => import("./PressPage-9Ghxpuqd.js"));
|
|
339
|
+
export {
|
|
340
|
+
Oe as O,
|
|
341
|
+
M as P,
|
|
342
|
+
Ne as W,
|
|
343
|
+
Ae as _,
|
|
344
|
+
ke as a,
|
|
345
|
+
be as c,
|
|
346
|
+
Be as p,
|
|
347
|
+
xe as u
|
|
348
|
+
};
|
|
349
|
+
//# sourceMappingURL=index-C6NYJ0-x.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-C6NYJ0-x.js","sources":["../src/module.ts","../src/api.ts","../src/messages.ts","../src/i18n.ts","../src/OutletPane.vue","../src/index.ts"],"sourcesContent":["import type { AdminModule } from '@webx-ui/module-admin'\n\nexport interface PressOptions {\n /** Where the outlets live inside the panel. */\n path?: string\n}\n\n/**\n * The press as a section of the panel (§4.9): one module and one entry, without a group of its\n * own — the reviews have one because they have two entries, and a group around a single item is\n * a heading over itself. A section whose server half is not installed never appears — the entry\n * is built from the manifest.\n */\nexport function press(options: PressOptions = {}): AdminModule {\n const path = options.path ?? '/press'\n\n return {\n id: 'press',\n path,\n // One route: the open outlet is in the address (`?outlet=`), beside the list it was opened\n // from, so a link to it is a link to both.\n routes: [\n {\n path,\n name: 'webx.press',\n component: () => import('./PressPage.vue'),\n props: { base: path },\n },\n ],\n }\n}\n","import { reorderItems, type AdminContext } from '@webx-ui/module-admin'\nimport type { ScreenModel } from '@webx-ui/schema'\nimport type { OutletDetail, OutletQuery, OutletRow, OutletsList } from './types'\n\nexport interface PressApi {\n list(query?: OutletQuery): Promise<OutletsList>\n get(id: number): Promise<OutletDetail>\n /**\n * A new outlet out of the values of its form, articles included, in one request: the form is\n * filled in first and the record made on the first save, so nobody leaves an empty outlet behind.\n */\n create(values: ScreenModel): Promise<OutletDetail>\n /** Refused with a 422 under the name of the field — `articles.<n>.<field>` for an article. */\n save(id: number, values: ScreenModel): Promise<OutletDetail>\n remove(id: number): Promise<void>\n restore(id: number): Promise<OutletRow>\n /** The order of the whole list. The order of the articles is the order of the form's rows. */\n reorder(ids: number[]): Promise<void>\n}\n\n/** The path of the section under the panel's API, and of its order. */\nexport const PRESS_API = 'press'\n\n/** Everything under `/press`, below the panel's API path (§4.10). */\nexport function createPressApi(admin: AdminContext): PressApi {\n const base = `${admin.apiPath}/${PRESS_API}`\n const data = <T>(body: { data: T }): T => body.data\n\n return {\n list: (query = {}) => {\n const search = new URLSearchParams()\n\n if (query.search) search.set('search', query.search)\n if (query.trashed) search.set('trashed', '1')\n\n return admin.http.get<OutletsList>(search.size > 0 ? `${base}?${search}` : base)\n },\n get: (id) => admin.http.get<{ data: OutletDetail }>(`${base}/${id}`).then(data),\n create: (values) => admin.http.post<{ data: OutletDetail }>(base, { values }).then(data),\n save: (id, values) =>\n admin.http.put<{ data: OutletDetail }>(`${base}/${id}`, { values }).then(data),\n remove: (id) => admin.http.delete<void>(`${base}/${id}`).then(() => undefined),\n // The resource of the list line, and not the form's answer: a restored outlet stays closed.\n restore: (id) => admin.http.post<{ data: OutletRow }>(`${base}/${id}/restore`, {}).then(data),\n reorder: (ids) => reorderItems(admin, PRESS_API, ids, null),\n }\n}\n","import type { Messages } from '@webx-ui/module-admin'\n\n/**\n * The English this package speaks on its own, before the server's dictionary arrives, or without\n * one. The server ships the same lines in ten languages under `webx-press::` and overrides these;\n * `messages.test.ts` keeps the two sets of keys equal.\n *\n * `screen` is what the described screen `press.outlet-form` is labelled with: the server sends the\n * labels as `trans::webx-press::screen.*`, and these are what they say when no dictionary came.\n *\n * `kinds` are the four of the default config (decision 3). A kind a site adds brings its word in\n * `lang/vendor/webx-press` — the server labels the options of the field itself, so a kind missing\n * here is only missing from a panel that runs with no server at all.\n */\nexport const pressMessages: Record<string, Messages> = {\n module: {\n press: 'Press',\n },\n outlet: {\n new: 'New outlet',\n untitled: 'Untitled',\n search: 'Search the outlets',\n empty: 'No outlets yet.',\n 'empty-help':\n 'An outlet is a magazine, a paper or a site that wrote about you; its articles are added on its form.',\n 'empty-search': 'Nothing matches that.',\n 'empty-bin': 'The bin is empty.',\n all: 'All',\n trashed: 'Bin',\n 'not-published': 'Not published',\n 'visible-nowhere': 'Published, but seen in no language: none of its articles has a title yet.',\n 'articles-count': 'Articles: :count',\n 'no-articles': 'No articles yet',\n featured: 'In the logo strip',\n 'seen-in': 'Seen in: :locales',\n choose: 'Choose an outlet',\n 'choose-help': 'Or add a new one: the first line of the list.',\n save: 'Save',\n saved: 'The outlet is saved.',\n 'save-failed': 'The outlet was not saved.',\n cancel: 'Cancel',\n delete: 'Delete',\n 'delete-title': 'Delete “:name”?',\n 'delete-text':\n 'It goes to the bin with its articles and leaves the site and every block. Restored, it comes back with them.',\n deleted: 'The outlet is in the bin.',\n restore: 'Restore',\n restored: 'The outlet is back.',\n 'reorder-failed': 'The new order was not saved.',\n 'leave-title': 'Leave without saving?',\n 'leave-text': 'What you wrote in this outlet is not on the server.',\n leave: 'Leave',\n back: 'Back to the list',\n open: 'Open on the site',\n 'address-moving': 'The page of the outlet moves to the new address when you save.',\n },\n screen: {\n general: 'General',\n outlet: 'Outlet',\n logo: 'Logo',\n 'logo-help': 'Without a logo the site prints the name.',\n title: 'Name',\n 'title-help': 'Where it is not written in a language, the name from another one is shown.',\n slug: 'Address',\n 'slug-help':\n \"The outlet's page. A language with articles and no address of its own takes this one.\",\n 'website-url': 'Website',\n 'website-url-help': 'An address that starts with http:// or https://.',\n summary: 'About the outlet',\n 'summary-help':\n 'A few words under the name on its page, and its description for search engines.',\n settings: 'Settings',\n published: 'Published',\n 'published-help': 'On the site at once — in the languages it has articles in.',\n featured: 'In the strip of logos',\n 'featured-help': 'Shown by the logos block set to the marked outlets only.',\n articles: 'Articles',\n 'articles-help': \"In the order they are shown on the outlet's page. Saved with the outlet.\",\n 'article-label': '#:number · :title',\n 'article-untitled': 'Untitled',\n 'article-title': 'Title',\n 'article-title-help': 'An article is shown in a language only when it has a title in it.',\n excerpt: 'Excerpt',\n kind: 'Kind',\n 'kind-none': 'No kind',\n 'published-on': 'Date',\n 'date-precision': 'Known to',\n 'date-precision-help': 'How much of the date is printed: the day, the month, or the year only.',\n precision: {\n day: 'Day',\n month: 'Month',\n year: 'Year',\n },\n url: 'Link',\n 'url-help': \"The article on the outlet's site. Without it the title leads to the PDF.\",\n file: 'PDF',\n 'file-help': 'A PDF from the library — a scan of the page, say.',\n hidden: 'Do not show',\n 'hidden-help': 'Kept here, and shown nowhere on the site.',\n seo: 'SEO',\n 'seo-empty': 'The SEO card appears here when module-seo is installed.',\n },\n kinds: {\n mention: 'Mention',\n interview: 'Interview',\n expert_comment: 'Expert comment',\n authored: 'Authored article',\n },\n}\n","import { useAdmin } from '@webx-ui/module-admin'\nimport { pressMessages } from './messages'\n\nconst seeded = new WeakSet<object>()\n\n/** Puts this package's English under the panel's dictionary, once per panel. */\nexport function usePressMessages(): void {\n try {\n const { i18n } = useAdmin()\n\n if (!seeded.has(i18n)) {\n i18n.defaults('webx-press', pressMessages)\n seeded.add(i18n)\n }\n } catch {\n // Outside a panel there is no dictionary to seed, and `useTranslate` falls back on its own.\n }\n}\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, ref } from 'vue'\nimport { onBeforeRouteLeave, onBeforeRouteUpdate, type RouteLocationNormalized } from 'vue-router'\nimport {\n confirm,\n localizedValue,\n toast,\n useLocales,\n WxActionBar,\n WxBadge,\n WxButton,\n WxSkeleton,\n type LocalizedValue,\n} from '@webx-ui/core'\nimport {\n provideRecordAddress,\n useAdmin,\n useErrorText,\n useTranslate,\n WxSaveState,\n WxScreen,\n WxScreenHead,\n type ScreenAction,\n useBodyKeys,\n} from '@webx-ui/module-admin'\nimport type { ScreenModel } from '@webx-ui/schema'\nimport { createPressApi } from './api'\nimport { usePressMessages } from './i18n'\nimport type { OutletDetail, OutletSummary } from './types'\n\n/**\n * One outlet with its articles: the pane beside the list, and the whole screen on a phone.\n *\n * The described screen `press.outlet-form` — General · Articles · SEO — with a head over it and\n * one button under it. One explicit save for the whole outlet, articles included (decision 15):\n * the articles are rows of its form, and the server writes them into their own table in the same\n * transaction (§4.6). No autosave: there is no draft (decision 9), so what is saved is on the site\n * at once — the button is the moment somebody decides it is ready.\n *\n * A new outlet is a form first and a record on the first save: an empty row made by pressing\n * \"New outlet\" and walking away would be an outlet with nothing in it on the list for ever.\n *\n * The way back is drawn here and not by the pane around it: the drawer a narrow screen opens\n * this in has no close of its own on purpose (CLAUDE.md §4).\n */\ndefineOptions({ name: 'WxOutletPane' })\n\nconst props = withDefaults(\n defineProps<{\n /** `null` — an outlet not written yet. */\n id: number | null\n /** False in the drawer a narrow screen opens this in. */\n inline?: boolean\n }>(),\n { inline: true },\n)\n\nconst emit = defineEmits<{\n back: []\n /** The outlet was written; the list redraws its row. */\n saved: [outlet: OutletSummary]\n /** The first save of a new outlet: it is a record now, with an id to be opened by. */\n created: [outlet: OutletSummary]\n removed: [id: number]\n}>()\n\nconst context = useAdmin()\nconst api = createPressApi(context)\nconst locales = useLocales()\nusePressMessages()\n\nconst t = useTranslate('webx-press')\n/* Not the server's `message`: the panel says how a request failed in its own words. */\nconst message = useErrorText()\n\nconst outlet = ref<OutletSummary | null>(null)\nconst values = ref<ScreenModel>({})\nconst prefix = ref<string | null>(null)\nconst snapshot = ref('')\n\nconst loading = ref(props.id !== null)\nconst saving = ref(false)\nconst errors = ref<Record<string, string[]>>({})\n\nconst canManage = computed(() => context.can('press.manage'))\n\nconst current = computed(() => JSON.stringify(values.value))\nconst dirty = computed(() => snapshot.value !== '' && current.value !== snapshot.value)\n\nconst state = computed<'saving' | 'unsaved' | 'saved'>(() => {\n if (saving.value) return 'saving'\n\n return dirty.value || props.id === null ? 'unsaved' : 'saved'\n})\n\n/** The name follows the field rather than the answer: an edit shows at the top as it is typed. */\nconst title = computed(() => {\n const written = values.value.title as LocalizedValue | string | null | undefined\n const fallback = props.id === null ? t('outlet.new') : (outlet.value?.title ?? '')\n\n return localizedValue(written, locales.active.value, fallback) || t('outlet.untitled')\n})\n\n/*\n * The address field is the panel's shared one (`wx-slug`), and this is what it prints. The form\n * answers with the page's address (`url`) in the panel's language — `/en/press/…` on a site whose\n * default is another — while the field compares it with the slug in the language being edited.\n * So the address is handed over without the host, the slash and the language, and only in its own\n * language: in any other the field has nothing to compare with, and says nothing rather than\n * warning that a page moves which does not.\n */\nprovideRecordAddress({\n values,\n prefix,\n path: computed(() => pathIn(outlet.value?.url ?? null, locales.active.value)),\n moving: () => t('outlet.address-moving'),\n})\n\nfunction pathIn(url: string | null, locale: string): string | null | undefined {\n if (url === null) return null\n\n let segments: string[]\n\n try {\n segments = new URL(url, 'http://site.invalid').pathname.split('/').filter((one) => one !== '')\n } catch {\n return null\n }\n\n const codes = locales.list.value.map((one) => one.code)\n const own =\n codes.includes(segments[0] ?? '') && segments[0] !== codes[0] ? segments.shift()! : codes[0]\n\n return own === undefined || own === locale ? segments.join('/') : undefined\n}\n\nfunction take(detail: OutletDetail): void {\n outlet.value = detail.outlet\n values.value = detail.values\n prefix.value = detail.prefix\n snapshot.value = JSON.stringify(detail.values)\n}\n\nif (props.id === null) {\n // What the server would answer for an outlet with nothing in it yet.\n const blank: ScreenModel = {\n title: {},\n slug: {},\n summary: {},\n published: false,\n featured: false,\n articles: [],\n }\n\n values.value = blank\n snapshot.value = JSON.stringify(blank)\n}\n\nasync function load(): Promise<void> {\n if (props.id === null) return\n\n loading.value = true\n\n try {\n take(await api.get(props.id))\n } catch (error) {\n toast.danger(message(error))\n emit('back')\n } finally {\n loading.value = false\n }\n}\n\nasync function save(): Promise<void> {\n if (saving.value || !canManage.value) return\n\n saving.value = true\n errors.value = {}\n\n try {\n const made = props.id === null\n const detail = made\n ? await api.create(values.value)\n : await api.save(props.id as number, values.value)\n\n take(detail)\n toast.success(t('outlet.saved'))\n if (made) emit('created', detail.outlet)\n else emit('saved', detail.outlet)\n } catch (error) {\n const body = (error as { body?: { errors?: Record<string, string[]> } }).body\n\n if (body?.errors) {\n // `articles.2.url` as the server names it: the repeater finds its row and field by that.\n errors.value = body.errors\n toast.danger(t('outlet.save-failed'))\n } else {\n toast.danger(message(error))\n }\n } finally {\n saving.value = false\n }\n}\n\nasync function remove(): Promise<void> {\n const record = outlet.value\n\n if (!record) return\n\n const agreed = await confirm({\n title: t('outlet.delete-title', { name: record.title }),\n message: t('outlet.delete-text'),\n confirmText: t('outlet.delete'),\n cancelText: t('outlet.cancel'),\n tone: 'danger',\n })\n\n if (!agreed) return\n\n try {\n await api.remove(record.id)\n toast.success(t('outlet.deleted'))\n // Nothing left to protect: the record is in the bin.\n snapshot.value = current.value\n emit('removed', record.id)\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\n/* The browser's own guard: it cannot wait for a request, so all it can do is ask. */\nfunction leaveGuard(event: BeforeUnloadEvent): void {\n if (dirty.value) event.preventDefault()\n}\n\n/* Ctrl+S saves, as it does everywhere else that has a save button. */\nfunction onKeydown(event: KeyboardEvent): void {\n if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 's') {\n event.preventDefault()\n if (dirty.value || props.id === null) void save()\n }\n}\n\n// And from the page around the form, where a click on empty space leaves the focus.\nuseBodyKeys(onKeydown)\n\nonMounted(() => {\n void load()\n window.addEventListener('beforeunload', leaveGuard)\n})\n\nonBeforeUnmount(() => {\n window.removeEventListener('beforeunload', leaveGuard)\n})\n\nasync function mayLeave(): Promise<boolean> {\n if (!dirty.value || !canManage.value) return true\n\n return await confirm({\n title: t('outlet.leave-title'),\n message: t('outlet.leave-text'),\n confirmText: t('outlet.leave'),\n cancelText: t('outlet.cancel'),\n tone: 'danger',\n })\n}\n\n/*\n * The list and this form are one route, so another outlet is an update of it rather than a way\n * out — and so is every keystroke in the search above the list, which goes into the address too.\n * Only a change of the outlet asks.\n */\nonBeforeRouteUpdate(async (to: RouteLocationNormalized, from: RouteLocationNormalized) =>\n to.query.outlet === from.query.outlet ? true : await mayLeave(),\n)\n\nonBeforeRouteLeave(mayLeave)\n\n/* What leads away from the outlet. On a narrow pane the head folds them into the ···. */\nconst actions = computed<ScreenAction[]>(() => {\n const record = outlet.value\n const list: ScreenAction[] = []\n\n // Only a page that answers: an unpublished outlet, or one seen nowhere, has no address.\n if (record?.url) {\n const url = record.url\n\n list.push({\n key: 'open',\n label: t('outlet.open'),\n icon: 'external-link',\n run: () => void window.open(url, '_blank', 'noopener'),\n })\n }\n\n if (canManage.value && record !== null) {\n list.push({\n key: 'delete',\n label: t('outlet.delete'),\n icon: 'trash',\n danger: true,\n menu: true,\n run: () => void remove(),\n })\n }\n\n return list\n})\n</script>\n\n<template>\n <div class=\"wx-outlet\" @keydown=\"onKeydown\">\n <wx-skeleton v-if=\"loading\" class=\"wx-outlet__ghost\" title :rows=\"6\" />\n\n <template v-else>\n <wx-screen-head\n :level=\"3\"\n :back=\"!props.inline\"\n :back-label=\"t('outlet.back')\"\n :title=\"title\"\n :actions=\"actions\"\n :collapse-below=\"480\"\n @back=\"emit('back')\"\n >\n <template v-if=\"outlet && !outlet.published\" #title-after>\n <wx-badge dot>{{ t('outlet.not-published') }}</wx-badge>\n </template>\n </wx-screen-head>\n\n <wx-screen\n v-model=\"values\"\n name=\"press.outlet-form\"\n :errors=\"errors\"\n :disabled=\"!canManage || saving\"\n />\n\n <wx-action-bar v-if=\"canManage\">\n <template #state>\n <wx-save-state :state=\"state\" />\n </template>\n\n <wx-button\n type=\"primary\"\n :loading=\"saving\"\n :disabled=\"!dirty && props.id !== null\"\n @click=\"save\"\n >\n {{ t('outlet.save') }}\n </wx-button>\n </wx-action-bar>\n </template>\n </div>\n</template>\n\n<style scoped>\n.wx-outlet {\n display: flex;\n flex-direction: column;\n gap: var(--wx-gap, var(--wx-space-16));\n min-width: 0;\n padding: var(--wx-gap, var(--wx-space-16));\n container-type: inline-size;\n}\n\n.wx-outlet__ghost {\n max-width: 480px;\n}\n</style>\n","import { defineAsyncComponent } from 'vue'\nexport { press, type PressOptions } from './module'\nexport { createPressApi, PRESS_API, type PressApi } from './api'\nexport { pressMessages } from './messages'\nexport const WxPressPage = defineAsyncComponent(() => import('./PressPage.vue'))\nexport { default as WxOutletPane } from './OutletPane.vue'\nexport type {\n ArticleValues,\n OutletDetail,\n OutletQuery,\n OutletRow,\n OutletsList,\n OutletSummary,\n} from './types'\n"],"names":["press","options","path","PRESS_API","createPressApi","admin","base","data","body","query","search","id","values","ids","reorderItems","pressMessages","seeded","usePressMessages","i18n","useAdmin","props","__props","emit","__emit","context","api","locales","useLocales","t","useTranslate","message","useErrorText","outlet","ref","prefix","snapshot","loading","saving","errors","canManage","computed","current","dirty","state","title","written","fallback","localizedValue","provideRecordAddress","pathIn","url","locale","segments","one","codes","own","take","detail","blank","load","error","toast","save","made","remove","record","confirm","leaveGuard","event","onKeydown","useBodyKeys","onMounted","onBeforeUnmount","mayLeave","onBeforeRouteUpdate","to","from","onBeforeRouteLeave","actions","list","_createElementBlock","_createBlock","_unref","WxSkeleton","_Fragment","_createVNode","WxScreenHead","WxBadge","WxScreen","$event","WxActionBar","WxSaveState","WxButton","WxPressPage","defineAsyncComponent"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
export { press, type PressOptions } from './module';
|
|
2
2
|
export { createPressApi, PRESS_API, type PressApi } from './api';
|
|
3
3
|
export { pressMessages } from './messages';
|
|
4
|
-
export
|
|
4
|
+
export declare const WxPressPage: import('vue').DefineComponent<{
|
|
5
|
+
base?: string;
|
|
6
|
+
}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{
|
|
7
|
+
base?: string;
|
|
8
|
+
}> & Readonly<{}>, {
|
|
9
|
+
base: string;
|
|
10
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
|
|
5
11
|
export { default as WxOutletPane } from './OutletPane';
|
|
6
12
|
export type { ArticleValues, OutletDetail, OutletQuery, OutletRow, OutletsList, OutletSummary, } from './types';
|