@webx-ui/module-vacancies 0.1.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/index.js ADDED
@@ -0,0 +1,1296 @@
1
+ import { reorderItems as Ke, useAdmin as oe, useTranslate as ue, useErrorText as ke, WxListScreen as je, WxFilterChips as Ye, WxRowMenu as Ge, useDates as Je, provideRelationOwner as Qe, provideRecordAddress as Xe, WxScreenHead as Ze, WxScreen as et, WxSaveState as tt, WxDate as at, categoryRoutes as nt } from "@webx-ui/module-admin";
2
+ import { defineComponent as de, ref as $, useTemplateRef as lt, onMounted as Re, nextTick as st, openBlock as f, createBlock as V, unref as e, isRef as it, withCtx as i, createVNode as d, createElementVNode as O, withKeys as ot, createTextVNode as k, toDisplayString as g, computed as h, watch as ie, onBeforeUnmount as Se, createElementBlock as z, createCommentVNode as R, Fragment as ee, normalizeClass as qe, resolveDynamicComponent as rt, mergeProps as ct, renderList as De, provide as ut, inject as dt } from "vue";
3
+ import { useRoute as Ee, useRouter as Oe, onBeforeRouteLeave as pt } from "vue-router";
4
+ import { useModal as vt, WxDialog as ht, WxFormItem as xe, WxInput as Pe, WxSpace as yt, WxButton as K, createModal as ft, WxIcon as se, WxPopover as mt, WxSelect as Ve, WxIndicator as gt, WxAction as wt, WxSkeleton as ce, WxEmpty as ze, WxSortableList as bt, WxTooltip as We, WxBadge as Y, WxAlert as Ae, toast as _, confirm as G, useLocales as _t, localizedValue as xt, WxCard as kt, WxBreadcrumb as Tt, WxBreadcrumbItem as Ce, WxActionBar as $t, WxText as Vt } from "@webx-ui/core";
5
+ const Ie = "vacancies";
6
+ function pe(r) {
7
+ const c = `${r.apiPath}/${Ie}`, y = (n) => n.data, p = (n, m) => r.http.post(`${c}/${n}/${m}`, {}).then(y);
8
+ return {
9
+ list: (n = {}) => {
10
+ const m = new URLSearchParams();
11
+ return n.trashed ? m.set("trashed", "1") : m.set("state", n.state ?? "open"), n.q && m.set("q", n.q), n.category != null && m.set("category", String(n.category)), n.status && m.set("status", n.status), r.http.get(`${c}?${m}`);
12
+ },
13
+ get: (n) => r.http.get(`${c}/${n}`).then(y),
14
+ create: (n) => r.http.post(c, n).then(y),
15
+ save: (n, m) => r.http.put(`${c}/${n}`, m).then(y),
16
+ discard: (n) => r.http.post(`${c}/${n}/discard`, {}).then(y),
17
+ duplicate: (n) => r.http.post(`${c}/${n}/duplicate`, {}).then(y),
18
+ publish: (n) => p(n, "publish"),
19
+ unpublish: (n) => p(n, "unpublish"),
20
+ close: (n) => p(n, "close"),
21
+ reopen: (n) => p(n, "reopen"),
22
+ remove: (n) => r.http.delete(`${c}/${n}`).then(() => {
23
+ }),
24
+ restore: (n) => p(n, "restore"),
25
+ // No `category`, ever: vacancies have one order (§4.11), unlike services.
26
+ reorder: (n) => Ke(r, Ie, n, null),
27
+ versions: (n) => r.http.get(`${c}/${n}/versions`).then(y),
28
+ restoreVersion: (n, m) => r.http.post(`${c}/${n}/versions/${m}/restore`, {}).then(y)
29
+ };
30
+ }
31
+ const Wt = /^(\d{4})-(\d{2})-(\d{2})$/;
32
+ function Me(r) {
33
+ const c = typeof r == "string" ? Wt.exec(r.slice(0, 10)) : null;
34
+ if (c === null) return null;
35
+ const [, y, p, n] = c, m = new Date(Number(y), Number(p) - 1, Number(n));
36
+ return Number.isNaN(m.getTime()) ? null : m;
37
+ }
38
+ function Ct(r, c, y = /* @__PURE__ */ new Date()) {
39
+ const p = Me(r);
40
+ return p === null ? "" : new Intl.DateTimeFormat(c, {
41
+ day: "numeric",
42
+ month: "short",
43
+ ...p.getFullYear() === y.getFullYear() ? {} : { year: "numeric" }
44
+ }).format(p);
45
+ }
46
+ function Le(r, c) {
47
+ const y = Me(r);
48
+ return y === null ? "" : new Intl.DateTimeFormat(c, { day: "numeric", month: "long", year: "numeric" }).format(y);
49
+ }
50
+ const It = {
51
+ module: {
52
+ group: "Vacancies",
53
+ vacancies: "Vacancies",
54
+ categories: "Categories"
55
+ },
56
+ panel: {
57
+ new: "New vacancy",
58
+ "new-title": "New vacancy",
59
+ "field-title": "Position",
60
+ create: "Create",
61
+ cancel: "Cancel",
62
+ search: "Search by position or address",
63
+ empty: "No vacancies yet.",
64
+ "empty-help": "A vacancy is who you are looking for: the position, where, the terms and the pay.",
65
+ "empty-open": "No open vacancies. The closed ones are on the next tab.",
66
+ "empty-closed": "No vacancy is closed.",
67
+ "empty-search": "Nothing matches that.",
68
+ "empty-bin": "The bin is empty.",
69
+ "status-draft": "Draft",
70
+ "status-published": "Live",
71
+ "status-modified": "Live",
72
+ "status-unpublished": "Off the site",
73
+ edits: "edits",
74
+ "closed-manual": "Closed",
75
+ "closed-expired": "Expired",
76
+ "closed-manual-help": "The hiring was closed by hand.",
77
+ "closed-expired-help": "Its last day is behind us.",
78
+ "no-address": "No address in this language",
79
+ "no-city": "No city",
80
+ until: "until :date",
81
+ "until-help": "Open to the end of :date",
82
+ "view-open": "Open",
83
+ "view-closed": "Closed",
84
+ "view-all": "All",
85
+ bin: "Bin",
86
+ filters: "Filters",
87
+ "filters-reset": "Reset the filters",
88
+ "filter-status": "State",
89
+ "any-status": "Any state",
90
+ "filter-category": "Category",
91
+ "any-category": "Any category",
92
+ "order-all": "Drag a vacancy by its handle to change the order the site lists them in.",
93
+ "order-closed": "The order is set on the Open and All tabs: a closed vacancy is on no list of the site.",
94
+ "order-locked": "The order can only be changed in the whole list — clear the search and the filters.",
95
+ "reorder-failed": "The new order was not saved.",
96
+ open: "Open",
97
+ "open-on-site": "Open on the site",
98
+ "copy-address": "Copy the address",
99
+ "address-copied": "The address is copied.",
100
+ duplicate: "Duplicate",
101
+ duplicated: "This is the copy: a draft. Change what differs and publish it.",
102
+ close: "Close the hiring",
103
+ reopen: "Reopen the hiring",
104
+ "close-title": "Close “:title”?",
105
+ "close-text": "It leaves every list of the site. Its page stays, marked as closed, so links from job boards still lead somewhere.",
106
+ "reopen-title": "Reopen “:title”?",
107
+ "reopen-text": "It is back on the lists of the site, unless its last day is already behind us.",
108
+ "reopen-expired": "Its last day is behind us, so it stays closed: change “Open until” in the editor to reopen it.",
109
+ closed: "The hiring is closed.",
110
+ reopened: "The hiring is open again.",
111
+ "close-edits": "This vacancy has edits waiting. Publish or discard them first — closing would put them on the site too.",
112
+ publish: "Publish",
113
+ unpublish: "Take off the site",
114
+ delete: "Delete",
115
+ restore: "Restore",
116
+ "delete-title": "Delete “:title”?",
117
+ "delete-text": "It goes to the bin and comes off the site, and its address is free again.",
118
+ deleted: "The vacancy is in the bin.",
119
+ restored: "The vacancy is back.",
120
+ published: "The vacancy is on the site.",
121
+ "unpublished-done": "The vacancy is off the site."
122
+ },
123
+ editor: {
124
+ trail: "Where this vacancy sits",
125
+ untitled: "Untitled",
126
+ save: "Save",
127
+ "save-failed": "The vacancy was not saved.",
128
+ "publish-title": "Put “:title” on the site?",
129
+ "publish-text": "It answers at :address from the moment you do, for everyone — with its categories and form as they are chosen now.",
130
+ "publish-nowhere": "It has no address in this language yet, so nothing will answer.",
131
+ preview: "Preview",
132
+ discard: "Discard changes",
133
+ "discard-title": "Discard what is waiting?",
134
+ "discard-text": "The vacancy goes back to what the site is showing. What was written since is not listed anywhere.",
135
+ discarded: "The vacancy is back to what is published.",
136
+ "conflict-title": "The vacancy changed while you were editing",
137
+ "conflict-mine": "Keep mine",
138
+ "conflict-theirs": "Take the newer version",
139
+ "conflict-theirs-title": "Give up what you wrote?",
140
+ "conflict-theirs-text": "The vacancy is read again as it now is, and what you have typed since goes.",
141
+ leave: "Leave",
142
+ "leave-title": "Leave without saving?",
143
+ "leave-text": "The vacancy could not be saved, and what you wrote is not on the server.",
144
+ "live-since": "On the site since :date",
145
+ "open-until": "Open until :date",
146
+ "address-moving": "The address is changing. The old one keeps working and leads to the new one.",
147
+ "history-empty": "This vacancy has never been published.",
148
+ version: "#:number",
149
+ "version-live": "On the site",
150
+ "source-panel": "From the panel",
151
+ "source-mcp": "By an agent",
152
+ "source-import": "Imported",
153
+ "restore-title": "Restore version :number?",
154
+ "restore-text": "It becomes the draft. The site keeps showing what is published until you publish this.",
155
+ "restore-version": "Restore",
156
+ "restored-version": "Version :number is now the draft."
157
+ },
158
+ category: {
159
+ new: "New category",
160
+ empty: "No categories yet.",
161
+ "empty-help": "A category is a group of vacancies — development, sales — and a filter of the list on the site. It has no page of its own.",
162
+ order: "Drag to change the order of the groups on the site.",
163
+ hidden: "Hidden from the site",
164
+ "no-page": "A group, with no page of its own",
165
+ vacancies: "Vacancies: :count",
166
+ "show-vacancies": "Show its vacancies",
167
+ "delete-blocked": "This category still holds vacancies. Move them first.",
168
+ "delete-text": "It goes to the bin. Its vacancies stay.",
169
+ deleted: "The category is in the bin.",
170
+ saved: "The category is saved.",
171
+ "field-title": "Title",
172
+ "field-slug": "Key",
173
+ "field-slug-help": "In the address of the filter: ?category=… Latin letters, digits and hyphens."
174
+ },
175
+ vacancy: {
176
+ workplace: {
177
+ onsite: "On site",
178
+ remote: "Remote",
179
+ hybrid: "Hybrid"
180
+ },
181
+ employment: {
182
+ FULL_TIME: "Full-time",
183
+ PART_TIME: "Part-time",
184
+ CONTRACTOR: "Contract",
185
+ TEMPORARY: "Temporary",
186
+ INTERN: "Internship",
187
+ VOLUNTEER: "Volunteer",
188
+ PER_DIEM: "Per day",
189
+ OTHER: "Other"
190
+ }
191
+ }
192
+ };
193
+ function Nt(r) {
194
+ return `vacancy.employment.${r}`;
195
+ }
196
+ const Ne = /* @__PURE__ */ new WeakSet();
197
+ function ve() {
198
+ try {
199
+ const { i18n: r } = oe();
200
+ Ne.has(r) || (r.defaults("webx-vacancies", It), Ne.add(r));
201
+ } catch {
202
+ }
203
+ }
204
+ const Rt = /* @__PURE__ */ de({
205
+ __name: "VacancyCreateDialog",
206
+ setup(r) {
207
+ const { open: c, resolve: y, dismiss: p } = vt(), n = oe(), m = pe(n);
208
+ ve();
209
+ const a = ue("webx-vacancies"), C = $(""), l = $(!1), N = $({}), q = lt("field");
210
+ Re(async () => {
211
+ await st(), q.value?.querySelector("input")?.focus();
212
+ });
213
+ async function A() {
214
+ if (!(C.value.trim() === "" || l.value)) {
215
+ l.value = !0, N.value = {};
216
+ try {
217
+ y((await m.create({ title: C.value.trim() })).vacancy);
218
+ } catch (v) {
219
+ N.value = v.body?.errors ?? {};
220
+ } finally {
221
+ l.value = !1;
222
+ }
223
+ }
224
+ }
225
+ return (v, w) => (f(), V(e(ht), {
226
+ open: e(c),
227
+ "onUpdate:open": w[2] || (w[2] = (W) => it(c) ? c.value = W : null),
228
+ title: e(a)("panel.new-title"),
229
+ width: 440
230
+ }, {
231
+ footer: i(() => [
232
+ d(e(yt), { size: "sm" }, {
233
+ default: i(() => [
234
+ d(e(K), {
235
+ variant: "outline",
236
+ onClick: w[1] || (w[1] = (W) => e(p)())
237
+ }, {
238
+ default: i(() => [
239
+ k(g(e(a)("panel.cancel")), 1)
240
+ ]),
241
+ _: 1
242
+ }),
243
+ d(e(K), {
244
+ type: "primary",
245
+ loading: l.value,
246
+ disabled: C.value.trim() === "",
247
+ onClick: A
248
+ }, {
249
+ default: i(() => [
250
+ k(g(e(a)("panel.create")), 1)
251
+ ]),
252
+ _: 1
253
+ }, 8, ["loading", "disabled"])
254
+ ]),
255
+ _: 1
256
+ })
257
+ ]),
258
+ default: i(() => [
259
+ d(e(xe), {
260
+ label: e(a)("panel.field-title"),
261
+ error: N.value.title?.[0] ?? N.value.slug?.[0],
262
+ required: ""
263
+ }, {
264
+ default: i(() => [
265
+ O("div", {
266
+ ref_key: "field",
267
+ ref: q
268
+ }, [
269
+ d(e(Pe), {
270
+ modelValue: C.value,
271
+ "onUpdate:modelValue": w[0] || (w[0] = (W) => C.value = W),
272
+ "aria-label": e(a)("panel.field-title"),
273
+ onKeyup: ot(A, ["enter"])
274
+ }, null, 8, ["modelValue", "aria-label"])
275
+ ], 512)
276
+ ]),
277
+ _: 1
278
+ }, 8, ["label", "error"])
279
+ ]),
280
+ _: 1
281
+ }, 8, ["open", "title"]));
282
+ }
283
+ }), St = { class: "wx-vacancies" }, qt = { class: "wx-vacancies__bar" }, Dt = { class: "wx-vacancies__filters" }, Et = {
284
+ key: 0,
285
+ class: "wx-vacancies__applied"
286
+ }, Ot = { class: "wx-vacancy-row__name" }, Pt = { class: "wx-vacancy-row__title" }, zt = { class: "wx-vacancy-row__address" }, At = { class: "wx-vacancy-row__facts" }, Mt = { class: "wx-vacancy-row__where" }, Lt = {
287
+ key: 0,
288
+ class: "wx-vacancy-row__employment"
289
+ }, Ft = { class: "wx-vacancy-row__until" }, Ut = { class: "wx-vacancy-row__state" }, Bt = /* @__PURE__ */ de({
290
+ __name: "VacanciesPage",
291
+ props: {
292
+ base: { default: "/vacancies" }
293
+ },
294
+ setup(r) {
295
+ const c = r, y = oe(), p = pe(y), n = Ee(), m = Oe();
296
+ ve();
297
+ const a = ue("webx-vacancies"), C = ke(), l = $([]), N = $({ categories: [] }), q = $(!0), A = ft(Rt), v = h(() => y.can("vacancies.manage")), w = h(
298
+ () => y.state.manifest?.modules.find((t) => t.id === "vacancies")?.title ?? a("module.vacancies")
299
+ ), W = h(() => y.i18n.state.locale), b = h({
300
+ get: () => typeof n.query.view == "string" ? n.query.view : "",
301
+ set: (t) => {
302
+ m.replace({
303
+ query: { ...n.query, view: t === "" ? void 0 : String(t) }
304
+ });
305
+ }
306
+ }), T = h(() => b.value === "trashed"), M = h(() => b.value === "closed" ? "closed" : b.value === "all" ? "all" : "open"), P = h(() => {
307
+ const t = n.query.category;
308
+ return typeof t == "string" && t !== "" && Number(t) || null;
309
+ }), I = h(
310
+ () => typeof n.query.status == "string" ? n.query.status : ""
311
+ ), F = h(() => typeof n.query.q == "string" ? n.query.q : ""), S = $(F.value), Z = h(() => [
312
+ { value: "", label: a("panel.view-open") },
313
+ { value: "closed", label: a("panel.view-closed") },
314
+ { value: "all", label: a("panel.view-all") },
315
+ { value: "trashed", label: a("panel.bin"), icon: "trash" }
316
+ ]), U = h(
317
+ () => ["published", "draft", "unpublished"].map((t) => ({
318
+ value: t,
319
+ label: a(`panel.status-${t}`)
320
+ }))
321
+ ), te = h(
322
+ () => F.value.trim() === "" && P.value === null && I.value === ""
323
+ ), J = h(() => M.value !== "closed" && !T.value), D = h(() => v.value && J.value && te.value), he = h(() => J.value ? a(te.value ? "panel.order-all" : "panel.order-locked") : a("panel.order-closed")), ae = h(() => F.value !== "" ? a("panel.empty-search") : T.value ? a("panel.empty-bin") : M.value === "closed" ? a("panel.empty-closed") : M.value === "all" ? a("panel.empty") : a("panel.empty-open")), Q = h(() => {
324
+ const t = [];
325
+ I.value !== "" && t.push({
326
+ key: "status",
327
+ label: `${a("panel.filter-status")}: ${a(`panel.status-${I.value}`)}`,
328
+ clear: () => L("status", void 0)
329
+ });
330
+ const u = N.value.categories.find((o) => o.id === P.value);
331
+ return u && t.push({
332
+ key: "category",
333
+ label: `${a("panel.filter-category")}: ${u.title}`,
334
+ clear: () => L("category", void 0)
335
+ }), t;
336
+ });
337
+ async function j() {
338
+ q.value = !0;
339
+ try {
340
+ const t = await p.list({
341
+ state: M.value,
342
+ q: F.value,
343
+ category: P.value,
344
+ status: T.value ? "" : I.value,
345
+ trashed: T.value
346
+ });
347
+ l.value = t.data, N.value = t.filters;
348
+ } catch (t) {
349
+ _.danger(C(t));
350
+ } finally {
351
+ q.value = !1;
352
+ }
353
+ }
354
+ ie([b, P, I, F], () => {
355
+ j();
356
+ }), j();
357
+ let B;
358
+ ie(S, (t) => {
359
+ clearTimeout(B), B = setTimeout(() => {
360
+ m.replace({ query: { ...n.query, q: t.trim() === "" ? void 0 : t } });
361
+ }, 300);
362
+ }), Se(() => clearTimeout(B));
363
+ function L(t, u) {
364
+ m.replace({
365
+ query: {
366
+ ...n.query,
367
+ [t]: typeof u == "number" || typeof u == "string" && u !== "" ? String(u) : void 0
368
+ }
369
+ });
370
+ }
371
+ function ye() {
372
+ const t = { ...n.query };
373
+ delete t.category, delete t.status, m.replace({ query: t });
374
+ }
375
+ function ne(t) {
376
+ m.push({ path: `${c.base}/${t.id}`, query: { ...n.query } });
377
+ }
378
+ async function H() {
379
+ const t = await A({});
380
+ t && ne(t);
381
+ }
382
+ async function fe() {
383
+ try {
384
+ await p.reorder(l.value.map((t) => t.id));
385
+ } catch (t) {
386
+ _.danger(C(t, a("panel.reorder-failed"))), await j();
387
+ }
388
+ }
389
+ const le = (t) => t.status === "published" || t.status === "modified";
390
+ function me(t) {
391
+ if (!v.value) return [];
392
+ if (T.value)
393
+ return [
394
+ {
395
+ key: "restore",
396
+ icon: "refresh",
397
+ label: a("panel.restore"),
398
+ run: () => {
399
+ _e(t);
400
+ }
401
+ }
402
+ ];
403
+ const u = [
404
+ { key: "open", icon: "edit", label: a("panel.open"), run: () => ne(t) },
405
+ {
406
+ key: "duplicate",
407
+ icon: "copy",
408
+ label: a("panel.duplicate"),
409
+ run: () => {
410
+ ge(t);
411
+ }
412
+ }
413
+ ];
414
+ return t.url && t.status !== "draft" && u.push({
415
+ key: "site",
416
+ icon: "external-link",
417
+ label: a("panel.open-on-site"),
418
+ href: t.url
419
+ }), le(t) && t.closed_reason === "manual" ? u.push({
420
+ key: "reopen",
421
+ icon: "refresh",
422
+ label: a("panel.reopen"),
423
+ run: () => {
424
+ be(t);
425
+ }
426
+ }) : le(t) && t.closed_reason === null && u.push({
427
+ key: "close",
428
+ icon: "lock",
429
+ label: a("panel.close"),
430
+ run: () => {
431
+ we(t);
432
+ }
433
+ }), u.push(
434
+ le(t) ? {
435
+ key: "unpublish",
436
+ icon: "eye-off",
437
+ label: a("panel.unpublish"),
438
+ run: () => {
439
+ s(() => p.unpublish(t.id), a("panel.unpublished-done"));
440
+ }
441
+ } : {
442
+ key: "publish",
443
+ icon: "upload",
444
+ label: a("panel.publish"),
445
+ run: () => {
446
+ s(() => p.publish(t.id), a("panel.published"));
447
+ }
448
+ }
449
+ ), u.push({
450
+ key: "delete",
451
+ icon: "trash",
452
+ label: a("panel.delete"),
453
+ danger: !0,
454
+ run: () => {
455
+ re(t);
456
+ }
457
+ }), u;
458
+ }
459
+ async function ge(t) {
460
+ try {
461
+ const u = await p.duplicate(t.id);
462
+ _.success(a("panel.duplicated")), ne(u.vacancy);
463
+ } catch (u) {
464
+ _.danger(C(u));
465
+ }
466
+ }
467
+ async function we(t) {
468
+ if (t.status === "modified") {
469
+ _.warning(a("panel.close-edits"));
470
+ return;
471
+ }
472
+ await G({
473
+ title: a("panel.close-title", { title: t.title }),
474
+ message: a("panel.close-text"),
475
+ confirmText: a("panel.close"),
476
+ cancelText: a("panel.cancel")
477
+ }) && await s(() => p.close(t.id), a("panel.closed"));
478
+ }
479
+ async function be(t) {
480
+ if (t.status === "modified") {
481
+ _.warning(a("panel.close-edits"));
482
+ return;
483
+ }
484
+ if (await G({
485
+ title: a("panel.reopen-title", { title: t.title }),
486
+ message: a("panel.reopen-text"),
487
+ confirmText: a("panel.reopen"),
488
+ cancelText: a("panel.cancel")
489
+ }))
490
+ try {
491
+ (await p.reopen(t.id)).closed ? _.warning(a("panel.reopen-expired")) : _.success(a("panel.reopened"));
492
+ } catch (o) {
493
+ _.danger(C(o));
494
+ } finally {
495
+ await j();
496
+ }
497
+ }
498
+ async function re(t) {
499
+ await G({
500
+ title: a("panel.delete-title", { title: t.title }),
501
+ message: a("panel.delete-text"),
502
+ confirmText: a("panel.delete"),
503
+ cancelText: a("panel.cancel"),
504
+ tone: "danger"
505
+ }) && await s(() => p.remove(t.id), a("panel.deleted"));
506
+ }
507
+ async function _e(t) {
508
+ await s(() => p.restore(t.id), a("panel.restored"));
509
+ }
510
+ async function s(t, u) {
511
+ try {
512
+ await t(), _.success(u);
513
+ } catch (o) {
514
+ _.danger(C(o));
515
+ } finally {
516
+ await j();
517
+ }
518
+ }
519
+ function x(t) {
520
+ return t === "published" || t === "modified" ? "success" : "default";
521
+ }
522
+ function E(t) {
523
+ return T.value ? "—" : t.path === null ? a("panel.no-address") : `/${t.path}`;
524
+ }
525
+ function X(t) {
526
+ if (t.workplace === "remote") return a("vacancy.workplace.remote");
527
+ const u = t.city !== "" ? t.city : a("panel.no-city");
528
+ return t.workplace === "hybrid" ? `${u} · ${a("vacancy.workplace.hybrid")}` : u;
529
+ }
530
+ function Ue(t) {
531
+ return t.employment_types.map((u) => a(Nt(u))).join(", ");
532
+ }
533
+ function Be(t) {
534
+ return t.closed && M.value === "all" && !T.value;
535
+ }
536
+ const He = h(
537
+ () => v.value ? [{ key: "new", label: a("panel.new"), icon: "plus", primary: !0, run: () => {
538
+ H();
539
+ } }] : []
540
+ );
541
+ return (t, u) => (f(), z("div", St, [
542
+ d(e(je), {
543
+ view: b.value,
544
+ "onUpdate:view": u[4] || (u[4] = (o) => b.value = o),
545
+ title: w.value,
546
+ views: Z.value,
547
+ actions: He.value,
548
+ padding: "sm"
549
+ }, {
550
+ default: i(() => [
551
+ O("div", qt, [
552
+ d(e(Pe), {
553
+ modelValue: S.value,
554
+ "onUpdate:modelValue": u[0] || (u[0] = (o) => S.value = o),
555
+ class: "wx-vacancies__search",
556
+ size: "sm",
557
+ clearable: "",
558
+ placeholder: e(a)("panel.search"),
559
+ "aria-label": e(a)("panel.search")
560
+ }, {
561
+ prefix: i(() => [
562
+ d(e(se), {
563
+ name: "search",
564
+ size: "sm"
565
+ })
566
+ ]),
567
+ _: 1
568
+ }, 8, ["modelValue", "placeholder", "aria-label"]),
569
+ d(e(mt), {
570
+ title: e(a)("panel.filters"),
571
+ width: 280,
572
+ side: "bottom",
573
+ align: "end"
574
+ }, {
575
+ trigger: i(() => [
576
+ d(e(gt), {
577
+ class: "wx-vacancies__funnel",
578
+ value: Q.value.length,
579
+ hidden: Q.value.length === 0,
580
+ type: "primary",
581
+ label: e(a)("panel.filters")
582
+ }, {
583
+ default: i(() => [
584
+ d(e(wt), {
585
+ icon: "filter",
586
+ size: "sm",
587
+ title: e(a)("panel.filters")
588
+ }, null, 8, ["title"])
589
+ ]),
590
+ _: 1
591
+ }, 8, ["value", "hidden", "label"])
592
+ ]),
593
+ default: i(() => [
594
+ O("div", Dt, [
595
+ T.value ? R("", !0) : (f(), V(e(xe), {
596
+ key: 0,
597
+ label: e(a)("panel.filter-status")
598
+ }, {
599
+ default: i(() => [
600
+ d(e(Ve), {
601
+ "model-value": I.value === "" ? null : I.value,
602
+ options: U.value,
603
+ placeholder: e(a)("panel.any-status"),
604
+ clearable: "",
605
+ size: "sm",
606
+ "onUpdate:modelValue": u[1] || (u[1] = (o) => L("status", o))
607
+ }, null, 8, ["model-value", "options", "placeholder"])
608
+ ]),
609
+ _: 1
610
+ }, 8, ["label"])),
611
+ d(e(xe), {
612
+ label: e(a)("panel.filter-category")
613
+ }, {
614
+ default: i(() => [
615
+ d(e(Ve), {
616
+ "model-value": P.value,
617
+ options: N.value.categories.map((o) => ({ value: o.id, label: o.title })),
618
+ placeholder: e(a)("panel.any-category"),
619
+ clearable: "",
620
+ size: "sm",
621
+ "onUpdate:modelValue": u[2] || (u[2] = (o) => L("category", o))
622
+ }, null, 8, ["model-value", "options", "placeholder"])
623
+ ]),
624
+ _: 1
625
+ }, 8, ["label"]),
626
+ Q.value.length > 0 ? (f(), V(e(K), {
627
+ key: 1,
628
+ variant: "text",
629
+ size: "sm",
630
+ block: "",
631
+ onClick: ye
632
+ }, {
633
+ icon: i(() => [
634
+ d(e(se), { name: "close" })
635
+ ]),
636
+ default: i(() => [
637
+ k(" " + g(e(a)("panel.filters-reset")), 1)
638
+ ]),
639
+ _: 1
640
+ })) : R("", !0)
641
+ ])
642
+ ]),
643
+ _: 1
644
+ }, 8, ["title"])
645
+ ]),
646
+ Q.value.length > 0 ? (f(), z("div", Et, [
647
+ d(e(Ye), { filters: Q.value }, null, 8, ["filters"])
648
+ ])) : R("", !0),
649
+ q.value && l.value.length === 0 ? (f(), V(e(ce), {
650
+ key: 1,
651
+ class: "wx-vacancies__loading",
652
+ rows: 5
653
+ })) : l.value.length === 0 ? (f(), V(e(ze), {
654
+ key: 2,
655
+ title: ae.value,
656
+ description: M.value === "all" && !T.value && te.value ? e(a)("panel.empty-help") : void 0
657
+ }, null, 8, ["title", "description"])) : (f(), z(ee, { key: 3 }, [
658
+ d(e(bt), {
659
+ modelValue: l.value,
660
+ "onUpdate:modelValue": u[3] || (u[3] = (o) => l.value = o),
661
+ class: qe(["wx-vacancies__list", { "is-loading": q.value }]),
662
+ plain: "",
663
+ "item-key": "id",
664
+ handle: D.value ? "grip" : "row",
665
+ "item-label": (o) => o.title,
666
+ disabled: !D.value,
667
+ onMove: fe
668
+ }, {
669
+ default: i(({ item: o }) => [
670
+ (f(), V(rt(T.value ? "div" : "router-link"), ct({
671
+ class: ["wx-vacancy-row", { "is-closed": Be(o) }]
672
+ }, T.value ? {} : { to: { path: `${c.base}/${o.id}`, query: e(n).query } }), {
673
+ default: i(() => [
674
+ O("span", Ot, [
675
+ O("span", Pt, g(o.title), 1),
676
+ O("span", zt, g(E(o)), 1)
677
+ ]),
678
+ O("span", At, [
679
+ O("span", Mt, [
680
+ d(e(se), {
681
+ name: o.workplace === "remote" ? "monitor" : "map-pin",
682
+ size: "sm"
683
+ }, null, 8, ["name"]),
684
+ k(" " + g(X(o)), 1)
685
+ ]),
686
+ o.employment_types.length > 0 ? (f(), z("span", Lt, g(Ue(o)), 1)) : R("", !0),
687
+ o.valid_through ? (f(), V(e(We), {
688
+ key: 1,
689
+ content: e(a)("panel.until-help", { date: e(Le)(o.valid_through, W.value) })
690
+ }, {
691
+ default: i(() => [
692
+ O("span", Ft, [
693
+ d(e(se), {
694
+ name: "calendar",
695
+ size: "sm"
696
+ }),
697
+ k(" " + g(e(a)("panel.until", { date: e(Ct)(o.valid_through, W.value) })), 1)
698
+ ])
699
+ ]),
700
+ _: 2
701
+ }, 1032, ["content"])) : R("", !0)
702
+ ]),
703
+ O("span", Ut, [
704
+ (f(!0), z(ee, null, De(o.categories, ($e) => (f(), V(e(Y), {
705
+ key: $e.id,
706
+ size: "sm",
707
+ round: ""
708
+ }, {
709
+ default: i(() => [
710
+ k(g($e.title), 1)
711
+ ]),
712
+ _: 2
713
+ }, 1024))), 128)),
714
+ o.closed_reason ? (f(), V(e(We), {
715
+ key: 0,
716
+ content: e(a)(`panel.closed-${o.closed_reason}-help`)
717
+ }, {
718
+ default: i(() => [
719
+ d(e(Y), {
720
+ type: "warning",
721
+ size: "sm",
722
+ round: ""
723
+ }, {
724
+ default: i(() => [
725
+ k(g(e(a)(`panel.closed-${o.closed_reason}`)), 1)
726
+ ]),
727
+ _: 2
728
+ }, 1024)
729
+ ]),
730
+ _: 2
731
+ }, 1032, ["content"])) : R("", !0),
732
+ d(e(Y), {
733
+ type: x(o.status),
734
+ dot: "",
735
+ size: "sm"
736
+ }, {
737
+ default: i(() => [
738
+ k(g(e(a)(`panel.status-${o.status}`)), 1)
739
+ ]),
740
+ _: 2
741
+ }, 1032, ["type"]),
742
+ o.status === "modified" ? (f(), V(e(Y), {
743
+ key: 1,
744
+ type: "primary",
745
+ size: "sm",
746
+ round: ""
747
+ }, {
748
+ default: i(() => [
749
+ k(g(e(a)("panel.edits")), 1)
750
+ ]),
751
+ _: 1
752
+ })) : R("", !0)
753
+ ])
754
+ ]),
755
+ _: 2
756
+ }, 1040, ["class"]))
757
+ ]),
758
+ actions: i(({ item: o }) => [
759
+ d(e(Ge), {
760
+ actions: me(o),
761
+ label: o.title
762
+ }, null, 8, ["actions", "label"])
763
+ ]),
764
+ _: 1
765
+ }, 8, ["modelValue", "class", "handle", "item-label", "disabled"]),
766
+ v.value && !T.value ? (f(), V(e(Ae), {
767
+ key: 0,
768
+ class: "wx-vacancies__note",
769
+ type: "info",
770
+ description: he.value
771
+ }, null, 8, ["description"])) : R("", !0)
772
+ ], 64))
773
+ ]),
774
+ _: 1
775
+ }, 8, ["view", "title", "views", "actions"])
776
+ ]));
777
+ }
778
+ }), Te = (r, c) => {
779
+ const y = r.__vccOpts || r;
780
+ for (const [p, n] of c)
781
+ y[p] = n;
782
+ return y;
783
+ }, Ht = /* @__PURE__ */ Te(Bt, [["__scopeId", "data-v-41756f57"]]), Fe = /* @__PURE__ */ Symbol("wx-vacancy-editor");
784
+ function Kt(r) {
785
+ ut(Fe, r);
786
+ }
787
+ function jt() {
788
+ return dt(Fe, null);
789
+ }
790
+ const Yt = { class: "wx-vacancy-editor__word" }, Gt = 1200, Jt = /* @__PURE__ */ de({
791
+ __name: "VacancyEditorPage",
792
+ props: {
793
+ base: { default: "/vacancies" }
794
+ },
795
+ setup(r) {
796
+ const c = r, y = oe(), p = pe(y), n = Ee(), m = Oe(), a = _t(), C = Je();
797
+ ve();
798
+ const l = ue("webx-vacancies"), N = ke(), q = h(() => Number(n.params.id)), A = h(() => c.base), v = $(null), w = $({}), W = $(""), b = $(null), T = $(null), M = $(!0), P = $(!1), I = $(!1), F = $({}), S = $(null), Z = $(""), U = h(() => y.can("vacancies.manage")), te = h(() => !U.value || I.value), J = h(() => JSON.stringify(w.value)), D = h(() => Z.value !== "" && J.value !== Z.value), he = h(() => P.value ? "saving" : D.value ? "unsaved" : "saved"), ae = h(() => {
799
+ const s = w.value.title;
800
+ return xt(s, a.active.value, v.value?.title ?? "");
801
+ }), Q = h(() => {
802
+ const s = v.value;
803
+ if (!s) return "";
804
+ const x = [];
805
+ return s.valid_through !== null && !s.closed && x.push(
806
+ l("editor.open-until", { date: Le(s.valid_through, y.i18n.state.locale) })
807
+ ), (s.status === "published" || s.status === "modified") && x.push(l("editor.live-since", { date: C.short(s.published_at) })), x.join(" · ");
808
+ });
809
+ Qe({ type: "vacancy", id: h(() => v.value?.id ?? null) }), Xe({
810
+ values: w,
811
+ prefix: b,
812
+ path: h(() => v.value?.path),
813
+ moving: () => l("editor.address-moving")
814
+ }), Kt({ vacancy: v, canManage: U.value, reload: () => B(!0) });
815
+ function j(s) {
816
+ const x = s.values;
817
+ v.value = s.vacancy, w.value = x, W.value = s.revision, b.value = s.prefix, T.value = s.preview_url, Z.value = JSON.stringify(x), S.value = null;
818
+ }
819
+ async function B(s = !1) {
820
+ s || (M.value = !0);
821
+ try {
822
+ j(await p.get(q.value));
823
+ } catch (x) {
824
+ _.danger(N(x)), m.push(A.value);
825
+ } finally {
826
+ M.value = !1;
827
+ }
828
+ }
829
+ let L;
830
+ function ye() {
831
+ !U.value || S.value || !D.value || (clearTimeout(L), L = setTimeout(() => {
832
+ H();
833
+ }, Gt));
834
+ }
835
+ function ne() {
836
+ !U.value || S.value || !D.value || P.value || (clearTimeout(L), H());
837
+ }
838
+ async function H() {
839
+ if (!v.value || P.value || !U.value) return;
840
+ clearTimeout(L);
841
+ const s = J.value, x = w.value;
842
+ P.value = !0, F.value = {};
843
+ try {
844
+ const E = await p.save(v.value.id, { values: x, revision: W.value });
845
+ v.value = E.vacancy, W.value = E.revision, b.value = E.prefix, T.value = E.preview_url, S.value = null, J.value === s && (Z.value = s);
846
+ } catch (E) {
847
+ const X = E;
848
+ X.status === 409 && X.body?.data ? S.value = X.body : X.body?.errors ? (F.value = X.body.errors, _.danger(l("editor.save-failed"))) : _.danger(N(E));
849
+ } finally {
850
+ P.value = !1;
851
+ }
852
+ }
853
+ async function fe() {
854
+ await G({
855
+ title: l("editor.conflict-theirs-title"),
856
+ message: l("editor.conflict-theirs-text"),
857
+ confirmText: l("editor.conflict-theirs"),
858
+ cancelText: l("panel.cancel"),
859
+ tone: "danger"
860
+ }) && await B(!0);
861
+ }
862
+ async function le() {
863
+ const s = S.value;
864
+ s && (W.value = s.data.revision, S.value = null, await H());
865
+ }
866
+ async function me() {
867
+ if (!(!v.value || !await G({
868
+ title: l("editor.discard-title"),
869
+ message: l("editor.discard-text"),
870
+ confirmText: l("editor.discard"),
871
+ cancelText: l("panel.cancel"),
872
+ tone: "danger"
873
+ }))) {
874
+ I.value = !0;
875
+ try {
876
+ j(await p.discard(v.value.id)), _.success(l("editor.discarded"));
877
+ } catch (x) {
878
+ _.danger(N(x));
879
+ } finally {
880
+ I.value = !1;
881
+ }
882
+ }
883
+ }
884
+ async function ge() {
885
+ const s = v.value;
886
+ if (!(!s || !await G({
887
+ title: l("editor.publish-title", { title: ae.value || s.title }),
888
+ message: s.path === null ? l("editor.publish-nowhere") : l("editor.publish-text", { address: `/${s.path}` }),
889
+ confirmText: l("panel.publish"),
890
+ cancelText: l("panel.cancel")
891
+ })) && (D.value && await H(), !S.value)) {
892
+ I.value = !0;
893
+ try {
894
+ await p.publish(s.id), await B(!0), _.success(l("panel.published"));
895
+ } catch (E) {
896
+ _.danger(N(E));
897
+ } finally {
898
+ I.value = !1;
899
+ }
900
+ }
901
+ }
902
+ async function we() {
903
+ const s = v.value;
904
+ if (s && (D.value && await H(), !(S.value || D.value))) {
905
+ I.value = !0;
906
+ try {
907
+ const x = await p.duplicate(s.id);
908
+ _.success(l("panel.duplicated")), await m.push({ path: `${A.value}/${x.vacancy.id}`, query: { ...n.query } });
909
+ } catch (x) {
910
+ _.danger(N(x));
911
+ } finally {
912
+ I.value = !1;
913
+ }
914
+ }
915
+ }
916
+ function be() {
917
+ const s = v.value?.status;
918
+ return s === "published" || s === "modified" ? "success" : "default";
919
+ }
920
+ function re(s) {
921
+ D.value && s.preventDefault();
922
+ }
923
+ ie(J, ye), ie(q, () => {
924
+ B();
925
+ }), Re(() => {
926
+ B(), window.addEventListener("beforeunload", re);
927
+ }), Se(() => {
928
+ clearTimeout(L), window.removeEventListener("beforeunload", re);
929
+ }), pt(async () => !D.value || !U.value || (await H(), !D.value) ? !0 : await G({
930
+ title: l("editor.leave-title"),
931
+ message: l("editor.leave-text"),
932
+ confirmText: l("editor.leave"),
933
+ cancelText: l("panel.cancel"),
934
+ tone: "danger"
935
+ }));
936
+ const _e = h(() => {
937
+ const s = [];
938
+ return T.value && s.push({ key: "preview", label: l("editor.preview"), icon: "eye", href: T.value }), v.value?.url && v.value.status !== "draft" && s.push({
939
+ key: "site",
940
+ label: l("panel.open-on-site"),
941
+ icon: "link",
942
+ href: v.value.url
943
+ }), v.value?.status === "modified" && s.push({
944
+ key: "discard",
945
+ label: l("editor.discard"),
946
+ icon: "refresh",
947
+ danger: !0,
948
+ menu: !0,
949
+ run: () => {
950
+ me();
951
+ }
952
+ }), s;
953
+ });
954
+ return (s, x) => (f(), z("div", {
955
+ class: "wx-vacancy-editor",
956
+ onFocusout: ne
957
+ }, [
958
+ M.value || !v.value ? (f(), z(ee, { key: 0 }, [
959
+ d(e(ce), {
960
+ class: "wx-vacancy-editor__ghost",
961
+ title: "",
962
+ rows: 1
963
+ }),
964
+ d(e(kt), null, {
965
+ default: i(() => [
966
+ d(e(ce), { rows: 8 })
967
+ ]),
968
+ _: 1
969
+ })
970
+ ], 64)) : (f(), z(ee, { key: 1 }, [
971
+ d(e(Ze), {
972
+ divider: "",
973
+ back: A.value,
974
+ "back-label": e(l)("module.vacancies"),
975
+ title: ae.value || e(l)("editor.untitled"),
976
+ subtitle: Q.value,
977
+ actions: _e.value
978
+ }, {
979
+ trail: i(() => [
980
+ d(e(Tt), {
981
+ size: "sm",
982
+ label: e(l)("editor.trail")
983
+ }, {
984
+ default: i(() => [
985
+ d(e(Ce), {
986
+ as: "router-link",
987
+ to: A.value
988
+ }, {
989
+ default: i(() => [
990
+ k(g(e(l)("module.vacancies")), 1)
991
+ ]),
992
+ _: 1
993
+ }, 8, ["to"]),
994
+ d(e(Ce), { current: "" }, {
995
+ default: i(() => [
996
+ k(g(ae.value || e(l)("editor.untitled")), 1)
997
+ ]),
998
+ _: 1
999
+ })
1000
+ ]),
1001
+ _: 1
1002
+ }, 8, ["label"])
1003
+ ]),
1004
+ "title-after": i(() => [
1005
+ d(e(Y), {
1006
+ type: be(),
1007
+ dot: ""
1008
+ }, {
1009
+ default: i(() => [
1010
+ k(g(e(l)(`panel.status-${v.value.status}`)), 1)
1011
+ ]),
1012
+ _: 1
1013
+ }, 8, ["type"]),
1014
+ v.value.status === "modified" ? (f(), V(e(Y), {
1015
+ key: 0,
1016
+ type: "primary",
1017
+ round: ""
1018
+ }, {
1019
+ default: i(() => [
1020
+ k(g(e(l)("panel.edits")), 1)
1021
+ ]),
1022
+ _: 1
1023
+ })) : R("", !0),
1024
+ v.value.closed_reason ? (f(), V(e(Y), {
1025
+ key: 1,
1026
+ type: "warning",
1027
+ round: ""
1028
+ }, {
1029
+ default: i(() => [
1030
+ k(g(e(l)(`panel.closed-${v.value.closed_reason}`)), 1)
1031
+ ]),
1032
+ _: 1
1033
+ })) : R("", !0)
1034
+ ]),
1035
+ _: 1
1036
+ }, 8, ["back", "back-label", "title", "subtitle", "actions"]),
1037
+ S.value ? (f(), V(e(Ae), {
1038
+ key: 0,
1039
+ type: "warning",
1040
+ title: e(l)("editor.conflict-title"),
1041
+ description: S.value.message
1042
+ }, {
1043
+ actions: i(() => [
1044
+ d(e(K), {
1045
+ size: "sm",
1046
+ variant: "outline",
1047
+ onClick: fe
1048
+ }, {
1049
+ default: i(() => [
1050
+ k(g(e(l)("editor.conflict-theirs")), 1)
1051
+ ]),
1052
+ _: 1
1053
+ }),
1054
+ d(e(K), {
1055
+ size: "sm",
1056
+ type: "primary",
1057
+ onClick: le
1058
+ }, {
1059
+ default: i(() => [
1060
+ k(g(e(l)("editor.conflict-mine")), 1)
1061
+ ]),
1062
+ _: 1
1063
+ })
1064
+ ]),
1065
+ _: 1
1066
+ }, 8, ["title", "description"])) : R("", !0),
1067
+ d(e(et), {
1068
+ modelValue: w.value,
1069
+ "onUpdate:modelValue": x[0] || (x[0] = (E) => w.value = E),
1070
+ name: "vacancies.form",
1071
+ errors: F.value,
1072
+ disabled: te.value
1073
+ }, null, 8, ["modelValue", "errors", "disabled"]),
1074
+ U.value ? (f(), V(e($t), { key: 1 }, {
1075
+ state: i(() => [
1076
+ d(e(tt), { state: he.value }, null, 8, ["state"])
1077
+ ]),
1078
+ default: i(() => [
1079
+ d(e(K), {
1080
+ variant: "text",
1081
+ disabled: I.value,
1082
+ "aria-label": e(l)("panel.duplicate"),
1083
+ onClick: we
1084
+ }, {
1085
+ icon: i(() => [
1086
+ d(e(se), { name: "copy" })
1087
+ ]),
1088
+ default: i(() => [
1089
+ O("span", Yt, g(e(l)("panel.duplicate")), 1)
1090
+ ]),
1091
+ _: 1
1092
+ }, 8, ["disabled", "aria-label"]),
1093
+ d(e(K), {
1094
+ variant: "outline",
1095
+ loading: P.value,
1096
+ disabled: !D.value,
1097
+ onClick: H
1098
+ }, {
1099
+ default: i(() => [
1100
+ k(g(e(l)("editor.save")), 1)
1101
+ ]),
1102
+ _: 1
1103
+ }, 8, ["loading", "disabled"]),
1104
+ d(e(K), {
1105
+ type: "primary",
1106
+ loading: I.value,
1107
+ disabled: v.value.status === "published" && !D.value,
1108
+ onClick: ge
1109
+ }, {
1110
+ default: i(() => [
1111
+ k(g(e(l)("panel.publish")), 1)
1112
+ ]),
1113
+ _: 1
1114
+ }, 8, ["loading", "disabled"])
1115
+ ]),
1116
+ _: 1
1117
+ })) : R("", !0)
1118
+ ], 64))
1119
+ ], 32));
1120
+ }
1121
+ }), Qt = /* @__PURE__ */ Te(Jt, [["__scopeId", "data-v-04fdc324"]]), Xt = { class: "wx-vacancy-history" }, Zt = { class: "wx-vacancy-history__number" }, ea = { class: "wx-vacancy-history__who" }, ta = /* @__PURE__ */ de({
1122
+ name: "WxVacancyHistory",
1123
+ __name: "VacancyHistory",
1124
+ setup(r) {
1125
+ const c = oe(), y = pe(c), p = jt();
1126
+ ve();
1127
+ const n = ue("webx-vacancies"), m = ke(), a = $(null), C = $(!1), l = h(() => p?.vacancy.value ?? null), N = h(() => p?.canManage ?? !1), q = h(
1128
+ () => l.value?.status === "published" || l.value?.status === "modified" ? a.value?.[0]?.number ?? null : null
1129
+ );
1130
+ async function A() {
1131
+ const w = l.value;
1132
+ if (w)
1133
+ try {
1134
+ a.value = await y.versions(w.id);
1135
+ } catch (W) {
1136
+ a.value = [], _.danger(m(W));
1137
+ }
1138
+ }
1139
+ async function v(w) {
1140
+ const W = l.value;
1141
+ if (!(!W || !await G({
1142
+ title: n("editor.restore-title", { number: w.number }),
1143
+ message: n("editor.restore-text"),
1144
+ confirmText: n("editor.restore-version"),
1145
+ cancelText: n("panel.cancel")
1146
+ }))) {
1147
+ C.value = !0;
1148
+ try {
1149
+ await y.restoreVersion(W.id, w.number), await p?.reload(), _.success(n("editor.restored-version", { number: w.number }));
1150
+ } catch (T) {
1151
+ _.danger(m(T));
1152
+ } finally {
1153
+ C.value = !1;
1154
+ }
1155
+ }
1156
+ }
1157
+ return ie(
1158
+ () => [l.value?.id, l.value?.published_at, l.value?.updated_at],
1159
+ () => {
1160
+ A();
1161
+ },
1162
+ { immediate: !0 }
1163
+ ), (w, W) => (f(), z("div", Xt, [
1164
+ a.value === null ? (f(), V(e(ce), {
1165
+ key: 0,
1166
+ class: "wx-vacancy-history__ghost",
1167
+ rows: 3
1168
+ })) : a.value.length === 0 ? (f(), V(e(ze), {
1169
+ key: 1,
1170
+ description: e(n)("editor.history-empty")
1171
+ }, null, 8, ["description"])) : (f(!0), z(ee, { key: 2 }, De(a.value, (b) => (f(), z("div", {
1172
+ key: b.number,
1173
+ class: qe(["wx-vacancy-history__row", { "is-live": b.number === q.value }])
1174
+ }, [
1175
+ O("code", Zt, g(e(n)("editor.version", { number: b.number })), 1),
1176
+ O("div", ea, [
1177
+ b.created_at ? (f(), V(e(at), {
1178
+ key: 0,
1179
+ value: b.created_at,
1180
+ size: "md",
1181
+ tone: "default"
1182
+ }, null, 8, ["value"])) : R("", !0),
1183
+ d(e(Vt), {
1184
+ size: "sm",
1185
+ tone: "muted"
1186
+ }, {
1187
+ default: i(() => [
1188
+ k(g(b.author ?? e(n)(`editor.source-${b.source}`)) + " ", 1),
1189
+ b.comment ? (f(), z(ee, { key: 0 }, [
1190
+ k(" · " + g(b.comment), 1)
1191
+ ], 64)) : R("", !0)
1192
+ ]),
1193
+ _: 2
1194
+ }, 1024)
1195
+ ]),
1196
+ b.number === q.value ? (f(), V(e(Y), {
1197
+ key: 0,
1198
+ type: "success",
1199
+ dot: ""
1200
+ }, {
1201
+ default: i(() => [
1202
+ k(g(e(n)("editor.version-live")), 1)
1203
+ ]),
1204
+ _: 1
1205
+ })) : R("", !0),
1206
+ N.value && b.number !== q.value ? (f(), V(e(K), {
1207
+ key: 1,
1208
+ size: "sm",
1209
+ variant: "outline",
1210
+ loading: C.value,
1211
+ onClick: (T) => v(b)
1212
+ }, {
1213
+ default: i(() => [
1214
+ k(g(e(n)("editor.restore-version")), 1)
1215
+ ]),
1216
+ _: 1
1217
+ }, 8, ["loading", "onClick"])) : R("", !0)
1218
+ ], 2))), 128))
1219
+ ]));
1220
+ }
1221
+ }), aa = /* @__PURE__ */ Te(ta, [["__scopeId", "data-v-77bc9b70"]]);
1222
+ function na(r = "/vacancies") {
1223
+ return {
1224
+ api: "vacancies/categories",
1225
+ path: `${r}/categories`,
1226
+ name: "webx.vacancies.categories",
1227
+ module: "vacancy-categories",
1228
+ screen: "vacancies.category-form",
1229
+ manage: "vacancies.categories.manage",
1230
+ count: "vacancies_count",
1231
+ // Every vacancy of the category, closed ones included: "what is filed here" is the question.
1232
+ items: (c) => ({ path: r, query: { category: String(c), view: "all" } }),
1233
+ words: {
1234
+ new: "webx-vacancies::category.new",
1235
+ empty: "webx-vacancies::category.empty",
1236
+ "empty-help": "webx-vacancies::category.empty-help",
1237
+ order: "webx-vacancies::category.order",
1238
+ hidden: "webx-vacancies::category.hidden",
1239
+ "no-address": "webx-vacancies::category.no-page",
1240
+ count: "webx-vacancies::category.vacancies",
1241
+ "show-items": "webx-vacancies::category.show-vacancies",
1242
+ "delete-blocked": "webx-vacancies::category.delete-blocked",
1243
+ "delete-text": "webx-vacancies::category.delete-text",
1244
+ deleted: "webx-vacancies::category.deleted",
1245
+ saved: "webx-vacancies::category.saved",
1246
+ "field-title": "webx-vacancies::category.field-title",
1247
+ "field-slug": "webx-vacancies::category.field-slug"
1248
+ }
1249
+ };
1250
+ }
1251
+ function ra(r = {}) {
1252
+ const c = r.path ?? "/vacancies";
1253
+ return [
1254
+ {
1255
+ id: "vacancies",
1256
+ path: c,
1257
+ routes: [
1258
+ { path: c, name: "webx.vacancies", component: Ht, props: { base: c } },
1259
+ {
1260
+ path: `${c}/:id(\\d+)`,
1261
+ name: "webx.vacancies.edit",
1262
+ component: Qt,
1263
+ props: { base: c }
1264
+ }
1265
+ ],
1266
+ /*
1267
+ * The one part of `vacancies.form` only this module can draw. Everything else on it is the
1268
+ * panel's (`wx-slug`, `wx-categories`, `wx-relations`, `wx-rich-text`, `wx-repeater`,
1269
+ * `wx-date-picker`, `wx-checkbox-group`).
1270
+ */
1271
+ types: {
1272
+ "wx-vacancy-history": { component: aa, kind: "display" }
1273
+ }
1274
+ },
1275
+ {
1276
+ id: "vacancy-categories",
1277
+ path: `${c}/categories`,
1278
+ routes: nt(na(c))
1279
+ }
1280
+ ];
1281
+ }
1282
+ export {
1283
+ Ie as VACANCIES_API,
1284
+ Ht as WxVacanciesPage,
1285
+ Rt as WxVacancyCreateDialog,
1286
+ Qt as WxVacancyEditorPage,
1287
+ aa as WxVacancyHistory,
1288
+ pe as createVacanciesApi,
1289
+ Kt as provideVacancyEditor,
1290
+ jt as useVacancyEditor,
1291
+ ra as vacancies,
1292
+ It as vacanciesMessages,
1293
+ na as vacancyCategoriesOptions,
1294
+ Fe as vacancyEditorKey
1295
+ };
1296
+ //# sourceMappingURL=index.js.map