@focus8/settings-registry 0.8.3 → 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +44 -31
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +327 -132
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +442 -183
package/src/index.ts
CHANGED
|
@@ -34,8 +34,8 @@ export type LocaleCode = 'en' | 'nb';
|
|
|
34
34
|
export type CalendarType = 'chronological' | 'time-based';
|
|
35
35
|
export type ClockType = 'digital' | 'analog';
|
|
36
36
|
export type TimePickerMode = 'dials' | 'keypad';
|
|
37
|
-
export type AlarmTimeout =
|
|
38
|
-
export const ALARM_TIMEOUTS: AlarmTimeout[] = [
|
|
37
|
+
export type AlarmTimeout = 5 | 30 | 60 | 120 | 180 | 300 | 600;
|
|
38
|
+
export const ALARM_TIMEOUTS: AlarmTimeout[] = [5, 30, 60, 120, 180, 300, 600];
|
|
39
39
|
export type CalendarViewMode =
|
|
40
40
|
| 'day'
|
|
41
41
|
| '3-days'
|
|
@@ -103,6 +103,7 @@ export type SettingUiType =
|
|
|
103
103
|
| 'CUSTOM_DISPLAY_DENSITY'
|
|
104
104
|
| 'CUSTOM_BRIGHTNESS'
|
|
105
105
|
| 'CUSTOM_SPLIT_VIEW_CONFIG'
|
|
106
|
+
| 'CUSTOM_EVENT_CATEGORIES'
|
|
106
107
|
| 'HIDDEN';
|
|
107
108
|
|
|
108
109
|
export type SettingOption<T = unknown> = {
|
|
@@ -110,6 +111,8 @@ export type SettingOption<T = unknown> = {
|
|
|
110
111
|
value: T;
|
|
111
112
|
/** i18n message key for the option label */
|
|
112
113
|
labelKey: string;
|
|
114
|
+
/** Optional values to pass to the i18n message formatter */
|
|
115
|
+
labelValues?: Record<string, unknown>;
|
|
113
116
|
};
|
|
114
117
|
|
|
115
118
|
export type SliderConfig = {
|
|
@@ -220,76 +223,149 @@ export function getCategoriesForCalendarType(
|
|
|
220
223
|
}
|
|
221
224
|
|
|
222
225
|
// ---------------------------------------------------------------------------
|
|
223
|
-
// Settings
|
|
226
|
+
// Settings sections — top-level groupings (e.g. "Kalender", "Enhet")
|
|
224
227
|
// ---------------------------------------------------------------------------
|
|
225
228
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
229
|
+
export const SETTINGS_SECTION_IDS = ['calendar', 'unit'] as const;
|
|
230
|
+
export type SettingsSectionId = (typeof SETTINGS_SECTION_IDS)[number];
|
|
231
|
+
|
|
232
|
+
export type SettingsSectionDef = {
|
|
233
|
+
id: SettingsSectionId;
|
|
234
|
+
labelKey: string;
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
export const SETTINGS_SECTIONS: readonly SettingsSectionDef[] = [
|
|
238
|
+
{ id: 'calendar', labelKey: 'Calendar.LabelCalendar' },
|
|
239
|
+
{ id: 'unit', labelKey: 'Settings.Unit' },
|
|
240
|
+
];
|
|
241
|
+
|
|
242
|
+
// ---------------------------------------------------------------------------
|
|
243
|
+
// Settings menu items — ordered list of all items in the settings menu
|
|
244
|
+
// ---------------------------------------------------------------------------
|
|
245
|
+
|
|
246
|
+
export const SETTINGS_MENU_ITEM_IDS = [
|
|
232
247
|
// Calendar section
|
|
233
248
|
'calendarView',
|
|
249
|
+
'calendars',
|
|
250
|
+
'eventCategories',
|
|
251
|
+
'notification',
|
|
234
252
|
'timer',
|
|
235
|
-
'
|
|
236
|
-
'
|
|
237
|
-
'
|
|
253
|
+
'guests',
|
|
254
|
+
'eventForm',
|
|
255
|
+
'chronologicalEventForm',
|
|
256
|
+
'weather',
|
|
257
|
+
'gallery',
|
|
258
|
+
'audioClips',
|
|
259
|
+
'gestures',
|
|
238
260
|
'calendarType',
|
|
239
|
-
'
|
|
261
|
+
'sharing',
|
|
240
262
|
// Unit section
|
|
241
|
-
'
|
|
242
|
-
'
|
|
263
|
+
'screen',
|
|
264
|
+
'volume',
|
|
243
265
|
'lockScreen',
|
|
244
266
|
'language',
|
|
245
|
-
'
|
|
267
|
+
'wifi',
|
|
268
|
+
'devices',
|
|
269
|
+
'profiles',
|
|
270
|
+
'tts',
|
|
271
|
+
'updates',
|
|
272
|
+
'about',
|
|
273
|
+
'help',
|
|
274
|
+
'dev',
|
|
275
|
+
// Account (rendered separately)
|
|
276
|
+
'account',
|
|
277
|
+
'activityLog',
|
|
246
278
|
] as const;
|
|
247
279
|
|
|
248
|
-
export type
|
|
280
|
+
export type SettingsMenuItemId = (typeof SETTINGS_MENU_ITEM_IDS)[number];
|
|
249
281
|
|
|
250
|
-
export type
|
|
251
|
-
|
|
252
|
-
id: SettingsGroupId;
|
|
253
|
-
/** i18n message key for the group label */
|
|
282
|
+
export type SettingsMenuItemDef = {
|
|
283
|
+
id: SettingsMenuItemId;
|
|
254
284
|
labelKey: string;
|
|
255
|
-
/** Lucide icon name */
|
|
256
285
|
icon: string;
|
|
286
|
+
section: SettingsSectionId | 'account';
|
|
287
|
+
/** Screen/page identifiers rendered for this menu item */
|
|
288
|
+
screens: string[];
|
|
257
289
|
/**
|
|
258
|
-
* Setting key matchers
|
|
259
|
-
*
|
|
260
|
-
*
|
|
290
|
+
* Setting key matchers for remote editing (web portal / profile editor).
|
|
291
|
+
* A setting is included if its key equals a matcher exactly, or starts
|
|
292
|
+
* with a matcher that ends with '.' (prefix match).
|
|
293
|
+
* Items without keys are navigation-only (e.g. gallery, guests).
|
|
261
294
|
*/
|
|
262
|
-
keys
|
|
295
|
+
keys?: string[];
|
|
263
296
|
/** Only show for this calendar type (undefined = always) */
|
|
264
297
|
calendarType?: CalendarType;
|
|
265
298
|
/** Only show for this app mode (undefined = always) */
|
|
266
299
|
appMode?: 'ENROLLED';
|
|
300
|
+
/** If true, don't wrap content in a scroll container */
|
|
301
|
+
noScrollView?: boolean;
|
|
267
302
|
};
|
|
268
303
|
|
|
269
304
|
/**
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
* in every consumer's i18n catalog.
|
|
305
|
+
* Ordered list of all settings menu items. The array order defines the
|
|
306
|
+
* display order within each section. Items without registry setting keys
|
|
307
|
+
* are navigation-only (e.g. gallery, guests).
|
|
274
308
|
*/
|
|
275
|
-
export const
|
|
276
|
-
//
|
|
309
|
+
export const SETTINGS_MENU_ITEMS: readonly SettingsMenuItemDef[] = [
|
|
310
|
+
// -- Calendar section --
|
|
277
311
|
{
|
|
278
312
|
id: 'calendarView',
|
|
279
|
-
labelKey: 'Settings.
|
|
313
|
+
labelKey: 'Settings.Calendar',
|
|
280
314
|
icon: 'Eye',
|
|
315
|
+
section: 'calendar',
|
|
316
|
+
screens: [
|
|
317
|
+
'calendarDayView',
|
|
318
|
+
'calendarWeekView',
|
|
319
|
+
'chronologicalHeader',
|
|
320
|
+
'chronologicalFooter',
|
|
321
|
+
'chronologicalMenu',
|
|
322
|
+
'dayColors',
|
|
323
|
+
'dateTime',
|
|
324
|
+
],
|
|
281
325
|
keys: [
|
|
282
326
|
'calendarView.showCalendarNames',
|
|
283
327
|
'calendarView.splitView',
|
|
284
328
|
'calendarView.dayViewZoom',
|
|
285
329
|
'calendarView.weekViewZoom',
|
|
286
330
|
'calendarView.calendarColumns',
|
|
331
|
+
'appearance.enableDayColors',
|
|
332
|
+
],
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
id: 'calendars',
|
|
336
|
+
labelKey: 'Common.Calendars',
|
|
337
|
+
icon: 'Calendar',
|
|
338
|
+
section: 'calendar',
|
|
339
|
+
screens: ['calendars'],
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
id: 'eventCategories',
|
|
343
|
+
labelKey: 'EventCategory.SettingsTitle',
|
|
344
|
+
icon: 'Tag',
|
|
345
|
+
section: 'calendar',
|
|
346
|
+
screens: ['eventCategories'],
|
|
347
|
+
calendarType: 'chronological',
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
id: 'notification',
|
|
351
|
+
labelKey: 'Settings.Notification',
|
|
352
|
+
icon: 'Bell',
|
|
353
|
+
section: 'calendar',
|
|
354
|
+
screens: ['notification'],
|
|
355
|
+
keys: [
|
|
356
|
+
'sound.reminderAlarmSound',
|
|
357
|
+
'sound.reminderAlarmTimeout',
|
|
358
|
+
'sound.reminderVolume',
|
|
359
|
+
'sound.allowCustomReminderSounds',
|
|
287
360
|
],
|
|
288
361
|
},
|
|
289
362
|
{
|
|
290
363
|
id: 'timer',
|
|
291
364
|
labelKey: 'Settings.TimerTitle',
|
|
292
365
|
icon: 'Timer',
|
|
366
|
+
section: 'calendar',
|
|
367
|
+
screens: ['timerFeatures', 'timer'],
|
|
368
|
+
appMode: 'ENROLLED',
|
|
293
369
|
keys: [
|
|
294
370
|
'chronological.timer.',
|
|
295
371
|
'timer.',
|
|
@@ -297,18 +373,39 @@ export const SETTINGS_GROUPS: readonly SettingsGroupDef[] = [
|
|
|
297
373
|
'sound.timerAlarmTimeout',
|
|
298
374
|
'sound.timerVolume',
|
|
299
375
|
],
|
|
300
|
-
appMode: 'ENROLLED',
|
|
301
376
|
},
|
|
302
377
|
{
|
|
303
|
-
id: '
|
|
304
|
-
labelKey: 'Settings.
|
|
305
|
-
icon: '
|
|
306
|
-
|
|
378
|
+
id: 'guests',
|
|
379
|
+
labelKey: 'Settings.GuestUsers',
|
|
380
|
+
icon: 'Users',
|
|
381
|
+
section: 'calendar',
|
|
382
|
+
screens: ['guests'],
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
id: 'eventForm',
|
|
386
|
+
labelKey: 'SettingsEventForm.Title',
|
|
387
|
+
icon: 'ClipboardList',
|
|
388
|
+
section: 'calendar',
|
|
389
|
+
screens: ['eventForm'],
|
|
390
|
+
calendarType: 'time-based',
|
|
391
|
+
keys: ['eventForm.'],
|
|
307
392
|
},
|
|
308
393
|
{
|
|
309
|
-
id: '
|
|
310
|
-
labelKey: '
|
|
394
|
+
id: 'chronologicalEventForm',
|
|
395
|
+
labelKey: 'SettingsChronologicalEventForm.Title',
|
|
396
|
+
icon: 'Plus',
|
|
397
|
+
section: 'calendar',
|
|
398
|
+
screens: ['chronologicalEventForm'],
|
|
399
|
+
calendarType: 'chronological',
|
|
400
|
+
keys: ['chronologicalEventForm.'],
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
id: 'weather',
|
|
404
|
+
labelKey: 'Settings.WeatherTitle',
|
|
311
405
|
icon: 'CloudSun',
|
|
406
|
+
section: 'calendar',
|
|
407
|
+
screens: ['weather'],
|
|
408
|
+
calendarType: 'time-based',
|
|
312
409
|
keys: [
|
|
313
410
|
'calendarView.showWeatherOnTimeline',
|
|
314
411
|
'calendarView.weatherLocation',
|
|
@@ -316,48 +413,64 @@ export const SETTINGS_GROUPS: readonly SettingsGroupDef[] = [
|
|
|
316
413
|
],
|
|
317
414
|
},
|
|
318
415
|
{
|
|
319
|
-
id: '
|
|
416
|
+
id: 'gallery',
|
|
417
|
+
labelKey: 'Gallery.Title',
|
|
418
|
+
icon: 'Images',
|
|
419
|
+
section: 'calendar',
|
|
420
|
+
screens: ['gallery'],
|
|
421
|
+
noScrollView: true,
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
id: 'audioClips',
|
|
425
|
+
labelKey: 'AudioClips.Title',
|
|
426
|
+
icon: 'AudioLines',
|
|
427
|
+
section: 'calendar',
|
|
428
|
+
screens: ['audioClips'],
|
|
429
|
+
noScrollView: true,
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
id: 'gestures',
|
|
320
433
|
labelKey: 'Settings.FunctionsTitle',
|
|
321
434
|
icon: 'Hand',
|
|
435
|
+
section: 'calendar',
|
|
436
|
+
screens: ['gestures'],
|
|
322
437
|
keys: ['touch.'],
|
|
323
438
|
},
|
|
324
439
|
{
|
|
325
440
|
id: 'calendarType',
|
|
326
|
-
labelKey: 'Settings.
|
|
327
|
-
icon: '
|
|
441
|
+
labelKey: 'Settings.Mode',
|
|
442
|
+
icon: 'SlidersHorizontal',
|
|
443
|
+
section: 'calendar',
|
|
444
|
+
screens: ['calendarType'],
|
|
328
445
|
keys: ['calendarView.type'],
|
|
329
446
|
},
|
|
330
447
|
{
|
|
331
|
-
id: '
|
|
332
|
-
labelKey: 'Settings.
|
|
333
|
-
icon: '
|
|
334
|
-
|
|
335
|
-
|
|
448
|
+
id: 'sharing',
|
|
449
|
+
labelKey: 'Settings.Sharing',
|
|
450
|
+
icon: 'Share2',
|
|
451
|
+
section: 'calendar',
|
|
452
|
+
screens: ['icalSubscriptions'],
|
|
336
453
|
},
|
|
337
|
-
//
|
|
454
|
+
// -- Unit section --
|
|
338
455
|
{
|
|
339
|
-
id: '
|
|
340
|
-
labelKey: 'Settings.
|
|
341
|
-
icon: '
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
'appearance.enableDayColors',
|
|
346
|
-
],
|
|
456
|
+
id: 'screen',
|
|
457
|
+
labelKey: 'Settings.Screen',
|
|
458
|
+
icon: 'LaptopMinimal',
|
|
459
|
+
section: 'unit',
|
|
460
|
+
screens: ['displayDensity', 'darkMode'],
|
|
461
|
+
keys: ['appearance.theme', 'appearance.clockType'],
|
|
347
462
|
},
|
|
348
463
|
{
|
|
349
|
-
id: '
|
|
350
|
-
labelKey: '
|
|
464
|
+
id: 'volume',
|
|
465
|
+
labelKey: 'Common.Volume',
|
|
351
466
|
icon: 'Volume2',
|
|
467
|
+
section: 'unit',
|
|
468
|
+
screens: ['volume'],
|
|
469
|
+
appMode: 'ENROLLED',
|
|
352
470
|
keys: [
|
|
353
|
-
'sound.reminderVolume',
|
|
354
471
|
'sound.mediaVolume',
|
|
355
|
-
'sound.reminderAlarmSound',
|
|
356
472
|
'sound.startAlarmSound',
|
|
357
473
|
'sound.endAlarmSound',
|
|
358
|
-
'sound.reminderAlarmTimeout',
|
|
359
|
-
'sound.allowCustomReminderSounds',
|
|
360
|
-
'notification.',
|
|
361
474
|
'sound.ttsEnabled',
|
|
362
475
|
'sound.ttsRate',
|
|
363
476
|
'sound.alarmSound',
|
|
@@ -367,26 +480,106 @@ export const SETTINGS_GROUPS: readonly SettingsGroupDef[] = [
|
|
|
367
480
|
id: 'lockScreen',
|
|
368
481
|
labelKey: 'Settings.LockScreen',
|
|
369
482
|
icon: 'Lock',
|
|
370
|
-
|
|
483
|
+
section: 'unit',
|
|
484
|
+
screens: ['inactivity', 'lockScreen'],
|
|
371
485
|
appMode: 'ENROLLED',
|
|
486
|
+
keys: ['lockScreen.'],
|
|
372
487
|
},
|
|
373
488
|
{
|
|
374
489
|
id: 'language',
|
|
375
490
|
labelKey: 'Settings.Language',
|
|
376
491
|
icon: 'Globe',
|
|
492
|
+
section: 'unit',
|
|
493
|
+
screens: ['language'],
|
|
377
494
|
keys: ['language.'],
|
|
378
495
|
},
|
|
379
496
|
{
|
|
380
|
-
id: '
|
|
497
|
+
id: 'wifi',
|
|
498
|
+
labelKey: 'Settings.WifiTitle',
|
|
499
|
+
icon: 'Wifi',
|
|
500
|
+
section: 'unit',
|
|
501
|
+
screens: ['wifi'],
|
|
502
|
+
appMode: 'ENROLLED',
|
|
503
|
+
},
|
|
504
|
+
{
|
|
505
|
+
id: 'devices',
|
|
381
506
|
labelKey: 'SettingsDevices.Title',
|
|
382
507
|
icon: 'Smartphone',
|
|
508
|
+
section: 'unit',
|
|
509
|
+
screens: ['devices'],
|
|
383
510
|
keys: [
|
|
384
511
|
'device.',
|
|
385
512
|
'calendarView.autoReturnToTodayEnabled',
|
|
386
513
|
'calendarView.autoReturnToTodayTimeoutSeconds',
|
|
387
514
|
],
|
|
388
515
|
},
|
|
389
|
-
|
|
516
|
+
{
|
|
517
|
+
id: 'profiles',
|
|
518
|
+
labelKey: 'SettingsProfiles.Title',
|
|
519
|
+
icon: 'BookCopy',
|
|
520
|
+
section: 'unit',
|
|
521
|
+
screens: ['profiles'],
|
|
522
|
+
},
|
|
523
|
+
{
|
|
524
|
+
id: 'tts',
|
|
525
|
+
labelKey: 'Settings.TtsTitle',
|
|
526
|
+
icon: 'Speech',
|
|
527
|
+
section: 'unit',
|
|
528
|
+
screens: ['tts'],
|
|
529
|
+
},
|
|
530
|
+
{
|
|
531
|
+
id: 'updates',
|
|
532
|
+
labelKey: 'Settings.UpdatesTitle',
|
|
533
|
+
icon: 'Download',
|
|
534
|
+
section: 'unit',
|
|
535
|
+
screens: ['updates'],
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
id: 'about',
|
|
539
|
+
labelKey: 'Settings.About',
|
|
540
|
+
icon: 'Info',
|
|
541
|
+
section: 'unit',
|
|
542
|
+
screens: ['restoreDefaults', 'recycleAppData', 'license', 'version'],
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
id: 'help',
|
|
546
|
+
labelKey: 'Settings.HelpTitle',
|
|
547
|
+
icon: 'CircleQuestionMark',
|
|
548
|
+
section: 'unit',
|
|
549
|
+
screens: ['help'],
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
id: 'dev',
|
|
553
|
+
labelKey: 'Settings.Dev',
|
|
554
|
+
icon: 'FolderCode',
|
|
555
|
+
section: 'unit',
|
|
556
|
+
screens: [
|
|
557
|
+
'devDeviceInfo',
|
|
558
|
+
'devComponents',
|
|
559
|
+
'devStores',
|
|
560
|
+
'devActions',
|
|
561
|
+
'devAuth',
|
|
562
|
+
'devNavigation',
|
|
563
|
+
'devNetwork',
|
|
564
|
+
'devAndroidSettings',
|
|
565
|
+
],
|
|
566
|
+
},
|
|
567
|
+
// -- Account (rendered separately) --
|
|
568
|
+
{
|
|
569
|
+
id: 'account',
|
|
570
|
+
labelKey: 'Settings.Profile',
|
|
571
|
+
icon: 'User',
|
|
572
|
+
section: 'account',
|
|
573
|
+
screens: ['account', 'mfa'],
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
id: 'activityLog',
|
|
577
|
+
labelKey: 'SettingsActivityLog.Title',
|
|
578
|
+
icon: 'ScrollText',
|
|
579
|
+
section: 'account',
|
|
580
|
+
screens: ['activityLog'],
|
|
581
|
+
},
|
|
582
|
+
];
|
|
390
583
|
|
|
391
584
|
/**
|
|
392
585
|
* Settings excluded from remote editing (web portal / profile management).
|
|
@@ -645,19 +838,16 @@ export const SETTINGS_LABELS: Readonly<Record<string, SettingLabelDef>> = {
|
|
|
645
838
|
'eventForm.checklist': { labelKey: 'EventChecklist.DefaultName' },
|
|
646
839
|
'eventForm.images': { labelKey: 'EventImageGallery.SectionTitle' },
|
|
647
840
|
'eventForm.audioClips': { labelKey: 'EventAudioGallery.SectionTitle' },
|
|
648
|
-
'eventForm.notificationReceivers': {
|
|
841
|
+
'eventForm.notificationReceivers': {
|
|
842
|
+
labelKey: 'EventForm.NotificationReceivers',
|
|
843
|
+
},
|
|
649
844
|
'eventForm.visibility': { labelKey: 'EventVisibility.Title' },
|
|
650
|
-
};
|
|
651
845
|
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
(matcher) =>
|
|
658
|
-
key === matcher || (matcher.endsWith('.') && key.startsWith(matcher)),
|
|
659
|
-
);
|
|
660
|
-
}
|
|
846
|
+
// ── Chronological event form ────────────────────────────────────────────
|
|
847
|
+
'chronologicalEventForm.field.category': {
|
|
848
|
+
labelKey: 'ChronologicalEventForm.CategoryField',
|
|
849
|
+
},
|
|
850
|
+
};
|
|
661
851
|
|
|
662
852
|
/** Return the index of the first matching key pattern in the group, for sorting. */
|
|
663
853
|
function groupKeyIndex(key: string, keys: readonly string[]): number {
|
|
@@ -687,78 +877,72 @@ function registryKeyOrder(): Map<string, number> {
|
|
|
687
877
|
}
|
|
688
878
|
|
|
689
879
|
/**
|
|
690
|
-
* Group parsed setting entries
|
|
691
|
-
*
|
|
692
|
-
*
|
|
693
|
-
*
|
|
694
|
-
* buckets them into the standard groups, filtering by calendar type and
|
|
695
|
-
* excluded keys.
|
|
880
|
+
* Group parsed setting entries using the app's menu structure (SETTINGS_MENU_ITEMS).
|
|
881
|
+
* Only includes menu items that have `keys` defined (editable settings).
|
|
882
|
+
* This ensures the web editor has the exact same menu items, order, sections,
|
|
883
|
+
* labels, and icons as the mobile app.
|
|
696
884
|
*/
|
|
697
|
-
export function
|
|
885
|
+
export function groupSettingsForWeb(
|
|
698
886
|
allSettings: ParsedSettingEntry[],
|
|
699
887
|
calendarType: CalendarType,
|
|
700
888
|
appMode?: 'ENROLLED',
|
|
701
|
-
): {
|
|
889
|
+
): {
|
|
890
|
+
id: SettingsMenuItemId;
|
|
891
|
+
labelKey: string;
|
|
892
|
+
icon: string;
|
|
893
|
+
section: SettingsSectionId | 'account';
|
|
894
|
+
settings: ParsedSettingEntry[];
|
|
895
|
+
}[] {
|
|
702
896
|
// Filter excluded and hidden settings
|
|
703
897
|
const settings = allSettings.filter(
|
|
704
898
|
(s) => !EXCLUDED_DEVICE_SETTINGS.has(s.key) && s.uiType !== 'HIDDEN',
|
|
705
899
|
);
|
|
706
900
|
|
|
707
|
-
// Calendar type filtering for event form keys
|
|
708
901
|
const isChronological = calendarType === 'chronological';
|
|
709
902
|
const filteredSettings = settings.filter((s) => {
|
|
710
|
-
if (isChronological && s.key.startsWith('eventForm.'))
|
|
903
|
+
if (isChronological && s.key.startsWith('eventForm.')) return false;
|
|
904
|
+
if (!isChronological && s.key.startsWith('chronologicalEventForm.'))
|
|
711
905
|
return false;
|
|
712
|
-
|
|
713
|
-
if (
|
|
714
|
-
return false;
|
|
715
|
-
}
|
|
716
|
-
// Per-setting calendar type restriction
|
|
717
|
-
if (s.calendarType && s.calendarType !== calendarType) {
|
|
718
|
-
return false;
|
|
719
|
-
}
|
|
720
|
-
// Per-setting app mode restriction
|
|
721
|
-
if (s.appMode && s.appMode !== appMode) {
|
|
722
|
-
return false;
|
|
723
|
-
}
|
|
906
|
+
if (s.calendarType && s.calendarType !== calendarType) return false;
|
|
907
|
+
if (s.appMode && s.appMode !== appMode) return false;
|
|
724
908
|
return true;
|
|
725
909
|
});
|
|
726
910
|
|
|
727
911
|
const claimed = new Set<string>();
|
|
728
912
|
const result: {
|
|
729
|
-
id:
|
|
913
|
+
id: SettingsMenuItemId;
|
|
730
914
|
labelKey: string;
|
|
731
915
|
icon: string;
|
|
916
|
+
section: SettingsSectionId | 'account';
|
|
732
917
|
settings: ParsedSettingEntry[];
|
|
733
918
|
}[] = [];
|
|
734
919
|
|
|
735
|
-
for (const
|
|
736
|
-
// Skip
|
|
737
|
-
if (
|
|
738
|
-
continue;
|
|
739
|
-
}
|
|
920
|
+
for (const menuItem of SETTINGS_MENU_ITEMS) {
|
|
921
|
+
// Skip items without keys (navigation-only like gallery, guests, etc.)
|
|
922
|
+
if (!menuItem.keys || menuItem.keys.length === 0) continue;
|
|
740
923
|
|
|
741
|
-
// Skip
|
|
742
|
-
if (
|
|
924
|
+
// Skip items not relevant for current calendar type
|
|
925
|
+
if (menuItem.calendarType && menuItem.calendarType !== calendarType)
|
|
743
926
|
continue;
|
|
744
|
-
}
|
|
745
927
|
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
);
|
|
749
|
-
if (matched.length === 0) {
|
|
750
|
-
continue;
|
|
751
|
-
}
|
|
928
|
+
// Skip items not relevant for current app mode
|
|
929
|
+
if (menuItem.appMode && menuItem.appMode !== appMode) continue;
|
|
752
930
|
|
|
753
|
-
|
|
754
|
-
|
|
931
|
+
const matched = filteredSettings.filter((s) => {
|
|
932
|
+
if (claimed.has(s.key)) return false;
|
|
933
|
+
return menuItem.keys!.some((k) =>
|
|
934
|
+
k.endsWith('.') ? s.key.startsWith(k) : s.key === k,
|
|
935
|
+
);
|
|
936
|
+
});
|
|
937
|
+
|
|
938
|
+
if (matched.length === 0) continue;
|
|
939
|
+
|
|
940
|
+
// Sort by key order within the menu item's keys array
|
|
755
941
|
const order = registryKeyOrder();
|
|
756
942
|
matched.sort((a, b) => {
|
|
757
|
-
const aIdx = groupKeyIndex(a.key,
|
|
758
|
-
const bIdx = groupKeyIndex(b.key,
|
|
759
|
-
if (aIdx !== bIdx)
|
|
760
|
-
return aIdx - bIdx;
|
|
761
|
-
}
|
|
943
|
+
const aIdx = groupKeyIndex(a.key, menuItem.keys!);
|
|
944
|
+
const bIdx = groupKeyIndex(b.key, menuItem.keys!);
|
|
945
|
+
if (aIdx !== bIdx) return aIdx - bIdx;
|
|
762
946
|
return (order.get(a.key) ?? Infinity) - (order.get(b.key) ?? Infinity);
|
|
763
947
|
});
|
|
764
948
|
|
|
@@ -767,9 +951,10 @@ export function groupSettingsForDevice(
|
|
|
767
951
|
}
|
|
768
952
|
|
|
769
953
|
result.push({
|
|
770
|
-
id:
|
|
771
|
-
labelKey:
|
|
772
|
-
icon:
|
|
954
|
+
id: menuItem.id,
|
|
955
|
+
labelKey: menuItem.labelKey,
|
|
956
|
+
icon: menuItem.icon,
|
|
957
|
+
section: menuItem.section,
|
|
773
958
|
settings: matched,
|
|
774
959
|
});
|
|
775
960
|
}
|
|
@@ -830,31 +1015,34 @@ export const DEFAULT_REGISTRY_CONFIG: RegistryConfig = {
|
|
|
830
1015
|
// ---------------------------------------------------------------------------
|
|
831
1016
|
|
|
832
1017
|
const ALARM_SOUND_OPTIONS: readonly SettingOption<AlarmSound>[] = [
|
|
833
|
-
{ value: 'none', labelKey: '
|
|
834
|
-
{ value: 'alarm1', labelKey: '
|
|
835
|
-
{ value: 'alarm2', labelKey: '
|
|
836
|
-
{ value: 'alarm3', labelKey: '
|
|
837
|
-
{ value: 'alarm4', labelKey: '
|
|
838
|
-
{ value: 'alarm5', labelKey: '
|
|
839
|
-
{ value: 'alarm6', labelKey: '
|
|
840
|
-
{ value: 'alarm7', labelKey: '
|
|
841
|
-
{ value: 'alarm8', labelKey: '
|
|
842
|
-
{ value: 'alarm9', labelKey: '
|
|
1018
|
+
{ value: 'none', labelKey: 'AlarmAsset.none' },
|
|
1019
|
+
{ value: 'alarm1', labelKey: 'AlarmAsset.alarm1' },
|
|
1020
|
+
{ value: 'alarm2', labelKey: 'AlarmAsset.alarm2' },
|
|
1021
|
+
{ value: 'alarm3', labelKey: 'AlarmAsset.alarm3' },
|
|
1022
|
+
{ value: 'alarm4', labelKey: 'AlarmAsset.alarm4' },
|
|
1023
|
+
{ value: 'alarm5', labelKey: 'AlarmAsset.alarm5' },
|
|
1024
|
+
{ value: 'alarm6', labelKey: 'AlarmAsset.alarm6' },
|
|
1025
|
+
{ value: 'alarm7', labelKey: 'AlarmAsset.alarm7' },
|
|
1026
|
+
{ value: 'alarm8', labelKey: 'AlarmAsset.alarm8' },
|
|
1027
|
+
{ value: 'alarm9', labelKey: 'AlarmAsset.alarm9' },
|
|
843
1028
|
];
|
|
844
1029
|
|
|
845
1030
|
const ALARM_TIMEOUT_OPTIONS: readonly SettingOption<AlarmTimeout>[] = [
|
|
846
|
-
{ value:
|
|
847
|
-
{ value:
|
|
848
|
-
{ value:
|
|
849
|
-
{ value:
|
|
850
|
-
{ value:
|
|
1031
|
+
{ value: 5, labelKey: 'Duration.CountSeconds', labelValues: { count: 5 } },
|
|
1032
|
+
{ value: 30, labelKey: 'Duration.CountSeconds', labelValues: { count: 30 } },
|
|
1033
|
+
{ value: 60, labelKey: 'Duration.CountMinutes', labelValues: { count: 1 } },
|
|
1034
|
+
{ value: 120, labelKey: 'Duration.CountMinutes', labelValues: { count: 2 } },
|
|
1035
|
+
{ value: 180, labelKey: 'Duration.CountMinutes', labelValues: { count: 3 } },
|
|
1036
|
+
{ value: 300, labelKey: 'Duration.CountMinutes', labelValues: { count: 5 } },
|
|
1037
|
+
{ value: 600, labelKey: 'Duration.CountMinutes', labelValues: { count: 10 } },
|
|
851
1038
|
];
|
|
852
1039
|
|
|
853
|
-
const DAY_VIEW_ZOOM_OPTIONS: readonly SettingOption<CalendarDayViewCellZoom>[] =
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
1040
|
+
const DAY_VIEW_ZOOM_OPTIONS: readonly SettingOption<CalendarDayViewCellZoom>[] =
|
|
1041
|
+
[
|
|
1042
|
+
{ value: 15, labelKey: 'Settings.Option.DayViewZoom.15min' },
|
|
1043
|
+
{ value: 30, labelKey: 'Settings.Option.DayViewZoom.30min' },
|
|
1044
|
+
{ value: 60, labelKey: 'Settings.Option.DayViewZoom.1hour' },
|
|
1045
|
+
];
|
|
858
1046
|
|
|
859
1047
|
const TIME_OF_DAY_SLIDER: SliderConfig = { min: 0, max: 23, step: 1 };
|
|
860
1048
|
|
|
@@ -912,11 +1100,16 @@ function buildEntries(config: RegistryConfig) {
|
|
|
912
1100
|
config.defaultTheme,
|
|
913
1101
|
'CUSTOM_THEME_PICKER',
|
|
914
1102
|
{
|
|
915
|
-
options:
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
1103
|
+
options: config.isEnrolled
|
|
1104
|
+
? [
|
|
1105
|
+
{ value: 'light', labelKey: 'Settings.Option.Theme.Light' },
|
|
1106
|
+
{ value: 'dark', labelKey: 'Settings.Option.Theme.Dark' },
|
|
1107
|
+
]
|
|
1108
|
+
: [
|
|
1109
|
+
{ value: 'light', labelKey: 'Settings.Option.Theme.Light' },
|
|
1110
|
+
{ value: 'dark', labelKey: 'Settings.Option.Theme.Dark' },
|
|
1111
|
+
{ value: 'system', labelKey: 'Settings.Option.Theme.System' },
|
|
1112
|
+
],
|
|
920
1113
|
},
|
|
921
1114
|
),
|
|
922
1115
|
'appearance.clockType': def<ClockType>(
|
|
@@ -1060,36 +1253,70 @@ function buildEntries(config: RegistryConfig) {
|
|
|
1060
1253
|
// ═══════════════════════════════════════════════════════════════════════
|
|
1061
1254
|
// Event form field visibility (time-based)
|
|
1062
1255
|
// ═══════════════════════════════════════════════════════════════════════
|
|
1063
|
-
'eventForm.recurrence': def<boolean>(
|
|
1256
|
+
'eventForm.recurrence': def<boolean>(
|
|
1257
|
+
'eventForm',
|
|
1258
|
+
'boolean',
|
|
1259
|
+
true,
|
|
1260
|
+
'TOGGLE',
|
|
1261
|
+
),
|
|
1064
1262
|
'eventForm.location': def<boolean>('eventForm', 'boolean', true, 'TOGGLE'),
|
|
1065
|
-
'eventForm.travelTime': def<boolean>(
|
|
1263
|
+
'eventForm.travelTime': def<boolean>(
|
|
1264
|
+
'eventForm',
|
|
1265
|
+
'boolean',
|
|
1266
|
+
false,
|
|
1267
|
+
'TOGGLE',
|
|
1268
|
+
),
|
|
1066
1269
|
'eventForm.reminders': def<boolean>('eventForm', 'boolean', true, 'TOGGLE'),
|
|
1067
|
-
'eventForm.emailReminders': def<boolean>(
|
|
1068
|
-
|
|
1270
|
+
'eventForm.emailReminders': def<boolean>(
|
|
1271
|
+
'eventForm',
|
|
1272
|
+
'boolean',
|
|
1273
|
+
false,
|
|
1274
|
+
'TOGGLE',
|
|
1275
|
+
),
|
|
1276
|
+
'eventForm.description': def<boolean>(
|
|
1277
|
+
'eventForm',
|
|
1278
|
+
'boolean',
|
|
1279
|
+
true,
|
|
1280
|
+
'TOGGLE',
|
|
1281
|
+
),
|
|
1069
1282
|
'eventForm.checklist': def<boolean>('eventForm', 'boolean', true, 'TOGGLE'),
|
|
1070
1283
|
'eventForm.images': def<boolean>('eventForm', 'boolean', false, 'TOGGLE'),
|
|
1071
|
-
'eventForm.audioClips': def<boolean>(
|
|
1284
|
+
'eventForm.audioClips': def<boolean>(
|
|
1285
|
+
'eventForm',
|
|
1286
|
+
'boolean',
|
|
1287
|
+
false,
|
|
1288
|
+
'TOGGLE',
|
|
1289
|
+
),
|
|
1072
1290
|
'eventForm.notificationReceivers': def<boolean>(
|
|
1073
1291
|
'eventForm',
|
|
1074
1292
|
'boolean',
|
|
1075
1293
|
true,
|
|
1076
1294
|
'TOGGLE',
|
|
1077
1295
|
),
|
|
1078
|
-
'eventForm.visibility': def<boolean>(
|
|
1296
|
+
'eventForm.visibility': def<boolean>(
|
|
1297
|
+
'eventForm',
|
|
1298
|
+
'boolean',
|
|
1299
|
+
false,
|
|
1300
|
+
'TOGGLE',
|
|
1301
|
+
),
|
|
1079
1302
|
|
|
1080
1303
|
// ═══════════════════════════════════════════════════════════════════════
|
|
1081
1304
|
// Sound & alerts
|
|
1082
1305
|
// ═══════════════════════════════════════════════════════════════════════
|
|
1083
1306
|
'sound.timerVolume': def<number>('sound', 'number', 0.5, 'VOLUME_SLIDER'),
|
|
1084
|
-
'sound.reminderVolume': def<number>(
|
|
1085
|
-
'sound.mediaVolume': def<number>('sound', 'number', 0.5, 'VOLUME_SLIDER', { appMode: 'ENROLLED' }),
|
|
1086
|
-
'sound.alarmSound': def<AlarmSound>(
|
|
1307
|
+
'sound.reminderVolume': def<number>(
|
|
1087
1308
|
'sound',
|
|
1088
|
-
'
|
|
1089
|
-
|
|
1090
|
-
'
|
|
1091
|
-
{
|
|
1309
|
+
'number',
|
|
1310
|
+
0.5,
|
|
1311
|
+
'VOLUME_SLIDER',
|
|
1312
|
+
{ appMode: 'ENROLLED' },
|
|
1092
1313
|
),
|
|
1314
|
+
'sound.mediaVolume': def<number>('sound', 'number', 0.5, 'VOLUME_SLIDER', {
|
|
1315
|
+
appMode: 'ENROLLED',
|
|
1316
|
+
}),
|
|
1317
|
+
'sound.alarmSound': def<AlarmSound>('sound', 'string', 'alarm1', 'SELECT', {
|
|
1318
|
+
options: ALARM_SOUND_OPTIONS,
|
|
1319
|
+
}),
|
|
1093
1320
|
'sound.reminderAlarmSound': def<AlarmSound>(
|
|
1094
1321
|
'sound',
|
|
1095
1322
|
'string',
|
|
@@ -1100,16 +1327,16 @@ function buildEntries(config: RegistryConfig) {
|
|
|
1100
1327
|
'sound.startAlarmSound': def<AlarmSound>(
|
|
1101
1328
|
'sound',
|
|
1102
1329
|
'string',
|
|
1103
|
-
'
|
|
1330
|
+
'alarm1',
|
|
1104
1331
|
'SELECT',
|
|
1105
|
-
{ options: ALARM_SOUND_OPTIONS
|
|
1332
|
+
{ options: ALARM_SOUND_OPTIONS },
|
|
1106
1333
|
),
|
|
1107
1334
|
'sound.endAlarmSound': def<AlarmSound>(
|
|
1108
1335
|
'sound',
|
|
1109
1336
|
'string',
|
|
1110
|
-
'
|
|
1337
|
+
'alarm1',
|
|
1111
1338
|
'SELECT',
|
|
1112
|
-
{ options: ALARM_SOUND_OPTIONS
|
|
1339
|
+
{ options: ALARM_SOUND_OPTIONS },
|
|
1113
1340
|
),
|
|
1114
1341
|
'sound.timerAlarmSound': def<AlarmSound>(
|
|
1115
1342
|
'sound',
|
|
@@ -1121,14 +1348,14 @@ function buildEntries(config: RegistryConfig) {
|
|
|
1121
1348
|
'sound.timerAlarmTimeout': def<AlarmTimeout>(
|
|
1122
1349
|
'sound',
|
|
1123
1350
|
'number',
|
|
1124
|
-
|
|
1351
|
+
180,
|
|
1125
1352
|
'SELECT',
|
|
1126
1353
|
{ options: ALARM_TIMEOUT_OPTIONS },
|
|
1127
1354
|
),
|
|
1128
1355
|
'sound.reminderAlarmTimeout': def<AlarmTimeout>(
|
|
1129
1356
|
'sound',
|
|
1130
1357
|
'number',
|
|
1131
|
-
|
|
1358
|
+
180,
|
|
1132
1359
|
'SELECT',
|
|
1133
1360
|
{ options: ALARM_TIMEOUT_OPTIONS },
|
|
1134
1361
|
),
|
|
@@ -1145,21 +1372,22 @@ function buildEntries(config: RegistryConfig) {
|
|
|
1145
1372
|
'TOGGLE',
|
|
1146
1373
|
{ appMode: 'ENROLLED' },
|
|
1147
1374
|
),
|
|
1148
|
-
'sound.ttsRate': def<number>(
|
|
1149
|
-
|
|
1150
|
-
'
|
|
1151
|
-
|
|
1152
|
-
'SLIDER',
|
|
1153
|
-
{ sliderConfig: { min: 0.5, max: 2, step: 0.1 }, appMode: 'ENROLLED' },
|
|
1154
|
-
),
|
|
1375
|
+
'sound.ttsRate': def<number>('sound', 'number', 1.0, 'SLIDER', {
|
|
1376
|
+
sliderConfig: { min: 0.5, max: 2, step: 0.1 },
|
|
1377
|
+
appMode: 'ENROLLED',
|
|
1378
|
+
}),
|
|
1155
1379
|
|
|
1156
1380
|
// ═══════════════════════════════════════════════════════════════════════
|
|
1157
1381
|
// Timer
|
|
1158
1382
|
// ═══════════════════════════════════════════════════════════════════════
|
|
1159
1383
|
'timer.showTimeRemaining': def<boolean>('timer', 'boolean', true, 'TOGGLE'),
|
|
1160
|
-
'timer.showEndTime': def<boolean>('timer', 'boolean', true, 'TOGGLE', {
|
|
1384
|
+
'timer.showEndTime': def<boolean>('timer', 'boolean', true, 'TOGGLE', {
|
|
1385
|
+
calendarType: 'time-based',
|
|
1386
|
+
}),
|
|
1161
1387
|
'timer.showRestartButton': def<boolean>('timer', 'boolean', true, 'TOGGLE'),
|
|
1162
|
-
'timer.showPauseButton': def<boolean>('timer', 'boolean', true, 'TOGGLE', {
|
|
1388
|
+
'timer.showPauseButton': def<boolean>('timer', 'boolean', true, 'TOGGLE', {
|
|
1389
|
+
calendarType: 'time-based',
|
|
1390
|
+
}),
|
|
1163
1391
|
|
|
1164
1392
|
// ═══════════════════════════════════════════════════════════════════════
|
|
1165
1393
|
// Lock screen
|
|
@@ -1268,7 +1496,12 @@ function buildEntries(config: RegistryConfig) {
|
|
|
1268
1496
|
// ═══════════════════════════════════════════════════════════════════════
|
|
1269
1497
|
// Touch / gestures
|
|
1270
1498
|
// ═══════════════════════════════════════════════════════════════════════
|
|
1271
|
-
'touch.enableTapToCreate': def<boolean>(
|
|
1499
|
+
'touch.enableTapToCreate': def<boolean>(
|
|
1500
|
+
'touch',
|
|
1501
|
+
'boolean',
|
|
1502
|
+
false,
|
|
1503
|
+
'TOGGLE',
|
|
1504
|
+
),
|
|
1272
1505
|
'touch.enableDragDrop': def<boolean>('touch', 'boolean', false, 'TOGGLE'),
|
|
1273
1506
|
|
|
1274
1507
|
// ═══════════════════════════════════════════════════════════════════════
|
|
@@ -1537,6 +1770,12 @@ function buildEntries(config: RegistryConfig) {
|
|
|
1537
1770
|
// Chronological event form
|
|
1538
1771
|
// ═══════════════════════════════════════════════════════════════════════
|
|
1539
1772
|
// Fixed fields
|
|
1773
|
+
'chronologicalEventForm.fixedField.category': def<boolean>(
|
|
1774
|
+
'chronologicalEventForm',
|
|
1775
|
+
'boolean',
|
|
1776
|
+
true,
|
|
1777
|
+
'TOGGLE',
|
|
1778
|
+
),
|
|
1540
1779
|
'chronologicalEventForm.fixedField.allDay': def<boolean>(
|
|
1541
1780
|
'chronologicalEventForm',
|
|
1542
1781
|
'boolean',
|
|
@@ -1604,6 +1843,12 @@ function buildEntries(config: RegistryConfig) {
|
|
|
1604
1843
|
true,
|
|
1605
1844
|
'TOGGLE',
|
|
1606
1845
|
),
|
|
1846
|
+
'chronologicalEventForm.field.category': def<boolean>(
|
|
1847
|
+
'chronologicalEventForm',
|
|
1848
|
+
'boolean',
|
|
1849
|
+
true,
|
|
1850
|
+
'TOGGLE',
|
|
1851
|
+
),
|
|
1607
1852
|
// Suggest end time
|
|
1608
1853
|
'chronologicalEventForm.suggestEndTime.enabled': def<boolean>(
|
|
1609
1854
|
'chronologicalEventForm',
|
|
@@ -1650,6 +1895,19 @@ function buildEntries(config: RegistryConfig) {
|
|
|
1650
1895
|
],
|
|
1651
1896
|
},
|
|
1652
1897
|
),
|
|
1898
|
+
// Default alarm toggles
|
|
1899
|
+
'chronologicalEventForm.defaultAlarm.atStart': def<boolean>(
|
|
1900
|
+
'chronologicalEventForm',
|
|
1901
|
+
'boolean',
|
|
1902
|
+
true,
|
|
1903
|
+
'TOGGLE',
|
|
1904
|
+
),
|
|
1905
|
+
'chronologicalEventForm.defaultAlarm.atEnd': def<boolean>(
|
|
1906
|
+
'chronologicalEventForm',
|
|
1907
|
+
'boolean',
|
|
1908
|
+
false,
|
|
1909
|
+
'TOGGLE',
|
|
1910
|
+
),
|
|
1653
1911
|
// Reminder presets
|
|
1654
1912
|
'chronologicalEventForm.reminderPresets.timed': def<number[]>(
|
|
1655
1913
|
'chronologicalEventForm',
|
|
@@ -1917,9 +2175,8 @@ export function parseSettingsSnapshot(
|
|
|
1917
2175
|
}
|
|
1918
2176
|
|
|
1919
2177
|
const labelDef = SETTINGS_LABELS[key];
|
|
1920
|
-
const entryDef =
|
|
1921
|
-
? registry.entries[key as SettingKey]
|
|
1922
|
-
: undefined;
|
|
2178
|
+
const entryDef =
|
|
2179
|
+
key in registry.entries ? registry.entries[key as SettingKey] : undefined;
|
|
1923
2180
|
groups.get(category)!.push({
|
|
1924
2181
|
key,
|
|
1925
2182
|
name,
|
|
@@ -1928,7 +2185,9 @@ export function parseSettingsSnapshot(
|
|
|
1928
2185
|
descriptionKey: labelDef?.descriptionKey,
|
|
1929
2186
|
value,
|
|
1930
2187
|
uiType: entryDef?.uiType ?? 'TEXT_INPUT',
|
|
1931
|
-
...(entryDef?.options && {
|
|
2188
|
+
...(entryDef?.options && {
|
|
2189
|
+
options: entryDef.options as readonly SettingOption[],
|
|
2190
|
+
}),
|
|
1932
2191
|
...(entryDef?.sliderConfig && { sliderConfig: entryDef.sliderConfig }),
|
|
1933
2192
|
...(entryDef?.appMode && { appMode: entryDef.appMode }),
|
|
1934
2193
|
...(entryDef?.calendarType && { calendarType: entryDef.calendarType }),
|