@xen-orchestra/web-core 0.55.0 → 0.56.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 (52) hide show
  1. package/lib/components/card-object-title/VtsCardObjectTitle.vue +36 -0
  2. package/lib/components/code-snippet/VtsCodeSnippet.vue +11 -5
  3. package/lib/components/drawer/VtsDrawer.vue +5 -1
  4. package/lib/components/drawer/VtsDrawerButton.vue +4 -3
  5. package/lib/components/drawer/VtsDrawerConfirmButton.vue +4 -2
  6. package/lib/components/icon/VtsIcon.vue +3 -1
  7. package/lib/components/layout/VtsContentSidePanel.vue +41 -0
  8. package/lib/components/menu/VtsActionsMenu.vue +37 -3
  9. package/lib/components/operation-card/VtsOperationCard.vue +2 -1
  10. package/lib/components/panel/VtsPanel.vue +80 -0
  11. package/lib/components/panel/VtsSidePanel.vue +140 -0
  12. package/lib/components/select/VtsSelect.vue +1 -0
  13. package/lib/components/state-hero/VtsStateHero.vue +9 -17
  14. package/lib/components/table/VtsTable.vue +2 -1
  15. package/lib/components/table/cells/VtsActionCell.vue +7 -0
  16. package/lib/components/table/cells/VtsLinkCell.vue +3 -1
  17. package/lib/components/tree/VtsTreeItem.vue +9 -3
  18. package/lib/components/tree/VtsTreeList.vue +6 -3
  19. package/lib/components/tree/VtsTreeLoadingItem.vue +3 -3
  20. package/lib/components/ui/head-bar/UiHeadBar.vue +1 -1
  21. package/lib/components/ui/input/UiInput.vue +3 -1
  22. package/lib/components/ui/link/UiLink.vue +3 -1
  23. package/lib/components/ui/panel/UiPanel.vue +7 -24
  24. package/lib/components/ui/tree-item-label/UiTreeItemLabel.vue +1 -1
  25. package/lib/composables/table-state.composable.ts +1 -1
  26. package/lib/icons/action-icons.ts +14 -0
  27. package/lib/locales/cs.json +56 -1
  28. package/lib/locales/de.json +3 -2
  29. package/lib/locales/en.json +22 -2
  30. package/lib/locales/es.json +11 -1
  31. package/lib/locales/fa.json +0 -1
  32. package/lib/locales/fr.json +22 -2
  33. package/lib/locales/it.json +0 -1
  34. package/lib/locales/ko.json +2 -0
  35. package/lib/locales/nl.json +2 -1
  36. package/lib/locales/pt-BR.json +0 -1
  37. package/lib/locales/pt.json +0 -1
  38. package/lib/locales/ru.json +0 -1
  39. package/lib/locales/sk.json +56 -1
  40. package/lib/locales/sv.json +3 -2
  41. package/lib/locales/uk.json +0 -1
  42. package/lib/locales/zh-Hans.json +79 -4
  43. package/lib/packages/remote-resource/define-remote-resource.ts +64 -29
  44. package/lib/packages/tree/types.ts +6 -0
  45. package/lib/packages/tree/use-tree.ts +38 -37
  46. package/lib/stores/panel.store.ts +56 -5
  47. package/lib/tables/column-definitions/action-column.ts +21 -9
  48. package/lib/tables/column-sets/vm-columns.ts +2 -3
  49. package/lib/types/state-hero.type.ts +19 -0
  50. package/lib/types/vue-virtual-scroller.d.ts +8 -2
  51. package/lib/utils/injection-keys.util.ts +1 -1
  52. package/package.json +1 -1
@@ -1,12 +1,63 @@
1
1
  import { useUiStore } from '@core/stores/ui.store'
2
+ import { useLocalStorage } from '@vueuse/core'
2
3
  import { defineStore } from 'pinia'
3
- import { computed, ref } from 'vue'
4
+ import { computed, watch } from 'vue'
4
5
 
5
6
  export const usePanelStore = defineStore('panel', () => {
6
7
  const uiStore = useUiStore()
7
- const isExpanded = ref(false)
8
- const open = () => (isExpanded.value = true)
9
- const close = () => (isExpanded.value = false)
8
+ const isExpanded = useLocalStorage('panel.expanded', true)
9
+ const isLocked = useLocalStorage('panel.locked', true)
10
10
 
11
- return { open, close, isExpanded: computed(() => !uiStore.isSmall || isExpanded.value) }
11
+ const cssHorizontalOffset = computed(() => (isExpanded.value ? 0 : '100%'))
12
+ /* Panel closes automatically when it has no content (true on small UI or when not locked) */
13
+ const syncsOpenStateWithSelection = computed(() => uiStore.isSmall || !isLocked.value)
14
+
15
+ function expand() {
16
+ isExpanded.value = true
17
+ }
18
+
19
+ function collapse() {
20
+ isExpanded.value = false
21
+ }
22
+
23
+ function syncWithSelection(hasSelection: boolean) {
24
+ if (!syncsOpenStateWithSelection.value) {
25
+ return
26
+ }
27
+ if (!hasSelection && isExpanded.value) {
28
+ collapse()
29
+ } else if (hasSelection && !isExpanded.value) {
30
+ expand()
31
+ }
32
+ }
33
+
34
+ function toggleLock() {
35
+ const next = !isLocked.value
36
+ isLocked.value = next
37
+ if (next && !uiStore.isSmall && !isExpanded.value) {
38
+ expand()
39
+ }
40
+ }
41
+
42
+ watch(
43
+ () => uiStore.isSmall,
44
+ isSmall => {
45
+ /* Expand when coming back from small to large UI, if locked and not expanded */
46
+ if (!isSmall && isLocked.value && !isExpanded.value) {
47
+ expand()
48
+ }
49
+ },
50
+ { immediate: true }
51
+ )
52
+
53
+ return {
54
+ isExpanded,
55
+ isLocked,
56
+ syncsOpenStateWithSelection,
57
+ expand,
58
+ collapse,
59
+ toggleLock,
60
+ syncWithSelection,
61
+ cssHorizontalOffset,
62
+ }
12
63
  })
@@ -4,18 +4,30 @@ import { defineColumn } from '@core/packages/table/define-column'
4
4
  import type { ButtonIconConfig } from '@core/tables/column-definitions/button-icon-column.ts'
5
5
  import { renderHeadCell } from '@core/tables/helpers/render-head-cell'
6
6
  import type { HeaderConfig } from '@core/tables/types.ts'
7
- import { h, toValue } from 'vue'
7
+ import { type Component, h, toValue } from 'vue'
8
8
 
9
9
  export type { ActionItem }
10
10
 
11
11
  export const useActionColumn = defineColumn((config: HeaderConfig & Partial<ButtonIconConfig>) => ({
12
12
  renderHead: () => renderHeadCell(config.headerLabel),
13
- renderBody: (params: { onClick: () => void; actions?: ActionItem[] }) =>
14
- h(VtsActionCell, {
15
- buttonIcon: toValue(config.buttonIcon ?? 'fa:eye'),
16
- buttonAccent: toValue(config.buttonAccent),
17
- buttonSize: toValue(config.buttonSize),
18
- actions: params.actions,
19
- onClick: params.onClick,
20
- }),
13
+ renderBody: (params: {
14
+ onClick: () => void
15
+ actions?: ActionItem[]
16
+ component?: Component
17
+ props?: Record<string, unknown>
18
+ }) => {
19
+ const { component, props } = params
20
+
21
+ return h(
22
+ VtsActionCell,
23
+ {
24
+ buttonIcon: toValue(config.buttonIcon ?? 'fa:eye'),
25
+ buttonAccent: toValue(config.buttonAccent),
26
+ buttonSize: toValue(config.buttonSize),
27
+ actions: params.actions,
28
+ onClick: params.onClick,
29
+ },
30
+ component ? () => h(component, props) : undefined
31
+ )
32
+ },
21
33
  }))
@@ -1,14 +1,13 @@
1
1
  import { defineColumns } from '@core/packages/table/define-columns.ts'
2
+ import { useActionColumn } from '@core/tables/column-definitions/action-column.ts'
2
3
  import { useAddressColumn } from '@core/tables/column-definitions/address-column.ts'
3
4
  import { useLinkColumn } from '@core/tables/column-definitions/link-column'
4
5
  import { useNumberColumn } from '@core/tables/column-definitions/number-column.ts'
5
- import { useSelectItemColumn } from '@core/tables/column-definitions/select-item-column'
6
6
  import { useTagColumn } from '@core/tables/column-definitions/tag-column.ts'
7
7
  import { useI18n } from 'vue-i18n'
8
8
 
9
9
  export const useVmColumns = defineColumns(() => {
10
10
  const { t } = useI18n()
11
-
12
11
  return {
13
12
  vm: useLinkColumn({ headerLabel: () => t('vm') }),
14
13
  ipAddresses: useAddressColumn({ headerLabel: () => t('ip-addresses') }),
@@ -16,6 +15,6 @@ export const useVmColumns = defineColumns(() => {
16
15
  ram: useNumberColumn({ headerLabel: () => t('ram') }),
17
16
  diskSpace: useNumberColumn({ headerLabel: () => t('disk-space') }),
18
17
  tags: useTagColumn({ headerLabel: () => t('tags') }),
19
- selectItem: useSelectItemColumn(),
18
+ actions: useActionColumn({}),
20
19
  }
21
20
  })
@@ -0,0 +1,19 @@
1
+ export const STATE_HERO_TYPES = [
2
+ 'busy',
3
+ 'no-result',
4
+ 'under-construction',
5
+ 'no-data',
6
+ 'no-selection',
7
+ 'error',
8
+ 'not-found',
9
+ 'offline',
10
+ 'all-good',
11
+ 'all-done',
12
+ 'creating',
13
+ ] as const
14
+
15
+ export type StateHeroType = (typeof STATE_HERO_TYPES)[number]
16
+
17
+ export type StateHeroFormat = 'page' | 'card' | 'panel' | 'table'
18
+
19
+ export type StateHeroSize = 'extra-small' | 'small' | 'medium' | 'large'
@@ -48,10 +48,16 @@ declare module 'vue-virtual-scroller' {
48
48
  after(): unknown
49
49
  }
50
50
 
51
+ interface ScrollToOptions {
52
+ smooth?: boolean
53
+ align?: 'start' | 'center' | 'end' | 'nearest'
54
+ offset?: number
55
+ }
56
+
51
57
  export interface RecycleScrollerInstance {
52
58
  getScroll(): { start: number; end: number }
53
- scrollToItem(index: number): void
54
- scrollToPosition(position: number): void
59
+ scrollToItem(index: number, options?: ScrollToOptions): void
60
+ scrollToPosition(position: number, options?: ScrollToOptions): void
55
61
  }
56
62
 
57
63
  export const RecycleScroller: <T>(
@@ -11,7 +11,7 @@ export const IK_TREE_ITEM_TOGGLE = Symbol('IK_TREE_ITEM_TOGGLE') as InjectionKey
11
11
 
12
12
  export const IK_TREE_ITEM_EXPANDED = Symbol('IK_TREE_ITEM_EXPANDED') as InjectionKey<Ref<boolean>>
13
13
 
14
- export const IK_TREE_LIST_DEPTH = Symbol('IK_TREE_LIST_DEPTH') as InjectionKey<number>
14
+ export const IK_TREE_LIST_DEPTH = Symbol('IK_TREE_LIST_DEPTH') as InjectionKey<Ref<number>>
15
15
 
16
16
  export const IK_MENU_HORIZONTAL = Symbol('IK_MENU_HORIZONTAL') as InjectionKey<ComputedRef<boolean>>
17
17
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xen-orchestra/web-core",
3
3
  "type": "module",
4
- "version": "0.55.0",
4
+ "version": "0.56.0",
5
5
  "private": false,
6
6
  "exports": {
7
7
  "./*": {