dsh-model-visibility 0.1.2 → 0.2.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/LICENSE +21 -21
- package/README.en.md +6 -6
- package/README.md +6 -6
- package/cordis.patch.yml +6 -6
- package/lib/client.js +521 -488
- package/lib/client.js.map +1 -1
- package/lib/index.js +13 -12
- package/lib/types/client/controller.d.ts +10 -38
- package/lib/types/client/index.d.ts +6 -1
- package/lib/types/client/locales.d.ts +1 -1
- package/lib/types/index.d.ts +34 -10
- package/lib/types/namespace.d.ts +10 -0
- package/package.json +36 -34
package/lib/client.js
CHANGED
|
@@ -1,225 +1,237 @@
|
|
|
1
|
-
window.__ModuleLoader__.load({
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
1
|
+
window.__ModuleLoader__.load({ id: "dsh-model-visibility", factory: (require) => {
|
|
2
|
+
var module = { exports: {} }; var exports = module.exports;
|
|
3
|
+
//#region rolldown:runtime
|
|
4
|
+
var __create = Object.create;
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
9
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
12
|
+
key = keys[i];
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
14
|
+
get: ((k) => from[k]).bind(null, key),
|
|
15
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
21
|
+
value: mod,
|
|
22
|
+
enumerable: true
|
|
23
|
+
}) : target, mod));
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
const __deepseek_ai_dsh_client_store = __toESM(require("@deepseek-ai/dsh-client-store"));
|
|
27
|
+
const react = __toESM(require("react"));
|
|
28
|
+
const react_jsx_runtime = __toESM(require("react/jsx-runtime"));
|
|
29
|
+
|
|
30
|
+
//#region src/namespace.ts
|
|
31
|
+
const MODEL_VISIBILITY_NS = "model-visibility";
|
|
32
|
+
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/client/controller.ts
|
|
35
|
+
const EMPTY = {
|
|
36
|
+
phase: "loading",
|
|
37
|
+
writable: false,
|
|
38
|
+
groups: [],
|
|
39
|
+
total: 0,
|
|
40
|
+
visible: 0
|
|
41
|
+
};
|
|
42
|
+
var ModelVisibilityCardController = class {
|
|
43
|
+
/** Exposed: the section contribution passes the store through its face as `hooks.snapshot`. */
|
|
44
|
+
store = (0, __deepseek_ai_dsh_client_store.createSnapshotStore)(EMPTY);
|
|
45
|
+
catalog;
|
|
46
|
+
loadError;
|
|
47
|
+
generation = 0;
|
|
48
|
+
unsubscribe;
|
|
49
|
+
constructor(form, catalogReader) {
|
|
50
|
+
this.form = form;
|
|
51
|
+
this.catalogReader = catalogReader;
|
|
52
|
+
this.unsubscribe = form.subscribe(() => {
|
|
53
|
+
this.recompute();
|
|
54
|
+
});
|
|
55
|
+
this.load();
|
|
56
|
+
}
|
|
57
|
+
/** The registration-side inject face. */
|
|
58
|
+
face() {
|
|
59
|
+
return {
|
|
60
|
+
hooks: { modelVisibility: this.store },
|
|
61
|
+
toggle: (provider, model, name$1, hidden) => {
|
|
62
|
+
this.toggle(provider, model, name$1, hidden);
|
|
63
|
+
},
|
|
64
|
+
toggleProvider: (provider, hidden) => {
|
|
65
|
+
this.toggleProvider(provider, hidden);
|
|
66
|
+
},
|
|
67
|
+
resetAll: () => {
|
|
68
|
+
this.resetAll();
|
|
69
|
+
},
|
|
70
|
+
reload: () => {
|
|
50
71
|
this.load();
|
|
51
72
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/** Re-read the catalog; an older response never overwrites a newer one. */
|
|
76
|
+
async load() {
|
|
77
|
+
const generation = ++this.generation;
|
|
78
|
+
if (this.catalog === void 0) this.store.update((draft) => {
|
|
79
|
+
draft.phase = "loading";
|
|
80
|
+
});
|
|
81
|
+
try {
|
|
82
|
+
const groups = await this.catalogReader.read();
|
|
83
|
+
if (generation !== this.generation) return;
|
|
84
|
+
this.catalog = groups.map((group) => ({
|
|
85
|
+
id: group.id,
|
|
86
|
+
name: group.name,
|
|
87
|
+
models: group.models.map((model) => ({
|
|
88
|
+
id: model.id,
|
|
89
|
+
name: model.name
|
|
90
|
+
}))
|
|
91
|
+
}));
|
|
92
|
+
this.loadError = void 0;
|
|
93
|
+
} catch (error) {
|
|
94
|
+
if (generation !== this.generation) return;
|
|
95
|
+
this.loadError = error instanceof Error ? error.message : String(error);
|
|
96
|
+
}
|
|
97
|
+
this.recompute();
|
|
98
|
+
}
|
|
99
|
+
/** Stop following the settings form (plugin unload). */
|
|
100
|
+
dispose() {
|
|
101
|
+
this.unsubscribe();
|
|
102
|
+
}
|
|
103
|
+
/** Compute the next hidden list from the current one plus one model's flip. */
|
|
104
|
+
nextHidden(current, provider, model, name$1, hidden) {
|
|
105
|
+
const rest = current.filter((entry) => !(entry.provider === provider && entry.model === model));
|
|
106
|
+
return hidden ? [...rest, {
|
|
107
|
+
provider,
|
|
108
|
+
model,
|
|
109
|
+
name: name$1
|
|
110
|
+
}] : rest;
|
|
111
|
+
}
|
|
112
|
+
/** Write the next hidden list, then re-pull the catalog the filter changed. */
|
|
113
|
+
async write(next) {
|
|
114
|
+
try {
|
|
115
|
+
await this.form.set("hidden", next);
|
|
116
|
+
} catch {}
|
|
117
|
+
await this.load();
|
|
118
|
+
}
|
|
119
|
+
/** Flip one model's visibility (public API — the section card calls it directly). */
|
|
120
|
+
async toggle(provider, model, name$1, hidden) {
|
|
121
|
+
const current = this.form.getSnapshot().value?.hidden ?? [];
|
|
122
|
+
await this.write(this.nextHidden(current, provider, model, name$1, hidden));
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
|
|
126
|
+
* Batch flip for one provider. Models are taken from the union of the
|
|
127
|
+
|
|
128
|
+
* (filtered) catalog rows and existing hidden entries so a provider with
|
|
129
|
+
|
|
130
|
+
* every model already hidden still flips back fully.
|
|
131
|
+
|
|
132
|
+
*/
|
|
133
|
+
/** Batch flip for one provider (public API). */
|
|
134
|
+
async toggleProvider(provider, hidden) {
|
|
135
|
+
const current = this.form.getSnapshot().value?.hidden ?? [];
|
|
136
|
+
const providerRows = this.stateRows().find((group) => group.id === provider);
|
|
137
|
+
const ids = new Set([...providerRows ? providerRows.models.map((model) => model.id) : [], ...current.filter((entry) => entry.provider === provider).map((entry) => entry.model)]);
|
|
138
|
+
if (ids.size === 0) return;
|
|
139
|
+
let next = current.filter((entry) => entry.provider !== provider);
|
|
140
|
+
if (hidden) {
|
|
141
|
+
const nameOf = (id) => providerRows?.models.find((model) => model.id === id)?.name ?? id;
|
|
142
|
+
next = [...next, ...[...ids].map((id) => ({
|
|
143
|
+
provider,
|
|
144
|
+
model: id,
|
|
145
|
+
name: nameOf(id)
|
|
146
|
+
}))];
|
|
147
|
+
}
|
|
148
|
+
await this.write(next);
|
|
149
|
+
}
|
|
150
|
+
/** Clear the hidden list entirely (public API). */
|
|
151
|
+
async resetAll() {
|
|
152
|
+
await this.write([]);
|
|
153
|
+
}
|
|
154
|
+
/** Current union rows (catalog ∪ hidden) without touching the store. */
|
|
155
|
+
stateRows() {
|
|
156
|
+
const snapshot = this.form.getSnapshot();
|
|
157
|
+
const hidden = snapshot.value?.hidden ?? [];
|
|
158
|
+
if (this.catalog === void 0) return [];
|
|
159
|
+
const hiddenKeys = new Set(hidden.map((entry) => `${entry.provider}\u0000${entry.model}`));
|
|
160
|
+
const groups = this.catalog.map((group) => ({
|
|
161
|
+
id: group.id,
|
|
162
|
+
name: group.name,
|
|
163
|
+
models: group.models.map((model) => ({
|
|
164
|
+
id: model.id,
|
|
165
|
+
name: model.name,
|
|
166
|
+
hidden: hiddenKeys.has(`${group.id}\u0000${model.id}`)
|
|
167
|
+
}))
|
|
168
|
+
}));
|
|
169
|
+
const groupsById = new Map(groups.map((group) => [group.id, group]));
|
|
170
|
+
for (const entry of hidden) {
|
|
171
|
+
const group = groupsById.get(entry.provider);
|
|
172
|
+
if (group?.models.some((model) => model.id === entry.model)) continue;
|
|
173
|
+
const row = {
|
|
174
|
+
id: entry.model,
|
|
175
|
+
name: entry.name ?? entry.model,
|
|
176
|
+
hidden: true
|
|
177
|
+
};
|
|
178
|
+
if (group !== void 0) group.models.push(row);
|
|
179
|
+
else {
|
|
180
|
+
const created = {
|
|
181
|
+
id: entry.provider,
|
|
182
|
+
name: entry.provider,
|
|
183
|
+
models: [row]
|
|
68
184
|
};
|
|
185
|
+
groupsById.set(entry.provider, created);
|
|
186
|
+
groups.push(created);
|
|
69
187
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
* (filtered) catalog rows and existing hidden entries so a provider with
|
|
118
|
-
* every model already hidden still flips back fully.
|
|
119
|
-
*/
|
|
120
|
-
/** Batch flip for one provider (public API). */
|
|
121
|
-
async toggleProvider(provider, hidden) {
|
|
122
|
-
const current = this.scope.getSnapshot().value?.hidden ?? [];
|
|
123
|
-
const providerRows = this.stateRows().find((group) => group.id === provider);
|
|
124
|
-
const ids = /* @__PURE__ */ new Set([...providerRows ? providerRows.models.map((model) => model.id) : [], ...current.filter((entry) => entry.provider === provider).map((entry) => entry.model)]);
|
|
125
|
-
if (ids.size === 0) return;
|
|
126
|
-
let next = current.filter((entry) => entry.provider !== provider);
|
|
127
|
-
if (hidden) {
|
|
128
|
-
const nameOf = (id) => providerRows?.models.find((model) => model.id === id)?.name ?? id;
|
|
129
|
-
next = [...next, ...[...ids].map((id) => ({
|
|
130
|
-
provider,
|
|
131
|
-
model: id,
|
|
132
|
-
name: nameOf(id)
|
|
133
|
-
}))];
|
|
134
|
-
}
|
|
135
|
-
await this.write(next);
|
|
136
|
-
}
|
|
137
|
-
/** Clear the hidden list entirely (public API). */
|
|
138
|
-
async resetAll() {
|
|
139
|
-
await this.write([]);
|
|
140
|
-
}
|
|
141
|
-
/** Current union rows (catalog ∪ hidden) without touching the store. */
|
|
142
|
-
stateRows() {
|
|
143
|
-
const hidden = this.scope.getSnapshot().value?.hidden ?? [];
|
|
144
|
-
if (this.catalog === void 0) return [];
|
|
145
|
-
const hiddenKeys = new Set(hidden.map((entry) => `${entry.provider}\u0000${entry.model}`));
|
|
146
|
-
const groups = this.catalog.map((group) => ({
|
|
147
|
-
id: group.id,
|
|
148
|
-
name: group.name,
|
|
149
|
-
models: group.models.map((model) => ({
|
|
150
|
-
id: model.id,
|
|
151
|
-
name: model.name,
|
|
152
|
-
hidden: hiddenKeys.has(`${group.id}\u0000${model.id}`)
|
|
153
|
-
}))
|
|
154
|
-
}));
|
|
155
|
-
const groupsById = new Map(groups.map((group) => [group.id, group]));
|
|
156
|
-
for (const entry of hidden) {
|
|
157
|
-
const group = groupsById.get(entry.provider);
|
|
158
|
-
if (group?.models.some((model) => model.id === entry.model)) continue;
|
|
159
|
-
const row = {
|
|
160
|
-
id: entry.model,
|
|
161
|
-
name: entry.name ?? entry.model,
|
|
162
|
-
hidden: true
|
|
163
|
-
};
|
|
164
|
-
if (group !== void 0) group.models.push(row);
|
|
165
|
-
else {
|
|
166
|
-
const created = {
|
|
167
|
-
id: entry.provider,
|
|
168
|
-
name: entry.provider,
|
|
169
|
-
models: [row]
|
|
170
|
-
};
|
|
171
|
-
groupsById.set(entry.provider, created);
|
|
172
|
-
groups.push(created);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
return groups;
|
|
176
|
-
}
|
|
177
|
-
/** Union the filtered catalog with the hidden entries into render rows. */
|
|
178
|
-
recompute() {
|
|
179
|
-
const snapshot = this.scope.getSnapshot();
|
|
180
|
-
if (this.catalog === void 0 && this.loadError !== void 0) {
|
|
181
|
-
this.store.set({
|
|
182
|
-
...EMPTY,
|
|
183
|
-
phase: "error",
|
|
184
|
-
error: this.loadError,
|
|
185
|
-
writable: snapshot.writable
|
|
186
|
-
});
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
if (this.catalog === void 0 || snapshot.status === "loading") {
|
|
190
|
-
this.store.set({
|
|
191
|
-
...EMPTY,
|
|
192
|
-
writable: snapshot.writable
|
|
193
|
-
});
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
const groups = this.stateRows();
|
|
197
|
-
const total = groups.reduce((count, group) => count + group.models.length, 0);
|
|
198
|
-
const visible = groups.reduce((count, group) => count + group.models.filter((model) => !model.hidden).length, 0);
|
|
199
|
-
this.store.set({
|
|
200
|
-
phase: "ready",
|
|
201
|
-
writable: snapshot.writable,
|
|
202
|
-
groups,
|
|
203
|
-
total,
|
|
204
|
-
visible
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
};
|
|
208
|
-
//#endregion
|
|
209
|
-
//#region src/client/ModelVisibilityCard.tsx
|
|
210
|
-
/**
|
|
211
|
-
* The model-visibility settings section, styled to mirror the official
|
|
212
|
-
* settings pages: big page title + muted intro, a controls row, then one
|
|
213
|
-
* bordered rounded card per provider (like the provider cards on the
|
|
214
|
-
* 模型 page) with pill action buttons and token-style switches.
|
|
215
|
-
*
|
|
216
|
-
* Consumes the `settings.section` contribution contract exactly like the
|
|
217
|
-
* official ModelsSection: props = spread inject face, where `hooks.snapshot`
|
|
218
|
-
* arrives as the `useSnapshot` selector hook; all three seats are undefined
|
|
219
|
-
* while the shell has not injected yet (render null then).
|
|
220
|
-
*/
|
|
221
|
-
const STYLE_ID = "dsh-model-visibility-styles";
|
|
222
|
-
const STYLES = `
|
|
188
|
+
}
|
|
189
|
+
return groups;
|
|
190
|
+
}
|
|
191
|
+
/** Union the filtered catalog with the hidden entries into render rows. */
|
|
192
|
+
recompute() {
|
|
193
|
+
const snapshot = this.form.getSnapshot();
|
|
194
|
+
if (snapshot.status === "unavailable") {
|
|
195
|
+
this.store.set({
|
|
196
|
+
...EMPTY,
|
|
197
|
+
phase: "unavailable",
|
|
198
|
+
writable: snapshot.writable
|
|
199
|
+
});
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (this.catalog === void 0 && this.loadError !== void 0) {
|
|
203
|
+
this.store.set({
|
|
204
|
+
...EMPTY,
|
|
205
|
+
phase: "error",
|
|
206
|
+
error: this.loadError,
|
|
207
|
+
writable: snapshot.writable
|
|
208
|
+
});
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
if (this.catalog === void 0 || snapshot.status === "loading") {
|
|
212
|
+
this.store.set({
|
|
213
|
+
...EMPTY,
|
|
214
|
+
writable: snapshot.writable
|
|
215
|
+
});
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
const groups = this.stateRows();
|
|
219
|
+
const total = groups.reduce((count, group) => count + group.models.length, 0);
|
|
220
|
+
const visible = groups.reduce((count, group) => count + group.models.filter((model) => !model.hidden).length, 0);
|
|
221
|
+
this.store.set({
|
|
222
|
+
phase: "ready",
|
|
223
|
+
writable: snapshot.writable,
|
|
224
|
+
groups,
|
|
225
|
+
total,
|
|
226
|
+
visible
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
//#endregion
|
|
232
|
+
//#region src/client/ModelVisibilityCard.tsx
|
|
233
|
+
const STYLE_ID = "dsh-model-visibility-styles";
|
|
234
|
+
const STYLES = `
|
|
223
235
|
.dsh-mvw { display:flex; flex-direction:column; gap:16px; }
|
|
224
236
|
.dsh-mvw .mvw-title { font-size:20px; font-weight:700; letter-spacing:.01em; }
|
|
225
237
|
.dsh-mvw .mvw-sub { font-size:13px; color:inherit; opacity:.62; margin-top:6px; max-width:64ch; line-height:1.55; }
|
|
@@ -273,286 +285,307 @@ window.__ModuleLoader__.load({
|
|
|
273
285
|
.dsh-mvw .mvw-warn { font-size:12.5px; color:#c77700; }
|
|
274
286
|
.dsh-mvw .mvw-seats-off { font-size:12.5px; opacity:.66; }
|
|
275
287
|
`;
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
288
|
+
function ensureStyles() {
|
|
289
|
+
if (typeof document === "undefined") return;
|
|
290
|
+
if (document.getElementById(STYLE_ID)) return;
|
|
291
|
+
const el = document.createElement("style");
|
|
292
|
+
el.id = STYLE_ID;
|
|
293
|
+
el.textContent = STYLES;
|
|
294
|
+
document.head.appendChild(el);
|
|
295
|
+
}
|
|
296
|
+
function ModelVisibilityCard(props) {
|
|
297
|
+
const { controller, useSnapshot, t } = props;
|
|
298
|
+
const state = (useSnapshot ?? ((_selector) => void 0))((snapshot) => snapshot);
|
|
299
|
+
const [query, setQuery] = (0, react.useState)("");
|
|
300
|
+
(0, react.useMemo)(() => {
|
|
301
|
+
ensureStyles();
|
|
302
|
+
}, []);
|
|
303
|
+
const filteredGroups = (0, react.useMemo)(() => {
|
|
304
|
+
const q = query.trim().toLowerCase();
|
|
305
|
+
if (q === "") return state?.groups ?? [];
|
|
306
|
+
return (state?.groups ?? []).map((group) => ({
|
|
307
|
+
...group,
|
|
308
|
+
models: group.models.filter((model) => model.id.toLowerCase().includes(q) || model.name.toLowerCase().includes(q) || group.id.toLowerCase().includes(q))
|
|
309
|
+
})).filter((group) => group.models.length > 0);
|
|
310
|
+
}, [state, query]);
|
|
311
|
+
if (controller === void 0 || useSnapshot === void 0 || t === void 0) return null;
|
|
312
|
+
if (state === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
|
|
313
|
+
className: "dsh-mvw",
|
|
314
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
315
|
+
className: "mvw-note",
|
|
316
|
+
children: t("loading")
|
|
317
|
+
})
|
|
318
|
+
});
|
|
319
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
320
|
+
className: "dsh-mvw",
|
|
321
|
+
children: [
|
|
322
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
323
|
+
className: "mvw-title",
|
|
324
|
+
children: t("title")
|
|
325
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
326
|
+
className: "mvw-sub",
|
|
327
|
+
children: t("intro")
|
|
328
|
+
})] }),
|
|
329
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
330
|
+
className: "mvw-controls",
|
|
309
331
|
children: [
|
|
310
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
332
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
333
|
+
type: "search",
|
|
334
|
+
className: "mvw-search",
|
|
335
|
+
value: query,
|
|
336
|
+
placeholder: t("searchPlaceholder"),
|
|
337
|
+
onChange: (event) => {
|
|
338
|
+
setQuery(event.target.value);
|
|
339
|
+
}
|
|
340
|
+
}),
|
|
341
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
342
|
+
type: "button",
|
|
343
|
+
className: "mvw-pill",
|
|
344
|
+
disabled: !state.writable || state.total === state.visible,
|
|
345
|
+
onClick: () => {
|
|
346
|
+
controller.resetAll();
|
|
347
|
+
},
|
|
348
|
+
children: t("showAllProviders")
|
|
349
|
+
}),
|
|
350
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
351
|
+
className: "mvw-count",
|
|
352
|
+
children: t("visibleCount", {
|
|
353
|
+
visible: state.visible,
|
|
354
|
+
total: state.total
|
|
355
|
+
})
|
|
356
|
+
})
|
|
357
|
+
]
|
|
358
|
+
}),
|
|
359
|
+
state.phase === "error" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
360
|
+
className: "mvw-warn",
|
|
361
|
+
children: [
|
|
362
|
+
t("loadFailed", { message: state.error ?? "" }),
|
|
363
|
+
" ",
|
|
364
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
365
|
+
type: "button",
|
|
366
|
+
className: "mvw-mini",
|
|
367
|
+
onClick: () => {
|
|
368
|
+
controller.load();
|
|
369
|
+
},
|
|
370
|
+
children: t("retry")
|
|
371
|
+
})
|
|
372
|
+
]
|
|
373
|
+
}),
|
|
374
|
+
state.phase === "unavailable" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
375
|
+
className: "mvw-note",
|
|
376
|
+
children: t("unavailable")
|
|
377
|
+
}),
|
|
378
|
+
state.phase === "ready" && !state.writable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
379
|
+
className: "mvw-note",
|
|
380
|
+
children: t("readOnly")
|
|
381
|
+
}),
|
|
382
|
+
state.phase === "ready" && state.groups.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
383
|
+
className: "mvw-note",
|
|
384
|
+
children: t("empty")
|
|
385
|
+
}),
|
|
386
|
+
state.phase === "ready" && state.total > 0 && state.visible === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
387
|
+
className: "mvw-warn",
|
|
388
|
+
children: t("allHiddenWarning")
|
|
389
|
+
}),
|
|
390
|
+
state.phase === "ready" && filteredGroups.length === 0 && state.groups.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
391
|
+
className: "mvw-note",
|
|
392
|
+
children: t("noMatch")
|
|
393
|
+
}),
|
|
394
|
+
state.phase === "ready" && filteredGroups.map((group) => {
|
|
395
|
+
const groupVisible = group.models.filter((model) => !model.hidden).length;
|
|
396
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
397
|
+
className: "mvw-card",
|
|
398
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
399
|
+
className: "mvw-prov-head",
|
|
400
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
401
|
+
className: "mvw-prov-name",
|
|
402
|
+
children: group.name
|
|
403
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
404
|
+
className: "mvw-prov-count",
|
|
405
|
+
children: t("providerRow", {
|
|
406
|
+
visible: groupVisible,
|
|
407
|
+
total: group.models.length
|
|
408
|
+
})
|
|
409
|
+
})] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
410
|
+
className: "mvw-prov-btns",
|
|
411
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
330
412
|
type: "button",
|
|
331
|
-
className: "mvw-
|
|
332
|
-
disabled: !state.writable ||
|
|
413
|
+
className: "mvw-mini",
|
|
414
|
+
disabled: !state.writable || groupVisible === 0,
|
|
333
415
|
onClick: () => {
|
|
334
|
-
controller.
|
|
416
|
+
controller.toggleProvider(group.id, true);
|
|
335
417
|
},
|
|
336
|
-
children: t("
|
|
337
|
-
}),
|
|
338
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
339
|
-
className: "mvw-count",
|
|
340
|
-
children: t("visibleCount", {
|
|
341
|
-
visible: state.visible,
|
|
342
|
-
total: state.total
|
|
343
|
-
})
|
|
344
|
-
})
|
|
345
|
-
]
|
|
346
|
-
}),
|
|
347
|
-
state.phase === "error" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
348
|
-
className: "mvw-warn",
|
|
349
|
-
children: [
|
|
350
|
-
t("loadFailed", { message: state.error ?? "" }),
|
|
351
|
-
" ",
|
|
352
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
418
|
+
children: t("hideAll")
|
|
419
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
353
420
|
type: "button",
|
|
354
421
|
className: "mvw-mini",
|
|
422
|
+
disabled: !state.writable || groupVisible === group.models.length,
|
|
355
423
|
onClick: () => {
|
|
356
|
-
controller.
|
|
424
|
+
controller.toggleProvider(group.id, false);
|
|
357
425
|
},
|
|
358
|
-
children: t("
|
|
359
|
-
})
|
|
360
|
-
]
|
|
361
|
-
}),
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
state.phase === "ready" && filteredGroups.length === 0 && state.groups.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
375
|
-
className: "mvw-note",
|
|
376
|
-
children: t("noMatch")
|
|
377
|
-
}),
|
|
378
|
-
state.phase === "ready" && filteredGroups.map((group) => {
|
|
379
|
-
const groupVisible = group.models.filter((model) => !model.hidden).length;
|
|
380
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
381
|
-
className: "mvw-card",
|
|
382
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
383
|
-
className: "mvw-prov-head",
|
|
384
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
385
|
-
className: "mvw-prov-name",
|
|
386
|
-
children: group.name
|
|
387
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
388
|
-
className: "mvw-prov-count",
|
|
389
|
-
children: t("providerRow", {
|
|
390
|
-
visible: groupVisible,
|
|
391
|
-
total: group.models.length
|
|
392
|
-
})
|
|
393
|
-
})] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
394
|
-
className: "mvw-prov-btns",
|
|
395
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
396
|
-
type: "button",
|
|
397
|
-
className: "mvw-mini",
|
|
398
|
-
disabled: !state.writable || groupVisible === 0,
|
|
399
|
-
onClick: () => {
|
|
400
|
-
controller.toggleProvider(group.id, true);
|
|
401
|
-
},
|
|
402
|
-
children: t("hideAll")
|
|
403
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
404
|
-
type: "button",
|
|
405
|
-
className: "mvw-mini",
|
|
406
|
-
disabled: !state.writable || groupVisible === group.models.length,
|
|
407
|
-
onClick: () => {
|
|
408
|
-
controller.toggleProvider(group.id, false);
|
|
409
|
-
},
|
|
410
|
-
children: t("showAll")
|
|
411
|
-
})]
|
|
426
|
+
children: t("showAll")
|
|
427
|
+
})]
|
|
428
|
+
})]
|
|
429
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
430
|
+
style: {
|
|
431
|
+
listStyle: "none",
|
|
432
|
+
margin: 0,
|
|
433
|
+
padding: 0
|
|
434
|
+
},
|
|
435
|
+
children: group.models.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
436
|
+
className: "mvw-row",
|
|
437
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
438
|
+
className: "mvw-name",
|
|
439
|
+
children: [model.name, model.name !== model.id && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
440
|
+
className: "mvw-id",
|
|
441
|
+
children: model.id
|
|
412
442
|
})]
|
|
413
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
className: "mvw-row",
|
|
421
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
422
|
-
className: "mvw-name",
|
|
423
|
-
children: [model.name, model.name !== model.id && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
424
|
-
className: "mvw-id",
|
|
425
|
-
children: model.id
|
|
426
|
-
})]
|
|
427
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Switch, {
|
|
428
|
-
on: !model.hidden,
|
|
429
|
-
disabled: !state.writable,
|
|
430
|
-
label: model.name,
|
|
431
|
-
onChange: (visible) => {
|
|
432
|
-
controller.toggle(group.id, model.id, model.name, !visible);
|
|
433
|
-
}
|
|
434
|
-
})]
|
|
435
|
-
}, model.id))
|
|
443
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Switch, {
|
|
444
|
+
on: !model.hidden,
|
|
445
|
+
disabled: !state.writable,
|
|
446
|
+
label: model.name,
|
|
447
|
+
onChange: (visible) => {
|
|
448
|
+
controller.toggle(group.id, model.id, model.name, !visible);
|
|
449
|
+
}
|
|
436
450
|
})]
|
|
437
|
-
},
|
|
438
|
-
})
|
|
439
|
-
|
|
440
|
-
})
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
451
|
+
}, model.id))
|
|
452
|
+
})]
|
|
453
|
+
}, group.id);
|
|
454
|
+
})
|
|
455
|
+
]
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
function Switch(props) {
|
|
459
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
460
|
+
type: "button",
|
|
461
|
+
role: "switch",
|
|
462
|
+
"aria-checked": props.on,
|
|
463
|
+
"aria-label": props.label,
|
|
464
|
+
disabled: props.disabled,
|
|
465
|
+
onClick: () => {
|
|
466
|
+
props.onChange(!props.on);
|
|
467
|
+
},
|
|
468
|
+
style: {
|
|
469
|
+
width: 40,
|
|
470
|
+
height: 22,
|
|
471
|
+
borderRadius: 11,
|
|
472
|
+
border: "none",
|
|
473
|
+
padding: 2,
|
|
474
|
+
cursor: props.disabled ? "not-allowed" : "pointer",
|
|
475
|
+
background: props.on ? "#4c8bf5" : "rgba(128,128,128,.45)",
|
|
476
|
+
opacity: props.disabled ? .5 : 1,
|
|
477
|
+
display: "inline-flex",
|
|
478
|
+
justifyContent: props.on ? "flex-end" : "flex-start",
|
|
479
|
+
transition: "background .15s",
|
|
480
|
+
flex: "none"
|
|
481
|
+
},
|
|
482
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: {
|
|
483
|
+
width: 18,
|
|
484
|
+
height: 18,
|
|
485
|
+
borderRadius: "50%",
|
|
486
|
+
background: "#fff",
|
|
487
|
+
display: "block"
|
|
488
|
+
} })
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
//#endregion
|
|
493
|
+
//#region src/client/locales.ts
|
|
494
|
+
const LOCALE_NS = "settings.modelVisibility";
|
|
495
|
+
const zh = {
|
|
496
|
+
nav: "模型可见性",
|
|
497
|
+
title: "模型可见性",
|
|
498
|
+
intro: "控制各模型是否出现在对话界面的模型选择菜单中。隐藏一个正在使用的模型不会中断该会话,也不会改动 Provider 配置。",
|
|
499
|
+
loading: "正在读取模型目录…",
|
|
500
|
+
loadFailed: "模型目录读取失败:{message}",
|
|
501
|
+
retry: "重试",
|
|
502
|
+
unavailable: "此连接不共享宿主设置,模型可见性不可用。",
|
|
503
|
+
empty: "没有任何 Provider 提供模型。",
|
|
504
|
+
allHiddenWarning: "所有模型都已隐藏,模型选择菜单将是空的。",
|
|
505
|
+
readOnly: "设置文档不可写,开关已禁用。",
|
|
506
|
+
visibleCount: "{visible} / {total} 可见",
|
|
507
|
+
searchPlaceholder: "搜索模型…",
|
|
508
|
+
noMatch: "没有匹配的模型。",
|
|
509
|
+
hideAll: "全部隐藏",
|
|
510
|
+
showAll: "全部显示",
|
|
511
|
+
showAllProviders: "恢复全部",
|
|
512
|
+
providerRow: "该渠道 {visible} / {total} 可见"
|
|
513
|
+
};
|
|
514
|
+
const en = {
|
|
515
|
+
nav: "Model visibility",
|
|
516
|
+
title: "Model visibility",
|
|
517
|
+
intro: "Control which models appear in the conversation model selector. Hiding a model a session already uses never interrupts that session or touches your provider config.",
|
|
518
|
+
loading: "Loading the model catalog…",
|
|
519
|
+
loadFailed: "Failed to load the model catalog: {message}",
|
|
520
|
+
retry: "Retry",
|
|
521
|
+
unavailable: "Model visibility is unavailable: this connection does not share the Host settings.",
|
|
522
|
+
empty: "No provider advertises any model.",
|
|
523
|
+
allHiddenWarning: "Every model is hidden; the model selector will be empty.",
|
|
524
|
+
readOnly: "The settings document is read-only; toggles are disabled.",
|
|
525
|
+
visibleCount: "{visible} / {total} visible",
|
|
526
|
+
searchPlaceholder: "Search models…",
|
|
527
|
+
noMatch: "No model matches.",
|
|
528
|
+
hideAll: "Hide all",
|
|
529
|
+
showAll: "Show all",
|
|
530
|
+
showAllProviders: "Reset all",
|
|
531
|
+
providerRow: "{visible} / {total} visible in this provider"
|
|
532
|
+
};
|
|
533
|
+
|
|
534
|
+
//#endregion
|
|
535
|
+
//#region src/client/index.ts
|
|
536
|
+
const name = "dsh-model-visibility";
|
|
537
|
+
const inject = [
|
|
538
|
+
"slots",
|
|
539
|
+
"locale",
|
|
540
|
+
"configForms",
|
|
541
|
+
"remote",
|
|
542
|
+
"remote.session"
|
|
543
|
+
];
|
|
544
|
+
function apply(ctx) {
|
|
545
|
+
ctx.effect(() => ctx.locale.register(LOCALE_NS, {
|
|
546
|
+
zh,
|
|
547
|
+
en
|
|
548
|
+
}), "model-visibility: copy dictionaries");
|
|
549
|
+
const form = ctx.configForms.get(MODEL_VISIBILITY_NS);
|
|
550
|
+
const catalog = { async read() {
|
|
551
|
+
const response = await ctx.remote.session.modelCatalog();
|
|
552
|
+
if (!response.ok) throw new Error(`${response.error.code}: ${response.error.message}`);
|
|
553
|
+
return response.value.groups;
|
|
554
|
+
} };
|
|
555
|
+
const controller = new ModelVisibilityCardController(form, catalog);
|
|
556
|
+
ctx.effect(() => () => {
|
|
557
|
+
controller.dispose();
|
|
558
|
+
}, "model-visibility: card controller");
|
|
559
|
+
ctx.effect(() => {
|
|
560
|
+
const offAdapters = ctx.remote.$on("llm/adapters-updated", () => {
|
|
561
|
+
controller.load();
|
|
562
|
+
});
|
|
563
|
+
const offSettings = ctx.remote.$on("settings/document-updated", (ns) => {
|
|
564
|
+
if (ns !== MODEL_VISIBILITY_NS) controller.load();
|
|
565
|
+
});
|
|
566
|
+
return () => {
|
|
567
|
+
offAdapters();
|
|
568
|
+
offSettings();
|
|
513
569
|
};
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
const scope = ctx.settingsScope.bind({ namespace: MODEL_VISIBILITY_NS });
|
|
530
|
-
const remote = ctx.remote;
|
|
531
|
-
const controller = new ModelVisibilityCardController(scope, { async read() {
|
|
532
|
-
const response = await remote.session.modelCatalog();
|
|
533
|
-
if (!response.ok) throw new Error(`${response.error.code}: ${response.error.message}`);
|
|
534
|
-
return response.value.groups;
|
|
535
|
-
} });
|
|
536
|
-
const t = ctx.locale.bind(LOCALE_NS);
|
|
537
|
-
const injected = () => ({
|
|
538
|
-
controller,
|
|
539
|
-
t,
|
|
540
|
-
hooks: { snapshot: controller.store }
|
|
541
|
-
});
|
|
542
|
-
ctx.slots.inject("settings.section", () => ctx.slots.register({
|
|
543
|
-
name: "settings.section",
|
|
544
|
-
id: "model-visibility",
|
|
545
|
-
order: 11,
|
|
546
|
-
label: () => t("nav"),
|
|
547
|
-
inject: injected
|
|
548
|
-
}, ModelVisibilityCard));
|
|
549
|
-
}
|
|
550
|
-
//#endregion
|
|
551
|
-
exports.apply = apply;
|
|
552
|
-
exports.inject = inject;
|
|
553
|
-
exports.name = name;
|
|
554
|
-
return module.exports;
|
|
555
|
-
}
|
|
556
|
-
});
|
|
570
|
+
}, "model-visibility: catalog invalidation");
|
|
571
|
+
const t = ctx.locale.bind(LOCALE_NS);
|
|
572
|
+
const injected = () => ({
|
|
573
|
+
controller,
|
|
574
|
+
t,
|
|
575
|
+
hooks: { snapshot: controller.store }
|
|
576
|
+
});
|
|
577
|
+
ctx.effect(() => ctx.configForms.whileServed([MODEL_VISIBILITY_NS], () => ctx.slots.inject("settings.section", () => ctx.slots.register({
|
|
578
|
+
name: "settings.section",
|
|
579
|
+
id: "model-visibility",
|
|
580
|
+
order: 11,
|
|
581
|
+
label: () => t("nav"),
|
|
582
|
+
inject: injected
|
|
583
|
+
}, ModelVisibilityCard))), "model-visibility: settings section");
|
|
584
|
+
}
|
|
557
585
|
|
|
586
|
+
//#endregion
|
|
587
|
+
exports.apply = apply;
|
|
588
|
+
exports.inject = inject;
|
|
589
|
+
exports.name = name;
|
|
590
|
+
return module.exports; } });
|
|
558
591
|
//# sourceMappingURL=client.js.map
|