@xen-orchestra/web-core 0.31.1 → 0.32.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 (64) hide show
  1. package/lib/assets/css/_colors.pcss +8 -0
  2. package/lib/components/button-group/VtsButtonGroup.vue +5 -1
  3. package/lib/components/menu/MenuList.vue +1 -0
  4. package/lib/components/modal/VtsModal.vue +82 -0
  5. package/lib/components/modal/VtsModalButton.vue +36 -0
  6. package/lib/components/modal/VtsModalCancelButton.vue +37 -0
  7. package/lib/components/modal/VtsModalConfirmButton.vue +21 -0
  8. package/lib/components/modal/VtsModalList.vue +34 -0
  9. package/lib/components/object-icon/VtsObjectIcon.vue +3 -8
  10. package/lib/components/status/VtsStatus.vue +66 -0
  11. package/lib/components/task/VtsQuickTaskList.vue +17 -5
  12. package/lib/components/tree/VtsTreeItem.vue +2 -2
  13. package/lib/components/ui/button/UiButton.vue +13 -67
  14. package/lib/components/ui/input/UiInput.vue +4 -1
  15. package/lib/components/ui/modal/UiModal.vue +164 -0
  16. package/lib/components/ui/quick-task-item/UiQuickTaskItem.vue +2 -2
  17. package/lib/composables/context.composable.ts +3 -5
  18. package/lib/composables/link-component.composable.ts +3 -2
  19. package/lib/composables/pagination.composable.ts +3 -2
  20. package/lib/composables/tree-filter.composable.ts +5 -3
  21. package/lib/icons/fa-icons.ts +4 -0
  22. package/lib/icons/index.ts +17 -0
  23. package/lib/locales/en.json +14 -1
  24. package/lib/locales/fr.json +14 -1
  25. package/lib/packages/collection/use-collection.ts +3 -2
  26. package/lib/packages/form-select/use-form-option-controller.ts +3 -2
  27. package/lib/packages/form-select/use-form-select.ts +8 -7
  28. package/lib/packages/menu/action.ts +4 -3
  29. package/lib/packages/menu/link.ts +5 -4
  30. package/lib/packages/menu/router-link.ts +3 -2
  31. package/lib/packages/menu/toggle-target.ts +3 -2
  32. package/lib/packages/modal/ModalProvider.vue +17 -0
  33. package/lib/packages/modal/README.md +253 -0
  34. package/lib/packages/modal/create-modal-opener.ts +103 -0
  35. package/lib/packages/modal/modal.store.ts +22 -0
  36. package/lib/packages/modal/types.ts +92 -0
  37. package/lib/packages/modal/use-modal.ts +53 -0
  38. package/lib/packages/progress/use-progress.ts +4 -3
  39. package/lib/packages/table/README.md +336 -0
  40. package/lib/packages/table/apply-extensions.ts +26 -0
  41. package/lib/packages/table/define-columns.ts +62 -0
  42. package/lib/packages/table/define-renderer/define-table-cell-renderer.ts +27 -0
  43. package/lib/packages/table/define-renderer/define-table-renderer.ts +47 -0
  44. package/lib/packages/table/define-renderer/define-table-row-renderer.ts +29 -0
  45. package/lib/packages/table/define-renderer/define-table-section-renderer.ts +29 -0
  46. package/lib/packages/table/define-table/define-multi-source-table.ts +39 -0
  47. package/lib/packages/table/define-table/define-table.ts +13 -0
  48. package/lib/packages/table/define-table/define-typed-table.ts +18 -0
  49. package/lib/packages/table/index.ts +11 -0
  50. package/lib/packages/table/transform-sources.ts +13 -0
  51. package/lib/packages/table/types/extensions.ts +16 -0
  52. package/lib/packages/table/types/index.ts +47 -0
  53. package/lib/packages/table/types/table-cell.ts +18 -0
  54. package/lib/packages/table/types/table-row.ts +20 -0
  55. package/lib/packages/table/types/table-section.ts +19 -0
  56. package/lib/packages/table/types/table.ts +28 -0
  57. package/lib/packages/threshold/use-threshold.ts +4 -3
  58. package/lib/types/vue-virtual-scroller.d.ts +101 -0
  59. package/lib/utils/injection-keys.util.ts +3 -0
  60. package/lib/utils/progress.util.ts +2 -1
  61. package/lib/utils/to-computed.util.ts +15 -0
  62. package/package.json +3 -2
  63. package/lib/components/backup-state/VtsBackupState.vue +0 -37
  64. package/lib/components/connection-status/VtsConnectionStatus.vue +0 -36
@@ -0,0 +1,47 @@
1
+ import type { Extensions, TableRenderer, TableCellRenderer, TableRowRenderer, TableSectionRenderer } from '.'
2
+ import type { ComputedRef } from 'vue'
3
+
4
+ export * from './table-cell'
5
+ export * from './table-row'
6
+ export * from './extensions'
7
+ export * from './table'
8
+ export * from './table-section'
9
+
10
+ export type ComponentLoader<TProps> = () => Promise<{
11
+ default: abstract new () => {
12
+ $props: TProps
13
+ }
14
+ }>
15
+
16
+ export type PropsOverride<TComponentProps> = Partial<TComponentProps> & Record<string, any>
17
+
18
+ export type Renderer<
19
+ TComponentProps extends Record<string, any>,
20
+ TExtensions extends Extensions<TComponentProps>,
21
+ TPropsConfig extends Record<string, any>,
22
+ > =
23
+ | TableRenderer<TComponentProps, TExtensions, TPropsConfig>
24
+ | TableSectionRenderer<TComponentProps, TExtensions, TPropsConfig>
25
+ | TableRowRenderer<TComponentProps, TExtensions, TPropsConfig>
26
+ | TableCellRenderer<TComponentProps, TExtensions, TPropsConfig>
27
+
28
+ export type Sources<T = any> = ComputedRef<T[]>
29
+
30
+ export type TransformProperty<
31
+ TSource,
32
+ TUseSource,
33
+ TPropertyName extends string = 'transform',
34
+ > = TUseSource extends TSource
35
+ ? { [K in TPropertyName]?: (source: TUseSource, index: number) => Partial<TSource> }
36
+ : {
37
+ [K in TPropertyName]: (
38
+ source: TUseSource,
39
+ index: number
40
+ ) => Partial<TSource> & {
41
+ [K in keyof TSource as K extends keyof TUseSource
42
+ ? TUseSource[K] extends TSource[K]
43
+ ? never
44
+ : K
45
+ : K]: TSource[K]
46
+ }
47
+ }
@@ -0,0 +1,18 @@
1
+ import type { Branded } from '@core/types/utility.type'
2
+ import type { PropsOverride, Extensions } from '.'
3
+ import type { VNode } from 'vue'
4
+
5
+ export type TableCellVNode = Branded<'CellVNode', VNode>
6
+
7
+ export type TableCellVNodes = TableCellVNode | TableCellVNodes[]
8
+
9
+ export type TableCellRenderer<
10
+ TComponentProps extends Record<string, any>,
11
+ TExtensions extends Extensions<TComponentProps>,
12
+ TPropsConfig extends Record<string, any>,
13
+ > = (
14
+ renderConfig: {
15
+ extensions?: { [K in keyof TExtensions]?: Parameters<TExtensions[K]>[0] }
16
+ props?: PropsOverride<TComponentProps>
17
+ } & TPropsConfig
18
+ ) => TableCellVNode
@@ -0,0 +1,20 @@
1
+ import type { Branded } from '@core/types/utility.type'
2
+ import type { PropsOverride, Extensions, TableCellVNodes } from '.'
3
+ import type { VNode } from 'vue'
4
+
5
+ export type TableRowVNode = Branded<'RowVNode', VNode>
6
+
7
+ export type TableRowVNodes = TableRowVNode | TableRowVNodes[]
8
+
9
+ export type TableRowRenderer<
10
+ TComponentProps extends Record<string, any>,
11
+ TExtensions extends Extensions<TComponentProps>,
12
+ TPropsConfig extends Record<string, any>,
13
+ > = (
14
+ renderConfig: {
15
+ extensions?: { [K in keyof TExtensions]?: Parameters<TExtensions[K]>[0] }
16
+ key: string | number
17
+ props?: PropsOverride<TComponentProps>
18
+ cells: () => TableCellVNodes
19
+ } & TPropsConfig
20
+ ) => TableRowVNode
@@ -0,0 +1,19 @@
1
+ import type { Branded } from '@core/types/utility.type'
2
+ import type { PropsOverride, Extensions, TableRowVNodes } from '.'
3
+ import type { VNode } from 'vue'
4
+
5
+ export type TableSectionVNode = Branded<'SectionVNode', VNode>
6
+
7
+ export type TableSectionVNodes = TableSectionVNode | TableSectionVNodes[]
8
+
9
+ export type TableSectionRenderer<
10
+ TComponentProps extends Record<string, any>,
11
+ TExtensions extends Extensions<TComponentProps>,
12
+ TPropsConfig extends Record<string, any>,
13
+ > = (
14
+ renderConfig: {
15
+ extensions?: { [K in keyof TExtensions]?: Parameters<TExtensions[K]>[0] }
16
+ rows: () => TableRowVNodes
17
+ props?: PropsOverride<TComponentProps>
18
+ } & TPropsConfig
19
+ ) => TableSectionVNode
@@ -0,0 +1,28 @@
1
+ import type { Branded } from '@core/types/utility.type'
2
+ import type {
3
+ TableCellVNodes,
4
+ PropsOverride,
5
+ TableRowVNodes,
6
+ TableSectionVNode,
7
+ TableSectionVNodes,
8
+ Extensions,
9
+ } from '.'
10
+ import type { VNode } from 'vue'
11
+
12
+ export type TableVNode = Branded<'TableVNode', VNode>
13
+
14
+ export type TableRenderer<
15
+ TComponentProps extends Record<string, any>,
16
+ TExtensions extends Extensions<TComponentProps>,
17
+ TPropsConfig extends Record<string, any>,
18
+ > = (
19
+ renderConfig: {
20
+ extensions?: { [K in keyof TExtensions]?: Parameters<TExtensions[K]>[0] }
21
+ props?: PropsOverride<TComponentProps>
22
+ thead:
23
+ | (() => TableSectionVNode)
24
+ | { rows: () => TableRowVNodes; cells?: never }
25
+ | { rows?: never; cells: () => TableCellVNodes }
26
+ tbody: (() => TableSectionVNodes) | { rows: () => TableRowVNodes }
27
+ } & TPropsConfig
28
+ ) => TableVNode
@@ -1,13 +1,14 @@
1
1
  import type { ThresholdConfig, ThresholdResult } from '@core/packages/threshold/type.ts'
2
- import { computed, type ComputedRef, type MaybeRefOrGetter, toValue } from 'vue'
2
+ import { toComputed } from '@core/utils/to-computed.util'
3
+ import { computed, type ComputedRef, type MaybeRefOrGetter } from 'vue'
3
4
 
4
5
  export function useThreshold<TPayload>(
5
6
  rawCurrentValue: MaybeRefOrGetter<number>,
6
7
  rawConfig: MaybeRefOrGetter<ThresholdConfig<TPayload>>
7
8
  ): ComputedRef<ThresholdResult<TPayload>> {
8
- const currentValue = computed(() => toValue(rawCurrentValue))
9
+ const currentValue = toComputed(rawCurrentValue)
9
10
 
10
- const config = computed(() => toValue(rawConfig))
11
+ const config = toComputed(rawConfig)
11
12
 
12
13
  return computed(
13
14
  () =>
@@ -0,0 +1,101 @@
1
+ declare module 'vue-virtual-scroller' {
2
+ import { type ObjectEmitsOptions, type PublicProps, type SetupContext, type SlotsType, type VNode } from 'vue'
3
+
4
+ interface RecycleScrollerProps<T> {
5
+ items: readonly T[]
6
+ direction?: 'vertical' | 'horizontal'
7
+ itemSize?: number | null
8
+ gridItems?: number
9
+ itemSecondarySize?: number
10
+ minItemSize?: number
11
+ sizeField?: string
12
+ typeField?: string
13
+ keyField?: keyof T
14
+ pageMode?: boolean
15
+ prerender?: number
16
+ buffer?: number
17
+ emitUpdate?: boolean
18
+ updateInterval?: number
19
+ listClass?: string
20
+ itemClass?: string
21
+ listTag?: string
22
+ itemTag?: string
23
+ }
24
+
25
+ interface DynamicScrollerProps<T> extends RecycleScrollerProps<T> {
26
+ minItemSize: number
27
+ }
28
+
29
+ interface RecycleScrollerEmitOptions extends ObjectEmitsOptions {
30
+ resize: () => void
31
+ visible: () => void
32
+ hidden: () => void
33
+ update: (startIndex: number, endIndex: number, visibleStartIndex: number, visibleEndIndex: number) => void
34
+ 'scroll-start': () => void
35
+ 'scroll-end': () => void
36
+ }
37
+
38
+ interface RecycleScrollerSlotProps<T> {
39
+ item: T
40
+ index: number
41
+ active: boolean
42
+ }
43
+
44
+ interface RecycleScrollerSlots<T> {
45
+ default(slotProps: RecycleScrollerSlotProps<T>): unknown
46
+ before(): unknown
47
+ empty(): unknown
48
+ after(): unknown
49
+ }
50
+
51
+ export interface RecycleScrollerInstance {
52
+ getScroll(): { start: number; end: number }
53
+ scrollToItem(index: number): void
54
+ scrollToPosition(position: number): void
55
+ }
56
+
57
+ export const RecycleScroller: <T>(
58
+ props: RecycleScrollerProps<T> & PublicProps,
59
+ ctx?: SetupContext<RecycleScrollerEmitOptions, SlotsType<RecycleScrollerSlots<T>>>,
60
+ expose?: (exposed: RecycleScrollerInstance) => void
61
+ ) => VNode & {
62
+ __ctx?: {
63
+ props: RecycleScrollerProps<T> & PublicProps
64
+ expose(exposed: RecycleScrollerInstance): void
65
+ slots: RecycleScrollerSlots<T>
66
+ }
67
+ }
68
+
69
+ export const DynamicScroller: <T>(
70
+ props: DynamicScrollerProps<T> & PublicProps,
71
+ ctx?: SetupContext<RecycleScrollerEmitOptions, SlotsType<RecycleScrollerSlots<T>>>,
72
+ expose?: (exposed: RecycleScrollerInstance) => void
73
+ ) => VNode & {
74
+ __ctx?: {
75
+ props: DynamicScrollerProps<T> & PublicProps
76
+ expose(exposed: RecycleScrollerInstance): void
77
+ slots: RecycleScrollerSlots<T>
78
+ }
79
+ }
80
+
81
+ interface DynamicScrollerItemProps<T> {
82
+ item: T
83
+ active: boolean
84
+ sizeDependencies?: unknown[]
85
+ watchData?: boolean
86
+ tag?: string
87
+ emitResize?: boolean
88
+ onResize?: () => void
89
+ }
90
+
91
+ interface DynamicScrollerItemEmitOptions extends ObjectEmitsOptions {
92
+ resize: () => void
93
+ }
94
+
95
+ export const DynamicScrollerItem: <T>(
96
+ props: DynamicScrollerItemProps<T> & PublicProps,
97
+ ctx?: SetupContext<DynamicScrollerItemEmitOptions>
98
+ ) => VNode
99
+
100
+ export function IdState(options?: { idProp?: (value: any) => unknown }): ComponentOptionsMixin
101
+ }
@@ -1,4 +1,5 @@
1
1
  import type { InputWrapperController } from '@core/components/input-wrapper/VtsInputWrapper.vue'
2
+ import type { ModalAccent } from '@core/components/ui/modal/UiModal.vue'
2
3
  import type { ValueFormatter } from '@core/types/chart'
3
4
  import type { ComputedRef, InjectionKey, Ref } from 'vue'
4
5
 
@@ -21,3 +22,5 @@ export const IK_MENU_TELEPORTED = Symbol('IK_MENU_TELEPORTED') as InjectionKey<b
21
22
  export const IK_DISABLED = Symbol('IK_DISABLED') as InjectionKey<ComputedRef<boolean>>
22
23
 
23
24
  export const IK_INPUT_WRAPPER_CONTROLLER = Symbol('IK_INPUT_WRAPPER_CONTROLLER') as InjectionKey<InputWrapperController>
25
+
26
+ export const IK_MODAL_ACCENT = Symbol('IK_MODAL_ACCENT') as InjectionKey<ComputedRef<ModalAccent>>
@@ -8,6 +8,7 @@ import type { ThresholdConfig } from '@core/packages/threshold/type.ts'
8
8
  import { formatSize } from '@core/utils/size.util.ts'
9
9
  import { computed, type ComputedRef, type MaybeRefOrGetter, type Reactive, toValue } from 'vue'
10
10
  import { useI18n } from 'vue-i18n'
11
+ import { toComputed } from './to-computed.util'
11
12
 
12
13
  export function defaultProgressThresholds(tooltip?: string): ThresholdConfig<ProgressBarThresholdPayload> {
13
14
  return {
@@ -42,7 +43,7 @@ export function useProgressToLegend(
42
43
  ) {
43
44
  const { n } = useI18n()
44
45
 
45
- const type = computed(() => toValue(rawType))
46
+ const type = toComputed(rawType)
46
47
 
47
48
  function toLegend(label: string, progress: Progress | Reactive<Progress>): ProgressBarLegend | undefined {
48
49
  switch (type.value) {
@@ -0,0 +1,15 @@
1
+ import { computed, toValue, type ComputedRef, type MaybeRefOrGetter } from 'vue'
2
+
3
+ export function toComputed<TValue>(value: MaybeRefOrGetter<TValue>): ComputedRef<TValue>
4
+
5
+ export function toComputed<TValue>(
6
+ value: MaybeRefOrGetter<TValue | undefined>,
7
+ defaultValue: MaybeRefOrGetter<TValue>
8
+ ): ComputedRef<TValue>
9
+
10
+ export function toComputed<TValue>(
11
+ value: MaybeRefOrGetter<TValue>,
12
+ defaultValue?: MaybeRefOrGetter<TValue>
13
+ ): ComputedRef<TValue | undefined> {
14
+ return computed(() => toValue(value) ?? toValue(defaultValue))
15
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xen-orchestra/web-core",
3
3
  "type": "module",
4
- "version": "0.31.1",
4
+ "version": "0.32.0",
5
5
  "private": false,
6
6
  "exports": {
7
7
  "./*": {
@@ -29,7 +29,8 @@
29
29
  "ndjson-readablestream": "^1.3.0",
30
30
  "placement.js": "^1.0.0-beta.5",
31
31
  "simple-icons": "^14.14.0",
32
- "vue-echarts": "^6.6.8"
32
+ "vue-echarts": "^6.6.8",
33
+ "vue-virtual-scroller": "^2.0.0-beta.8"
33
34
  },
34
35
  "peerDependencies": {
35
36
  "pinia": "^3.0.1",
@@ -1,37 +0,0 @@
1
- <template>
2
- <UiInfo :accent="state.accent" class="vts-backup-state">
3
- {{ state.text }}
4
- </UiInfo>
5
- </template>
6
-
7
- <script lang="ts" setup>
8
- import UiInfo, { type InfoAccent } from '@core/components/ui/info/UiInfo.vue'
9
- import { useMapper } from '@core/packages/mapper'
10
- import { useI18n } from 'vue-i18n'
11
-
12
- const { state: _state } = defineProps<{
13
- state: BackupState
14
- }>()
15
-
16
- const { t } = useI18n()
17
-
18
- type BackupState = 'success' | 'failure' | 'skipped' | 'interrupted' | 'pending'
19
-
20
- const state = useMapper<BackupState, { text: string; accent: InfoAccent }>(
21
- () => _state,
22
- {
23
- success: { text: t('success'), accent: 'success' },
24
- failure: { text: t('failure'), accent: 'danger' },
25
- skipped: { text: t('skipped'), accent: 'warning' },
26
- interrupted: { text: t('interrupted'), accent: 'danger' },
27
- pending: { text: t('pending'), accent: 'info' },
28
- },
29
- 'failure'
30
- )
31
- </script>
32
-
33
- <style lang="postcss" scoped>
34
- .vts-backup-state {
35
- font-size: 1rem;
36
- }
37
- </style>
@@ -1,36 +0,0 @@
1
- <template>
2
- <UiInfo :accent="currentStatus.accent">
3
- {{ currentStatus.text }}
4
- </UiInfo>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- import UiInfo, { type InfoAccent } from '@core/components/ui/info/UiInfo.vue'
9
- import { computed, type ComputedRef } from 'vue'
10
- import { useI18n } from 'vue-i18n'
11
-
12
- export type ConnectionStatus =
13
- | 'connected'
14
- | 'disconnected'
15
- | 'partially-connected'
16
- | 'disconnected-from-physical-device'
17
- | 'physically-disconnected'
18
- type ConnectionStatusesMap = Record<ConnectionStatus, { text: string; accent: InfoAccent }>
19
-
20
- const { status } = defineProps<{
21
- status: ConnectionStatus
22
- }>()
23
-
24
- const { t } = useI18n()
25
-
26
- const statuses: ComputedRef<ConnectionStatusesMap> = computed(() => ({
27
- connected: { text: t('connected'), accent: 'success' },
28
- disconnected: { text: t('disconnected'), accent: 'danger' },
29
- 'partially-connected': { text: t('partially-connected'), accent: 'warning' },
30
- 'disconnected-from-physical-device': { text: t('disconnected-from-physical-device'), accent: 'warning' },
31
- // This status is used in host pif side panel
32
- 'physically-disconnected': { text: t('disconnected-from-physical-device'), accent: 'danger' },
33
- }))
34
-
35
- const currentStatus = computed(() => statuses.value[status])
36
- </script>