dashboard-shell-shell 1.0.1000000116 → 1.0.1000000117

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.
Files changed (124) hide show
  1. package/assets/images/action.svg +6 -0
  2. package/assets/images/pl/logo.png +0 -0
  3. package/assets/styles/base/_functions.scss +0 -0
  4. package/assets/styles/base/_mixins.scss +1 -1
  5. package/assets/styles/global/_button.scss +17 -10
  6. package/assets/styles/global/_form.scss +2 -2
  7. package/assets/styles/global/_labeled-input.scss +6 -2
  8. package/assets/styles/global/_select.scss +6 -7
  9. package/assets/styles/global/_table.scss +3 -2
  10. package/assets/styles/global/_tooltip.scss +8 -1
  11. package/assets/styles/themes/_dark.scss +2 -0
  12. package/assets/styles/themes/_light.scss +5 -2
  13. package/assets/styles/vendor/vue-select.scss +2 -1
  14. package/assets/translations/en-us.yaml +1 -3
  15. package/assets/translations/zh-hans.yaml +51 -28
  16. package/components/ActionDropdown.vue +1 -0
  17. package/components/ActionMenuShell.vue +6 -3
  18. package/components/BrandImage.vue +22 -0
  19. package/components/ClusterIconMenu.vue +1 -1
  20. package/components/CodeMirror.vue +1 -0
  21. package/components/CruResource.vue +1 -1
  22. package/components/CruResourceFooter.vue +1 -1
  23. package/components/ExplorerProjectsNamespaces.vue +4 -24
  24. package/components/GlobalRoleBindings.vue +112 -48
  25. package/components/IndentedPanel.vue +4 -10
  26. package/components/PromptRemove.vue +3 -3
  27. package/components/ResourceDetail/Masthead.vue +190 -242
  28. package/components/ResourceDetail/index.vue +20 -5
  29. package/components/ResourceList/Masthead.vue +146 -84
  30. package/components/ResourceList/ResourceLoadingIndicator.vue +5 -2
  31. package/components/ResourceTable.vue +76 -1
  32. package/components/SideNav.vue +66 -29
  33. package/components/SortableTable/THead.vue +6 -0
  34. package/components/SortableTable/index.vue +481 -388
  35. package/components/Tabbed/index.vue +4 -5
  36. package/components/auth/Principal.vue +3 -2
  37. package/components/auth/RoleDetailEdit.vue +58 -5
  38. package/components/auth/SelectPrincipal.vue +1 -0
  39. package/components/form/BannerSettings.vue +18 -16
  40. package/components/form/ChangePassword.vue +4 -4
  41. package/components/form/ColorInput.vue +32 -8
  42. package/components/form/Footer.vue +1 -1
  43. package/components/form/InputWithSelect.vue +2 -0
  44. package/components/form/KeyValue.vue +31 -7
  45. package/components/form/LabeledSelect.vue +178 -178
  46. package/components/form/Members/ClusterPermissionsEditor.vue +1 -2
  47. package/components/form/Members/MembershipEditor.vue +1 -1
  48. package/components/form/NameNsDescription.vue +24 -11
  49. package/components/form/Password.vue +6 -2
  50. package/components/form/ResourceQuota/Namespace.vue +1 -1
  51. package/components/form/ResourceQuota/NamespaceRow.vue +13 -10
  52. package/components/form/ResourceQuota/ProjectRow.vue +0 -1
  53. package/components/form/Select.vue +2 -2
  54. package/components/nav/Favorite.vue +5 -1
  55. package/components/nav/Group.vue +69 -23
  56. package/components/nav/Header.vue +82 -17
  57. package/components/nav/HeaderPageActionMenu.vue +1 -0
  58. package/components/nav/NamespaceFilter.vue +0 -3
  59. package/components/nav/TopLevelMenu.vue +182 -119
  60. package/components/nav/Type.vue +48 -11
  61. package/composables/useClickOutside.ts +1 -1
  62. package/config/product/auth.js +16 -7
  63. package/config/product/explorer.js +1 -1
  64. package/config/product/settings.js +17 -8
  65. package/config/settings.ts +28 -0
  66. package/edit/management.cattle.io.user.vue +17 -4
  67. package/edit/networking.k8s.io.ingress/RulePath.vue +1 -1
  68. package/edit/token.vue +1 -1
  69. package/list/harvesterhci.io.management.cluster.vue +17 -0
  70. package/list/management.cattle.io.setting.vue +22 -13
  71. package/list/management.cattle.io.user.vue +25 -14
  72. package/list/provisioning.cattle.io.cluster.vue +6 -7
  73. package/mixins/brand.js +17 -0
  74. package/package.json +1 -1
  75. package/pages/auth/login.vue +84 -29
  76. package/pages/c/_cluster/auth/roles/index.vue +61 -14
  77. package/pages/c/_cluster/settings/banners.vue +174 -101
  78. package/pages/c/_cluster/settings/brand.vue +348 -301
  79. package/pages/c/_cluster/settings/performance.vue +61 -38
  80. package/pages/home.vue +70 -21
  81. package/pages/prefs.vue +25 -23
  82. package/pkg/tsconfig.json +9 -9
  83. package/pkg/vue.config.js +1 -1
  84. package/promptRemove/mixin/roleDeletionCheck.js +2 -2
  85. package/scripts/clean +0 -0
  86. package/scripts/extension/bundle +0 -0
  87. package/scripts/extension/helm/scripts/package +0 -0
  88. package/scripts/extension/helm/scripts/patch +0 -0
  89. package/scripts/extension/helm/scripts/version +0 -0
  90. package/scripts/extension/helmpatch +0 -0
  91. package/scripts/extension/parse-tag-name +0 -0
  92. package/scripts/extension/publish +0 -0
  93. package/scripts/publish-shell.sh +86 -60
  94. package/scripts/serve-pkgs +0 -0
  95. package/scripts/sync-shell-deps +0 -0
  96. package/scripts/typegen.sh +44 -28
  97. package/store/i18n.js +5 -5
  98. package/store/prefs.js +17 -5
  99. package/store/type-map.js +2 -1
  100. package/types/shell/index.d.ts +1 -1
  101. package/utils/error.js +4 -0
  102. package/utils/router.js +3 -3
  103. package/vue.config.js +1 -6
  104. package/components/rancherResourceDetail/Masthead.vue +0 -769
  105. package/components/rancherResourceDetail/__tests__/Masthead.test.ts +0 -65
  106. package/components/rancherResourceDetail/index.vue +0 -591
  107. package/components/rancherResourceList/Masthead.vue +0 -375
  108. package/components/rancherResourceList/ResourceLoadingIndicator.vue +0 -140
  109. package/components/rancherResourceList/index.vue +0 -307
  110. package/components/rancherResourceList/resource-list.config.js +0 -7
  111. package/components/rancherResourceTable.vue +0 -783
  112. package/components/rancherSortableTable/THead.vue +0 -561
  113. package/components/rancherSortableTable/actions.js +0 -153
  114. package/components/rancherSortableTable/advanced-filtering.js +0 -272
  115. package/components/rancherSortableTable/debug.js +0 -117
  116. package/components/rancherSortableTable/filtering.js +0 -290
  117. package/components/rancherSortableTable/grouping.js +0 -48
  118. package/components/rancherSortableTable/index.vue +0 -2712
  119. package/components/rancherSortableTable/paging.js +0 -155
  120. package/components/rancherSortableTable/selection.js +0 -629
  121. package/components/rancherSortableTable/sortable-config.ts +0 -4
  122. package/components/rancherSortableTable/sorting.js +0 -129
  123. package/types/cloud-shell/index.d.ts +0 -11014
  124. /package/components/{rancherResourceList → ResourceList}/Masthead-btn.vue +0 -0
@@ -34,8 +34,8 @@ export default {
34
34
  uiBannerLightSetting: fetchOrCreateSetting(this.$store, SETTING.BANNER_LIGHT, ''),
35
35
  uiLoginBackgroundDarkSetting: fetchOrCreateSetting(this.$store, SETTING.LOGIN_BACKGROUND_DARK, ''),
36
36
  uiLoginBackgroundLightSetting: fetchOrCreateSetting(this.$store, SETTING.LOGIN_BACKGROUND_LIGHT, ''),
37
- uiColorSetting: fetchOrCreateSetting(this.$store, SETTING.PRIMARY_COLOR, ''),
38
- uiLinkColorSetting: fetchOrCreateSetting(this.$store, SETTING.LINK_COLOR, ''),
37
+ uiColorSetting: fetchOrCreateSetting(this.$store, SETTING.PRIMARY_COLOR, 'rgb(24, 144, 255)'),
38
+ uiLinkColorSetting: fetchOrCreateSetting(this.$store, SETTING.LINK_COLOR, 'rgb(24, 144, 255)'),
39
39
  uiFaviconSetting: fetchOrCreateSetting(this.$store, SETTING.FAVICON, ''),
40
40
  });
41
41
 
@@ -249,329 +249,357 @@ export default {
249
249
 
250
250
  <template>
251
251
  <Loading v-if="$fetchState.pending" />
252
- <div v-else>
252
+ <div v-else style="padding-bottom:60px;">
253
+
254
+ <!-- 面包屑 -->
255
+ <div class="excram-list">全局设置 / <span style="color: #1890FF;">界面</span></div>
253
256
  <h1 class="mb-20">
254
257
  <TabTitle>{{ t('branding.label') }}</TabTitle>
255
258
  </h1>
259
+ <div style="margin-bottom: 20px;">用于统一配置系统形象与视觉主题,可管理登录页与操作界面的Logo、背景、色彩等核心元素,实现全局自定义UI界面。</div>
256
260
  <TypeDescription resource="branding" />
257
261
  <div>
262
+ <!-- 系统名称 -->
258
263
  <div class="row">
259
- <div class="col span-6">
260
- <LabeledInput
261
- v-model:value="uiPLSetting.value"
262
- :label="t('branding.uiPL.label')"
263
- :mode="mode"
264
- :maxlength="100"
265
- />
266
- </div>
267
- </div>
268
- <h3 class="mt-20 mb-5 pb-5">
269
- {{ t('branding.logos.label') }}
270
- </h3>
271
- <label class="text-label">
272
- {{ t('branding.logos.tip', {}, true) }}
273
- </label>
274
-
275
- <div class="row mt-10 mb-20">
276
- <Checkbox
277
- v-model:value="customizeLogo"
278
- :label="t('branding.logos.useCustom')"
279
- :mode="mode"
280
- />
281
- </div>
282
-
283
- <div
284
- v-if="customizeLogo"
285
- class="row mb-20"
286
- >
287
- <div class="col preview-container logo span-6">
288
- <div class="mb-10">
289
- <FileImageSelector
290
- :byte-limit="20000"
291
- :read-as-data-url="true"
292
- class="role-secondary"
293
- :label="t('branding.logos.uploadLight')"
294
- :mode="mode"
295
- accept="image/jpeg,image/png,image/svg+xml"
296
- @error="setError"
297
- @update:value="updateBranding($event, 'uiLogoLight')"
298
- />
299
- </div>
300
- <SimpleBox
301
- v-if="uiLogoLight || uiLogoDark"
302
- class="theme-light mb-10"
303
- >
304
- <label class="text-muted">{{ t('branding.logos.lightPreview') }}</label>
305
- <img
306
- class="img-preview"
307
- data-testid="branding-logo-light-preview"
308
- :src="uiLogoLight ? uiLogoLight : uiLogoDark"
309
- >
310
- </SimpleBox>
311
- </div>
312
- <div class="col preview-container logo span-6">
313
- <div class="mb-10">
314
- <FileImageSelector
315
- :byte-limit="20000"
316
- :read-as-data-url="true"
317
- class="role-secondary"
318
- :label="t('branding.logos.uploadDark')"
264
+ <div class="mb-20 pl-20 pt-20" style="border: 1px solid var(--nav-border);width: 100%;">
265
+ <h3 class="mb-20">系统名称</h3>
266
+ <div class="col span-6">
267
+ <LabeledInput
268
+ v-model:value="uiPLSetting.value"
269
+ :label="'名称'"
319
270
  :mode="mode"
320
- accept="image/jpeg,image/png,image/svg+xml"
321
- @error="setError"
322
- @update:value="updateBranding($event, 'uiLogoDark')"
271
+ :maxlength="100"
323
272
  />
324
273
  </div>
325
- <SimpleBox
326
- v-if="uiLogoDark || uiLogoLight"
327
- class="theme-dark mb-10"
328
- >
329
- <label class="text-muted">{{ t('branding.logos.darkPreview') }}</label>
330
- <img
331
- class="img-preview"
332
- data-testid="branding-logo-dark-preview"
333
- :src="uiLogoDark ? uiLogoDark : uiLogoLight"
334
- >
335
- </SimpleBox>
336
274
  </div>
337
275
  </div>
338
276
 
339
- <h3 class="mt-20 mb-5 pb-5">
340
- {{ t('branding.banner.label') }}
341
- </h3>
342
- <label class="text-label">
343
- {{ t('branding.banner.tip', {}, true) }}
344
- </label>
345
-
346
- <div class="row mt-10 mb-20">
347
- <Checkbox
348
- v-model:value="customizeBanner"
349
- :label="t('branding.banner.useCustom')"
350
- :mode="mode"
351
- />
352
- </div>
353
-
354
- <div
355
- v-if="customizeBanner"
356
- class="row mb-20"
357
- >
358
- <div class="col preview-container banner span-6">
359
- <div class="mb-10">
360
- <FileImageSelector
361
- :byte-limit="200000"
362
- :read-as-data-url="true"
363
- class="role-secondary"
364
- :label="t('branding.banner.uploadLight')"
365
- :mode="mode"
366
- accept="image/jpeg,image/png,image/svg+xml"
367
- @error="setError"
368
- @update:value="updateBranding($event, 'uiBannerLight')"
369
- />
370
- </div>
371
- <SimpleBox
372
- v-if="uiBannerLight || uiBannerDark"
373
- class="theme-light mb-10"
374
- >
375
- <label class="text-muted">{{ t('branding.banner.lightPreview') }}</label>
376
- <img
377
- class="img-preview"
378
- data-testid="branding-banner-light-preview"
379
- :src="uiBannerLight ? uiBannerLight : uiBannerDark"
380
- >
381
- </SimpleBox>
277
+ <!-- Logo -->
278
+ <div class="mb-20 pl-20" style="border: 1px solid var(--nav-border);">
279
+ <h3 class="mt-20 mb-20">
280
+ {{ t('branding.logos.label') }}
281
+ </h3>
282
+ <label class="text-label">
283
+ {{ t('branding.logos.tip', {}, true) }}
284
+ </label>
285
+
286
+ <div class="row mt-10 mb-20">
287
+ <Checkbox
288
+ v-model:value="customizeLogo"
289
+ :label="t('branding.logos.useCustom')"
290
+ :mode="mode"
291
+ />
382
292
  </div>
383
- <div class="col preview-container banner span-6">
384
- <div class="mb-10">
385
- <FileImageSelector
386
- :byte-limit="200000"
387
- :read-as-data-url="true"
388
- class="role-secondary"
389
- :label="t('branding.banner.uploadDark')"
390
- :mode="mode"
391
- accept="image/jpeg,image/png,image/svg+xml"
392
- @error="setError"
393
- @update:value="updateBranding($event, 'uiBannerDark')"
394
- />
293
+
294
+ <div
295
+ v-if="customizeLogo"
296
+ class="row mb-20"
297
+ >
298
+ <div class="col preview-container logo span-6">
299
+ <div class="mb-10">
300
+ <FileImageSelector
301
+ :byte-limit="20000"
302
+ :read-as-data-url="true"
303
+ class="role-secondary"
304
+ :label="t('branding.logos.uploadLight')"
305
+ :mode="mode"
306
+ accept="image/jpeg,image/png,image/svg+xml"
307
+ @error="setError"
308
+ @update:value="updateBranding($event, 'uiLogoLight')"
309
+ />
310
+ </div>
311
+ <SimpleBox
312
+ v-if="uiLogoLight || uiLogoDark"
313
+ class="theme-light mb-10"
314
+ >
315
+ <label class="text-muted">{{ t('branding.logos.lightPreview') }}</label>
316
+ <img
317
+ class="img-preview"
318
+ data-testid="branding-logo-light-preview"
319
+ :src="uiLogoLight ? uiLogoLight : uiLogoDark"
320
+ >
321
+ </SimpleBox>
395
322
  </div>
396
- <SimpleBox
397
- v-if="uiBannerDark || uiBannerLight"
398
- class="theme-dark mb-10"
399
- >
400
- <label class="text-muted">{{ t('branding.banner.darkPreview') }}</label>
401
- <img
402
- class="img-preview"
403
- data-testid="branding-banner-dark-preview"
404
- :src="uiBannerDark ? uiBannerDark : uiBannerLight"
323
+ <div class="col preview-container logo span-6">
324
+ <div class="mb-10">
325
+ <FileImageSelector
326
+ :byte-limit="20000"
327
+ :read-as-data-url="true"
328
+ class="role-secondary"
329
+ :label="t('branding.logos.uploadDark')"
330
+ :mode="mode"
331
+ accept="image/jpeg,image/png,image/svg+xml"
332
+ @error="setError"
333
+ @update:value="updateBranding($event, 'uiLogoDark')"
334
+ />
335
+ </div>
336
+ <SimpleBox
337
+ v-if="uiLogoDark || uiLogoLight"
338
+ class="theme-dark mb-10"
405
339
  >
406
- </SimpleBox>
340
+ <label class="text-muted">{{ t('branding.logos.darkPreview') }}</label>
341
+ <img
342
+ class="img-preview"
343
+ data-testid="branding-logo-dark-preview"
344
+ :src="uiLogoDark ? uiLogoDark : uiLogoLight"
345
+ >
346
+ </SimpleBox>
347
+ </div>
407
348
  </div>
408
349
  </div>
409
350
 
410
- <h3 class="mt-20 mb-5 pb-5">
411
- {{ t('branding.loginBackground.label') }}
412
- </h3>
413
- <label class="text-label">
414
- {{ t('branding.loginBackground.tip', {}, true) }}
415
- </label>
416
-
417
- <div class="row mt-10 mb-20">
418
- <Checkbox
419
- v-model:value="customizeLoginBackground"
420
- :label="t('branding.loginBackground.useCustom')"
421
- :mode="mode"
422
- />
423
- </div>
424
-
425
- <div
426
- v-if="customizeLoginBackground"
427
- class="row mb-20"
428
- >
429
- <div class="col preview-container login-background span-6">
430
- <div class="mb-10">
431
- <FileImageSelector
432
- :byte-limit="200000"
433
- :read-as-data-url="true"
434
- class="role-secondary"
435
- :label="t('branding.loginBackground.uploadLight')"
351
+ <!-- Banner -->
352
+ <div class="mb-20 pl-20" style="border: 1px solid var(--nav-border);">
353
+ <h3 class="mt-20 mb-20">
354
+ {{ t('branding.banner.label') }}
355
+ </h3>
356
+ <label class="text-label">
357
+ {{ t('branding.banner.tip', {}, true) }}
358
+ </label>
359
+
360
+ <div class="row mt-10 mb-20">
361
+ <Checkbox
362
+ v-model:value="customizeBanner"
363
+ :label="t('branding.banner.useCustom')"
364
+ :mode="mode"
365
+ />
366
+ </div>
367
+
368
+ <div
369
+ v-if="customizeBanner"
370
+ class="row mb-20"
371
+ >
372
+ <div class="col preview-container banner span-6">
373
+ <div class="mb-10">
374
+ <FileImageSelector
375
+ :byte-limit="200000"
376
+ :read-as-data-url="true"
377
+ class="role-secondary"
378
+ :label="t('branding.banner.uploadLight')"
379
+ :mode="mode"
380
+ accept="image/jpeg,image/png,image/svg+xml"
381
+ @error="setError"
382
+ @update:value="updateBranding($event, 'uiBannerLight')"
383
+ />
384
+ </div>
385
+ <SimpleBox
386
+ v-if="uiBannerLight || uiBannerDark"
387
+ class="theme-light mb-10"
388
+ >
389
+ <label class="text-muted">{{ t('branding.banner.lightPreview') }}</label>
390
+ <img
391
+ class="img-preview"
392
+ data-testid="branding-banner-light-preview"
393
+ :src="uiBannerLight ? uiBannerLight : uiBannerDark"
394
+ >
395
+ </SimpleBox>
396
+ </div>
397
+ <div class="col preview-container banner span-6">
398
+ <div class="mb-10">
399
+ <FileImageSelector
400
+ :byte-limit="200000"
401
+ :read-as-data-url="true"
402
+ class="role-secondary"
403
+ :label="t('branding.banner.uploadDark')"
404
+ :mode="mode"
405
+ accept="image/jpeg,image/png,image/svg+xml"
406
+ @error="setError"
407
+ @update:value="updateBranding($event, 'uiBannerDark')"
408
+ />
409
+ </div>
410
+ <SimpleBox
411
+ v-if="uiBannerDark || uiBannerLight"
412
+ class="theme-dark mb-10"
413
+ >
414
+ <label class="text-muted">{{ t('branding.banner.darkPreview') }}</label>
415
+ <img
416
+ class="img-preview"
417
+ data-testid="branding-banner-dark-preview"
418
+ :src="uiBannerDark ? uiBannerDark : uiBannerLight"
419
+ >
420
+ </SimpleBox>
421
+ </div>
422
+ </div>
423
+ </div>
424
+
425
+ <!-- Login Background -->
426
+ <div class="mb-20 pl-20" style="border: 1px solid var(--nav-border);">
427
+ <h3 class="mt-20 mb-20">
428
+ {{ t('branding.loginBackground.label') }}
429
+ </h3>
430
+ <label class="text-label">
431
+ {{ t('branding.loginBackground.tip', {}, true) }}
432
+ </label>
433
+
434
+ <div class="row mt-10 mb-20">
435
+ <Checkbox
436
+ v-model:value="customizeLoginBackground"
437
+ :label="t('branding.loginBackground.useCustom')"
438
+ :mode="mode"
439
+ />
440
+ </div>
441
+
442
+ <div
443
+ v-if="customizeLoginBackground"
444
+ class="row mb-20"
445
+ >
446
+ <div class="col preview-container login-background span-6">
447
+ <div class="mb-10">
448
+ <FileImageSelector
449
+ :byte-limit="200000"
450
+ :read-as-data-url="true"
451
+ class="role-secondary"
452
+ :label="t('branding.loginBackground.uploadLight')"
453
+ :mode="mode"
454
+ accept="image/jpeg,image/png,image/svg+xml"
455
+ @error="setError"
456
+ @update:value="updateBranding($event, 'uiLoginBackgroundLight')"
457
+ />
458
+ </div>
459
+ <SimpleBox
460
+ v-if="uiLoginBackgroundLight || uiLoginBackgroundDark"
461
+ class="theme-light mb-10"
462
+ >
463
+ <label class="text-muted">{{ t('branding.loginBackground.lightPreview') }}</label>
464
+ <img
465
+ class="img-preview"
466
+ data-testid="branding-login-background-light-preview"
467
+ :src="uiLoginBackgroundLight ? uiLoginBackgroundLight : uiLoginBackgroundDark"
468
+ >
469
+ </SimpleBox>
470
+ </div>
471
+ <div class="col preview-container login-background span-6">
472
+ <div class="mb-10">
473
+ <FileImageSelector
474
+ :byte-limit="200000"
475
+ :read-as-data-url="true"
476
+ class="role-secondary"
477
+ :label="t('branding.loginBackground.uploadDark')"
478
+ :mode="mode"
479
+ accept="image/jpeg,image/png,image/svg+xml"
480
+ @error="setError"
481
+ @update:value="updateBranding($event, 'uiLoginBackgroundDark')"
482
+ />
483
+ </div>
484
+ <SimpleBox
485
+ v-if="uiLoginBackgroundDark || uiLoginBackgroundLight"
486
+ class="theme-dark mb-10"
487
+ >
488
+ <label class="text-muted">{{ t('branding.loginBackground.darkPreview') }}</label>
489
+ <img
490
+ class="img-preview"
491
+ data-testid="branding-login-background-dark-preview"
492
+ :src="uiLoginBackgroundDark ? uiLoginBackgroundDark : uiLoginBackgroundLight"
493
+ >
494
+ </SimpleBox>
495
+ </div>
496
+ </div>
497
+ </div>
498
+
499
+ <!-- 网站图标 -->
500
+ <div class="mb-20 pl-20" style="border: 1px solid var(--nav-border);">
501
+ <h3 class="mt-20 mb-20">
502
+ {{ t('branding.favicon.label') }}
503
+ </h3>
504
+ <label class="text-label">
505
+ {{ t('branding.favicon.tip', {}, true) }}
506
+ </label>
507
+
508
+ <div class="row mt-10 mb-20">
509
+ <Checkbox
510
+ v-model:value="customizeFavicon"
511
+ :label="t('branding.favicon.useCustom')"
512
+ :mode="mode"
513
+ />
514
+ </div>
515
+
516
+ <div
517
+ v-if="customizeFavicon"
518
+ class="row mb-20"
519
+ >
520
+ <div class="col favicon-container span-12">
521
+ <div class="mb-10">
522
+ <FileImageSelector
523
+ :byte-limit="20000"
524
+ :read-as-data-url="true"
525
+ class="role-secondary"
526
+ :label="t('branding.favicon.upload')"
527
+ :mode="mode"
528
+ accept="image/jpeg,image/png,image/svg+xml"
529
+ @error="setError"
530
+ @update:value="updateBranding($event, 'uiFavicon')"
531
+ />
532
+ </div>
533
+ <SimpleBox v-if="uiFavicon">
534
+ <label class="text-muted">{{ t('branding.favicon.preview') }}</label>
535
+ <img
536
+ class="favicon-preview"
537
+ data-testid="branding-favicon-preview"
538
+ :src="uiFavicon"
539
+ >
540
+ </SimpleBox>
541
+ </div>
542
+ </div>
543
+ </div>
544
+
545
+ <!-- 主题色 -->
546
+ <div class="mb-20 pl-20 pb-20" style="border: 1px solid var(--nav-border);">
547
+ <h3 class="mt-20 mb-20">
548
+ {{ t('branding.color.label') }}
549
+ </h3>
550
+ <label class="text-label">
551
+ {{ t('branding.color.tip', {}, true) }}
552
+ </label>
553
+ <div class="row mt-20">
554
+ <Checkbox
555
+ v-model:value="customizeColor"
556
+ :label="t('branding.color.useCustom')"
557
+ :mode="mode"
558
+ />
559
+ </div>
560
+ <div
561
+ v-if="customizeColor"
562
+ class="row mt-20 mb-20"
563
+ >
564
+ <ColorInput
565
+ v-model:value="uiColor"
566
+ component-testid="primary"
567
+ />
568
+ </div>
569
+ </div>
570
+
571
+ <!-- 链接颜色 -->
572
+ <div class="mb-20 pl-20 pb-20" style="border: 1px solid var(--nav-border);">
573
+ <h3 class="mt-20 mb-20">
574
+ {{ t('branding.linkColor.label') }}
575
+ </h3>
576
+ <label class="text-label">
577
+ {{ t('branding.linkColor.tip', {}, true) }}
578
+ </label>
579
+ <div class="row mt-20">
580
+ <Checkbox
581
+ v-model:value="customizeLinkColor"
582
+ :label="t('branding.linkColor.useCustom')"
436
583
  :mode="mode"
437
- accept="image/jpeg,image/png,image/svg+xml"
438
- @error="setError"
439
- @update:value="updateBranding($event, 'uiLoginBackgroundLight')"
440
584
  />
441
585
  </div>
442
- <SimpleBox
443
- v-if="uiLoginBackgroundLight || uiLoginBackgroundDark"
444
- class="theme-light mb-10"
586
+ <div
587
+ v-if="customizeLinkColor"
588
+ class="row mt-20 mb-20"
445
589
  >
446
- <label class="text-muted">{{ t('branding.loginBackground.lightPreview') }}</label>
447
- <img
448
- class="img-preview"
449
- data-testid="branding-login-background-light-preview"
450
- :src="uiLoginBackgroundLight ? uiLoginBackgroundLight : uiLoginBackgroundDark"
451
- >
452
- </SimpleBox>
453
- </div>
454
- <div class="col preview-container login-background span-6">
455
- <div class="mb-10">
456
- <FileImageSelector
457
- :byte-limit="200000"
458
- :read-as-data-url="true"
459
- class="role-secondary"
460
- :label="t('branding.loginBackground.uploadDark')"
461
- :mode="mode"
462
- accept="image/jpeg,image/png,image/svg+xml"
463
- @error="setError"
464
- @update:value="updateBranding($event, 'uiLoginBackgroundDark')"
465
- />
466
- </div>
467
- <SimpleBox
468
- v-if="uiLoginBackgroundDark || uiLoginBackgroundLight"
469
- class="theme-dark mb-10"
470
- >
471
- <label class="text-muted">{{ t('branding.loginBackground.darkPreview') }}</label>
472
- <img
473
- class="img-preview"
474
- data-testid="branding-login-background-dark-preview"
475
- :src="uiLoginBackgroundDark ? uiLoginBackgroundDark : uiLoginBackgroundLight"
476
- >
477
- </SimpleBox>
478
- </div>
479
- </div>
480
-
481
- <h3 class="mt-20 mb-5 pb-5">
482
- {{ t('branding.favicon.label') }}
483
- </h3>
484
- <label class="text-label">
485
- {{ t('branding.favicon.tip', {}, true) }}
486
- </label>
487
-
488
- <div class="row mt-10 mb-20">
489
- <Checkbox
490
- v-model:value="customizeFavicon"
491
- :label="t('branding.favicon.useCustom')"
492
- :mode="mode"
493
- />
494
- </div>
495
-
496
- <div
497
- v-if="customizeFavicon"
498
- class="row mb-20"
499
- >
500
- <div class="col favicon-container span-12">
501
- <div class="mb-10">
502
- <FileImageSelector
503
- :byte-limit="20000"
504
- :read-as-data-url="true"
505
- class="role-secondary"
506
- :label="t('branding.favicon.upload')"
507
- :mode="mode"
508
- accept="image/jpeg,image/png,image/svg+xml"
509
- @error="setError"
510
- @update:value="updateBranding($event, 'uiFavicon')"
590
+ <ColorInput
591
+ v-model:value="uiLinkColor"
592
+ class="col"
593
+ component-testid="link"
511
594
  />
595
+ <span class="col link-example">
596
+ <a :style="customLinkColor">
597
+ {{ t('branding.linkColor.example') }}
598
+ </a>
599
+ </span>
512
600
  </div>
513
- <SimpleBox v-if="uiFavicon">
514
- <label class="text-muted">{{ t('branding.favicon.preview') }}</label>
515
- <img
516
- class="favicon-preview"
517
- data-testid="branding-favicon-preview"
518
- :src="uiFavicon"
519
- >
520
- </SimpleBox>
521
601
  </div>
522
- </div>
523
602
 
524
- <h3 class="mt-40 mb-5 pb-0">
525
- {{ t('branding.color.label') }}
526
- </h3>
527
- <label class="text-label">
528
- {{ t('branding.color.tip', {}, true) }}
529
- </label>
530
- <div class="row mt-20">
531
- <Checkbox
532
- v-model:value="customizeColor"
533
- :label="t('branding.color.useCustom')"
534
- :mode="mode"
535
- />
536
- </div>
537
- <div
538
- v-if="customizeColor"
539
- class="row mt-20 mb-20"
540
- >
541
- <ColorInput
542
- v-model:value="uiColor"
543
- component-testid="primary"
544
- />
545
- </div>
546
-
547
- <!-- <h3 class="mt-40 mb-5 pb-0">
548
- {{ t('branding.linkColor.label') }}
549
- </h3>
550
- <label class="text-label">
551
- {{ t('branding.linkColor.tip', {}, true) }}
552
- </label>
553
- <div class="row mt-20">
554
- <Checkbox
555
- v-model:value="customizeLinkColor"
556
- :label="t('branding.linkColor.useCustom')"
557
- :mode="mode"
558
- />
559
- </div>
560
- <div
561
- v-if="customizeLinkColor"
562
- class="row mt-20 mb-20"
563
- >
564
- <ColorInput
565
- v-model:value="uiLinkColor"
566
- class="col"
567
- component-testid="link"
568
- />
569
- <span class="col link-example">
570
- <a :style="customLinkColor">
571
- {{ t('branding.linkColor.example') }}
572
- </a>
573
- </span>
574
- </div> -->
575
603
  </div>
576
604
  <template
577
605
  v-for="(err, i) in errors"
@@ -582,10 +610,10 @@ export default {
582
610
  :label="err"
583
611
  />
584
612
  </template>
585
- <div v-if="mode === 'edit'">
613
+ <div class="action-btn" v-if="mode === 'edit'">
586
614
  <AsyncButton
587
615
  component-testid="branding-apply"
588
- class="pull-right mt-20"
616
+ class="pull-right"
589
617
  mode="apply"
590
618
  @click="save"
591
619
  />
@@ -594,6 +622,16 @@ export default {
594
622
  </template>
595
623
 
596
624
  <style scoped lang='scss'>
625
+ .action-btn {
626
+ padding: 10px 30px;
627
+ position: fixed;
628
+ bottom: 0;
629
+ left: 0;
630
+ width: 100%;
631
+ background: var(--body-bg);
632
+ border-top: 1px solid var(--nav-border);
633
+ }
634
+
597
635
  .link-example {
598
636
  display: flex;
599
637
  align-content: center;
@@ -645,4 +683,13 @@ export default {
645
683
  left: 10px;
646
684
  }
647
685
  }
686
+ h3 {
687
+ font-size: 14px;
688
+ }
689
+ .excram-list{
690
+ font-size: 14px;
691
+ line-height: 22px;
692
+ margin-bottom: 20px;
693
+ font-family: 'Microsoft YaHei';
694
+ }
648
695
  </style>