@woosau/dsh-custom-env 0.1.8 → 0.1.10
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/README.md +28 -11
- package/README.zh-CN.md +28 -11
- package/lib/client.js +682 -408
- package/lib/index.js +337 -19
- package/lib/typert.host.js +407 -465
- package/lib/typert.remote-client.d.ts +2 -1
- package/lib/typert.remote-client.js +371 -373
- package/lib/types/client/EnvSettingsSection.d.ts +7 -3
- package/lib/types/client/locales.d.ts +22 -2
- package/lib/types/group-ids.d.ts +5 -0
- package/lib/types/groups-store.d.ts +73 -0
- package/lib/types/index.d.ts +40 -6
- package/lib/types/os-user-env/write-user-env-child.d.ts +11 -0
- package/lib/types/os-user-env/write-user-env.child.d.ts +4 -0
- package/lib/types/types.d.ts +22 -0
- package/lib/write-user-env.child.js +158 -0
- package/package.json +2 -1
package/lib/client.js
CHANGED
|
@@ -179,18 +179,27 @@ var ResultValue = class {
|
|
|
179
179
|
};
|
|
180
180
|
|
|
181
181
|
// lib/typert.remote-client.js
|
|
182
|
+
var envGroupSchema = () => import_zod.z.object({
|
|
183
|
+
id: import_zod.z.string().readonly(),
|
|
184
|
+
title: import_zod.z.string().readonly()
|
|
185
|
+
}).readonly();
|
|
186
|
+
var envEntrySchema = () => import_zod.z.object({
|
|
187
|
+
id: import_zod.z.string().readonly(),
|
|
188
|
+
name: import_zod.z.string().readonly(),
|
|
189
|
+
value: import_zod.z.string().readonly(),
|
|
190
|
+
groupId: import_zod.z.string().readonly(),
|
|
191
|
+
kind: import_zod.z.enum(["unchanged", "modified", "added"]).readonly(),
|
|
192
|
+
previous: import_zod.z.string().nullable().readonly()
|
|
193
|
+
}).readonly();
|
|
182
194
|
var list$result$schema$value;
|
|
183
195
|
var list$result$schema = () => list$result$schema$value ??= import_zod.z.object({
|
|
184
196
|
path: import_zod.z.string().readonly(),
|
|
185
197
|
exists: import_zod.z.boolean().readonly(),
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
name: import_zod.z.string().readonly(),
|
|
189
|
-
value: import_zod.z.string().readonly(),
|
|
190
|
-
kind: import_zod.z.enum(["unchanged", "modified", "added"]).readonly(),
|
|
191
|
-
previous: import_zod.z.string().nullable().readonly()
|
|
192
|
-
}).readonly()).readonly()
|
|
198
|
+
groups: import_zod.z.array(envGroupSchema()).readonly(),
|
|
199
|
+
entries: import_zod.z.array(envEntrySchema()).readonly()
|
|
193
200
|
});
|
|
201
|
+
var envGroup$result$schema$value;
|
|
202
|
+
var envGroup$result$schema = () => envGroup$result$schema$value ??= envGroupSchema();
|
|
194
203
|
var cliStatus$result$schema$value;
|
|
195
204
|
var cliStatus$result$schema = () => cliStatus$result$schema$value ??= import_zod.z.object({
|
|
196
205
|
platform: import_zod.z.string().readonly(),
|
|
@@ -201,38 +210,38 @@ var cliStatus$result$schema = () => cliStatus$result$schema$value ??= import_zod
|
|
|
201
210
|
canInstall: import_zod.z.boolean().readonly(),
|
|
202
211
|
reason: import_zod.z.string().nullable().readonly()
|
|
203
212
|
});
|
|
204
|
-
var
|
|
205
|
-
var upsert$parameter$0$schema = () => upsert$parameter$0$schema$value ??= import_zod.z.string();
|
|
206
|
-
var upsert$parameter$1$schema$value;
|
|
207
|
-
var upsert$parameter$1$schema = () => upsert$parameter$1$schema$value ??= import_zod.z.string();
|
|
208
|
-
var upsert$parameter$2$schema$value;
|
|
209
|
-
var upsert$parameter$2$schema = () => upsert$parameter$2$schema$value ??= import_zod.z.string();
|
|
210
|
-
var remove$parameter$0$schema$value;
|
|
211
|
-
var remove$parameter$0$schema = () => remove$parameter$0$schema$value ??= import_zod.z.string();
|
|
212
|
-
var setVar$parameter$0$schema$value;
|
|
213
|
-
var setVar$parameter$0$schema = () => setVar$parameter$0$schema$value ??= import_zod.z.string();
|
|
214
|
-
var setVar$parameter$1$schema$value;
|
|
215
|
-
var setVar$parameter$1$schema = () => setVar$parameter$1$schema$value ??= import_zod.z.string();
|
|
213
|
+
var str = () => import_zod.z.string();
|
|
216
214
|
var setVars$parameter$0$schema$value;
|
|
217
215
|
var setVars$parameter$0$schema = () => setVars$parameter$0$schema$value ??= import_zod.z.array(import_zod.z.object({
|
|
218
216
|
name: import_zod.z.string().readonly(),
|
|
219
|
-
value: import_zod.z.string().readonly()
|
|
217
|
+
value: import_zod.z.string().readonly(),
|
|
218
|
+
group: import_zod.z.string().optional()
|
|
220
219
|
}).readonly()).readonly();
|
|
221
|
-
var removeVar$parameter$0$schema$value;
|
|
222
|
-
var removeVar$parameter$0$schema = () => removeVar$parameter$0$schema$value ??= import_zod.z.string();
|
|
223
220
|
var removeVars$parameter$0$schema$value;
|
|
224
221
|
var removeVars$parameter$0$schema = () => removeVars$parameter$0$schema$value ??= import_zod.z.array(import_zod.z.string()).readonly();
|
|
222
|
+
var deleteGroup$parameter$1$schema$value;
|
|
223
|
+
var deleteGroup$parameter$1$schema = () => deleteGroup$parameter$1$schema$value ??= import_zod.z.object({
|
|
224
|
+
moveToDefault: import_zod.z.boolean().readonly()
|
|
225
|
+
}).readonly();
|
|
225
226
|
var envVarWriteJsonSchema = {
|
|
226
227
|
type: "object",
|
|
227
228
|
properties: {
|
|
228
229
|
name: { type: "string" },
|
|
229
|
-
value: { type: "string" }
|
|
230
|
+
value: { type: "string" },
|
|
231
|
+
group: { type: "string" }
|
|
230
232
|
},
|
|
231
233
|
required: ["name", "value"],
|
|
232
234
|
additionalProperties: false
|
|
233
235
|
};
|
|
234
|
-
var
|
|
235
|
-
|
|
236
|
+
var envGroupJsonSchema = {
|
|
237
|
+
type: "object",
|
|
238
|
+
properties: {
|
|
239
|
+
id: { type: "string" },
|
|
240
|
+
title: { type: "string" }
|
|
241
|
+
},
|
|
242
|
+
required: ["id", "title"],
|
|
243
|
+
additionalProperties: true
|
|
244
|
+
};
|
|
236
245
|
var cliStatusJsonSchema = {
|
|
237
246
|
type: "object",
|
|
238
247
|
properties: {
|
|
@@ -252,6 +261,10 @@ var envSnapshotJsonSchema = {
|
|
|
252
261
|
properties: {
|
|
253
262
|
path: { type: "string" },
|
|
254
263
|
exists: { type: "boolean" },
|
|
264
|
+
groups: {
|
|
265
|
+
type: "array",
|
|
266
|
+
items: envGroupJsonSchema
|
|
267
|
+
},
|
|
255
268
|
entries: {
|
|
256
269
|
type: "array",
|
|
257
270
|
items: {
|
|
@@ -260,90 +273,84 @@ var envSnapshotJsonSchema = {
|
|
|
260
273
|
id: { type: "string" },
|
|
261
274
|
name: { type: "string" },
|
|
262
275
|
value: { type: "string" },
|
|
276
|
+
groupId: { type: "string" },
|
|
263
277
|
kind: { type: "string", enum: ["unchanged", "modified", "added"] },
|
|
264
278
|
previous: { type: ["string", "null"] }
|
|
265
279
|
},
|
|
266
|
-
required: ["id", "name", "value", "kind", "previous"],
|
|
280
|
+
required: ["id", "name", "value", "groupId", "kind", "previous"],
|
|
267
281
|
additionalProperties: true
|
|
268
282
|
}
|
|
269
283
|
}
|
|
270
284
|
},
|
|
271
|
-
required: ["path", "exists", "entries"],
|
|
285
|
+
required: ["path", "exists", "groups", "entries"],
|
|
272
286
|
additionalProperties: true
|
|
273
287
|
};
|
|
288
|
+
var stringParam = (name, description, options = {}) => ({
|
|
289
|
+
name,
|
|
290
|
+
description,
|
|
291
|
+
source: "json",
|
|
292
|
+
...options.acceptsUndefined ? { acceptsUndefined: true } : {},
|
|
293
|
+
codec: {
|
|
294
|
+
mode: "strict",
|
|
295
|
+
typeSymbol: "string",
|
|
296
|
+
create: str,
|
|
297
|
+
jsonSchema: { type: "string" }
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
var snapshotResult = (description = "updated snapshot.") => ({
|
|
301
|
+
mode: "strict",
|
|
302
|
+
typeSymbol: "@woosau/dsh-custom-env/types#EnvSnapshot",
|
|
303
|
+
create: list$result$schema,
|
|
304
|
+
description,
|
|
305
|
+
jsonSchema: envSnapshotJsonSchema
|
|
306
|
+
});
|
|
307
|
+
var groupResult = (description = "group record.") => ({
|
|
308
|
+
mode: "strict",
|
|
309
|
+
typeSymbol: "@woosau/dsh-custom-env/types#EnvGroup",
|
|
310
|
+
create: envGroup$result$schema,
|
|
311
|
+
description,
|
|
312
|
+
jsonSchema: envGroupJsonSchema
|
|
313
|
+
});
|
|
314
|
+
var voidResult = {
|
|
315
|
+
mode: "strict",
|
|
316
|
+
typeSymbol: "void",
|
|
317
|
+
create: () => import_zod.z.undefined(),
|
|
318
|
+
description: "no return value.",
|
|
319
|
+
jsonSchema: { type: "null" }
|
|
320
|
+
};
|
|
321
|
+
var src = { file: "src/index.ts", line: 1, column: 1 };
|
|
274
322
|
var TYPERT_REMOTE = createTypertRemoteInfo({
|
|
275
323
|
package: "@woosau/dsh-custom-env",
|
|
276
324
|
methods: {
|
|
277
325
|
"customEnv/list": {
|
|
278
326
|
service: "customEnv",
|
|
279
|
-
description: "List current $DSH_HOME/.env entries with pending classification.",
|
|
327
|
+
description: "List current $DSH_HOME/.env entries with groups and pending classification.",
|
|
280
328
|
invocation: { kind: "direct" },
|
|
281
329
|
parameters: [],
|
|
282
|
-
result:
|
|
283
|
-
|
|
284
|
-
typeSymbol: "@woosau/dsh-custom-env/types#EnvSnapshot",
|
|
285
|
-
create: list$result$schema,
|
|
286
|
-
description: "path, existence, and sorted entries.",
|
|
287
|
-
jsonSchema: envSnapshotJsonSchema
|
|
288
|
-
},
|
|
289
|
-
sourceLocation: { file: "src/index.ts", line: 1, column: 1 }
|
|
330
|
+
result: snapshotResult("path, existence, groups, and sorted entries."),
|
|
331
|
+
sourceLocation: src
|
|
290
332
|
},
|
|
291
333
|
"customEnv/upsert": {
|
|
292
334
|
service: "customEnv",
|
|
293
|
-
description: "Create or update one row. Empty id creates a new row;
|
|
335
|
+
description: "Create or update one row. Empty id creates a new row; optional groupId assigns membership.",
|
|
294
336
|
invocation: { kind: "direct" },
|
|
295
337
|
parameters: [
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
codec: {
|
|
301
|
-
mode: "strict",
|
|
302
|
-
typeSymbol: "string",
|
|
303
|
-
create: upsert$parameter$0$schema,
|
|
304
|
-
jsonSchema: { type: "string" }
|
|
305
|
-
}
|
|
306
|
-
},
|
|
307
|
-
{
|
|
308
|
-
name: "name",
|
|
309
|
-
description: "writable variable name.",
|
|
310
|
-
source: "json",
|
|
311
|
-
codec: {
|
|
312
|
-
mode: "strict",
|
|
313
|
-
typeSymbol: "string",
|
|
314
|
-
create: upsert$parameter$1$schema,
|
|
315
|
-
jsonSchema: { type: "string" }
|
|
316
|
-
}
|
|
317
|
-
},
|
|
318
|
-
{
|
|
319
|
-
name: "value",
|
|
320
|
-
description: "value (empty string allowed).",
|
|
321
|
-
source: "json",
|
|
322
|
-
codec: {
|
|
323
|
-
mode: "strict",
|
|
324
|
-
typeSymbol: "string",
|
|
325
|
-
create: upsert$parameter$2$schema,
|
|
326
|
-
jsonSchema: { type: "string" }
|
|
327
|
-
}
|
|
328
|
-
}
|
|
338
|
+
stringParam("id", "stable row id from list(), or empty string for a new row."),
|
|
339
|
+
stringParam("name", "writable variable name."),
|
|
340
|
+
stringParam("value", "value (empty string allowed)."),
|
|
341
|
+
stringParam("groupId", "target group id for create/move (optional).", { acceptsUndefined: true })
|
|
329
342
|
],
|
|
330
|
-
result:
|
|
331
|
-
|
|
332
|
-
typeSymbol: "@woosau/dsh-custom-env/types#EnvSnapshot",
|
|
333
|
-
create: list$result$schema,
|
|
334
|
-
description: "updated snapshot.",
|
|
335
|
-
jsonSchema: envSnapshotJsonSchema
|
|
336
|
-
},
|
|
337
|
-
sourceLocation: { file: "src/index.ts", line: 1, column: 1 }
|
|
343
|
+
result: snapshotResult(),
|
|
344
|
+
sourceLocation: src
|
|
338
345
|
},
|
|
339
346
|
"customEnv/setVars": {
|
|
340
347
|
service: "customEnv",
|
|
341
|
-
description: "Create or replace many variables by name in one rewrite.
|
|
348
|
+
description: "Create or replace many variables by name in one rewrite. Optional group per entry.",
|
|
342
349
|
invocation: { kind: "direct" },
|
|
343
350
|
parameters: [
|
|
344
351
|
{
|
|
345
352
|
name: "entries",
|
|
346
|
-
description: "name/value pairs (last duplicate name wins).",
|
|
353
|
+
description: "name/value pairs with optional group (last duplicate name wins).",
|
|
347
354
|
source: "json",
|
|
348
355
|
codec: {
|
|
349
356
|
mode: "strict",
|
|
@@ -353,51 +360,20 @@ var TYPERT_REMOTE = createTypertRemoteInfo({
|
|
|
353
360
|
}
|
|
354
361
|
}
|
|
355
362
|
],
|
|
356
|
-
result:
|
|
357
|
-
|
|
358
|
-
typeSymbol: "void",
|
|
359
|
-
create: () => import_zod.z.undefined(),
|
|
360
|
-
description: "no return value.",
|
|
361
|
-
jsonSchema: { type: "null" }
|
|
362
|
-
},
|
|
363
|
-
sourceLocation: { file: "src/index.ts", line: 1, column: 1 }
|
|
363
|
+
result: voidResult,
|
|
364
|
+
sourceLocation: src
|
|
364
365
|
},
|
|
365
366
|
"customEnv/setVar": {
|
|
366
367
|
service: "customEnv",
|
|
367
|
-
description: "Create or replace one variable by name.
|
|
368
|
+
description: "Create or replace one variable by name. Optional group: new names default to default; existing keep group when omitted.",
|
|
368
369
|
invocation: { kind: "direct" },
|
|
369
370
|
parameters: [
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
source: "json",
|
|
374
|
-
codec: {
|
|
375
|
-
mode: "strict",
|
|
376
|
-
typeSymbol: "string",
|
|
377
|
-
create: setVar$parameter$0$schema,
|
|
378
|
-
jsonSchema: { type: "string" }
|
|
379
|
-
}
|
|
380
|
-
},
|
|
381
|
-
{
|
|
382
|
-
name: "value",
|
|
383
|
-
description: "value to store (empty string allowed).",
|
|
384
|
-
source: "json",
|
|
385
|
-
codec: {
|
|
386
|
-
mode: "strict",
|
|
387
|
-
typeSymbol: "string",
|
|
388
|
-
create: setVar$parameter$1$schema,
|
|
389
|
-
jsonSchema: { type: "string" }
|
|
390
|
-
}
|
|
391
|
-
}
|
|
371
|
+
stringParam("name", "writable variable name."),
|
|
372
|
+
stringParam("value", "value to store (empty string allowed)."),
|
|
373
|
+
stringParam("group", "optional group id; omit to keep existing membership.", { acceptsUndefined: true })
|
|
392
374
|
],
|
|
393
|
-
result:
|
|
394
|
-
|
|
395
|
-
typeSymbol: "void",
|
|
396
|
-
create: () => import_zod.z.undefined(),
|
|
397
|
-
description: "no return value.",
|
|
398
|
-
jsonSchema: { type: "null" }
|
|
399
|
-
},
|
|
400
|
-
sourceLocation: { file: "src/index.ts", line: 1, column: 1 }
|
|
375
|
+
result: voidResult,
|
|
376
|
+
sourceLocation: src
|
|
401
377
|
},
|
|
402
378
|
"customEnv/removeVars": {
|
|
403
379
|
service: "customEnv",
|
|
@@ -423,24 +399,14 @@ var TYPERT_REMOTE = createTypertRemoteInfo({
|
|
|
423
399
|
description: "number of .env lines removed.",
|
|
424
400
|
jsonSchema: { type: "number" }
|
|
425
401
|
},
|
|
426
|
-
sourceLocation:
|
|
402
|
+
sourceLocation: src
|
|
427
403
|
},
|
|
428
404
|
"customEnv/removeVar": {
|
|
429
405
|
service: "customEnv",
|
|
430
406
|
description: "Remove one variable by name from the file, Host, and OS user environment.",
|
|
431
407
|
invocation: { kind: "direct" },
|
|
432
408
|
parameters: [
|
|
433
|
-
|
|
434
|
-
name: "name",
|
|
435
|
-
description: "writable variable name.",
|
|
436
|
-
source: "json",
|
|
437
|
-
codec: {
|
|
438
|
-
mode: "strict",
|
|
439
|
-
typeSymbol: "string",
|
|
440
|
-
create: removeVar$parameter$0$schema,
|
|
441
|
-
jsonSchema: { type: "string" }
|
|
442
|
-
}
|
|
443
|
-
}
|
|
409
|
+
stringParam("name", "writable variable name.")
|
|
444
410
|
],
|
|
445
411
|
result: {
|
|
446
412
|
mode: "strict",
|
|
@@ -449,59 +415,85 @@ var TYPERT_REMOTE = createTypertRemoteInfo({
|
|
|
449
415
|
description: "true when a .env line was removed.",
|
|
450
416
|
jsonSchema: { type: "boolean" }
|
|
451
417
|
},
|
|
452
|
-
sourceLocation:
|
|
418
|
+
sourceLocation: src
|
|
453
419
|
},
|
|
454
420
|
"customEnv/deleteEntry": {
|
|
455
421
|
service: "customEnv",
|
|
456
422
|
description: "Delete one entry from the file, Host, and OS user environment.",
|
|
457
423
|
invocation: { kind: "direct" },
|
|
458
424
|
parameters: [
|
|
459
|
-
|
|
460
|
-
name: "id",
|
|
461
|
-
description: "stable row id from list().",
|
|
462
|
-
source: "json",
|
|
463
|
-
codec: {
|
|
464
|
-
mode: "strict",
|
|
465
|
-
typeSymbol: "string",
|
|
466
|
-
create: remove$parameter$0$schema,
|
|
467
|
-
jsonSchema: { type: "string" }
|
|
468
|
-
}
|
|
469
|
-
}
|
|
425
|
+
stringParam("id", "stable row id from list().")
|
|
470
426
|
],
|
|
471
|
-
result:
|
|
472
|
-
|
|
473
|
-
typeSymbol: "@woosau/dsh-custom-env/types#EnvSnapshot",
|
|
474
|
-
create: list$result$schema,
|
|
475
|
-
description: "updated snapshot.",
|
|
476
|
-
jsonSchema: envSnapshotJsonSchema
|
|
477
|
-
},
|
|
478
|
-
sourceLocation: { file: "src/index.ts", line: 1, column: 1 }
|
|
427
|
+
result: snapshotResult(),
|
|
428
|
+
sourceLocation: src
|
|
479
429
|
},
|
|
480
430
|
"customEnv/restore": {
|
|
481
431
|
service: "customEnv",
|
|
482
432
|
description: "Restore Host-start original name+value for this id, or delete if added after start.",
|
|
483
433
|
invocation: { kind: "direct" },
|
|
484
434
|
parameters: [
|
|
435
|
+
stringParam("id", "stable row id from list().")
|
|
436
|
+
],
|
|
437
|
+
result: snapshotResult(),
|
|
438
|
+
sourceLocation: src
|
|
439
|
+
},
|
|
440
|
+
"customEnv/createGroup": {
|
|
441
|
+
service: "customEnv",
|
|
442
|
+
description: "Create a custom environment variable group.",
|
|
443
|
+
invocation: { kind: "direct" },
|
|
444
|
+
parameters: [
|
|
445
|
+
stringParam("title", "non-empty display title.")
|
|
446
|
+
],
|
|
447
|
+
result: groupResult("created group."),
|
|
448
|
+
sourceLocation: src
|
|
449
|
+
},
|
|
450
|
+
"customEnv/renameGroup": {
|
|
451
|
+
service: "customEnv",
|
|
452
|
+
description: "Rename a custom group (not the default group).",
|
|
453
|
+
invocation: { kind: "direct" },
|
|
454
|
+
parameters: [
|
|
455
|
+
stringParam("id", "group id."),
|
|
456
|
+
stringParam("title", "new non-empty title.")
|
|
457
|
+
],
|
|
458
|
+
result: groupResult("renamed group."),
|
|
459
|
+
sourceLocation: src
|
|
460
|
+
},
|
|
461
|
+
"customEnv/deleteGroup": {
|
|
462
|
+
service: "customEnv",
|
|
463
|
+
description: "Delete a custom group; optionally move members to default or remove their variables.",
|
|
464
|
+
invocation: { kind: "direct" },
|
|
465
|
+
parameters: [
|
|
466
|
+
stringParam("id", "group id (not default)."),
|
|
485
467
|
{
|
|
486
|
-
name: "
|
|
487
|
-
description: "
|
|
468
|
+
name: "options",
|
|
469
|
+
description: "moveToDefault controls whether members are kept.",
|
|
488
470
|
source: "json",
|
|
489
471
|
codec: {
|
|
490
472
|
mode: "strict",
|
|
491
|
-
typeSymbol: "
|
|
492
|
-
create:
|
|
493
|
-
jsonSchema: {
|
|
473
|
+
typeSymbol: "DeleteGroupOptions",
|
|
474
|
+
create: deleteGroup$parameter$1$schema,
|
|
475
|
+
jsonSchema: {
|
|
476
|
+
type: "object",
|
|
477
|
+
properties: { moveToDefault: { type: "boolean" } },
|
|
478
|
+
required: ["moveToDefault"],
|
|
479
|
+
additionalProperties: false
|
|
480
|
+
}
|
|
494
481
|
}
|
|
495
482
|
}
|
|
496
483
|
],
|
|
497
|
-
result:
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
},
|
|
504
|
-
|
|
484
|
+
result: snapshotResult(),
|
|
485
|
+
sourceLocation: src
|
|
486
|
+
},
|
|
487
|
+
"customEnv/moveEntry": {
|
|
488
|
+
service: "customEnv",
|
|
489
|
+
description: "Move one row into another group.",
|
|
490
|
+
invocation: { kind: "direct" },
|
|
491
|
+
parameters: [
|
|
492
|
+
stringParam("id", "stable row id from list()."),
|
|
493
|
+
stringParam("groupId", "target group id.")
|
|
494
|
+
],
|
|
495
|
+
result: snapshotResult(),
|
|
496
|
+
sourceLocation: src
|
|
505
497
|
},
|
|
506
498
|
"customEnv/cliStatus": {
|
|
507
499
|
service: "customEnv",
|
|
@@ -515,7 +507,7 @@ var TYPERT_REMOTE = createTypertRemoteInfo({
|
|
|
515
507
|
description: "active path, expected path, and whether Install should be offered.",
|
|
516
508
|
jsonSchema: cliStatusJsonSchema
|
|
517
509
|
},
|
|
518
|
-
sourceLocation:
|
|
510
|
+
sourceLocation: src
|
|
519
511
|
},
|
|
520
512
|
"customEnv/cliInstall": {
|
|
521
513
|
service: "customEnv",
|
|
@@ -529,7 +521,7 @@ var TYPERT_REMOTE = createTypertRemoteInfo({
|
|
|
529
521
|
description: "refreshed status after install.",
|
|
530
522
|
jsonSchema: cliStatusJsonSchema
|
|
531
523
|
},
|
|
532
|
-
sourceLocation:
|
|
524
|
+
sourceLocation: src
|
|
533
525
|
}
|
|
534
526
|
}
|
|
535
527
|
}, import_zod.z);
|
|
@@ -539,6 +531,9 @@ var typert_remote_client_default = TYPERT_REMOTE;
|
|
|
539
531
|
var import_react = require("react");
|
|
540
532
|
var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
541
533
|
|
|
534
|
+
// src/group-ids.ts
|
|
535
|
+
var DEFAULT_GROUP_ID = "default";
|
|
536
|
+
|
|
542
537
|
// src/client/format-remote-error.ts
|
|
543
538
|
function isRemoteFailure(value) {
|
|
544
539
|
return typeof value === "object" && value !== null && value.isDSHRemoteError === true && typeof value.code === "string";
|
|
@@ -547,6 +542,7 @@ function formatRemoteError(error, t) {
|
|
|
547
542
|
if (isRemoteFailure(error)) {
|
|
548
543
|
if (error.code === "custom-env/invalid-name") return t("error.invalidName");
|
|
549
544
|
if (error.code === "custom-env/invalid-value") return t("error.invalidValue");
|
|
545
|
+
if (error.code === "custom-env/invalid-group") return t("error.invalidGroup");
|
|
550
546
|
if (error.code === "custom-env/restore-failed") return t("error.restoreFailed");
|
|
551
547
|
if (error.code === "custom-env/cli-install-failed") return t("error.cliInstall");
|
|
552
548
|
}
|
|
@@ -626,23 +622,41 @@ function rowIdFromPoint(clientX, clientY) {
|
|
|
626
622
|
}
|
|
627
623
|
|
|
628
624
|
// src/client/EnvSettingsSection.module.css
|
|
629
|
-
var css = ".EnvSettingsSection_section {\n display: flex;\n flex-direction: column;\n gap: 16px;\n max-width: 760px;\n color: var(--dsw-alias-label-primary);\n}\n\n.EnvSettingsSection_heading {\n margin: 0;\n font-size: 18px;\n font-weight: 500;\n line-height: 1.3;\n}\n\n/* \u2014\u2014 dsh CLI: exactly two lines (label + path) \u2014\u2014 */\n.EnvSettingsSection_cli {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.EnvSettingsSection_cliHeading {\n margin: 0;\n font-size: 13px;\n font-weight: 500;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.EnvSettingsSection_cliBody {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 28px;\n gap: 8px;\n align-items: center;\n height: 28px;\n}\n\n.EnvSettingsSection_cliPath {\n margin: 0;\n min-width: 0;\n font-size: 13px;\n line-height: 28px;\n color: var(--dsw-alias-label-tertiary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.EnvSettingsSection_cliSlot {\n display: flex;\n width: 28px;\n height: 28px;\n align-items: center;\n justify-content: center;\n}\n\n.EnvSettingsSection_cliSlot[data-empty='true'] {\n visibility: hidden;\n pointer-events: none;\n}\n\n.EnvSettingsSection_notice
|
|
625
|
+
var css = ".EnvSettingsSection_section {\n display: flex;\n flex-direction: column;\n gap: 16px;\n max-width: 760px;\n min-width: 0;\n color: var(--dsw-alias-label-primary);\n container-type: inline-size;\n}\n\n.EnvSettingsSection_heading {\n margin: 0;\n font-size: 18px;\n font-weight: 500;\n line-height: 1.3;\n}\n\n/* \u2014\u2014 dsh CLI: exactly two lines (label + path) \u2014\u2014 */\n.EnvSettingsSection_cli {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.EnvSettingsSection_cliHeading {\n margin: 0;\n font-size: 13px;\n font-weight: 500;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.EnvSettingsSection_cliBody {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 28px;\n gap: 8px;\n align-items: center;\n height: 28px;\n}\n\n.EnvSettingsSection_cliPath {\n margin: 0;\n min-width: 0;\n font-size: 13px;\n line-height: 28px;\n color: var(--dsw-alias-label-tertiary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.EnvSettingsSection_cliSlot {\n display: flex;\n width: 28px;\n height: 28px;\n align-items: center;\n justify-content: center;\n}\n\n.EnvSettingsSection_cliSlot[data-empty='true'] {\n visibility: hidden;\n pointer-events: none;\n}\n\n.EnvSettingsSection_notice {\n margin: 0;\n font-size: 13px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.EnvSettingsSection_notice[data-tone='error'] {\n color: var(--dsw-alias-label-danger, #c62828);\n}\n\n/* \u2014\u2014 variable rows: name | value | actions \u2014\u2014 */\n.EnvSettingsSection_header,\n.EnvSettingsSection_row {\n display: grid;\n grid-template-columns: minmax(0, 0.75fr) minmax(0, 1.25fr) 116px;\n gap: 10px;\n align-items: center;\n min-width: 0;\n}\n\n.EnvSettingsSection_row {\n padding: 4px 6px;\n margin: 0 -6px;\n user-select: none;\n}\n\n.EnvSettingsSection_row[data-selected='true'] {\n background: var(--dsw-alias-fill-hover, rgba(127, 127, 127, 0.1));\n}\n\n.EnvSettingsSection_row[data-composer='true'] {\n user-select: auto;\n}\n\n.EnvSettingsSection_header {\n padding: 0 0 2px;\n}\n\n.EnvSettingsSection_headerLabel {\n margin: 0;\n font-size: 12px;\n font-weight: 500;\n line-height: 1.3;\n color: var(--dsw-alias-label-tertiary);\n}\n\n.EnvSettingsSection_headerActions {\n width: 116px;\n}\n\n/* Extremely narrow pane: value wraps under name; actions stay on the first row. */\n@container (max-width: 360px) {\n .EnvSettingsSection_header,\n .EnvSettingsSection_row {\n grid-template-columns: minmax(0, 1fr) 116px;\n align-items: start;\n row-gap: 8px;\n }\n\n .EnvSettingsSection_header {\n align-items: end;\n }\n\n .EnvSettingsSection_header > :nth-child(1),\n .EnvSettingsSection_row > :nth-child(1) {\n grid-column: 1;\n grid-row: 1;\n }\n\n .EnvSettingsSection_header > :nth-child(3),\n .EnvSettingsSection_row > :nth-child(3) {\n grid-column: 2;\n grid-row: 1;\n }\n\n .EnvSettingsSection_header > :nth-child(2),\n .EnvSettingsSection_row > :nth-child(2) {\n grid-column: 1 / -1;\n grid-row: 2;\n }\n\n .EnvSettingsSection_actions {\n margin-left: 0;\n }\n}\n\n.EnvSettingsSection_field {\n min-width: 0;\n overflow: hidden;\n}\n\n.EnvSettingsSection_fieldInput {\n display: flex;\n box-sizing: border-box;\n width: 100%;\n max-width: 100%;\n min-width: 0;\n user-select: none;\n}\n\n.EnvSettingsSection_field:focus-within,\n.EnvSettingsSection_field:focus-within .EnvSettingsSection_fieldInput,\n.EnvSettingsSection_row[data-composer='true'] .EnvSettingsSection_fieldInput {\n user-select: text;\n}\n\n.EnvSettingsSection_actions {\n display: grid;\n grid-template-columns: repeat(4, 26px);\n gap: 2px;\n align-items: center;\n justify-content: end;\n width: 116px;\n margin-left: auto;\n flex-shrink: 0;\n}\n\n.EnvSettingsSection_slot {\n display: flex;\n width: 26px;\n height: 26px;\n align-items: center;\n justify-content: center;\n}\n\n.EnvSettingsSection_slot[data-empty='true'] {\n visibility: hidden;\n pointer-events: none;\n}\n\n.EnvSettingsSection_iconButton {\n display: inline-flex;\n width: 26px;\n height: 26px;\n margin: 0;\n padding: 0;\n align-items: center;\n justify-content: center;\n border: none;\n border-radius: var(--dsw-radius-sm, 6px);\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n\n.EnvSettingsSection_iconButton:hover:not(:disabled) {\n background: var(--dsw-alias-fill-hover, rgba(127, 127, 127, 0.12));\n color: var(--dsw-alias-label-primary);\n}\n\n.EnvSettingsSection_iconButton:disabled {\n opacity: 0.45;\n cursor: default;\n}\n\n.EnvSettingsSection_iconButtonDanger:hover:not(:disabled) {\n color: var(--dsw-alias-label-danger, #c62828);\n}\n\n.EnvSettingsSection_iconButtonPrimary {\n color: var(--dsw-alias-brand-primary, #247bbf);\n}\n\n.EnvSettingsSection_restartBadge {\n display: inline-flex;\n width: 26px;\n height: 26px;\n align-items: center;\n justify-content: center;\n color: var(--dsw-alias-label-warning, #c67c00);\n}\n\n.EnvSettingsSection_spinner {\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n to { transform: rotate(360deg); }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .EnvSettingsSection_spinner {\n animation: none;\n }\n}\n\n.EnvSettingsSection_groups {\n display: flex;\n flex-direction: column;\n gap: 14px;\n min-width: 0;\n}\n\n.EnvSettingsSection_group {\n display: flex;\n flex-direction: column;\n gap: 10px;\n min-width: 0;\n}\n\n.EnvSettingsSection_group + .EnvSettingsSection_group {\n border-top: 0.5px solid var(--dsw-alias-border-l2, rgba(127, 127, 127, 0.25));\n padding-top: 14px;\n}\n\n.EnvSettingsSection_groupTitleRow {\n display: flex;\n align-items: center;\n gap: 8px;\n min-height: 36px;\n}\n\n.EnvSettingsSection_groupToggle {\n display: flex;\n flex: none;\n align-items: center;\n gap: 8px;\n border: 0;\n padding: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n\n.EnvSettingsSection_groupToggle:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary, #247bbf);\n outline-offset: 2px;\n}\n\n.EnvSettingsSection_groupToggle > .EnvSettingsSection_chevron {\n transform: rotate(-90deg);\n}\n\n.EnvSettingsSection_groupToggle[aria-expanded='true'] > .EnvSettingsSection_chevron {\n transform: none;\n}\n\n.EnvSettingsSection_groupTitle {\n font-size: 14px;\n line-height: 22px;\n font-weight: 400;\n color: var(--dsw-alias-label-primary);\n}\n\n.EnvSettingsSection_headerEnd {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-left: auto;\n}\n\n.EnvSettingsSection_groupBody {\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-width: 0;\n}\n\n.EnvSettingsSection_modalField {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 8px;\n}\n\n.EnvSettingsSection_modalCheck {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 12px;\n font-size: 13px;\n line-height: 18px;\n color: var(--dsw-alias-label-secondary);\n}\n";
|
|
630
626
|
if (typeof document !== "undefined" && !document.getElementById("dsh-custom-env-css")) {
|
|
631
627
|
const style = document.createElement("style");
|
|
632
628
|
style.id = "dsh-custom-env-css";
|
|
633
629
|
style.textContent = css;
|
|
634
630
|
document.head.appendChild(style);
|
|
635
631
|
}
|
|
636
|
-
var EnvSettingsSection_default = { "section": "EnvSettingsSection_section", "heading": "EnvSettingsSection_heading", "cli": "EnvSettingsSection_cli", "cliHeading": "EnvSettingsSection_cliHeading", "cliBody": "EnvSettingsSection_cliBody", "cliPath": "EnvSettingsSection_cliPath", "cliSlot": "EnvSettingsSection_cliSlot", "notice": "EnvSettingsSection_notice", "
|
|
632
|
+
var EnvSettingsSection_default = { "section": "EnvSettingsSection_section", "heading": "EnvSettingsSection_heading", "cli": "EnvSettingsSection_cli", "cliHeading": "EnvSettingsSection_cliHeading", "cliBody": "EnvSettingsSection_cliBody", "cliPath": "EnvSettingsSection_cliPath", "cliSlot": "EnvSettingsSection_cliSlot", "notice": "EnvSettingsSection_notice", "header": "EnvSettingsSection_header", "row": "EnvSettingsSection_row", "headerLabel": "EnvSettingsSection_headerLabel", "headerActions": "EnvSettingsSection_headerActions", "actions": "EnvSettingsSection_actions", "field": "EnvSettingsSection_field", "fieldInput": "EnvSettingsSection_fieldInput", "slot": "EnvSettingsSection_slot", "iconButton": "EnvSettingsSection_iconButton", "iconButtonDanger": "EnvSettingsSection_iconButtonDanger", "iconButtonPrimary": "EnvSettingsSection_iconButtonPrimary", "restartBadge": "EnvSettingsSection_restartBadge", "spinner": "EnvSettingsSection_spinner", "groups": "EnvSettingsSection_groups", "group": "EnvSettingsSection_group", "groupTitleRow": "EnvSettingsSection_groupTitleRow", "groupToggle": "EnvSettingsSection_groupToggle", "chevron": "EnvSettingsSection_chevron", "groupTitle": "EnvSettingsSection_groupTitle", "headerEnd": "EnvSettingsSection_headerEnd", "groupBody": "EnvSettingsSection_groupBody", "modalField": "EnvSettingsSection_modalField", "modalCheck": "EnvSettingsSection_modalCheck" };
|
|
637
633
|
|
|
638
634
|
// src/client/EnvSettingsSection.tsx
|
|
639
635
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
640
636
|
var NAME_OK2 = /^[A-Za-z_][A-Za-z0-9_]*$/u;
|
|
641
|
-
var COMPOSER_ID = "";
|
|
642
637
|
var PENDING_PREFIX = "pending:";
|
|
638
|
+
var COMPOSER_PREFIX = "composer:";
|
|
643
639
|
function isPendingId(id) {
|
|
644
640
|
return id.startsWith(PENDING_PREFIX);
|
|
645
641
|
}
|
|
642
|
+
function composerId(groupId) {
|
|
643
|
+
return `${COMPOSER_PREFIX}${groupId}`;
|
|
644
|
+
}
|
|
645
|
+
function isComposerId(id) {
|
|
646
|
+
return id.startsWith(COMPOSER_PREFIX);
|
|
647
|
+
}
|
|
648
|
+
function rowsByGroup(groups, entries, pendingOrder, pendingGroup) {
|
|
649
|
+
const saved = new Map(groups.map((group) => [group.id, []]));
|
|
650
|
+
const pending = new Map(groups.map((group) => [group.id, []]));
|
|
651
|
+
for (const entry of entries) {
|
|
652
|
+
(saved.get(saved.has(entry.groupId) ? entry.groupId : DEFAULT_GROUP_ID) ?? saved.get(DEFAULT_GROUP_ID)).push(entry);
|
|
653
|
+
}
|
|
654
|
+
for (const id of pendingOrder) {
|
|
655
|
+
const groupId = pendingGroup[id] ?? DEFAULT_GROUP_ID;
|
|
656
|
+
(pending.get(pending.has(groupId) ? groupId : DEFAULT_GROUP_ID) ?? pending.get(DEFAULT_GROUP_ID)).push(id);
|
|
657
|
+
}
|
|
658
|
+
return { saved, pending };
|
|
659
|
+
}
|
|
646
660
|
function IconAction({
|
|
647
661
|
label,
|
|
648
662
|
disabled,
|
|
@@ -675,14 +689,37 @@ function RowActions({
|
|
|
675
689
|
canConfirm,
|
|
676
690
|
pending = false,
|
|
677
691
|
showRemove = true,
|
|
692
|
+
moveItems,
|
|
678
693
|
onConfirm,
|
|
679
694
|
onCancel,
|
|
680
695
|
onRestore,
|
|
681
|
-
onRemove
|
|
696
|
+
onRemove,
|
|
697
|
+
onMove
|
|
682
698
|
}) {
|
|
699
|
+
const [moveOpen, setMoveOpen] = (0, import_react.useState)(false);
|
|
700
|
+
const showMove = moveItems !== void 0 && moveItems.length > 0 && onMove !== void 0;
|
|
683
701
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: EnvSettingsSection_default.actions, role: "group", "aria-label": t("field.actions"), children: [
|
|
684
702
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Slot, { empty: !dirty && !pending, children: dirty ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconAction, { label: loading ? t("panel.loading") : t("action.confirm"), primary: true, disabled: busy || !canConfirm, onClick: onConfirm, children: loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconLoadingOutlineRegular, { className: EnvSettingsSection_default.spinner, size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconCheckOutlineRegular, { size: 14 }) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Tooltip, { portal: true, label: t("status.restartRequired"), side: "top", delayMs: 400, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: EnvSettingsSection_default.restartBadge, role: "img", "aria-label": t("status.restartRequired"), title: t("status.restartRequired"), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconWarningOutlineRegular, { size: 14 }) }) }) }),
|
|
685
703
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Slot, { empty: !dirty && !pending, children: dirty ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconAction, { label: t("action.cancel"), disabled: busy, onClick: onCancel, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconCloseOutlineRegular, { size: 14 }) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconAction, { label: t("action.restore"), disabled: busy, onClick: onRestore, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconRefreshOutlineRegular, { size: 14 }) }) }),
|
|
704
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Slot, { empty: !showMove, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
705
|
+
import_dsh_client_ui_primitives.Menu,
|
|
706
|
+
{
|
|
707
|
+
open: moveOpen,
|
|
708
|
+
onClose: () => {
|
|
709
|
+
setMoveOpen(false);
|
|
710
|
+
},
|
|
711
|
+
items: (moveItems ?? []).map((item) => ({ id: item.id, label: item.label })),
|
|
712
|
+
onSelect: (groupId) => {
|
|
713
|
+
setMoveOpen(false);
|
|
714
|
+
onMove?.(groupId);
|
|
715
|
+
},
|
|
716
|
+
align: "end",
|
|
717
|
+
portal: true,
|
|
718
|
+
anchor: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconAction, { label: t("action.moveGroup"), disabled: busy, onClick: () => {
|
|
719
|
+
setMoveOpen((value) => !value);
|
|
720
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconFolderOpenOutlineRegular, { size: 14 }) })
|
|
721
|
+
}
|
|
722
|
+
) }),
|
|
686
723
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Slot, { empty: !showRemove, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconAction, { label: t("action.remove"), danger: true, disabled: busy, onClick: onRemove, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconTrashOutlineRegular, { size: 14 }) }) })
|
|
687
724
|
] });
|
|
688
725
|
}
|
|
@@ -718,23 +755,33 @@ function EnvSettingsSection({
|
|
|
718
755
|
upsert,
|
|
719
756
|
remove,
|
|
720
757
|
restore,
|
|
758
|
+
moveEntry,
|
|
759
|
+
createGroup,
|
|
760
|
+
renameGroup,
|
|
761
|
+
deleteGroup,
|
|
721
762
|
cliStatus,
|
|
722
763
|
cliInstall
|
|
723
764
|
}) {
|
|
724
765
|
const [snapshot, setSnapshot] = (0, import_react.useState)();
|
|
725
766
|
const [cli, setCli] = (0, import_react.useState)();
|
|
726
|
-
const [drafts, setDrafts] = (0, import_react.useState)({
|
|
767
|
+
const [drafts, setDrafts] = (0, import_react.useState)({});
|
|
727
768
|
const [pendingOrder, setPendingOrder] = (0, import_react.useState)([]);
|
|
769
|
+
const [pendingGroup, setPendingGroup] = (0, import_react.useState)({});
|
|
770
|
+
const [openGroups, setOpenGroups] = (0, import_react.useState)({ [DEFAULT_GROUP_ID]: true });
|
|
728
771
|
const [busyTarget, setBusyTarget] = (0, import_react.useState)();
|
|
729
772
|
const [error, setError] = (0, import_react.useState)();
|
|
730
773
|
const [nameError, setNameError] = (0, import_react.useState)(false);
|
|
731
774
|
const [pendingRemove, setPendingRemove] = (0, import_react.useState)();
|
|
775
|
+
const [groupModal, setGroupModal] = (0, import_react.useState)();
|
|
776
|
+
const [groupTitleDraft, setGroupTitleDraft] = (0, import_react.useState)("");
|
|
732
777
|
const [selectedIds, setSelectedIds] = (0, import_react.useState)(() => /* @__PURE__ */ new Set());
|
|
733
778
|
const pendingSeq = (0, import_react.useRef)(0);
|
|
734
779
|
const draftsRef = (0, import_react.useRef)(drafts);
|
|
735
780
|
draftsRef.current = drafts;
|
|
736
781
|
const pendingOrderRef = (0, import_react.useRef)(pendingOrder);
|
|
737
782
|
pendingOrderRef.current = pendingOrder;
|
|
783
|
+
const pendingGroupRef = (0, import_react.useRef)(pendingGroup);
|
|
784
|
+
pendingGroupRef.current = pendingGroup;
|
|
738
785
|
const selectedRef = (0, import_react.useRef)(selectedIds);
|
|
739
786
|
selectedRef.current = selectedIds;
|
|
740
787
|
const anchorIdRef = (0, import_react.useRef)(void 0);
|
|
@@ -743,35 +790,61 @@ function EnvSettingsSection({
|
|
|
743
790
|
const dragPendingCrossRef = (0, import_react.useRef)(false);
|
|
744
791
|
const pendingRemoveRef = (0, import_react.useRef)(pendingRemove);
|
|
745
792
|
pendingRemoveRef.current = pendingRemove;
|
|
793
|
+
const groupModalRef = (0, import_react.useRef)(groupModal);
|
|
794
|
+
groupModalRef.current = groupModal;
|
|
746
795
|
const busy = busyTarget !== void 0;
|
|
796
|
+
const groups = snapshot?.groups ?? [{ id: DEFAULT_GROUP_ID, title: t("group.defaultTitle") }];
|
|
747
797
|
const entries = snapshot?.entries ?? [];
|
|
748
798
|
const taken = new Set(entries.map((entry) => entry.name));
|
|
749
|
-
const
|
|
799
|
+
const grouped = rowsByGroup(groups, entries, pendingOrder, pendingGroup);
|
|
800
|
+
const selectableOrder = groups.flatMap((group) => [
|
|
801
|
+
...(grouped.saved.get(group.id) ?? []).map((entry) => entry.id),
|
|
802
|
+
...grouped.pending.get(group.id) ?? []
|
|
803
|
+
]);
|
|
750
804
|
const selectableOrderRef = (0, import_react.useRef)(selectableOrder);
|
|
751
805
|
selectableOrderRef.current = selectableOrder;
|
|
752
|
-
const
|
|
806
|
+
const groupLabel = (group) => group.id === DEFAULT_GROUP_ID ? t("group.defaultTitle") : group.title;
|
|
807
|
+
const keepTransientDrafts = (current, dropId) => {
|
|
753
808
|
const kept = {};
|
|
754
809
|
for (const [id, draft] of Object.entries(current)) {
|
|
755
|
-
if (
|
|
756
|
-
kept[id] = draft;
|
|
810
|
+
if (isComposerId(id)) kept[id] = draft;
|
|
811
|
+
else if (isPendingId(id) && id !== dropId) kept[id] = draft;
|
|
757
812
|
}
|
|
758
813
|
return kept;
|
|
759
814
|
};
|
|
815
|
+
const emptyComposers = (nextGroups, current) => Object.fromEntries(nextGroups.map((group) => {
|
|
816
|
+
const id = composerId(group.id);
|
|
817
|
+
return [id, current[id] ?? { name: "", value: "" }];
|
|
818
|
+
}));
|
|
819
|
+
const forgetPendingId = (id) => {
|
|
820
|
+
setPendingOrder((order) => order.filter((item) => item !== id));
|
|
821
|
+
setPendingGroup((previous) => {
|
|
822
|
+
if (previous[id] === void 0) return previous;
|
|
823
|
+
const next = { ...previous };
|
|
824
|
+
delete next[id];
|
|
825
|
+
return next;
|
|
826
|
+
});
|
|
827
|
+
setSelectedIds((previous) => {
|
|
828
|
+
if (!previous.has(id)) return previous;
|
|
829
|
+
const next = new Set(previous);
|
|
830
|
+
next.delete(id);
|
|
831
|
+
return next;
|
|
832
|
+
});
|
|
833
|
+
if (anchorIdRef.current === id) anchorIdRef.current = void 0;
|
|
834
|
+
};
|
|
760
835
|
const applySnapshot = (next, dropPendingId) => {
|
|
761
836
|
setSnapshot(next);
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
if (
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
if (anchorIdRef.current === dropPendingId) anchorIdRef.current = void 0;
|
|
771
|
-
}
|
|
837
|
+
setOpenGroups((previous) => {
|
|
838
|
+
const merged = { ...previous };
|
|
839
|
+
for (const group of next.groups) {
|
|
840
|
+
if (merged[group.id] === void 0) merged[group.id] = group.id === DEFAULT_GROUP_ID;
|
|
841
|
+
}
|
|
842
|
+
return merged;
|
|
843
|
+
});
|
|
844
|
+
if (dropPendingId !== void 0) forgetPendingId(dropPendingId);
|
|
772
845
|
setDrafts((current) => ({
|
|
773
|
-
|
|
774
|
-
...
|
|
846
|
+
...emptyComposers(next.groups, current),
|
|
847
|
+
...keepTransientDrafts(current, dropPendingId),
|
|
775
848
|
...Object.fromEntries(next.entries.map((entry) => [entry.id, { name: entry.name, value: entry.value }]))
|
|
776
849
|
}));
|
|
777
850
|
};
|
|
@@ -782,14 +855,7 @@ function EnvSettingsSection({
|
|
|
782
855
|
}));
|
|
783
856
|
};
|
|
784
857
|
const dropPending = (id) => {
|
|
785
|
-
|
|
786
|
-
setSelectedIds((previous) => {
|
|
787
|
-
if (!previous.has(id)) return previous;
|
|
788
|
-
const next = new Set(previous);
|
|
789
|
-
next.delete(id);
|
|
790
|
-
return next;
|
|
791
|
-
});
|
|
792
|
-
if (anchorIdRef.current === id) anchorIdRef.current = void 0;
|
|
858
|
+
forgetPendingId(id);
|
|
793
859
|
setDrafts((previous) => {
|
|
794
860
|
const next = { ...previous };
|
|
795
861
|
delete next[id];
|
|
@@ -832,11 +898,13 @@ function EnvSettingsSection({
|
|
|
832
898
|
setError(void 0);
|
|
833
899
|
try {
|
|
834
900
|
setPendingOrder([]);
|
|
901
|
+
setPendingGroup({});
|
|
835
902
|
clearSelection();
|
|
836
903
|
const next = await load();
|
|
837
904
|
setSnapshot(next);
|
|
905
|
+
setOpenGroups(Object.fromEntries(next.groups.map((group) => [group.id, group.id === DEFAULT_GROUP_ID])));
|
|
838
906
|
setDrafts({
|
|
839
|
-
|
|
907
|
+
...emptyComposers(next.groups, {}),
|
|
840
908
|
...Object.fromEntries(next.entries.map((entry) => [entry.id, { name: entry.name, value: entry.value }]))
|
|
841
909
|
});
|
|
842
910
|
try {
|
|
@@ -854,13 +922,12 @@ function EnvSettingsSection({
|
|
|
854
922
|
void refresh();
|
|
855
923
|
}, [refresh]);
|
|
856
924
|
(0, import_react.useEffect)(() => {
|
|
857
|
-
|
|
858
|
-
pruneSelection(allowed);
|
|
925
|
+
pruneSelection(new Set(selectableOrder));
|
|
859
926
|
}, [selectableOrder.join("\0")]);
|
|
860
927
|
const stopEditingGesture = () => {
|
|
861
928
|
clearDomTextSelection();
|
|
862
929
|
const active = document.activeElement;
|
|
863
|
-
if (active instanceof HTMLInputElement && active.closest(`.${EnvSettingsSection_default.
|
|
930
|
+
if (active instanceof HTMLInputElement && active.closest(`.${EnvSettingsSection_default.groups}`) !== null) active.blur();
|
|
864
931
|
};
|
|
865
932
|
const applyDragOverRow = (id) => {
|
|
866
933
|
if (dragModeRef.current === void 0) return;
|
|
@@ -899,7 +966,7 @@ function EnvSettingsSection({
|
|
|
899
966
|
if (id !== void 0) applyDragOverRow(id);
|
|
900
967
|
};
|
|
901
968
|
const onPointerDown = (event) => {
|
|
902
|
-
if (selectedRef.current.size === 0 || pendingRemoveRef.current !== void 0) return;
|
|
969
|
+
if (selectedRef.current.size === 0 || pendingRemoveRef.current !== void 0 || groupModalRef.current !== void 0) return;
|
|
903
970
|
if (!(event.target instanceof Element)) return;
|
|
904
971
|
if (event.target.closest("[data-env-row]") !== null) return;
|
|
905
972
|
clearSelection();
|
|
@@ -955,37 +1022,42 @@ function EnvSettingsSection({
|
|
|
955
1022
|
}
|
|
956
1023
|
if (draft.value === "") return;
|
|
957
1024
|
setNameError(false);
|
|
958
|
-
|
|
1025
|
+
const groupId = pendingGroup[id] ?? DEFAULT_GROUP_ID;
|
|
1026
|
+
void run(`pending:${id}`, () => upsert("", name, draft.value, groupId), id);
|
|
959
1027
|
};
|
|
960
|
-
const typeIntoComposer = (patch, focus) => {
|
|
1028
|
+
const typeIntoComposer = (groupId, patch, focus) => {
|
|
961
1029
|
setNameError(false);
|
|
962
|
-
const
|
|
1030
|
+
const key = composerId(groupId);
|
|
1031
|
+
const base = draftsRef.current[key] ?? { name: "", value: "" };
|
|
963
1032
|
const next = { name: patch.name ?? base.name, value: patch.value ?? base.value };
|
|
964
1033
|
const id = `${PENDING_PREFIX}${++pendingSeq.current}`;
|
|
965
1034
|
setDrafts((previous) => ({
|
|
966
1035
|
...previous,
|
|
967
1036
|
[id]: next,
|
|
968
|
-
[
|
|
1037
|
+
[key]: { name: "", value: "" }
|
|
969
1038
|
}));
|
|
970
1039
|
setPendingOrder((order) => [...order, id]);
|
|
1040
|
+
setPendingGroup((previous) => ({ ...previous, [id]: groupId }));
|
|
971
1041
|
queueMicrotask(() => {
|
|
972
1042
|
document.getElementById(`env-${focus}-${id}`)?.focus();
|
|
973
1043
|
});
|
|
974
1044
|
};
|
|
975
|
-
const appendPendingPairs = (pairs) => {
|
|
1045
|
+
const appendPendingPairs = (groupId, pairs) => {
|
|
976
1046
|
if (pairs.length === 0) return;
|
|
977
1047
|
setNameError(false);
|
|
978
1048
|
const previous = draftsRef.current;
|
|
979
1049
|
const order = pendingOrderRef.current;
|
|
980
|
-
const
|
|
981
|
-
const
|
|
1050
|
+
const groupsByPending = pendingGroupRef.current;
|
|
1051
|
+
const nextDrafts = { ...previous, [composerId(groupId)]: { name: "", value: "" } };
|
|
982
1052
|
const existingPendingByName = /* @__PURE__ */ new Map();
|
|
983
1053
|
for (const id of order) {
|
|
984
1054
|
const draft = previous[id];
|
|
985
1055
|
if (draft !== void 0) existingPendingByName.set(draft.name.trim(), id);
|
|
986
1056
|
}
|
|
1057
|
+
const savedByName = new Map(entries.map((entry) => [entry.name, entry.id]));
|
|
987
1058
|
const added = [];
|
|
988
|
-
const
|
|
1059
|
+
const dropPendingIds = /* @__PURE__ */ new Set();
|
|
1060
|
+
const nextPendingGroup = { ...groupsByPending };
|
|
989
1061
|
for (const pair of pairs) {
|
|
990
1062
|
const savedId = savedByName.get(pair.name);
|
|
991
1063
|
if (savedId !== void 0) {
|
|
@@ -993,7 +1065,8 @@ function EnvSettingsSection({
|
|
|
993
1065
|
const pendingDup = existingPendingByName.get(pair.name);
|
|
994
1066
|
if (pendingDup !== void 0) {
|
|
995
1067
|
delete nextDrafts[pendingDup];
|
|
996
|
-
|
|
1068
|
+
dropPendingIds.add(pendingDup);
|
|
1069
|
+
delete nextPendingGroup[pendingDup];
|
|
997
1070
|
existingPendingByName.delete(pair.name);
|
|
998
1071
|
}
|
|
999
1072
|
continue;
|
|
@@ -1006,19 +1079,21 @@ function EnvSettingsSection({
|
|
|
1006
1079
|
const id = `${PENDING_PREFIX}${++pendingSeq.current}`;
|
|
1007
1080
|
nextDrafts[id] = { name: pair.name, value: pair.value };
|
|
1008
1081
|
existingPendingByName.set(pair.name, id);
|
|
1082
|
+
nextPendingGroup[id] = groupId;
|
|
1009
1083
|
added.push(id);
|
|
1010
1084
|
}
|
|
1011
1085
|
setDrafts(nextDrafts);
|
|
1012
|
-
|
|
1013
|
-
|
|
1086
|
+
setPendingGroup(nextPendingGroup);
|
|
1087
|
+
if (added.length > 0 || dropPendingIds.size > 0) {
|
|
1088
|
+
setPendingOrder([...order.filter((id) => !dropPendingIds.has(id)), ...added]);
|
|
1014
1089
|
}
|
|
1015
1090
|
};
|
|
1016
|
-
const onComposerPaste = (event) => {
|
|
1091
|
+
const onComposerPaste = (groupId, event) => {
|
|
1017
1092
|
const text = event.clipboardData.getData("text");
|
|
1018
1093
|
const pairs = parseEnvPaste(text);
|
|
1019
1094
|
if (pairs.length === 0) return;
|
|
1020
1095
|
event.preventDefault();
|
|
1021
|
-
appendPendingPairs(pairs);
|
|
1096
|
+
appendPendingPairs(groupId, pairs);
|
|
1022
1097
|
};
|
|
1023
1098
|
const onRowMouseDown = (id, event) => {
|
|
1024
1099
|
if (event.button !== 0) return;
|
|
@@ -1053,11 +1128,246 @@ function EnvSettingsSection({
|
|
|
1053
1128
|
dragVisitedRef.current = /* @__PURE__ */ new Set([id]);
|
|
1054
1129
|
dragPendingCrossRef.current = true;
|
|
1055
1130
|
};
|
|
1056
|
-
const
|
|
1131
|
+
const submitGroupModal = () => {
|
|
1132
|
+
if (groupModal === void 0 || busyTarget !== void 0) return;
|
|
1133
|
+
if (groupModal.kind === "create" || groupModal.kind === "rename") {
|
|
1134
|
+
const title = groupTitleDraft.trim();
|
|
1135
|
+
if (title === "") return;
|
|
1136
|
+
setBusyTarget("group");
|
|
1137
|
+
setError(void 0);
|
|
1138
|
+
void (async () => {
|
|
1139
|
+
try {
|
|
1140
|
+
if (groupModal.kind === "create") {
|
|
1141
|
+
const group = await createGroup(title);
|
|
1142
|
+
const next = await load();
|
|
1143
|
+
applySnapshot(next);
|
|
1144
|
+
setOpenGroups((previous) => ({ ...previous, [group.id]: true }));
|
|
1145
|
+
} else {
|
|
1146
|
+
await renameGroup(groupModal.id, title);
|
|
1147
|
+
applySnapshot(await load());
|
|
1148
|
+
}
|
|
1149
|
+
setGroupModal(void 0);
|
|
1150
|
+
} catch (err) {
|
|
1151
|
+
setError(formatRemoteError(err, t));
|
|
1152
|
+
} finally {
|
|
1153
|
+
setBusyTarget(void 0);
|
|
1154
|
+
}
|
|
1155
|
+
})();
|
|
1156
|
+
return;
|
|
1157
|
+
}
|
|
1158
|
+
setBusyTarget("group");
|
|
1159
|
+
setError(void 0);
|
|
1160
|
+
void (async () => {
|
|
1161
|
+
try {
|
|
1162
|
+
applySnapshot(await deleteGroup(groupModal.id, groupModal.moveToDefault));
|
|
1163
|
+
setGroupModal(void 0);
|
|
1164
|
+
} catch (err) {
|
|
1165
|
+
setError(formatRemoteError(err, t));
|
|
1166
|
+
} finally {
|
|
1167
|
+
setBusyTarget(void 0);
|
|
1168
|
+
}
|
|
1169
|
+
})();
|
|
1170
|
+
};
|
|
1057
1171
|
const cliInstalling = busyTarget === "cli";
|
|
1058
1172
|
const cliBooting = busyTarget === "boot" || cli === void 0;
|
|
1059
1173
|
const showCliAction = cli?.canInstall === true || cliInstalling;
|
|
1060
1174
|
const notice = error ?? (nameError ? t("error.invalidName") : void 0) ?? (cli?.reason === "could-not-resolve-expected-cli" ? t("error.cliUnresolved") : void 0) ?? (cli?.reason === "unsupported-platform" ? t("error.cliUnsupported") : void 0);
|
|
1175
|
+
const moveTargets = (currentGroupId) => groups.filter((group) => group.id !== currentGroupId).map((group) => ({ id: group.id, label: groupLabel(group) }));
|
|
1176
|
+
const renderRow = (entry) => {
|
|
1177
|
+
const draft = drafts[entry.id] ?? { name: entry.name, value: entry.value };
|
|
1178
|
+
const dirty = draft.name !== entry.name || draft.value !== entry.value;
|
|
1179
|
+
const pendingKind = entry.kind === "added" || entry.kind === "modified";
|
|
1180
|
+
const loading = busyTarget === `row:${entry.id}`;
|
|
1181
|
+
const nextName = draft.name.trim();
|
|
1182
|
+
const canConfirm = NAME_OK2.test(nextName) && draft.value !== "" && !(nextName !== entry.name && taken.has(nextName));
|
|
1183
|
+
const selected = selectedIds.has(entry.id);
|
|
1184
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1185
|
+
"div",
|
|
1186
|
+
{
|
|
1187
|
+
className: EnvSettingsSection_default.row,
|
|
1188
|
+
"data-env-row": entry.id,
|
|
1189
|
+
"data-selected": selected ? "true" : "false",
|
|
1190
|
+
"aria-selected": selected,
|
|
1191
|
+
onMouseDown: (event) => {
|
|
1192
|
+
onRowMouseDown(entry.id, event);
|
|
1193
|
+
},
|
|
1194
|
+
children: [
|
|
1195
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1196
|
+
Field,
|
|
1197
|
+
{
|
|
1198
|
+
id: `env-name-${entry.id}`,
|
|
1199
|
+
value: draft.name,
|
|
1200
|
+
disabled: busy,
|
|
1201
|
+
title: draft.name,
|
|
1202
|
+
invalid: nameError && dirty,
|
|
1203
|
+
label: t("field.name"),
|
|
1204
|
+
rowSelectGestures: true,
|
|
1205
|
+
onChange: (name) => {
|
|
1206
|
+
setNameError(false);
|
|
1207
|
+
setDraft(entry.id, { name });
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
),
|
|
1211
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1212
|
+
Field,
|
|
1213
|
+
{
|
|
1214
|
+
id: `env-value-${entry.id}`,
|
|
1215
|
+
value: draft.value,
|
|
1216
|
+
disabled: busy,
|
|
1217
|
+
title: draft.value,
|
|
1218
|
+
label: t("field.value"),
|
|
1219
|
+
rowSelectGestures: true,
|
|
1220
|
+
onChange: (value) => {
|
|
1221
|
+
setDraft(entry.id, { value });
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
),
|
|
1225
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1226
|
+
RowActions,
|
|
1227
|
+
{
|
|
1228
|
+
t,
|
|
1229
|
+
busy,
|
|
1230
|
+
loading,
|
|
1231
|
+
dirty: dirty || loading,
|
|
1232
|
+
canConfirm,
|
|
1233
|
+
pending: pendingKind && !dirty ? true : false,
|
|
1234
|
+
moveItems: moveTargets(entry.groupId),
|
|
1235
|
+
onConfirm: () => {
|
|
1236
|
+
saveExisting(entry.id, entry.name);
|
|
1237
|
+
},
|
|
1238
|
+
onCancel: () => {
|
|
1239
|
+
setNameError(false);
|
|
1240
|
+
setDraft(entry.id, { name: entry.name, value: entry.value });
|
|
1241
|
+
},
|
|
1242
|
+
onRestore: () => {
|
|
1243
|
+
void run(`row:${entry.id}`, () => restore(entry.id));
|
|
1244
|
+
},
|
|
1245
|
+
onRemove: () => {
|
|
1246
|
+
setPendingRemove({ id: entry.id, name: entry.name });
|
|
1247
|
+
},
|
|
1248
|
+
onMove: (groupId) => {
|
|
1249
|
+
void run(`row:${entry.id}`, () => moveEntry(entry.id, groupId));
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
)
|
|
1253
|
+
]
|
|
1254
|
+
},
|
|
1255
|
+
entry.id
|
|
1256
|
+
);
|
|
1257
|
+
};
|
|
1258
|
+
const renderPending = (id, groupId) => {
|
|
1259
|
+
const draft = drafts[id] ?? { name: "", value: "" };
|
|
1260
|
+
const loading = busyTarget === `pending:${id}`;
|
|
1261
|
+
const nextName = draft.name.trim();
|
|
1262
|
+
const canConfirm = NAME_OK2.test(nextName) && draft.value !== "" && !taken.has(nextName);
|
|
1263
|
+
const selected = selectedIds.has(id);
|
|
1264
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1265
|
+
"div",
|
|
1266
|
+
{
|
|
1267
|
+
className: EnvSettingsSection_default.row,
|
|
1268
|
+
"data-env-row": id,
|
|
1269
|
+
"data-selected": selected ? "true" : "false",
|
|
1270
|
+
"aria-selected": selected,
|
|
1271
|
+
onMouseDown: (event) => {
|
|
1272
|
+
onRowMouseDown(id, event);
|
|
1273
|
+
},
|
|
1274
|
+
children: [
|
|
1275
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1276
|
+
Field,
|
|
1277
|
+
{
|
|
1278
|
+
id: `env-name-${id}`,
|
|
1279
|
+
value: draft.name,
|
|
1280
|
+
disabled: busy,
|
|
1281
|
+
title: draft.name,
|
|
1282
|
+
invalid: nameError,
|
|
1283
|
+
label: t("field.name"),
|
|
1284
|
+
rowSelectGestures: true,
|
|
1285
|
+
onChange: (name) => {
|
|
1286
|
+
setNameError(false);
|
|
1287
|
+
setDraft(id, { name });
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
),
|
|
1291
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1292
|
+
Field,
|
|
1293
|
+
{
|
|
1294
|
+
id: `env-value-${id}`,
|
|
1295
|
+
value: draft.value,
|
|
1296
|
+
disabled: busy,
|
|
1297
|
+
title: draft.value,
|
|
1298
|
+
label: t("field.value"),
|
|
1299
|
+
rowSelectGestures: true,
|
|
1300
|
+
onChange: (value) => {
|
|
1301
|
+
setDraft(id, { value });
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
),
|
|
1305
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1306
|
+
RowActions,
|
|
1307
|
+
{
|
|
1308
|
+
t,
|
|
1309
|
+
busy,
|
|
1310
|
+
loading,
|
|
1311
|
+
dirty: true,
|
|
1312
|
+
canConfirm,
|
|
1313
|
+
showRemove: false,
|
|
1314
|
+
onConfirm: () => {
|
|
1315
|
+
savePending(id);
|
|
1316
|
+
},
|
|
1317
|
+
onCancel: () => {
|
|
1318
|
+
setNameError(false);
|
|
1319
|
+
dropPending(id);
|
|
1320
|
+
},
|
|
1321
|
+
onRestore: () => void 0,
|
|
1322
|
+
onRemove: () => void 0
|
|
1323
|
+
}
|
|
1324
|
+
)
|
|
1325
|
+
]
|
|
1326
|
+
},
|
|
1327
|
+
id
|
|
1328
|
+
);
|
|
1329
|
+
};
|
|
1330
|
+
const renderComposer = (groupId) => {
|
|
1331
|
+
const key = composerId(groupId);
|
|
1332
|
+
const composer = drafts[key] ?? { name: "", value: "" };
|
|
1333
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: EnvSettingsSection_default.row, "data-composer": "true", children: [
|
|
1334
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1335
|
+
Field,
|
|
1336
|
+
{
|
|
1337
|
+
id: `env-new-name-${groupId}`,
|
|
1338
|
+
value: composer.name,
|
|
1339
|
+
disabled: busy,
|
|
1340
|
+
placeholder: t("field.namePlaceholder"),
|
|
1341
|
+
title: composer.name || t("field.namePlaceholder"),
|
|
1342
|
+
label: t("field.name"),
|
|
1343
|
+
onChange: (name) => {
|
|
1344
|
+
typeIntoComposer(groupId, { name }, "name");
|
|
1345
|
+
},
|
|
1346
|
+
onPaste: (event) => {
|
|
1347
|
+
onComposerPaste(groupId, event);
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
),
|
|
1351
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1352
|
+
Field,
|
|
1353
|
+
{
|
|
1354
|
+
id: `env-new-value-${groupId}`,
|
|
1355
|
+
value: composer.value,
|
|
1356
|
+
disabled: busy,
|
|
1357
|
+
placeholder: t("field.valuePlaceholder"),
|
|
1358
|
+
title: composer.value || t("field.valuePlaceholder"),
|
|
1359
|
+
label: t("field.value"),
|
|
1360
|
+
onChange: (value) => {
|
|
1361
|
+
typeIntoComposer(groupId, { value }, "value");
|
|
1362
|
+
},
|
|
1363
|
+
onPaste: (event) => {
|
|
1364
|
+
onComposerPaste(groupId, event);
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
),
|
|
1368
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: EnvSettingsSection_default.actions, "aria-hidden": "true" })
|
|
1369
|
+
] });
|
|
1370
|
+
};
|
|
1061
1371
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: EnvSettingsSection_default.section, children: [
|
|
1062
1372
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: EnvSettingsSection_default.heading, children: t("panel.title") }),
|
|
1063
1373
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: EnvSettingsSection_default.cli, "aria-label": t("cli.title"), children: [
|
|
@@ -1097,197 +1407,83 @@ function EnvSettingsSection({
|
|
|
1097
1407
|
] })
|
|
1098
1408
|
] }),
|
|
1099
1409
|
notice !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: EnvSettingsSection_default.notice, "data-tone": error !== void 0 || nameError ? "error" : void 0, role: "status", children: notice }) : null,
|
|
1100
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
)
|
|
1180
|
-
]
|
|
1181
|
-
},
|
|
1182
|
-
entry.id
|
|
1183
|
-
);
|
|
1184
|
-
}),
|
|
1185
|
-
pendingOrder.map((id) => {
|
|
1186
|
-
const draft = drafts[id] ?? { name: "", value: "" };
|
|
1187
|
-
const loading = busyTarget === `pending:${id}`;
|
|
1188
|
-
const nextName = draft.name.trim();
|
|
1189
|
-
const canConfirm = NAME_OK2.test(nextName) && draft.value !== "" && !taken.has(nextName);
|
|
1190
|
-
const selected = selectedIds.has(id);
|
|
1191
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1192
|
-
"div",
|
|
1193
|
-
{
|
|
1194
|
-
className: EnvSettingsSection_default.row,
|
|
1195
|
-
"data-env-row": id,
|
|
1196
|
-
"data-selected": selected ? "true" : "false",
|
|
1197
|
-
"aria-selected": selected,
|
|
1198
|
-
onMouseDown: (event) => {
|
|
1199
|
-
onRowMouseDown(id, event);
|
|
1200
|
-
},
|
|
1201
|
-
children: [
|
|
1202
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1203
|
-
Field,
|
|
1204
|
-
{
|
|
1205
|
-
id: `env-name-${id}`,
|
|
1206
|
-
value: draft.name,
|
|
1207
|
-
disabled: busy,
|
|
1208
|
-
title: draft.name,
|
|
1209
|
-
invalid: nameError,
|
|
1210
|
-
label: t("field.name"),
|
|
1211
|
-
rowSelectGestures: true,
|
|
1212
|
-
onChange: (name) => {
|
|
1213
|
-
setNameError(false);
|
|
1214
|
-
setDraft(id, { name });
|
|
1215
|
-
}
|
|
1216
|
-
}
|
|
1217
|
-
),
|
|
1218
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1219
|
-
Field,
|
|
1220
|
-
{
|
|
1221
|
-
id: `env-value-${id}`,
|
|
1222
|
-
value: draft.value,
|
|
1223
|
-
disabled: busy,
|
|
1224
|
-
title: draft.value,
|
|
1225
|
-
label: t("field.value"),
|
|
1226
|
-
rowSelectGestures: true,
|
|
1227
|
-
onChange: (value) => {
|
|
1228
|
-
setDraft(id, { value });
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
),
|
|
1232
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1233
|
-
RowActions,
|
|
1234
|
-
{
|
|
1235
|
-
t,
|
|
1236
|
-
busy,
|
|
1237
|
-
loading,
|
|
1238
|
-
dirty: true,
|
|
1239
|
-
canConfirm,
|
|
1240
|
-
showRemove: false,
|
|
1241
|
-
onConfirm: () => {
|
|
1242
|
-
savePending(id);
|
|
1243
|
-
},
|
|
1244
|
-
onCancel: () => {
|
|
1245
|
-
setNameError(false);
|
|
1246
|
-
dropPending(id);
|
|
1247
|
-
},
|
|
1248
|
-
onRestore: () => void 0,
|
|
1249
|
-
onRemove: () => void 0
|
|
1250
|
-
}
|
|
1251
|
-
)
|
|
1252
|
-
]
|
|
1253
|
-
},
|
|
1254
|
-
id
|
|
1255
|
-
);
|
|
1256
|
-
}),
|
|
1257
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: EnvSettingsSection_default.row, "data-composer": "true", children: [
|
|
1258
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1259
|
-
Field,
|
|
1260
|
-
{
|
|
1261
|
-
id: "env-new-name",
|
|
1262
|
-
value: composer.name,
|
|
1263
|
-
disabled: busy,
|
|
1264
|
-
placeholder: t("field.namePlaceholder"),
|
|
1265
|
-
title: composer.name || t("field.namePlaceholder"),
|
|
1266
|
-
label: t("field.name"),
|
|
1267
|
-
onChange: (name) => {
|
|
1268
|
-
typeIntoComposer({ name }, "name");
|
|
1269
|
-
},
|
|
1270
|
-
onPaste: onComposerPaste
|
|
1271
|
-
}
|
|
1272
|
-
),
|
|
1273
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1274
|
-
Field,
|
|
1275
|
-
{
|
|
1276
|
-
id: "env-new-value",
|
|
1277
|
-
value: composer.value,
|
|
1278
|
-
disabled: busy,
|
|
1279
|
-
placeholder: t("field.valuePlaceholder"),
|
|
1280
|
-
title: composer.value || t("field.valuePlaceholder"),
|
|
1281
|
-
label: t("field.value"),
|
|
1282
|
-
onChange: (value) => {
|
|
1283
|
-
typeIntoComposer({ value }, "value");
|
|
1284
|
-
},
|
|
1285
|
-
onPaste: onComposerPaste
|
|
1286
|
-
}
|
|
1287
|
-
),
|
|
1288
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: EnvSettingsSection_default.actions, "aria-hidden": "true" })
|
|
1289
|
-
] })
|
|
1290
|
-
] }),
|
|
1410
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: EnvSettingsSection_default.groups, children: groups.map((group) => {
|
|
1411
|
+
const expanded = openGroups[group.id] === true;
|
|
1412
|
+
const groupEntries = grouped.saved.get(group.id) ?? [];
|
|
1413
|
+
const groupPending = grouped.pending.get(group.id) ?? [];
|
|
1414
|
+
const isDefault = group.id === DEFAULT_GROUP_ID;
|
|
1415
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: EnvSettingsSection_default.group, children: [
|
|
1416
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: EnvSettingsSection_default.groupTitleRow, children: [
|
|
1417
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1418
|
+
"button",
|
|
1419
|
+
{
|
|
1420
|
+
type: "button",
|
|
1421
|
+
className: EnvSettingsSection_default.groupToggle,
|
|
1422
|
+
"aria-expanded": expanded,
|
|
1423
|
+
onClick: () => {
|
|
1424
|
+
setOpenGroups((previous) => ({ ...previous, [group.id]: !expanded }));
|
|
1425
|
+
},
|
|
1426
|
+
children: [
|
|
1427
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconChevronDownOutlineRegular, { className: EnvSettingsSection_default.chevron, size: 12, "aria-hidden": "true" }),
|
|
1428
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: EnvSettingsSection_default.groupTitle, children: groupLabel(group) })
|
|
1429
|
+
]
|
|
1430
|
+
}
|
|
1431
|
+
),
|
|
1432
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: EnvSettingsSection_default.headerEnd, children: isDefault ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1433
|
+
IconAction,
|
|
1434
|
+
{
|
|
1435
|
+
label: t("action.createGroup"),
|
|
1436
|
+
disabled: busy,
|
|
1437
|
+
onClick: () => {
|
|
1438
|
+
setGroupTitleDraft("");
|
|
1439
|
+
setGroupModal({ kind: "create" });
|
|
1440
|
+
},
|
|
1441
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconPlusOutlineRegular, { size: 14 })
|
|
1442
|
+
}
|
|
1443
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1444
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1445
|
+
IconAction,
|
|
1446
|
+
{
|
|
1447
|
+
label: t("action.renameGroup"),
|
|
1448
|
+
disabled: busy,
|
|
1449
|
+
onClick: () => {
|
|
1450
|
+
setGroupTitleDraft(group.title);
|
|
1451
|
+
setGroupModal({ kind: "rename", id: group.id, title: group.title });
|
|
1452
|
+
},
|
|
1453
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconEditOutlineRegular, { size: 14 })
|
|
1454
|
+
}
|
|
1455
|
+
),
|
|
1456
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1457
|
+
IconAction,
|
|
1458
|
+
{
|
|
1459
|
+
label: t("action.deleteGroup"),
|
|
1460
|
+
danger: true,
|
|
1461
|
+
disabled: busy,
|
|
1462
|
+
onClick: () => {
|
|
1463
|
+
setGroupModal({
|
|
1464
|
+
kind: "delete",
|
|
1465
|
+
id: group.id,
|
|
1466
|
+
title: group.title,
|
|
1467
|
+
moveToDefault: true
|
|
1468
|
+
});
|
|
1469
|
+
},
|
|
1470
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconTrashOutlineRegular, { size: 14 })
|
|
1471
|
+
}
|
|
1472
|
+
)
|
|
1473
|
+
] }) })
|
|
1474
|
+
] }),
|
|
1475
|
+
expanded ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: EnvSettingsSection_default.groupBody, children: [
|
|
1476
|
+
isDefault ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: EnvSettingsSection_default.header, children: [
|
|
1477
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: EnvSettingsSection_default.headerLabel, children: t("field.name") }),
|
|
1478
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: EnvSettingsSection_default.headerLabel, children: t("field.value") }),
|
|
1479
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: EnvSettingsSection_default.headerActions, "aria-hidden": "true" })
|
|
1480
|
+
] }) : null,
|
|
1481
|
+
groupEntries.map((entry) => renderRow(entry)),
|
|
1482
|
+
groupPending.map((id) => renderPending(id, group.id)),
|
|
1483
|
+
renderComposer(group.id)
|
|
1484
|
+
] }) : null
|
|
1485
|
+
] }, group.id);
|
|
1486
|
+
}) }),
|
|
1291
1487
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1292
1488
|
import_dsh_client_ui_primitives.Modal,
|
|
1293
1489
|
{
|
|
@@ -1318,6 +1514,60 @@ function EnvSettingsSection({
|
|
|
1318
1514
|
)
|
|
1319
1515
|
] })
|
|
1320
1516
|
}
|
|
1517
|
+
),
|
|
1518
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1519
|
+
import_dsh_client_ui_primitives.Modal,
|
|
1520
|
+
{
|
|
1521
|
+
open: groupModal !== void 0,
|
|
1522
|
+
onClose: () => {
|
|
1523
|
+
if (!busy) setGroupModal(void 0);
|
|
1524
|
+
},
|
|
1525
|
+
title: groupModal?.kind === "create" ? t("action.createGroup") : groupModal?.kind === "rename" ? t("action.renameGroup") : t("action.deleteGroupTitle"),
|
|
1526
|
+
closeLabel: t("action.close"),
|
|
1527
|
+
description: groupModal?.kind === "delete" ? t("action.deleteGroupConfirm", { title: groupModal.title }) : void 0,
|
|
1528
|
+
footer: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1529
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "outline", disabled: busy, onClick: () => {
|
|
1530
|
+
setGroupModal(void 0);
|
|
1531
|
+
}, children: t("action.cancel") }),
|
|
1532
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1533
|
+
import_dsh_client_ui_primitives.Button,
|
|
1534
|
+
{
|
|
1535
|
+
variant: "primary",
|
|
1536
|
+
disabled: busy || (groupModal?.kind === "create" || groupModal?.kind === "rename") && groupTitleDraft.trim() === "",
|
|
1537
|
+
onClick: () => {
|
|
1538
|
+
submitGroupModal();
|
|
1539
|
+
},
|
|
1540
|
+
children: groupModal?.kind === "delete" ? t("action.deleteGroup") : t("action.confirm")
|
|
1541
|
+
}
|
|
1542
|
+
)
|
|
1543
|
+
] }),
|
|
1544
|
+
children: [
|
|
1545
|
+
groupModal?.kind === "create" || groupModal?.kind === "rename" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: EnvSettingsSection_default.modalField, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1546
|
+
import_dsh_client_ui_primitives.Input,
|
|
1547
|
+
{
|
|
1548
|
+
value: groupTitleDraft,
|
|
1549
|
+
placeholder: t("action.groupTitlePlaceholder"),
|
|
1550
|
+
"aria-label": t("action.groupTitle"),
|
|
1551
|
+
disabled: busy,
|
|
1552
|
+
onChange: (event) => {
|
|
1553
|
+
setGroupTitleDraft(event.target.value);
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
) }) : null,
|
|
1557
|
+
groupModal?.kind === "delete" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1558
|
+
import_dsh_client_ui_primitives.Checkbox,
|
|
1559
|
+
{
|
|
1560
|
+
className: EnvSettingsSection_default.modalCheck,
|
|
1561
|
+
checked: groupModal.moveToDefault,
|
|
1562
|
+
disabled: busy,
|
|
1563
|
+
label: t("action.deleteGroupMove"),
|
|
1564
|
+
onChange: (checked) => {
|
|
1565
|
+
setGroupModal({ ...groupModal, moveToDefault: checked });
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
) : null
|
|
1569
|
+
]
|
|
1570
|
+
}
|
|
1321
1571
|
)
|
|
1322
1572
|
] });
|
|
1323
1573
|
}
|
|
@@ -1327,7 +1577,6 @@ var NS = "settings.env";
|
|
|
1327
1577
|
var zh = {
|
|
1328
1578
|
"panel.nav": "\u73AF\u5883\u53D8\u91CF",
|
|
1329
1579
|
"panel.title": "\u73AF\u5883\u53D8\u91CF",
|
|
1330
|
-
"panel.empty": "\u6682\u65E0\u53D8\u91CF",
|
|
1331
1580
|
"panel.loading": "\u52A0\u8F7D\u4E2D\u2026",
|
|
1332
1581
|
"field.name": "\u540D\u79F0",
|
|
1333
1582
|
"field.value": "\u503C",
|
|
@@ -1341,6 +1590,16 @@ var zh = {
|
|
|
1341
1590
|
"action.removeConfirm": "\u5220\u9664 {name}\uFF1F",
|
|
1342
1591
|
"action.restore": "\u6062\u590D\u539F\u503C",
|
|
1343
1592
|
"action.close": "\u5173\u95ED",
|
|
1593
|
+
"action.moveGroup": "\u4FEE\u6539\u5206\u7EC4",
|
|
1594
|
+
"action.createGroup": "\u65B0\u5EFA\u5206\u7EC4",
|
|
1595
|
+
"action.renameGroup": "\u91CD\u547D\u540D\u5206\u7EC4",
|
|
1596
|
+
"action.deleteGroup": "\u5220\u9664\u5206\u7EC4",
|
|
1597
|
+
"action.deleteGroupTitle": "\u5220\u9664\u5206\u7EC4",
|
|
1598
|
+
"action.deleteGroupConfirm": "\u5220\u9664\u5206\u7EC4\u300C{title}\u300D\uFF1F",
|
|
1599
|
+
"action.deleteGroupMove": "\u53D8\u91CF\u79FB\u5165\u9ED8\u8BA4\u5206\u7EC4",
|
|
1600
|
+
"action.groupTitle": "\u5206\u7EC4\u540D\u79F0",
|
|
1601
|
+
"action.groupTitlePlaceholder": "\u5206\u7EC4\u540D\u79F0",
|
|
1602
|
+
"group.defaultTitle": "\u9ED8\u8BA4\u5206\u7EC4",
|
|
1344
1603
|
"status.restartRequired": "\u9700\u91CD\u542F\u5BA2\u6237\u7AEF",
|
|
1345
1604
|
"cli.title": "dsh",
|
|
1346
1605
|
"cli.activeMissing": "\u672A\u627E\u5230",
|
|
@@ -1349,6 +1608,7 @@ var zh = {
|
|
|
1349
1608
|
"error.generic": "\u66F4\u65B0\u5931\u8D25",
|
|
1350
1609
|
"error.invalidName": "\u540D\u79F0\u65E0\u6548",
|
|
1351
1610
|
"error.invalidValue": "\u503C\u65E0\u6548",
|
|
1611
|
+
"error.invalidGroup": "\u5206\u7EC4\u65E0\u6548",
|
|
1352
1612
|
"error.restoreFailed": "\u6062\u590D\u5931\u8D25",
|
|
1353
1613
|
"error.cliInstall": "\u5B89\u88C5\u5931\u8D25",
|
|
1354
1614
|
"error.cliUnresolved": "\u65E0\u6CD5\u5B89\u88C5",
|
|
@@ -1357,7 +1617,6 @@ var zh = {
|
|
|
1357
1617
|
var en = {
|
|
1358
1618
|
"panel.nav": "Environment",
|
|
1359
1619
|
"panel.title": "Environment",
|
|
1360
|
-
"panel.empty": "No variables",
|
|
1361
1620
|
"panel.loading": "Loading\u2026",
|
|
1362
1621
|
"field.name": "Name",
|
|
1363
1622
|
"field.value": "Value",
|
|
@@ -1371,6 +1630,16 @@ var en = {
|
|
|
1371
1630
|
"action.removeConfirm": "Delete {name}?",
|
|
1372
1631
|
"action.restore": "Restore original",
|
|
1373
1632
|
"action.close": "Close",
|
|
1633
|
+
"action.moveGroup": "Move to group",
|
|
1634
|
+
"action.createGroup": "New group",
|
|
1635
|
+
"action.renameGroup": "Rename group",
|
|
1636
|
+
"action.deleteGroup": "Delete group",
|
|
1637
|
+
"action.deleteGroupTitle": "Delete group",
|
|
1638
|
+
"action.deleteGroupConfirm": 'Delete group "{title}"?',
|
|
1639
|
+
"action.deleteGroupMove": "Move variables into Default",
|
|
1640
|
+
"action.groupTitle": "Group name",
|
|
1641
|
+
"action.groupTitlePlaceholder": "Group name",
|
|
1642
|
+
"group.defaultTitle": "Default",
|
|
1374
1643
|
"status.restartRequired": "Restart the client",
|
|
1375
1644
|
"cli.title": "dsh",
|
|
1376
1645
|
"cli.activeMissing": "Not found",
|
|
@@ -1379,6 +1648,7 @@ var en = {
|
|
|
1379
1648
|
"error.generic": "Update failed",
|
|
1380
1649
|
"error.invalidName": "Invalid name",
|
|
1381
1650
|
"error.invalidValue": "Invalid value",
|
|
1651
|
+
"error.invalidGroup": "Invalid group",
|
|
1382
1652
|
"error.restoreFailed": "Restore failed",
|
|
1383
1653
|
"error.cliInstall": "Install failed",
|
|
1384
1654
|
"error.cliUnresolved": "Install unavailable",
|
|
@@ -1402,9 +1672,13 @@ function registerUi(ctx) {
|
|
|
1402
1672
|
locale: NS,
|
|
1403
1673
|
inject: () => ({
|
|
1404
1674
|
load: async () => call(await ctx.remote.customEnv.list()),
|
|
1405
|
-
upsert: async (id, name, value) => call(await ctx.remote.customEnv.upsert(id, name, value)),
|
|
1675
|
+
upsert: async (id, name, value, groupId) => call(await ctx.remote.customEnv.upsert(id, name, value, groupId)),
|
|
1406
1676
|
remove: async (id) => call(await ctx.remote.customEnv.deleteEntry(id)),
|
|
1407
1677
|
restore: async (id) => call(await ctx.remote.customEnv.restore(id)),
|
|
1678
|
+
moveEntry: async (id, groupId) => call(await ctx.remote.customEnv.moveEntry(id, groupId)),
|
|
1679
|
+
createGroup: async (title) => call(await ctx.remote.customEnv.createGroup(title)),
|
|
1680
|
+
renameGroup: async (id, title) => call(await ctx.remote.customEnv.renameGroup(id, title)),
|
|
1681
|
+
deleteGroup: async (id, moveToDefault) => call(await ctx.remote.customEnv.deleteGroup(id, { moveToDefault })),
|
|
1408
1682
|
cliStatus: async () => call(await ctx.remote.customEnv.cliStatus()),
|
|
1409
1683
|
cliInstall: async () => call(await ctx.remote.customEnv.cliInstall())
|
|
1410
1684
|
})
|