@xen-orchestra/web-core 0.26.1 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/lib/components/card/VtsCardRowKeyValue.vue +1 -0
  2. package/lib/components/cell-object/VtsCellObject.vue +1 -2
  3. package/lib/components/console/VtsActionsConsole.vue +3 -9
  4. package/lib/components/copy-button/VtsCopyButton.vue +1 -3
  5. package/lib/components/dropdown/DropdownTitle.vue +3 -3
  6. package/lib/components/icon/VtsIcon.vue +32 -76
  7. package/lib/components/input-wrapper/VtsInputWrapper.vue +2 -2
  8. package/lib/components/layout/VtsLayoutSidebar.vue +1 -2
  9. package/lib/components/menu/MenuItem.vue +4 -5
  10. package/lib/components/menu/MenuTrigger.vue +3 -3
  11. package/lib/components/object-icon/VtsObjectIcon.vue +2 -2
  12. package/lib/components/resources/VtsResource.vue +3 -3
  13. package/lib/components/select/VtsSelect.vue +4 -5
  14. package/lib/components/table/ColumnTitle.vue +11 -12
  15. package/lib/components/task/VtsQuickTaskButton.vue +1 -2
  16. package/lib/components/tree/VtsTreeLoadingItem.vue +3 -3
  17. package/lib/components/ui/alarm-item/UiAlarmItem.vue +1 -2
  18. package/lib/components/ui/alert/UiAlert.vue +14 -13
  19. package/lib/components/ui/button/UiButton.vue +4 -5
  20. package/lib/components/ui/button-icon/UiButtonIcon.vue +3 -3
  21. package/lib/components/ui/checkbox/UiCheckbox.vue +2 -9
  22. package/lib/components/ui/chip/ChipIcon.vue +3 -3
  23. package/lib/components/ui/chip/ChipRemoveIcon.vue +1 -2
  24. package/lib/components/ui/chip/UiChip.vue +2 -2
  25. package/lib/components/ui/circle-progress-bar/UiCircleProgressBar.vue +7 -4
  26. package/lib/components/ui/collapsible-list/UiCollapsibleList.vue +73 -0
  27. package/lib/components/ui/donut-chart/UiDonutChart.vue +30 -17
  28. package/lib/components/ui/dropdown/UiDropdown.vue +5 -7
  29. package/lib/components/ui/dropdown-button/UiDropdownButton.vue +4 -5
  30. package/lib/components/ui/head-bar/UiHeadBar.vue +6 -11
  31. package/lib/components/ui/info/UiInfo.vue +14 -20
  32. package/lib/components/ui/input/UiInput.vue +6 -7
  33. package/lib/components/ui/label/UiLabel.vue +3 -3
  34. package/lib/components/ui/legend/UiLegend.vue +3 -3
  35. package/lib/components/ui/legend-title/UiLegendTitle.vue +7 -3
  36. package/lib/components/ui/link/UiLink.vue +4 -5
  37. package/lib/components/ui/{quoteCode/UiQuoteCode.vue → log-entry-viewer/UiLogEntryViewer.vue} +58 -21
  38. package/lib/components/ui/object-link/UiObjectLink.vue +4 -4
  39. package/lib/components/ui/query-search-bar/UiQuerySearchBar.vue +3 -4
  40. package/lib/components/ui/quick-task-item/UiQuickTaskItem.vue +3 -4
  41. package/lib/components/ui/radio-button/UiRadioButton.vue +1 -2
  42. package/lib/components/ui/table-pagination/PaginationButton.vue +2 -25
  43. package/lib/components/ui/table-pagination/UiTablePagination.vue +56 -95
  44. package/lib/components/ui/tag/UiTag.vue +3 -3
  45. package/lib/components/ui/text-area/UiTextarea.vue +2 -2
  46. package/lib/components/ui/toaster/UiToaster.vue +15 -13
  47. package/lib/components/ui/tree-item-label/UiTreeItemLabel.vue +4 -5
  48. package/lib/composables/default-tab.composable.md +42 -0
  49. package/lib/composables/default-tab.composable.ts +26 -0
  50. package/lib/composables/link-component.composable.ts +3 -2
  51. package/lib/composables/pagination.composable.ts +5 -0
  52. package/lib/i18n.ts +4 -0
  53. package/lib/icons/fa-icons.ts +48 -2
  54. package/lib/icons/index.ts +4 -0
  55. package/lib/icons/legacy-icons.ts +10 -0
  56. package/lib/icons/object-icons.ts +1 -1
  57. package/lib/layouts/CoreLayout.vue +1 -2
  58. package/lib/locales/cs.json +29 -10
  59. package/lib/locales/de.json +70 -7
  60. package/lib/locales/en.json +25 -0
  61. package/lib/locales/es.json +3 -3
  62. package/lib/locales/fr.json +25 -0
  63. package/lib/locales/it.json +17 -5
  64. package/lib/locales/nl.json +28 -10
  65. package/lib/locales/pt_BR.json +67 -0
  66. package/lib/locales/sv.json +17 -0
  67. package/lib/packages/form-select/types.ts +3 -0
  68. package/lib/packages/form-select/use-form-option-controller.ts +5 -6
  69. package/lib/packages/form-select/use-form-select-controller.ts +1 -0
  70. package/lib/packages/form-select/use-form-select.ts +153 -109
  71. package/lib/packages/icon/DisplayIcon.vue +1 -0
  72. package/lib/packages/progress/README.md +62 -0
  73. package/lib/packages/progress/types.ts +19 -0
  74. package/lib/packages/progress/use-progress-group.ts +68 -0
  75. package/lib/packages/progress/use-progress.ts +22 -0
  76. package/lib/packages/remote-resource/README.md +115 -0
  77. package/lib/packages/remote-resource/define-remote-resource.ts +294 -0
  78. package/lib/packages/remote-resource/types.ts +28 -0
  79. package/lib/packages/threshold/README.md +30 -0
  80. package/lib/packages/threshold/type.ts +3 -0
  81. package/lib/packages/threshold/use-threshold.ts +19 -0
  82. package/lib/types/object-icon.type.ts +0 -40
  83. package/package.json +2 -2
  84. package/lib/components/icon/NewVtsIcon.vue +0 -49
  85. package/lib/components/ui/complex-icon/UiComplexIcon.vue +0 -45
  86. package/lib/components/ui/object-icon/UiObjectIcon.vue +0 -251
@@ -1,44 +1,51 @@
1
+ <!-- v2 -->
1
2
  <template>
2
- <div class="ui-quote-code" :class="className">
3
+ <div class="ui-log-entry-viewer" :class="className">
3
4
  <div class="label-container">
4
5
  <div :class="fontClasses.labelClass" class="label">
5
6
  {{ label }}
6
7
  </div>
7
- <div v-if="slots.actions || copy" class="actions">
8
- <VtsCopyButton v-if="copy" :value="codeTextValue ?? ''" />
9
- <slot name="actions" />
8
+ <div class="actions">
9
+ <VtsCopyButton :value="content" />
10
+ <UiButtonIcon
11
+ icon="fa:arrow-up-right-from-square"
12
+ size="medium"
13
+ accent="brand"
14
+ @click="openRawValueInNewTab()"
15
+ />
10
16
  </div>
11
17
  </div>
12
- <code ref="code-element" :class="fontClasses.codeClass" class="code-container">
13
- <slot />
18
+ <code :class="fontClasses.codeClass" class="code-container">
19
+ {{ content }}
14
20
  </code>
15
21
  </div>
16
22
  </template>
17
23
 
18
24
  <script setup lang="ts">
19
25
  import VtsCopyButton from '@core/components/copy-button/VtsCopyButton.vue'
26
+ import UiButtonIcon from '@core/components/ui/button-icon/UiButtonIcon.vue'
20
27
  import { useMapper } from '@core/packages/mapper'
21
28
  import { toVariants } from '@core/utils/to-variants.util.ts'
22
- import { computed, useTemplateRef } from 'vue'
29
+ import { computed, watch } from 'vue'
23
30
 
24
- type QuoteCodeAccent = 'brand' | 'danger'
25
- type QuoteCodeSize = 'small' | 'medium'
31
+ type LogEntryViewerAccent = 'info' | 'warning' | 'danger'
32
+ type LogEntryViewerSize = 'small' | 'medium'
26
33
 
27
- const { size, accent } = defineProps<{
34
+ const {
35
+ size,
36
+ accent,
37
+ content: rawContent = '',
38
+ } = defineProps<{
28
39
  label: string
29
- size: QuoteCodeSize
30
- accent: QuoteCodeAccent
31
- copy?: boolean
40
+ content: string | object | undefined
41
+ size: LogEntryViewerSize
42
+ accent: LogEntryViewerAccent
32
43
  }>()
33
44
 
34
- const slots = defineSlots<{
45
+ defineSlots<{
35
46
  default(): any
36
- actions?(): any
37
47
  }>()
38
48
 
39
- const codeElement = useTemplateRef('code-element')
40
- const codeTextValue = computed(() => codeElement.value?.textContent)
41
-
42
49
  const mapping = {
43
50
  small: {
44
51
  labelClass: 'typo-body-regular-small',
@@ -57,10 +64,32 @@ const className = computed(() =>
57
64
  accent,
58
65
  })
59
66
  )
67
+
68
+ const content = computed(() => {
69
+ if (typeof rawContent === 'object') {
70
+ return JSON.stringify(rawContent, null, 2)
71
+ }
72
+
73
+ return rawContent
74
+ })
75
+
76
+ const pre = document.createElement('pre')
77
+
78
+ watch(
79
+ () => content,
80
+ content => {
81
+ pre.textContent = content.value
82
+ },
83
+ { immediate: true }
84
+ )
85
+
86
+ function openRawValueInNewTab() {
87
+ window.open('', '_blank')?.document.body.appendChild(pre)
88
+ }
60
89
  </script>
61
90
 
62
91
  <style lang="postcss" scoped>
63
- .ui-quote-code {
92
+ .ui-log-entry-viewer {
64
93
  display: flex;
65
94
  flex-direction: column;
66
95
  gap: 0.4rem;
@@ -88,11 +117,19 @@ const className = computed(() =>
88
117
  border-inline-start: 0.2rem solid;
89
118
  white-space: pre-wrap;
90
119
  word-break: break-word;
120
+ max-height: 18rem;
121
+ overflow: auto;
122
+ }
123
+
124
+ &.accent--info {
125
+ .code-container {
126
+ border-inline-start-color: var(--color-info-item-base);
127
+ }
91
128
  }
92
129
 
93
- &.accent--brand {
130
+ &.accent--warning {
94
131
  .code-container {
95
- border-inline-start-color: var(--color-brand-item-base);
132
+ border-inline-start-color: var(--color-warning-item-base);
96
133
  }
97
134
  }
98
135
 
@@ -3,7 +3,7 @@
3
3
  <RouterLink v-if="route && !disabled" :to="route" class="ui-object-link is-link typo-action-link-small">
4
4
  <span class="icon">
5
5
  <slot name="icon">
6
- <VtsIcon :icon accent="current" />
6
+ <VtsIcon :name="icon" size="medium" />
7
7
  </slot>
8
8
  </span>
9
9
  <span v-tooltip class="content text-ellipsis">
@@ -13,7 +13,7 @@
13
13
  <span v-else :class="{ disabled }" class="ui-object-link typo-action-link-small">
14
14
  <span class="icon">
15
15
  <slot name="icon">
16
- <VtsIcon :icon accent="current" />
16
+ <VtsIcon :name="icon" size="medium" />
17
17
  </slot>
18
18
  </span>
19
19
  <slot />
@@ -23,13 +23,13 @@
23
23
  <script lang="ts" setup>
24
24
  import VtsIcon from '@core/components/icon/VtsIcon.vue'
25
25
  import { vTooltip } from '@core/directives/tooltip.directive'
26
- import type { IconDefinition } from '@fortawesome/fontawesome-common-types'
26
+ import type { IconName } from '@core/icons'
27
27
  import { type RouteLocationRaw } from 'vue-router'
28
28
 
29
29
  defineProps<{
30
30
  route?: RouteLocationRaw
31
31
  disabled?: boolean
32
- icon?: IconDefinition
32
+ icon?: IconName
33
33
  }>()
34
34
 
35
35
  defineSlots<{
@@ -10,7 +10,7 @@
10
10
  type="text"
11
11
  accent="brand"
12
12
  :aria-label="uiStore.isMobile ? t('core.query-search-bar.label') : undefined"
13
- :icon="!uiStore.isMobile ? faMagnifyingGlass : undefined"
13
+ :icon="!uiStore.isMobile ? 'fa:magnifying-glass' : undefined"
14
14
  :placeholder="t('core.query-search-bar.placeholder')"
15
15
  />
16
16
  <template v-if="!uiStore.isMobile">
@@ -32,8 +32,8 @@
32
32
 
33
33
  <!-- Mobile icons: search + filter -->
34
34
  <template v-else>
35
- <UiButtonIcon accent="brand" size="medium" type="submit" :icon="faMagnifyingGlass" class="action-button" />
36
- <UiButtonIcon accent="brand" size="medium" disabled :icon="faFilter" class="action-button" />
35
+ <UiButtonIcon accent="brand" size="medium" type="submit" icon="fa:magnifying-glass" class="action-button" />
36
+ <UiButtonIcon accent="brand" size="medium" disabled icon="fa:filter" class="action-button" />
37
37
  </template>
38
38
  </form>
39
39
  </template>
@@ -46,7 +46,6 @@ import UiInput from '@core/components/ui/input/UiInput.vue'
46
46
  import { vTooltip } from '@core/directives/tooltip.directive'
47
47
  import { useUiStore } from '@core/stores/ui.store'
48
48
  import { uniqueId } from '@core/utils/unique-id.util'
49
- import { faFilter, faMagnifyingGlass } from '@fortawesome/free-solid-svg-icons'
50
49
  import { ref } from 'vue'
51
50
  import { useI18n } from 'vue-i18n'
52
51
 
@@ -2,7 +2,7 @@
2
2
  <template>
3
3
  <li class="ui-quick-task-item">
4
4
  <div v-if="hasSubTasks" class="toggle" @click="toggleExpand()">
5
- <UiButtonIcon accent="brand" :icon="isExpanded ? faAngleDown : faAngleRight" size="small" />
5
+ <UiButtonIcon accent="brand" :icon="isExpanded ? 'fa:angle-down' : 'fa:angle-right'" size="small" />
6
6
  </div>
7
7
  <div class="content">
8
8
  <div class="typo-body-bold">
@@ -12,14 +12,14 @@
12
12
  <div class="line-1">
13
13
  <UiTag v-if="task.tag" accent="neutral" variant="primary">{{ task.tag }}</UiTag>
14
14
  <div v-if="hasSubTasks" class="subtasks">
15
- <VtsIcon :icon="faCircleNotch" accent="current" />
15
+ <VtsIcon name="fa:circle-notch" size="medium" />
16
16
  <span class="typo-body-regular-small">{{ t('tasks.n-subtasks', { n: subTasksCount }) }}</span>
17
17
  </div>
18
18
  </div>
19
19
  <div v-if="task.start" class="line-2 typo-body-regular-small">
20
20
  {{ d(task.start, 'datetime_short') }}
21
21
  <template v-if="task.end">
22
- <VtsIcon :icon="faArrowRight" accent="current" />
22
+ <VtsIcon name="fa:arrow-right" size="medium" />
23
23
  {{ d(new Date(task.end), 'datetime_short') }}
24
24
  </template>
25
25
  </div>
@@ -34,7 +34,6 @@ import VtsIcon from '@core/components/icon/VtsIcon.vue'
34
34
  import VtsQuickTaskList from '@core/components/task/VtsQuickTaskList.vue'
35
35
  import UiButtonIcon from '@core/components/ui/button-icon/UiButtonIcon.vue'
36
36
  import UiTag from '@core/components/ui/tag/UiTag.vue'
37
- import { faAngleDown, faAngleRight, faArrowRight, faCircleNotch } from '@fortawesome/free-solid-svg-icons'
38
37
  import { useToggle } from '@vueuse/core'
39
38
  import { computed } from 'vue'
40
39
  import { useI18n } from 'vue-i18n'
@@ -3,7 +3,7 @@
3
3
  <label :class="variant" class="ui-radio-button typo-body-regular">
4
4
  <span class="radio-container">
5
5
  <input v-model="model" :disabled="isDisabled" :value class="input" type="radio" />
6
- <VtsIcon :icon="faCircle" accent="current" class="radio-icon" />
6
+ <VtsIcon name="fa:circle" size="medium" class="radio-icon" />
7
7
  </span>
8
8
  <slot />
9
9
  </label>
@@ -13,7 +13,6 @@
13
13
  import VtsIcon from '@core/components/icon/VtsIcon.vue'
14
14
  import { useDisabled } from '@core/composables/disabled.composable'
15
15
  import { toVariants } from '@core/utils/to-variants.util'
16
- import { faCircle } from '@fortawesome/free-solid-svg-icons'
17
16
  import { computed } from 'vue'
18
17
 
19
18
  const { accent, value, disabled } = defineProps<{
@@ -4,33 +4,10 @@
4
4
 
5
5
  <script setup lang="ts">
6
6
  import UiButtonIcon from '@core/components/ui/button-icon/UiButtonIcon.vue'
7
- import type { IconDefinition } from '@fortawesome/fontawesome-common-types'
7
+ import type { IconName } from '@core/icons'
8
8
 
9
9
  defineProps<{
10
10
  disabled: boolean
11
- icon: IconDefinition
11
+ icon: IconName
12
12
  }>()
13
13
  </script>
14
-
15
- <style scoped lang="postcss">
16
- .pagination-button.accent--brand {
17
- border: 0.1rem solid var(--color-neutral-border);
18
- font-size: 1rem;
19
- /* Override UiButtonIcon size to match DS */
20
- width: 3rem;
21
- height: 3rem;
22
-
23
- &:hover {
24
- border-color: var(--color-brand-item-hover);
25
- }
26
-
27
- &:active {
28
- border-color: var(--color-brand-item-active);
29
- }
30
-
31
- &:disabled {
32
- background-color: var(--color-neutral-background-disabled);
33
- border-color: transparent;
34
- }
35
- }
36
- </style>
@@ -1,45 +1,41 @@
1
- <!-- v3 -->
1
+ <!-- v5 -->
2
2
  <template>
3
- <div class="ui-table-pagination">
4
- <div class="buttons-container">
5
- <PaginationButton :disabled="isFirstPage" :icon="faAngleDoubleLeft" @click="emit('first')" />
6
- <PaginationButton :disabled="isFirstPage" :icon="faAngleLeft" @click="emit('previous')" />
7
- <PaginationButton :disabled="isLastPage" :icon="faAngleRight" @click="emit('next')" />
8
- <PaginationButton :disabled="isLastPage" :icon="faAngleDoubleRight" @click="emit('last')" />
3
+ <div class="ui-table-pagination" :class="className">
4
+ <div class="container">
5
+ <span class="typo-body-regular-small label">
6
+ {{ t('core.select.n-object-of', { from, to, total }) }}
7
+ </span>
8
+ <div class="buttons-container">
9
+ <PaginationButton :disabled="isFirstPage" icon="fa:angle-double-left" @click="emit('first')" />
10
+ <PaginationButton :disabled="isFirstPage" icon="fa:angle-left" @click="emit('previous')" />
11
+ <PaginationButton :disabled="isLastPage" icon="fa:angle-right" @click="emit('next')" />
12
+ <PaginationButton :disabled="isLastPage" icon="fa:angle-double-right" @click="emit('last')" />
13
+ </div>
9
14
  </div>
10
- <span class="typo-body-regular-small label">
11
- {{ t('core.select.n-object-of', { from, to, total }) }}
12
- </span>
13
- <span class="typo-body-regular-small label show">{{ t('core.pagination.show-by') }}</span>
14
- <div class="dropdown-wrapper">
15
- <select v-model="showBy" class="dropdown typo-body-regular-small">
16
- <option v-for="option in [12, 24, 48, -1]" :key="option" :value="option" class="typo-body-bold-small">
17
- {{ option === -1 ? t('core.pagination.all') : option }}
18
- </option>
19
- </select>
20
- <VtsIcon :icon="faAngleDown" accent="current" class="icon" />
15
+ <div class="container">
16
+ <span class="typo-body-regular-small label show">{{ t('core.pagination.show-by') }}</span>
17
+ <VtsSelect :id="showBySelectId" accent="brand" class="typo-body-regular-small show-by-select" />
21
18
  </div>
22
19
  </div>
23
20
  </template>
24
21
 
25
22
  <script lang="ts" setup>
26
- import VtsIcon from '@core/components/icon/VtsIcon.vue'
23
+ import VtsSelect from '@core/components/select/VtsSelect.vue'
27
24
  import PaginationButton from '@core/components/ui/table-pagination/PaginationButton.vue'
28
- import {
29
- faAngleDoubleLeft,
30
- faAngleDoubleRight,
31
- faAngleDown,
32
- faAngleLeft,
33
- faAngleRight,
34
- } from '@fortawesome/free-solid-svg-icons'
25
+ import { useFormSelect } from '@core/packages/form-select'
26
+ import { toVariants } from '@core/utils/to-variants.util.ts'
27
+ import { computed } from 'vue'
35
28
  import { useI18n } from 'vue-i18n'
36
29
 
37
- defineProps<{
30
+ export type TablePaginationSize = 'small' | 'medium'
31
+
32
+ const { size } = defineProps<{
38
33
  from: number
39
34
  to: number
40
35
  total: number
41
36
  isFirstPage: boolean
42
37
  isLastPage: boolean
38
+ size: TablePaginationSize
43
39
  }>()
44
40
 
45
41
  const emit = defineEmits<{
@@ -51,7 +47,16 @@ const emit = defineEmits<{
51
47
 
52
48
  const showBy = defineModel<number>('showBy', { default: 24 })
53
49
 
50
+ const className = computed(() => toVariants({ size }))
51
+
54
52
  const { t } = useI18n()
53
+
54
+ const { id: showBySelectId } = useFormSelect([12, 24, 48, -1], {
55
+ model: showBy,
56
+ option: {
57
+ label: option => (option === -1 ? t('core.pagination.all') : option.toString()),
58
+ },
59
+ })
55
60
  </script>
56
61
 
57
62
  <style lang="postcss" scoped>
@@ -60,6 +65,21 @@ const { t } = useI18n()
60
65
  align-items: center;
61
66
  gap: 0.8rem;
62
67
 
68
+ &.size--small {
69
+ flex-direction: column;
70
+ align-items: flex-end;
71
+ }
72
+
73
+ &.size--medium {
74
+ flex-direction: row;
75
+ }
76
+
77
+ .container {
78
+ display: flex;
79
+ gap: 0.8rem;
80
+ align-items: center;
81
+ }
82
+
63
83
  .buttons-container {
64
84
  display: flex;
65
85
  gap: 0.2rem;
@@ -69,78 +89,19 @@ const { t } = useI18n()
69
89
  color: var(--color-neutral-txt-secondary);
70
90
  }
71
91
 
72
- .show::before {
73
- content: '-';
74
- margin-right: 0.8rem;
75
- }
76
-
77
- .dropdown-wrapper {
78
- position: relative;
92
+ /* Workaround: we don't have "small" select yet */
93
+ .show-by-select {
94
+ width: 6rem;
79
95
 
80
- .dropdown {
81
- cursor: pointer;
82
- padding: 0.2rem 0.6rem;
96
+ &:deep(.ui-input) {
83
97
  height: 3rem;
84
- width: 5rem;
85
- appearance: none;
86
- border-radius: 0.4rem;
87
- color: var(--color-brand-txt-base);
88
- border: 0.1rem solid var(--color-neutral-border);
89
- background-color: var(--color-neutral-background-primary);
90
-
91
- &:hover {
92
- border-color: var(--color-brand-item-hover);
93
- background-color: var(--color-brand-background-hover);
94
- color: var(--color-brand-txt-hover);
95
-
96
- + .icon {
97
- color: var(--color-brand-txt-hover);
98
- }
99
- }
100
-
101
- &:disabled {
102
- cursor: not-allowed;
103
- background-color: var(--color-neutral-background-disabled);
104
- color: var(--color-neutral-txt-secondary);
105
- border-color: transparent;
106
-
107
- + .icon {
108
- color: var(--color-neutral-txt-secondary);
109
- }
110
- }
111
-
112
- &:active {
113
- background-color: var(--color-brand-background-active);
114
- border-color: var(--color-brand-item-active);
115
- }
116
-
117
- &:focus-visible {
118
- outline: 0.1rem solid var(--color-brand-item-base);
119
- border: 0.1rem solid var(--color-brand-item-base);
120
- color: var(--color-brand-txt-base);
121
- background-color: var(--color-brand-background-selected);
122
-
123
- + .icon {
124
- color: var(--color-brand-txt-base);
125
- }
126
- }
127
-
128
- option {
129
- background-color: var(--color-neutral-background-primary);
130
- border: 0.1rem solid var(--color-neutral-border);
131
- border-radius: 0.4rem;
132
- color: var(--color-neutral-txt-primary);
133
- }
98
+ padding-inline: 0.8rem;
99
+ gap: 0.8rem;
100
+ min-width: 6rem;
134
101
  }
135
102
 
136
- .icon {
137
- position: absolute;
138
- top: 50%;
139
- right: 0.8rem;
140
- transform: translateY(-50%);
141
- pointer-events: none;
142
- font-size: 1rem;
143
- color: var(--color-brand-txt-base);
103
+ &:deep(.input) {
104
+ font-size: 1.4rem;
144
105
  }
145
106
  }
146
107
  }
@@ -3,7 +3,7 @@
3
3
  <template>
4
4
  <span :class="toVariants({ accent, variant })" class="ui-tag typo-body-regular-small">
5
5
  <slot name="icon">
6
- <VtsIcon :icon accent="current" fixed-width />
6
+ <VtsIcon :name="icon" size="medium" />
7
7
  </slot>
8
8
  <span class="text-ellipsis"><slot /></span>
9
9
  </span>
@@ -11,8 +11,8 @@
11
11
 
12
12
  <script lang="ts" setup>
13
13
  import VtsIcon from '@core/components/icon/VtsIcon.vue'
14
+ import type { IconName } from '@core/icons'
14
15
  import { toVariants } from '@core/utils/to-variants.util'
15
- import type { IconDefinition } from '@fortawesome/fontawesome-common-types'
16
16
 
17
17
  type TagAccent = 'info' | 'neutral' | 'success' | 'warning' | 'danger' | 'muted'
18
18
  type TagVariant = 'primary' | 'secondary'
@@ -20,7 +20,7 @@ type TagVariant = 'primary' | 'secondary'
20
20
  defineProps<{
21
21
  accent: TagAccent
22
22
  variant: TagVariant
23
- icon?: IconDefinition
23
+ icon?: IconName
24
24
  }>()
25
25
 
26
26
  defineSlots<{
@@ -19,8 +19,8 @@
19
19
  import UiCharacterLimit from '@core/components/ui/character-limit/UiCharacterLimit.vue'
20
20
  import UiInfo from '@core/components/ui/info/UiInfo.vue'
21
21
  import UiLabel from '@core/components/ui/label/UiLabel.vue'
22
+ import type { IconName } from '@core/icons'
22
23
  import { toVariants } from '@core/utils/to-variants.util'
23
- import type { IconDefinition } from '@fortawesome/fontawesome-common-types'
24
24
  import { useFocus } from '@vueuse/core'
25
25
  import { computed, useAttrs, useId, useTemplateRef } from 'vue'
26
26
  import { useI18n } from 'vue-i18n'
@@ -39,7 +39,7 @@ const {
39
39
  maxCharacters?: number
40
40
  disabled?: boolean
41
41
  href?: string
42
- icon?: IconDefinition
42
+ icon?: IconName
43
43
  required?: boolean
44
44
  }>()
45
45
 
@@ -2,7 +2,7 @@
2
2
  <template>
3
3
  <div :class="toVariants({ accent })" class="ui-toaster">
4
4
  <div class="content">
5
- <VtsIcon class="information-icon" :accent :icon="faCircle" :overlay-icon="icon" />
5
+ <VtsIcon class="information-icon" :name="icon" size="medium" />
6
6
  <div>
7
7
  <div class="typo-h5">
8
8
  <slot />
@@ -11,7 +11,7 @@
11
11
  <slot name="description" />
12
12
  </div>
13
13
  </div>
14
- <UiButtonIcon class="close-icon" :icon="faXmark" accent="brand" size="medium" @click="emit('close')" />
14
+ <UiButtonIcon class="close-icon" icon="fa:xmark" accent="brand" size="medium" @click="emit('close')" />
15
15
  </div>
16
16
  <div v-if="slots.actions" class="actions">
17
17
  <slot name="actions" />
@@ -22,14 +22,13 @@
22
22
  <script setup lang="ts">
23
23
  import VtsIcon from '@core/components/icon/VtsIcon.vue'
24
24
  import UiButtonIcon from '@core/components/ui/button-icon/UiButtonIcon.vue'
25
+ import type { IconName } from '@core/icons'
26
+ import { useMapper } from '@core/packages/mapper'
25
27
  import { toVariants } from '@core/utils/to-variants.util'
26
- import type { IconDefinition } from '@fortawesome/fontawesome-common-types'
27
- import { faCheck, faCircle, faExclamation, faInfo, faXmark } from '@fortawesome/free-solid-svg-icons'
28
- import { computed } from 'vue'
29
28
 
30
29
  type ToasterAccent = 'info' | 'success' | 'warning' | 'danger'
31
30
 
32
- const props = defineProps<{
31
+ const { accent } = defineProps<{
33
32
  accent: ToasterAccent
34
33
  }>()
35
34
 
@@ -43,13 +42,16 @@ const slots = defineSlots<{
43
42
  actions?(): any
44
43
  }>()
45
44
 
46
- const states: Record<ToasterAccent, IconDefinition> = {
47
- info: faInfo,
48
- success: faCheck,
49
- warning: faExclamation,
50
- danger: faXmark,
51
- }
52
- const icon = computed(() => states[props.accent])
45
+ const icon = useMapper<ToasterAccent, IconName>(
46
+ () => accent,
47
+ {
48
+ info: 'legacy:status:info',
49
+ success: 'legacy:status:success',
50
+ warning: 'legacy:status:warning',
51
+ danger: 'legacy:status:danger',
52
+ },
53
+ 'info'
54
+ )
53
55
  </script>
54
56
 
55
57
  <style scoped lang="postcss">
@@ -19,7 +19,7 @@
19
19
  v-tooltip="isExpanded ? t('core.close') : t('core.open')"
20
20
  class="toggle"
21
21
  accent="brand"
22
- :icon="isExpanded ? faAngleDown : faAngleRight"
22
+ :icon="isExpanded ? 'fa:angle-down' : 'fa:angle-right'"
23
23
  size="small"
24
24
  :target-scale="{ x: 1.5, y: 2 }"
25
25
  @click="emit('toggle')"
@@ -27,7 +27,7 @@
27
27
  <div v-else class="h-line" />
28
28
  <a v-tooltip="{ selector: '.text' }" :href class="link typo-body-bold-small" @click="navigate">
29
29
  <slot name="icon">
30
- <VtsIcon :icon accent="current" class="icon" />
30
+ <VtsIcon :name="icon" size="medium" class="icon" />
31
31
  </slot>
32
32
  <div class="text text-ellipsis">
33
33
  <slot />
@@ -43,9 +43,8 @@ import VtsIcon from '@core/components/icon/VtsIcon.vue'
43
43
  import VtsTreeLine from '@core/components/tree/VtsTreeLine.vue'
44
44
  import UiButtonIcon from '@core/components/ui/button-icon/UiButtonIcon.vue'
45
45
  import { vTooltip } from '@core/directives/tooltip.directive'
46
+ import type { IconName } from '@core/icons'
46
47
  import { IK_TREE_ITEM_EXPANDED, IK_TREE_ITEM_HAS_CHILDREN, IK_TREE_LIST_DEPTH } from '@core/utils/injection-keys.util'
47
- import type { IconDefinition } from '@fortawesome/fontawesome-common-types'
48
- import { faAngleDown, faAngleRight } from '@fortawesome/free-solid-svg-icons'
49
48
  import { inject, ref, useAttrs } from 'vue'
50
49
  import { useI18n } from 'vue-i18n'
51
50
  import type { RouteLocationRaw } from 'vue-router'
@@ -56,7 +55,7 @@ defineOptions({
56
55
 
57
56
  defineProps<{
58
57
  route: RouteLocationRaw
59
- icon?: IconDefinition
58
+ icon?: IconName
60
59
  active?: boolean
61
60
  }>()
62
61
 
@@ -0,0 +1,42 @@
1
+ # `useDefaultTab` Composable
2
+
3
+ This composable manages automatic navigation to default tabs and remembers the last visited tab for a given router dispatcher.
4
+
5
+ ## How it works
6
+
7
+ The composable watches route changes and:
8
+
9
+ - Automatically redirects to the remembered or default tab when navigating to the base dispatcher route
10
+ - Stores the current tab in localStorage for future visits
11
+ - Uses the naming convention `{dispatcherRouteName}/{tabName}` for tab route names
12
+
13
+ ## Parameters
14
+
15
+ | Name | Type | Required | Description |
16
+ | --------------------- | -------- | :------: | ----------------------------------------------- |
17
+ | `dispatcherRouteName` | `string` | ✓ | Dispatcher page route name (e.g., '/pool/<id>') |
18
+ | `defaultTab` | `string` | ✓ | Default tab name (e.g., 'dashboard') |
19
+
20
+ ## Usage
21
+
22
+ ```typescript
23
+ // In the dispatcher page component (e.g., `pages/pool/[id].vue`)
24
+ useDefaultTab('pool/[id]', 'dashboard')
25
+
26
+ // User first navigates to /pool/123
27
+ // → Automatic redirect to /pool/123/dashboard (default tab)
28
+
29
+ // User then navigates to /pool/123/stats
30
+ // → 'stats' is stored as the last visited tab for this route
31
+
32
+ // Finally, user navigates to /pool/456
33
+ // → Automatic redirect to /pool/456/stats
34
+ ```
35
+
36
+ ## Storage
37
+
38
+ Tab preferences are stored in localStorage under the key `default-tabs` with the structure:
39
+
40
+ ```typescript
41
+ Map<string, string> // dispatcherRouteName -> lastVisitedTab
42
+ ```