@webx-ui/module-auth 0.12.0 → 0.13.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 CHANGED
@@ -1,3229 +1,29 @@
1
- import { inject as xe, defineComponent as Q, computed as L, ref as W, useTemplateRef as oe, onBeforeUnmount as nt, resolveComponent as Y, openBlock as m, createBlock as _, withCtx as t, createVNode as a, withModifiers as Oe, createCommentVNode as E, createElementVNode as S, createTextVNode as c, toDisplayString as i, watch as de, unref as e, isRef as Ve, normalizeClass as Be, createElementBlock as H, resolveDynamicComponent as Ee, createSlots as Ae, Fragment as ue, renderList as Ce, onMounted as Ie, h as De } from "vue";
2
- import { useTranslate as G, HttpError as st, useAdmin as X, useI18n as Ne, useErrorText as re, rowMenuWidth as ot, WxDate as ae, WxRowMenu as Se, WxFilterChips as Me, WxListScreen as Ke, WxScreen as it, useTheme as ut } from "@webx-ui/module-admin";
3
- import { useRouter as rt, useRoute as ct } from "vue-router";
4
- import { useModal as _e, WxDialog as be, WxFormItem as M, WxInput as le, WxSelect as ne, WxSpace as se, WxCheckbox as Le, WxText as B, WxButton as N, toast as K, useElementWidth as ge, WxTable as ke, WxEntityCard as we, WxBadge as q, WxAvatar as dt, WxIcon as ee, confirm as ze, WxAlert as qe, WxRadioGroup as mt, createModal as he, WxHeading as me, WxCard as $e, WxSkeleton as vt, WxTabs as pt, WxTab as ye, WxThemeSwitch as ft } from "@webx-ui/core";
5
- const He = /* @__PURE__ */ Symbol("webx-auth");
6
- function We() {
7
- const s = xe(He, null);
8
- if (s === null)
9
- throw new Error("useAuth() was called outside a panel that installed the auth plugin.");
10
- return s;
11
- }
12
- function yt(s) {
13
- const r = `${s.apiPath}/auth`;
14
- return {
15
- async me() {
16
- try {
17
- return (await s.http.get(`${r}/me`)).data;
18
- } catch (l) {
19
- if (_t(l))
20
- return null;
21
- throw l;
22
- }
23
- },
24
- async login(l) {
25
- const u = await s.http.post(`${r}/login`, {
26
- email: l.email,
27
- password: l.password,
28
- remember: l.remember ?? !1
29
- });
30
- return s.setUser(u.data), await s.reload(), u.data;
31
- },
32
- async setLocale(l) {
33
- const u = await s.http.put(`${r}/locale`, { locale: l });
34
- s.setUser(u.data), await s.setLocale(l);
35
- },
36
- async setTheme(l) {
37
- const u = await s.http.put(`${r}/theme`, {
38
- theme: l === "system" ? null : l
39
- });
40
- s.setUser(u.data);
41
- },
42
- async setSiteBar(l) {
43
- const u = await s.http.put(`${r}/site-bar`, { enabled: l });
44
- s.setUser(u.data);
45
- },
46
- async updateProfile(l) {
47
- const u = await s.http.put(
48
- `${r}/me`,
49
- l
50
- );
51
- return s.setUser(u.data), u.data;
52
- },
53
- async logout() {
54
- try {
55
- await s.http.post(`${r}/logout`);
56
- } finally {
57
- s.setUser(null), s.state.status = "unauthenticated", s.state.manifest = null;
58
- }
59
- }
60
- };
61
- }
62
- const je = /* @__PURE__ */ Symbol("webx-auth-avatar"), Ge = /* @__PURE__ */ Symbol("webx-auth-avatar-field");
63
- function ht(s, r, l = null, u = null) {
64
- s.provide(He, r), s.provide(je, l), s.provide(Ge, u);
65
- }
66
- function _t(s) {
67
- return typeof s == "object" && s !== null && "status" in s && s.status === 401;
68
- }
69
- const bt = ["title", "aria-label", "aria-pressed"], gt = /* @__PURE__ */ Q({
70
- __name: "LoginCard",
71
- props: {
72
- emailLabel: { default: void 0 },
73
- passwordLabel: { default: void 0 },
74
- rememberLabel: { default: void 0 },
75
- submitLabel: { default: void 0 },
76
- capsLockWarning: { default: void 0 },
77
- throttleMessage: { default: void 0 },
78
- revealLabel: { default: void 0 },
79
- hideLabel: { default: void 0 },
80
- remember: { type: Boolean, default: !0 },
81
- autofocus: { type: Boolean, default: !0 }
82
- },
83
- emits: ["success"],
84
- setup(s, { expose: r, emit: l }) {
85
- const u = s, v = l, y = We(), A = G("webx-auth"), o = L(() => ({
86
- email: u.emailLabel ?? A("card.email"),
87
- password: u.passwordLabel ?? A("card.password"),
88
- remember: u.rememberLabel ?? A("card.remember"),
89
- submit: u.submitLabel ?? A("card.submit"),
90
- capsLock: u.capsLockWarning ?? A("card.caps-lock"),
91
- reveal: u.revealLabel ?? A("card.reveal"),
92
- hide: u.hideLabel ?? A("card.hide")
93
- })), h = W(""), U = W(""), d = W(!1), k = W(!1), V = W(!1), p = W(!1), g = W(""), b = W({}), w = W(0), F = oe("emailField");
94
- let C = null;
95
- nt(O);
96
- const D = L(() => w.value > 0), n = L(
97
- () => u.throttleMessage === void 0 ? A("card.throttled", { seconds: w.value }) : u.throttleMessage.replace(":seconds", String(w.value))
98
- );
99
- async function x() {
100
- if (!(k.value || D.value)) {
101
- k.value = !0, g.value = "", b.value = {};
102
- try {
103
- await y.login({
104
- email: h.value,
105
- password: U.value,
106
- remember: d.value
107
- }), U.value = "", v("success");
108
- } catch (f) {
109
- P(f);
110
- } finally {
111
- k.value = !1;
112
- }
113
- }
114
- }
115
- function P(f) {
116
- if (!(f instanceof st)) {
117
- g.value = f instanceof Error ? f.message : String(f);
118
- return;
119
- }
120
- if (f.isValidation) {
121
- b.value = f.errors;
122
- return;
123
- }
124
- if (f.isThrottled) {
125
- J(f.retryAfter ?? 60);
126
- return;
127
- }
128
- g.value = f.message;
129
- }
130
- function J(f) {
131
- O(), w.value = f, C = setInterval(() => {
132
- w.value -= 1, w.value <= 0 && O();
133
- }, 1e3);
134
- }
135
- function O() {
136
- C !== null && (clearInterval(C), C = null), w.value = 0;
137
- }
138
- function z(f) {
139
- p.value = f.getModifierState("CapsLock");
140
- }
141
- return r({ focus: () => F.value?.focus() }), (f, R) => {
142
- const $ = Y("wx-alert"), Z = Y("wx-icon"), fe = Y("wx-input"), I = Y("wx-form-item"), j = Y("wx-checkbox"), T = Y("wx-button"), ie = Y("wx-form"), lt = Y("wx-card");
143
- return m(), _(lt, {
144
- class: "wx-login",
145
- padding: 24
146
- }, {
147
- default: t(() => [
148
- a(ie, {
149
- errors: b.value,
150
- disabled: k.value,
151
- gap: "md",
152
- onSubmit: Oe(x, ["prevent"])
153
- }, {
154
- default: t(() => [
155
- g.value !== "" ? (m(), _($, {
156
- key: 0,
157
- type: "danger",
158
- variant: "soft",
159
- live: "",
160
- description: g.value,
161
- class: "wx-login__message"
162
- }, null, 8, ["description"])) : D.value ? (m(), _($, {
163
- key: 1,
164
- type: "warning",
165
- variant: "soft",
166
- live: "",
167
- description: n.value,
168
- class: "wx-login__message"
169
- }, null, 8, ["description"])) : E("", !0),
170
- a(I, { name: "email" }, {
171
- default: t(() => [
172
- a(fe, {
173
- ref_key: "emailField",
174
- ref: F,
175
- modelValue: h.value,
176
- "onUpdate:modelValue": R[0] || (R[0] = (ce) => h.value = ce),
177
- type: "email",
178
- placeholder: o.value.email,
179
- "aria-label": o.value.email,
180
- autocomplete: "username",
181
- autofocus: s.autofocus,
182
- inputmode: "email",
183
- size: "lg"
184
- }, {
185
- prefix: t(() => [
186
- a(Z, { name: "mail" })
187
- ]),
188
- _: 1
189
- }, 8, ["modelValue", "placeholder", "aria-label", "autofocus"])
190
- ]),
191
- _: 1
192
- }),
193
- a(I, {
194
- name: "password",
195
- help: p.value ? o.value.capsLock : void 0
196
- }, {
197
- default: t(() => [
198
- a(fe, {
199
- modelValue: U.value,
200
- "onUpdate:modelValue": R[2] || (R[2] = (ce) => U.value = ce),
201
- type: V.value ? "text" : "password",
202
- placeholder: o.value.password,
203
- "aria-label": o.value.password,
204
- autocomplete: "current-password",
205
- size: "lg",
206
- onKeydown: z,
207
- onKeyup: z
208
- }, {
209
- prefix: t(() => [
210
- a(Z, { name: "lock" })
211
- ]),
212
- suffix: t(() => [
213
- S("button", {
214
- type: "button",
215
- class: "wx-login__reveal",
216
- title: V.value ? o.value.hide : o.value.reveal,
217
- "aria-label": V.value ? o.value.hide : o.value.reveal,
218
- "aria-pressed": V.value,
219
- tabindex: "-1",
220
- onClick: R[1] || (R[1] = (ce) => V.value = !V.value)
221
- }, [
222
- a(Z, {
223
- name: V.value ? "eye-off" : "eye"
224
- }, null, 8, ["name"])
225
- ], 8, bt)
226
- ]),
227
- _: 1
228
- }, 8, ["modelValue", "type", "placeholder", "aria-label"])
229
- ]),
230
- _: 1
231
- }, 8, ["help"]),
232
- s.remember ? (m(), _(j, {
233
- key: 2,
234
- modelValue: d.value,
235
- "onUpdate:modelValue": R[3] || (R[3] = (ce) => d.value = ce),
236
- label: o.value.remember,
237
- class: "wx-login__remember"
238
- }, null, 8, ["modelValue", "label"])) : E("", !0),
239
- a(T, {
240
- type: "primary",
241
- "native-type": "submit",
242
- size: "lg",
243
- block: "",
244
- loading: k.value,
245
- disabled: D.value
246
- }, {
247
- default: t(() => [
248
- c(i(o.value.submit), 1)
249
- ]),
250
- _: 1
251
- }, 8, ["loading", "disabled"])
252
- ]),
253
- _: 1
254
- }, 8, ["errors", "disabled"])
255
- ]),
256
- _: 1
257
- });
258
- };
259
- }
260
- }), ve = (s, r) => {
261
- const l = s.__vccOpts || s;
262
- for (const [u, v] of r)
263
- l[u] = v;
264
- return l;
265
- }, kt = /* @__PURE__ */ ve(gt, [["__scopeId", "data-v-3c206e31"]]);
266
- function Ye(s) {
267
- return s.types["wx-media"]?.component ?? null;
268
- }
269
- function Je(s) {
270
- const r = s.assetUrls;
271
- return r ? async (l) => (await r([l]))[l] ?? null : null;
272
- }
273
- const Qe = {
274
- card: {
275
- email: "Email",
276
- password: "Password",
277
- remember: "Stay signed in",
278
- submit: "Sign in",
279
- "caps-lock": "Caps Lock is on.",
280
- reveal: "Show the password",
281
- hide: "Hide the password",
282
- throttled: "Too many attempts. Try again in :seconds s.",
283
- failed: "Those details do not match an account."
284
- },
285
- admins: {
286
- title: "Administrators",
287
- "filter-role": "Role",
288
- "filter-state": "State",
289
- search: "Search administrators",
290
- new: "New administrator",
291
- edit: "Edit administrator",
292
- // The same two, short enough for a button on a phone and for a dialog's heading.
293
- "new-short": "Add",
294
- "edit-short": "Edit",
295
- name: "Name",
296
- email: "Email",
297
- password: "Password",
298
- "password-hint": "At least 12 characters",
299
- "password-keep": "Leave blank to keep the current one",
300
- avatar: "Photo",
301
- roles: "Roles",
302
- "no-roles": "No roles",
303
- active: "Active",
304
- super: "Super administrator",
305
- "super-hint": "Answers yes to everything, whatever the roles say",
306
- locale: "Panel language",
307
- "locale-auto": "Follow the browser",
308
- "last-login": "Last signed in",
309
- save: "Save",
310
- cancel: "Cancel",
311
- delete: "Delete",
312
- "delete-title": "Delete :name?",
313
- "delete-text": "They lose access at once. What they have written stays.",
314
- "all-roles": "All roles",
315
- "any-state": "Active and not",
316
- "only-active": "Active only",
317
- "only-inactive": "Switched off only",
318
- empty: "Nobody matches that",
319
- "select-one": "Choose an administrator",
320
- "select-many": "Choose administrators",
321
- chosen: "Chosen: :count",
322
- created: "Administrator created",
323
- updated: "Administrator saved",
324
- deleted: "Administrator deleted"
325
- },
326
- // The trail of what agents did through the panel: the view next to the administrators.
327
- calls: {
328
- title: "Agent calls",
329
- when: "When",
330
- who: "Who",
331
- client: "Client",
332
- tool: "Tool",
333
- outcome: "Outcome",
334
- took: "Took",
335
- ms: ":count ms",
336
- answered: "Answered",
337
- refused: "Refused",
338
- "dry-run": "Dry run",
339
- local: "Local server",
340
- deleted: "Administrator #:id",
341
- "filter-user": "Administrator",
342
- "filter-tool": "Tool",
343
- "filter-outcome": "Outcome",
344
- everybody: "Everybody",
345
- "all-tools": "All tools",
346
- "any-outcome": "Any outcome",
347
- "only-answered": "Answered only",
348
- "only-refused": "Refused only",
349
- "only-dry": "Dry runs only",
350
- arguments: "Arguments",
351
- "no-arguments": "Called with no arguments",
352
- request: "The agent's request",
353
- "request-hint": "What the agent passed to the tool. The answer is not kept.",
354
- error: "Refused with",
355
- empty: "No calls match"
356
- },
357
- // The connections tab and the page that tells somebody how to make one.
358
- connections: {
359
- title: "Connections",
360
- client: "Client",
361
- allowed: "What is allowed",
362
- connected: "Connected",
363
- "last-used": "Last used",
364
- who: "Administrator",
365
- full: "Everything :name can do",
366
- "full-you": "Everything you can do",
367
- "read-only": "Reading only",
368
- "returns-to": "Answers go to :host",
369
- disconnect: "Disconnect",
370
- disconnected: "Disconnected",
371
- "never-used": "Never",
372
- empty: "No agents are connected",
373
- "empty-all": "Nobody has connected an agent",
374
- "confirm-title": "Disconnect :client?",
375
- "confirm-text": "It loses access at once, including the month of refreshing it was given. Connecting it again takes three clicks.",
376
- confirm: "Disconnect",
377
- cancel: "Cancel",
378
- done: ":client is disconnected",
379
- deleted: "Administrator #:id"
380
- },
381
- // Keys for programs, issued and revoked under Administrators → Keys.
382
- keys: {
383
- title: "Keys",
384
- issue: "Issue a key",
385
- "issue-short": "Issue",
386
- lead: "A key lets a program — a queue watcher, a nightly import — work in this panel without a browser. It acts as the administrator you choose and can never do more than they may. A key is a program, not a person: what a module keeps for a person, such as a stage checked by hand, it cannot do.",
387
- name: "Name",
388
- "name-hint": 'What the program is, so that the list says it: "queue watcher", "nightly import".',
389
- who: "Acts as",
390
- "who-hint": "Everything the key changes is done in this administrator's name, within their permissions.",
391
- allowed: "What is allowed",
392
- everything: "Everything the administrator may do",
393
- chosen: "Only the scopes chosen below",
394
- scopes: "Scopes",
395
- "scopes-hint": "A module installed later is out of reach until a new key names it.",
396
- "scopes-required": "Choose at least one scope.",
397
- lifetime: "Lives for",
398
- "lifetime-hint": "A key cannot be extended: issue a new one before this one runs out, then revoke the old one.",
399
- "days-30": "30 days",
400
- "days-90": "90 days",
401
- "days-365": "1 year",
402
- "days-1095": "3 years",
403
- "days-3650": "10 years",
404
- "issued-title": "Copy the key now",
405
- "issued-text": "This is the only time the key is shown. Nobody can see it again — not here, not on the server. If it is lost, revoke it and issue a new one.",
406
- secret: "Key",
407
- copy: "Copy",
408
- copied: "Copied",
409
- "copy-failed": "Could not reach the clipboard. Select the key and copy it by hand.",
410
- address: "Server address",
411
- "header-hint": "The program sends the key in a header: Authorization: Bearer <key>.",
412
- done: "Done",
413
- cancel: "Cancel",
414
- expires: "Expires",
415
- until: "until",
416
- "last-used": "Last used",
417
- "never-used": "Never",
418
- "issued-by": "Issued by :name",
419
- "issued-console": "Issued in a terminal",
420
- full: "Everything :name can do",
421
- deleted: "Administrator #:id",
422
- revoke: "Revoke",
423
- revoked: "Revoked",
424
- expired: "Expired",
425
- "confirm-title": "Revoke :name?",
426
- "confirm-text": "The program using it is refused from its next call. A revoked key cannot be switched back on.",
427
- confirm: "Revoke",
428
- "revoked-done": ":name is revoked",
429
- empty: "No keys have been issued"
430
- },
431
- connect: {
432
- lead: "An AI agent — Claude, ChatGPT, Cursor — can work in this panel as you. Give it the address below; it will ask you to sign in and then ask what it may do.",
433
- title: "Connect an agent",
434
- address: "The address of this panel for agents",
435
- copy: "Copy the address",
436
- copied: "Copied",
437
- "copy-failed": "Could not reach the clipboard. Select the address and copy it by hand.",
438
- "copy-line": "Copy",
439
- how: "How to add it",
440
- "claude-title": "Claude",
441
- "claude-1": "Open Settings and go to Connectors.",
442
- "claude-2": 'Press "Add custom connector".',
443
- "claude-3": "Paste the address and press Add.",
444
- "chatgpt-title": "ChatGPT",
445
- "chatgpt-1": "Open Settings and go to Connectors.",
446
- "chatgpt-2": 'Press "Add" and choose a custom MCP server.',
447
- "chatgpt-3": "Paste the address, leave the authentication as OAuth, and confirm.",
448
- "claude-code-title": "Claude Code",
449
- "claude-code-hint": "One line in a terminal, from any project:",
450
- "codex-title": "Codex",
451
- "codex-hint": "These lines in ~/.codex/config.toml:",
452
- "one-click": "One click",
453
- "one-click-hint": "These two take the whole thing from a link: the editor opens, asks once, and the server is there.",
454
- "install-in": "Add to :client",
455
- "cursor-title": "Cursor",
456
- "vscode-title": "VS Code",
457
- next: "What happens next",
458
- "next-1": "The client opens this site in a browser and asks you to sign in to the panel, with your usual password. It never sees the password.",
459
- "next-2": 'The panel shows who is asking and where the answer goes. There is a "read only" switch on that screen, and turning it on is the safe way to begin.',
460
- "next-3": "From then on the agent acts as you: it can do what you can do and nothing more, and every call it makes is written down.",
461
- mine: "Your connections",
462
- rules: "Rules for agents",
463
- "rules-hint": "Every connected agent reads these before it writes anything a visitor will see."
464
- },
465
- errors: {
466
- unauthenticated: "Unauthenticated.",
467
- inactive: "This account is no longer active.",
468
- forbidden: "This account may not do that.",
469
- "not-yourself": "You cannot do that to your own account.",
470
- "last-super": "There has to be one super administrator left."
471
- },
472
- // Somebody editing themselves, which is a shorter list than an administrator editing them.
473
- profile: {
474
- title: "Your profile",
475
- menu: "Edit your profile",
476
- name: "Name",
477
- avatar: "Photo",
478
- password: "New password",
479
- "password-hint": "At least 12 characters. Leave blank to keep the current one.",
480
- "current-password": "Current password",
481
- "current-password-hint": "Asked for before the password is changed.",
482
- "wrong-password": "That is not the current password.",
483
- saved: "Your profile is saved.",
484
- save: "Save",
485
- cancel: "Cancel"
486
- },
487
- menu: {
488
- "sign-out": "Sign out",
489
- language: "Interface language",
490
- "site-bar": "Panel on the site"
491
- }
492
- };
493
- function pe(s) {
494
- const r = `${s.apiPath}/auth`, l = (u) => u.data;
495
- return {
496
- list: (u = {}) => s.http.get(`${r}/admins`, {
497
- query: {
498
- q: u.q || void 0,
499
- role: u.role ?? void 0,
500
- active: u.active ?? void 0,
501
- sort: u.sort,
502
- page: u.page,
503
- per_page: u.per_page
504
- }
505
- }).then((v) => ({ ...v.meta, data: v.data })),
506
- get: (u) => s.http.get(`${r}/admins/${u}`).then(l),
507
- create: (u) => s.http.post(`${r}/admins`, u).then(l),
508
- update: (u, v) => s.http.patch(`${r}/admins/${u}`, v).then(l),
509
- remove: (u) => s.http.delete(`${r}/admins/${u}`),
510
- roles: () => s.http.get(`${r}/roles`).then(l),
511
- calls: (u = {}) => s.http.get(`${r}/mcp-calls`, {
512
- query: {
513
- user: u.user ?? void 0,
514
- tool: u.tool ?? void 0,
515
- outcome: u.outcome ?? void 0,
516
- page: u.page,
517
- per_page: u.per_page
518
- }
519
- }).then((v) => ({ ...v.meta, data: v.data, filters: v.filters }))
520
- };
521
- }
522
- const Te = /* @__PURE__ */ new WeakSet();
523
- function te() {
524
- try {
525
- const { i18n: s } = X();
526
- Te.has(s) || (s.defaults("webx-auth", Qe), Te.add(s));
527
- } catch {
528
- }
529
- }
530
- const wt = { class: "wx-admin-form" }, xt = {
531
- key: 0,
532
- class: "wx-admin-form__aside"
533
- }, Ct = { class: "wx-admin-form__fields" }, $t = /* @__PURE__ */ Q({
534
- __name: "AdminDialog",
535
- props: {
536
- admin: { default: null },
537
- avatarField: { default: void 0 }
538
- },
539
- setup(s) {
540
- const r = s, { resolve: l, dismiss: u, open: v } = _e(), y = X(), A = pe(y), o = Ne();
541
- te();
542
- const h = G("webx-auth"), U = re(), d = W([]), k = W(!1), V = W({}), p = W({
543
- name: "",
544
- email: "",
545
- password: "",
546
- avatar: null,
547
- is_active: !0,
548
- is_super: !1,
549
- locale: null,
550
- roles: []
551
- }), g = L({
552
- get: () => p.value.avatar ? { path: p.value.avatar } : null,
553
- set: (n) => {
554
- p.value.avatar = n?.path ?? null;
555
- }
556
- }), b = L(() => r.admin !== null), w = L(() => d.value.map((n) => ({ value: n.id, label: n.name }))), F = L(() => [
557
- { value: "auto", label: h("admins.locale-auto") },
558
- ...o.state.panelLocales.map((n) => ({ value: n.code, label: n.nativeName }))
559
- ]);
560
- A.roles().then((n) => d.value = n), de(
561
- () => r.admin,
562
- (n) => {
563
- p.value = {
564
- name: n?.name ?? "",
565
- email: n?.email ?? "",
566
- password: "",
567
- avatar: n?.avatar ?? null,
568
- is_active: n?.is_active ?? !0,
569
- is_super: n?.is_super ?? !1,
570
- locale: n?.locale ?? "auto",
571
- roles: n?.roles.map((x) => x.id) ?? []
572
- }, V.value = {};
573
- },
574
- { immediate: !0 }
575
- );
576
- function C(n) {
577
- return V.value[n]?.[0];
578
- }
579
- async function D() {
580
- k.value = !0, V.value = {};
581
- const n = {
582
- name: p.value.name,
583
- email: p.value.email,
584
- avatar: p.value.avatar,
585
- is_active: p.value.is_active,
586
- is_super: p.value.is_super,
587
- locale: p.value.locale === "auto" ? null : p.value.locale,
588
- roles: p.value.roles ?? []
589
- };
590
- p.value.password && (n.password = p.value.password);
591
- try {
592
- const x = r.admin ? await A.update(r.admin.id, n) : await A.create(n);
593
- K.success(h(b.value ? "admins.updated" : "admins.created")), l(x);
594
- } catch (x) {
595
- const P = x.body;
596
- P?.errors ? V.value = P.errors : K.danger(U(x));
597
- } finally {
598
- k.value = !1;
599
- }
600
- }
601
- return (n, x) => (m(), _(e(be), {
602
- open: e(v),
603
- "onUpdate:open": x[9] || (x[9] = (P) => Ve(v) ? v.value = P : null),
604
- title: b.value ? e(h)("admins.edit-short") : e(h)("admins.new-short"),
605
- width: 720
606
- }, {
607
- footer: t(() => [
608
- a(e(se), { size: "sm" }, {
609
- default: t(() => [
610
- a(e(N), {
611
- variant: "outline",
612
- onClick: x[8] || (x[8] = (P) => e(u)())
613
- }, {
614
- default: t(() => [
615
- c(i(e(h)("admins.cancel")), 1)
616
- ]),
617
- _: 1
618
- }),
619
- a(e(N), {
620
- type: "primary",
621
- loading: k.value,
622
- onClick: D
623
- }, {
624
- default: t(() => [
625
- c(i(e(h)("admins.save")), 1)
626
- ]),
627
- _: 1
628
- }, 8, ["loading"])
629
- ]),
630
- _: 1
631
- })
632
- ]),
633
- default: t(() => [
634
- S("div", wt, [
635
- S("div", {
636
- class: Be(["wx-admin-form__grid", { "has-aside": s.avatarField }])
637
- }, [
638
- s.avatarField ? (m(), H("div", xt, [
639
- (m(), _(Ee(s.avatarField), {
640
- modelValue: g.value,
641
- "onUpdate:modelValue": x[0] || (x[0] = (P) => g.value = P),
642
- label: e(h)("admins.avatar"),
643
- aspect: "1/1",
644
- captions: !1
645
- }, null, 8, ["modelValue", "label"]))
646
- ])) : E("", !0),
647
- S("div", Ct, [
648
- a(e(M), {
649
- label: e(h)("admins.name"),
650
- error: C("name")
651
- }, {
652
- default: t(() => [
653
- a(e(le), {
654
- modelValue: p.value.name,
655
- "onUpdate:modelValue": x[1] || (x[1] = (P) => p.value.name = P),
656
- name: "name"
657
- }, null, 8, ["modelValue"])
658
- ]),
659
- _: 1
660
- }, 8, ["label", "error"]),
661
- a(e(M), {
662
- label: e(h)("admins.email"),
663
- error: C("email")
664
- }, {
665
- default: t(() => [
666
- a(e(le), {
667
- modelValue: p.value.email,
668
- "onUpdate:modelValue": x[2] || (x[2] = (P) => p.value.email = P),
669
- type: "email",
670
- name: "email",
671
- autocomplete: "off"
672
- }, null, 8, ["modelValue"])
673
- ]),
674
- _: 1
675
- }, 8, ["label", "error"]),
676
- a(e(M), {
677
- label: e(h)("admins.password"),
678
- error: C("password"),
679
- help: b.value ? e(h)("admins.password-keep") : e(h)("admins.password-hint")
680
- }, {
681
- default: t(() => [
682
- a(e(le), {
683
- modelValue: p.value.password,
684
- "onUpdate:modelValue": x[3] || (x[3] = (P) => p.value.password = P),
685
- type: "password",
686
- name: "password",
687
- autocomplete: "new-password"
688
- }, null, 8, ["modelValue"])
689
- ]),
690
- _: 1
691
- }, 8, ["label", "error", "help"]),
692
- a(e(M), {
693
- label: e(h)("admins.roles"),
694
- error: C("roles")
695
- }, {
696
- default: t(() => [
697
- a(e(ne), {
698
- modelValue: p.value.roles,
699
- "onUpdate:modelValue": x[4] || (x[4] = (P) => p.value.roles = P),
700
- options: w.value,
701
- multiple: ""
702
- }, null, 8, ["modelValue", "options"])
703
- ]),
704
- _: 1
705
- }, 8, ["label", "error"]),
706
- a(e(M), {
707
- label: e(h)("admins.locale")
708
- }, {
709
- default: t(() => [
710
- a(e(ne), {
711
- modelValue: p.value.locale,
712
- "onUpdate:modelValue": x[5] || (x[5] = (P) => p.value.locale = P),
713
- options: F.value
714
- }, null, 8, ["modelValue", "options"])
715
- ]),
716
- _: 1
717
- }, 8, ["label"]),
718
- a(e(se), { size: "md" }, {
719
- default: t(() => [
720
- a(e(Le), {
721
- modelValue: p.value.is_active,
722
- "onUpdate:modelValue": x[6] || (x[6] = (P) => p.value.is_active = P),
723
- label: e(h)("admins.active")
724
- }, null, 8, ["modelValue", "label"]),
725
- a(e(Le), {
726
- modelValue: p.value.is_super,
727
- "onUpdate:modelValue": x[7] || (x[7] = (P) => p.value.is_super = P),
728
- label: e(h)("admins.super")
729
- }, null, 8, ["modelValue", "label"])
730
- ]),
731
- _: 1
732
- }),
733
- a(e(B), {
734
- size: "sm",
735
- tone: "muted"
736
- }, {
737
- default: t(() => [
738
- c(i(e(h)("admins.super-hint")), 1)
739
- ]),
740
- _: 1
741
- })
742
- ])
743
- ], 2)
744
- ])
745
- ]),
746
- _: 1
747
- }, 8, ["open", "title"]));
748
- }
749
- }), Ue = 480, Xe = /* @__PURE__ */ Q({
750
- __name: "AdminList",
751
- props: {
752
- picking: { type: Boolean, default: !1 },
753
- multiple: { type: Boolean, default: !1 },
754
- removable: { type: Boolean, default: !1 },
755
- filters: { type: Boolean, default: !1 },
756
- resolveAvatar: { type: Function, default: void 0 }
757
- },
758
- emits: ["open", "chosen", "selection", "remove"],
759
- setup(s, { expose: r, emit: l }) {
760
- const u = s, v = l, y = X(), A = pe(y);
761
- te();
762
- const o = oe("root"), h = ge(o), U = L(() => h.value > 0 && h.value < Ue), d = G("webx-auth"), k = G("webx-admin"), V = W(null), p = W([]), g = W(!1), b = W("all"), w = W("any"), F = W([]), C = W({});
763
- let D = { page: 1, perPage: 20, sort: null, search: "" };
764
- const n = L(() => [
765
- { value: "all", label: d("admins.all-roles") },
766
- ...p.value.map((I) => ({ value: I.slug, label: I.name }))
767
- ]), x = L(() => [
768
- { value: "any", label: d("admins.any-state") },
769
- { value: "yes", label: d("admins.only-active") },
770
- { value: "no", label: d("admins.only-inactive") }
771
- ]), P = L(() => {
772
- const I = [], j = p.value.find((T) => T.slug === b.value);
773
- return j && I.push({
774
- key: "role",
775
- label: `${d("admins.filter-role")}: ${j.name}`,
776
- clear: () => b.value = "all"
777
- }), w.value !== "any" && I.push({
778
- key: "state",
779
- label: `${d("admins.filter-state")}: ${w.value === "yes" ? d("admins.only-active") : d("admins.only-inactive")}`,
780
- clear: () => w.value = "any"
781
- }), I;
782
- });
783
- function J() {
784
- b.value = "all", w.value = "any";
785
- }
786
- const O = L(() => U.value ? [{ key: "card", label: "" }] : [
787
- { key: "name", label: d("admins.name"), sortable: !0 },
788
- { key: "email", label: d("admins.email"), sortable: !0, hideBelow: 560 },
789
- { key: "roles", label: d("admins.roles"), hideBelow: 760 },
790
- { key: "is_active", label: d("admins.active"), align: "center", hideBelow: 660 },
791
- {
792
- key: "last_login_at",
793
- label: d("admins.last-login"),
794
- sortable: !0,
795
- hideBelow: 900,
796
- // The first thing to go when a row becomes a card: it is a date somebody scans down a
797
- // column, and a card has no column to scan.
798
- hideOnCards: !0
799
- },
800
- {
801
- key: "actions",
802
- label: "",
803
- width: ot,
804
- align: "right",
805
- hidden: !u.removable,
806
- // A card puts them along its top instead, through the `card-actions` slot.
807
- hideOnCards: !0
808
- }
809
- ]);
810
- A.roles().then((I) => p.value = I), de([b, w], () => z(D));
811
- async function z(I) {
812
- D = I, g.value = !0;
813
- try {
814
- V.value = await A.list({
815
- q: I.search,
816
- role: b.value === "all" ? null : b.value,
817
- active: w.value === "any" ? null : w.value,
818
- sort: I.sort ? `${I.sort.order === "desc" ? "-" : ""}${I.sort.key}` : "name",
819
- page: I.page,
820
- per_page: I.perPage
821
- }), f();
822
- } finally {
823
- g.value = !1;
824
- }
825
- }
826
- async function f() {
827
- const I = u.resolveAvatar;
828
- if (I)
829
- for (const j of V.value?.data ?? []) {
830
- if (!j.avatar || C.value[j.avatar]) continue;
831
- const T = await I(j.avatar);
832
- T && (C.value = { ...C.value, [j.avatar]: T });
833
- }
834
- }
835
- function R(I) {
836
- return [
837
- {
838
- key: "delete",
839
- icon: "trash",
840
- label: d("admins.delete"),
841
- danger: !0,
842
- run: () => v("remove", I)
843
- }
844
- ];
845
- }
846
- function $(I) {
847
- if (u.picking) {
848
- v("chosen", [I]);
849
- return;
850
- }
851
- v("open", I);
852
- }
853
- const Z = L(() => !(u.picking && u.multiple));
854
- function fe(I, j) {
855
- F.value = j, v("selection", j);
856
- }
857
- return r({ reload: () => z(D), chosen: () => F.value }), (I, j) => (m(), H("div", {
858
- ref_key: "root",
859
- ref: o,
860
- class: "wx-admin-list"
861
- }, [
862
- a(e(ke), {
863
- data: V.value,
864
- columns: O.value,
865
- "row-key": "id",
866
- searchable: "",
867
- clickable: Z.value,
868
- hover: Z.value,
869
- flush: "",
870
- loading: g.value,
871
- "search-placeholder": e(d)("admins.search"),
872
- "empty-text": e(d)("admins.empty"),
873
- selectable: s.picking && s.multiple,
874
- "select-row-label": e(k)("filters.select-row"),
875
- "select-all-label": e(k)("filters.select-all"),
876
- "cards-below": Ue,
877
- "filters-count": P.value.length,
878
- "filters-label": e(k)("filters.title"),
879
- onRowClick: $,
880
- onStateChange: z,
881
- onSelectionChange: fe
882
- }, Ae({
883
- "cell-name": t(({ row: T }) => [
884
- a(e(se), {
885
- size: "sm",
886
- align: "center"
887
- }, {
888
- default: t(() => [
889
- a(e(dt), {
890
- name: T.name,
891
- src: T.avatar ? C.value[T.avatar] : void 0,
892
- size: "sm"
893
- }, null, 8, ["name", "src"]),
894
- S("span", null, i(T.name), 1),
895
- T.is_super ? (m(), _(e(q), {
896
- key: 0,
897
- type: "warning"
898
- }, {
899
- default: t(() => [
900
- c(i(e(d)("admins.super")), 1)
901
- ]),
902
- _: 1
903
- })) : E("", !0)
904
- ]),
905
- _: 2
906
- }, 1024)
907
- ]),
908
- "cell-roles": t(({ row: T }) => [
909
- T.roles.length > 0 ? (m(), _(e(se), {
910
- key: 0,
911
- size: "xs",
912
- wrap: ""
913
- }, {
914
- default: t(() => [
915
- (m(!0), H(ue, null, Ce(T.roles, (ie) => (m(), _(e(q), {
916
- key: ie.id
917
- }, {
918
- default: t(() => [
919
- c(i(ie.name), 1)
920
- ]),
921
- _: 2
922
- }, 1024))), 128))
923
- ]),
924
- _: 2
925
- }, 1024)) : (m(), _(e(B), {
926
- key: 1,
927
- size: "sm",
928
- tone: "muted"
929
- }, {
930
- default: t(() => [
931
- c(i(e(d)("admins.no-roles")), 1)
932
- ]),
933
- _: 1
934
- }))
935
- ]),
936
- "cell-is_active": t(({ row: T }) => [
937
- a(e(q), {
938
- type: T.is_active ? "success" : "default",
939
- dot: ""
940
- }, {
941
- default: t(() => [
942
- c(i(T.is_active ? e(d)("admins.active") : e(d)("admins.only-inactive")), 1)
943
- ]),
944
- _: 2
945
- }, 1032, ["type"])
946
- ]),
947
- "card-actions": t(({ row: T }) => [
948
- s.removable ? (m(), _(e(Se), {
949
- key: 0,
950
- actions: R(T),
951
- label: T.name
952
- }, null, 8, ["actions", "label"])) : E("", !0)
953
- ]),
954
- "cell-actions": t(({ row: T }) => [
955
- a(e(Se), {
956
- actions: R(T),
957
- label: T.name
958
- }, null, 8, ["actions", "label"])
959
- ]),
960
- "cell-last_login_at": t(({ row: T }) => [
961
- a(e(ae), {
962
- value: T.last_login_at,
963
- tone: T.last_login_at ? "default" : "muted",
964
- compact: ""
965
- }, null, 8, ["value", "tone"])
966
- ]),
967
- "cell-card": t(({ row: T }) => [
968
- a(e(we), {
969
- variant: "plain",
970
- shape: "circle",
971
- title: T.name,
972
- image: T.avatar ? C.value[T.avatar] : void 0,
973
- subtitle: T.email
974
- }, {
975
- meta: t(() => [
976
- T.is_super ? (m(), _(e(q), {
977
- key: 0,
978
- type: "warning",
979
- size: "sm"
980
- }, {
981
- default: t(() => [
982
- c(i(e(d)("admins.super")), 1)
983
- ]),
984
- _: 1
985
- })) : E("", !0),
986
- (m(!0), H(ue, null, Ce(T.roles, (ie) => (m(), _(e(q), {
987
- key: ie.id,
988
- size: "sm"
989
- }, {
990
- default: t(() => [
991
- c(i(ie.name), 1)
992
- ]),
993
- _: 2
994
- }, 1024))), 128)),
995
- a(e(q), {
996
- type: T.is_active ? "success" : "default",
997
- dot: "",
998
- size: "sm"
999
- }, {
1000
- default: t(() => [
1001
- c(i(T.is_active ? e(d)("admins.active") : e(d)("admins.only-inactive")), 1)
1002
- ]),
1003
- _: 2
1004
- }, 1032, ["type"])
1005
- ]),
1006
- _: 2
1007
- }, 1032, ["title", "image", "subtitle"])
1008
- ]),
1009
- _: 2
1010
- }, [
1011
- s.filters ? {
1012
- name: "filters",
1013
- fn: t(() => [
1014
- a(e(M), {
1015
- label: e(d)("admins.filter-role")
1016
- }, {
1017
- default: t(() => [
1018
- a(e(ne), {
1019
- modelValue: b.value,
1020
- "onUpdate:modelValue": j[0] || (j[0] = (T) => b.value = T),
1021
- options: n.value,
1022
- size: "sm"
1023
- }, null, 8, ["modelValue", "options"])
1024
- ]),
1025
- _: 1
1026
- }, 8, ["label"]),
1027
- a(e(M), {
1028
- label: e(d)("admins.filter-state")
1029
- }, {
1030
- default: t(() => [
1031
- a(e(ne), {
1032
- modelValue: w.value,
1033
- "onUpdate:modelValue": j[1] || (j[1] = (T) => w.value = T),
1034
- options: x.value,
1035
- size: "sm"
1036
- }, null, 8, ["modelValue", "options"])
1037
- ]),
1038
- _: 1
1039
- }, 8, ["label"]),
1040
- P.value.length > 0 ? (m(), _(e(N), {
1041
- key: 0,
1042
- variant: "text",
1043
- size: "sm",
1044
- block: "",
1045
- onClick: J
1046
- }, {
1047
- icon: t(() => [
1048
- a(e(ee), { name: "close" })
1049
- ]),
1050
- default: t(() => [
1051
- c(" " + i(e(k)("filters.reset")), 1)
1052
- ]),
1053
- _: 1
1054
- })) : E("", !0)
1055
- ]),
1056
- key: "0"
1057
- } : void 0,
1058
- s.filters ? {
1059
- name: "applied",
1060
- fn: t(() => [
1061
- a(e(Me), { filters: P.value }, null, 8, ["filters"])
1062
- ]),
1063
- key: "1"
1064
- } : void 0
1065
- ]), 1032, ["data", "columns", "clickable", "hover", "loading", "search-placeholder", "empty-text", "selectable", "select-row-label", "select-all-label", "filters-count", "filters-label"])
1066
- ], 512));
1067
- }
1068
- }), Vt = { class: "wx-call-list__details" }, At = { class: "wx-call-list__label" }, zt = {
1069
- key: 1,
1070
- class: "wx-call-list__arguments"
1071
- }, Wt = {
1072
- class: "wx-call-list__glyph",
1073
- "aria-hidden": "true"
1074
- }, St = {
1075
- key: 2,
1076
- class: "wx-call-list__arguments"
1077
- }, Pe = 480, Lt = /* @__PURE__ */ Q({
1078
- __name: "CallList",
1079
- setup(s, { expose: r }) {
1080
- const l = X(), u = pe(l);
1081
- te();
1082
- const v = oe("root"), y = ge(v), A = L(() => y.value > 0 && y.value < Pe), o = G("webx-auth"), h = G("webx-admin"), U = W(null), d = W({ users: [], tools: [] }), k = W(!1), V = W("all"), p = W("all"), g = W("any");
1083
- let b = { page: 1, perPage: 30, sort: null, search: "" };
1084
- function w(f) {
1085
- return f === null ? o("calls.local") : f.name ?? o("calls.deleted", { id: f.id });
1086
- }
1087
- const F = L(() => [
1088
- { value: "all", label: o("calls.everybody") },
1089
- ...d.value.users.map((f) => ({
1090
- value: f.id === null ? "none" : String(f.id),
1091
- label: w(f.id === null ? null : { id: f.id, name: f.name })
1092
- }))
1093
- ]), C = L(() => [
1094
- { value: "all", label: o("calls.all-tools") },
1095
- ...d.value.tools.map((f) => ({ value: f, label: f }))
1096
- ]), D = L(() => [
1097
- { value: "any", label: o("calls.any-outcome") },
1098
- { value: "ok", label: o("calls.only-answered") },
1099
- { value: "failed", label: o("calls.only-refused") },
1100
- { value: "dry", label: o("calls.only-dry") }
1101
- ]), n = L(() => {
1102
- const f = [], R = F.value.find((Z) => Z.value === V.value);
1103
- V.value !== "all" && R && f.push({
1104
- key: "user",
1105
- label: `${o("calls.filter-user")}: ${R.label}`,
1106
- clear: () => V.value = "all"
1107
- }), p.value !== "all" && f.push({
1108
- key: "tool",
1109
- label: `${o("calls.filter-tool")}: ${p.value}`,
1110
- clear: () => p.value = "all"
1111
- });
1112
- const $ = D.value.find((Z) => Z.value === g.value);
1113
- return g.value !== "any" && $ && f.push({
1114
- key: "outcome",
1115
- label: `${o("calls.filter-outcome")}: ${$.label}`,
1116
- clear: () => g.value = "any"
1117
- }), f;
1118
- });
1119
- function x() {
1120
- V.value = "all", p.value = "all", g.value = "any";
1121
- }
1122
- const P = L(() => A.value ? [{ key: "card", label: "" }] : [
1123
- { key: "at", label: o("calls.when") },
1124
- { key: "user", label: o("calls.who"), hideBelow: 640 },
1125
- { key: "tool", label: o("calls.tool") },
1126
- { key: "outcome", label: o("calls.outcome") },
1127
- { key: "duration_ms", label: o("calls.took"), align: "right", hideBelow: 820 },
1128
- { key: "client", label: o("calls.client"), hideBelow: 960 }
1129
- ]);
1130
- de([V, p, g], () => J({ ...b, page: 1 }));
1131
- async function J(f) {
1132
- b = f, k.value = !0;
1133
- try {
1134
- U.value = await u.calls({
1135
- user: V.value === "all" ? null : V.value,
1136
- tool: p.value === "all" ? null : p.value,
1137
- outcome: g.value === "any" ? null : g.value,
1138
- page: f.page,
1139
- per_page: f.perPage
1140
- }), d.value = U.value.filters;
1141
- } finally {
1142
- k.value = !1;
1143
- }
1144
- }
1145
- function O(f) {
1146
- return f.ok ? f.dry_run ? { type: "info", label: o("calls.dry-run") } : { type: "success", label: o("calls.answered") } : { type: "danger", label: o("calls.refused") };
1147
- }
1148
- function z(f) {
1149
- return f.arguments !== null || f.error !== null;
1150
- }
1151
- return r({ reload: () => J(b) }), (f, R) => (m(), H("div", {
1152
- ref_key: "root",
1153
- ref: v,
1154
- class: "wx-call-list"
1155
- }, [
1156
- a(e(ke), {
1157
- data: U.value,
1158
- columns: P.value,
1159
- "row-key": "id",
1160
- flush: "",
1161
- loading: k.value,
1162
- clickable: !1,
1163
- expandable: !A.value,
1164
- "expandable-if": z,
1165
- "empty-text": e(o)("calls.empty"),
1166
- "cards-below": Pe,
1167
- "filters-count": n.value.length,
1168
- "filters-label": e(h)("filters.title"),
1169
- onStateChange: J
1170
- }, {
1171
- filters: t(() => [
1172
- a(e(M), {
1173
- label: e(o)("calls.filter-user")
1174
- }, {
1175
- default: t(() => [
1176
- a(e(ne), {
1177
- modelValue: V.value,
1178
- "onUpdate:modelValue": R[0] || (R[0] = ($) => V.value = $),
1179
- options: F.value,
1180
- size: "sm"
1181
- }, null, 8, ["modelValue", "options"])
1182
- ]),
1183
- _: 1
1184
- }, 8, ["label"]),
1185
- a(e(M), {
1186
- label: e(o)("calls.filter-tool")
1187
- }, {
1188
- default: t(() => [
1189
- a(e(ne), {
1190
- modelValue: p.value,
1191
- "onUpdate:modelValue": R[1] || (R[1] = ($) => p.value = $),
1192
- options: C.value,
1193
- size: "sm"
1194
- }, null, 8, ["modelValue", "options"])
1195
- ]),
1196
- _: 1
1197
- }, 8, ["label"]),
1198
- a(e(M), {
1199
- label: e(o)("calls.filter-outcome")
1200
- }, {
1201
- default: t(() => [
1202
- a(e(ne), {
1203
- modelValue: g.value,
1204
- "onUpdate:modelValue": R[2] || (R[2] = ($) => g.value = $),
1205
- options: D.value,
1206
- size: "sm"
1207
- }, null, 8, ["modelValue", "options"])
1208
- ]),
1209
- _: 1
1210
- }, 8, ["label"]),
1211
- n.value.length > 0 ? (m(), _(e(N), {
1212
- key: 0,
1213
- variant: "text",
1214
- size: "sm",
1215
- block: "",
1216
- onClick: x
1217
- }, {
1218
- icon: t(() => [
1219
- a(e(ee), { name: "close" })
1220
- ]),
1221
- default: t(() => [
1222
- c(" " + i(e(h)("filters.reset")), 1)
1223
- ]),
1224
- _: 1
1225
- })) : E("", !0)
1226
- ]),
1227
- applied: t(() => [
1228
- a(e(Me), { filters: n.value }, null, 8, ["filters"])
1229
- ]),
1230
- "cell-at": t(({ row: $ }) => [
1231
- a(e(ae), {
1232
- value: $.at,
1233
- tone: "default",
1234
- compact: ""
1235
- }, null, 8, ["value"])
1236
- ]),
1237
- "cell-user": t(({ row: $ }) => [
1238
- a(e(B), {
1239
- tone: $.user === null || $.user.name === null ? "muted" : "default"
1240
- }, {
1241
- default: t(() => [
1242
- c(i(w($.user)), 1)
1243
- ]),
1244
- _: 2
1245
- }, 1032, ["tone"])
1246
- ]),
1247
- "cell-tool": t(({ row: $ }) => [
1248
- a(e(B), {
1249
- mono: "",
1250
- size: "sm"
1251
- }, {
1252
- default: t(() => [
1253
- c(i($.tool), 1)
1254
- ]),
1255
- _: 2
1256
- }, 1024)
1257
- ]),
1258
- "cell-outcome": t(({ row: $ }) => [
1259
- a(e(q), {
1260
- type: O($).type,
1261
- dot: ""
1262
- }, {
1263
- default: t(() => [
1264
- c(i(O($).label), 1)
1265
- ]),
1266
- _: 2
1267
- }, 1032, ["type"])
1268
- ]),
1269
- "cell-duration_ms": t(({ row: $ }) => [
1270
- a(e(B), {
1271
- size: "sm",
1272
- tone: "muted"
1273
- }, {
1274
- default: t(() => [
1275
- c(i(e(o)("calls.ms", { count: $.duration_ms })), 1)
1276
- ]),
1277
- _: 2
1278
- }, 1024)
1279
- ]),
1280
- "cell-client": t(({ row: $ }) => [
1281
- $.client ? (m(), _(e(B), {
1282
- key: 0,
1283
- size: "sm"
1284
- }, {
1285
- default: t(() => [
1286
- c(i($.client), 1)
1287
- ]),
1288
- _: 2
1289
- }, 1024)) : (m(), _(e(B), {
1290
- key: 1,
1291
- size: "sm",
1292
- tone: "muted"
1293
- }, {
1294
- default: t(() => [...R[3] || (R[3] = [
1295
- c("—", -1)
1296
- ])]),
1297
- _: 1
1298
- }))
1299
- ]),
1300
- expanded: t(({ row: $ }) => [
1301
- S("div", Vt, [
1302
- $.error ? (m(), _(e(B), {
1303
- key: 0,
1304
- tone: "danger",
1305
- size: "sm",
1306
- class: "wx-call-list__error"
1307
- }, {
1308
- default: t(() => [
1309
- S("strong", null, i(e(o)("calls.error")) + ":", 1),
1310
- c(" " + i($.error), 1)
1311
- ]),
1312
- _: 2
1313
- }, 1024)) : E("", !0),
1314
- S("div", At, [
1315
- a(e(B), {
1316
- size: "sm",
1317
- weight: "semibold"
1318
- }, {
1319
- default: t(() => [
1320
- c(i(e(o)("calls.request")), 1)
1321
- ]),
1322
- _: 1
1323
- }),
1324
- a(e(B), {
1325
- size: "xs",
1326
- tone: "muted"
1327
- }, {
1328
- default: t(() => [
1329
- c(i(e(o)("calls.request-hint")), 1)
1330
- ]),
1331
- _: 1
1332
- })
1333
- ]),
1334
- $.arguments ? (m(), H("pre", zt, i($.arguments), 1)) : (m(), _(e(B), {
1335
- key: 2,
1336
- size: "sm",
1337
- tone: "muted"
1338
- }, {
1339
- default: t(() => [
1340
- c(i(e(o)("calls.no-arguments")), 1)
1341
- ]),
1342
- _: 1
1343
- }))
1344
- ])
1345
- ]),
1346
- "cell-card": t(({ row: $ }) => [
1347
- a(e(we), {
1348
- variant: "plain",
1349
- title: $.tool,
1350
- subtitle: w($.user)
1351
- }, {
1352
- media: t(() => [
1353
- S("span", Wt, [
1354
- a(e(ee), { name: "sliders" })
1355
- ])
1356
- ]),
1357
- meta: t(() => [
1358
- a(e(q), {
1359
- type: O($).type,
1360
- dot: "",
1361
- size: "sm"
1362
- }, {
1363
- default: t(() => [
1364
- c(i(O($).label), 1)
1365
- ]),
1366
- _: 2
1367
- }, 1032, ["type"]),
1368
- a(e(ae), {
1369
- value: $.at,
1370
- compact: ""
1371
- }, null, 8, ["value"]),
1372
- $.client ? (m(), _(e(B), {
1373
- key: 0,
1374
- size: "xs",
1375
- tone: "muted"
1376
- }, {
1377
- default: t(() => [
1378
- c(i($.client), 1)
1379
- ]),
1380
- _: 2
1381
- }, 1024)) : E("", !0)
1382
- ]),
1383
- default: t(() => [
1384
- z($) ? (m(), _(e(se), {
1385
- key: 0,
1386
- direction: "vertical",
1387
- size: "xs",
1388
- class: "wx-call-list__card-details"
1389
- }, {
1390
- default: t(() => [
1391
- $.error ? (m(), _(e(B), {
1392
- key: 0,
1393
- tone: "danger",
1394
- size: "sm"
1395
- }, {
1396
- default: t(() => [
1397
- c(i($.error), 1)
1398
- ]),
1399
- _: 2
1400
- }, 1024)) : E("", !0),
1401
- $.arguments ? (m(), _(e(B), {
1402
- key: 1,
1403
- size: "xs",
1404
- tone: "muted"
1405
- }, {
1406
- default: t(() => [
1407
- c(i(e(o)("calls.request")), 1)
1408
- ]),
1409
- _: 1
1410
- })) : E("", !0),
1411
- $.arguments ? (m(), H("pre", St, i($.arguments), 1)) : E("", !0)
1412
- ]),
1413
- _: 2
1414
- }, 1024)) : E("", !0)
1415
- ]),
1416
- _: 2
1417
- }, 1032, ["title", "subtitle"])
1418
- ]),
1419
- _: 1
1420
- }, 8, ["data", "columns", "loading", "expandable", "empty-text", "filters-count", "filters-label"])
1421
- ], 512));
1422
- }
1423
- });
1424
- function Tt(s) {
1425
- const r = `${s.apiPath}/auth/connections`;
1426
- return {
1427
- list: (l = "mine") => s.http.get(r, { query: { all: l === "all" ? 1 : void 0 } }).then((u) => ({
1428
- data: u.data,
1429
- scope: u.meta.scope,
1430
- canSeeEverybody: u.meta.can_see_everybody
1431
- })),
1432
- disconnect: (l) => s.http.delete(`${r}/${l}`).then((u) => u.data)
1433
- };
1434
- }
1435
- const Ut = {
1436
- class: "wx-connection-list__glyph",
1437
- "aria-hidden": "true"
1438
- }, Fe = 560, Ze = /* @__PURE__ */ Q({
1439
- __name: "ConnectionList",
1440
- props: {
1441
- scope: { default: "mine" }
1442
- },
1443
- setup(s, { expose: r }) {
1444
- const l = s, u = X(), v = Tt(u);
1445
- te();
1446
- const y = G("webx-auth"), A = re(), o = oe("root"), h = ge(o), U = L(() => h.value > 0 && h.value < Fe), d = W([]), k = W(!1), V = W(null), p = L(() => U.value ? [{ key: "card", label: "" }] : [
1447
- { key: "client", label: y("connections.client"), minWidth: 210 },
1448
- ...l.scope === "all" ? [{ key: "user", label: y("connections.who"), minWidth: 140 }] : [],
1449
- { key: "read_only", label: y("connections.allowed"), minWidth: 160 },
1450
- { key: "connected_at", label: y("connections.connected"), hideBelow: 860 },
1451
- { key: "last_used_at", label: y("connections.last-used"), minWidth: 130 },
1452
- { key: "end", label: "", align: "right", width: 140 }
1453
- ]);
1454
- function g(C) {
1455
- return C.user.name ?? y("calls.deleted", { id: C.user.id });
1456
- }
1457
- function b(C) {
1458
- if (C.read_only) return y("connections.read-only");
1459
- if (l.scope !== "all") return y("connections.full-you");
1460
- const D = C.user.name?.split(" ")[0];
1461
- return y("connections.full", { name: D || g(C) });
1462
- }
1463
- async function w() {
1464
- k.value = !0;
1465
- try {
1466
- d.value = (await v.list(l.scope)).data;
1467
- } catch (C) {
1468
- K.danger(A(C));
1469
- } finally {
1470
- k.value = !1;
1471
- }
1472
- }
1473
- async function F(C) {
1474
- if (await ze({
1475
- title: y("connections.confirm-title", { client: C.client }),
1476
- message: y("connections.confirm-text"),
1477
- confirmText: y("connections.confirm"),
1478
- cancelText: y("connections.cancel"),
1479
- tone: "danger"
1480
- })) {
1481
- V.value = C.id;
1482
- try {
1483
- const n = await v.disconnect(C.id);
1484
- d.value = d.value.map((x) => x.id === n.id ? n : x), K.success(y("connections.done", { client: C.client }));
1485
- } catch (n) {
1486
- K.danger(A(n));
1487
- } finally {
1488
- V.value = null;
1489
- }
1490
- }
1491
- }
1492
- return de(() => l.scope, w, { immediate: !0 }), r({ reload: w }), (C, D) => (m(), H("div", {
1493
- ref_key: "root",
1494
- ref: o,
1495
- class: "wx-connection-list"
1496
- }, [
1497
- a(e(ke), {
1498
- data: d.value,
1499
- columns: p.value,
1500
- "row-key": "id",
1501
- flush: "",
1502
- loading: k.value,
1503
- clickable: !1,
1504
- "empty-text": s.scope === "all" ? e(y)("connections.empty-all") : e(y)("connections.empty"),
1505
- "cards-below": Fe,
1506
- "row-class": (n) => n.revoked_at ? "is-ended" : ""
1507
- }, {
1508
- "cell-client": t(({ row: n }) => [
1509
- a(e(se), {
1510
- direction: "vertical",
1511
- size: "none"
1512
- }, {
1513
- default: t(() => [
1514
- a(e(B), {
1515
- tone: n.revoked_at ? "muted" : "default",
1516
- weight: "medium"
1517
- }, {
1518
- default: t(() => [
1519
- c(i(n.client), 1)
1520
- ]),
1521
- _: 2
1522
- }, 1032, ["tone"]),
1523
- a(e(B), {
1524
- size: "xs",
1525
- tone: "muted"
1526
- }, {
1527
- default: t(() => [
1528
- c(i(e(y)("connections.returns-to", { host: n.host })), 1)
1529
- ]),
1530
- _: 2
1531
- }, 1024)
1532
- ]),
1533
- _: 2
1534
- }, 1024)
1535
- ]),
1536
- "cell-user": t(({ row: n }) => [
1537
- a(e(B), {
1538
- tone: n.user.name === null ? "muted" : "default"
1539
- }, {
1540
- default: t(() => [
1541
- c(i(g(n)), 1)
1542
- ]),
1543
- _: 2
1544
- }, 1032, ["tone"])
1545
- ]),
1546
- "cell-read_only": t(({ row: n }) => [
1547
- n.revoked_at ? (m(), _(e(q), {
1548
- key: 0,
1549
- type: "default",
1550
- dot: ""
1551
- }, {
1552
- default: t(() => [
1553
- c(i(e(y)("connections.disconnected")), 1)
1554
- ]),
1555
- _: 1
1556
- })) : (m(), _(e(q), {
1557
- key: 1,
1558
- type: n.read_only ? "info" : "success",
1559
- dot: ""
1560
- }, {
1561
- default: t(() => [
1562
- c(i(b(n)), 1)
1563
- ]),
1564
- _: 2
1565
- }, 1032, ["type"]))
1566
- ]),
1567
- "cell-connected_at": t(({ row: n }) => [
1568
- a(e(ae), {
1569
- value: n.connected_at,
1570
- tone: "muted",
1571
- compact: ""
1572
- }, null, 8, ["value"])
1573
- ]),
1574
- "cell-last_used_at": t(({ row: n }) => [
1575
- n.last_used_at ? (m(), _(e(ae), {
1576
- key: 0,
1577
- value: n.last_used_at,
1578
- tone: "default",
1579
- compact: ""
1580
- }, null, 8, ["value"])) : (m(), _(e(B), {
1581
- key: 1,
1582
- size: "sm",
1583
- tone: "muted"
1584
- }, {
1585
- default: t(() => [
1586
- c(i(e(y)("connections.never-used")), 1)
1587
- ]),
1588
- _: 1
1589
- }))
1590
- ]),
1591
- "cell-end": t(({ row: n }) => [
1592
- n.revoked_at ? E("", !0) : (m(), _(e(N), {
1593
- key: 0,
1594
- type: "danger",
1595
- variant: "text",
1596
- size: "sm",
1597
- loading: V.value === n.id,
1598
- onClick: (x) => F(n)
1599
- }, {
1600
- default: t(() => [
1601
- c(i(e(y)("connections.disconnect")), 1)
1602
- ]),
1603
- _: 1
1604
- }, 8, ["loading", "onClick"]))
1605
- ]),
1606
- "cell-card": t(({ row: n }) => [
1607
- a(e(we), {
1608
- variant: "plain",
1609
- title: n.client,
1610
- subtitle: e(y)("connections.returns-to", { host: n.host })
1611
- }, {
1612
- media: t(() => [
1613
- S("span", Ut, [
1614
- a(e(ee), { name: "link" })
1615
- ])
1616
- ]),
1617
- meta: t(() => [
1618
- n.revoked_at ? (m(), _(e(q), {
1619
- key: 0,
1620
- type: "default",
1621
- dot: "",
1622
- size: "sm"
1623
- }, {
1624
- default: t(() => [
1625
- c(i(e(y)("connections.disconnected")), 1)
1626
- ]),
1627
- _: 1
1628
- })) : (m(), _(e(q), {
1629
- key: 1,
1630
- type: n.read_only ? "info" : "success",
1631
- dot: "",
1632
- size: "sm"
1633
- }, {
1634
- default: t(() => [
1635
- c(i(b(n)), 1)
1636
- ]),
1637
- _: 2
1638
- }, 1032, ["type"])),
1639
- s.scope === "all" ? (m(), _(e(B), {
1640
- key: 2,
1641
- size: "xs",
1642
- tone: "muted"
1643
- }, {
1644
- default: t(() => [
1645
- c(i(g(n)), 1)
1646
- ]),
1647
- _: 2
1648
- }, 1024)) : E("", !0),
1649
- n.last_used_at ? (m(), _(e(ae), {
1650
- key: 3,
1651
- value: n.last_used_at,
1652
- compact: ""
1653
- }, null, 8, ["value"])) : (m(), _(e(B), {
1654
- key: 4,
1655
- size: "xs",
1656
- tone: "muted"
1657
- }, {
1658
- default: t(() => [
1659
- c(i(e(y)("connections.never-used")), 1)
1660
- ]),
1661
- _: 1
1662
- }))
1663
- ]),
1664
- actions: t(() => [
1665
- n.revoked_at ? E("", !0) : (m(), _(e(N), {
1666
- key: 0,
1667
- type: "danger",
1668
- variant: "text",
1669
- size: "sm",
1670
- loading: V.value === n.id,
1671
- onClick: (x) => F(n)
1672
- }, {
1673
- default: t(() => [
1674
- c(i(e(y)("connections.disconnect")), 1)
1675
- ]),
1676
- _: 1
1677
- }, 8, ["loading", "onClick"]))
1678
- ]),
1679
- _: 2
1680
- }, 1032, ["title", "subtitle"])
1681
- ]),
1682
- _: 1
1683
- }, 8, ["data", "columns", "loading", "empty-text", "row-class"])
1684
- ], 512));
1685
- }
1686
- });
1687
- async function et(s) {
1688
- try {
1689
- if (navigator.clipboard?.writeText)
1690
- return await navigator.clipboard.writeText(s), !0;
1691
- } catch {
1692
- }
1693
- return Pt(s);
1694
- }
1695
- function Pt(s) {
1696
- const r = document.createElement("textarea");
1697
- r.value = s, r.setAttribute("readonly", ""), r.style.position = "fixed", r.style.opacity = "0", document.body.append(r), r.select();
1698
- try {
1699
- return document.execCommand("copy");
1700
- } catch {
1701
- return !1;
1702
- } finally {
1703
- r.remove();
1704
- }
1705
- }
1706
- function tt(s) {
1707
- const r = `${s.apiPath}/auth/keys`;
1708
- return {
1709
- list: () => s.http.get(r).then((l) => ({
1710
- data: l.data,
1711
- scopes: l.meta.scopes,
1712
- maxDays: l.meta.max_days
1713
- })),
1714
- issue: (l) => s.http.post(r, l).then((u) => ({ key: u.data, token: u.token })),
1715
- revoke: (l) => s.http.delete(`${r}/${l}`).then((u) => u.data)
1716
- };
1717
- }
1718
- const Ft = {
1719
- key: 0,
1720
- class: "wx-key-dialog"
1721
- }, Rt = { class: "wx-key-dialog__secret" }, Ot = {
1722
- key: 1,
1723
- class: "wx-key-dialog"
1724
- }, Bt = /* @__PURE__ */ Q({
1725
- __name: "KeyDialog",
1726
- setup(s) {
1727
- const { open: r, resolve: l, dismiss: u } = _e(), v = X(), y = tt(v), A = pe(v);
1728
- te();
1729
- const o = G("webx-auth"), h = re(), U = [30, 90, 365, 1095, 3650], d = W({
1730
- name: "",
1731
- admin: null,
1732
- access: "everything",
1733
- scopes: [],
1734
- days: 365
1735
- }), k = W([]), V = W([]), p = W(!1), g = W({}), b = W(null), w = W(!1), F = L(
1736
- () => k.value.filter((z) => z !== "mcp:use").map((z) => ({ value: z, label: z }))
1737
- ), C = L(() => [
1738
- { value: "everything", label: o("keys.everything") },
1739
- { value: "chosen", label: o("keys.chosen") }
1740
- ]), D = L(
1741
- () => U.map((z) => ({ value: z, label: o(`keys.days-${z}`) }))
1742
- ), n = L(() => {
1743
- const z = v.state.manifest?.modules.find((f) => f.id === "connect")?.meta;
1744
- return typeof z?.url == "string" ? z.url : "";
1745
- });
1746
- y.list().then(
1747
- (z) => k.value = z.scopes,
1748
- (z) => K.danger(h(z))
1749
- ), A.list({ active: "yes", per_page: 100, sort: "name" }).then(
1750
- (z) => V.value = z.data.map((f) => ({
1751
- value: f.id,
1752
- label: `${f.name} · ${f.email}`
1753
- })),
1754
- (z) => K.danger(h(z))
1755
- );
1756
- function x(z) {
1757
- return g.value[z]?.[0] ?? g.value[`${z}.0`]?.[0];
1758
- }
1759
- async function P() {
1760
- if (g.value = {}, d.value.access === "chosen" && d.value.scopes.length === 0) {
1761
- g.value = { scopes: [o("keys.scopes-required")] };
1762
- return;
1763
- }
1764
- p.value = !0;
1765
- try {
1766
- b.value = await y.issue({
1767
- name: d.value.name,
1768
- admin: d.value.admin ?? 0,
1769
- scopes: d.value.access === "chosen" ? d.value.scopes : [],
1770
- days: d.value.days
1771
- });
1772
- } catch (z) {
1773
- const f = z.body;
1774
- f?.errors ? g.value = f.errors : K.danger(h(z));
1775
- } finally {
1776
- p.value = !1;
1777
- }
1778
- }
1779
- async function J() {
1780
- b.value !== null && (await et(b.value.token) ? w.value = !0 : K.danger(o("keys.copy-failed")));
1781
- }
1782
- function O() {
1783
- b.value ? l(b.value.key) : u();
1784
- }
1785
- return (z, f) => (m(), _(e(be), {
1786
- open: e(r),
1787
- title: b.value ? e(o)("keys.issued-title") : e(o)("keys.issue"),
1788
- width: 640,
1789
- "onUpdate:open": f[5] || (f[5] = (R) => R ? void 0 : O())
1790
- }, {
1791
- footer: t(() => [
1792
- a(e(se), { size: "sm" }, {
1793
- default: t(() => [
1794
- b.value ? (m(), _(e(N), {
1795
- key: 0,
1796
- type: "primary",
1797
- onClick: O
1798
- }, {
1799
- default: t(() => [
1800
- c(i(e(o)("keys.done")), 1)
1801
- ]),
1802
- _: 1
1803
- })) : (m(), H(ue, { key: 1 }, [
1804
- a(e(N), {
1805
- variant: "outline",
1806
- onClick: O
1807
- }, {
1808
- default: t(() => [
1809
- c(i(e(o)("keys.cancel")), 1)
1810
- ]),
1811
- _: 1
1812
- }),
1813
- a(e(N), {
1814
- type: "primary",
1815
- loading: p.value,
1816
- onClick: P
1817
- }, {
1818
- default: t(() => [
1819
- c(i(e(o)("keys.issue-short")), 1)
1820
- ]),
1821
- _: 1
1822
- }, 8, ["loading"])
1823
- ], 64))
1824
- ]),
1825
- _: 1
1826
- })
1827
- ]),
1828
- default: t(() => [
1829
- b.value ? (m(), H("div", Ft, [
1830
- a(e(qe), {
1831
- type: "warning",
1832
- closable: !1
1833
- }, {
1834
- default: t(() => [
1835
- c(i(e(o)("keys.issued-text")), 1)
1836
- ]),
1837
- _: 1
1838
- }),
1839
- a(e(M), {
1840
- label: e(o)("keys.secret")
1841
- }, {
1842
- default: t(() => [
1843
- S("div", Rt, [
1844
- a(e(le), {
1845
- "model-value": b.value.token,
1846
- readonly: "",
1847
- name: "token"
1848
- }, null, 8, ["model-value"]),
1849
- a(e(N), {
1850
- type: "primary",
1851
- onClick: J
1852
- }, {
1853
- icon: t(() => [
1854
- a(e(ee), {
1855
- name: w.value ? "check" : "copy"
1856
- }, null, 8, ["name"])
1857
- ]),
1858
- default: t(() => [
1859
- c(" " + i(w.value ? e(o)("keys.copied") : e(o)("keys.copy")), 1)
1860
- ]),
1861
- _: 1
1862
- })
1863
- ])
1864
- ]),
1865
- _: 1
1866
- }, 8, ["label"]),
1867
- n.value ? (m(), _(e(M), {
1868
- key: 0,
1869
- label: e(o)("keys.address")
1870
- }, {
1871
- default: t(() => [
1872
- a(e(le), {
1873
- "model-value": n.value,
1874
- readonly: "",
1875
- name: "address"
1876
- }, null, 8, ["model-value"])
1877
- ]),
1878
- _: 1
1879
- }, 8, ["label"])) : E("", !0),
1880
- a(e(B), {
1881
- size: "sm",
1882
- tone: "muted"
1883
- }, {
1884
- default: t(() => [
1885
- c(i(e(o)("keys.header-hint")), 1)
1886
- ]),
1887
- _: 1
1888
- })
1889
- ])) : (m(), H("div", Ot, [
1890
- a(e(B), {
1891
- size: "sm",
1892
- tone: "muted"
1893
- }, {
1894
- default: t(() => [
1895
- c(i(e(o)("keys.lead")), 1)
1896
- ]),
1897
- _: 1
1898
- }),
1899
- a(e(M), {
1900
- label: e(o)("keys.name"),
1901
- error: x("name"),
1902
- help: e(o)("keys.name-hint")
1903
- }, {
1904
- default: t(() => [
1905
- a(e(le), {
1906
- modelValue: d.value.name,
1907
- "onUpdate:modelValue": f[0] || (f[0] = (R) => d.value.name = R),
1908
- name: "name",
1909
- autocomplete: "off"
1910
- }, null, 8, ["modelValue"])
1911
- ]),
1912
- _: 1
1913
- }, 8, ["label", "error", "help"]),
1914
- a(e(M), {
1915
- label: e(o)("keys.who"),
1916
- error: x("admin"),
1917
- help: e(o)("keys.who-hint")
1918
- }, {
1919
- default: t(() => [
1920
- a(e(ne), {
1921
- modelValue: d.value.admin,
1922
- "onUpdate:modelValue": f[1] || (f[1] = (R) => d.value.admin = R),
1923
- options: V.value,
1924
- filterable: "",
1925
- name: "admin"
1926
- }, null, 8, ["modelValue", "options"])
1927
- ]),
1928
- _: 1
1929
- }, 8, ["label", "error", "help"]),
1930
- a(e(M), {
1931
- label: e(o)("keys.allowed")
1932
- }, {
1933
- default: t(() => [
1934
- a(e(mt), {
1935
- modelValue: d.value.access,
1936
- "onUpdate:modelValue": f[2] || (f[2] = (R) => d.value.access = R),
1937
- options: C.value,
1938
- name: "access"
1939
- }, null, 8, ["modelValue", "options"])
1940
- ]),
1941
- _: 1
1942
- }, 8, ["label"]),
1943
- d.value.access === "chosen" ? (m(), _(e(M), {
1944
- key: 0,
1945
- label: e(o)("keys.scopes"),
1946
- error: x("scopes"),
1947
- help: e(o)("keys.scopes-hint")
1948
- }, {
1949
- default: t(() => [
1950
- a(e(ne), {
1951
- modelValue: d.value.scopes,
1952
- "onUpdate:modelValue": f[3] || (f[3] = (R) => d.value.scopes = R),
1953
- options: F.value,
1954
- multiple: "",
1955
- filterable: "",
1956
- name: "scopes"
1957
- }, null, 8, ["modelValue", "options"])
1958
- ]),
1959
- _: 1
1960
- }, 8, ["label", "error", "help"])) : E("", !0),
1961
- a(e(M), {
1962
- label: e(o)("keys.lifetime"),
1963
- error: x("days"),
1964
- help: e(o)("keys.lifetime-hint")
1965
- }, {
1966
- default: t(() => [
1967
- a(e(ne), {
1968
- modelValue: d.value.days,
1969
- "onUpdate:modelValue": f[4] || (f[4] = (R) => d.value.days = R),
1970
- options: D.value,
1971
- name: "days"
1972
- }, null, 8, ["modelValue", "options"])
1973
- ]),
1974
- _: 1
1975
- }, 8, ["label", "error", "help"])
1976
- ]))
1977
- ]),
1978
- _: 1
1979
- }, 8, ["open", "title"]));
1980
- }
1981
- }), Et = {
1982
- class: "wx-key-list__glyph",
1983
- "aria-hidden": "true"
1984
- }, Re = 560, It = /* @__PURE__ */ Q({
1985
- __name: "KeyList",
1986
- setup(s, { expose: r }) {
1987
- const l = X(), u = tt(l);
1988
- te();
1989
- const v = G("webx-auth"), y = re(), A = oe("root"), o = ge(A), h = L(() => o.value > 0 && o.value < Re), U = W([]), d = W(!1), k = W(null), V = L(() => h.value ? [{ key: "card", label: "" }] : [
1990
- { key: "name", label: v("keys.name"), minWidth: 200 },
1991
- { key: "user", label: v("keys.who"), minWidth: 140 },
1992
- { key: "scopes", label: v("keys.allowed"), minWidth: 180 },
1993
- { key: "expires_at", label: v("keys.expires"), minWidth: 120 },
1994
- { key: "last_used_at", label: v("keys.last-used"), minWidth: 120, hideBelow: 860 },
1995
- { key: "end", label: "", align: "right", width: 120 }
1996
- ]);
1997
- function p(C) {
1998
- return C.user.name ?? v("keys.deleted", { id: C.user.id });
1999
- }
2000
- function g(C) {
2001
- return C.created_by?.name ? v("keys.issued-by", { name: C.created_by.name }) : v("keys.issued-console");
2002
- }
2003
- function b(C) {
2004
- return C.everything ? v("keys.full", { name: C.user.name?.split(" ")[0] || p(C) }) : C.scopes.join(", ");
2005
- }
2006
- async function w() {
2007
- d.value = !0;
2008
- try {
2009
- U.value = (await u.list()).data;
2010
- } catch (C) {
2011
- K.danger(y(C));
2012
- } finally {
2013
- d.value = !1;
2014
- }
2015
- }
2016
- async function F(C) {
2017
- if (await ze({
2018
- title: v("keys.confirm-title", { name: C.name }),
2019
- message: v("keys.confirm-text"),
2020
- confirmText: v("keys.confirm"),
2021
- cancelText: v("keys.cancel"),
2022
- tone: "danger"
2023
- })) {
2024
- k.value = C.id;
2025
- try {
2026
- const n = await u.revoke(C.id);
2027
- U.value = U.value.map((x) => x.id === n.id ? n : x), K.success(v("keys.revoked-done", { name: C.name }));
2028
- } catch (n) {
2029
- K.danger(y(n));
2030
- } finally {
2031
- k.value = null;
2032
- }
2033
- }
2034
- }
2035
- return Ie(w), r({ reload: w }), (C, D) => (m(), H("div", {
2036
- ref_key: "root",
2037
- ref: A,
2038
- class: "wx-key-list"
2039
- }, [
2040
- a(e(ke), {
2041
- data: U.value,
2042
- columns: V.value,
2043
- "row-key": "id",
2044
- flush: "",
2045
- loading: d.value,
2046
- clickable: !1,
2047
- "empty-text": e(v)("keys.empty"),
2048
- "cards-below": Re,
2049
- "row-class": (n) => n.state === "live" ? "" : "is-ended"
2050
- }, {
2051
- "cell-name": t(({ row: n }) => [
2052
- a(e(se), {
2053
- direction: "vertical",
2054
- size: "none"
2055
- }, {
2056
- default: t(() => [
2057
- a(e(B), {
2058
- tone: n.state === "live" ? "default" : "muted",
2059
- weight: "medium"
2060
- }, {
2061
- default: t(() => [
2062
- c(i(n.name), 1)
2063
- ]),
2064
- _: 2
2065
- }, 1032, ["tone"]),
2066
- a(e(B), {
2067
- size: "xs",
2068
- tone: "muted"
2069
- }, {
2070
- default: t(() => [
2071
- c(i(g(n)) + " · ", 1),
2072
- a(e(ae), {
2073
- value: n.created_at,
2074
- tone: "muted",
2075
- compact: ""
2076
- }, null, 8, ["value"])
2077
- ]),
2078
- _: 2
2079
- }, 1024)
2080
- ]),
2081
- _: 2
2082
- }, 1024)
2083
- ]),
2084
- "cell-user": t(({ row: n }) => [
2085
- a(e(B), {
2086
- tone: n.user.name === null ? "muted" : "default"
2087
- }, {
2088
- default: t(() => [
2089
- c(i(p(n)), 1)
2090
- ]),
2091
- _: 2
2092
- }, 1032, ["tone"])
2093
- ]),
2094
- "cell-scopes": t(({ row: n }) => [
2095
- n.state === "revoked" ? (m(), _(e(q), {
2096
- key: 0,
2097
- type: "default",
2098
- dot: ""
2099
- }, {
2100
- default: t(() => [
2101
- c(i(e(v)("keys.revoked")), 1)
2102
- ]),
2103
- _: 1
2104
- })) : n.state === "expired" ? (m(), _(e(q), {
2105
- key: 1,
2106
- type: "default",
2107
- dot: ""
2108
- }, {
2109
- default: t(() => [
2110
- c(i(e(v)("keys.expired")), 1)
2111
- ]),
2112
- _: 1
2113
- })) : (m(), _(e(q), {
2114
- key: 2,
2115
- type: n.everything ? "success" : "info",
2116
- dot: ""
2117
- }, {
2118
- default: t(() => [
2119
- c(i(b(n)), 1)
2120
- ]),
2121
- _: 2
2122
- }, 1032, ["type"]))
2123
- ]),
2124
- "cell-expires_at": t(({ row: n }) => [
2125
- n.expires_at ? (m(), _(e(ae), {
2126
- key: 0,
2127
- value: n.expires_at,
2128
- compact: ""
2129
- }, null, 8, ["value"])) : E("", !0)
2130
- ]),
2131
- "cell-last_used_at": t(({ row: n }) => [
2132
- n.last_used_at ? (m(), _(e(ae), {
2133
- key: 0,
2134
- value: n.last_used_at,
2135
- compact: ""
2136
- }, null, 8, ["value"])) : (m(), _(e(B), {
2137
- key: 1,
2138
- size: "sm",
2139
- tone: "muted"
2140
- }, {
2141
- default: t(() => [
2142
- c(i(e(v)("keys.never-used")), 1)
2143
- ]),
2144
- _: 1
2145
- }))
2146
- ]),
2147
- "cell-end": t(({ row: n }) => [
2148
- n.state === "live" ? (m(), _(e(N), {
2149
- key: 0,
2150
- type: "danger",
2151
- variant: "text",
2152
- size: "sm",
2153
- loading: k.value === n.id,
2154
- onClick: (x) => F(n)
2155
- }, {
2156
- default: t(() => [
2157
- c(i(e(v)("keys.revoke")), 1)
2158
- ]),
2159
- _: 1
2160
- }, 8, ["loading", "onClick"])) : E("", !0)
2161
- ]),
2162
- "cell-card": t(({ row: n }) => [
2163
- a(e(we), {
2164
- variant: "plain",
2165
- title: n.name,
2166
- subtitle: p(n)
2167
- }, {
2168
- media: t(() => [
2169
- S("span", Et, [
2170
- a(e(ee), { name: "lock" })
2171
- ])
2172
- ]),
2173
- meta: t(() => [
2174
- n.state === "revoked" ? (m(), _(e(q), {
2175
- key: 0,
2176
- type: "default",
2177
- dot: "",
2178
- size: "sm"
2179
- }, {
2180
- default: t(() => [
2181
- c(i(e(v)("keys.revoked")), 1)
2182
- ]),
2183
- _: 1
2184
- })) : n.state === "expired" ? (m(), _(e(q), {
2185
- key: 1,
2186
- type: "default",
2187
- dot: "",
2188
- size: "sm"
2189
- }, {
2190
- default: t(() => [
2191
- c(i(e(v)("keys.expired")), 1)
2192
- ]),
2193
- _: 1
2194
- })) : (m(), _(e(q), {
2195
- key: 2,
2196
- type: n.everything ? "success" : "info",
2197
- dot: "",
2198
- size: "sm"
2199
- }, {
2200
- default: t(() => [
2201
- c(i(b(n)), 1)
2202
- ]),
2203
- _: 2
2204
- }, 1032, ["type"])),
2205
- n.expires_at ? (m(), _(e(B), {
2206
- key: 3,
2207
- size: "xs",
2208
- tone: "muted"
2209
- }, {
2210
- default: t(() => [
2211
- c(i(e(v)("keys.until")) + " ", 1),
2212
- a(e(ae), {
2213
- value: n.expires_at,
2214
- compact: ""
2215
- }, null, 8, ["value"])
2216
- ]),
2217
- _: 2
2218
- }, 1024)) : E("", !0)
2219
- ]),
2220
- actions: t(() => [
2221
- n.state === "live" ? (m(), _(e(N), {
2222
- key: 0,
2223
- type: "danger",
2224
- variant: "text",
2225
- size: "sm",
2226
- loading: k.value === n.id,
2227
- onClick: (x) => F(n)
2228
- }, {
2229
- default: t(() => [
2230
- c(i(e(v)("keys.revoke")), 1)
2231
- ]),
2232
- _: 1
2233
- }, 8, ["loading", "onClick"])) : E("", !0)
2234
- ]),
2235
- _: 2
2236
- }, 1032, ["title", "subtitle"])
2237
- ]),
2238
- _: 1
2239
- }, 8, ["data", "columns", "loading", "empty-text", "row-class"])
2240
- ], 512));
2241
- }
2242
- }), Dt = /* @__PURE__ */ Q({
2243
- __name: "AdminsPage",
2244
- props: {
2245
- base: { default: "/admins" },
2246
- current: { default: "admins" },
2247
- avatarField: { default: void 0 },
2248
- resolveAvatar: { type: Function, default: void 0 }
2249
- },
2250
- setup(s) {
2251
- const r = s, l = X(), u = pe(l), v = r.avatarField ?? Ye(l) ?? void 0, y = r.resolveAvatar ?? Je(l) ?? void 0, A = rt(), o = ct();
2252
- te();
2253
- const h = G("webx-auth"), U = re(), d = oe("list"), k = oe("keys"), V = W(null), p = he($t), g = he(Bt), b = l.can("admins.manage"), w = l.can("admins.audit"), F = L(
2254
- () => l.state.manifest?.modules.find((O) => O.id === "admins")?.title ?? h("admins.title")
2255
- ), C = L(() => {
2256
- const O = [{ value: "admins", label: F.value }];
2257
- return w && O.push({ value: "calls", label: h("calls.title") }), b && O.push({ value: "connections", label: h("connections.title") }), b && O.push({ value: "keys", label: h("keys.title") }), O.length > 1 ? O : void 0;
2258
- }), D = L({
2259
- get: () => r.current,
2260
- set: (O) => {
2261
- const z = O === "admins" ? r.base : `${r.base}/${String(O)}`;
2262
- z !== o.path && A.push(z);
2263
- }
2264
- }), n = L(() => b ? r.current === "admins" ? [
2265
- {
2266
- key: "new",
2267
- label: h("admins.new-short"),
2268
- icon: "plus",
2269
- primary: !0,
2270
- run: () => {
2271
- P(null);
2272
- }
2273
- }
2274
- ] : r.current === "keys" ? [
2275
- {
2276
- key: "issue",
2277
- label: h("keys.issue-short"),
2278
- icon: "plus",
2279
- primary: !0,
2280
- run: () => {
2281
- x();
2282
- }
2283
- }
2284
- ] : [] : []);
2285
- async function x() {
2286
- await g() && k.value?.reload();
2287
- }
2288
- async function P(O) {
2289
- V.value = O, await p({ admin: O, avatarField: v }) && d.value?.reload();
2290
- }
2291
- async function J(O) {
2292
- if (await ze({
2293
- title: h("admins.delete-title", { name: O.name }),
2294
- message: h("admins.delete-text"),
2295
- confirmText: h("admins.delete"),
2296
- cancelText: h("admins.cancel"),
2297
- tone: "danger"
2298
- }))
2299
- try {
2300
- await u.remove(O.id), K.success(h("admins.deleted")), d.value?.reload();
2301
- } catch (f) {
2302
- K.danger(U(f));
2303
- }
2304
- }
2305
- return (O, z) => (m(), _(e(Ke), {
2306
- view: D.value,
2307
- "onUpdate:view": z[0] || (z[0] = (f) => D.value = f),
2308
- title: F.value,
2309
- views: C.value,
2310
- actions: n.value
2311
- }, {
2312
- default: t(() => [
2313
- s.current === "calls" ? (m(), _(Lt, { key: 0 })) : s.current === "connections" ? (m(), _(Ze, {
2314
- key: 1,
2315
- scope: "all"
2316
- })) : s.current === "keys" ? (m(), _(It, {
2317
- key: 2,
2318
- ref: "keys"
2319
- }, null, 512)) : (m(), _(Xe, {
2320
- key: 3,
2321
- ref_key: "list",
2322
- ref: d,
2323
- removable: e(b),
2324
- "resolve-avatar": e(y),
2325
- onOpen: P,
2326
- onRemove: J
2327
- }, null, 8, ["removable", "resolve-avatar"]))
2328
- ]),
2329
- _: 1
2330
- }, 8, ["view", "title", "views", "actions"]));
2331
- }
2332
- }), Nt = {
2333
- key: 0,
2334
- class: "wx-content-rules"
2335
- }, Mt = { class: "wx-content-rules__foot" }, Kt = /* @__PURE__ */ Q({
2336
- __name: "ContentRulesCard",
2337
- setup(s) {
2338
- const r = X();
2339
- te();
2340
- const l = G("webx-auth"), u = G("webx-admin"), v = re(), y = L(() => {
2341
- const b = r.state.manifest?.modules.find((w) => w.id === "settings")?.meta?.content_screen;
2342
- return typeof b == "string" ? b : null;
2343
- }), A = r.can("settings.view") || r.can("settings.manage"), o = r.can("settings.manage"), h = W({}), U = W({}), d = W(!0), k = W(!1), V = `${r.apiPath}/settings/content`;
2344
- Ie(async () => {
2345
- if (!(!y.value || !A))
2346
- try {
2347
- const g = await r.http.get(V);
2348
- h.value = g.data.values;
2349
- } catch (g) {
2350
- K.danger(v(g));
2351
- } finally {
2352
- d.value = !1;
2353
- }
2354
- });
2355
- async function p() {
2356
- k.value = !0, U.value = {};
2357
- try {
2358
- const g = await r.http.put(V, {
2359
- values: h.value
2360
- });
2361
- h.value = g.data.values, K.success(u("editor.saved"));
2362
- } catch (g) {
2363
- const b = g.body;
2364
- b?.errors && (U.value = b.errors), K.danger(v(g));
2365
- } finally {
2366
- k.value = !1;
2367
- }
2368
- }
2369
- return (g, b) => y.value && e(A) ? (m(), H("section", Nt, [
2370
- a(e(me), {
2371
- level: 2,
2372
- size: "sm"
2373
- }, {
2374
- default: t(() => [
2375
- c(i(e(l)("connect.rules")), 1)
2376
- ]),
2377
- _: 1
2378
- }),
2379
- a(e($e), null, Ae({
2380
- default: t(() => [
2381
- d.value ? (m(), _(e(vt), {
2382
- key: 0,
2383
- rows: 4
2384
- })) : (m(), _(e(it), {
2385
- key: 1,
2386
- modelValue: h.value,
2387
- "onUpdate:modelValue": b[0] || (b[0] = (w) => h.value = w),
2388
- name: y.value,
2389
- errors: U.value,
2390
- disabled: !e(o)
2391
- }, null, 8, ["modelValue", "name", "errors", "disabled"]))
2392
- ]),
2393
- _: 2
2394
- }, [
2395
- d.value ? void 0 : {
2396
- name: "footer",
2397
- fn: t(() => [
2398
- S("div", Mt, [
2399
- a(e(B), {
2400
- size: "sm",
2401
- tone: "muted"
2402
- }, {
2403
- default: t(() => [
2404
- c(i(e(l)("connect.rules-hint")), 1)
2405
- ]),
2406
- _: 1
2407
- }),
2408
- e(o) ? (m(), _(e(N), {
2409
- key: 0,
2410
- type: "primary",
2411
- loading: k.value,
2412
- onClick: p
2413
- }, {
2414
- default: t(() => [
2415
- c(i(e(u)("editor.save")), 1)
2416
- ]),
2417
- _: 1
2418
- }, 8, ["loading"])) : E("", !0)
2419
- ])
2420
- ]),
2421
- key: "0"
2422
- }
2423
- ]), 1024)
2424
- ])) : E("", !0);
2425
- }
2426
- }), qt = /* @__PURE__ */ ve(Kt, [["__scopeId", "data-v-55be157e"]]), Ht = { class: "wx-connect" }, jt = { class: "wx-connect__section" }, Gt = { class: "wx-connect__row" }, Yt = { class: "wx-connect__url" }, Jt = { class: "wx-connect__section" }, Qt = { class: "wx-connect__steps" }, Xt = { class: "wx-connect__steps" }, Zt = { class: "wx-connect__snippet" }, ea = { class: "wx-connect__snippet" }, ta = { class: "wx-connect__section" }, aa = { class: "wx-connect__links" }, la = { class: "wx-connect__steps" }, na = { class: "wx-connect__section" }, sa = /* @__PURE__ */ Q({
2427
- __name: "ConnectPage",
2428
- setup(s) {
2429
- const r = X();
2430
- te();
2431
- const l = G("webx-auth"), u = W(!1);
2432
- let v;
2433
- const y = L(() => {
2434
- const p = r.state.manifest?.modules.find((g) => g.id === "connect")?.meta;
2435
- return typeof p?.url == "string" ? p.url : "";
2436
- }), A = L(() => {
2437
- try {
2438
- return new URL(y.value).hostname.split(".")[0] || "webx";
2439
- } catch {
2440
- return "webx";
2441
- }
2442
- }), o = L(() => `claude mcp add --transport http ${A.value} ${y.value}`), h = L(() => `[mcp_servers.${A.value}]
2443
- url = "${y.value}"`), U = L(() => {
2444
- const p = k(JSON.stringify({ url: y.value }));
2445
- return `cursor://anysphere.cursor-deeplink/mcp/install?name=${encodeURIComponent(A.value)}&config=${p}`;
2446
- }), d = L(() => {
2447
- const p = JSON.stringify({ name: A.value, type: "http", url: y.value });
2448
- return `vscode:mcp/install?${encodeURIComponent(p)}`;
2449
- });
2450
- function k(p) {
2451
- const g = new TextEncoder().encode(p);
2452
- let b = "";
2453
- for (const w of g) b += String.fromCharCode(w);
2454
- return encodeURIComponent(btoa(b));
2455
- }
2456
- async function V(p) {
2457
- if (!await et(p)) {
2458
- K.danger(l("connect.copy-failed"));
2459
- return;
2460
- }
2461
- u.value = !0, clearTimeout(v), v = setTimeout(() => u.value = !1, 2e3);
2462
- }
2463
- return (p, g) => (m(), _(e(Ke), {
2464
- title: e(l)("connect.title"),
2465
- card: !1
2466
- }, {
2467
- default: t(() => [
2468
- S("div", Ht, [
2469
- a(e(B), { class: "wx-connect__lead" }, {
2470
- default: t(() => [
2471
- c(i(e(l)("connect.lead")), 1)
2472
- ]),
2473
- _: 1
2474
- }),
2475
- S("section", jt, [
2476
- a(e(me), {
2477
- level: 2,
2478
- size: "sm"
2479
- }, {
2480
- default: t(() => [
2481
- c(i(e(l)("connect.address")), 1)
2482
- ]),
2483
- _: 1
2484
- }),
2485
- a(e($e), { bordered: "" }, {
2486
- default: t(() => [
2487
- S("div", Gt, [
2488
- S("code", Yt, i(y.value), 1),
2489
- a(e(N), {
2490
- type: "primary",
2491
- disabled: y.value === "",
2492
- onClick: g[0] || (g[0] = (b) => V(y.value))
2493
- }, {
2494
- icon: t(() => [
2495
- a(e(ee), {
2496
- name: u.value ? "check" : "copy"
2497
- }, null, 8, ["name"])
2498
- ]),
2499
- default: t(() => [
2500
- c(" " + i(u.value ? e(l)("connect.copied") : e(l)("connect.copy")), 1)
2501
- ]),
2502
- _: 1
2503
- }, 8, ["disabled"])
2504
- ])
2505
- ]),
2506
- _: 1
2507
- })
2508
- ]),
2509
- S("section", Jt, [
2510
- a(e(me), {
2511
- level: 2,
2512
- size: "sm"
2513
- }, {
2514
- default: t(() => [
2515
- c(i(e(l)("connect.how")), 1)
2516
- ]),
2517
- _: 1
2518
- }),
2519
- a(e(pt), {
2520
- variant: "line",
2521
- "aria-label": e(l)("connect.how")
2522
- }, {
2523
- default: t(() => [
2524
- a(e(ye), {
2525
- value: "claude",
2526
- label: e(l)("connect.claude-title")
2527
- }, {
2528
- default: t(() => [
2529
- S("ol", Qt, [
2530
- S("li", null, i(e(l)("connect.claude-1")), 1),
2531
- S("li", null, i(e(l)("connect.claude-2")), 1),
2532
- S("li", null, i(e(l)("connect.claude-3")), 1)
2533
- ])
2534
- ]),
2535
- _: 1
2536
- }, 8, ["label"]),
2537
- a(e(ye), {
2538
- value: "chatgpt",
2539
- label: e(l)("connect.chatgpt-title")
2540
- }, {
2541
- default: t(() => [
2542
- S("ol", Xt, [
2543
- S("li", null, i(e(l)("connect.chatgpt-1")), 1),
2544
- S("li", null, i(e(l)("connect.chatgpt-2")), 1),
2545
- S("li", null, i(e(l)("connect.chatgpt-3")), 1)
2546
- ])
2547
- ]),
2548
- _: 1
2549
- }, 8, ["label"]),
2550
- a(e(ye), {
2551
- value: "claude-code",
2552
- label: e(l)("connect.claude-code-title")
2553
- }, {
2554
- default: t(() => [
2555
- a(e(B), { size: "sm" }, {
2556
- default: t(() => [
2557
- c(i(e(l)("connect.claude-code-hint")), 1)
2558
- ]),
2559
- _: 1
2560
- }),
2561
- S("div", Zt, [
2562
- S("pre", null, i(o.value), 1),
2563
- a(e(N), {
2564
- variant: "text",
2565
- size: "sm",
2566
- onClick: g[1] || (g[1] = (b) => V(o.value))
2567
- }, {
2568
- icon: t(() => [
2569
- a(e(ee), { name: "copy" })
2570
- ]),
2571
- default: t(() => [
2572
- c(" " + i(e(l)("connect.copy-line")), 1)
2573
- ]),
2574
- _: 1
2575
- })
2576
- ])
2577
- ]),
2578
- _: 1
2579
- }, 8, ["label"]),
2580
- a(e(ye), {
2581
- value: "codex",
2582
- label: e(l)("connect.codex-title")
2583
- }, {
2584
- default: t(() => [
2585
- a(e(B), { size: "sm" }, {
2586
- default: t(() => [
2587
- c(i(e(l)("connect.codex-hint")), 1)
2588
- ]),
2589
- _: 1
2590
- }),
2591
- S("div", ea, [
2592
- S("pre", null, i(h.value), 1),
2593
- a(e(N), {
2594
- variant: "text",
2595
- size: "sm",
2596
- onClick: g[2] || (g[2] = (b) => V(h.value))
2597
- }, {
2598
- icon: t(() => [
2599
- a(e(ee), { name: "copy" })
2600
- ]),
2601
- default: t(() => [
2602
- c(" " + i(e(l)("connect.copy-line")), 1)
2603
- ]),
2604
- _: 1
2605
- })
2606
- ])
2607
- ]),
2608
- _: 1
2609
- }, 8, ["label"])
2610
- ]),
2611
- _: 1
2612
- }, 8, ["aria-label"])
2613
- ]),
2614
- S("section", ta, [
2615
- a(e(me), {
2616
- level: 2,
2617
- size: "sm"
2618
- }, {
2619
- default: t(() => [
2620
- c(i(e(l)("connect.one-click")), 1)
2621
- ]),
2622
- _: 1
2623
- }),
2624
- a(e(B), {
2625
- size: "sm",
2626
- tone: "muted"
2627
- }, {
2628
- default: t(() => [
2629
- c(i(e(l)("connect.one-click-hint")), 1)
2630
- ]),
2631
- _: 1
2632
- }),
2633
- S("div", aa, [
2634
- a(e(N), {
2635
- href: U.value,
2636
- variant: "outline",
2637
- disabled: y.value === "",
2638
- class: "wx-connect__link"
2639
- }, {
2640
- icon: t(() => [
2641
- a(e(ee), { name: "external-link" })
2642
- ]),
2643
- default: t(() => [
2644
- c(" " + i(e(l)("connect.install-in", { client: e(l)("connect.cursor-title") })), 1)
2645
- ]),
2646
- _: 1
2647
- }, 8, ["href", "disabled"]),
2648
- a(e(N), {
2649
- href: d.value,
2650
- variant: "outline",
2651
- disabled: y.value === "",
2652
- class: "wx-connect__link"
2653
- }, {
2654
- icon: t(() => [
2655
- a(e(ee), { name: "external-link" })
2656
- ]),
2657
- default: t(() => [
2658
- c(" " + i(e(l)("connect.install-in", { client: e(l)("connect.vscode-title") })), 1)
2659
- ]),
2660
- _: 1
2661
- }, 8, ["href", "disabled"])
2662
- ])
2663
- ]),
2664
- a(e(qe), {
2665
- type: "info",
2666
- title: e(l)("connect.next")
2667
- }, {
2668
- default: t(() => [
2669
- S("ol", la, [
2670
- S("li", null, i(e(l)("connect.next-1")), 1),
2671
- S("li", null, i(e(l)("connect.next-2")), 1),
2672
- S("li", null, i(e(l)("connect.next-3")), 1)
2673
- ])
2674
- ]),
2675
- _: 1
2676
- }, 8, ["title"]),
2677
- a(qt),
2678
- S("section", na, [
2679
- a(e(me), {
2680
- level: 2,
2681
- size: "sm"
2682
- }, {
2683
- default: t(() => [
2684
- c(i(e(l)("connect.mine")), 1)
2685
- ]),
2686
- _: 1
2687
- }),
2688
- a(e($e), { padding: "none" }, {
2689
- default: t(() => [
2690
- a(Ze, { scope: "mine" })
2691
- ]),
2692
- _: 1
2693
- })
2694
- ])
2695
- ])
2696
- ]),
2697
- _: 1
2698
- }, 8, ["title"]));
2699
- }
2700
- }), oa = /* @__PURE__ */ ve(sa, [["__scopeId", "data-v-19a489e0"]]);
2701
- function Ca(s = {}) {
2702
- const r = s.path ?? "/admins", l = (u) => ({
2703
- render: () => De(Dt, {
2704
- base: r,
2705
- current: u,
2706
- avatarField: s.avatarField,
2707
- resolveAvatar: s.resolveAvatar
2708
- })
2709
- });
2710
- return {
2711
- id: "admins",
2712
- path: r,
2713
- routes: [
2714
- { path: r, name: "webx.admins", component: l("admins") },
2715
- // What their agents did, which agents they let in, and their keys: more views of the same
2716
- // section, each with an address of its own so that its filters survive a trip to the
2717
- // people and back.
2718
- { path: `${r}/calls`, name: "webx.admins.calls", component: l("calls") },
2719
- {
2720
- path: `${r}/connections`,
2721
- name: "webx.admins.connections",
2722
- component: l("connections")
2723
- },
2724
- // Keys for programs: a connection without a browser, issued by somebody who manages
2725
- // the people it acts as.
2726
- { path: `${r}/keys`, name: "webx.admins.keys", component: l("keys") }
2727
- ]
2728
- };
2729
- }
2730
- function $a(s = {}) {
2731
- const r = s.path ?? "/connect";
2732
- return {
2733
- id: "connect",
2734
- path: r,
2735
- routes: [{ path: r, name: "webx.connect", component: oa }]
2736
- };
2737
- }
2738
- const ia = /* @__PURE__ */ Q({
2739
- __name: "AdminPicker",
2740
- props: {
2741
- multiple: { type: Boolean, default: !1 },
2742
- title: { default: void 0 },
2743
- resolveAvatar: { type: Function, default: void 0 }
2744
- },
2745
- setup(s) {
2746
- const r = s, { open: l, resolve: u, dismiss: v } = _e();
2747
- te();
2748
- const y = G("webx-auth"), A = oe("list"), o = W(0);
2749
- function h(d) {
2750
- u(d);
2751
- }
2752
- function U(d) {
2753
- o.value = d.length;
2754
- }
2755
- return (d, k) => (m(), _(e(be), {
2756
- open: e(l),
2757
- "onUpdate:open": k[2] || (k[2] = (V) => Ve(l) ? l.value = V : null),
2758
- title: s.title ?? e(y)(s.multiple ? "admins.select-many" : "admins.select-one"),
2759
- width: 880
2760
- }, Ae({
2761
- default: t(() => [
2762
- a(Xe, {
2763
- ref_key: "list",
2764
- ref: A,
2765
- picking: "",
2766
- multiple: s.multiple,
2767
- "resolve-avatar": r.resolveAvatar,
2768
- onChosen: h,
2769
- onSelection: U
2770
- }, null, 8, ["multiple", "resolve-avatar"])
2771
- ]),
2772
- _: 2
2773
- }, [
2774
- s.multiple ? {
2775
- name: "footer",
2776
- fn: t(() => [
2777
- a(e(se), {
2778
- size: "sm",
2779
- align: "center"
2780
- }, {
2781
- default: t(() => [
2782
- a(e(B), {
2783
- size: "sm",
2784
- tone: "muted"
2785
- }, {
2786
- default: t(() => [
2787
- c(i(e(y)("admins.chosen", { count: o.value })), 1)
2788
- ]),
2789
- _: 1
2790
- }),
2791
- a(e(N), {
2792
- variant: "outline",
2793
- onClick: k[0] || (k[0] = (V) => e(v)())
2794
- }, {
2795
- default: t(() => [
2796
- c(i(e(y)("admins.cancel")), 1)
2797
- ]),
2798
- _: 1
2799
- }),
2800
- a(e(N), {
2801
- type: "primary",
2802
- disabled: o.value === 0,
2803
- onClick: k[1] || (k[1] = (V) => e(u)(A.value?.chosen() ?? []))
2804
- }, {
2805
- default: t(() => [
2806
- c(i(e(y)("admins.save")), 1)
2807
- ]),
2808
- _: 1
2809
- }, 8, ["disabled"])
2810
- ]),
2811
- _: 1
2812
- })
2813
- ]),
2814
- key: "0"
2815
- } : void 0
2816
- ]), 1032, ["open", "title"]));
2817
- }
2818
- }), at = he(ia);
2819
- async function Va(s = {}) {
2820
- return (await at({ ...s, multiple: !1 }))?.[0];
2821
- }
2822
- function Aa(s = {}) {
2823
- return at({ ...s, multiple: !0 });
2824
- }
2825
- const ua = { class: "wx-profile-host" }, ra = { class: "wx-profile" }, ca = {
2826
- key: 0,
2827
- class: "wx-profile__aside"
2828
- }, da = { class: "wx-profile__fields" }, ma = /* @__PURE__ */ Q({
2829
- __name: "ProfileDialog",
2830
- props: {
2831
- avatarField: { default: void 0 }
2832
- },
2833
- setup(s) {
2834
- const r = s, { resolve: l, dismiss: u, open: v } = _e(), y = X(), A = We();
2835
- te();
2836
- const o = G("webx-auth"), h = re(), U = W(!1), d = W({}), k = W({
2837
- name: y.state.user?.name ?? "",
2838
- avatar: y.state.user?.avatar ?? null,
2839
- password: "",
2840
- current_password: ""
2841
- }), V = W(k.value.avatar ? { path: k.value.avatar } : null);
2842
- function p(b) {
2843
- return d.value[b]?.[0];
2844
- }
2845
- async function g() {
2846
- U.value = !0, d.value = {};
2847
- try {
2848
- await A.updateProfile({
2849
- name: k.value.name,
2850
- avatar: V.value?.path ?? null,
2851
- // Blank is left out entirely rather than sent as an empty string: the server reads a
2852
- // filled password as "change it", and an empty one would be a change to nothing.
2853
- ...k.value.password ? { password: k.value.password, current_password: k.value.current_password } : {}
2854
- }), K.success(o("profile.saved")), l(!0);
2855
- } catch (b) {
2856
- const w = b.body;
2857
- w?.errors ? d.value = w.errors : K.danger(h(b));
2858
- } finally {
2859
- U.value = !1;
2860
- }
2861
- }
2862
- return (b, w) => (m(), _(e(be), {
2863
- open: e(v),
2864
- "onUpdate:open": w[5] || (w[5] = (F) => Ve(v) ? v.value = F : null),
2865
- title: e(o)("profile.title"),
2866
- width: 560
2867
- }, {
2868
- footer: t(() => [
2869
- a(e(N), {
2870
- onClick: w[4] || (w[4] = (F) => e(u)())
2871
- }, {
2872
- default: t(() => [
2873
- c(i(e(o)("profile.cancel")), 1)
2874
- ]),
2875
- _: 1
2876
- }),
2877
- a(e(N), {
2878
- type: "primary",
2879
- loading: U.value,
2880
- onClick: g
2881
- }, {
2882
- default: t(() => [
2883
- c(i(e(o)("profile.save")), 1)
2884
- ]),
2885
- _: 1
2886
- }, 8, ["loading"])
2887
- ]),
2888
- default: t(() => [
2889
- S("div", ua, [
2890
- S("div", ra, [
2891
- r.avatarField ? (m(), H("div", ca, [
2892
- (m(), _(Ee(r.avatarField), {
2893
- modelValue: V.value,
2894
- "onUpdate:modelValue": w[0] || (w[0] = (F) => V.value = F),
2895
- label: e(o)("profile.avatar"),
2896
- aspect: "1/1",
2897
- captions: !1
2898
- }, null, 8, ["modelValue", "label"]))
2899
- ])) : E("", !0),
2900
- S("div", da, [
2901
- a(e(M), {
2902
- label: e(o)("profile.name"),
2903
- error: p("name")
2904
- }, {
2905
- default: t(() => [
2906
- a(e(le), {
2907
- modelValue: k.value.name,
2908
- "onUpdate:modelValue": w[1] || (w[1] = (F) => k.value.name = F),
2909
- name: "name"
2910
- }, null, 8, ["modelValue"])
2911
- ]),
2912
- _: 1
2913
- }, 8, ["label", "error"]),
2914
- a(e(M), {
2915
- label: e(o)("admins.email")
2916
- }, {
2917
- default: t(() => [
2918
- a(e(le), {
2919
- "model-value": e(y).state.user?.email ?? "",
2920
- readonly: ""
2921
- }, null, 8, ["model-value"])
2922
- ]),
2923
- _: 1
2924
- }, 8, ["label"]),
2925
- a(e(M), {
2926
- label: e(o)("profile.password"),
2927
- help: e(o)("profile.password-hint"),
2928
- error: p("password")
2929
- }, {
2930
- default: t(() => [
2931
- a(e(le), {
2932
- modelValue: k.value.password,
2933
- "onUpdate:modelValue": w[2] || (w[2] = (F) => k.value.password = F),
2934
- type: "password",
2935
- autocomplete: "new-password"
2936
- }, null, 8, ["modelValue"])
2937
- ]),
2938
- _: 1
2939
- }, 8, ["label", "help", "error"]),
2940
- k.value.password ? (m(), _(e(M), {
2941
- key: 0,
2942
- label: e(o)("profile.current-password"),
2943
- help: e(o)("profile.current-password-hint"),
2944
- error: p("current_password")
2945
- }, {
2946
- default: t(() => [
2947
- a(e(le), {
2948
- modelValue: k.value.current_password,
2949
- "onUpdate:modelValue": w[3] || (w[3] = (F) => k.value.current_password = F),
2950
- type: "password",
2951
- autocomplete: "current-password"
2952
- }, null, 8, ["modelValue"])
2953
- ]),
2954
- _: 1
2955
- }, 8, ["label", "help", "error"])) : E("", !0)
2956
- ])
2957
- ])
2958
- ])
2959
- ]),
2960
- _: 1
2961
- }, 8, ["open", "title"]));
2962
- }
2963
- }), va = /* @__PURE__ */ ve(ma, [["__scopeId", "data-v-9583a67a"]]), pa = ["title"], fa = { class: "wx-user-menu__who" }, ya = { class: "wx-user-menu__name" }, ha = { class: "wx-user-menu__email" }, _a = /* @__PURE__ */ Q({
2964
- __name: "UserMenu",
2965
- props: {
2966
- signOutLabel: { default: void 0 },
2967
- resolveAvatar: { type: Function, default: void 0 },
2968
- avatarField: { default: void 0 },
2969
- expanded: { type: Boolean, default: !1 }
2970
- },
2971
- setup(s) {
2972
- const r = s, l = X(), u = We(), v = Ne(), y = ut(), A = G("webx-auth"), o = v.scope("webx-admin"), h = L(() => l.state.user), U = l.siteUrl, d = L(
2973
- () => v.state.panelLocales.length > 1 ? v.state.panelLocales : []
2974
- ), k = xe(je, null), V = xe(Ge, null), p = W(void 0);
2975
- de(
2976
- () => typeof h.value?.avatar == "string" ? h.value.avatar : null,
2977
- async (n) => {
2978
- const x = r.resolveAvatar ?? k;
2979
- if (n === null || n === "" || x === null) {
2980
- p.value = void 0;
2981
- return;
2982
- }
2983
- const P = await x(n);
2984
- h.value?.avatar === n && (p.value = P ?? void 0);
2985
- },
2986
- { immediate: !0 }
2987
- );
2988
- const g = he(va);
2989
- function b() {
2990
- setTimeout(
2991
- () => {
2992
- g({ avatarField: r.avatarField ?? V ?? void 0 });
2993
- },
2994
- 0
2995
- );
2996
- }
2997
- const w = L({
2998
- get: () => y.state.preference,
2999
- set: (n) => {
3000
- y.set(n), u.setTheme(n);
3001
- }
3002
- }), F = L(
3003
- () => typeof h.value?.siteBar == "boolean" ? h.value.siteBar : null
3004
- );
3005
- function C() {
3006
- F.value !== null && u.setSiteBar(!F.value);
3007
- }
3008
- async function D(n) {
3009
- n !== v.state.locale && await u.setLocale(n);
3010
- }
3011
- return (n, x) => {
3012
- const P = Y("wx-avatar"), J = Y("wx-icon"), O = Y("wx-text"), z = Y("wx-dropdown-item"), f = Y("wx-divider"), R = Y("wx-dropdown");
3013
- return h.value !== null ? (m(), _(R, { key: 0 }, {
3014
- trigger: t(() => [
3015
- S("button", {
3016
- type: "button",
3017
- class: Be(["wx-user-menu__trigger", { "wx-user-menu__trigger--named": s.expanded }]),
3018
- title: h.value.name
3019
- }, [
3020
- a(P, {
3021
- name: h.value.name,
3022
- src: p.value,
3023
- size: "lg"
3024
- }, null, 8, ["name", "src"]),
3025
- s.expanded ? (m(), H(ue, { key: 0 }, [
3026
- S("span", fa, [
3027
- S("span", ya, i(h.value.name), 1),
3028
- S("span", ha, i(h.value.email), 1)
3029
- ]),
3030
- a(J, {
3031
- name: "chevron-up",
3032
- size: "sm",
3033
- class: "wx-user-menu__chevron"
3034
- })
3035
- ], 64)) : E("", !0)
3036
- ], 10, pa)
3037
- ]),
3038
- default: t(() => [
3039
- a(z, { disabled: "" }, {
3040
- default: t(() => [
3041
- a(O, { size: "sm" }, {
3042
- default: t(() => [
3043
- c(i(h.value.email), 1)
3044
- ]),
3045
- _: 1
3046
- })
3047
- ]),
3048
- _: 1
3049
- }),
3050
- a(f, { spacing: "sm" }),
3051
- a(z, {
3052
- icon: "user",
3053
- onClick: b
3054
- }, {
3055
- default: t(() => [
3056
- c(i(e(A)("profile.menu")), 1)
3057
- ]),
3058
- _: 1
3059
- }),
3060
- e(U) ? (m(), _(z, {
3061
- key: 0,
3062
- icon: "external-link",
3063
- href: e(U),
3064
- target: "_blank",
3065
- rel: "noopener"
3066
- }, {
3067
- default: t(() => [
3068
- c(i(e(o)("nav.open-site")), 1)
3069
- ]),
3070
- _: 1
3071
- }, 8, ["href"])) : E("", !0),
3072
- a(f, { spacing: "sm" }),
3073
- a(z, { disabled: "" }, {
3074
- default: t(() => [
3075
- a(O, {
3076
- size: "sm",
3077
- tone: "muted"
3078
- }, {
3079
- default: t(() => [
3080
- c(i(e(o)("theme.label")), 1)
3081
- ]),
3082
- _: 1
3083
- })
3084
- ]),
3085
- _: 1
3086
- }),
3087
- S("div", {
3088
- class: "wx-user-menu__theme",
3089
- onClick: x[1] || (x[1] = Oe(() => {
3090
- }, ["stop"]))
3091
- }, [
3092
- a(e(ft), {
3093
- modelValue: w.value,
3094
- "onUpdate:modelValue": x[0] || (x[0] = ($) => w.value = $),
3095
- size: "sm",
3096
- block: "",
3097
- "aria-label": e(o)("theme.label"),
3098
- "light-label": e(o)("theme.light"),
3099
- "dark-label": e(o)("theme.dark"),
3100
- "system-label": e(o)("theme.system")
3101
- }, null, 8, ["modelValue", "aria-label", "light-label", "dark-label", "system-label"])
3102
- ]),
3103
- F.value !== null ? (m(), H(ue, { key: 1 }, [
3104
- a(f, { spacing: "sm" }),
3105
- a(z, {
3106
- icon: F.value ? "check" : void 0,
3107
- onClick: C
3108
- }, {
3109
- default: t(() => [
3110
- c(i(e(A)("menu.site-bar")), 1)
3111
- ]),
3112
- _: 1
3113
- }, 8, ["icon"])
3114
- ], 64)) : E("", !0),
3115
- d.value.length > 0 ? (m(), H(ue, { key: 2 }, [
3116
- a(f, { spacing: "sm" }),
3117
- a(z, { disabled: "" }, {
3118
- default: t(() => [
3119
- a(O, {
3120
- size: "sm",
3121
- tone: "muted"
3122
- }, {
3123
- default: t(() => [
3124
- c(i(e(A)("menu.language")), 1)
3125
- ]),
3126
- _: 1
3127
- })
3128
- ]),
3129
- _: 1
3130
- }),
3131
- (m(!0), H(ue, null, Ce(d.value, ($) => (m(), _(z, {
3132
- key: $.code,
3133
- icon: $.code === e(v).state.locale ? "check" : void 0,
3134
- onClick: (Z) => D($.code)
3135
- }, {
3136
- default: t(() => [
3137
- c(i($.nativeName), 1)
3138
- ]),
3139
- _: 2
3140
- }, 1032, ["icon", "onClick"]))), 128)),
3141
- a(f, { spacing: "sm" })
3142
- ], 64)) : E("", !0),
3143
- a(z, {
3144
- icon: "logout",
3145
- onClick: x[2] || (x[2] = ($) => e(u).logout())
3146
- }, {
3147
- default: t(() => [
3148
- c(i(s.signOutLabel ?? e(A)("menu.sign-out")), 1)
3149
- ]),
3150
- _: 1
3151
- })
3152
- ]),
3153
- _: 1
3154
- })) : E("", !0);
3155
- };
3156
- }
3157
- }), za = /* @__PURE__ */ ve(_a, [["__scopeId", "data-v-31b12be6"]]);
3158
- function Wa(s = {}) {
3159
- const r = s.path ?? "/login";
3160
- return {
3161
- install(l) {
3162
- const u = yt(l.context);
3163
- l.i18n.defaults("webx-auth", Qe), ht(
3164
- l.app,
3165
- u,
3166
- s.resolveAvatar ?? Je(l.context),
3167
- s.avatarField ?? Ye(l.context)
3168
- ), l.context.useSessionLoader(() => u.me()), l.router.addRoute({
3169
- path: r,
3170
- name: "webx.login",
3171
- meta: { public: !0 },
3172
- component: { render: () => De(kt, { ...s.card }) }
3173
- }), l.router.beforeEach((v) => v.meta.public === !0 || l.context.state.status !== "unauthenticated" ? !0 : { path: r, query: v.fullPath === "/" ? {} : { next: v.fullPath } }), de(
3174
- () => l.context.state.status,
3175
- (v) => {
3176
- const y = l.router.currentRoute.value;
3177
- if (v === "unauthenticated" && y.path !== r) {
3178
- l.router.replace({ path: r, query: { next: y.fullPath } });
3179
- return;
3180
- }
3181
- if (v === "ready" && y.path === r) {
3182
- const A = y.query.next;
3183
- if (typeof A == "string" && ba(A)) {
3184
- location.assign(A);
3185
- return;
3186
- }
3187
- l.router.replace(typeof A == "string" ? A : "/");
3188
- }
3189
- }
3190
- );
3191
- }
3192
- };
3193
- }
3194
- function ba(s) {
3195
- if (!/^https?:\/\//i.test(s))
3196
- return !1;
3197
- try {
3198
- return new URL(s).origin === location.origin;
3199
- } catch {
3200
- return !1;
3201
- }
3202
- }
1
+ import "vue";
2
+ import { b as t, d as i, e as n, W as o, a as r, f as A, L as c, P as d, U as x, g as W, h as l, i as m, j as u, k as g, l as h, m as p, n as L, o as v, p as y, q as C, r as K, s as P, t as f, v as M } from "./index-BUVSIwLQ.js";
3203
3
  export {
3204
- Xe as WxAdminList,
3205
- Dt as WxAdminsPage,
3206
- Lt as WxAgentCallList,
3207
- oa as WxConnectPage,
3208
- Ze as WxConnectionList,
3209
- It as WxKeyList,
3210
- kt as WxLoginCard,
3211
- va as WxProfileDialog,
3212
- za as WxUserMenu,
3213
- Ca as admins,
3214
- Wa as auth,
3215
- He as authKey,
3216
- Qe as authMessages,
3217
- Ge as avatarFieldKey,
3218
- je as avatarResolverKey,
3219
- $a as connect,
3220
- pe as createAdminsApi,
3221
- yt as createAuthSession,
3222
- Tt as createConnectionsApi,
3223
- tt as createKeysApi,
3224
- ht as provideAuth,
3225
- Va as selectAdmin,
3226
- Aa as selectAdmins,
3227
- We as useAuth
4
+ t as WxAdminList,
5
+ i as WxAdminsPage,
6
+ n as WxAgentCallList,
7
+ o as WxConnectPage,
8
+ r as WxConnectionList,
9
+ A as WxKeyList,
10
+ c as WxLoginCard,
11
+ d as WxProfileDialog,
12
+ x as WxUserMenu,
13
+ W as admins,
14
+ l as auth,
15
+ m as authKey,
16
+ u as authMessages,
17
+ g as avatarFieldKey,
18
+ h as avatarResolverKey,
19
+ p as connect,
20
+ L as createAdminsApi,
21
+ v as createAuthSession,
22
+ y as createConnectionsApi,
23
+ C as createKeysApi,
24
+ K as provideAuth,
25
+ P as selectAdmin,
26
+ f as selectAdmins,
27
+ M as useAuth
3228
28
  };
3229
29
  //# sourceMappingURL=index.js.map