@goodandready/dsh-subscriptions 0.2.6 → 0.2.8
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/lib/client.js +111 -22
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -6,27 +6,39 @@ window.__ModuleLoader__.load({
|
|
|
6
6
|
const React = require('react')
|
|
7
7
|
|
|
8
8
|
const CSS =
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
9
|
+
// card — same structure as core PluginCard (bash, agent-loop, web-search)
|
|
10
|
+
'.dsub-card{list-style:none;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;transition:border-color .16s,background .16s}' +
|
|
11
|
+
'.dsub-card:hover{border-color:var(--dsw-alias-label-dimmed)}' +
|
|
12
|
+
'.dsub-cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}' +
|
|
13
|
+
'.dsub-header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}' +
|
|
14
|
+
'.dsub-header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}' +
|
|
15
|
+
'.dsub-headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}' +
|
|
16
|
+
'.dsub-name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}' +
|
|
17
|
+
'.dsub-description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}' +
|
|
18
|
+
'.dsub-chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}' +
|
|
19
|
+
'.dsub-chevronOpen{transform:rotate(180deg)}' +
|
|
20
|
+
'.dsub-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding:16px 0 8px}' +
|
|
21
|
+
// existing dsub classes kept for SubsSection internals
|
|
22
|
+
'.dsub-wrap{display:flex;flex-direction:column;gap:22px;padding:4px 0;max-width:760px}' +
|
|
23
|
+
'.dsub-block{display:flex;flex-direction:column;gap:10px}' +
|
|
24
|
+
'.dsub-h{font-size:14px;font-weight:600;color:var(--dsw-alias-label-primary)}' +
|
|
25
|
+
'.dsub-sub{font-size:12px;color:var(--dsw-alias-label-secondary)}' +
|
|
26
|
+
'.dsub-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}' +
|
|
27
|
+
'.dsub-row input,.dsub-field input,.dsub-row select{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);border-radius:6px;padding:6px 8px;font-size:13px}' +
|
|
28
|
+
'.dsub-grow{flex:1;min-width:180px}' +
|
|
29
|
+
'.dsub-field{display:flex;flex-direction:column;gap:4px;font-size:12px;color:var(--dsw-alias-label-secondary)}' +
|
|
30
|
+
'.dsub-mini{border:1px solid var(--dsw-alias-border-l2);background:transparent;color:var(--dsw-alias-label-primary);border-radius:6px;height:28px;padding:0 8px;cursor:pointer}' +
|
|
31
|
+
'.dsub-save{background:var(--dsw-alias-brand-primary);color:#fff;border:none;border-radius:6px;padding:7px 14px;font-size:13px;cursor:pointer}' +
|
|
32
|
+
'.dsub-ok{font-size:12px;color:var(--dsw-alias-state-success-primary)}' +
|
|
33
|
+
'.dsub-bad{font-size:12px;color:var(--dsw-alias-state-error-primary)}' +
|
|
34
|
+
'.dsub-badge{font-size:11px;padding:2px 8px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);white-space:nowrap}' +
|
|
35
|
+
'.dsub-badge-on{color:var(--dsw-alias-state-success-primary);border-color:currentColor}' +
|
|
36
|
+
'.dsub-badge-warn{color:var(--dsw-alias-state-warning-primary);border-color:currentColor}' +
|
|
37
|
+
'.dsub-link{background:none;border:none;color:var(--dsw-alias-label-secondary);cursor:pointer;font-size:12px;padding:0}' +
|
|
38
|
+
'.dsub-verify{font-size:12px;color:var(--dsw-alias-state-warning-primary)}' +
|
|
39
|
+
'.dsub-verify a{color:var(--dsw-alias-brand-primary)}'
|
|
28
40
|
|
|
29
|
-
|
|
41
|
+
const cssId = 'dsh-subscriptions/settings.module.css'
|
|
30
42
|
if (typeof document !== 'undefined' && !document.querySelector('style[data-plugin-css="' + cssId + '"]')) {
|
|
31
43
|
const tag = document.createElement('style')
|
|
32
44
|
tag.textContent = CSS
|
|
@@ -46,6 +58,9 @@ window.__ModuleLoader__.load({
|
|
|
46
58
|
'usageFull': 'Usage 100%',
|
|
47
59
|
'connected': 'Connected',
|
|
48
60
|
'title': 'Subscriptions',
|
|
61
|
+
'cardIntro': 'Subscription accounts, rotation and limits.',
|
|
62
|
+
'show': 'Show',
|
|
63
|
+
'hide': 'Hide',
|
|
49
64
|
'intro': 'Log in with a consumer subscription. Tokens stay on the host credentials store. The browser never reads them back. After Connect, if the provider lands on localhost or a vendor page, paste the redirected URL or the code here.',
|
|
50
65
|
'useOrigin': 'Use this Web UI origin as OAuth redirect_uri',
|
|
51
66
|
'useOriginHint': 'Leave off unless you registered your own OAuth client for this origin. Vendor CLI clients usually require their published redirect URI plus the paste step.',
|
|
@@ -73,6 +88,9 @@ window.__ModuleLoader__.load({
|
|
|
73
88
|
'usageFull': 'Лимит исчерпан',
|
|
74
89
|
'connected': 'Подключено',
|
|
75
90
|
'title': 'Подписки',
|
|
91
|
+
'cardIntro': 'Аккаунты подписок, ротация и лимиты.',
|
|
92
|
+
'show': 'Показать',
|
|
93
|
+
'hide': 'Скрыть',
|
|
76
94
|
'intro': 'Вход по обычной пользовательской подписке. Токены остаются в хранилище учётных данных харнесса, браузер их обратно не читает. Если после «Подключить» провайдер увёл на localhost или на свою страницу, вставьте сюда адрес перехода или код.',
|
|
77
95
|
'useOrigin': 'Использовать адрес этого веб-интерфейса как redirect_uri',
|
|
78
96
|
'useOriginHint': 'Включайте, только если зарегистрировали собственного клиента OAuth на этот адрес. Штатным консольным клиентам провайдеров нужен их опубликованный адрес возврата и вставка кода вручную.',
|
|
@@ -102,6 +120,26 @@ window.__ModuleLoader__.load({
|
|
|
102
120
|
return t('connected')
|
|
103
121
|
}
|
|
104
122
|
|
|
123
|
+
// Карточка во вкладке «Плагины» рисует свой заголовок и сворачивание:
|
|
124
|
+
// ядро даёт только рамку списка.
|
|
125
|
+
function PluginCard(props) {
|
|
126
|
+
const t = (props && props.t) || ((key) => key)
|
|
127
|
+
const [open, setOpen] = React.useState(false)
|
|
128
|
+
return React.createElement('div', { className: 'dsub-block' },
|
|
129
|
+
React.createElement('div', { className: 'dsub-row' },
|
|
130
|
+
React.createElement('span', { className: 'dsub-h' }, t('title')),
|
|
131
|
+
React.createElement('span', { className: 'dsub-sub' }, t('cardIntro')),
|
|
132
|
+
React.createElement('span', { style: { flex: 1 } }),
|
|
133
|
+
React.createElement('button', {
|
|
134
|
+
type: 'button',
|
|
135
|
+
className: 'dsub-mini',
|
|
136
|
+
onClick: () => setOpen(!open),
|
|
137
|
+
}, open ? t('hide') : t('show')),
|
|
138
|
+
),
|
|
139
|
+
open ? React.createElement(SubsSection, props) : null,
|
|
140
|
+
)
|
|
141
|
+
}
|
|
142
|
+
|
|
105
143
|
function SubsSection(props) {
|
|
106
144
|
// Переводчик приходит от слота, потому что в его записи указан locale.
|
|
107
145
|
const t = (props && props.t) || ((key) => key)
|
|
@@ -345,11 +383,62 @@ window.__ModuleLoader__.load({
|
|
|
345
383
|
)
|
|
346
384
|
}
|
|
347
385
|
|
|
386
|
+
// Карточка во вкладке «Плагины» — как карточки bash/agent-loop/web-search:
|
|
387
|
+
// заголовок с именем, описанием и шевроном, сворачивание, каёмка.
|
|
388
|
+
function PluginCard(props) {
|
|
389
|
+
const t = (props && props.t) || ((key) => key)
|
|
390
|
+
const [open, setOpen] = React.useState(false)
|
|
391
|
+
return React.createElement('li', {
|
|
392
|
+
className: 'dsub-card' + (open ? ' dsub-cardOpen' : ''),
|
|
393
|
+
},
|
|
394
|
+
React.createElement('button', {
|
|
395
|
+
type: 'button',
|
|
396
|
+
className: 'dsub-header',
|
|
397
|
+
onClick: () => setOpen(!open),
|
|
398
|
+
'aria-expanded': open,
|
|
399
|
+
},
|
|
400
|
+
React.createElement('div', { className: 'dsub-headText' },
|
|
401
|
+
React.createElement('div', { className: 'dsub-name' }, t('title')),
|
|
402
|
+
React.createElement('div', { className: 'dsub-description' }, t('cardIntro')),
|
|
403
|
+
),
|
|
404
|
+
React.createElement('svg', {
|
|
405
|
+
className: 'dsub-chevron' + (open ? ' dsub-chevronOpen' : ''),
|
|
406
|
+
width: 16, height: 16, viewBox: '0 0 16 16', fill: 'none',
|
|
407
|
+
},
|
|
408
|
+
React.createElement('path', {
|
|
409
|
+
d: 'M4 6l4 4 4-4', stroke: 'currentColor', 'stroke-width': 1.5,
|
|
410
|
+
'stroke-linecap': 'round', 'stroke-linejoin': 'round',
|
|
411
|
+
}),
|
|
412
|
+
),
|
|
413
|
+
),
|
|
414
|
+
open ? React.createElement('div', { className: 'dsub-body' },
|
|
415
|
+
React.createElement(SubsSection, props),
|
|
416
|
+
) : null,
|
|
417
|
+
)
|
|
418
|
+
}
|
|
419
|
+
|
|
348
420
|
function registerSettings(ctx) {
|
|
349
421
|
ctx.effect(() => ctx.locale.register(NS, { en, ru }), 'dsh-subscriptions: словари')
|
|
350
|
-
//
|
|
351
|
-
// туда не доходит, поэтому берём переводчик, привязанный к namespace.
|
|
422
|
+
// Подписи вне компонента берут переводчик, привязанный к namespace.
|
|
352
423
|
const t = ctx.locale.bind(NS)
|
|
424
|
+
// Штатное место — вкладка «Плагины»: карточка со своим заголовком и
|
|
425
|
+
// сворачиванием вместо строки в боковом списке. Ключ регистрации обязан
|
|
426
|
+
// равняться пространству настроек, иначе вкладка молча не покажет слот.
|
|
427
|
+
let moved = false
|
|
428
|
+
try {
|
|
429
|
+
moved = !!ctx.slots.inject('settings.plugin.item', () => ctx.slots.register(
|
|
430
|
+
{
|
|
431
|
+
name: 'settings.plugin.item',
|
|
432
|
+
key: NS,
|
|
433
|
+
locale: NS,
|
|
434
|
+
inject: () => ({ ctx: ctx }),
|
|
435
|
+
},
|
|
436
|
+
PluginCard,
|
|
437
|
+
))
|
|
438
|
+
} catch { moved = false }
|
|
439
|
+
if (moved) return
|
|
440
|
+
// Запасной путь для сборок без settings.plugin.item: прежний раздел,
|
|
441
|
+
// чтобы настройки не пропали.
|
|
353
442
|
ctx.slots.inject('settings.section', () => ctx.slots.register(
|
|
354
443
|
{
|
|
355
444
|
name: 'settings.section',
|
package/package.json
CHANGED