From ea19b0851fadff1ff09c7199b6dbd03d3fcc1989 Mon Sep 17 00:00:00 2001 From: Thierry Goettelmann Date: Mon, 15 Jan 2024 11:12:53 +0100 Subject: [PATCH] feat(lite): upgrade deps + root eslint config (#7292) --- .eslintrc.js | 35 +- .gitignore | 1 + @xen-orchestra/lite/.eslintrc.cjs | 29 - @xen-orchestra/lite/.prettierrc.cjs | 4 - @xen-orchestra/lite/README.md | 38 +- @xen-orchestra/lite/docs/component-stories.md | 82 +- @xen-orchestra/lite/docs/modals.md | 22 +- .../lite/docs/xen-api-collections.md | 60 +- @xen-orchestra/lite/env.d.ts | 4 +- @xen-orchestra/lite/package.json | 45 +- @xen-orchestra/lite/postcss.config.js | 6 - @xen-orchestra/lite/postcss.config.mjs | 6 + @xen-orchestra/lite/scripts/release.mjs | 275 ++-- @xen-orchestra/lite/src/App.vue | 82 +- @xen-orchestra/lite/src/assets/base.css | 19 +- @xen-orchestra/lite/src/assets/theme.css | 20 +- .../lite/src/components/AccountButton.vue | 48 +- .../lite/src/components/AppHeader.vue | 41 +- .../lite/src/components/AppLogin.vue | 99 +- .../lite/src/components/AppMarkdown.vue | 31 +- .../lite/src/components/AppNavigation.vue | 39 +- .../lite/src/components/AppTooltip.vue | 60 +- .../lite/src/components/AppTooltips.vue | 17 +- .../lite/src/components/CodeHighlight.vue | 30 +- .../lite/src/components/CollectionFilter.vue | 43 +- .../src/components/CollectionFilterRow.vue | 198 ++- .../lite/src/components/CollectionSorter.vue | 49 +- .../lite/src/components/CollectionTable.vue | 71 +- .../lite/src/components/ColumnHeader.vue | 8 +- .../lite/src/components/FormWidget.vue | 23 +- .../lite/src/components/HostPatchesTable.vue | 36 +- .../lite/src/components/LoginError.vue | 16 +- .../lite/src/components/NoDataError.vue | 2 +- .../lite/src/components/NoResult.vue | 2 +- .../lite/src/components/ObjectLink.vue | 75 +- .../src/components/ObjectNotFoundWrapper.vue | 32 +- .../src/components/PageUnderConstruction.vue | 8 +- .../src/components/PoolOverrideWarning.vue | 24 +- .../lite/src/components/PowerStateIcon.vue | 24 +- .../lite/src/components/ProgressCircle.vue | 24 +- .../lite/src/components/RelativeTime.vue | 18 +- .../lite/src/components/RemoteConsole.vue | 117 +- .../lite/src/components/RouterTab.vue | 16 +- .../lite/src/components/TextLogo.vue | 8 +- .../lite/src/components/TitleBar.vue | 8 +- .../lite/src/components/UsageBar.vue | 39 +- .../lite/src/components/charts/LinearChart.md | 14 +- .../src/components/charts/LinearChart.vue | 73 +- .../component-story/ComponentStory.vue | 274 ++-- .../component-story/StoryEventParams.vue | 10 +- .../component-story/StoryExampleComponent.vue | 46 +- .../components/component-story/StoryMenu.vue | 67 +- .../component-story/StoryMenuTree.vue | 40 +- .../component-story/StoryPropParams.vue | 69 +- .../component-story/StorySettingParams.vue | 22 +- .../component-story/StorySlotParams.vue | 10 +- .../component-story/StoryWidget.vue | 62 +- .../lite/src/components/form/FormByteSize.vue | 69 +- .../lite/src/components/form/FormCheckbox.vue | 59 +- .../lite/src/components/form/FormInput.vue | 91 +- .../src/components/form/FormInputWrapper.vue | 78 +- .../lite/src/components/form/FormJson.vue | 40 +- .../lite/src/components/form/FormNumber.vue | 65 +- .../lite/src/components/form/FormRadio.vue | 8 +- .../lite/src/components/form/FormSection.vue | 34 +- .../lite/src/components/form/FormSelect.vue | 8 +- .../lite/src/components/form/FormTextarea.vue | 8 +- .../lite/src/components/form/FormToggle.vue | 8 +- .../lite/src/components/infra/InfraAction.vue | 8 +- .../src/components/infra/InfraHostItem.vue | 75 +- .../src/components/infra/InfraHostList.vue | 16 +- .../src/components/infra/InfraItemLabel.vue | 30 +- .../src/components/infra/InfraLoadingItem.vue | 8 +- .../src/components/infra/InfraPoolList.vue | 29 +- .../lite/src/components/infra/InfraVmItem.vue | 42 +- .../lite/src/components/infra/InfraVmList.vue | 26 +- .../lite/src/components/menu/AppMenu.vue | 84 +- .../lite/src/components/menu/MenuItem.vue | 68 +- .../src/components/menu/MenuSeparator.vue | 6 +- .../lite/src/components/menu/MenuTrigger.vue | 14 +- .../components/modals/CodeHighlightModal.vue | 10 +- .../modals/CollectionFilterModal.vue | 96 +- .../modals/CollectionSorterModal.vue | 42 +- .../components/modals/InvalidFieldModal.vue | 22 +- .../src/components/modals/JsonEditorModal.vue | 57 +- .../modals/UnreachableHostsModal.vue | 28 +- .../src/components/modals/VmDeleteModal.vue | 44 +- .../modals/VmExportBlockedUrlsModal.vue | 34 +- .../src/components/modals/VmExportModal.vue | 48 +- .../src/components/modals/VmMigrateModal.vue | 48 +- .../lite/src/components/pool/PoolHeader.vue | 12 +- .../lite/src/components/pool/PoolTabBar.vue | 26 +- .../pool/dashboard/PoolDashboardAlarms.vue | 36 +- .../PoolDashboardCpuProvisioning.vue | 93 +- .../pool/dashboard/PoolDashboardCpuUsage.vue | 46 +- .../dashboard/PoolDashboardHostsPatches.vue | 18 +- .../dashboard/PoolDashboardNetworkChart.vue | 132 +- .../pool/dashboard/PoolDashboardRamUsage.vue | 48 +- .../pool/dashboard/PoolDashboardStatus.vue | 76 +- .../dashboard/PoolDashboardStatusItem.vue | 16 +- .../dashboard/PoolDashboardStorageUsage.vue | 87 +- .../pool/dashboard/PoolDashboardTasks.vue | 12 +- .../pool/dashboard/alarm/AlarmRow.vue | 37 +- .../pool/dashboard/cpuUsage/HostsCpuUsage.vue | 52 +- .../dashboard/cpuUsage/PoolCpuUsageChart.vue | 118 +- .../pool/dashboard/cpuUsage/VmsCpuUsage.vue | 58 +- .../pool/dashboard/ramUsage/HostsRamUsage.vue | 48 +- .../pool/dashboard/ramUsage/PoolRamUsage.vue | 138 +- .../pool/dashboard/ramUsage/VmsRamUsage.vue | 54 +- .../lite/src/components/tasks/TaskRow.vue | 43 +- .../lite/src/components/tasks/TasksTable.vue | 47 +- .../src/components/ui/SizeStatsSummary.vue | 26 +- .../lite/src/components/ui/UiActionButton.vue | 20 +- .../lite/src/components/ui/UiBadge.vue | 8 +- .../lite/src/components/ui/UiButton.vue | 58 +- .../lite/src/components/ui/UiButtonGroup.vue | 35 +- .../lite/src/components/ui/UiCard.vue | 25 +- .../src/components/ui/UiCardComingSoon.vue | 10 +- .../lite/src/components/ui/UiCardGroup.vue | 8 +- .../lite/src/components/ui/UiCardSpinner.vue | 2 +- .../lite/src/components/ui/UiCardTitle.vue | 26 +- .../lite/src/components/ui/UiCounter.vue | 8 +- .../lite/src/components/ui/UiFilter.vue | 10 +- .../lite/src/components/ui/UiKeyValueRow.vue | 2 +- .../lite/src/components/ui/UiSpinner.vue | 29 +- .../lite/src/components/ui/UiStatusPanel.vue | 8 +- .../lite/src/components/ui/UiTab.vue | 22 +- .../lite/src/components/ui/UiTabBar.vue | 10 +- .../lite/src/components/ui/UiTable.vue | 11 +- .../lite/src/components/ui/UiTitle.vue | 14 +- .../lite/src/components/ui/icon/UiIcon.vue | 21 +- .../src/components/ui/icon/UiStatusIcon.vue | 30 +- .../ui/modals/ModalApproveButton.vue | 8 +- .../components/ui/modals/ModalCloseIcon.vue | 23 +- .../components/ui/modals/ModalContainer.vue | 28 +- .../ui/modals/ModalDeclineButton.vue | 10 +- .../src/components/ui/modals/ModalList.vue | 12 +- .../components/ui/modals/ModalListItem.vue | 12 +- .../lite/src/components/ui/modals/UiModal.vue | 30 +- .../ui/modals/layouts/BasicModalLayout.vue | 8 +- .../ui/modals/layouts/ConfirmModalLayout.vue | 32 +- .../ui/modals/layouts/FormModalLayout.vue | 28 +- .../components/ui/progress/UiProgressBar.vue | 25 +- .../ui/progress/UiProgressLegend.vue | 20 +- .../ui/progress/UiProgressScale.vue | 12 +- .../components/ui/resources/UiResource.vue | 12 +- .../vm/VmActionItems/VmActionCopyItem.vue | 61 +- .../vm/VmActionItems/VmActionDeleteItem.vue | 40 +- .../vm/VmActionItems/VmActionExportItem.vue | 52 +- .../vm/VmActionItems/VmActionExportItems.vue | 48 +- .../vm/VmActionItems/VmActionMigrateItem.vue | 61 +- .../VmActionItems/VmActionPowerStateItems.vue | 160 +-- .../vm/VmActionItems/VmActionSnapshotItem.vue | 54 +- .../lite/src/components/vm/VmHeader.vue | 57 +- .../lite/src/components/vm/VmTabBar.vue | 24 +- .../lite/src/components/vm/VmsActionsBar.vue | 44 +- .../array-removed-items-history.composable.md | 34 +- .../array-removed-items-history.composable.ts | 36 +- .../lite/src/composables/busy.composable.md | 6 +- .../lite/src/composables/busy.composable.ts | 22 +- .../src/composables/chart-theme.composable.ts | 188 ++- .../collection-filter.composable.md | 47 +- .../collection-filter.composable.ts | 56 +- .../collection-sorter.composable.md | 17 +- .../collection-sorter.composable.ts | 80 +- .../src/composables/context.composable.md | 56 +- .../src/composables/context.composable.ts | 45 +- .../src/composables/fetch-stats.composable.md | 17 +- .../src/composables/fetch-stats.composable.ts | 97 +- .../filtered-collection.composable.md | 15 +- .../filtered-collection.composable.ts | 8 +- .../composables/host-patches.composable.ts | 94 +- .../lite/src/composables/modal.composable.ts | 7 +- .../composables/multi-select.composable.md | 4 +- .../composables/multi-select.composable.ts | 30 +- .../composables/relative-time.composable.md | 8 +- .../composables/relative-time.composable.ts | 69 +- .../sorted-collection.composable.ts | 8 +- .../src/composables/stat-status.composable.ts | 31 +- .../src/composables/subscriber.composable.ts | 48 +- .../unreachable-hosts.composable.ts | 47 +- .../composables/vm-migration.composable.ts | 77 +- .../xen-api-store-base-context.composable.ts | 77 +- ...i-store-subscribable-context.composable.ts | 24 +- .../xen-api-store-subscriber.composable.ts | 96 +- @xen-orchestra/lite/src/context.ts | 12 +- .../lite/src/directives/tooltip.directive.md | 18 +- .../lite/src/directives/tooltip.directive.ts | 54 +- @xen-orchestra/lite/src/i18n.ts | 130 +- @xen-orchestra/lite/src/libs/alarm.ts | 65 +- .../lite/src/libs/complex-matcher.utils.ts | 164 +-- @xen-orchestra/lite/src/libs/highlight.ts | 37 +- @xen-orchestra/lite/src/libs/markdown.ts | 78 +- @xen-orchestra/lite/src/libs/mixin.ts | 31 +- .../lite/src/libs/story/story-param.ts | 352 +++-- .../lite/src/libs/story/story-widget.ts | 85 +- @xen-orchestra/lite/src/libs/utils.ts | 122 +- @xen-orchestra/lite/src/libs/vm.ts | 37 +- @xen-orchestra/lite/src/libs/xapi-stats.ts | 376 +++--- .../lite/src/libs/xen-api/xen-api.enums.ts | 616 ++++----- .../lite/src/libs/xen-api/xen-api.ts | 381 +++--- .../lite/src/libs/xen-api/xen-api.types.ts | 1147 ++++++++--------- .../lite/src/libs/xen-api/xen-api.utils.ts | 131 +- @xen-orchestra/lite/src/main.ts | 20 +- @xen-orchestra/lite/src/router/index.ts | 46 +- @xen-orchestra/lite/src/router/pool.ts | 62 +- @xen-orchestra/lite/src/router/story.ts | 60 +- @xen-orchestra/lite/src/router/vm.ts | 56 +- .../src/stores/closing-confirmation.store.ts | 67 +- @xen-orchestra/lite/src/stores/modal.store.ts | 69 +- .../lite/src/stores/navigation.store.ts | 34 +- .../lite/src/stores/page-title.store.ts | 83 +- .../lite/src/stores/tooltip.store.ts | 82 +- @xen-orchestra/lite/src/stores/ui.store.ts | 32 +- .../lite/src/stores/xen-api.store.ts | 119 +- .../lite/src/stores/xen-api/alarm.store.ts | 86 +- .../lite/src/stores/xen-api/console.store.ts | 14 +- .../stores/xen-api/create-use-collection.ts | 93 +- .../src/stores/xen-api/host-metrics.store.ts | 31 +- .../lite/src/stores/xen-api/host.store.ts | 79 +- .../lite/src/stores/xen-api/message.store.ts | 16 +- .../lite/src/stores/xen-api/network.store.ts | 14 +- .../lite/src/stores/xen-api/pool.store.ts | 22 +- .../lite/src/stores/xen-api/sr.store.ts | 14 +- .../lite/src/stores/xen-api/task.store.ts | 74 +- .../src/stores/xen-api/vm-metrics.store.ts | 14 +- .../lite/src/stores/xen-api/vm.store.ts | 124 +- .../stories/button/ui-button-group.story.vue | 10 +- .../src/stories/button/ui-button.story.vue | 8 +- .../src/stories/form/form-byte-size.story.vue | 10 +- .../stories/form/form-input-group.story.vue | 14 +- .../stories/form/form-input-wrapper.story.vue | 12 +- .../src/stories/form/form-input.story.vue | 19 +- .../src/stories/form/form-section.story.vue | 10 +- .../lite/src/stories/linear-chart.story.md | 10 +- .../lite/src/stories/linear-chart.story.vue | 46 +- .../layouts/basic-modal-layout.story.vue | 15 +- .../layouts/confirm-modal-layout.story.vue | 10 +- .../layouts/form-modal-layout.story.vue | 31 +- .../stories/modals/modal-container.story.vue | 32 +- .../src/stories/power-state-icon.story.vue | 10 +- .../src/stories/progress-circle.story.vue | 23 +- .../lite/src/stories/story-example.story.vue | 80 +- .../src/stories/tab-bar/router-tab.story.vue | 10 +- .../src/stories/tab-bar/ui-tab-bar.story.vue | 13 +- .../lite/src/stories/tab-bar/ui-tab.story.vue | 10 +- .../lite/src/stories/ui-badge.story.vue | 8 +- .../lite/src/stories/ui-filter.story.vue | 15 +- .../ui-resources/ui-resource.story.vue | 28 +- .../ui-resources/ui-resources.story.vue | 21 +- @xen-orchestra/lite/src/types/chart.ts | 12 +- .../lite/src/types/complex-matcher.d.ts | 98 +- .../src/types/decorator-synchronized.d.ts | 4 +- @xen-orchestra/lite/src/types/filter.ts | 76 +- @xen-orchestra/lite/src/types/index.ts | 16 +- .../lite/src/types/injection-keys.ts | 62 +- .../lite/src/types/iterable-backoff.d.ts | 2 +- .../types/limit-concurrency-decorator.d.ts | 4 +- @xen-orchestra/lite/src/types/novnc.d.ts | 168 ++- @xen-orchestra/lite/src/types/router.d.ts | 12 +- @xen-orchestra/lite/src/types/sort.ts | 22 +- @xen-orchestra/lite/src/types/stat.ts | 10 +- @xen-orchestra/lite/src/types/stories.d.ts | 8 +- @xen-orchestra/lite/src/types/xen-api.ts | 60 +- @xen-orchestra/lite/src/views/HomeView.vue | 16 +- .../lite/src/views/ObjectNotFoundView.vue | 22 +- .../lite/src/views/PageNotFoundView.vue | 18 +- @xen-orchestra/lite/src/views/StoryView.vue | 20 +- .../lite/src/views/host/HostDashboardView.vue | 8 +- .../lite/src/views/host/HostRootView.vue | 30 +- .../lite/src/views/pool/PoolAlarmsView.vue | 8 +- .../lite/src/views/pool/PoolDashboardView.vue | 115 +- .../lite/src/views/pool/PoolHostsView.vue | 8 +- .../lite/src/views/pool/PoolNetworkView.vue | 8 +- .../lite/src/views/pool/PoolRootView.vue | 12 +- .../lite/src/views/pool/PoolStatsView.vue | 8 +- .../lite/src/views/pool/PoolStorageView.vue | 8 +- .../lite/src/views/pool/PoolSystemView.vue | 8 +- .../lite/src/views/pool/PoolTasksView.vue | 28 +- .../lite/src/views/pool/PoolVmsView.vue | 72 +- .../lite/src/views/settings/SettingsView.vue | 171 +-- .../lite/src/views/story/HomeView.vue | 191 ++- .../lite/src/views/vm/VmAlarmsView.vue | 8 +- .../lite/src/views/vm/VmConsoleView.vue | 121 +- .../lite/src/views/vm/VmDashboardView.vue | 8 +- .../lite/src/views/vm/VmNetworkView.vue | 8 +- .../lite/src/views/vm/VmRootView.vue | 32 +- .../lite/src/views/vm/VmStatsView.vue | 8 +- .../lite/src/views/vm/VmStorageView.vue | 8 +- .../lite/src/views/vm/VmSystemView.vue | 8 +- .../lite/src/views/vm/VmTasksView.vue | 8 +- .../src/views/xoa-deploy/XoaDeployView.vue | 479 +++---- @xen-orchestra/lite/tsconfig.app.json | 13 + @xen-orchestra/lite/tsconfig.config.json | 8 - @xen-orchestra/lite/tsconfig.json | 17 +- @xen-orchestra/lite/tsconfig.node.json | 11 + @xen-orchestra/lite/tsconfig.type-check.json | 4 + @xen-orchestra/lite/vite.config.ts | 54 +- package.json | 11 +- scripts/.eslintrc.js | 10 - yarn.lock | 727 +++++++---- 301 files changed, 7351 insertions(+), 8798 deletions(-) delete mode 100644 @xen-orchestra/lite/.eslintrc.cjs delete mode 100644 @xen-orchestra/lite/.prettierrc.cjs delete mode 100644 @xen-orchestra/lite/postcss.config.js create mode 100644 @xen-orchestra/lite/postcss.config.mjs mode change 100644 => 100755 @xen-orchestra/lite/scripts/release.mjs create mode 100644 @xen-orchestra/lite/tsconfig.app.json delete mode 100644 @xen-orchestra/lite/tsconfig.config.json create mode 100644 @xen-orchestra/lite/tsconfig.node.json create mode 100644 @xen-orchestra/lite/tsconfig.type-check.json delete mode 100644 scripts/.eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js index 0e4b2703522..76e4110bd62 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -15,9 +15,10 @@ module.exports = { overrides: [ { - files: ['cli.{,c,m}js', '*-cli.{,c,m}js', '**/*cli*/**/*.{,c,m}js'], + files: ['cli.{,c,m}js', '*-cli.{,c,m}js', '**/*cli*/**/*.{,c,m}js', '**/scripts/**.{,c,m}js'], rules: { 'n/no-process-exit': 'off', + 'n/shebang': 'off', 'no-console': 'off', }, }, @@ -46,6 +47,38 @@ module.exports = { ], }, }, + { + files: ['@xen-orchestra/lite/**/*.{vue,ts}'], + parserOptions: { + sourceType: 'module', + }, + plugins: ['import'], + extends: [ + 'plugin:import/recommended', + 'plugin:import/typescript', + 'plugin:vue/vue3-recommended', + '@vue/eslint-config-typescript/recommended', + '@vue/eslint-config-prettier', + ], + settings: { + 'import/resolver': { + typescript: true, + 'eslint-import-resolver-custom-alias': { + alias: { + '@': './src', + }, + extensions: ['.ts'], + packages: ['@xen-orchestra/lite'], + }, + }, + }, + rules: { + 'no-void': 'off', + 'n/no-missing-import': 'off', // using 'import' plugin instead to support TS aliases + '@typescript-eslint/no-explicit-any': 'off', + 'vue/require-default-prop': 'off', // https://github.com/vuejs/eslint-plugin-vue/issues/2051 + }, + }, ], parserOptions: { diff --git a/.gitignore b/.gitignore index ffb53b2dff7..158ea337fcc 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ pnpm-debug.log.* yarn-error.log yarn-error.log.* .env +*.tsbuildinfo # code coverage .nyc_output/ diff --git a/@xen-orchestra/lite/.eslintrc.cjs b/@xen-orchestra/lite/.eslintrc.cjs deleted file mode 100644 index 7f782d90827..00000000000 --- a/@xen-orchestra/lite/.eslintrc.cjs +++ /dev/null @@ -1,29 +0,0 @@ -/* eslint-env node */ -require("@rushstack/eslint-patch/modern-module-resolution"); - -module.exports = { - globals: { - XO_LITE_GIT_HEAD: true, - XO_LITE_VERSION: true, - }, - root: true, - env: { - node: true, - }, - extends: [ - "plugin:vue/vue3-essential", - "eslint:recommended", - "@vue/eslint-config-typescript/recommended", - "@vue/eslint-config-prettier", - ], - plugins: ["@limegrass/import-alias"], - ignorePatterns: ["scripts/*.mjs"], - rules: { - "@typescript-eslint/no-non-null-assertion": "off", - "@typescript-eslint/no-explicit-any": "off", - "@limegrass/import-alias/import-alias": [ - "error", - { aliasConfigPath: require("path").join(__dirname, "tsconfig.json") }, - ], - }, -}; diff --git a/@xen-orchestra/lite/.prettierrc.cjs b/@xen-orchestra/lite/.prettierrc.cjs deleted file mode 100644 index 471dd0c365e..00000000000 --- a/@xen-orchestra/lite/.prettierrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -// Keeping this file to prevent applying the global monorepo config for now -module.exports = { - trailingComma: "es5", -}; diff --git a/@xen-orchestra/lite/README.md b/@xen-orchestra/lite/README.md index 4afe3129600..b6915250079 100644 --- a/@xen-orchestra/lite/README.md +++ b/@xen-orchestra/lite/README.md @@ -48,18 +48,16 @@ Note: When reading Vue official doc, don't forget to set "API Preference" toggle ```vue ``` @@ -73,9 +71,9 @@ Vue variables can be interpolated with `v-bind`. ```vue diff --git a/@xen-orchestra/lite/src/components/CodeHighlight.vue b/@xen-orchestra/lite/src/components/CodeHighlight.vue index fb7525b141e..ea1de103dd3 100644 --- a/@xen-orchestra/lite/src/components/CodeHighlight.vue +++ b/@xen-orchestra/lite/src/components/CodeHighlight.vue @@ -1,33 +1,33 @@ diff --git a/@xen-orchestra/lite/src/components/RemoteConsole.vue b/@xen-orchestra/lite/src/components/RemoteConsole.vue index 6b060f638af..fcca6f186c5 100644 --- a/@xen-orchestra/lite/src/components/RemoteConsole.vue +++ b/@xen-orchestra/lite/src/components/RemoteConsole.vue @@ -3,112 +3,103 @@ diff --git a/@xen-orchestra/lite/src/components/TextLogo.vue b/@xen-orchestra/lite/src/components/TextLogo.vue index d46a905e7b2..ea10ae3cb01 100644 --- a/@xen-orchestra/lite/src/components/TextLogo.vue +++ b/@xen-orchestra/lite/src/components/TextLogo.vue @@ -19,12 +19,8 @@ - - + + diff --git a/@xen-orchestra/lite/src/components/TitleBar.vue b/@xen-orchestra/lite/src/components/TitleBar.vue index 9002e3277cb..2477ef1133b 100644 --- a/@xen-orchestra/lite/src/components/TitleBar.vue +++ b/@xen-orchestra/lite/src/components/TitleBar.vue @@ -11,12 +11,12 @@ diff --git a/@xen-orchestra/lite/src/components/form/FormTextarea.vue b/@xen-orchestra/lite/src/components/form/FormTextarea.vue index fbeb39d36b5..20346669e59 100644 --- a/@xen-orchestra/lite/src/components/form/FormTextarea.vue +++ b/@xen-orchestra/lite/src/components/form/FormTextarea.vue @@ -3,11 +3,11 @@ diff --git a/@xen-orchestra/lite/src/components/form/FormToggle.vue b/@xen-orchestra/lite/src/components/form/FormToggle.vue index a75205aa5dc..3dc3b6d7dff 100644 --- a/@xen-orchestra/lite/src/components/form/FormToggle.vue +++ b/@xen-orchestra/lite/src/components/form/FormToggle.vue @@ -3,9 +3,9 @@ diff --git a/@xen-orchestra/lite/src/components/infra/InfraAction.vue b/@xen-orchestra/lite/src/components/infra/InfraAction.vue index 7ef6f9c14f6..e2a209c8094 100644 --- a/@xen-orchestra/lite/src/components/infra/InfraAction.vue +++ b/@xen-orchestra/lite/src/components/infra/InfraAction.vue @@ -7,12 +7,12 @@ diff --git a/@xen-orchestra/lite/src/components/modals/JsonEditorModal.vue b/@xen-orchestra/lite/src/components/modals/JsonEditorModal.vue index 5a52dfbc9ca..0f0a4eef412 100644 --- a/@xen-orchestra/lite/src/components/modals/JsonEditorModal.vue +++ b/@xen-orchestra/lite/src/components/modals/JsonEditorModal.vue @@ -1,8 +1,5 @@ diff --git a/@xen-orchestra/lite/src/components/vm/VmActionItems/VmActionDeleteItem.vue b/@xen-orchestra/lite/src/components/vm/VmActionItems/VmActionDeleteItem.vue index eed5e64e562..b6f67d336bf 100644 --- a/@xen-orchestra/lite/src/components/vm/VmActionItems/VmActionDeleteItem.vue +++ b/@xen-orchestra/lite/src/components/vm/VmActionItems/VmActionDeleteItem.vue @@ -5,40 +5,34 @@ :icon="faTrashCan" @click="openDeleteModal" > - {{ $t("delete") }} + {{ $t('delete') }} diff --git a/@xen-orchestra/lite/src/components/vm/VmActionItems/VmActionExportItem.vue b/@xen-orchestra/lite/src/components/vm/VmActionItems/VmActionExportItem.vue index 77b57b71f4c..b1991746183 100644 --- a/@xen-orchestra/lite/src/components/vm/VmActionItems/VmActionExportItem.vue +++ b/@xen-orchestra/lite/src/components/vm/VmActionItems/VmActionExportItem.vue @@ -1,53 +1,47 @@ diff --git a/@xen-orchestra/lite/src/components/vm/VmActionItems/VmActionExportItems.vue b/@xen-orchestra/lite/src/components/vm/VmActionItems/VmActionExportItems.vue index 49f1a204888..6695a5edd0b 100644 --- a/@xen-orchestra/lite/src/components/vm/VmActionItems/VmActionExportItems.vue +++ b/@xen-orchestra/lite/src/components/vm/VmActionItems/VmActionExportItems.vue @@ -1,45 +1,31 @@ diff --git a/@xen-orchestra/lite/src/components/vm/VmActionItems/VmActionMigrateItem.vue b/@xen-orchestra/lite/src/components/vm/VmActionItems/VmActionMigrateItem.vue index dd1fb2d58e2..84ef6c2435a 100644 --- a/@xen-orchestra/lite/src/components/vm/VmActionItems/VmActionMigrateItem.vue +++ b/@xen-orchestra/lite/src/components/vm/VmActionItems/VmActionMigrateItem.vue @@ -3,63 +3,52 @@ v-tooltip=" selectedRefs.length > 0 && !isMigratable && - $t( - isSingleAction - ? 'this-vm-cant-be-migrated' - : 'no-selected-vm-can-be-migrated' - ) + $t(isSingleAction ? 'this-vm-cant-be-migrated' : 'no-selected-vm-can-be-migrated') " :busy="isMigrating" :disabled="isParentDisabled || !isMigratable" :icon="faRoute" @click="openModal()" > - {{ $t("migrate") }} + {{ $t('migrate') }} diff --git a/@xen-orchestra/lite/src/components/vm/VmActionItems/VmActionPowerStateItems.vue b/@xen-orchestra/lite/src/components/vm/VmActionItems/VmActionPowerStateItems.vue index aebff351337..275cb840fde 100644 --- a/@xen-orchestra/lite/src/components/vm/VmActionItems/VmActionPowerStateItems.vue +++ b/@xen-orchestra/lite/src/components/vm/VmActionItems/VmActionPowerStateItems.vue @@ -1,53 +1,26 @@ diff --git a/@xen-orchestra/lite/src/components/vm/VmHeader.vue b/@xen-orchestra/lite/src/components/vm/VmHeader.vue index 7f03f23f72b..93dd0c64bab 100644 --- a/@xen-orchestra/lite/src/components/vm/VmHeader.vue +++ b/@xen-orchestra/lite/src/components/vm/VmHeader.vue @@ -5,7 +5,7 @@ @@ -14,15 +14,15 @@ @@ -35,35 +35,28 @@ "; - code = highlight(str, { language: "css" }).value; - break; + openTag = '' + code = highlight(str, { language: 'css' }).value + break } - const openTagHtml = highlight(openTag, { language: "xml" }).value; - const closeTagHtml = highlight(closeTag, { language: "xml" }).value; + const openTagHtml = highlight(openTag, { language: 'xml' }).value + const closeTagHtml = highlight(closeTag, { language: 'xml' }).value - return `${openTagHtml}${copyable(code)}${closeTagHtml}`; + return `${openTagHtml}${copyable(code)}${closeTagHtml}` } function copyable(code: string) { - return `
${code}
`; + return `
${code}
` } -export default marked; +export default marked diff --git a/@xen-orchestra/lite/src/libs/mixin.ts b/@xen-orchestra/lite/src/libs/mixin.ts index fdf47517259..1e0a2cd7f31 100644 --- a/@xen-orchestra/lite/src/libs/mixin.ts +++ b/@xen-orchestra/lite/src/libs/mixin.ts @@ -1,19 +1,13 @@ -type UnionToIntersection = (T extends any ? (x: T) => any : never) extends ( - x: infer R -) => any - ? R - : never; +type UnionToIntersection = (T extends any ? (x: T) => any : never) extends (x: infer R) => any ? R : never -export type MixinConstructor = new (...args: any[]) => T; +export type MixinConstructor = new (...args: any[]) => T -export type MixinAbstractConstructor = abstract new ( - ...args: any[] -) => T; +export type MixinAbstractConstructor = abstract new (...args: any[]) => T export type MixinFunction< T extends MixinConstructor | MixinAbstractConstructor = MixinConstructor, R extends T = T & MixinConstructor, -> = (Base: T) => R; +> = (Base: T) => R export type MixinReturnValue< T extends MixinConstructor | MixinAbstractConstructor, @@ -21,16 +15,13 @@ export type MixinReturnValue< > = UnionToIntersection< | T | { - [K in keyof M]: M[K] extends MixinFunction ? U : never; + [K in keyof M]: M[K] extends MixinFunction ? U : never }[number] ->; +> -export default function mixin< - T extends MixinConstructor | MixinAbstractConstructor, - M extends MixinFunction[], ->(Base: T, ...mixins: M): MixinReturnValue { - return mixins.reduce( - (mix, applyMixin) => applyMixin(mix), - Base - ) as MixinReturnValue; +export default function mixin[]>( + Base: T, + ...mixins: M +): MixinReturnValue { + return mixins.reduce((mix, applyMixin) => applyMixin(mix), Base) as MixinReturnValue } diff --git a/@xen-orchestra/lite/src/libs/story/story-param.ts b/@xen-orchestra/lite/src/libs/story/story-param.ts index e572ca35839..b32f79f6580 100644 --- a/@xen-orchestra/lite/src/libs/story/story-param.ts +++ b/@xen-orchestra/lite/src/libs/story/story-param.ts @@ -1,451 +1,425 @@ -import { - faFloppyDisk, - faRocket, - faShip, - faTrash, -} from "@fortawesome/free-solid-svg-icons"; -import mixin, { type MixinAbstractConstructor } from "@/libs/mixin"; -import type { Widget } from "@/libs/story/story-widget"; -import { - boolean, - choice, - number, - object, - text, -} from "@/libs/story/story-widget"; +import { faFloppyDisk, faRocket, faShip, faTrash } from '@fortawesome/free-solid-svg-icons' +import mixin, { type MixinAbstractConstructor } from '@/libs/mixin' +import type { Widget } from '@/libs/story/story-widget' +import { boolean, choice, number, object, text } from '@/libs/story/story-widget' function WithType(Base: MixinAbstractConstructor) { - abstract class WithType extends Base /*implements HasType*/ { - #type: string | undefined; + abstract class WithType extends Base /* implements HasType */ { + #type: string | undefined type(type: string) { - this.#type = type; + this.#type = type - return this; + return this } - abstract getTypeLabel(): string; + abstract getTypeLabel(): string getType() { - return this.#type; + return this.#type } } - return WithType; + return WithType } function WithWidget(Base: MixinAbstractConstructor) { - abstract class WithWidget extends Base /*implements HasWidget*/ { - #widget: Widget | undefined; + abstract class WithWidget extends Base /* implements HasWidget */ { + #widget: Widget | undefined - abstract guessWidget(): Widget | undefined; + abstract guessWidget(): Widget | undefined widget(widget?: Widget): this { - this.#widget = widget === undefined ? this.guessWidget() : widget; + this.#widget = widget === undefined ? this.guessWidget() : widget - return this; + return this } getWidget() { - return this.#widget; + return this.#widget } hasWidget() { - return this.#widget !== undefined; + return this.#widget !== undefined } } - return WithWidget; + return WithWidget } abstract class BaseParam { - #help: string | undefined; - readonly #name: string; - #presetValue: any; + #help: string | undefined + readonly #name: string + #presetValue: any - protected abstract getNamePrefix(): string; + protected abstract getNamePrefix(): string - protected abstract getNameSuffix(): string; + protected abstract getNameSuffix(): string constructor(name: string) { - this.#name = name; + this.#name = name } get name() { - return this.#name; + return this.#name } getFullName() { - return `${this.getNamePrefix()}${this.name}${this.getNameSuffix()}`; + return `${this.getNamePrefix()}${this.name}${this.getNameSuffix()}` } help(help: string) { - this.#help = help; - return this; + this.#help = help + return this } getHelp() { - return this.#help; + return this.#help } preset(presetValue: any) { - this.#presetValue = presetValue; - return this; + this.#presetValue = presetValue + return this } getPresetValue() { - return this.#presetValue; + return this.#presetValue } } export class PropParam extends mixin(BaseParam, WithWidget, WithType) { - #isRequired = false; - #defaultValue: any; - #isVModel: boolean; + #isRequired = false + #defaultValue: any + #isVModel: boolean constructor(name: string, isVModel = false) { - super(name); - this.#isVModel = isVModel; + super(name) + this.#isVModel = isVModel } isRequired() { - return this.#isRequired; + return this.#isRequired } isVModel() { - return this.#isVModel; + return this.#isVModel } getVModelDirective() { - return this.name === "modelValue" ? "v-model" : `v-model:${this.name}`; + return this.name === 'modelValue' ? 'v-model' : `v-model:${this.name}` } getNamePrefix() { - return this.getType() === "string" ? "" : ":"; + return this.getType() === 'string' ? '' : ':' } getNameSuffix() { - return this.isRequired() ? "" : "?"; + return this.isRequired() ? '' : '?' } getTypeLabel() { - const type = this.getType(); + const type = this.getType() if (type !== undefined) { - return type; + return type } if (this.#isEnum) { - return this.#enumItems.map((item) => JSON.stringify(item)).join(" | "); + return this.#enumItems.map(item => JSON.stringify(item)).join(' | ') } - const presetValue = this.getPresetValue(); + const presetValue = this.getPresetValue() if (presetValue !== undefined) { - return typeof presetValue; + return typeof presetValue } - return "unknown"; + return 'unknown' } guessWidget() { if (this.#isEnum) { - return choice(...this.#enumItems); + return choice(...this.#enumItems) } if (this.#isObject) { - return object(); + return object() } switch (this.getTypeLabel()) { - case "boolean": - return boolean(); - case "number": - return number(); - case "string": - return text(); + case 'boolean': + return boolean() + case 'number': + return number() + case 'string': + return text() } } required() { - this.#isRequired = true; - return this; + this.#isRequired = true + return this } default(defaultValue: any) { - this.#defaultValue = defaultValue; - return this; + this.#defaultValue = defaultValue + return this } getDefaultValue() { - return this.#defaultValue; + return this.#defaultValue } bool() { - return this.default(false).type("boolean"); + return this.default(false).type('boolean') } num() { - return this.type("number"); + return this.type('number') } str() { - return this.type("string"); + return this.type('string') } - arr(type = "any") { - return this.type(`${type}[]`); + arr(type = 'any') { + return this.type(`${type}[]`) } - #isEnum = false; - #enumItems: any[] = []; + #isEnum = false + #enumItems: any[] = [] enum(...items: any[]) { - this.#isEnum = true; - this.#enumItems = items; - return this; + this.#isEnum = true + this.#enumItems = items + return this } any() { - return this.type("any"); + return this.type('any') } - #isObject = false; + #isObject = false - obj(type = "object") { - this.#isObject = true; - return this.type(type); + obj(type = 'object') { + this.#isObject = true + return this.type(type) } - #isUsingContext = false; + #isUsingContext = false ctx() { - this.#isUsingContext = true; - return this; + this.#isUsingContext = true + return this } isUsingContext() { - return this.#isUsingContext; + return this.#isUsingContext } } export class EventParam extends mixin(BaseParam, WithType) { - #args: Record = {}; - #returnType: string | undefined; - readonly #isVModel: boolean; + #args: Record = {} + #returnType: string | undefined + readonly #isVModel: boolean constructor(name: string, isVModel = false) { - super(name); - this.#isVModel = isVModel; + super(name) + this.#isVModel = isVModel } get name() { if (this.isVModel()) { - return `update:${super.name}`; + return `update:${super.name}` } - return super.name; + return super.name } get rawName() { - return super.name; + return super.name } isVModel() { - return this.#isVModel; + return this.#isVModel } getNamePrefix() { - return "@"; + return '@' } getNameSuffix() { - return ""; + return '' } args(args: Record) { - this.#args = args; - return this; + this.#args = args + return this } getArguments() { - return this.#args; + return this.#args } return(returnType: string) { - this.#returnType = returnType; - return this; + this.#returnType = returnType + return this } getTypeLabel() { - const type = this.getType(); + const type = this.getType() if (type !== undefined) { - return type; + return type } - const args: string[] = []; + const args: string[] = [] Object.entries(this.#args).forEach(([name, type]) => { - args.push(`${name}: ${type}`); - }); + args.push(`${name}: ${type}`) + }) - return `(${args.join(", ")}) => ${this.#returnType ?? "void"}`; + return `(${args.join(', ')}) => ${this.#returnType ?? 'void'}` } } export class SlotParam extends BaseParam { - #props: { name: string; type: string }[] = []; + #props: { name: string; type: string }[] = [] getNamePrefix() { - return "#"; + return '#' } getNameSuffix() { - return ""; + return '' } prop(name: string, type: string) { - this.#props.push({ name, type }); - return this; + this.#props.push({ name, type }) + return this } getPropsType() { - return `{ ${this.#props - .map((prop) => `${prop.name}: ${prop.type}`) - .join(", ")} }`; + return `{ ${this.#props.map(prop => `${prop.name}: ${prop.type}`).join(', ')} }` } hasProps() { - return this.#props.length > 0; + return this.#props.length > 0 } get props() { - return this.#props; + return this.#props } preset(): never { - throw new Error("Cannot preset a slot"); + throw new Error('Cannot preset a slot') } } export class SettingParam extends mixin(BaseParam, WithWidget) { getNamePrefix() { - return ""; + return '' } getNameSuffix() { - return ""; + return '' } guessWidget() { - const type = typeof this.getPresetValue(); + const type = typeof this.getPresetValue() switch (type) { - case "string": - return text(); + case 'string': + return text() } } } export class ModelParam extends BaseParam { - readonly #prop: PropParam; - readonly #event: EventParam; + readonly #prop: PropParam + readonly #event: EventParam protected getNameSuffix() { - return ""; + return '' } protected getNamePrefix() { - return ""; + return '' } constructor(name: string) { - super(name); - this.#prop = new PropParam(name, true); + super(name) + this.#prop = new PropParam(name, true) this.#event = new EventParam(name, true).args({ - value: "unknown", - }); + value: 'unknown', + }) } prop(func: (param: PropParam) => void) { - func(this.#prop); - return this; + func(this.#prop) + return this } event(func: (param: EventParam) => void) { - func(this.#event); - return this; + func(this.#event) + return this } required() { - this.#prop.required(); - return this; + this.#prop.required() + return this } type(type: string) { - this.#prop.type(type); - this.#event.args({ value: type }); - return this; + this.#prop.type(type) + this.#event.args({ value: type }) + return this } preset(presetValue: any) { - this.#prop.preset(presetValue); - return this; + this.#prop.preset(presetValue) + return this } help(help: string) { - this.#prop.help(help); - return this; + this.#prop.help(help) + return this } getPropParam() { - return this.#prop; + return this.#prop } getEventParam() { - return this.#event; + return this.#event } } -export type Param = - | EventParam - | PropParam - | SlotParam - | ModelParam - | SettingParam; - -export const prop = (name: string) => new PropParam(name); -export const event = (name: string) => new EventParam(name); -export const slot = (name = "default") => new SlotParam(name); -export const setting = (name: string) => new SettingParam(name); -export const model = (name = "modelValue") => new ModelParam(name); - -export const isPropParam = (param: any): param is PropParam => - param instanceof PropParam; -export const isSettingParam = (param: any): param is SettingParam => - param instanceof SettingParam; -export const isEventParam = (param: any): param is EventParam => - param instanceof EventParam; -export const isSlotParam = (param: any): param is SlotParam => - param instanceof SlotParam; -export const isModelParam = (param: any): param is ModelParam => - param instanceof ModelParam; - -export const colorProp = (name = "color") => - prop(name) - .enum("info", "success", "warning", "error") - .default("info") - .widget(); +export type Param = EventParam | PropParam | SlotParam | ModelParam | SettingParam + +export const prop = (name: string) => new PropParam(name) +export const event = (name: string) => new EventParam(name) +export const slot = (name = 'default') => new SlotParam(name) +export const setting = (name: string) => new SettingParam(name) +export const model = (name = 'modelValue') => new ModelParam(name) + +export const isPropParam = (param: any): param is PropParam => param instanceof PropParam +export const isSettingParam = (param: any): param is SettingParam => param instanceof SettingParam +export const isEventParam = (param: any): param is EventParam => param instanceof EventParam +export const isSlotParam = (param: any): param is SlotParam => param instanceof SlotParam +export const isModelParam = (param: any): param is ModelParam => param instanceof ModelParam + +export const colorProp = (name = 'color') => + prop(name).enum('info', 'success', 'warning', 'error').default('info').widget() -export const iconProp = (name = "icon") => +export const iconProp = (name = 'icon') => prop(name) - .type("IconDefinition") + .type('IconDefinition') .widget( choice( - { label: "Ship", value: faShip }, - { label: "Rocket", value: faRocket }, - { label: "Floppy", value: faFloppyDisk }, - { label: "Trash", value: faTrash } + { label: 'Ship', value: faShip }, + { label: 'Rocket', value: faRocket }, + { label: 'Floppy', value: faFloppyDisk }, + { label: 'Trash', value: faTrash } ) - ); + ) diff --git a/@xen-orchestra/lite/src/libs/story/story-widget.ts b/@xen-orchestra/lite/src/libs/story/story-widget.ts index 26a44535341..2f6de8e7aaa 100644 --- a/@xen-orchestra/lite/src/libs/story/story-widget.ts +++ b/@xen-orchestra/lite/src/libs/story/story-widget.ts @@ -1,110 +1,95 @@ -export type WidgetType = - | "select" - | "radio" - | "boolean" - | "text" - | "object" - | "static" - | "number"; +export type WidgetType = 'select' | 'radio' | 'boolean' | 'text' | 'object' | 'static' | 'number' export abstract class Widget { - #type: WidgetType; + #type: WidgetType protected constructor(type: WidgetType) { - this.#type = type; + this.#type = type } get type() { - return this.#type; + return this.#type } protected set type(type: WidgetType) { - this.#type = type; + this.#type = type } } const hasOwn = (obj: object, ...properties: PropertyKey[]) => { - return properties.every((property) => - Object.prototype.hasOwnProperty.call(obj, property) - ); -}; + return properties.every(property => Object.prototype.hasOwnProperty.call(obj, property)) +} class ChoiceWidget extends Widget { - #choices: any[]; - #isEnum = false; + #choices: any[] + #isEnum = false constructor(choices: any[]) { - super("select"); - this.#choices = choices; + super('select') + this.#choices = choices } get choices(): { label: any; value: any }[] { - return this.#choices.map((choice) => { - if (hasOwn(choice, "label", "value")) { - return choice; + return this.#choices.map(choice => { + if (hasOwn(choice, 'label', 'value')) { + return choice } - return { label: choice, value: choice }; - }); + return { label: choice, value: choice } + }) } enum() { - this.#isEnum = true; + this.#isEnum = true } radio() { - this.type = "radio"; - return this; + this.type = 'radio' + return this } } class TextWidget extends Widget { constructor() { - super("text"); + super('text') } } class NumberWidget extends Widget { constructor() { - super("number"); + super('number') } } class BooleanWidget extends Widget { constructor() { - super("boolean"); + super('boolean') } } class ObjectWidget extends Widget { constructor() { - super("object"); + super('object') } } -export const choice = (...choices: any[]) => new ChoiceWidget(choices); -export const text = () => new TextWidget(); -export const number = () => new NumberWidget(); -export const boolean = () => new BooleanWidget(); -export const object = () => new ObjectWidget(); +export const choice = (...choices: any[]) => new ChoiceWidget(choices) +export const text = () => new TextWidget() +export const number = () => new NumberWidget() +export const boolean = () => new BooleanWidget() +export const object = () => new ObjectWidget() -export const isSelectWidget = (widget: Widget): widget is ChoiceWidget => - widget.type === "select"; +export const isSelectWidget = (widget: Widget): widget is ChoiceWidget => widget.type === 'select' -export const isRadioWidget = (widget: Widget): widget is ChoiceWidget => - widget.type === "radio"; +export const isRadioWidget = (widget: Widget): widget is ChoiceWidget => widget.type === 'radio' export const isChoiceWidget = (widget: Widget): widget is ChoiceWidget => - isSelectWidget(widget) || isRadioWidget(widget); + isSelectWidget(widget) || isRadioWidget(widget) -export const isBooleanWidget = (widget: Widget): widget is BooleanWidget => - widget.type === "boolean"; +export const isBooleanWidget = (widget: Widget): widget is BooleanWidget => widget.type === 'boolean' -export const isNumberWidget = (widget: Widget): widget is NumberWidget => - widget.type === "number"; +export const isNumberWidget = (widget: Widget): widget is NumberWidget => widget.type === 'number' -export const isTextWidget = (widget: Widget): widget is TextWidget => - widget.type === "text"; +export const isTextWidget = (widget: Widget): widget is TextWidget => widget.type === 'text' -export const isObjectWidget = (widget: Widget): widget is ObjectWidget => - widget.type === "object"; +export const isObjectWidget = (widget: Widget): widget is ObjectWidget => widget.type === 'object' diff --git a/@xen-orchestra/lite/src/libs/utils.ts b/@xen-orchestra/lite/src/libs/utils.ts index 1ce7d692183..a0a5abda76f 100644 --- a/@xen-orchestra/lite/src/libs/utils.ts +++ b/@xen-orchestra/lite/src/libs/utils.ts @@ -1,22 +1,19 @@ -import type { Filter } from "@/types/filter"; -import { faSquareCheck } from "@fortawesome/free-regular-svg-icons"; -import { faFont, faHashtag, faList } from "@fortawesome/free-solid-svg-icons"; -import { utcParse } from "d3-time-format"; -import humanFormat from "human-format"; -import { find, forEach, round, size, sum } from "lodash-es"; - -export function sortRecordsByNameLabel( - record1: { name_label: string }, - record2: { name_label: string } -) { - const label1 = record1.name_label.toLocaleLowerCase(); - const label2 = record2.name_label.toLocaleLowerCase(); - - return label1.localeCompare(label2); +import type { Filter } from '@/types/filter' +import { faSquareCheck } from '@fortawesome/free-regular-svg-icons' +import { faFont, faHashtag, faList } from '@fortawesome/free-solid-svg-icons' +import { utcParse } from 'd3-time-format' +import format from 'human-format' +import { find, forEach, round, size, sum } from 'lodash-es' + +export function sortRecordsByNameLabel(record1: { name_label: string }, record2: { name_label: string }) { + const label1 = record1.name_label.toLocaleLowerCase() + const label2 = record2.name_label.toLocaleLowerCase() + + return label1.localeCompare(label2) } export function escapeRegExp(string: string) { - return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') } const iconsByType = { @@ -24,86 +21,79 @@ const iconsByType = { number: faHashtag, boolean: faSquareCheck, enum: faList, -}; +} export function formatSize(bytes: number) { - return bytes != null - ? humanFormat(bytes, { scale: "binary", unit: "B" }) - : "N/D"; + return bytes != null ? format(bytes, { scale: 'binary', unit: 'B' }) : 'N/D' } export function getFilterIcon(filter: Filter | undefined) { if (!filter) { - return; + return } if (filter.icon) { - return filter.icon; + return filter.icon } - return iconsByType[filter.type]; + return iconsByType[filter.type] } export function parseDateTime(dateTime: Date | string | number): number { - if (typeof dateTime === "number") { - return dateTime; + if (typeof dateTime === 'number') { + return dateTime } if (dateTime instanceof Date) { - return dateTime.getTime(); + return dateTime.getTime() } - dateTime = dateTime.replace(/(-|\.\d{3})/g, ""); // Allow toISOString() date-time format - const date = utcParse("%Y%m%dT%H:%M:%SZ")(dateTime); + dateTime = dateTime.replace(/(-|\.\d{3})/g, '') // Allow toISOString() date-time format + const date = utcParse('%Y%m%dT%H:%M:%SZ')(dateTime) if (date === null) { - throw new RangeError( - `unable to parse XAPI datetime ${JSON.stringify(dateTime)}` - ); + throw new RangeError(`unable to parse XAPI datetime ${JSON.stringify(dateTime)}`) } - return date.getTime(); + return date.getTime() } -export const hasEllipsis = ( - target: Element | undefined | null, - { vertical = false }: { vertical?: boolean } = {} -) => { +export const hasEllipsis = (target: Element | undefined | null, { vertical = false }: { vertical?: boolean } = {}) => { if (target == null) { - return false; + return false } if (vertical) { - return target.clientHeight < target.scrollHeight; + return target.clientHeight < target.scrollHeight } - return target.clientWidth < target.scrollWidth; -}; + return target.clientWidth < target.scrollWidth +} export function percent(currentValue: number, maxValue: number, precision = 2) { - return round((currentValue / maxValue) * 100, precision); + return round((currentValue / maxValue) * 100, precision) } export function getAvgCpuUsage(cpus?: object | any[], { nSequence = 4 } = {}) { - const statsLength = getStatsLength(cpus); + const statsLength = getStatsLength(cpus) if (statsLength === undefined) { - return; + return } - const _nSequence = statsLength < nSequence ? statsLength : nSequence; + const _nSequence = statsLength < nSequence ? statsLength : nSequence - let totalCpusUsage = 0; + let totalCpusUsage = 0 forEach(cpus, (cpuState: number[]) => { - totalCpusUsage += sum(cpuState.slice(cpuState.length - _nSequence)); - }); - const stackedValue = totalCpusUsage / _nSequence; - return stackedValue / size(cpus); + totalCpusUsage += sum(cpuState.slice(cpuState.length - _nSequence)) + }) + const stackedValue = totalCpusUsage / _nSequence + return stackedValue / size(cpus) } // stats can be null. // Return the size of the first non-null object. export function getStatsLength(stats?: object | any[]) { if (stats === undefined) { - return undefined; + return undefined } - return size(find(stats, (stat) => stat != null)); + return size(find(stats, stat => stat != null)) } export function parseRamUsage( @@ -111,34 +101,32 @@ export function parseRamUsage( memory, memoryFree, }: { - memory: number[]; - memoryFree?: number[]; + memory: number[] + memoryFree?: number[] }, { nSequence = 4 } = {} ) { - const _nSequence = Math.min(memory.length, nSequence); + const _nSequence = Math.min(memory.length, nSequence) - let total = 0; - let used = 0; + let total = 0 + let used = 0 - memory = memory.slice(memory.length - _nSequence); - memoryFree = memoryFree?.slice(memoryFree.length - _nSequence); + memory = memory.slice(memory.length - _nSequence) + memoryFree = memoryFree?.slice(memoryFree.length - _nSequence) memory.forEach((ram, key) => { - total += ram; - used += ram - (memoryFree?.[key] ?? 0); - }); + total += ram + used += ram - (memoryFree?.[key] ?? 0) + }) - const percentUsed = percent(used, total); + const percentUsed = percent(used, total) return { // In case `memoryFree` is not given by the xapi, // we won't be able to calculate the percentage of used memory properly. - percentUsed: - memoryFree === undefined || isNaN(percentUsed) ? 0 : percentUsed, + percentUsed: memoryFree === undefined || isNaN(percentUsed) ? 0 : percentUsed, total: total / _nSequence, used: memoryFree === undefined ? 0 : used / _nSequence, - }; + } } -export const getFirst = (value: T | T[]): T | undefined => - Array.isArray(value) ? value[0] : value; +export const getFirst = (value: T | T[]): T | undefined => (Array.isArray(value) ? value[0] : value) diff --git a/@xen-orchestra/lite/src/libs/vm.ts b/@xen-orchestra/lite/src/libs/vm.ts index d4d039fb925..003e8f4d844 100644 --- a/@xen-orchestra/lite/src/libs/vm.ts +++ b/@xen-orchestra/lite/src/libs/vm.ts @@ -1,41 +1,36 @@ -import { saveAs } from "file-saver"; -import type { XenApiVm } from "@/libs/xen-api/xen-api.types"; +import { saveAs } from 'file-saver' +import type { XenApiVm } from '@/libs/xen-api/xen-api.types' function stringifyCsvValue(value: any) { - let res = ""; + let res = '' if (Array.isArray(value)) { - res = value.join(";"); - } else if (typeof value === "object") { - res = JSON.stringify(value); + res = value.join(';') + } else if (typeof value === 'object') { + res = JSON.stringify(value) } else { - res = String(value); + res = String(value) } - return `"${res.replace(/"/g, '""')}"`; + return `"${res.replace(/"/g, '""')}"` } export function exportVmsAsCsvFile(vms: XenApiVm[], fileName: string) { - const csvHeaders = Object.keys(vms[0]); + const csvHeaders = Object.keys(vms[0]) - const csvRows = vms.map((vm) => - csvHeaders.map((header) => stringifyCsvValue(vm[header as keyof XenApiVm])) - ); + const csvRows = vms.map(vm => csvHeaders.map(header => stringifyCsvValue(vm[header as keyof XenApiVm]))) saveAs( - new Blob( - [[csvHeaders, ...csvRows].map((row) => row.join(",")).join("\n")], - { - type: "text/csv;charset=utf-8", - } - ), + new Blob([[csvHeaders, ...csvRows].map(row => row.join(',')).join('\n')], { + type: 'text/csv;charset=utf-8', + }), fileName - ); + ) } export function exportVmsAsJsonFile(vms: XenApiVm[], fileName: string) { saveAs( new Blob([JSON.stringify(vms, null, 2)], { - type: "application/json", + type: 'application/json', }), fileName - ); + ) } diff --git a/@xen-orchestra/lite/src/libs/xapi-stats.ts b/@xen-orchestra/lite/src/libs/xapi-stats.ts index f8c3b8e688e..6069cd1a3dc 100644 --- a/@xen-orchestra/lite/src/libs/xapi-stats.ts +++ b/@xen-orchestra/lite/src/libs/xapi-stats.ts @@ -1,10 +1,11 @@ -import { synchronized } from "decorator-synchronized"; -import JSON5 from "json5"; -import { limitConcurrency } from "limit-concurrency-decorator"; -import { defaults, findKey, forEach, identity, map } from "lodash-es"; -import { BaseError } from "make-error"; -import type XenApi from "@/libs/xen-api/xen-api"; -import type { XenApiHost } from "@/libs/xen-api/xen-api.types"; +import type XenApi from '@/libs/xen-api/xen-api' +import type { XenApiHost } from '@/libs/xen-api/xen-api.types' +import { synchronized } from 'decorator-synchronized' +// eslint-disable-next-line import/default -- https://github.com/json5/json5/issues/287 +import JSON5 from 'json5' +import { limitConcurrency } from 'limit-concurrency-decorator' +import { defaults, findKey, forEach, identity, map } from 'lodash-es' +import { BaseError } from 'make-error' class FaultyGranularity extends BaseError {} @@ -24,10 +25,10 @@ enum RRD_STEP { } export enum GRANULARITY { - Seconds = "seconds", - Minutes = "minutes", - Hours = "hours", - Days = "days", + Seconds = 'seconds', + Minutes = 'minutes', + Hours = 'hours', + Days = 'days', } export const RRD_STEP_FROM_STRING: { [key in GRANULARITY]: RRD_STEP } = { @@ -35,7 +36,7 @@ export const RRD_STEP_FROM_STRING: { [key in GRANULARITY]: RRD_STEP } = { [GRANULARITY.Minutes]: RRD_STEP.Minutes, [GRANULARITY.Hours]: RRD_STEP.Hours, [GRANULARITY.Days]: RRD_STEP.Days, -}; +} // points = intervalInSeconds / step const RRD_POINTS_PER_STEP: { [key in RRD_STEP]: number } = { @@ -43,69 +44,52 @@ const RRD_POINTS_PER_STEP: { [key in RRD_STEP]: number } = { [RRD_STEP.Minutes]: 120, [RRD_STEP.Hours]: 168, [RRD_STEP.Days]: 366, -}; +} // ------------------------------------------------------------------- // Utils // ------------------------------------------------------------------- function convertNanToNull(value: number) { - return isNaN(value) ? null : value; + return isNaN(value) ? null : value } // ------------------------------------------------------------------- // Stats // ------------------------------------------------------------------- -const computeValues = ( - dataRow: any, - legendIndex: number, - transformValue = identity -) => - map(dataRow, ({ values }) => - transformValue(convertNanToNull(values[legendIndex])) - ); - -const createGetProperty = ( - obj: object, - property: string, - defaultValue: unknown -) => defaults(obj, { [property]: defaultValue })[property] as any; +const computeValues = (dataRow: any, legendIndex: number, transformValue = identity) => + map(dataRow, ({ values }) => transformValue(convertNanToNull(values[legendIndex]))) + +const createGetProperty = (obj: object, property: string, defaultValue: unknown) => + defaults(obj, { [property]: defaultValue })[property] as any const testMetric = ( - test: - | string - | { exec: (type: string) => boolean } - | { (type: string): boolean }, + test: string | { exec: (type: string) => boolean } | { (type: string): boolean }, type: string -): boolean => - typeof test === "string" - ? test === type - : typeof test === "function" - ? test(type) - : test.exec(type); +): boolean => (typeof test === 'string' ? test === type : typeof test === 'function' ? test(type) : test.exec(type)) const findMetric = (metrics: any, metricType: string) => { - let testResult; - let metric; + let testResult + let metric - forEach(metrics, (current) => { + forEach(metrics, current => { if (current.test === undefined) { - const newValues = findMetric(current, metricType); + const newValues = findMetric(current, metricType) - metric = newValues.metric; + metric = newValues.metric if (metric !== undefined) { - testResult = newValues.testResult; - return false; + testResult = newValues.testResult + return false } } else if ((testResult = testMetric(current.test, metricType))) { - metric = current; - return false; + metric = current + return false } - }); + }) - return { metric, testResult }; -}; + return { metric, testResult } +} // ------------------------------------------------------------------- @@ -116,115 +100,115 @@ const findMetric = (metrics: any, metricType: string) => { const STATS: { [key: string]: object } = { host: { load: { - test: "loadavg", + test: 'loadavg', }, memoryFree: { - test: "memory_free_kib", + test: 'memory_free_kib', transformValue: (value: number) => value * 1024, }, memory: { - test: "memory_total_kib", + test: 'memory_total_kib', transformValue: (value: number) => value * 1024, }, cpus: { test: /^cpu(\d+)$/, - getPath: (matches: any) => ["cpus", matches[1]], + getPath: (matches: any) => ['cpus', matches[1]], transformValue: (value: number) => value * 1e2, }, pifs: { rx: { test: /^pif_eth(\d+)_rx$/, - getPath: (matches: unknown[]) => ["pifs", "rx", matches[1]], + getPath: (matches: unknown[]) => ['pifs', 'rx', matches[1]], }, tx: { test: /^pif_eth(\d+)_tx$/, - getPath: (matches: unknown[]) => ["pifs", "tx", matches[1]], + getPath: (matches: unknown[]) => ['pifs', 'tx', matches[1]], }, }, iops: { r: { test: /^iops_read_(\w+)$/, - getPath: (matches: unknown[]) => ["iops", "r", matches[1]], + getPath: (matches: unknown[]) => ['iops', 'r', matches[1]], }, w: { test: /^iops_write_(\w+)$/, - getPath: (matches: unknown[]) => ["iops", "w", matches[1]], + getPath: (matches: unknown[]) => ['iops', 'w', matches[1]], }, }, ioThroughput: { r: { test: /^io_throughput_read_(\w+)$/, - getPath: (matches: unknown[]) => ["ioThroughput", "r", matches[1]], + getPath: (matches: unknown[]) => ['ioThroughput', 'r', matches[1]], transformValue: (value: number) => value * 2 ** 20, }, w: { test: /^io_throughput_write_(\w+)$/, - getPath: (matches: unknown[]) => ["ioThroughput", "w", matches[1]], + getPath: (matches: unknown[]) => ['ioThroughput', 'w', matches[1]], transformValue: (value: number) => value * 2 ** 20, }, }, latency: { r: { test: /^read_latency_(\w+)$/, - getPath: (matches: unknown[]) => ["latency", "r", matches[1]], + getPath: (matches: unknown[]) => ['latency', 'r', matches[1]], transformValue: (value: number) => value / 1e3, }, w: { test: /^write_latency_(\w+)$/, - getPath: (matches: unknown[]) => ["latency", "w", matches[1]], + getPath: (matches: unknown[]) => ['latency', 'w', matches[1]], transformValue: (value: number) => value / 1e3, }, }, iowait: { test: /^iowait_(\w+)$/, - getPath: (matches: unknown[]) => ["iowait", matches[1]], + getPath: (matches: unknown[]) => ['iowait', matches[1]], }, }, vm: { memoryFree: { - test: "memory_internal_free", + test: 'memory_internal_free', transformValue: (value: number) => value * 1024, }, memory: { - test: (metricType: string) => metricType.endsWith("memory"), + test: (metricType: string) => metricType.endsWith('memory'), }, cpus: { test: /^cpu(\d+)$/, - getPath: (matches: unknown[]) => ["cpus", matches[1]], + getPath: (matches: unknown[]) => ['cpus', matches[1]], transformValue: (value: number) => value * 1e2, }, vifs: { rx: { test: /^vif_(\d+)_rx$/, - getPath: (matches: unknown[]) => ["vifs", "rx", matches[1]], + getPath: (matches: unknown[]) => ['vifs', 'rx', matches[1]], }, tx: { test: /^vif_(\d+)_tx$/, - getPath: (matches: unknown[]) => ["vifs", "tx", matches[1]], + getPath: (matches: unknown[]) => ['vifs', 'tx', matches[1]], }, }, xvds: { r: { test: /^vbd_xvd(.)_read$/, - getPath: (matches: unknown[]) => ["xvds", "r", matches[1]], + getPath: (matches: unknown[]) => ['xvds', 'r', matches[1]], }, w: { test: /^vbd_xvd(.)_write$/, - getPath: (matches: unknown[]) => ["xvds", "w", matches[1]], + getPath: (matches: unknown[]) => ['xvds', 'w', matches[1]], }, }, iops: { r: { test: /^vbd_xvd(.)_iops_read$/, - getPath: (matches: unknown[]) => ["iops", "r", matches[1]], + getPath: (matches: unknown[]) => ['iops', 'r', matches[1]], }, w: { test: /^vbd_xvd(.)_iops_write$/, - getPath: (matches: unknown[]) => ["iops", "w", matches[1]], + getPath: (matches: unknown[]) => ['iops', 'w', matches[1]], }, }, }, -}; +} // ------------------------------------------------------------------- @@ -253,66 +237,66 @@ const STATS: { [key: string]: object } = { // } export type VmStats = { - cpus: Record; + cpus: Record iops: { - r: Record; - w: Record; - }; - memory: number[]; - memoryFree?: number[]; + r: Record + w: Record + } + memory: number[] + memoryFree?: number[] vifs: { - rx: Record; - tx: Record; - }; + rx: Record + tx: Record + } xvds: { - w: Record; - r: Record; - }; -}; + w: Record + r: Record + } +} export type HostStats = { - cpus: Record; + cpus: Record ioThroughput: { - r: Record; - w: Record; - }; + r: Record + w: Record + } iops: { - r: Record; - w: Record; - }; - iowait: Record; + r: Record + w: Record + } + iowait: Record latency: { - r: Record; - w: Record; - }; - load: number[]; - memory: number[]; - memoryFree: number[]; + r: Record + w: Record + } + load: number[] + memory: number[] + memoryFree: number[] pifs: { - rx: Record; - tx: Record; - }; -}; + rx: Record + tx: Record + } +} export type XapiStatsResponse = { - canBeExpired: boolean; - endTimestamp: number; - interval: number; - stats: T; -}; + canBeExpired: boolean + endTimestamp: number + interval: number + stats: T +} type StatsByObject = { [uuid: string]: { - [step: string]: XapiStatsResponse; - }; -}; + [step: string]: XapiStatsResponse + } +} export default class XapiStats { - #xapi; - #statsByObject: StatsByObject = {}; - #cachedStatsByObject: StatsByObject = {}; + #xapi + #statsByObject: StatsByObject = {} + #cachedStatsByObject: StatsByObject = {} constructor(xapi: XenApi) { - this.#xapi = xapi; + this.#xapi = xapi } // Execute one http request on a XenServer for get stats @@ -324,45 +308,41 @@ export default class XapiStats { step: RRD_STEP, { abortSignal }: { abortSignal?: AbortSignal } = {} ) { - const resp = await this.#xapi.getResource("/rrd_updates", { + const resp = await this.#xapi.getResource('/rrd_updates', { host, query: { - cf: "AVERAGE", - host: "true", + cf: 'AVERAGE', + host: 'true', interval: step, - json: "true", + json: 'true', start: timestamp, }, abortSignal, - }); - return JSON5.parse(await resp.text()); + }) + // eslint-disable-next-line import/no-named-as-default-member -- https://github.com/json5/json5/issues/287 + return JSON5.parse(await resp.text()) } // To avoid multiple requests, we keep a cache for the stats and // only return it if we not exceed a step - #getCachedStats( - uuid: string, - step: RRD_STEP, - currentTimeStamp: number, - ignoreExpired = false - ) { + #getCachedStats(uuid: string, step: RRD_STEP, currentTimeStamp: number, ignoreExpired = false) { if (ignoreExpired) { - return this.#cachedStatsByObject[uuid]?.[step]; + return this.#cachedStatsByObject[uuid]?.[step] } - const statsByObject = this.#statsByObject; + const statsByObject = this.#statsByObject - const stats = statsByObject[uuid]?.[step]; + const stats = statsByObject[uuid]?.[step] if (stats === undefined) { - return; + return } if (stats.endTimestamp + step < currentTimeStamp) { - delete statsByObject[uuid][step]; - return; + delete statsByObject[uuid][step] + return } - return stats; + return stats } @synchronized.withKey(({ host }: { host: XenApiHost }) => host.uuid) @@ -373,145 +353,107 @@ export default class XapiStats { uuid, granularity, }: { - abortSignal?: AbortSignal; - host: XenApiHost; - ignoreExpired?: boolean; - uuid: any; - granularity: GRANULARITY; + abortSignal?: AbortSignal + host: XenApiHost + ignoreExpired?: boolean + uuid: any + granularity: GRANULARITY }) { - const step = - granularity === undefined - ? RRD_STEP.Seconds - : RRD_STEP_FROM_STRING[granularity]; + const step = granularity === undefined ? RRD_STEP.Seconds : RRD_STEP_FROM_STRING[granularity] if (step === undefined) { throw new FaultyGranularity( `Unknown granularity: '${granularity}'. Use 'seconds', 'minutes', 'hours', or 'days'.` - ); + ) } - const currentTimeStamp = Math.floor(new Date().getTime() / 1000); + const currentTimeStamp = Math.floor(new Date().getTime() / 1000) - const stats = this.#getCachedStats( - uuid, - step, - currentTimeStamp, - ignoreExpired - ) as XapiStatsResponse; + const stats = this.#getCachedStats(uuid, step, currentTimeStamp, ignoreExpired) as XapiStatsResponse if (stats !== undefined) { - return stats; + return stats } - const maxDuration = step * RRD_POINTS_PER_STEP[step]; + const maxDuration = step * RRD_POINTS_PER_STEP[step] // To avoid crossing over the boundary, we ask for one less step - const optimumTimestamp = currentTimeStamp - maxDuration + step; + const optimumTimestamp = currentTimeStamp - maxDuration + step try { const json = await this._getJson(host, optimumTimestamp, step, { abortSignal, - }); + }) - const actualStep = json.meta.step as number; + const actualStep = json.meta.step as number if (json.data.length > 0) { // fetched data is organized from the newest to the oldest // but this implementation requires it in the other direction - json.data.reverse(); + json.data.reverse() json.meta.legend.forEach((legend: any, index: number) => { - const [, type, uuid, metricType] = /^AVERAGE:([^:]+):(.+):(.+)$/.exec( - legend - ) as any; + const [, type, uuid, metricType] = /^AVERAGE:([^:]+):(.+):(.+)$/.exec(legend) as any - const metrics = STATS[type] as any; + const metrics = STATS[type] as any if (metrics === undefined) { - return; + return } - const { metric, testResult } = findMetric(metrics, metricType) as any; + const { metric, testResult } = findMetric(metrics, metricType) as any if (metric === undefined) { - return; + return } - const xoObjectStats = createGetProperty( - this.#statsByObject, - uuid, - {} - ); - const cacheXoObjectStats = createGetProperty( - this.#cachedStatsByObject, - uuid, - {} - ); - - let stepStats = xoObjectStats[actualStep]; - let cacheStepStats = cacheXoObjectStats[actualStep]; - if ( - stepStats === undefined || - stepStats.endTimestamp !== json.meta.end - ) { + const xoObjectStats = createGetProperty(this.#statsByObject, uuid, {}) + const cacheXoObjectStats = createGetProperty(this.#cachedStatsByObject, uuid, {}) + + let stepStats = xoObjectStats[actualStep] + let cacheStepStats = cacheXoObjectStats[actualStep] + if (stepStats === undefined || stepStats.endTimestamp !== json.meta.end) { stepStats = xoObjectStats[actualStep] = { endTimestamp: json.meta.end, interval: actualStep, canBeExpired: false, - }; + } cacheStepStats = cacheXoObjectStats[actualStep] = { endTimestamp: json.meta.end, interval: actualStep, canBeExpired: true, - }; + } } - const path = - metric.getPath !== undefined - ? metric.getPath(testResult) - : [findKey(metrics, metric)]; + const path = metric.getPath !== undefined ? metric.getPath(testResult) : [findKey(metrics, metric)] - const lastKey = path.length - 1; - let metricStats = createGetProperty(stepStats, "stats", {}); - let cacheMetricStats = createGetProperty(cacheStepStats, "stats", {}); + const lastKey = path.length - 1 + let metricStats = createGetProperty(stepStats, 'stats', {}) + let cacheMetricStats = createGetProperty(cacheStepStats, 'stats', {}) path.forEach((property: any, key: number) => { if (key === lastKey) { - metricStats[property] = computeValues( - json.data, - index, - metric.transformValue - ); - cacheMetricStats[property] = computeValues( - json.data, - index, - metric.transformValue - ); - return; + metricStats[property] = computeValues(json.data, index, metric.transformValue) + cacheMetricStats[property] = computeValues(json.data, index, metric.transformValue) + return } - metricStats = createGetProperty(metricStats, property, {}); - cacheMetricStats = createGetProperty( - cacheMetricStats, - property, - {} - ); - }); - }); + metricStats = createGetProperty(metricStats, property, {}) + cacheMetricStats = createGetProperty(cacheMetricStats, property, {}) + }) + }) } if (actualStep !== step) { - throw new FaultyGranularity( - `Unable to get the true granularity: ${actualStep}` - ); + throw new FaultyGranularity(`Unable to get the true granularity: ${actualStep}`) } } catch (error) { - if (error instanceof Error && error.name === "AbortError") { - return; + if (error instanceof Error && error.name === 'AbortError') { + return } - throw error; + throw error } return (this.#statsByObject[uuid]?.[step] ?? { endTimestamp: currentTimeStamp, interval: step, stats: {}, - }) as XapiStatsResponse; + }) as XapiStatsResponse } } diff --git a/@xen-orchestra/lite/src/libs/xen-api/xen-api.enums.ts b/@xen-orchestra/lite/src/libs/xen-api/xen-api.enums.ts index 0a2f286001d..7b2dea9b32a 100644 --- a/@xen-orchestra/lite/src/libs/xen-api/xen-api.enums.ts +++ b/@xen-orchestra/lite/src/libs/xen-api/xen-api.enums.ts @@ -1,499 +1,499 @@ export enum TASK_ALLOWED_OPERATION { - CANCEL = "cancel", - DESTROY = "destroy", + CANCEL = 'cancel', + DESTROY = 'destroy', } export enum TASK_STATUS_TYPE { - CANCELLED = "cancelled", - CANCELLING = "cancelling", - FAILURE = "failure", - PENDING = "pending", - SUCCESS = "success", + CANCELLED = 'cancelled', + CANCELLING = 'cancelling', + FAILURE = 'failure', + PENDING = 'pending', + SUCCESS = 'success', } export enum EVENT_OPERATION { - ADD = "add", - DEL = "del", - MOD = "mod", + ADD = 'add', + DEL = 'del', + MOD = 'mod', } export enum POOL_ALLOWED_OPERATION { - APPLY_UPDATES = "apply_updates", - CERT_REFRESH = "cert_refresh", - CLUSTER_CREATE = "cluster_create", - CONFIGURE_REPOSITORIES = "configure_repositories", - COPY_PRIMARY_HOST_CERTS = "copy_primary_host_certs", - DESIGNATE_NEW_MASTER = "designate_new_master", - EXCHANGE_CA_CERTIFICATES_ON_JOIN = "exchange_ca_certificates_on_join", - EXCHANGE_CERTIFICATES_ON_JOIN = "exchange_certificates_on_join", - GET_UPDATES = "get_updates", - HA_DISABLE = "ha_disable", - HA_ENABLE = "ha_enable", - SYNC_UPDATES = "sync_updates", - TLS_VERIFICATION_ENABLE = "tls_verification_enable", + APPLY_UPDATES = 'apply_updates', + CERT_REFRESH = 'cert_refresh', + CLUSTER_CREATE = 'cluster_create', + CONFIGURE_REPOSITORIES = 'configure_repositories', + COPY_PRIMARY_HOST_CERTS = 'copy_primary_host_certs', + DESIGNATE_NEW_MASTER = 'designate_new_master', + EXCHANGE_CA_CERTIFICATES_ON_JOIN = 'exchange_ca_certificates_on_join', + EXCHANGE_CERTIFICATES_ON_JOIN = 'exchange_certificates_on_join', + GET_UPDATES = 'get_updates', + HA_DISABLE = 'ha_disable', + HA_ENABLE = 'ha_enable', + SYNC_UPDATES = 'sync_updates', + TLS_VERIFICATION_ENABLE = 'tls_verification_enable', } export enum TELEMETRY_FREQUENCY { - DAILY = "daily", - MONTHLY = "monthly", - WEEKLY = "weekly", + DAILY = 'daily', + MONTHLY = 'monthly', + WEEKLY = 'weekly', } export enum UPDATE_SYNC_FREQUENCY { - DAILY = "daily", - WEEKLY = "weekly", + DAILY = 'daily', + WEEKLY = 'weekly', } export enum AFTER_APPLY_GUIDANCE { - RESTART_HOST = "restartHost", - RESTART_HVM = "restartHVM", - RESTART_PV = "restartPV", - RESTART_XAPI = "restartXAPI", + RESTART_HOST = 'restartHost', + RESTART_HVM = 'restartHVM', + RESTART_PV = 'restartPV', + RESTART_XAPI = 'restartXAPI', } export enum UPDATE_AFTER_APPLY_GUIDANCE { - RESTART_HOST = "restartHost", - RESTART_HVM = "restartHVM", - RESTART_PV = "restartPV", - RESTART_XAPI = "restartXAPI", + RESTART_HOST = 'restartHost', + RESTART_HVM = 'restartHVM', + RESTART_PV = 'restartPV', + RESTART_XAPI = 'restartXAPI', } export enum LIVEPATCH_STATUS { - OK = "ok", - OK_LIVEPATCH_COMPLETE = "ok_livepatch_complete", - OK_LIVEPATCH_INCOMPLETE = "ok_livepatch_incomplete", + OK = 'ok', + OK_LIVEPATCH_COMPLETE = 'ok_livepatch_complete', + OK_LIVEPATCH_INCOMPLETE = 'ok_livepatch_incomplete', } export enum VM_POWER_STATE { - HALTED = "Halted", - PAUSED = "Paused", - RUNNING = "Running", - SUSPENDED = "Suspended", + HALTED = 'Halted', + PAUSED = 'Paused', + RUNNING = 'Running', + SUSPENDED = 'Suspended', } export enum UPDATE_GUIDANCE { - REBOOT_HOST = "reboot_host", - REBOOT_HOST_ON_LIVEPATCH_FAILURE = "reboot_host_on_livepatch_failure", - RESTART_DEVICE_MODEL = "restart_device_model", - RESTART_TOOLSTACK = "restart_toolstack", + REBOOT_HOST = 'reboot_host', + REBOOT_HOST_ON_LIVEPATCH_FAILURE = 'reboot_host_on_livepatch_failure', + RESTART_DEVICE_MODEL = 'restart_device_model', + RESTART_TOOLSTACK = 'restart_toolstack', } export enum ON_SOFTREBOOT_BEHAVIOR { - DESTROY = "destroy", - PRESERVE = "preserve", - RESTART = "restart", - SOFT_REBOOT = "soft_reboot", + DESTROY = 'destroy', + PRESERVE = 'preserve', + RESTART = 'restart', + SOFT_REBOOT = 'soft_reboot', } export enum ON_NORMAL_EXIT { - DESTROY = "destroy", - RESTART = "restart", + DESTROY = 'destroy', + RESTART = 'restart', } export enum VM_OPERATION { - ASSERT_OPERATION_VALID = "assert_operation_valid", - AWAITING_MEMORY_LIVE = "awaiting_memory_live", - CALL_PLUGIN = "call_plugin", - CHANGING_DYNAMIC_RANGE = "changing_dynamic_range", - CHANGING_MEMORY_LIMITS = "changing_memory_limits", - CHANGING_MEMORY_LIVE = "changing_memory_live", - CHANGING_NVRAM = "changing_NVRAM", - CHANGING_SHADOW_MEMORY = "changing_shadow_memory", - CHANGING_SHADOW_MEMORY_LIVE = "changing_shadow_memory_live", - CHANGING_STATIC_RANGE = "changing_static_range", - CHANGING_VCPUS = "changing_VCPUs", - CHANGING_VCPUS_LIVE = "changing_VCPUs_live", - CHECKPOINT = "checkpoint", - CLEAN_REBOOT = "clean_reboot", - CLEAN_SHUTDOWN = "clean_shutdown", - CLONE = "clone", - COPY = "copy", - CREATE_TEMPLATE = "create_template", - CREATE_VTPM = "create_vtpm", - CSVM = "csvm", - DATA_SOURCE_OP = "data_source_op", - DESTROY = "destroy", - EXPORT = "export", - GET_BOOT_RECORD = "get_boot_record", - HARD_REBOOT = "hard_reboot", - HARD_SHUTDOWN = "hard_shutdown", - IMPORT = "import", - MAKE_INTO_TEMPLATE = "make_into_template", - METADATA_EXPORT = "metadata_export", - MIGRATE_SEND = "migrate_send", - PAUSE = "pause", - POOL_MIGRATE = "pool_migrate", - POWER_STATE_RESET = "power_state_reset", - PROVISION = "provision", - QUERY_SERVICES = "query_services", - RESUME = "resume", - RESUME_ON = "resume_on", - REVERT = "revert", - REVERTING = "reverting", - SEND_SYSRQ = "send_sysrq", - SEND_TRIGGER = "send_trigger", - SHUTDOWN = "shutdown", - SNAPSHOT = "snapshot", - SNAPSHOT_WITH_QUIESCE = "snapshot_with_quiesce", - START = "start", - START_ON = "start_on", - SUSPEND = "suspend", - UNPAUSE = "unpause", - UPDATE_ALLOWED_OPERATIONS = "update_allowed_operations", + ASSERT_OPERATION_VALID = 'assert_operation_valid', + AWAITING_MEMORY_LIVE = 'awaiting_memory_live', + CALL_PLUGIN = 'call_plugin', + CHANGING_DYNAMIC_RANGE = 'changing_dynamic_range', + CHANGING_MEMORY_LIMITS = 'changing_memory_limits', + CHANGING_MEMORY_LIVE = 'changing_memory_live', + CHANGING_NVRAM = 'changing_NVRAM', + CHANGING_SHADOW_MEMORY = 'changing_shadow_memory', + CHANGING_SHADOW_MEMORY_LIVE = 'changing_shadow_memory_live', + CHANGING_STATIC_RANGE = 'changing_static_range', + CHANGING_VCPUS = 'changing_VCPUs', + CHANGING_VCPUS_LIVE = 'changing_VCPUs_live', + CHECKPOINT = 'checkpoint', + CLEAN_REBOOT = 'clean_reboot', + CLEAN_SHUTDOWN = 'clean_shutdown', + CLONE = 'clone', + COPY = 'copy', + CREATE_TEMPLATE = 'create_template', + CREATE_VTPM = 'create_vtpm', + CSVM = 'csvm', + DATA_SOURCE_OP = 'data_source_op', + DESTROY = 'destroy', + EXPORT = 'export', + GET_BOOT_RECORD = 'get_boot_record', + HARD_REBOOT = 'hard_reboot', + HARD_SHUTDOWN = 'hard_shutdown', + IMPORT = 'import', + MAKE_INTO_TEMPLATE = 'make_into_template', + METADATA_EXPORT = 'metadata_export', + MIGRATE_SEND = 'migrate_send', + PAUSE = 'pause', + POOL_MIGRATE = 'pool_migrate', + POWER_STATE_RESET = 'power_state_reset', + PROVISION = 'provision', + QUERY_SERVICES = 'query_services', + RESUME = 'resume', + RESUME_ON = 'resume_on', + REVERT = 'revert', + REVERTING = 'reverting', + SEND_SYSRQ = 'send_sysrq', + SEND_TRIGGER = 'send_trigger', + SHUTDOWN = 'shutdown', + SNAPSHOT = 'snapshot', + SNAPSHOT_WITH_QUIESCE = 'snapshot_with_quiesce', + START = 'start', + START_ON = 'start_on', + SUSPEND = 'suspend', + UNPAUSE = 'unpause', + UPDATE_ALLOWED_OPERATIONS = 'update_allowed_operations', } export enum ON_CRASH_BEHAVIOUR { - COREDUMP_AND_DESTROY = "coredump_and_destroy", - COREDUMP_AND_RESTART = "coredump_and_restart", - DESTROY = "destroy", - PRESERVE = "preserve", - RENAME_RESTART = "rename_restart", - RESTART = "restart", + COREDUMP_AND_DESTROY = 'coredump_and_destroy', + COREDUMP_AND_RESTART = 'coredump_and_restart', + DESTROY = 'destroy', + PRESERVE = 'preserve', + RENAME_RESTART = 'rename_restart', + RESTART = 'restart', } export enum DOMAIN_TYPE { - HVM = "hvm", - PV = "pv", - PVH = "pvh", - PV_IN_PVH = "pv_in_pvh", - UNSPECIFIED = "unspecified", + HVM = 'hvm', + PV = 'pv', + PVH = 'pvh', + PV_IN_PVH = 'pv_in_pvh', + UNSPECIFIED = 'unspecified', } export enum TRISTATE_TYPE { - NO = "no", - UNSPECIFIED = "unspecified", - YES = "yes", + NO = 'no', + UNSPECIFIED = 'unspecified', + YES = 'yes', } export enum VMPP_BACKUP_TYPE { - CHECKPOINT = "checkpoint", - SNAPSHOT = "snapshot", + CHECKPOINT = 'checkpoint', + SNAPSHOT = 'snapshot', } export enum VMPP_BACKUP_FREQUENCY { - DAILY = "daily", - HOURLY = "hourly", - WEEKLY = "weekly", + DAILY = 'daily', + HOURLY = 'hourly', + WEEKLY = 'weekly', } export enum VMPP_ARCHIVE_FREQUENCY { - ALWAYS_AFTER_BACKUP = "always_after_backup", - DAILY = "daily", - NEVER = "never", - WEEKLY = "weekly", + ALWAYS_AFTER_BACKUP = 'always_after_backup', + DAILY = 'daily', + NEVER = 'never', + WEEKLY = 'weekly', } export enum VMPP_ARCHIVE_TARGET_TYPE { - CIFS = "cifs", - NFS = "nfs", - NONE = "none", + CIFS = 'cifs', + NFS = 'nfs', + NONE = 'none', } export enum VMSS_FREQUENCY { - DAILY = "daily", - HOURLY = "hourly", - WEEKLY = "weekly", + DAILY = 'daily', + HOURLY = 'hourly', + WEEKLY = 'weekly', } export enum VMSS_TYPE { - CHECKPOINT = "checkpoint", - SNAPSHOT = "snapshot", - SNAPSHOT_WITH_QUIESCE = "snapshot_with_quiesce", + CHECKPOINT = 'checkpoint', + SNAPSHOT = 'snapshot', + SNAPSHOT_WITH_QUIESCE = 'snapshot_with_quiesce', } export enum VM_APPLIANCE_OPERATION { - CLEAN_SHUTDOWN = "clean_shutdown", - HARD_SHUTDOWN = "hard_shutdown", - SHUTDOWN = "shutdown", - START = "start", + CLEAN_SHUTDOWN = 'clean_shutdown', + HARD_SHUTDOWN = 'hard_shutdown', + SHUTDOWN = 'shutdown', + START = 'start', } export enum HOST_ALLOWED_OPERATION { - APPLY_UPDATES = "apply_updates", - EVACUATE = "evacuate", - POWER_ON = "power_on", - PROVISION = "provision", - REBOOT = "reboot", - SHUTDOWN = "shutdown", - VM_MIGRATE = "vm_migrate", - VM_RESUME = "vm_resume", - VM_START = "vm_start", + APPLY_UPDATES = 'apply_updates', + EVACUATE = 'evacuate', + POWER_ON = 'power_on', + PROVISION = 'provision', + REBOOT = 'reboot', + SHUTDOWN = 'shutdown', + VM_MIGRATE = 'vm_migrate', + VM_RESUME = 'vm_resume', + VM_START = 'vm_start', } export enum LATEST_SYNCED_UPDATES_APPLIED_STATE { - NO = "no", - UNKNOWN = "unknown", - YES = "yes", + NO = 'no', + UNKNOWN = 'unknown', + YES = 'yes', } export enum HOST_DISPLAY { - DISABLED = "disabled", - DISABLE_ON_REBOOT = "disable_on_reboot", - ENABLED = "enabled", - ENABLE_ON_REBOOT = "enable_on_reboot", + DISABLED = 'disabled', + DISABLE_ON_REBOOT = 'disable_on_reboot', + ENABLED = 'enabled', + ENABLE_ON_REBOOT = 'enable_on_reboot', } export enum HOST_SCHED_GRAN { - CORE = "core", - CPU = "cpu", - SOCKET = "socket", + CORE = 'core', + CPU = 'cpu', + SOCKET = 'socket', } export enum NETWORK_OPERATION { - ATTACHING = "attaching", + ATTACHING = 'attaching', } export enum NETWORK_DEFAULT_LOCKING_MODE { - DISABLED = "disabled", - UNLOCKED = "unlocked", + DISABLED = 'disabled', + UNLOCKED = 'unlocked', } export enum NETWORK_PURPOSE { - INSECURE_NBD = "insecure_nbd", - NBD = "nbd", + INSECURE_NBD = 'insecure_nbd', + NBD = 'nbd', } export enum VIF_OPERATION { - ATTACH = "attach", - PLUG = "plug", - UNPLUG = "unplug", + ATTACH = 'attach', + PLUG = 'plug', + UNPLUG = 'unplug', } export enum VIF_LOCKING_MODE { - DISABLED = "disabled", - LOCKED = "locked", - NETWORK_DEFAULT = "network_default", - UNLOCKED = "unlocked", + DISABLED = 'disabled', + LOCKED = 'locked', + NETWORK_DEFAULT = 'network_default', + UNLOCKED = 'unlocked', } export enum VIF_IPV4_CONFIGURATION_MODE { - NONE = "None", - STATIC = "Static", + NONE = 'None', + STATIC = 'Static', } export enum VIF_IPV6_CONFIGURATION_MODE { - NONE = "None", - STATIC = "Static", + NONE = 'None', + STATIC = 'Static', } export enum PIF_IGMP_STATUS { - DISABLED = "disabled", - ENABLED = "enabled", - UNKNOWN = "unknown", + DISABLED = 'disabled', + ENABLED = 'enabled', + UNKNOWN = 'unknown', } export enum IP_CONFIGURATION_MODE { - DHCP = "DHCP", - NONE = "None", - STATIC = "Static", + DHCP = 'DHCP', + NONE = 'None', + STATIC = 'Static', } export enum IPV6_CONFIGURATION_MODE { - AUTOCONF = "Autoconf", - DHCP = "DHCP", - NONE = "None", - STATIC = "Static", + AUTOCONF = 'Autoconf', + DHCP = 'DHCP', + NONE = 'None', + STATIC = 'Static', } export enum PRIMARY_ADDRESS_TYPE { - IPV4 = "IPv4", - IPV6 = "IPv6", + IPV4 = 'IPv4', + IPV6 = 'IPv6', } export enum BOND_MODE { - ACTIVE_BACKUP = "active-backup", - BALANCE_SLB = "balance-slb", - LACP = "lacp", + ACTIVE_BACKUP = 'active-backup', + BALANCE_SLB = 'balance-slb', + LACP = 'lacp', } export enum STORAGE_OPERATION { - DESTROY = "destroy", - FORGET = "forget", - PBD_CREATE = "pbd_create", - PBD_DESTROY = "pbd_destroy", - PLUG = "plug", - SCAN = "scan", - UNPLUG = "unplug", - UPDATE = "update", - VDI_CLONE = "vdi_clone", - VDI_CREATE = "vdi_create", - VDI_DATA_DESTROY = "vdi_data_destroy", - VDI_DESTROY = "vdi_destroy", - VDI_DISABLE_CBT = "vdi_disable_cbt", - VDI_ENABLE_CBT = "vdi_enable_cbt", - VDI_INTRODUCE = "vdi_introduce", - VDI_LIST_CHANGED_BLOCKS = "vdi_list_changed_blocks", - VDI_MIRROR = "vdi_mirror", - VDI_RESIZE = "vdi_resize", - VDI_SET_ON_BOOT = "vdi_set_on_boot", - VDI_SNAPSHOT = "vdi_snapshot", + DESTROY = 'destroy', + FORGET = 'forget', + PBD_CREATE = 'pbd_create', + PBD_DESTROY = 'pbd_destroy', + PLUG = 'plug', + SCAN = 'scan', + UNPLUG = 'unplug', + UPDATE = 'update', + VDI_CLONE = 'vdi_clone', + VDI_CREATE = 'vdi_create', + VDI_DATA_DESTROY = 'vdi_data_destroy', + VDI_DESTROY = 'vdi_destroy', + VDI_DISABLE_CBT = 'vdi_disable_cbt', + VDI_ENABLE_CBT = 'vdi_enable_cbt', + VDI_INTRODUCE = 'vdi_introduce', + VDI_LIST_CHANGED_BLOCKS = 'vdi_list_changed_blocks', + VDI_MIRROR = 'vdi_mirror', + VDI_RESIZE = 'vdi_resize', + VDI_SET_ON_BOOT = 'vdi_set_on_boot', + VDI_SNAPSHOT = 'vdi_snapshot', } export enum SR_HEALTH { - HEALTHY = "healthy", - RECOVERING = "recovering", + HEALTHY = 'healthy', + RECOVERING = 'recovering', } export enum VDI_OPERATION { - BLOCKED = "blocked", - CLONE = "clone", - COPY = "copy", - DATA_DESTROY = "data_destroy", - DESTROY = "destroy", - DISABLE_CBT = "disable_cbt", - ENABLE_CBT = "enable_cbt", - FORCE_UNLOCK = "force_unlock", - FORGET = "forget", - GENERATE_CONFIG = "generate_config", - LIST_CHANGED_BLOCKS = "list_changed_blocks", - MIRROR = "mirror", - RESIZE = "resize", - RESIZE_ONLINE = "resize_online", - SET_ON_BOOT = "set_on_boot", - SNAPSHOT = "snapshot", - UPDATE = "update", + BLOCKED = 'blocked', + CLONE = 'clone', + COPY = 'copy', + DATA_DESTROY = 'data_destroy', + DESTROY = 'destroy', + DISABLE_CBT = 'disable_cbt', + ENABLE_CBT = 'enable_cbt', + FORCE_UNLOCK = 'force_unlock', + FORGET = 'forget', + GENERATE_CONFIG = 'generate_config', + LIST_CHANGED_BLOCKS = 'list_changed_blocks', + MIRROR = 'mirror', + RESIZE = 'resize', + RESIZE_ONLINE = 'resize_online', + SET_ON_BOOT = 'set_on_boot', + SNAPSHOT = 'snapshot', + UPDATE = 'update', } export enum VDI_TYPE { - CBT_METADATA = "cbt_metadata", - CRASHDUMP = "crashdump", - EPHEMERAL = "ephemeral", - HA_STATEFILE = "ha_statefile", - METADATA = "metadata", - PVS_CACHE = "pvs_cache", - REDO_LOG = "redo_log", - RRD = "rrd", - SUSPEND = "suspend", - SYSTEM = "system", - USER = "user", + CBT_METADATA = 'cbt_metadata', + CRASHDUMP = 'crashdump', + EPHEMERAL = 'ephemeral', + HA_STATEFILE = 'ha_statefile', + METADATA = 'metadata', + PVS_CACHE = 'pvs_cache', + REDO_LOG = 'redo_log', + RRD = 'rrd', + SUSPEND = 'suspend', + SYSTEM = 'system', + USER = 'user', } export enum ON_BOOT { - PERSIST = "persist", - RESET = "reset", + PERSIST = 'persist', + RESET = 'reset', } export enum VBD_OPERATION { - ATTACH = "attach", - EJECT = "eject", - INSERT = "insert", - PAUSE = "pause", - PLUG = "plug", - UNPAUSE = "unpause", - UNPLUG = "unplug", - UNPLUG_FORCE = "unplug_force", + ATTACH = 'attach', + EJECT = 'eject', + INSERT = 'insert', + PAUSE = 'pause', + PLUG = 'plug', + UNPAUSE = 'unpause', + UNPLUG = 'unplug', + UNPLUG_FORCE = 'unplug_force', } export enum VBD_TYPE { - CD = "CD", - DISK = "Disk", - FLOPPY = "Floppy", + CD = 'CD', + DISK = 'Disk', + FLOPPY = 'Floppy', } export enum VBD_MODE { - RO = "RO", - RW = "RW", + RO = 'RO', + RW = 'RW', } export enum VTPM_OPERATION { - DESTROY = "destroy", + DESTROY = 'destroy', } export enum PERSISTENCE_BACKEND { - XAPI = "xapi", + XAPI = 'xapi', } export enum CONSOLE_PROTOCOL { - RDP = "rdp", - RFB = "rfb", - VT100 = "vt100", + RDP = 'rdp', + RFB = 'rfb', + VT100 = 'vt100', } export enum CLS { - CERTIFICATE = "Certificate", - HOST = "Host", - POOL = "Pool", - PVS_PROXY = "PVS_proxy", - SR = "SR", - VDI = "VDI", - VM = "VM", - VMPP = "VMPP", - VMSS = "VMSS", + CERTIFICATE = 'Certificate', + HOST = 'Host', + POOL = 'Pool', + PVS_PROXY = 'PVS_proxy', + SR = 'SR', + VDI = 'VDI', + VM = 'VM', + VMPP = 'VMPP', + VMSS = 'VMSS', } export enum TUNNEL_PROTOCOL { - GRE = "gre", - VXLAN = "vxlan", + GRE = 'gre', + VXLAN = 'vxlan', } export enum SRIOV_CONFIGURATION_MODE { - MANUAL = "manual", - MODPROBE = "modprobe", - SYSFS = "sysfs", - UNKNOWN = "unknown", + MANUAL = 'manual', + MODPROBE = 'modprobe', + SYSFS = 'sysfs', + UNKNOWN = 'unknown', } export enum PGPU_DOM0_ACCESS { - DISABLED = "disabled", - DISABLE_ON_REBOOT = "disable_on_reboot", - ENABLED = "enabled", - ENABLE_ON_REBOOT = "enable_on_reboot", + DISABLED = 'disabled', + DISABLE_ON_REBOOT = 'disable_on_reboot', + ENABLED = 'enabled', + ENABLE_ON_REBOOT = 'enable_on_reboot', } export enum ALLOCATION_ALGORITHM { - BREADTH_FIRST = "breadth_first", - DEPTH_FIRST = "depth_first", + BREADTH_FIRST = 'breadth_first', + DEPTH_FIRST = 'depth_first', } export enum VGPU_TYPE_IMPLEMENTATION { - GVT_G = "gvt_g", - MXGPU = "mxgpu", - NVIDIA = "nvidia", - NVIDIA_SRIOV = "nvidia_sriov", - PASSTHROUGH = "passthrough", + GVT_G = 'gvt_g', + MXGPU = 'mxgpu', + NVIDIA = 'nvidia', + NVIDIA_SRIOV = 'nvidia_sriov', + PASSTHROUGH = 'passthrough', } export enum PVS_PROXY_STATUS { - CACHING = "caching", - INCOMPATIBLE_PROTOCOL_VERSION = "incompatible_protocol_version", - INCOMPATIBLE_WRITE_CACHE_MODE = "incompatible_write_cache_mode", - INITIALISED = "initialised", - STOPPED = "stopped", + CACHING = 'caching', + INCOMPATIBLE_PROTOCOL_VERSION = 'incompatible_protocol_version', + INCOMPATIBLE_WRITE_CACHE_MODE = 'incompatible_write_cache_mode', + INITIALISED = 'initialised', + STOPPED = 'stopped', } export enum SDN_CONTROLLER_PROTOCOL { - PSSL = "pssl", - SSL = "ssl", + PSSL = 'pssl', + SSL = 'ssl', } export enum VUSB_OPERATION { - ATTACH = "attach", - PLUG = "plug", - UNPLUG = "unplug", + ATTACH = 'attach', + PLUG = 'plug', + UNPLUG = 'unplug', } export enum CLUSTER_OPERATION { - ADD = "add", - DESTROY = "destroy", - DISABLE = "disable", - ENABLE = "enable", - REMOVE = "remove", + ADD = 'add', + DESTROY = 'destroy', + DISABLE = 'disable', + ENABLE = 'enable', + REMOVE = 'remove', } export enum CLUSTER_HOST_OPERATION { - DESTROY = "destroy", - DISABLE = "disable", - ENABLE = "enable", + DESTROY = 'destroy', + DISABLE = 'disable', + ENABLE = 'enable', } export enum CERTIFICATE_TYPE { - CA = "ca", - HOST = "host", - HOST_INTERNAL = "host_internal", + CA = 'ca', + HOST = 'host', + HOST_INTERNAL = 'host_internal', } export enum VM_COMPRESSION_TYPE { - DISABLED = "false", - GZIP = "true", - ZSTD = "zstd", + DISABLED = 'false', + GZIP = 'true', + ZSTD = 'zstd', } diff --git a/@xen-orchestra/lite/src/libs/xen-api/xen-api.ts b/@xen-orchestra/lite/src/libs/xen-api/xen-api.ts index b082670507f..54888a08521 100644 --- a/@xen-orchestra/lite/src/libs/xen-api/xen-api.ts +++ b/@xen-orchestra/lite/src/libs/xen-api/xen-api.ts @@ -14,406 +14,313 @@ import type { XenApiRecordLoadErrorEvent, XenApiRecordModEvent, XenApiVm, -} from "@/libs/xen-api/xen-api.types"; -import { buildXoObject, typeToRawType } from "@/libs/xen-api/xen-api.utils"; -import { JSONRPCClient } from "json-rpc-2.0"; -import { castArray } from "lodash-es"; -import type { VM_COMPRESSION_TYPE } from "@/libs/xen-api/xen-api.enums"; -import { useModal } from "@/composables/modal.composable"; +} from '@/libs/xen-api/xen-api.types' +import { buildXoObject, typeToRawType } from '@/libs/xen-api/xen-api.utils' +import { JSONRPCClient } from 'json-rpc-2.0' +import { castArray } from 'lodash-es' +import type { VM_COMPRESSION_TYPE } from '@/libs/xen-api/xen-api.enums' +import { useModal } from '@/composables/modal.composable' export default class XenApi { - private client: JSONRPCClient; - private sessionId: string | undefined; - private events = new Map< - XenApiRecordEvent, - Set<(...args: any[]) => void> - >(); - private fromToken: string | undefined; - private hostUrl: string; + private client: JSONRPCClient + private sessionId: string | undefined + private events = new Map, Set<(...args: any[]) => void>>() + private fromToken: string | undefined + private hostUrl: string constructor(hostUrl: string) { - this.hostUrl = hostUrl; - this.client = new JSONRPCClient(async (request) => { + this.hostUrl = hostUrl + this.client = new JSONRPCClient(async request => { const response = await fetch(`${this.hostUrl}/jsonrpc`, { - method: "POST", - headers: { "content-type": "application/json" }, + method: 'POST', + headers: { 'content-type': 'application/json' }, body: JSON.stringify(request), - }); + }) if (response.status === 200) { - const json = await response.json(); - return this.client.receive(json); + const json = await response.json() + return this.client.receive(json) } else if (request.id !== undefined) { - return Promise.reject(new Error(response.statusText)); + return Promise.reject(new Error(response.statusText)) } - }); + }) } async connectWithPassword(username: string, password: string) { - this.sessionId = await this.request("session.login_with_password", [ - username, - password, - ]); + this.sessionId = await this.request('session.login_with_password', [username, password]) - return this.sessionId; + return this.sessionId } async connectWithSessionId(sessionId: string) { try { - this.sessionId = undefined; + this.sessionId = undefined - await this.request("session.get_all_subject_identifiers", [sessionId]); + await this.request('session.get_all_subject_identifiers', [sessionId]) - this.sessionId = sessionId; + this.sessionId = sessionId - return true; + return true } catch (error: any) { - if (error?.message === "SESSION_INVALID") { - return false; + if (error?.message === 'SESSION_INVALID') { + return false } else { - throw error; + throw error } } } async disconnect() { - await this.call("session.logout"); - this.sessionId = undefined; - this.fromToken = undefined; + await this.call('session.logout') + this.sessionId = undefined + this.fromToken = undefined } private request(method: string, args: any[] = []): PromiseLike { - return this.client.request(method, args); + return this.client.request(method, args) } call = (method: string, args: any[] = []): PromiseLike => { - return this.request(method, [this.sessionId, ...args]); - }; + return this.request(method, [this.sessionId, ...args]) + } async getResource( pathname: string, - { - abortSignal, - host, - query, - }: { abortSignal?: AbortSignal; host: XenApiHost; query: any } + { abortSignal, host, query }: { abortSignal?: AbortSignal; host: XenApiHost; query: any } ) { - const url = new URL("http://localhost"); - url.protocol = window.location.protocol; - url.hostname = host.address; - url.pathname = pathname; + const url = new URL('http://localhost') + url.protocol = window.location.protocol + url.hostname = host.address + url.pathname = pathname url.search = new URLSearchParams({ ...query, session_id: this.sessionId, - }).toString(); + }).toString() - return fetch(url, { signal: abortSignal }); + return fetch(url, { signal: abortSignal }) } - async loadRecords< - Type extends ObjectType, - XRecord extends ObjectTypeToRecord, - >(type: Type): Promise { - this.emitEvent(`${type}.beforeLoad`); + async loadRecords>(type: Type): Promise { + this.emitEvent(`${type}.beforeLoad`) try { - const result = await this.call< - Record> - >(`${typeToRawType(type)}.get_all_records`); + const result = await this.call>>( + `${typeToRawType(type)}.get_all_records` + ) const records = Object.entries(result).map(([opaqueRef, record]) => buildXoObject(record as RawXenApiRecord, { - opaqueRef: opaqueRef as XRecord["$ref"], + opaqueRef: opaqueRef as XRecord['$ref'], }) - ); + ) - this.emitEvent(`${type}.afterLoad`, records); + this.emitEvent(`${type}.afterLoad`, records) - return records; + return records } catch (e) { - this.emitEvent(`${type}.loadError`, e); - return []; + this.emitEvent(`${type}.loadError`, e) + return [] } } - addEventListener< - Type extends ObjectType, - XRecord extends ObjectTypeToRecord, - >( + addEventListener>( event: XenApiRecordAfterLoadEvent, callback: (records: XRecord[]) => void - ): void; + ): void - addEventListener( - event: XenApiRecordBeforeLoadEvent, - callback: () => void - ): void; + addEventListener(event: XenApiRecordBeforeLoadEvent, callback: () => void): void addEventListener( event: XenApiRecordLoadErrorEvent, callback: (error: Error) => void - ): void; + ): void - addEventListener< - Type extends ObjectType, - XRecord extends ObjectTypeToRecord, - >( + addEventListener>( event: XenApiRecordAddEvent | XenApiRecordModEvent, callback: (record: XRecord) => void - ): void; + ): void - addEventListener< - Type extends ObjectType, - XRecord extends ObjectTypeToRecord, - >( + addEventListener>( event: XenApiRecordDelEvent, - callback: (opaqueRef: XRecord["$ref"]) => void - ): void; + callback: (opaqueRef: XRecord['$ref']) => void + ): void - addEventListener( - event: XenApiRecordEvent, - callback: (...args: any[]) => void - ) { + addEventListener(event: XenApiRecordEvent, callback: (...args: any[]) => void) { if (!this.events.has(event)) { - this.events.set(event, new Set()); + this.events.set(event, new Set()) } - this.events.get(event)!.add(callback); + this.events.get(event)!.add(callback) } - removeEventListener( - event: XenApiRecordBeforeLoadEvent, - callback: () => void - ): void; + removeEventListener(event: XenApiRecordBeforeLoadEvent, callback: () => void): void removeEventListener( event: XenApiRecordLoadErrorEvent, callback: (error: Error) => void - ): void; + ): void - removeEventListener< - Type extends ObjectType, - XRecord extends ObjectTypeToRecord, - >( + removeEventListener>( event: XenApiRecordAfterLoadEvent, callback: (records: XRecord[]) => void - ): void; + ): void - removeEventListener< - Type extends ObjectType, - XRecord extends ObjectTypeToRecord, - >( + removeEventListener>( event: XenApiRecordAddEvent | XenApiRecordModEvent, callback: (record: XRecord) => void - ): void; + ): void - removeEventListener< - Type extends ObjectType, - XRecord extends ObjectTypeToRecord, - >( + removeEventListener>( event: XenApiRecordDelEvent, - callback: (opaqueRef: XRecord["$ref"]) => void - ): void; + callback: (opaqueRef: XRecord['$ref']) => void + ): void - removeEventListener( - event: XenApiRecordEvent, - callback: (value: any) => void - ) { - this.events.get(event)?.delete(callback); + removeEventListener(event: XenApiRecordEvent, callback: (value: any) => void) { + this.events.get(event)?.delete(callback) } get listenedTypes() { - const keys = new Set(); + const keys = new Set() for (const event of this.events.keys()) { - keys.add(event.split(".")[0] as ObjectType); + keys.add(event.split('.')[0] as ObjectType) } - return Array.from(keys); + return Array.from(keys) } - private emitEvent( - event: XenApiRecordEvent, - ...args: any[] - ) { - const callbacks = this.events.get(event); + private emitEvent(event: XenApiRecordEvent, ...args: any[]) { + const callbacks = this.events.get(event) if (callbacks !== undefined) { - callbacks.forEach((callback) => { - callback(...args); - }); + callbacks.forEach(callback => { + // eslint-disable-next-line n/no-callback-literal + callback(...args) + }) } } private handleEvents(events: XenApiEvent>[]) { events.forEach(({ class: cls, operation, ref, snapshot }) => { - const eventName = `${cls}.${operation}` as XenApiRecordEvent; + const eventName = `${cls}.${operation}` as XenApiRecordEvent - if (operation === "add" || operation === "mod") { - this.emitEvent(eventName, buildXoObject(snapshot, { opaqueRef: ref })); - return; + if (operation === 'add' || operation === 'mod') { + this.emitEvent(eventName, buildXoObject(snapshot, { opaqueRef: ref })) + return } - if (operation === "del") { - this.emitEvent(eventName, ref); - return; + if (operation === 'del') { + this.emitEvent(eventName, ref) } - }); + }) } - async startWatching(poolRef: XenApiPool["$ref"]) { - this.fromToken = await this.call("event.inject", ["pool", poolRef]); - return this.watch(); + async startWatching(poolRef: XenApiPool['$ref']) { + this.fromToken = await this.call('event.inject', ['pool', poolRef]) + return this.watch() } - private async watch() { + private async watch(): Promise { if (this.fromToken === undefined || this.sessionId === undefined) { - return; + return } - await new Promise((resolve) => setTimeout(resolve, 2000)); + await new Promise(resolve => setTimeout(resolve, 2000)) if (this.listenedTypes.length === 0) { - void this.watch(); - return; + return this.watch() } const result: { - token: string; - events: XenApiEvent>[]; - } = await this.call("event.from", [ - this.listenedTypes, - this.fromToken, - 5.001, - ]); + token: string + events: XenApiEvent>[] + } = await this.call('event.from', [this.listenedTypes, this.fromToken, 5.001]) - this.fromToken = result.token; + this.fromToken = result.token - this.handleEvents(result.events); + this.handleEvents(result.events) - void this.watch(); + return this.watch() } get vm() { - type VmRefs = XenApiVm["$ref"] | XenApiVm["$ref"][]; - type VmRefsWithPowerState = Record< - XenApiVm["$ref"], - XenApiVm["power_state"] - >; - type VmRefsWithNameLabel = Record; + type VmRefs = XenApiVm['$ref'] | XenApiVm['$ref'][] + type VmRefsWithPowerState = Record + type VmRefsWithNameLabel = Record return { - delete: (vmRefs: VmRefs) => - Promise.all( - castArray(vmRefs).map((vmRef) => this.call("VM.destroy", [vmRef])) - ), + delete: (vmRefs: VmRefs) => Promise.all(castArray(vmRefs).map(vmRef => this.call('VM.destroy', [vmRef]))), start: (vmRefs: VmRefs) => - Promise.all( - castArray(vmRefs).map((vmRef) => - this.call("VM.start", [vmRef, false, false]) - ) - ), - startOn: (vmRefs: VmRefs, hostRef: XenApiHost["$ref"]) => - Promise.all( - castArray(vmRefs).map((vmRef) => - this.call("VM.start_on", [vmRef, hostRef, false, false]) - ) - ), - pause: (vmRefs: VmRefs) => - Promise.all( - castArray(vmRefs).map((vmRef) => this.call("VM.pause", [vmRef])) - ), + Promise.all(castArray(vmRefs).map(vmRef => this.call('VM.start', [vmRef, false, false]))), + startOn: (vmRefs: VmRefs, hostRef: XenApiHost['$ref']) => + Promise.all(castArray(vmRefs).map(vmRef => this.call('VM.start_on', [vmRef, hostRef, false, false]))), + pause: (vmRefs: VmRefs) => Promise.all(castArray(vmRefs).map(vmRef => this.call('VM.pause', [vmRef]))), suspend: (vmRefs: VmRefs) => { - return Promise.all( - castArray(vmRefs).map((vmRef) => this.call("VM.suspend", [vmRef])) - ); + return Promise.all(castArray(vmRefs).map(vmRef => this.call('VM.suspend', [vmRef]))) }, resume: (vmRefsWithPowerState: VmRefsWithPowerState) => { - const vmRefs = Object.keys(vmRefsWithPowerState) as XenApiVm["$ref"][]; + const vmRefs = Object.keys(vmRefsWithPowerState) as XenApiVm['$ref'][] return Promise.all( - vmRefs.map((vmRef) => { - if (vmRefsWithPowerState[vmRef] === "Suspended") { - return this.call("VM.resume", [vmRef, false, false]); + vmRefs.map(vmRef => { + if (vmRefsWithPowerState[vmRef] === 'Suspended') { + return this.call('VM.resume', [vmRef, false, false]) } - return this.call("VM.unpause", [vmRef]); + return this.call('VM.unpause', [vmRef]) }) - ); + ) }, reboot: (vmRefs: VmRefs, force = false) => { - return Promise.all( - castArray(vmRefs).map((vmRef) => - this.call(`VM.${force ? "hard" : "clean"}_reboot`, [vmRef]) - ) - ); + return Promise.all(castArray(vmRefs).map(vmRef => this.call(`VM.${force ? 'hard' : 'clean'}_reboot`, [vmRef]))) }, shutdown: (vmRefs: VmRefs, force = false) => { return Promise.all( - castArray(vmRefs).map((vmRef) => - this.call(`VM.${force ? "hard" : "clean"}_shutdown`, [vmRef]) - ) - ); + castArray(vmRefs).map(vmRef => this.call(`VM.${force ? 'hard' : 'clean'}_shutdown`, [vmRef])) + ) }, clone: (vmRefsToClone: VmRefsWithNameLabel) => { - const vmRefs = Object.keys(vmRefsToClone) as XenApiVm["$ref"][]; + const vmRefs = Object.keys(vmRefsToClone) as XenApiVm['$ref'][] - return Promise.all( - vmRefs.map((vmRef) => - this.call("VM.clone", [vmRef, vmRefsToClone[vmRef]]) - ) - ); + return Promise.all(vmRefs.map(vmRef => this.call('VM.clone', [vmRef, vmRefsToClone[vmRef]]))) }, - migrate: (vmRefs: VmRefs, destinationHostRef: XenApiHost["$ref"]) => { + migrate: (vmRefs: VmRefs, destinationHostRef: XenApiHost['$ref']) => { return Promise.all( - castArray(vmRefs).map((vmRef) => - this.call("VM.pool_migrate", [ - vmRef, - destinationHostRef, - { force: "false" }, - ]) - ) - ); + castArray(vmRefs).map(vmRef => this.call('VM.pool_migrate', [vmRef, destinationHostRef, { force: 'false' }])) + ) }, snapshot: (vmRefsToSnapshot: VmRefsWithNameLabel) => { - const vmRefs = Object.keys(vmRefsToSnapshot) as XenApiVm["$ref"][]; + const vmRefs = Object.keys(vmRefsToSnapshot) as XenApiVm['$ref'][] - return Promise.all( - vmRefs.map((vmRef) => - this.call("VM.snapshot", [vmRef, vmRefsToSnapshot[vmRef]]) - ) - ); + return Promise.all(vmRefs.map(vmRef => this.call('VM.snapshot', [vmRef, vmRefsToSnapshot[vmRef]]))) }, export: (vmRefs: VmRefs, compression: VM_COMPRESSION_TYPE) => { - const blockedUrls: URL[] = []; + const blockedUrls: URL[] = [] - castArray(vmRefs).forEach((vmRef) => { - const url = new URL(this.hostUrl); - url.pathname = "/export/"; + castArray(vmRefs).forEach(vmRef => { + const url = new URL(this.hostUrl) + url.pathname = '/export/' url.search = new URLSearchParams({ session_id: this.sessionId!, ref: vmRef, use_compression: compression, - }).toString(); + }).toString() - const _window = window.open(url.href, "_blank"); + const _window = window.open(url.href, '_blank') if (_window === null) { - blockedUrls.push(url); + blockedUrls.push(url) } else { - URL.revokeObjectURL(url.toString()); + URL.revokeObjectURL(url.toString()) } - }); + }) if (blockedUrls.length > 0) { - const { onClose } = useModal( - () => import("@/components/modals/VmExportBlockedUrlsModal.vue"), - { blockedUrls } - ); - onClose(() => - blockedUrls.forEach((url) => URL.revokeObjectURL(url.toString())) - ); + const { onClose } = useModal(() => import('@/components/modals/VmExportBlockedUrlsModal.vue'), { + blockedUrls, + }) + onClose(() => blockedUrls.forEach(url => URL.revokeObjectURL(url.toString()))) } }, - }; + } } } diff --git a/@xen-orchestra/lite/src/libs/xen-api/xen-api.types.ts b/@xen-orchestra/lite/src/libs/xen-api/xen-api.types.ts index 66afcbc11aa..22075e4fe59 100644 --- a/@xen-orchestra/lite/src/libs/xen-api/xen-api.types.ts +++ b/@xen-orchestra/lite/src/libs/xen-api/xen-api.types.ts @@ -1,3 +1,5 @@ +/* eslint-disable no-use-before-define */ + import type { ALLOCATION_ALGORITHM, BOND_MODE, @@ -39,600 +41,591 @@ import type { VMSS_TYPE, VTPM_OPERATION, VUSB_OPERATION, -} from "@/libs/xen-api/xen-api.enums"; -import type { XEN_API_OBJECT_TYPES } from "@/libs/xen-api/xen-api.utils"; +} from '@/libs/xen-api/xen-api.enums' +import type { XEN_API_OBJECT_TYPES } from '@/libs/xen-api/xen-api.utils' -type TypeMapping = typeof XEN_API_OBJECT_TYPES; -export type ObjectType = keyof TypeMapping; -export type RawObjectType = TypeMapping[ObjectType]; +type TypeMapping = typeof XEN_API_OBJECT_TYPES +export type ObjectType = keyof TypeMapping +export type RawObjectType = TypeMapping[ObjectType] -export type RawTypeToType = Lowercase; -export type TypeToRawType = TypeMapping[Type]; +export type RawTypeToType = Lowercase +export type TypeToRawType = TypeMapping[Type] type ObjectTypeToRecordMapping = { - console: XenApiConsole; - host: XenApiHost; - host_metrics: XenApiHostMetrics; - message: XenApiMessage; - network: XenApiNetwork; - pool: XenApiPool; - sr: XenApiSr; - vm: XenApiVm; - vm_guest_metrics: XenApiVmGuestMetrics; - vm_metrics: XenApiVmMetrics; -}; - -export type ObjectTypeToRecord = - Type extends keyof ObjectTypeToRecordMapping - ? ObjectTypeToRecordMapping[Type] - : never; - -export type XenApiRecordBeforeLoadEvent = - `${Type}.beforeLoad`; -export type XenApiRecordAfterLoadEvent = - `${Type}.afterLoad`; -export type XenApiRecordLoadErrorEvent = - `${Type}.loadError`; -export type XenApiRecordAddEvent = `${Type}.add`; -export type XenApiRecordModEvent = `${Type}.mod`; -export type XenApiRecordDelEvent = `${Type}.del`; + console: XenApiConsole + host: XenApiHost + host_metrics: XenApiHostMetrics + message: XenApiMessage + network: XenApiNetwork + pool: XenApiPool + sr: XenApiSr + vm: XenApiVm + vm_guest_metrics: XenApiVmGuestMetrics + vm_metrics: XenApiVmMetrics +} + +export type ObjectTypeToRecord = Type extends keyof ObjectTypeToRecordMapping + ? ObjectTypeToRecordMapping[Type] + : never + +export type XenApiRecordBeforeLoadEvent = `${Type}.beforeLoad` +export type XenApiRecordAfterLoadEvent = `${Type}.afterLoad` +export type XenApiRecordLoadErrorEvent = `${Type}.loadError` +export type XenApiRecordAddEvent = `${Type}.add` +export type XenApiRecordModEvent = `${Type}.mod` +export type XenApiRecordDelEvent = `${Type}.del` export type XenApiRecordEvent = | XenApiRecordBeforeLoadEvent | XenApiRecordAfterLoadEvent | XenApiRecordLoadErrorEvent | XenApiRecordAddEvent | XenApiRecordModEvent - | XenApiRecordDelEvent; + | XenApiRecordDelEvent -declare const __brand: unique symbol; +declare const __brand: unique symbol export interface XenApiRecord { - $ref: string & { [__brand]: `${Type}Ref` }; - uuid: string & { [__brand]: `${Type}Uuid` }; + $ref: string & { [__brand]: `${Type}Ref` } + uuid: string & { [__brand]: `${Type}Uuid` } } -export type RawXenApiRecord> = Omit< - T, - "$ref" ->; +export type RawXenApiRecord> = Omit -export interface XenApiPool extends XenApiRecord<"pool"> { +export interface XenApiPool extends XenApiRecord<'pool'> { cpu_info: { - cpu_count: string; - }; - master: XenApiHost["$ref"]; - name_label: string; -} - -export interface XenApiHost extends XenApiRecord<"host"> { - address: string; - name_label: string; - metrics: XenApiHostMetrics["$ref"]; - resident_VMs: XenApiVm["$ref"][]; - cpu_info: { cpu_count: string }; - software_version: { product_version: string }; -} - -export interface XenApiSr extends XenApiRecord<"sr"> { - content_type: string; - name_label: string; - physical_size: number; - physical_utilisation: number; - shared: boolean; -} - -export interface XenApiVm extends XenApiRecord<"vm"> { - HVM_boot_params: Record; - HVM_boot_policy: string; - HVM_shadow_multiplier: number; - NVRAM: Record; - PCI_bus: string; - PV_args: string; - PV_bootloader: string; - PV_bootloader_args: string; - PV_kernel: string; - PV_legacy_args: string; - PV_ramdisk: string; - VBDs: XenApiVbd["$ref"][]; - VCPUs_at_startup: number; - VCPUs_max: number; - VCPUs_params: Record; - VGPUs: XenApiVgpu["$ref"][]; - VIFs: XenApiVif["$ref"][]; - VTPMs: XenApiVtpm["$ref"][]; - VUSBs: XenApiVusb["$ref"][]; - actions_after_crash: ON_CRASH_BEHAVIOUR; - actions_after_reboot: ON_NORMAL_EXIT; - actions_after_shutdown: ON_NORMAL_EXIT; - actions_after_softreboot: ON_SOFTREBOOT_BEHAVIOR; - affinity: XenApiHost["$ref"]; - allowed_operations: VM_OPERATION[]; - appliance: XenApiVmAppliance["$ref"]; - attached_PCIs: XenApiPci["$ref"][]; - bios_strings: Record; - blobs: Record; - blocked_operations: Record; - children: XenApiVm["$ref"][]; - consoles: XenApiConsole["$ref"][]; - crash_dumps: XenApiCrashdump["$ref"][]; - current_operations: Record; - domain_type: DOMAIN_TYPE; - domarch: string; - domid: number; - generation_id: string; - guest_metrics: XenApiVmGuestMetrics["$ref"]; - ha_always_run: boolean; - ha_restart_priority: string; - hardware_platform_version: number; - has_vendor_device: boolean; - is_a_snapshot: boolean; - is_a_template: boolean; - is_control_domain: boolean; - is_default_template: boolean; - is_snapshot_from_vmpp: boolean; - is_vmss_snapshot: boolean; - last_boot_CPU_flags: Record; - last_booted_record: string; - memory_dynamic_max: number; - memory_dynamic_min: number; - memory_overhead: number; - memory_static_max: number; - memory_static_min: number; - memory_target: number; - metrics: XenApiVmMetrics["$ref"]; - name_description: string; - name_label: string; - order: number; - other_config: Record; - parent: XenApiVm["$ref"]; - pending_guidances: UPDATE_GUIDANCE[]; - platform: Record; - power_state: VM_POWER_STATE; - protection_policy: XenApiVmpp["$ref"]; - recommendations: string; - reference_label: string; - requires_reboot: boolean; - resident_on: XenApiHost["$ref"]; - scheduled_to_be_resident_on: XenApiHost["$ref"]; - shutdown_delay: number; - snapshot_info: Record; - snapshot_metadata: string; - snapshot_of: XenApiVm["$ref"]; - snapshot_schedule: XenApiVmss["$ref"]; - snapshot_time: string; - snapshots: XenApiVm["$ref"][]; - start_delay: number; - suspend_SR: XenApiSr["$ref"]; - suspend_VDI: XenApiVdi["$ref"]; - tags: string[]; - transportable_snapshot_id: string; - user_version: number; - version: number; - xenstore_data: Record; -} - -export interface XenApiVtpm extends XenApiRecord<"vtpm"> { - VM: XenApiVm["$ref"]; - allowed_operations: VTPM_OPERATION[]; - backend: XenApiVm["$ref"]; - current_operations: Record; - is_protected: boolean; - is_unique: boolean; - persistence_backend: PERSISTENCE_BACKEND; -} - -export interface XenApiVusb extends XenApiRecord<"vusb"> { - USB_group: XenApiUsbGroup["$ref"]; - VM: XenApiVm["$ref"]; - allowed_operations: VUSB_OPERATION[]; - current_operations: Record; - currently_attached: boolean; - other_config: Record; -} - -export interface XenApiUsbGroup extends XenApiRecord<"usb_group"> { - PUSBs: XenApiPusb["$ref"][]; - VUSBs: XenApiVusb["$ref"][]; - name_description: string; - name_label: string; - other_config: Record; -} - -export interface XenApiPusb extends XenApiRecord<"pusb"> { - USB_group: XenApiUsbGroup["$ref"]; - description: string; - host: XenApiHost["$ref"]; - other_config: Record; - passthrough_enabled: boolean; - path: string; - product_desc: string; - product_id: string; - serial: string; - speed: number; - vendor_desc: string; - vendor_id: string; - version: string; -} - -export interface XenApiVgpu extends XenApiRecord<"vgpu"> { - GPU_group: XenApiGpuGroup["$ref"]; - PCI: XenApiPci["$ref"]; - VM: XenApiVm["$ref"]; - compatibility_metadata: Record; - currently_attached: boolean; - device: string; - extra_args: string; - other_config: Record; - resident_on: XenApiPgpu["$ref"]; - scheduled_to_be_resident_on: XenApiPgpu["$ref"]; - type: XenApiVgpuType["$ref"]; -} - -export interface XenApiGpuGroup extends XenApiRecord<"gpu_group"> { - GPU_types: string[]; - PGPUs: XenApiPgpu["$ref"][]; - VGPUs: XenApiVgpu["$ref"][]; - allocation_algorithm: ALLOCATION_ALGORITHM; - enabled_VGPU_types: XenApiVgpuType["$ref"][]; - name_description: string; - name_label: string; - other_config: Record; - supported_VGPU_types: XenApiVgpuType["$ref"][]; -} - -export interface XenApiPgpu extends XenApiRecord<"pgpu"> { - GPU_group: XenApiGpuGroup["$ref"]; - PCI: XenApiPci["$ref"]; - compatibility_metadata: Record; - dom0_access: PGPU_DOM0_ACCESS; - enabled_VGPU_types: XenApiVgpuType["$ref"][]; - host: XenApiHost["$ref"]; - is_system_display_device: boolean; - other_config: Record; - resident_VGPUs: XenApiVgpu["$ref"][]; - supported_VGPU_max_capacities: Record; - supported_VGPU_types: XenApiVgpuType["$ref"][]; -} - -export interface XenApiVgpuType extends XenApiRecord<"vgpu_type"> { - VGPUs: XenApiVgpu["$ref"][]; - compatible_types_in_vm: XenApiVgpuType["$ref"][]; - enabled_on_GPU_groups: XenApiGpuGroup["$ref"][]; - enabled_on_PGPUs: XenApiPgpu["$ref"][]; - experimental: boolean; - framebuffer_size: number; - identifier: string; - implementation: VGPU_TYPE_IMPLEMENTATION; - max_heads: number; - max_resolution_x: number; - max_resolution_y: number; - model_name: string; - supported_on_GPU_groups: XenApiGpuGroup["$ref"][]; - supported_on_PGPUs: XenApiPgpu["$ref"][]; - vendor_name: string; -} - -export interface XenApiVmAppliance extends XenApiRecord<"vm_appliance"> { - VMs: XenApiVm["$ref"][]; - allowed_operations: VM_APPLIANCE_OPERATION[]; - current_operations: Record; - name_description: string; - name_label: string; -} - -export interface XenApiVmpp extends XenApiRecord<"vmpp"> { - VMs: XenApiVm["$ref"][]; - alarm_config: Record; - archive_frequency: VMPP_ARCHIVE_FREQUENCY; - archive_last_run_time: string; - archive_schedule: Record; - archive_target_config: Record; - archive_target_type: VMPP_ARCHIVE_TARGET_TYPE; - backup_frequency: VMPP_BACKUP_FREQUENCY; - backup_last_run_time: string; - backup_retention_value: number; - backup_schedule: Record; - backup_type: VMPP_BACKUP_TYPE; - is_alarm_enabled: boolean; - is_archive_running: boolean; - is_backup_running: boolean; - is_policy_enabled: boolean; - name_description: string; - name_label: string; - recent_alerts: string[]; -} - -export interface XenApiVmss extends XenApiRecord<"vmss"> { - VMs: XenApiVm["$ref"][]; - enabled: boolean; - frequency: VMSS_FREQUENCY; - last_run_time: string; - name_description: string; - name_label: string; - retained_snapshots: number; - schedule: Record; - type: VMSS_TYPE; -} - -export interface XenApiConsole extends XenApiRecord<"console"> { - protocol: string; - location: string; -} - -export interface XenApiHostMetrics extends XenApiRecord<"host_metrics"> { - live: boolean; - memory_free: number; - memory_total: number; -} - -export interface XenApiVmMetrics extends XenApiRecord<"vm_metrics"> { - VCPUs_number: number; -} - -export type XenApiVmGuestMetrics = XenApiRecord<"vm_guest_metrics">; - -export interface XenApiTask extends XenApiRecord<"task"> { - name_label: string; - resident_on: XenApiHost["$ref"]; - created: string; - finished: string; - status: string; - progress: number; -} - -export interface XenApiMessage - extends XenApiRecord<"message"> { - body: string; - cls: RelationType; - name: string; - obj_uuid: ObjectTypeToRecord>["uuid"]; - priority: number; - timestamp: string; -} - -export interface XenApiVbd extends XenApiRecord<"vbd"> { - VDI: XenApiVdi["$ref"]; - VM: XenApiVm["$ref"]; - allowed_operations: VBD_OPERATION[]; - bootable: boolean; - current_operations: Record; - currently_attached: boolean; - device: string; - empty: boolean; - metrics: XenApiVbdMetrics["$ref"]; - mode: VBD_MODE; - other_config: Record; - qos_algorithm_params: Record; - qos_algorithm_type: string; - qos_supported_algorithms: string[]; - runtime_properties: Record; - status_code: number; - status_detail: string; - storage_lock: boolean; - type: VBD_TYPE; - unpluggable: boolean; - userdevice: string; -} - -export interface XenApiVbdMetrics extends XenApiRecord<"vbd_metrics"> { - io_read_kbs: number; - io_write_kbs: number; - last_updated: string; - other_config: Record; -} - -export interface XenApiVdi extends XenApiRecord<"vdi"> { - SR: XenApiSr["$ref"]; - VBDs: XenApiVbd["$ref"][]; - allow_caching: boolean; - allowed_operations: VDI_OPERATION[]; - cbt_enabled: boolean; - crash_dumps: XenApiCrashdump["$ref"][]; - current_operations: Record; - is_a_snapshot: boolean; - is_tools_iso: boolean; - location: string; - managed: boolean; - metadata_latest: boolean; - metadata_of_pool: XenApiPool["$ref"]; - missing: boolean; - name_description: string; - name_label: string; - on_boot: ON_BOOT; - other_config: Record; - parent: XenApiVdi["$ref"]; - physical_utilisation: number; - read_only: boolean; - sharable: boolean; - sm_config: Record; - snapshot_of: XenApiVdi["$ref"]; - snapshot_time: string; - snapshots: XenApiVdi["$ref"][]; - storage_lock: boolean; - tags: string[]; - type: VDI_TYPE; - virtual_size: number; - xenstore_data: Record; -} - -export interface XenApiCrashdump extends XenApiRecord<"crashdump"> { - VDI: XenApiVdi["$ref"]; - VM: XenApiVm["$ref"]; - other_config: Record; -} - -export interface XenApiNetwork extends XenApiRecord<"network"> { - MTU: number; - PIFs: XenApiPif["$ref"][]; - VIFs: XenApiVif["$ref"][]; - allowed_operations: NETWORK_OPERATION[]; - assigned_ips: Record; - blobs: Record; - bridge: string; - current_operations: Record; - default_locking_mode: NETWORK_DEFAULT_LOCKING_MODE; - managed: boolean; - name_description: string; - name_label: string; - other_config: Record; - purpose: NETWORK_PURPOSE[]; - tags: string[]; -} - -export interface XenApiBlob extends XenApiRecord<"blob"> { - last_updated: string; - mime_type: string; - name_description: string; - name_label: string; - public: boolean; - size: number; -} - -export interface XenApiVif extends XenApiRecord<"vif"> { - MAC: string; - MAC_autogenerated: boolean; - MTU: number; - VM: XenApiVm["$ref"]; - allowed_operations: VIF_OPERATION[]; - current_operations: Record; - currently_attached: boolean; - device: string; - ipv4_addresses: string[]; - ipv4_allowed: string[]; - ipv4_configuration_mode: VIF_IPV4_CONFIGURATION_MODE; - ipv4_gateway: string; - ipv6_addresses: string[]; - ipv6_allowed: string[]; - ipv6_configuration_mode: VIF_IPV6_CONFIGURATION_MODE; - ipv6_gateway: string; - locking_mode: VIF_LOCKING_MODE; - metrics: XenApiVifMetrics["$ref"]; - network: XenApiNetwork["$ref"]; - other_config: Record; - qos_algorithm_params: Record; - qos_algorithm_type: string; - qos_supported_algorithms: string[]; - runtime_properties: Record; - status_code: number; - status_detail: string; -} - -export interface XenApiVifMetrics extends XenApiRecord<"vif_metrics"> { - io_read_kbs: number; - io_write_kbs: number; - last_updated: string; - other_config: Record; -} - -export interface XenApiPif extends XenApiRecord<"pif"> { - DNS: string; - IP: string; - IPv6: string[]; - MAC: string; - MTU: number; - PCI: XenApiPci["$ref"]; - VLAN: number; - VLAN_master_of: XenApiVlan["$ref"]; - VLAN_slave_of: XenApiVlan["$ref"][]; - bond_master_of: XenApiBond["$ref"][]; - bond_slave_of: XenApiBond["$ref"]; - capabilities: string[]; - currently_attached: boolean; - device: string; - disallow_unplug: boolean; - gateway: string; - host: XenApiHost["$ref"]; - igmp_snooping_status: PIF_IGMP_STATUS; - ip_configuration_mode: IP_CONFIGURATION_MODE; - ipv6_configuration_mode: IPV6_CONFIGURATION_MODE; - ipv6_gateway: string; - managed: boolean; - management: boolean; - metrics: XenApiPifMetrics["$ref"]; - netmask: string; - network: XenApiNetwork["$ref"]; - other_config: Record; - physical: boolean; - primary_address_type: PRIMARY_ADDRESS_TYPE; - properties: Record; - sriov_logical_PIF_of: XenApiNetworkSriov["$ref"][]; - sriov_physical_PIF_of: XenApiNetworkSriov["$ref"][]; - tunnel_access_PIF_of: XenApiTunnel["$ref"][]; - tunnel_transport_PIF_of: XenApiTunnel["$ref"][]; -} - -export interface XenApiNetworkSriov extends XenApiRecord<"network_sriov"> { - configuration_mode: SRIOV_CONFIGURATION_MODE; - logical_PIF: XenApiPif["$ref"]; - physical_PIF: XenApiPif["$ref"]; - requires_reboot: boolean; -} - -export interface XenApiVlan extends XenApiRecord<"vlan"> { - other_config: Record; - tag: number; - tagged_PIF: XenApiPif["$ref"]; - untagged_PIF: XenApiPif["$ref"]; -} - -export interface XenApiTunnel extends XenApiRecord<"tunnel"> { - access_PIF: XenApiPif["$ref"]; - other_config: Record; - protocol: TUNNEL_PROTOCOL; - status: Record; - transport_PIF: XenApiPif["$ref"]; -} - -export interface XenApiPci extends XenApiRecord<"pci"> { - class_name: string; - dependencies: XenApiPci["$ref"][]; - device_name: string; - driver_name: string; - host: XenApiHost["$ref"]; - other_config: Record; - pci_id: string; - subsystem_device_name: string; - subsystem_vendor_name: string; - vendor_name: string; -} - -export interface XenApiPifMetrics extends XenApiRecord<"pif_metrics"> { - carrier: boolean; - device_id: string; - device_name: string; - duplex: boolean; - io_read_kbs: number; - io_write_kbs: number; - last_updated: string; - other_config: Record; - pci_bus_path: string; - speed: number; - vendor_id: string; - vendor_name: string; -} - -export interface XenApiBond extends XenApiRecord<"bond"> { - auto_update_mac: boolean; - links_up: number; - master: XenApiPif["$ref"]; - mode: BOND_MODE; - other_config: Record; - primary_slave: XenApiPif["$ref"]; - properties: Record; - slaves: XenApiPif["$ref"][]; -} - -export type XenApiEvent< - RelationType extends ObjectType, - XRecord extends ObjectTypeToRecord, -> = { - id: string; - class: RelationType; - operation: "add" | "mod" | "del"; - ref: XRecord["$ref"]; - snapshot: RawXenApiRecord; -}; + cpu_count: string + } + master: XenApiHost['$ref'] + name_label: string +} + +export interface XenApiHost extends XenApiRecord<'host'> { + address: string + name_label: string + metrics: XenApiHostMetrics['$ref'] + resident_VMs: XenApiVm['$ref'][] + cpu_info: { cpu_count: string } + software_version: { product_version: string } +} + +export interface XenApiSr extends XenApiRecord<'sr'> { + content_type: string + name_label: string + physical_size: number + physical_utilisation: number + shared: boolean +} + +export interface XenApiVm extends XenApiRecord<'vm'> { + HVM_boot_params: Record + HVM_boot_policy: string + HVM_shadow_multiplier: number + NVRAM: Record + PCI_bus: string + PV_args: string + PV_bootloader: string + PV_bootloader_args: string + PV_kernel: string + PV_legacy_args: string + PV_ramdisk: string + VBDs: XenApiVbd['$ref'][] + VCPUs_at_startup: number + VCPUs_max: number + VCPUs_params: Record + VGPUs: XenApiVgpu['$ref'][] + VIFs: XenApiVif['$ref'][] + VTPMs: XenApiVtpm['$ref'][] + VUSBs: XenApiVusb['$ref'][] + actions_after_crash: ON_CRASH_BEHAVIOUR + actions_after_reboot: ON_NORMAL_EXIT + actions_after_shutdown: ON_NORMAL_EXIT + actions_after_softreboot: ON_SOFTREBOOT_BEHAVIOR + affinity: XenApiHost['$ref'] + allowed_operations: VM_OPERATION[] + appliance: XenApiVmAppliance['$ref'] + attached_PCIs: XenApiPci['$ref'][] + bios_strings: Record + blobs: Record + blocked_operations: Record + children: XenApiVm['$ref'][] + consoles: XenApiConsole['$ref'][] + crash_dumps: XenApiCrashdump['$ref'][] + current_operations: Record + domain_type: DOMAIN_TYPE + domarch: string + domid: number + generation_id: string + guest_metrics: XenApiVmGuestMetrics['$ref'] + ha_always_run: boolean + ha_restart_priority: string + hardware_platform_version: number + has_vendor_device: boolean + is_a_snapshot: boolean + is_a_template: boolean + is_control_domain: boolean + is_default_template: boolean + is_snapshot_from_vmpp: boolean + is_vmss_snapshot: boolean + last_boot_CPU_flags: Record + last_booted_record: string + memory_dynamic_max: number + memory_dynamic_min: number + memory_overhead: number + memory_static_max: number + memory_static_min: number + memory_target: number + metrics: XenApiVmMetrics['$ref'] + name_description: string + name_label: string + order: number + other_config: Record + parent: XenApiVm['$ref'] + pending_guidances: UPDATE_GUIDANCE[] + platform: Record + power_state: VM_POWER_STATE + protection_policy: XenApiVmpp['$ref'] + recommendations: string + reference_label: string + requires_reboot: boolean + resident_on: XenApiHost['$ref'] + scheduled_to_be_resident_on: XenApiHost['$ref'] + shutdown_delay: number + snapshot_info: Record + snapshot_metadata: string + snapshot_of: XenApiVm['$ref'] + snapshot_schedule: XenApiVmss['$ref'] + snapshot_time: string + snapshots: XenApiVm['$ref'][] + start_delay: number + suspend_SR: XenApiSr['$ref'] + suspend_VDI: XenApiVdi['$ref'] + tags: string[] + transportable_snapshot_id: string + user_version: number + version: number + xenstore_data: Record +} + +export interface XenApiVtpm extends XenApiRecord<'vtpm'> { + VM: XenApiVm['$ref'] + allowed_operations: VTPM_OPERATION[] + backend: XenApiVm['$ref'] + current_operations: Record + is_protected: boolean + is_unique: boolean + persistence_backend: PERSISTENCE_BACKEND +} + +export interface XenApiVusb extends XenApiRecord<'vusb'> { + USB_group: XenApiUsbGroup['$ref'] + VM: XenApiVm['$ref'] + allowed_operations: VUSB_OPERATION[] + current_operations: Record + currently_attached: boolean + other_config: Record +} + +export interface XenApiUsbGroup extends XenApiRecord<'usb_group'> { + PUSBs: XenApiPusb['$ref'][] + VUSBs: XenApiVusb['$ref'][] + name_description: string + name_label: string + other_config: Record +} + +export interface XenApiPusb extends XenApiRecord<'pusb'> { + USB_group: XenApiUsbGroup['$ref'] + description: string + host: XenApiHost['$ref'] + other_config: Record + passthrough_enabled: boolean + path: string + product_desc: string + product_id: string + serial: string + speed: number + vendor_desc: string + vendor_id: string + version: string +} + +export interface XenApiVgpu extends XenApiRecord<'vgpu'> { + GPU_group: XenApiGpuGroup['$ref'] + PCI: XenApiPci['$ref'] + VM: XenApiVm['$ref'] + compatibility_metadata: Record + currently_attached: boolean + device: string + extra_args: string + other_config: Record + resident_on: XenApiPgpu['$ref'] + scheduled_to_be_resident_on: XenApiPgpu['$ref'] + type: XenApiVgpuType['$ref'] +} + +export interface XenApiGpuGroup extends XenApiRecord<'gpu_group'> { + GPU_types: string[] + PGPUs: XenApiPgpu['$ref'][] + VGPUs: XenApiVgpu['$ref'][] + allocation_algorithm: ALLOCATION_ALGORITHM + enabled_VGPU_types: XenApiVgpuType['$ref'][] + name_description: string + name_label: string + other_config: Record + supported_VGPU_types: XenApiVgpuType['$ref'][] +} + +export interface XenApiPgpu extends XenApiRecord<'pgpu'> { + GPU_group: XenApiGpuGroup['$ref'] + PCI: XenApiPci['$ref'] + compatibility_metadata: Record + dom0_access: PGPU_DOM0_ACCESS + enabled_VGPU_types: XenApiVgpuType['$ref'][] + host: XenApiHost['$ref'] + is_system_display_device: boolean + other_config: Record + resident_VGPUs: XenApiVgpu['$ref'][] + supported_VGPU_max_capacities: Record + supported_VGPU_types: XenApiVgpuType['$ref'][] +} + +export interface XenApiVgpuType extends XenApiRecord<'vgpu_type'> { + VGPUs: XenApiVgpu['$ref'][] + compatible_types_in_vm: XenApiVgpuType['$ref'][] + enabled_on_GPU_groups: XenApiGpuGroup['$ref'][] + enabled_on_PGPUs: XenApiPgpu['$ref'][] + experimental: boolean + framebuffer_size: number + identifier: string + implementation: VGPU_TYPE_IMPLEMENTATION + max_heads: number + max_resolution_x: number + max_resolution_y: number + model_name: string + supported_on_GPU_groups: XenApiGpuGroup['$ref'][] + supported_on_PGPUs: XenApiPgpu['$ref'][] + vendor_name: string +} + +export interface XenApiVmAppliance extends XenApiRecord<'vm_appliance'> { + VMs: XenApiVm['$ref'][] + allowed_operations: VM_APPLIANCE_OPERATION[] + current_operations: Record + name_description: string + name_label: string +} + +export interface XenApiVmpp extends XenApiRecord<'vmpp'> { + VMs: XenApiVm['$ref'][] + alarm_config: Record + archive_frequency: VMPP_ARCHIVE_FREQUENCY + archive_last_run_time: string + archive_schedule: Record + archive_target_config: Record + archive_target_type: VMPP_ARCHIVE_TARGET_TYPE + backup_frequency: VMPP_BACKUP_FREQUENCY + backup_last_run_time: string + backup_retention_value: number + backup_schedule: Record + backup_type: VMPP_BACKUP_TYPE + is_alarm_enabled: boolean + is_archive_running: boolean + is_backup_running: boolean + is_policy_enabled: boolean + name_description: string + name_label: string + recent_alerts: string[] +} + +export interface XenApiVmss extends XenApiRecord<'vmss'> { + VMs: XenApiVm['$ref'][] + enabled: boolean + frequency: VMSS_FREQUENCY + last_run_time: string + name_description: string + name_label: string + retained_snapshots: number + schedule: Record + type: VMSS_TYPE +} + +export interface XenApiConsole extends XenApiRecord<'console'> { + protocol: string + location: string +} + +export interface XenApiHostMetrics extends XenApiRecord<'host_metrics'> { + live: boolean + memory_free: number + memory_total: number +} + +export interface XenApiVmMetrics extends XenApiRecord<'vm_metrics'> { + VCPUs_number: number +} + +export type XenApiVmGuestMetrics = XenApiRecord<'vm_guest_metrics'> + +export interface XenApiTask extends XenApiRecord<'task'> { + name_label: string + resident_on: XenApiHost['$ref'] + created: string + finished: string + status: string + progress: number +} + +export interface XenApiMessage extends XenApiRecord<'message'> { + body: string + cls: RelationType + name: string + obj_uuid: ObjectTypeToRecord>['uuid'] + priority: number + timestamp: string +} + +export interface XenApiVbd extends XenApiRecord<'vbd'> { + VDI: XenApiVdi['$ref'] + VM: XenApiVm['$ref'] + allowed_operations: VBD_OPERATION[] + bootable: boolean + current_operations: Record + currently_attached: boolean + device: string + empty: boolean + metrics: XenApiVbdMetrics['$ref'] + mode: VBD_MODE + other_config: Record + qos_algorithm_params: Record + qos_algorithm_type: string + qos_supported_algorithms: string[] + runtime_properties: Record + status_code: number + status_detail: string + storage_lock: boolean + type: VBD_TYPE + unpluggable: boolean + userdevice: string +} + +export interface XenApiVbdMetrics extends XenApiRecord<'vbd_metrics'> { + io_read_kbs: number + io_write_kbs: number + last_updated: string + other_config: Record +} + +export interface XenApiVdi extends XenApiRecord<'vdi'> { + SR: XenApiSr['$ref'] + VBDs: XenApiVbd['$ref'][] + allow_caching: boolean + allowed_operations: VDI_OPERATION[] + cbt_enabled: boolean + crash_dumps: XenApiCrashdump['$ref'][] + current_operations: Record + is_a_snapshot: boolean + is_tools_iso: boolean + location: string + managed: boolean + metadata_latest: boolean + metadata_of_pool: XenApiPool['$ref'] + missing: boolean + name_description: string + name_label: string + on_boot: ON_BOOT + other_config: Record + parent: XenApiVdi['$ref'] + physical_utilisation: number + read_only: boolean + sharable: boolean + sm_config: Record + snapshot_of: XenApiVdi['$ref'] + snapshot_time: string + snapshots: XenApiVdi['$ref'][] + storage_lock: boolean + tags: string[] + type: VDI_TYPE + virtual_size: number + xenstore_data: Record +} + +export interface XenApiCrashdump extends XenApiRecord<'crashdump'> { + VDI: XenApiVdi['$ref'] + VM: XenApiVm['$ref'] + other_config: Record +} + +export interface XenApiNetwork extends XenApiRecord<'network'> { + MTU: number + PIFs: XenApiPif['$ref'][] + VIFs: XenApiVif['$ref'][] + allowed_operations: NETWORK_OPERATION[] + assigned_ips: Record + blobs: Record + bridge: string + current_operations: Record + default_locking_mode: NETWORK_DEFAULT_LOCKING_MODE + managed: boolean + name_description: string + name_label: string + other_config: Record + purpose: NETWORK_PURPOSE[] + tags: string[] +} + +export interface XenApiBlob extends XenApiRecord<'blob'> { + last_updated: string + mime_type: string + name_description: string + name_label: string + public: boolean + size: number +} + +export interface XenApiVif extends XenApiRecord<'vif'> { + MAC: string + MAC_autogenerated: boolean + MTU: number + VM: XenApiVm['$ref'] + allowed_operations: VIF_OPERATION[] + current_operations: Record + currently_attached: boolean + device: string + ipv4_addresses: string[] + ipv4_allowed: string[] + ipv4_configuration_mode: VIF_IPV4_CONFIGURATION_MODE + ipv4_gateway: string + ipv6_addresses: string[] + ipv6_allowed: string[] + ipv6_configuration_mode: VIF_IPV6_CONFIGURATION_MODE + ipv6_gateway: string + locking_mode: VIF_LOCKING_MODE + metrics: XenApiVifMetrics['$ref'] + network: XenApiNetwork['$ref'] + other_config: Record + qos_algorithm_params: Record + qos_algorithm_type: string + qos_supported_algorithms: string[] + runtime_properties: Record + status_code: number + status_detail: string +} + +export interface XenApiVifMetrics extends XenApiRecord<'vif_metrics'> { + io_read_kbs: number + io_write_kbs: number + last_updated: string + other_config: Record +} + +export interface XenApiPif extends XenApiRecord<'pif'> { + DNS: string + IP: string + IPv6: string[] + MAC: string + MTU: number + PCI: XenApiPci['$ref'] + VLAN: number + VLAN_master_of: XenApiVlan['$ref'] + VLAN_slave_of: XenApiVlan['$ref'][] + bond_master_of: XenApiBond['$ref'][] + bond_slave_of: XenApiBond['$ref'] + capabilities: string[] + currently_attached: boolean + device: string + disallow_unplug: boolean + gateway: string + host: XenApiHost['$ref'] + igmp_snooping_status: PIF_IGMP_STATUS + ip_configuration_mode: IP_CONFIGURATION_MODE + ipv6_configuration_mode: IPV6_CONFIGURATION_MODE + ipv6_gateway: string + managed: boolean + management: boolean + metrics: XenApiPifMetrics['$ref'] + netmask: string + network: XenApiNetwork['$ref'] + other_config: Record + physical: boolean + primary_address_type: PRIMARY_ADDRESS_TYPE + properties: Record + sriov_logical_PIF_of: XenApiNetworkSriov['$ref'][] + sriov_physical_PIF_of: XenApiNetworkSriov['$ref'][] + tunnel_access_PIF_of: XenApiTunnel['$ref'][] + tunnel_transport_PIF_of: XenApiTunnel['$ref'][] +} + +export interface XenApiNetworkSriov extends XenApiRecord<'network_sriov'> { + configuration_mode: SRIOV_CONFIGURATION_MODE + logical_PIF: XenApiPif['$ref'] + physical_PIF: XenApiPif['$ref'] + requires_reboot: boolean +} + +export interface XenApiVlan extends XenApiRecord<'vlan'> { + other_config: Record + tag: number + tagged_PIF: XenApiPif['$ref'] + untagged_PIF: XenApiPif['$ref'] +} + +export interface XenApiTunnel extends XenApiRecord<'tunnel'> { + access_PIF: XenApiPif['$ref'] + other_config: Record + protocol: TUNNEL_PROTOCOL + status: Record + transport_PIF: XenApiPif['$ref'] +} + +export interface XenApiPci extends XenApiRecord<'pci'> { + class_name: string + dependencies: XenApiPci['$ref'][] + device_name: string + driver_name: string + host: XenApiHost['$ref'] + other_config: Record + pci_id: string + subsystem_device_name: string + subsystem_vendor_name: string + vendor_name: string +} + +export interface XenApiPifMetrics extends XenApiRecord<'pif_metrics'> { + carrier: boolean + device_id: string + device_name: string + duplex: boolean + io_read_kbs: number + io_write_kbs: number + last_updated: string + other_config: Record + pci_bus_path: string + speed: number + vendor_id: string + vendor_name: string +} + +export interface XenApiBond extends XenApiRecord<'bond'> { + auto_update_mac: boolean + links_up: number + master: XenApiPif['$ref'] + mode: BOND_MODE + other_config: Record + primary_slave: XenApiPif['$ref'] + properties: Record + slaves: XenApiPif['$ref'][] +} + +export type XenApiEvent> = { + id: string + class: RelationType + operation: 'add' | 'mod' | 'del' + ref: XRecord['$ref'] + snapshot: RawXenApiRecord +} export interface XenApiError extends Error { - data?: any; + data?: any } + +/* eslint-enable no-use-before-define */ diff --git a/@xen-orchestra/lite/src/libs/xen-api/xen-api.utils.ts b/@xen-orchestra/lite/src/libs/xen-api/xen-api.utils.ts index ca939091cfa..6f4d7387c6b 100644 --- a/@xen-orchestra/lite/src/libs/xen-api/xen-api.utils.ts +++ b/@xen-orchestra/lite/src/libs/xen-api/xen-api.utils.ts @@ -5,81 +5,78 @@ import type { RawXenApiRecord, TypeToRawType, XenApiRecord, -} from "@/libs/xen-api/xen-api.types"; +} from '@/libs/xen-api/xen-api.types' export const XEN_API_OBJECT_TYPES = { - bond: "Bond", - certificate: "Certificate", - cluster: "Cluster", - cluster_host: "Cluster_host", - dr_task: "DR_task", - feature: "Feature", - gpu_group: "GPU_group", - pbd: "PBD", - pci: "PCI", - pgpu: "PGPU", - pif: "PIF", - pif_metrics: "PIF_metrics", - pusb: "PUSB", - pvs_cache_storage: "PVS_cache_storage", - pvs_proxy: "PVS_proxy", - pvs_server: "PVS_server", - pvs_site: "PVS_site", - sdn_controller: "SDN_controller", - sm: "SM", - sr: "SR", - usb_group: "USB_group", - vbd: "VBD", - vbd_metrics: "VBD_metrics", - vdi: "VDI", - vgpu: "VGPU", - vgpu_type: "VGPU_type", - vif: "VIF", - vif_metrics: "VIF_metrics", - vlan: "VLAN", - vm: "VM", - vmpp: "VMPP", - vmss: "VMSS", - vm_appliance: "VM_appliance", - vm_guest_metrics: "VM_guest_metrics", - vm_metrics: "VM_metrics", - vusb: "VUSB", - blob: "blob", - console: "console", - crashdump: "crashdump", - host: "host", - host_cpu: "host_cpu", - host_crashdump: "host_crashdump", - host_metrics: "host_metrics", - host_patch: "host_patch", - message: "message", - network: "network", - network_sriov: "network_sriov", - pool: "pool", - pool_patch: "pool_patch", - pool_update: "pool_update", - role: "role", - secret: "secret", - subject: "subject", - task: "task", - tunnel: "tunnel", - vtpm: "VTPM", -} as const; + bond: 'Bond', + certificate: 'Certificate', + cluster: 'Cluster', + cluster_host: 'Cluster_host', + dr_task: 'DR_task', + feature: 'Feature', + gpu_group: 'GPU_group', + pbd: 'PBD', + pci: 'PCI', + pgpu: 'PGPU', + pif: 'PIF', + pif_metrics: 'PIF_metrics', + pusb: 'PUSB', + pvs_cache_storage: 'PVS_cache_storage', + pvs_proxy: 'PVS_proxy', + pvs_server: 'PVS_server', + pvs_site: 'PVS_site', + sdn_controller: 'SDN_controller', + sm: 'SM', + sr: 'SR', + usb_group: 'USB_group', + vbd: 'VBD', + vbd_metrics: 'VBD_metrics', + vdi: 'VDI', + vgpu: 'VGPU', + vgpu_type: 'VGPU_type', + vif: 'VIF', + vif_metrics: 'VIF_metrics', + vlan: 'VLAN', + vm: 'VM', + vmpp: 'VMPP', + vmss: 'VMSS', + vm_appliance: 'VM_appliance', + vm_guest_metrics: 'VM_guest_metrics', + vm_metrics: 'VM_metrics', + vusb: 'VUSB', + blob: 'blob', + console: 'console', + crashdump: 'crashdump', + host: 'host', + host_cpu: 'host_cpu', + host_crashdump: 'host_crashdump', + host_metrics: 'host_metrics', + host_patch: 'host_patch', + message: 'message', + network: 'network', + network_sriov: 'network_sriov', + pool: 'pool', + pool_patch: 'pool_patch', + pool_update: 'pool_update', + role: 'role', + secret: 'secret', + subject: 'subject', + task: 'task', + tunnel: 'tunnel', + vtpm: 'VTPM', +} as const -export const rawTypeToType = ( - rawType: RawType -): RawTypeToType => rawType.toLowerCase() as Lowercase; +export const rawTypeToType = (rawType: RawType): RawTypeToType => + rawType.toLowerCase() as Lowercase -export const typeToRawType = ( - type: Type -): TypeToRawType => XEN_API_OBJECT_TYPES[type]; +export const typeToRawType = (type: Type): TypeToRawType => XEN_API_OBJECT_TYPES[type] export const buildXoObject = >( record: RawXenApiRecord, - params: { opaqueRef: T["$ref"] } + params: { opaqueRef: T['$ref'] } ) => { return { ...record, $ref: params.opaqueRef, - } as T; -}; + } as T +} diff --git a/@xen-orchestra/lite/src/main.ts b/@xen-orchestra/lite/src/main.ts index b76098227d4..777105d19e4 100644 --- a/@xen-orchestra/lite/src/main.ts +++ b/@xen-orchestra/lite/src/main.ts @@ -1,13 +1,13 @@ -import { createPinia } from "pinia"; -import { createApp } from "vue"; -import App from "@/App.vue"; -import i18n from "@/i18n"; -import router from "@/router"; +import { createPinia } from 'pinia' +import { createApp } from 'vue' +import App from '@/App.vue' +import i18n from '@/i18n' +import router from '@/router' -const app = createApp(App); +const app = createApp(App) -app.use(i18n); -app.use(createPinia()); -app.use(router); +app.use(i18n) +app.use(createPinia()) +app.use(router) -app.mount("#root"); +app.mount('#root') diff --git a/@xen-orchestra/lite/src/router/index.ts b/@xen-orchestra/lite/src/router/index.ts index c68f341355c..8d1633b53f4 100644 --- a/@xen-orchestra/lite/src/router/index.ts +++ b/@xen-orchestra/lite/src/router/index.ts @@ -1,47 +1,47 @@ -import pool from "@/router/pool"; -import story from "@/router/story"; -import vm from "@/router/vm"; -import HomeView from "@/views/HomeView.vue"; -import { createRouter, createWebHashHistory } from "vue-router"; +import pool from '@/router/pool' +import story from '@/router/story' +import vm from '@/router/vm' +import HomeView from '@/views/HomeView.vue' +import { createRouter, createWebHashHistory } from 'vue-router' const router = createRouter({ history: createWebHashHistory(), routes: [ { - path: "/", - name: "home", + path: '/', + name: 'home', component: HomeView, }, { - path: "/xoa-deploy", - name: "xoa.deploy", - component: () => import("@/views/xoa-deploy/XoaDeployView.vue"), + path: '/xoa-deploy', + name: 'xoa.deploy', + component: () => import('@/views/xoa-deploy/XoaDeployView.vue'), }, { - path: "/settings", - name: "settings", - component: () => import("@/views/settings/SettingsView.vue"), + path: '/settings', + name: 'settings', + component: () => import('@/views/settings/SettingsView.vue'), }, story, pool, vm, { - path: "/host/:uuid", - component: () => import("@/views/host/HostRootView.vue"), + path: '/host/:uuid', + component: () => import('@/views/host/HostRootView.vue'), children: [ { - path: "", - name: "host.dashboard", - component: () => import("@/views/host/HostDashboardView.vue"), + path: '', + name: 'host.dashboard', + component: () => import('@/views/host/HostDashboardView.vue'), }, ], }, { - path: "/:pathMatch(.*)*", - name: "not-found", - component: () => import("@/views/PageNotFoundView.vue"), + path: '/:pathMatch(.*)*', + name: 'not-found', + component: () => import('@/views/PageNotFoundView.vue'), }, ], -}); +}) -export default router; +export default router diff --git a/@xen-orchestra/lite/src/router/pool.ts b/@xen-orchestra/lite/src/router/pool.ts index a02d50cdfc9..d10ebb08542 100644 --- a/@xen-orchestra/lite/src/router/pool.ts +++ b/@xen-orchestra/lite/src/router/pool.ts @@ -1,55 +1,55 @@ -import PoolDashboardView from "@/views/pool/PoolDashboardView.vue"; -import PoolRootView from "@/views/pool/PoolRootView.vue"; +import PoolDashboardView from '@/views/pool/PoolDashboardView.vue' +import PoolRootView from '@/views/pool/PoolRootView.vue' export default { - path: "/pool/:uuid", + path: '/pool/:uuid', component: PoolRootView, - redirect: { name: "pool.dashboard" }, + redirect: { name: 'pool.dashboard' }, children: [ { - path: "dashboard", - name: "pool.dashboard", + path: 'dashboard', + name: 'pool.dashboard', component: PoolDashboardView, }, { - path: "alarms", - name: "pool.alarms", - component: () => import("@/views/pool/PoolAlarmsView.vue"), + path: 'alarms', + name: 'pool.alarms', + component: () => import('@/views/pool/PoolAlarmsView.vue'), }, { - path: "stats", - name: "pool.stats", - component: () => import("@/views/pool/PoolStatsView.vue"), + path: 'stats', + name: 'pool.stats', + component: () => import('@/views/pool/PoolStatsView.vue'), }, { - path: "system", - name: "pool.system", - component: () => import("@/views/pool/PoolSystemView.vue"), + path: 'system', + name: 'pool.system', + component: () => import('@/views/pool/PoolSystemView.vue'), }, { - path: "network", - name: "pool.network", - component: () => import("@/views/pool/PoolNetworkView.vue"), + path: 'network', + name: 'pool.network', + component: () => import('@/views/pool/PoolNetworkView.vue'), }, { - path: "storage", - name: "pool.storage", - component: () => import("@/views/pool/PoolStorageView.vue"), + path: 'storage', + name: 'pool.storage', + component: () => import('@/views/pool/PoolStorageView.vue'), }, { - path: "tasks", - name: "pool.tasks", - component: () => import("@/views/pool/PoolTasksView.vue"), + path: 'tasks', + name: 'pool.tasks', + component: () => import('@/views/pool/PoolTasksView.vue'), }, { - path: "hosts", - name: "pool.hosts", - component: () => import("@/views/pool/PoolHostsView.vue"), + path: 'hosts', + name: 'pool.hosts', + component: () => import('@/views/pool/PoolHostsView.vue'), }, { - path: "vms", - name: "pool.vms", - component: () => import("@/views/pool/PoolVmsView.vue"), + path: 'vms', + name: 'pool.vms', + component: () => import('@/views/pool/PoolVmsView.vue'), }, ], -}; +} diff --git a/@xen-orchestra/lite/src/router/story.ts b/@xen-orchestra/lite/src/router/story.ts index 23712941f5f..accab08d65f 100644 --- a/@xen-orchestra/lite/src/router/story.ts +++ b/@xen-orchestra/lite/src/router/story.ts @@ -1,42 +1,40 @@ -import type { RouteRecordRaw } from "vue-router"; +import type { RouteRecordRaw } from 'vue-router' -const componentLoaders = import.meta.glob("@/stories/**/*.story.vue"); -const docLoaders = import.meta.glob("@/stories/**/*.story.md", { as: "raw" }); +const componentLoaders = import.meta.glob('@/stories/**/*.story.vue') +const docLoaders = import.meta.glob('@/stories/**/*.story.md', { as: 'raw' }) -const children: RouteRecordRaw[] = Object.entries(componentLoaders).map( - ([path, componentLoader]) => { - const basePath = path.replace(/^\/src\/stories\/(.*)\.story.vue$/, "$1"); - const docPath = path.replace(/\.vue$/, ".md"); - const routeName = `story-${basePath}`; +const children: RouteRecordRaw[] = Object.entries(componentLoaders).map(([path, componentLoader]) => { + const basePath = path.replace(/^\/src\/stories\/(.*)\.story.vue$/, '$1') + const docPath = path.replace(/\.vue$/, '.md') + const routeName = `story-${basePath}` - return { - name: routeName, - path: basePath, - component: componentLoader, - meta: { - isStory: true, - storyTitle: basePathToStoryTitle(basePath), - storyMdLoader: docLoaders[docPath], - }, - }; + return { + name: routeName, + path: basePath, + component: componentLoader, + meta: { + isStory: true, + storyTitle: basePathToStoryTitle(basePath), + storyMdLoader: docLoaders[docPath], + }, } -); +}) if (import.meta.env.DEV) { children.push({ - path: "", - name: "story-home", - component: () => import("@/views/story/HomeView.vue"), - }); + path: '', + name: 'story-home', + component: () => import('@/views/story/HomeView.vue'), + }) } export default { - path: "/story", - name: "story", - component: () => import("@/views/StoryView.vue"), + path: '/story', + name: 'story', + component: () => import('@/views/StoryView.vue'), children, meta: { hasStoryNav: true }, -}; +} /** * Transform the route basename to a page title. @@ -48,9 +46,9 @@ export default { */ function basePathToStoryTitle(basePath: string) { return basePath - .split("/") + .split('/') .pop()! - .split("-") - .map((s) => `${s.charAt(0).toUpperCase()}${s.substring(1)}`) - .join(" "); + .split('-') + .map(s => `${s.charAt(0).toUpperCase()}${s.substring(1)}`) + .join(' ') } diff --git a/@xen-orchestra/lite/src/router/vm.ts b/@xen-orchestra/lite/src/router/vm.ts index 3f8ff1f4a29..ac3381f2249 100644 --- a/@xen-orchestra/lite/src/router/vm.ts +++ b/@xen-orchestra/lite/src/router/vm.ts @@ -1,47 +1,47 @@ export default { - path: "/vm/:uuid", - component: () => import("@/views/vm/VmRootView.vue"), - redirect: { name: "vm.console" }, + path: '/vm/:uuid', + component: () => import('@/views/vm/VmRootView.vue'), + redirect: { name: 'vm.console' }, children: [ { - path: "dashboard", - name: "vm.dashboard", - component: () => import("@/views/vm/VmDashboardView.vue"), + path: 'dashboard', + name: 'vm.dashboard', + component: () => import('@/views/vm/VmDashboardView.vue'), }, { - path: "console", - name: "vm.console", - component: () => import("@/views/vm/VmConsoleView.vue"), + path: 'console', + name: 'vm.console', + component: () => import('@/views/vm/VmConsoleView.vue'), }, { - path: "alarms", - name: "vm.alarms", - component: () => import("@/views/vm/VmAlarmsView.vue"), + path: 'alarms', + name: 'vm.alarms', + component: () => import('@/views/vm/VmAlarmsView.vue'), }, { - path: "stats", - name: "vm.stats", - component: () => import("@/views/vm/VmStatsView.vue"), + path: 'stats', + name: 'vm.stats', + component: () => import('@/views/vm/VmStatsView.vue'), }, { - path: "system", - name: "vm.system", - component: () => import("@/views/vm/VmSystemView.vue"), + path: 'system', + name: 'vm.system', + component: () => import('@/views/vm/VmSystemView.vue'), }, { - path: "network", - name: "vm.network", - component: () => import("@/views/vm/VmNetworkView.vue"), + path: 'network', + name: 'vm.network', + component: () => import('@/views/vm/VmNetworkView.vue'), }, { - path: "storage", - name: "vm.storage", - component: () => import("@/views/vm/VmStorageView.vue"), + path: 'storage', + name: 'vm.storage', + component: () => import('@/views/vm/VmStorageView.vue'), }, { - path: "tasks", - name: "vm.tasks", - component: () => import("@/views/vm/VmTasksView.vue"), + path: 'tasks', + name: 'vm.tasks', + component: () => import('@/views/vm/VmTasksView.vue'), }, ], -}; +} diff --git a/@xen-orchestra/lite/src/stores/closing-confirmation.store.ts b/@xen-orchestra/lite/src/stores/closing-confirmation.store.ts index 8313f08deeb..186d96d5726 100644 --- a/@xen-orchestra/lite/src/stores/closing-confirmation.store.ts +++ b/@xen-orchestra/lite/src/stores/closing-confirmation.store.ts @@ -1,39 +1,34 @@ -import { defineStore } from "pinia"; -import { onBeforeUnmount, ref, watch } from "vue"; +import { defineStore } from 'pinia' +import { onBeforeUnmount, ref, watch } from 'vue' const beforeUnloadListener = function (e: BeforeUnloadEvent) { - e.preventDefault(); - e.returnValue = ""; // Required to trigger the modal on some browser. https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event#browser_compatibility -}; - -export const useClosingConfirmationStore = defineStore( - "closing-confirmation", - () => { - const registeredIds = ref(new Set()); - watch( - () => registeredIds.value.size > 0, - (isConfirmationNeeded) => { - const eventMethod = isConfirmationNeeded - ? "addEventListener" - : "removeEventListener"; - - window[eventMethod]("beforeunload", beforeUnloadListener); - } - ); - - const register = () => { - const id = Symbol(); - registeredIds.value.add(id); - - const unregister = () => registeredIds.value.delete(id); - - onBeforeUnmount(unregister); - - return unregister; - }; - - return { - register, - }; + e.preventDefault() + e.returnValue = '' // Required to trigger the modal on some browser. https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event#browser_compatibility +} + +export const useClosingConfirmationStore = defineStore('closing-confirmation', () => { + const registeredIds = ref(new Set()) + watch( + () => registeredIds.value.size > 0, + isConfirmationNeeded => { + const eventMethod = isConfirmationNeeded ? 'addEventListener' : 'removeEventListener' + + window[eventMethod]('beforeunload', beforeUnloadListener) + } + ) + + const register = () => { + const id = Symbol('CLOSING_CONFIRMATION_ID') + registeredIds.value.add(id) + + const unregister = () => registeredIds.value.delete(id) + + onBeforeUnmount(unregister) + + return unregister + } + + return { + register, } -); +}) diff --git a/@xen-orchestra/lite/src/stores/modal.store.ts b/@xen-orchestra/lite/src/stores/modal.store.ts index af77904a1bd..600b2afb535 100644 --- a/@xen-orchestra/lite/src/stores/modal.store.ts +++ b/@xen-orchestra/lite/src/stores/modal.store.ts @@ -1,52 +1,45 @@ -import type { ModalController } from "@/types"; -import { createEventHook } from "@vueuse/core"; -import { defineStore } from "pinia"; -import { - type AsyncComponentLoader, - computed, - defineAsyncComponent, - markRaw, - reactive, - ref, -} from "vue"; +import type { ModalController } from '@/types' +import { createEventHook } from '@vueuse/core' +import { defineStore } from 'pinia' +import { type AsyncComponentLoader, computed, defineAsyncComponent, markRaw, reactive, ref } from 'vue' -export const useModalStore = defineStore("modal", () => { - const modals = ref(new Map()); +export const useModalStore = defineStore('modal', () => { + const modals = ref(new Map()) const open = (loader: AsyncComponentLoader, props: object) => { - const id = Symbol(); - const isBusy = ref(false); - const component = defineAsyncComponent(loader); + const id = Symbol('MODAL_ID') + const isBusy = ref(false) + const component = defineAsyncComponent(loader) - const approveEvent = createEventHook(); - const declineEvent = createEventHook(); - const closeEvent = createEventHook(); + const approveEvent = createEventHook() + const declineEvent = createEventHook() + const closeEvent = createEventHook() const close = async () => { - await closeEvent.trigger(undefined); - modals.value.delete(id); - }; + await closeEvent.trigger(undefined) + modals.value.delete(id) + } const approve = async (payload: any) => { try { - isBusy.value = true; - const result = await payload; - await approveEvent.trigger(result); - void close(); + isBusy.value = true + const result = await payload + await approveEvent.trigger(result) + await close() } finally { - isBusy.value = false; + isBusy.value = false } - }; + } const decline = async () => { try { - isBusy.value = true; - await declineEvent.trigger(undefined); - void close(); + isBusy.value = true + await declineEvent.trigger(undefined) + await close() } finally { - isBusy.value = false; + isBusy.value = false } - }; + } modals.value.set( id, @@ -58,18 +51,18 @@ export const useModalStore = defineStore("modal", () => { decline, isBusy, }) - ); + ) return { onApprove: approveEvent.on, onDecline: declineEvent.on, onClose: closeEvent.on, id, - }; - }; + } + } return { open, modals: computed(() => modals.value.values()), - }; -}); + } +}) diff --git a/@xen-orchestra/lite/src/stores/navigation.store.ts b/@xen-orchestra/lite/src/stores/navigation.store.ts index 417aace4530..5e9ef23ab47 100644 --- a/@xen-orchestra/lite/src/stores/navigation.store.ts +++ b/@xen-orchestra/lite/src/stores/navigation.store.ts @@ -1,32 +1,32 @@ -import { useUiStore } from "@/stores/ui.store"; -import { useEventListener, whenever } from "@vueuse/core"; -import { defineStore } from "pinia"; -import { ref } from "vue"; -import { useRouter } from "vue-router"; +import { useUiStore } from '@/stores/ui.store' +import { useEventListener, whenever } from '@vueuse/core' +import { defineStore } from 'pinia' +import { ref } from 'vue' +import { useRouter } from 'vue-router' -export const useNavigationStore = defineStore("navigation", () => { - const router = useRouter(); - const uiStore = useUiStore(); +export const useNavigationStore = defineStore('navigation', () => { + const router = useRouter() + const uiStore = useUiStore() - const trigger = ref(); - const isOpen = ref(false); - const toggle = () => (isOpen.value = !isOpen.value); + const trigger = ref() + const isOpen = ref(false) + const toggle = () => (isOpen.value = !isOpen.value) // Close the menu when the user navigates to a new page router.afterEach(() => { - isOpen.value = false; - }); + isOpen.value = false + }) - useEventListener(trigger, "click", toggle); + useEventListener(trigger, 'click', toggle) whenever( () => uiStore.isDesktop, () => (isOpen.value = false) - ); + ) return { trigger, toggle, isOpen, - }; -}); + } +}) diff --git a/@xen-orchestra/lite/src/stores/page-title.store.ts b/@xen-orchestra/lite/src/stores/page-title.store.ts index 7f1a7fa9f91..f477ebbe381 100644 --- a/@xen-orchestra/lite/src/stores/page-title.store.ts +++ b/@xen-orchestra/lite/src/stores/page-title.store.ts @@ -1,92 +1,75 @@ -import { useTitle } from "@vueuse/core"; -import { defineStore } from "pinia"; -import { - computed, - type MaybeRefOrGetter, - onBeforeUnmount, - reactive, - toRef, - watch, -} from "vue"; +import { useTitle } from '@vueuse/core' +import { defineStore } from 'pinia' +import { computed, type MaybeRefOrGetter, onBeforeUnmount, reactive, toRef, watch } from 'vue' -const PAGE_TITLE_SUFFIX = "XO Lite"; +const PAGE_TITLE_SUFFIX = 'XO Lite' interface PageTitleConfig { - object: { name_label: string } | undefined; - title: string | undefined; - count: number | undefined; + object: { name_label: string } | undefined + title: string | undefined + count: number | undefined } -export const usePageTitleStore = defineStore("page-title", () => { +export const usePageTitleStore = defineStore('page-title', () => { const pageTitleConfig = reactive({ count: undefined, title: undefined, object: undefined, - }); + }) const generatedPageTitle = computed(() => { - const { object, title, count } = pageTitleConfig; - const parts = []; + const { object, title, count } = pageTitleConfig + const parts = [] if (count !== undefined && count > 0) { - parts.push(`(${count})`); + parts.push(`(${count})`) } if (title !== undefined && object !== undefined) { - parts.push(`${title} - ${object.name_label}`); + parts.push(`${title} - ${object.name_label}`) } else if (title !== undefined) { - parts.push(title); + parts.push(title) } else if (object !== undefined) { - parts.push(object.name_label); + parts.push(object.name_label) } if (parts.length === 0) { - return undefined; + return undefined } - return parts.join(" "); - }); + return parts.join(' ') + }) useTitle(generatedPageTitle, { titleTemplate: computed(() => - generatedPageTitle.value === undefined - ? PAGE_TITLE_SUFFIX - : `%s - ${PAGE_TITLE_SUFFIX}` + generatedPageTitle.value === undefined ? PAGE_TITLE_SUFFIX : `%s - ${PAGE_TITLE_SUFFIX}` ), - }); + }) const setPageTitleConfig = ( configKey: T, value: MaybeRefOrGetter ) => { - const stop = watch( - toRef(value), - (newValue) => - (pageTitleConfig[configKey] = newValue as PageTitleConfig[T]), - { - immediate: true, - } - ); + const stop = watch(toRef(value), newValue => (pageTitleConfig[configKey] = newValue as PageTitleConfig[T]), { + immediate: true, + }) onBeforeUnmount(() => { - stop(); - pageTitleConfig[configKey] = undefined; - }); - }; + stop() + pageTitleConfig[configKey] = undefined + }) + } - const setObject = ( - object: MaybeRefOrGetter<{ name_label: string } | undefined> - ) => setPageTitleConfig("object", object); + const setObject = (object: MaybeRefOrGetter<{ name_label: string } | undefined>) => + setPageTitleConfig('object', object) - const setTitle = (title: MaybeRefOrGetter) => - setPageTitleConfig("title", title); + const setTitle = (title: MaybeRefOrGetter) => setPageTitleConfig('title', title) - const setCount = (count: MaybeRefOrGetter) => - setPageTitleConfig("count", count); + const setCount = (count: MaybeRefOrGetter) => setPageTitleConfig('count', count) return { setObject, setTitle, setCount, - }; -}); + } +}) diff --git a/@xen-orchestra/lite/src/stores/tooltip.store.ts b/@xen-orchestra/lite/src/stores/tooltip.store.ts index 88ea9e51799..707ae441d66 100644 --- a/@xen-orchestra/lite/src/stores/tooltip.store.ts +++ b/@xen-orchestra/lite/src/stores/tooltip.store.ts @@ -1,75 +1,71 @@ -import { uniqueId } from "lodash-es"; -import { defineStore } from "pinia"; -import type { Options } from "placement.js"; -import { type EffectScope, computed, effectScope, ref } from "vue"; -import { type WindowEventName, useEventListener } from "@vueuse/core"; +import { uniqueId } from 'lodash-es' +import { defineStore } from 'pinia' +import type { Options } from 'placement.js' +import { type EffectScope, computed, effectScope, ref } from 'vue' +import { type WindowEventName, useEventListener } from '@vueuse/core' export type TooltipOptions = { - content: string | false; - placement: Options["placement"]; -}; + content: string | false + placement: Options['placement'] +} -export type TooltipEvents = { on: WindowEventName; off: WindowEventName }; +export type TooltipEvents = { on: WindowEventName; off: WindowEventName } -export const useTooltipStore = defineStore("tooltip", () => { - const targetsScopes = new WeakMap(); - const targets = ref(new Set()); - const targetsOptions = ref(new Map()); - const targetsIds = ref(new Map()); +export const useTooltipStore = defineStore('tooltip', () => { + const targetsScopes = new WeakMap() + const targets = ref(new Set()) + const targetsOptions = ref(new Map()) + const targetsIds = ref(new Map()) - const register = ( - target: HTMLElement, - options: TooltipOptions, - events: TooltipEvents - ) => { - const scope = effectScope(); + const register = (target: HTMLElement, options: TooltipOptions, events: TooltipEvents) => { + const scope = effectScope() - targetsScopes.set(target, scope); - targetsOptions.value.set(target, options); - targetsIds.value.set(target, uniqueId("tooltip-")); + targetsScopes.set(target, scope) + targetsOptions.value.set(target, options) + targetsIds.value.set(target, uniqueId('tooltip-')) scope.run(() => { useEventListener(target, events.on, () => { - targets.value.add(target); + targets.value.add(target) scope.run(() => { useEventListener( target, events.off, () => { - targets.value.delete(target); + targets.value.delete(target) }, { once: true } - ); - }); - }); - }); - }; + ) + }) + }) + }) + } const updateOptions = (target: HTMLElement, options: TooltipOptions) => { - targetsOptions.value.set(target, options); - }; + targetsOptions.value.set(target, options) + } const unregister = (target: HTMLElement) => { - targets.value.delete(target); - targetsOptions.value.delete(target); - targetsScopes.get(target)?.stop(); - targetsScopes.delete(target); - targetsIds.value.delete(target); - }; + targets.value.delete(target) + targetsOptions.value.delete(target) + targetsScopes.get(target)?.stop() + targetsScopes.delete(target) + targetsIds.value.delete(target) + } return { register, unregister, updateOptions, tooltips: computed(() => { - return Array.from(targets.value.values()).map((target) => { + return Array.from(targets.value.values()).map(target => { return { target, options: targetsOptions.value.get(target)!, key: targetsIds.value.get(target)!, - }; - }); + } + }) }), - }; -}); + } +}) diff --git a/@xen-orchestra/lite/src/stores/ui.store.ts b/@xen-orchestra/lite/src/stores/ui.store.ts index 9ff30ba95fb..4b2265e9b8f 100644 --- a/@xen-orchestra/lite/src/stores/ui.store.ts +++ b/@xen-orchestra/lite/src/stores/ui.store.ts @@ -1,28 +1,28 @@ -import { useBreakpoints, useColorMode } from "@vueuse/core"; -import { defineStore } from "pinia"; -import { computed, ref } from "vue"; -import { useRoute, useRouter } from "vue-router"; +import { useBreakpoints, useColorMode } from '@vueuse/core' +import { defineStore } from 'pinia' +import { computed, ref } from 'vue' +import { useRoute, useRouter } from 'vue-router' -export const useUiStore = defineStore("ui", () => { - const currentHostOpaqueRef = ref(); +export const useUiStore = defineStore('ui', () => { + const currentHostOpaqueRef = ref() - const { store: colorMode } = useColorMode({ initialValue: "dark" }); + const { store: colorMode } = useColorMode({ initialValue: 'dark' }) const { desktop: isDesktop } = useBreakpoints({ desktop: 1024, - }); + }) - const isMobile = computed(() => !isDesktop.value); + const isMobile = computed(() => !isDesktop.value) - const router = useRouter(); - const route = useRoute(); + const router = useRouter() + const route = useRoute() const hasUi = computed({ - get: () => route.query.ui !== "0", + get: () => route.query.ui !== '0', set: (value: boolean) => { - void router.replace({ query: { ui: value ? undefined : "0" } }); + void router.replace({ query: { ui: value ? undefined : '0' } }) }, - }); + }) return { colorMode, @@ -30,5 +30,5 @@ export const useUiStore = defineStore("ui", () => { isDesktop, isMobile, hasUi, - }; -}); + } +}) diff --git a/@xen-orchestra/lite/src/stores/xen-api.store.ts b/@xen-orchestra/lite/src/stores/xen-api.store.ts index 0467613ae65..355fccafe47 100644 --- a/@xen-orchestra/lite/src/stores/xen-api.store.ts +++ b/@xen-orchestra/lite/src/stores/xen-api.store.ts @@ -1,14 +1,11 @@ -import XapiStats from "@/libs/xapi-stats"; -import XenApi from "@/libs/xen-api/xen-api"; -import { useLocalStorage, useSessionStorage, whenever } from "@vueuse/core"; -import { defineStore } from "pinia"; -import { computed, ref, watchEffect } from "vue"; -import { useRouter } from "vue-router"; -import { useRoute } from "vue-router"; +import XapiStats from '@/libs/xapi-stats' +import XenApi from '@/libs/xen-api/xen-api' +import { useLocalStorage, useSessionStorage, whenever } from '@vueuse/core' +import { defineStore } from 'pinia' +import { computed, ref, watchEffect } from 'vue' +import { useRouter, useRoute } from 'vue-router' -const HOST_URL = import.meta.env.PROD - ? window.origin - : import.meta.env.VITE_XO_HOST; +const HOST_URL = import.meta.env.PROD ? window.origin : import.meta.env.VITE_XO_HOST enum STATUS { DISCONNECTED, @@ -16,90 +13,82 @@ enum STATUS { CONNECTED, } -export const useXenApiStore = defineStore("xen-api", () => { +export const useXenApiStore = defineStore('xen-api', () => { // undefined not correctly handled. See https://github.com/vueuse/vueuse/issues/3595 - const masterSessionStorage = useSessionStorage("master", null); - const router = useRouter(); - const route = useRoute(); + const masterSessionStorage = useSessionStorage('master', null) + const router = useRouter() + const route = useRoute() whenever( () => route.query.master, - async (newMaster) => { - masterSessionStorage.value = newMaster as string; - await router.replace({ query: { ...route.query, master: undefined } }); - window.location.reload(); + async newMaster => { + masterSessionStorage.value = newMaster as string + await router.replace({ query: { ...route.query, master: undefined } }) + window.location.reload() } - ); + ) - const hostUrl = new URL(HOST_URL); + const hostUrl = new URL(HOST_URL) if (masterSessionStorage.value !== null) { - hostUrl.hostname = masterSessionStorage.value; + hostUrl.hostname = masterSessionStorage.value } - const isPoolOverridden = hostUrl.origin !== new URL(HOST_URL).origin; - const xenApi = new XenApi(hostUrl.origin); - const xapiStats = new XapiStats(xenApi); - const storedSessionId = useLocalStorage( - "sessionId", - undefined - ); - const currentSessionId = ref(storedSessionId.value); - const rememberMe = useLocalStorage("rememberMe", false); - const status = ref(STATUS.DISCONNECTED); - const isConnected = computed(() => status.value === STATUS.CONNECTED); - const isConnecting = computed(() => status.value === STATUS.CONNECTING); - const getXapi = () => xenApi; - const getXapiStats = () => xapiStats; + const isPoolOverridden = hostUrl.origin !== new URL(HOST_URL).origin + const xenApi = new XenApi(hostUrl.origin) + const xapiStats = new XapiStats(xenApi) + const storedSessionId = useLocalStorage('sessionId', undefined) + const currentSessionId = ref(storedSessionId.value) + const rememberMe = useLocalStorage('rememberMe', false) + const status = ref(STATUS.DISCONNECTED) + const isConnected = computed(() => status.value === STATUS.CONNECTED) + const isConnecting = computed(() => status.value === STATUS.CONNECTING) + const getXapi = () => xenApi + const getXapiStats = () => xapiStats watchEffect(() => { - storedSessionId.value = rememberMe.value - ? currentSessionId.value - : undefined; - }); + storedSessionId.value = rememberMe.value ? currentSessionId.value : undefined + }) const connect = async (username: string, password: string) => { - status.value = STATUS.CONNECTING; + status.value = STATUS.CONNECTING try { - currentSessionId.value = await xenApi.connectWithPassword( - username, - password - ); - const success = currentSessionId.value !== undefined; - status.value = success ? STATUS.CONNECTED : STATUS.DISCONNECTED; - return success; + currentSessionId.value = await xenApi.connectWithPassword(username, password) + const success = currentSessionId.value !== undefined + status.value = success ? STATUS.CONNECTED : STATUS.DISCONNECTED + return success } catch (error) { - status.value = STATUS.DISCONNECTED; - throw error; + status.value = STATUS.DISCONNECTED + throw error } - }; + } const reconnect = async () => { if (currentSessionId.value === undefined) { - return false; + return false } - status.value = STATUS.CONNECTING; + status.value = STATUS.CONNECTING try { - const success = await xenApi.connectWithSessionId(currentSessionId.value); - status.value = success ? STATUS.CONNECTED : STATUS.DISCONNECTED; - return success; + const success = await xenApi.connectWithSessionId(currentSessionId.value) + status.value = success ? STATUS.CONNECTED : STATUS.DISCONNECTED + return success } catch (error) { - status.value = STATUS.DISCONNECTED; - throw error; + status.value = STATUS.DISCONNECTED + throw error } - }; + } async function disconnect() { - await xenApi.disconnect(); - currentSessionId.value = undefined; - status.value = STATUS.DISCONNECTED; + await xenApi.disconnect() + currentSessionId.value = undefined + status.value = STATUS.DISCONNECTED } function resetPoolMasterIp() { - masterSessionStorage.value = null; - window.location.reload(); + masterSessionStorage.value = null + window.location.reload() } return { @@ -113,5 +102,5 @@ export const useXenApiStore = defineStore("xen-api", () => { getXapiStats, currentSessionId, resetPoolMasterIp, - }; -}); + } +}) diff --git a/@xen-orchestra/lite/src/stores/xen-api/alarm.store.ts b/@xen-orchestra/lite/src/stores/xen-api/alarm.store.ts index c2a2c173981..8b7fb38cf58 100644 --- a/@xen-orchestra/lite/src/stores/xen-api/alarm.store.ts +++ b/@xen-orchestra/lite/src/stores/xen-api/alarm.store.ts @@ -1,66 +1,66 @@ -import { useSubscriber } from "@/composables/subscriber.composable"; -import { useXenApiStoreBaseContext } from "@/composables/xen-api-store-base-context.composable"; -import { messagesToAlarms, messageToAlarm } from "@/libs/alarm"; -import type { XenApiMessage } from "@/libs/xen-api/xen-api.types"; -import { useXenApiStore } from "@/stores/xen-api.store"; -import { createUseCollection } from "@/stores/xen-api/create-use-collection"; -import { useMessageStore } from "@/stores/xen-api/message.store"; -import type { XenApiAlarm } from "@/types/xen-api"; -import { defineStore } from "pinia"; +import { useSubscriber } from '@/composables/subscriber.composable' +import { useXenApiStoreBaseContext } from '@/composables/xen-api-store-base-context.composable' +import { messagesToAlarms, messageToAlarm } from '@/libs/alarm' +import type { XenApiMessage } from '@/libs/xen-api/xen-api.types' +import { useXenApiStore } from '@/stores/xen-api.store' +import { createUseCollection } from '@/stores/xen-api/create-use-collection' +import { useMessageStore } from '@/stores/xen-api/message.store' +import type { XenApiAlarm } from '@/types/xen-api' +import { defineStore } from 'pinia' -export const useAlarmStore = defineStore("xen-api-alarm", () => { - const context = useXenApiStoreBaseContext>(); - const xenApiStore = useXenApiStore(); - const xenApi = xenApiStore.getXapi(); - const messageStore = useMessageStore(); +export const useAlarmStore = defineStore('xen-api-alarm', () => { + const context = useXenApiStoreBaseContext>() + const xenApiStore = useXenApiStore() + const xenApi = xenApiStore.getXapi() + const messageStore = useMessageStore() - const onBeforeLoad = () => (context.isFetching.value = true); + const onBeforeLoad = () => (context.isFetching.value = true) const onAfterLoad = (records: XenApiMessage[]) => { - const alarms = messagesToAlarms(records); - alarms.forEach((alarm) => context.add(alarm)); - context.isFetching.value = false; - context.isReady.value = true; - }; + const alarms = messagesToAlarms(records) + alarms.forEach(alarm => context.add(alarm)) + context.isFetching.value = false + context.isReady.value = true + } const onAdd = (record: XenApiMessage) => { - const alarm = messageToAlarm(record); + const alarm = messageToAlarm(record) if (alarm !== undefined) { - context.add(alarm); + context.add(alarm) } - }; + } - const onRemove = (opaqueRef: XenApiMessage["$ref"]) => { - context.remove(opaqueRef); - }; + const onRemove = (opaqueRef: XenApiMessage['$ref']) => { + context.remove(opaqueRef) + } - const subscriptionId = Symbol(); + const subscriptionId = Symbol('SUBSCRIPTION_ID') const subscriber = useSubscriber({ enabled: () => xenApiStore.isConnected, onSubscriptionStart: () => { - xenApi.addEventListener("message.beforeLoad", onBeforeLoad); - xenApi.addEventListener("message.afterLoad", onAfterLoad); - xenApi.addEventListener("message.add", onAdd); - xenApi.addEventListener("message.mod", onAdd); - xenApi.addEventListener("message.del", onRemove); - messageStore.subscribe(subscriptionId); + xenApi.addEventListener('message.beforeLoad', onBeforeLoad) + xenApi.addEventListener('message.afterLoad', onAfterLoad) + xenApi.addEventListener('message.add', onAdd) + xenApi.addEventListener('message.mod', onAdd) + xenApi.addEventListener('message.del', onRemove) + messageStore.subscribe(subscriptionId) }, onSubscriptionEnd: () => { - xenApi.removeEventListener("message.beforeLoad", onBeforeLoad); - xenApi.removeEventListener("message.afterLoad", onAfterLoad); - xenApi.removeEventListener("message.add", onAdd); - xenApi.removeEventListener("message.mod", onAdd); - xenApi.removeEventListener("message.del", onRemove); - messageStore.unsubscribe(subscriptionId); + xenApi.removeEventListener('message.beforeLoad', onBeforeLoad) + xenApi.removeEventListener('message.afterLoad', onAfterLoad) + xenApi.removeEventListener('message.add', onAdd) + xenApi.removeEventListener('message.mod', onAdd) + xenApi.removeEventListener('message.del', onRemove) + messageStore.unsubscribe(subscriptionId) }, - }); + }) return { ...context, ...subscriber, - }; -}); + } +}) -export const useAlarmCollection = createUseCollection(useAlarmStore); +export const useAlarmCollection = createUseCollection(useAlarmStore) diff --git a/@xen-orchestra/lite/src/stores/xen-api/console.store.ts b/@xen-orchestra/lite/src/stores/xen-api/console.store.ts index 55343bb1946..de3c34e7f55 100644 --- a/@xen-orchestra/lite/src/stores/xen-api/console.store.ts +++ b/@xen-orchestra/lite/src/stores/xen-api/console.store.ts @@ -1,9 +1,9 @@ -import { useXenApiStoreSubscribableContext } from "@/composables/xen-api-store-subscribable-context.composable"; -import { createUseCollection } from "@/stores/xen-api/create-use-collection"; -import { defineStore } from "pinia"; +import { useXenApiStoreSubscribableContext } from '@/composables/xen-api-store-subscribable-context.composable' +import { createUseCollection } from '@/stores/xen-api/create-use-collection' +import { defineStore } from 'pinia' -export const useConsoleStore = defineStore("xen-api-console", () => { - return useXenApiStoreSubscribableContext("console"); -}); +export const useConsoleStore = defineStore('xen-api-console', () => { + return useXenApiStoreSubscribableContext('console') +}) -export const useConsoleCollection = createUseCollection(useConsoleStore); +export const useConsoleCollection = createUseCollection(useConsoleStore) diff --git a/@xen-orchestra/lite/src/stores/xen-api/create-use-collection.ts b/@xen-orchestra/lite/src/stores/xen-api/create-use-collection.ts index 1ae40c7d334..b9c6071f2ae 100644 --- a/@xen-orchestra/lite/src/stores/xen-api/create-use-collection.ts +++ b/@xen-orchestra/lite/src/stores/xen-api/create-use-collection.ts @@ -1,71 +1,52 @@ -import type { - PiniaCustomStateProperties, - Store, - StoreDefinition, - StoreGetters, - StoreState, -} from "pinia"; -import { storeToRefs } from "pinia"; -import type { ComputedRef, Ref, ToRef, ToRefs } from "vue"; -import { computed, onUnmounted } from "vue"; +import type { PiniaCustomStateProperties, Store, StoreDefinition, StoreGetters, StoreState } from 'pinia' +import { storeToRefs } from 'pinia' +import type { ComputedRef, Ref, ToRef, ToRefs } from 'vue' +import { computed, onUnmounted } from 'vue' type IgnoredProperties = - | "_customProperties" - | "$id" - | "$dispose" - | "$state" - | "$patch" - | "$reset" - | "$subscribe" - | "$unsubscribe" - | "$onAction" - | "add" - | "remove" - | "subscribe" - | "hasSubscribers" - | "unsubscribe"; + | '_customProperties' + | '$id' + | '$dispose' + | '$state' + | '$patch' + | '$reset' + | '$subscribe' + | '$unsubscribe' + | '$onAction' + | 'add' + | 'remove' + | 'subscribe' + | 'hasSubscribers' + | 'unsubscribe' type ToComputedRefs = { - [K in keyof T]: ToRef extends Ref - ? ComputedRef - : ToRef; -}; + [K in keyof T]: ToRef extends Ref ? ComputedRef : ToRef +} type StoreToRefs> = ToRefs< StoreState & PiniaCustomStateProperties> > & - ToComputedRefs>; + ToComputedRefs> -type Output< - S extends StoreDefinition, - Defer extends boolean, -> = Omit | IgnoredProperties> & +type Output, Defer extends boolean> = Omit< + S, + keyof StoreToRefs | IgnoredProperties +> & StoreToRefs & - (Defer extends true - ? { start: () => void; isStarted: ComputedRef } - : object); + (Defer extends true ? { start: () => void; isStarted: ComputedRef } : object) export const createUseCollection = < SD extends StoreDefinition, - UseStore extends SD extends StoreDefinition< - infer Id, - infer S, - infer G, - infer A - > - ? Store - : never, + UseStore extends SD extends StoreDefinition ? Store : never, >( useStore: SD ) => { - return (options?: { - defer: Defer; - }): Output => { - const store = useStore(); + return (options?: { defer: Defer }): Output => { + const store = useStore() - const id = Symbol(store.$id); - onUnmounted(() => store.unsubscribe(id)); - const start = () => store.subscribe(id); + const id = Symbol(store.$id) + onUnmounted(() => store.unsubscribe(id)) + const start = () => store.subscribe(id) if (options?.defer) { return { @@ -73,14 +54,14 @@ export const createUseCollection = < ...storeToRefs(store), start, isStarted: computed(() => store.hasSubscribers), - } as unknown as Output; + } as unknown as Output } - start(); + start() return { ...store, ...storeToRefs(store), - } as unknown as Output; - }; -}; + } as unknown as Output + } +} diff --git a/@xen-orchestra/lite/src/stores/xen-api/host-metrics.store.ts b/@xen-orchestra/lite/src/stores/xen-api/host-metrics.store.ts index d85caeb2792..ed3d8b61f83 100644 --- a/@xen-orchestra/lite/src/stores/xen-api/host-metrics.store.ts +++ b/@xen-orchestra/lite/src/stores/xen-api/host-metrics.store.ts @@ -1,33 +1,32 @@ -import { useXenApiStoreSubscribableContext } from "@/composables/xen-api-store-subscribable-context.composable"; -import type { XenApiHost } from "@/libs/xen-api/xen-api.types"; -import { createUseCollection } from "@/stores/xen-api/create-use-collection"; -import { defineStore } from "pinia"; +import { useXenApiStoreSubscribableContext } from '@/composables/xen-api-store-subscribable-context.composable' +import type { XenApiHost } from '@/libs/xen-api/xen-api.types' +import { createUseCollection } from '@/stores/xen-api/create-use-collection' +import { defineStore } from 'pinia' -export const useHostMetricsStore = defineStore("xen-api-host-metrics", () => { - const context = useXenApiStoreSubscribableContext("host_metrics"); +export const useHostMetricsStore = defineStore('xen-api-host-metrics', () => { + const context = useXenApiStoreSubscribableContext('host_metrics') const getHostMemory = (host: XenApiHost) => { - const hostMetrics = context.getByOpaqueRef(host.metrics); + const hostMetrics = context.getByOpaqueRef(host.metrics) if (hostMetrics !== undefined) { - const total = +hostMetrics.memory_total; + const total = +hostMetrics.memory_total return { usage: total - +hostMetrics.memory_free, size: total, - }; + } } - }; + } const isHostRunning = (host: XenApiHost) => { - return context.getByOpaqueRef(host.metrics)?.live === true; - }; + return context.getByOpaqueRef(host.metrics)?.live === true + } return { ...context, getHostMemory, isHostRunning, - }; -}); + } +}) -export const useHostMetricsCollection = - createUseCollection(useHostMetricsStore); +export const useHostMetricsCollection = createUseCollection(useHostMetricsStore) diff --git a/@xen-orchestra/lite/src/stores/xen-api/host.store.ts b/@xen-orchestra/lite/src/stores/xen-api/host.store.ts index a1dc47ce42c..4dda5028e17 100644 --- a/@xen-orchestra/lite/src/stores/xen-api/host.store.ts +++ b/@xen-orchestra/lite/src/stores/xen-api/host.store.ts @@ -1,38 +1,29 @@ -import type { GetStats } from "@/composables/fetch-stats.composable"; -import { useXenApiStoreSubscribableContext } from "@/composables/xen-api-store-subscribable-context.composable"; -import type { XenApiHost } from "@/libs/xen-api/xen-api.types"; -import { useXenApiStore } from "@/stores/xen-api.store"; -import { createUseCollection } from "@/stores/xen-api/create-use-collection"; -import { useHostMetricsStore } from "@/stores/xen-api/host-metrics.store"; -import type { XenApiPatch } from "@/types/xen-api"; -import { defineStore } from "pinia"; -import { computed } from "vue"; +import type { GetStats } from '@/composables/fetch-stats.composable' +import { useXenApiStoreSubscribableContext } from '@/composables/xen-api-store-subscribable-context.composable' +import type { XenApiHost } from '@/libs/xen-api/xen-api.types' +import { useXenApiStore } from '@/stores/xen-api.store' +import { createUseCollection } from '@/stores/xen-api/create-use-collection' +import { useHostMetricsStore } from '@/stores/xen-api/host-metrics.store' +import type { XenApiPatch } from '@/types/xen-api' +import { defineStore } from 'pinia' +import { computed } from 'vue' -export const useHostStore = defineStore("xen-api-host", () => { - const hostMetricsStore = useHostMetricsStore(); +export const useHostStore = defineStore('xen-api-host', () => { + const hostMetricsStore = useHostMetricsStore() - const context = useXenApiStoreSubscribableContext("host", [hostMetricsStore]); + const context = useXenApiStoreSubscribableContext('host', [hostMetricsStore]) - const runningHosts = computed(() => - context.records.value.filter((host) => hostMetricsStore.isHostRunning(host)) - ); + const runningHosts = computed(() => context.records.value.filter(host => hostMetricsStore.isHostRunning(host))) - const getStats = (( - hostUuid, - granularity, - ignoreExpired = false, - { abortSignal } - ) => { - const xenApiStore = useXenApiStore(); - const host = context.getByUuid(hostUuid); + const getStats = ((hostUuid, granularity, ignoreExpired = false, { abortSignal }) => { + const xenApiStore = useXenApiStore() + const host = context.getByUuid(hostUuid) if (host === undefined) { - throw new Error(`Host ${hostUuid} could not be found.`); + throw new Error(`Host ${hostUuid} could not be found.`) } - const xapiStats = xenApiStore.isConnected - ? xenApiStore.getXapiStats() - : undefined; + const xapiStats = xenApiStore.isConnected ? xenApiStore.getXapiStats() : undefined return xapiStats?._getAndUpdateStats({ abortSignal, @@ -40,40 +31,30 @@ export const useHostStore = defineStore("xen-api-host", () => { ignoreExpired, uuid: host.uuid, granularity, - }); - }) as GetStats; + }) + }) as GetStats - const fetchMissingPatches = async ( - hostRef: XenApiHost["$ref"] - ): Promise => { - const xenApiStore = useXenApiStore(); + const fetchMissingPatches = async (hostRef: XenApiHost['$ref']): Promise => { + const xenApiStore = useXenApiStore() const rawPatchesAsString = await xenApiStore .getXapi() - .call("host.call_plugin", [ - hostRef, - "updater.py", - "check_update", - {}, - ]); + .call('host.call_plugin', [hostRef, 'updater.py', 'check_update', {}]) - const rawPatches = JSON.parse(rawPatchesAsString) as Omit< - XenApiPatch, - "$id" - >[]; + const rawPatches = JSON.parse(rawPatchesAsString) as Omit[] - return rawPatches.map((rawPatch) => ({ + return rawPatches.map(rawPatch => ({ ...rawPatch, $id: `${rawPatch.name}-${rawPatch.version}`, - })); - }; + })) + } return { ...context, runningHosts, getStats, fetchMissingPatches, - }; -}); + } +}) -export const useHostCollection = createUseCollection(useHostStore); +export const useHostCollection = createUseCollection(useHostStore) diff --git a/@xen-orchestra/lite/src/stores/xen-api/message.store.ts b/@xen-orchestra/lite/src/stores/xen-api/message.store.ts index f421e4a9877..cac9eee09a1 100644 --- a/@xen-orchestra/lite/src/stores/xen-api/message.store.ts +++ b/@xen-orchestra/lite/src/stores/xen-api/message.store.ts @@ -1,14 +1,14 @@ -import { useSubscriber } from "@/composables/subscriber.composable"; -import { useXenApiStore } from "@/stores/xen-api.store"; -import { defineStore } from "pinia"; +import { useSubscriber } from '@/composables/subscriber.composable' +import { useXenApiStore } from '@/stores/xen-api.store' +import { defineStore } from 'pinia' -export const useMessageStore = defineStore("xen-api-message", () => { - const xenApiStore = useXenApiStore(); +export const useMessageStore = defineStore('xen-api-message', () => { + const xenApiStore = useXenApiStore() return useSubscriber({ enabled: () => xenApiStore.isConnected, onSubscriptionStart: () => { - void xenApiStore.getXapi().loadRecords("message"); + void xenApiStore.getXapi().loadRecords('message') }, - }); -}); + }) +}) diff --git a/@xen-orchestra/lite/src/stores/xen-api/network.store.ts b/@xen-orchestra/lite/src/stores/xen-api/network.store.ts index 460aa279a56..662e73ae45e 100644 --- a/@xen-orchestra/lite/src/stores/xen-api/network.store.ts +++ b/@xen-orchestra/lite/src/stores/xen-api/network.store.ts @@ -1,9 +1,9 @@ -import { useXenApiStoreSubscribableContext } from "@/composables/xen-api-store-subscribable-context.composable"; -import { createUseCollection } from "@/stores/xen-api/create-use-collection"; -import { defineStore } from "pinia"; +import { useXenApiStoreSubscribableContext } from '@/composables/xen-api-store-subscribable-context.composable' +import { createUseCollection } from '@/stores/xen-api/create-use-collection' +import { defineStore } from 'pinia' -export const useNetworkStore = defineStore("xen-api-network", () => { - return useXenApiStoreSubscribableContext("network"); -}); +export const useNetworkStore = defineStore('xen-api-network', () => { + return useXenApiStoreSubscribableContext('network') +}) -export const useNetworkCollection = createUseCollection(useNetworkStore); +export const useNetworkCollection = createUseCollection(useNetworkStore) diff --git a/@xen-orchestra/lite/src/stores/xen-api/pool.store.ts b/@xen-orchestra/lite/src/stores/xen-api/pool.store.ts index 46869d01097..b81cb10ba57 100644 --- a/@xen-orchestra/lite/src/stores/xen-api/pool.store.ts +++ b/@xen-orchestra/lite/src/stores/xen-api/pool.store.ts @@ -1,18 +1,18 @@ -import { useXenApiStoreSubscribableContext } from "@/composables/xen-api-store-subscribable-context.composable"; -import type { XenApiPool } from "@/libs/xen-api/xen-api.types"; -import { createUseCollection } from "@/stores/xen-api/create-use-collection"; -import { defineStore } from "pinia"; -import { computed } from "vue"; +import { useXenApiStoreSubscribableContext } from '@/composables/xen-api-store-subscribable-context.composable' +import type { XenApiPool } from '@/libs/xen-api/xen-api.types' +import { createUseCollection } from '@/stores/xen-api/create-use-collection' +import { defineStore } from 'pinia' +import { computed } from 'vue' -export const usePoolStore = defineStore("xen-api-pool", () => { - const context = useXenApiStoreSubscribableContext("pool"); +export const usePoolStore = defineStore('xen-api-pool', () => { + const context = useXenApiStoreSubscribableContext('pool') - const pool = computed(() => context.records.value[0]); + const pool = computed(() => context.records.value[0]) return { ...context, pool, - }; -}); + } +}) -export const usePoolCollection = createUseCollection(usePoolStore); +export const usePoolCollection = createUseCollection(usePoolStore) diff --git a/@xen-orchestra/lite/src/stores/xen-api/sr.store.ts b/@xen-orchestra/lite/src/stores/xen-api/sr.store.ts index ac401961547..dfa9e08d75f 100644 --- a/@xen-orchestra/lite/src/stores/xen-api/sr.store.ts +++ b/@xen-orchestra/lite/src/stores/xen-api/sr.store.ts @@ -1,9 +1,9 @@ -import { useXenApiStoreSubscribableContext } from "@/composables/xen-api-store-subscribable-context.composable"; -import { createUseCollection } from "@/stores/xen-api/create-use-collection"; -import { defineStore } from "pinia"; +import { useXenApiStoreSubscribableContext } from '@/composables/xen-api-store-subscribable-context.composable' +import { createUseCollection } from '@/stores/xen-api/create-use-collection' +import { defineStore } from 'pinia' -export const useSrStore = defineStore("xen-api-sr", () => { - return useXenApiStoreSubscribableContext("sr"); -}); +export const useSrStore = defineStore('xen-api-sr', () => { + return useXenApiStoreSubscribableContext('sr') +}) -export const useSrCollection = createUseCollection(useSrStore); +export const useSrCollection = createUseCollection(useSrStore) diff --git a/@xen-orchestra/lite/src/stores/xen-api/task.store.ts b/@xen-orchestra/lite/src/stores/xen-api/task.store.ts index c7b63102ffb..ca74743736e 100644 --- a/@xen-orchestra/lite/src/stores/xen-api/task.store.ts +++ b/@xen-orchestra/lite/src/stores/xen-api/task.store.ts @@ -1,52 +1,42 @@ -import useArrayRemovedItemsHistory from "@/composables/array-removed-items-history.composable"; -import useCollectionFilter from "@/composables/collection-filter.composable"; -import useCollectionSorter from "@/composables/collection-sorter.composable"; -import useFilteredCollection from "@/composables/filtered-collection.composable"; -import useSortedCollection from "@/composables/sorted-collection.composable"; -import { useXenApiStoreSubscribableContext } from "@/composables/xen-api-store-subscribable-context.composable"; -import type { XenApiTask } from "@/libs/xen-api/xen-api.types"; -import { createUseCollection } from "@/stores/xen-api/create-use-collection"; -import { defineStore } from "pinia"; - -export const useTaskStore = defineStore("xen-api-task", () => { - const context = useXenApiStoreSubscribableContext("task"); +import useArrayRemovedItemsHistory from '@/composables/array-removed-items-history.composable' +import useCollectionFilter from '@/composables/collection-filter.composable' +import useCollectionSorter from '@/composables/collection-sorter.composable' +import useFilteredCollection from '@/composables/filtered-collection.composable' +import useSortedCollection from '@/composables/sorted-collection.composable' +import { useXenApiStoreSubscribableContext } from '@/composables/xen-api-store-subscribable-context.composable' +import type { XenApiTask } from '@/libs/xen-api/xen-api.types' +import { createUseCollection } from '@/stores/xen-api/create-use-collection' +import { defineStore } from 'pinia' + +export const useTaskStore = defineStore('xen-api-task', () => { + const context = useXenApiStoreSubscribableContext('task') const { compareFn } = useCollectionSorter({ - initialSorts: ["-created"], - }); + initialSorts: ['-created'], + }) const { predicate } = useCollectionFilter({ - initialFilters: [ - "!name_label:|(SR.scan host.call_plugin)", - "status:pending", - ], - }); - - const sortedTasks = useSortedCollection(context.records, compareFn); - - const pendingTasks = useFilteredCollection( - sortedTasks, - predicate - ); - - const finishedTasks = useArrayRemovedItemsHistory( - sortedTasks, - (task) => task.uuid, - { - limit: 50, - onRemove: (tasks) => - tasks.map((task) => ({ - ...task, - finished: new Date().toISOString(), - })), - } - ); + initialFilters: ['!name_label:|(SR.scan host.call_plugin)', 'status:pending'], + }) + + const sortedTasks = useSortedCollection(context.records, compareFn) + + const pendingTasks = useFilteredCollection(sortedTasks, predicate) + + const finishedTasks = useArrayRemovedItemsHistory(sortedTasks, task => task.uuid, { + limit: 50, + onRemove: tasks => + tasks.map(task => ({ + ...task, + finished: new Date().toISOString(), + })), + }) return { ...context, pendingTasks, finishedTasks: useSortedCollection(finishedTasks, compareFn), - }; -}); + } +}) -export const useTaskCollection = createUseCollection(useTaskStore); +export const useTaskCollection = createUseCollection(useTaskStore) diff --git a/@xen-orchestra/lite/src/stores/xen-api/vm-metrics.store.ts b/@xen-orchestra/lite/src/stores/xen-api/vm-metrics.store.ts index 163266b6a15..2c735037fba 100644 --- a/@xen-orchestra/lite/src/stores/xen-api/vm-metrics.store.ts +++ b/@xen-orchestra/lite/src/stores/xen-api/vm-metrics.store.ts @@ -1,9 +1,9 @@ -import { useXenApiStoreSubscribableContext } from "@/composables/xen-api-store-subscribable-context.composable"; -import { createUseCollection } from "@/stores/xen-api/create-use-collection"; -import { defineStore } from "pinia"; +import { useXenApiStoreSubscribableContext } from '@/composables/xen-api-store-subscribable-context.composable' +import { createUseCollection } from '@/stores/xen-api/create-use-collection' +import { defineStore } from 'pinia' -export const useVmMetricsStore = defineStore("xen-api-vm-metrics", () => { - return useXenApiStoreSubscribableContext("vm_metrics"); -}); +export const useVmMetricsStore = defineStore('xen-api-vm-metrics', () => { + return useXenApiStoreSubscribableContext('vm_metrics') +}) -export const useVmMetricsCollection = createUseCollection(useVmMetricsStore); +export const useVmMetricsCollection = createUseCollection(useVmMetricsStore) diff --git a/@xen-orchestra/lite/src/stores/xen-api/vm.store.ts b/@xen-orchestra/lite/src/stores/xen-api/vm.store.ts index 4ccfbf0c678..cca01e16e2d 100644 --- a/@xen-orchestra/lite/src/stores/xen-api/vm.store.ts +++ b/@xen-orchestra/lite/src/stores/xen-api/vm.store.ts @@ -1,93 +1,71 @@ -import type { GetStats } from "@/composables/fetch-stats.composable"; -import { useXenApiStoreSubscribableContext } from "@/composables/xen-api-store-subscribable-context.composable"; -import { sortRecordsByNameLabel } from "@/libs/utils"; -import type { VmStats } from "@/libs/xapi-stats"; -import type { XenApiHost, XenApiVm } from "@/libs/xen-api/xen-api.types"; -import { - type VM_OPERATION, - VM_POWER_STATE, -} from "@/libs/xen-api/xen-api.enums"; -import { useXenApiStore } from "@/stores/xen-api.store"; -import { createUseCollection } from "@/stores/xen-api/create-use-collection"; -import { useHostStore } from "@/stores/xen-api/host.store"; -import { castArray } from "lodash-es"; -import { defineStore } from "pinia"; -import { computed } from "vue"; - -export const useVmStore = defineStore("xen-api-vm", () => { - const context = useXenApiStoreSubscribableContext("vm"); +import type { GetStats } from '@/composables/fetch-stats.composable' +import { useXenApiStoreSubscribableContext } from '@/composables/xen-api-store-subscribable-context.composable' +import { sortRecordsByNameLabel } from '@/libs/utils' +import type { VmStats } from '@/libs/xapi-stats' +import type { XenApiHost, XenApiVm } from '@/libs/xen-api/xen-api.types' +import { type VM_OPERATION, VM_POWER_STATE } from '@/libs/xen-api/xen-api.enums' +import { useXenApiStore } from '@/stores/xen-api.store' +import { createUseCollection } from '@/stores/xen-api/create-use-collection' +import { useHostStore } from '@/stores/xen-api/host.store' +import { castArray } from 'lodash-es' +import { defineStore } from 'pinia' +import { computed } from 'vue' + +export const useVmStore = defineStore('xen-api-vm', () => { + const context = useXenApiStoreSubscribableContext('vm') const records = computed(() => context.records.value - .filter( - (vm) => !vm.is_a_snapshot && !vm.is_a_template && !vm.is_control_domain - ) + .filter(vm => !vm.is_a_snapshot && !vm.is_a_template && !vm.is_control_domain) .sort(sortRecordsByNameLabel) - ); - - const isOperationPending = ( - vm: XenApiVm, - operations: VM_OPERATION[] | VM_OPERATION - ) => { - const currentOperations = Object.values(vm.current_operations); - - return castArray(operations).some((operation) => - currentOperations.includes(operation) - ); - }; - - const areSomeOperationAllowed = ( - vm: XenApiVm, - operations: VM_OPERATION[] | VM_OPERATION - ) => { - const allowedOperations = Object.values(vm.allowed_operations); - - return castArray(operations).some((operation) => - allowedOperations.includes(operation) - ); - }; - - const runningVms = computed(() => - records.value.filter((vm) => vm.power_state === VM_POWER_STATE.RUNNING) - ); + ) + + const isOperationPending = (vm: XenApiVm, operations: VM_OPERATION[] | VM_OPERATION) => { + const currentOperations = Object.values(vm.current_operations) + + return castArray(operations).some(operation => currentOperations.includes(operation)) + } + + const areSomeOperationAllowed = (vm: XenApiVm, operations: VM_OPERATION[] | VM_OPERATION) => { + const allowedOperations = Object.values(vm.allowed_operations) + + return castArray(operations).some(operation => allowedOperations.includes(operation)) + } + + const runningVms = computed(() => records.value.filter(vm => vm.power_state === VM_POWER_STATE.RUNNING)) const recordsByHostRef = computed(() => { - const vmsByHostOpaqueRef = new Map(); + const vmsByHostOpaqueRef = new Map() - records.value.forEach((vm) => { + records.value.forEach(vm => { if (!vmsByHostOpaqueRef.has(vm.resident_on)) { - vmsByHostOpaqueRef.set(vm.resident_on, []); + vmsByHostOpaqueRef.set(vm.resident_on, []) } - vmsByHostOpaqueRef.get(vm.resident_on)?.push(vm); - }); + vmsByHostOpaqueRef.get(vm.resident_on)?.push(vm) + }) - return vmsByHostOpaqueRef; - }); - const getStats = (( - id, - granularity, - ignoreExpired = false, - { abortSignal } - ) => { - const xenApiStore = useXenApiStore(); + return vmsByHostOpaqueRef + }) + const getStats = ((id, granularity, ignoreExpired = false, { abortSignal }) => { + const xenApiStore = useXenApiStore() if (!xenApiStore.isConnected) { - return undefined; + return undefined } - const vm = context.getByUuid(id); + const vm = context.getByUuid(id) if (vm === undefined) { - throw new Error(`VM ${id} could not be found.`); + throw new Error(`VM ${id} could not be found.`) } - const hostStore = useHostStore(); + const hostStore = useHostStore() - const host = hostStore.getByOpaqueRef(vm.resident_on); + const host = hostStore.getByOpaqueRef(vm.resident_on) if (host === undefined) { - throw new Error(`VM ${id} is halted or host could not be found.`); + throw new Error(`VM ${id} is halted or host could not be found.`) } return xenApiStore.getXapiStats()._getAndUpdateStats({ @@ -96,8 +74,8 @@ export const useVmStore = defineStore("xen-api-vm", () => { ignoreExpired, uuid: vm.uuid, granularity, - }); - }) as GetStats; + }) + }) as GetStats return { ...context, @@ -107,7 +85,7 @@ export const useVmStore = defineStore("xen-api-vm", () => { runningVms, recordsByHostRef, getStats, - }; -}); + } +}) -export const useVmCollection = createUseCollection(useVmStore); +export const useVmCollection = createUseCollection(useVmStore) diff --git a/@xen-orchestra/lite/src/stories/button/ui-button-group.story.vue b/@xen-orchestra/lite/src/stories/button/ui-button-group.story.vue index 517c15749d2..3e9ebd57e21 100644 --- a/@xen-orchestra/lite/src/stories/button/ui-button-group.story.vue +++ b/@xen-orchestra/lite/src/stories/button/ui-button-group.story.vue @@ -1,5 +1,6 @@ diff --git a/@xen-orchestra/lite/src/stories/button/ui-button.story.vue b/@xen-orchestra/lite/src/stories/button/ui-button.story.vue index 6b89fba21a3..dab07da595b 100644 --- a/@xen-orchestra/lite/src/stories/button/ui-button.story.vue +++ b/@xen-orchestra/lite/src/stories/button/ui-button.story.vue @@ -38,10 +38,10 @@ diff --git a/@xen-orchestra/lite/src/stories/form/form-byte-size.story.vue b/@xen-orchestra/lite/src/stories/form/form-byte-size.story.vue index 6df2d16e75e..c065f3a0ddc 100644 --- a/@xen-orchestra/lite/src/stories/form/form-byte-size.story.vue +++ b/@xen-orchestra/lite/src/stories/form/form-byte-size.story.vue @@ -1,16 +1,14 @@ diff --git a/@xen-orchestra/lite/src/stories/form/form-input-group.story.vue b/@xen-orchestra/lite/src/stories/form/form-input-group.story.vue index 26b9dbb78a8..5c4bf5ff2ea 100644 --- a/@xen-orchestra/lite/src/stories/form/form-input-group.story.vue +++ b/@xen-orchestra/lite/src/stories/form/form-input-group.story.vue @@ -1,7 +1,5 @@ diff --git a/@xen-orchestra/lite/src/stories/form/form-input-wrapper.story.vue b/@xen-orchestra/lite/src/stories/form/form-input-wrapper.story.vue index 9aeb67cb6c9..78e57a3b6a8 100644 --- a/@xen-orchestra/lite/src/stories/form/form-input-wrapper.story.vue +++ b/@xen-orchestra/lite/src/stories/form/form-input-wrapper.story.vue @@ -20,11 +20,11 @@ diff --git a/@xen-orchestra/lite/src/stories/form/form-input.story.vue b/@xen-orchestra/lite/src/stories/form/form-input.story.vue index 328160e0a1d..3a644b5d539 100644 --- a/@xen-orchestra/lite/src/stories/form/form-input.story.vue +++ b/@xen-orchestra/lite/src/stories/form/form-input.story.vue @@ -1,5 +1,6 @@ diff --git a/@xen-orchestra/lite/src/stories/form/form-section.story.vue b/@xen-orchestra/lite/src/stories/form/form-section.story.vue index c002503d085..739c5e8378d 100644 --- a/@xen-orchestra/lite/src/stories/form/form-section.story.vue +++ b/@xen-orchestra/lite/src/stories/form/form-section.story.vue @@ -4,7 +4,7 @@ :params="[ prop('label').required().str().preset('Install settings').widget(), prop('collapsible').bool().widget(), - model('collapsed').prop((p) => p.bool()), + model('collapsed').prop(p => p.bool()), slot(), ]" > @@ -15,10 +15,10 @@ diff --git a/@xen-orchestra/lite/src/stories/linear-chart.story.md b/@xen-orchestra/lite/src/stories/linear-chart.story.md index d601a529cb7..1953a0fbcc2 100644 --- a/@xen-orchestra/lite/src/stories/linear-chart.story.md +++ b/@xen-orchestra/lite/src/stories/linear-chart.story.md @@ -4,12 +4,12 @@ ```typescript type LinearChartData = { - label: string; + label: string data: { - timestamp: number; - value: number; - }[]; -}[]; + timestamp: number + value: number + }[] +}[] ``` ### Example diff --git a/@xen-orchestra/lite/src/stories/linear-chart.story.vue b/@xen-orchestra/lite/src/stories/linear-chart.story.vue index 0c89cf2dc73..7840b37f4f9 100644 --- a/@xen-orchestra/lite/src/stories/linear-chart.story.vue +++ b/@xen-orchestra/lite/src/stories/linear-chart.story.vue @@ -1,38 +1,34 @@ diff --git a/@xen-orchestra/lite/src/stories/modals/layouts/basic-modal-layout.story.vue b/@xen-orchestra/lite/src/stories/modals/layouts/basic-modal-layout.story.vue index 610952092df..1685911b2cd 100644 --- a/@xen-orchestra/lite/src/stories/modals/layouts/basic-modal-layout.story.vue +++ b/@xen-orchestra/lite/src/stories/modals/layouts/basic-modal-layout.story.vue @@ -1,12 +1,7 @@ diff --git a/@xen-orchestra/lite/src/stories/modals/layouts/confirm-modal-layout.story.vue b/@xen-orchestra/lite/src/stories/modals/layouts/confirm-modal-layout.story.vue index 44d8a593606..b86e2aa5302 100644 --- a/@xen-orchestra/lite/src/stories/modals/layouts/confirm-modal-layout.story.vue +++ b/@xen-orchestra/lite/src/stories/modals/layouts/confirm-modal-layout.story.vue @@ -23,9 +23,9 @@ diff --git a/@xen-orchestra/lite/src/stories/modals/layouts/form-modal-layout.story.vue b/@xen-orchestra/lite/src/stories/modals/layouts/form-modal-layout.story.vue index f82f024c385..3f5681b4ae9 100644 --- a/@xen-orchestra/lite/src/stories/modals/layouts/form-modal-layout.story.vue +++ b/@xen-orchestra/lite/src/stories/modals/layouts/form-modal-layout.story.vue @@ -1,25 +1,14 @@ diff --git a/@xen-orchestra/lite/src/stories/modals/modal-container.story.vue b/@xen-orchestra/lite/src/stories/modals/modal-container.story.vue index cf7ee47fbd3..5737fc062dd 100644 --- a/@xen-orchestra/lite/src/stories/modals/modal-container.story.vue +++ b/@xen-orchestra/lite/src/stories/modals/modal-container.story.vue @@ -6,22 +6,10 @@ slot('header'), slot(), slot('footer'), - setting('headerSlotContent') - .preset('Header') - .widget(text()) - .help('Content for default slot'), - setting('defaultSlotContent') - .preset('Content') - .widget(text()) - .help('Content for default slot'), - setting('footerSlotContent') - .preset('Footer') - .widget(text()) - .help('Content for default slot'), - setting('showNested') - .preset(false) - .widget(boolean()) - .help('Show nested modal'), + setting('headerSlotContent').preset('Header').widget(text()).help('Content for default slot'), + setting('defaultSlotContent').preset('Content').widget(text()).help('Content for default slot'), + setting('footerSlotContent').preset('Footer').widget(text()).help('Content for default slot'), + setting('showNested').preset(false).widget(boolean()).help('Show nested modal'), ]" > @@ -31,9 +19,7 @@ diff --git a/@xen-orchestra/lite/src/stories/power-state-icon.story.vue b/@xen-orchestra/lite/src/stories/power-state-icon.story.vue index 8606b1d792e..5b65cff6e8c 100644 --- a/@xen-orchestra/lite/src/stories/power-state-icon.story.vue +++ b/@xen-orchestra/lite/src/stories/power-state-icon.story.vue @@ -1,5 +1,6 @@ diff --git a/@xen-orchestra/lite/src/stories/progress-circle.story.vue b/@xen-orchestra/lite/src/stories/progress-circle.story.vue index 2229ddd40d1..7e468ea2d60 100644 --- a/@xen-orchestra/lite/src/stories/progress-circle.story.vue +++ b/@xen-orchestra/lite/src/stories/progress-circle.story.vue @@ -1,35 +1,32 @@ diff --git a/@xen-orchestra/lite/src/stories/tab-bar/ui-tab-bar.story.vue b/@xen-orchestra/lite/src/stories/tab-bar/ui-tab-bar.story.vue index 783fb4b397a..4c25328a427 100644 --- a/@xen-orchestra/lite/src/stories/tab-bar/ui-tab-bar.story.vue +++ b/@xen-orchestra/lite/src/stories/tab-bar/ui-tab-bar.story.vue @@ -1,10 +1,7 @@ diff --git a/@xen-orchestra/lite/src/stories/tab-bar/ui-tab.story.vue b/@xen-orchestra/lite/src/stories/tab-bar/ui-tab.story.vue index 524d27e3dd2..a389cc574ec 100644 --- a/@xen-orchestra/lite/src/stories/tab-bar/ui-tab.story.vue +++ b/@xen-orchestra/lite/src/stories/tab-bar/ui-tab.story.vue @@ -16,11 +16,11 @@ diff --git a/@xen-orchestra/lite/src/stories/ui-badge.story.vue b/@xen-orchestra/lite/src/stories/ui-badge.story.vue index 8af9c5b32cd..bbfdfe179bd 100644 --- a/@xen-orchestra/lite/src/stories/ui-badge.story.vue +++ b/@xen-orchestra/lite/src/stories/ui-badge.story.vue @@ -1,14 +1,14 @@ diff --git a/@xen-orchestra/lite/src/stories/ui-filter.story.vue b/@xen-orchestra/lite/src/stories/ui-filter.story.vue index e0d63d3f084..3d57b2a37ae 100644 --- a/@xen-orchestra/lite/src/stories/ui-filter.story.vue +++ b/@xen-orchestra/lite/src/stories/ui-filter.story.vue @@ -1,22 +1,17 @@ diff --git a/@xen-orchestra/lite/src/stories/ui-resources/ui-resource.story.vue b/@xen-orchestra/lite/src/stories/ui-resources/ui-resource.story.vue index a96731cff46..fed9fb590b7 100644 --- a/@xen-orchestra/lite/src/stories/ui-resources/ui-resource.story.vue +++ b/@xen-orchestra/lite/src/stories/ui-resources/ui-resource.story.vue @@ -4,11 +4,7 @@ :params="[ iconProp().preset(faRocket), prop('label').required().str().widget().preset('Rockets'), - prop('count') - .required() - .type('string | number') - .widget(text()) - .preset('175'), + prop('count').required().type('string | number').widget(text()).preset('175'), ]" :presets="presets" > @@ -17,10 +13,10 @@ diff --git a/@xen-orchestra/lite/src/stories/ui-resources/ui-resources.story.vue b/@xen-orchestra/lite/src/stories/ui-resources/ui-resources.story.vue index 3864cccb55a..67ccb022548 100644 --- a/@xen-orchestra/lite/src/stories/ui-resources/ui-resources.story.vue +++ b/@xen-orchestra/lite/src/stories/ui-resources/ui-resources.story.vue @@ -1,8 +1,5 @@ diff --git a/@xen-orchestra/lite/src/types/chart.ts b/@xen-orchestra/lite/src/types/chart.ts index 6958af099f7..f9fb8673343 100644 --- a/@xen-orchestra/lite/src/types/chart.ts +++ b/@xen-orchestra/lite/src/types/chart.ts @@ -1,9 +1,9 @@ export type LinearChartData = { - label: string; + label: string data: { - timestamp: number; - value: number; - }[]; -}[]; + timestamp: number + value: number + }[] +}[] -export type ValueFormatter = (value: number) => string; +export type ValueFormatter = (value: number) => string diff --git a/@xen-orchestra/lite/src/types/complex-matcher.d.ts b/@xen-orchestra/lite/src/types/complex-matcher.d.ts index a5da63a699e..7632c2161c0 100644 --- a/@xen-orchestra/lite/src/types/complex-matcher.d.ts +++ b/@xen-orchestra/lite/src/types/complex-matcher.d.ts @@ -1,89 +1,85 @@ -declare module "complex-matcher" { - type ComparisonOperator = ">" | ">=" | "<" | "<="; +declare module 'complex-matcher' { + type ComparisonOperator = '>' | '>=' | '<' | '<=' class ComplexMatcherNode { - createPredicate(): (value) => boolean; + createPredicate(): (value) => boolean } class Null extends ComplexMatcherNode { - match(): true; - toString(): ""; + match(): true + toString(): '' } class And extends ComplexMatcherNode { - constructor(children: ComplexMatcherNode[]); - match(value: any): boolean; - toString(isNested?: boolean): string; - children: ComplexMatcherNode[]; + constructor(children: ComplexMatcherNode[]) + match(value: any): boolean + toString(isNested?: boolean): string + children: ComplexMatcherNode[] } class Comparison extends ComplexMatcherNode { - constructor(operator: ComparisonOperator, value: number); - match(value: any): boolean; - toString(): string; - _operator: ComparisonOperator; - _value: number; + constructor(operator: ComparisonOperator, value: number) + match(value: any): boolean + toString(): string + _operator: ComparisonOperator + _value: number } class Or extends ComplexMatcherNode { - constructor(children: ComplexMatcherNode[]); - match(value: any): boolean; - toString(): string; - children: ComplexMatcherNode[]; + constructor(children: ComplexMatcherNode[]) + match(value: any): boolean + toString(): string + children: ComplexMatcherNode[] } class Not extends ComplexMatcherNode { - constructor(child: ComplexMatcherNode); - match(value: any): boolean; - toString(): string; - child: ComplexMatcherNode; + constructor(child: ComplexMatcherNode) + match(value: any): boolean + toString(): string + child: ComplexMatcherNode } class Number extends ComplexMatcherNode { - constructor(value: number); - match(value: any): boolean; - toString(): string; - value: number; + constructor(value: number) + match(value: any): boolean + toString(): string + value: number } class Property extends ComplexMatcherNode { - constructor(name: string, child: ComplexMatcherNode); - match(value: any): boolean; - toString(): string; - name: string; - child: ComplexMatcherNode; + constructor(name: string, child: ComplexMatcherNode) + match(value: any): boolean + toString(): string + name: string + child: ComplexMatcherNode } class GlobPattern extends ComplexMatcherNode { - constructor(value: string); - match(re: RegExp, value: any): boolean; - toString(): string; - value: string; + constructor(value: string) + match(re: RegExp, value: any): boolean + toString(): string + value: string } class RegExpNode extends ComplexMatcherNode { - constructor(pattern: string, flags: string); - match(value: any): boolean; - toString(): string; - re: RegExp; + constructor(pattern: string, flags: string) + match(value: any): boolean + toString(): string + re: RegExp } class StringNode extends ComplexMatcherNode { - constructor(value: string); - match(lcValue: string, value: any): boolean; - toString(): string; - value: string; + constructor(value: string) + match(lcValue: string, value: any): boolean + toString(): string + value: string } class TruthyProperty extends ComplexMatcherNode { - constructor(name: string); - match(value: any): boolean; - toString(): string; + constructor(name: string) + match(value: any): boolean + toString(): string } - function parse( - input: string, - pos? = 0, - end?: input.length - ): ComplexMatcherNode; + function parse(input: string, pos? = 0, end?: input.length): ComplexMatcherNode } diff --git a/@xen-orchestra/lite/src/types/decorator-synchronized.d.ts b/@xen-orchestra/lite/src/types/decorator-synchronized.d.ts index fd246e7ff8f..3e0fca0d457 100644 --- a/@xen-orchestra/lite/src/types/decorator-synchronized.d.ts +++ b/@xen-orchestra/lite/src/types/decorator-synchronized.d.ts @@ -1,3 +1,3 @@ -declare module "decorator-synchronized" { - export const synchronized: any; +declare module 'decorator-synchronized' { + export const synchronized: any } diff --git a/@xen-orchestra/lite/src/types/filter.ts b/@xen-orchestra/lite/src/types/filter.ts index eb1cfcde6ca..88622b20b49 100644 --- a/@xen-orchestra/lite/src/types/filter.ts +++ b/@xen-orchestra/lite/src/types/filter.ts @@ -1,58 +1,58 @@ -import type { IconDefinition } from "@fortawesome/fontawesome-common-types"; +import type { IconDefinition } from '@fortawesome/fontawesome-common-types' -export type FilterType = "string" | "boolean" | "number" | "enum"; +export type FilterType = 'string' | 'boolean' | 'number' | 'enum' export type FilterComparisonType = - | "stringContains" - | "stringDoesNotContains" - | "stringEquals" - | "stringDoesNotEqual" - | "stringStartsWith" - | "stringDoesNotStartWith" - | "stringEndsWith" - | "stringDoesNotEndWith" - | "stringMatchesRegex" - | "stringDoesNotMatchRegex" - | "numberLessThan" - | "numberLessThanOrEquals" - | "numberEquals" - | "numberGreaterThanOrEquals" - | "numberGreaterThan" - | "booleanTrue" - | "booleanFalse" - | "enumIs" - | "enumIsNot"; + | 'stringContains' + | 'stringDoesNotContains' + | 'stringEquals' + | 'stringDoesNotEqual' + | 'stringStartsWith' + | 'stringDoesNotStartWith' + | 'stringEndsWith' + | 'stringDoesNotEndWith' + | 'stringMatchesRegex' + | 'stringDoesNotMatchRegex' + | 'numberLessThan' + | 'numberLessThanOrEquals' + | 'numberEquals' + | 'numberGreaterThanOrEquals' + | 'numberGreaterThan' + | 'booleanTrue' + | 'booleanFalse' + | 'enumIs' + | 'enumIsNot' export type FilterComparisons = { - [key in FilterComparisonType]?: string; -}; + [key in FilterComparisonType]?: string +} interface FilterCommon { - label?: string; - icon?: IconDefinition; + label?: string + icon?: IconDefinition } export interface FilterEnum extends FilterCommon { - type: "enum"; - choices: string[]; + type: 'enum' + choices: string[] } interface FilterOther extends FilterCommon { - type: Exclude; + type: Exclude } -export type Filter = FilterEnum | FilterOther; +export type Filter = FilterEnum | FilterOther -export type Filters = { [key: string]: Filter }; +export type Filters = { [key: string]: Filter } export interface NewFilter { - id: number; - content: string; - isAdvanced: boolean; + id: number + content: string + isAdvanced: boolean builder: { - property: string; - comparison: FilterComparisonType | ""; - value: string; - negate: boolean; - }; + property: string + comparison: FilterComparisonType | '' + value: string + negate: boolean + } } diff --git a/@xen-orchestra/lite/src/types/index.ts b/@xen-orchestra/lite/src/types/index.ts index 48052e40128..50851579b80 100644 --- a/@xen-orchestra/lite/src/types/index.ts +++ b/@xen-orchestra/lite/src/types/index.ts @@ -1,10 +1,10 @@ -export type Color = "info" | "error" | "warning" | "success"; +export type Color = 'info' | 'error' | 'warning' | 'success' export type ModalController = { - id: symbol; - component: any; - props: object; - approve:

(payload?: P) => void; - decline: () => void; - isBusy: boolean; -}; + id: symbol + component: any + props: object + approve:

(payload?: P) => void + decline: () => void + isBusy: boolean +} diff --git a/@xen-orchestra/lite/src/types/injection-keys.ts b/@xen-orchestra/lite/src/types/injection-keys.ts index d9c830c2a79..da475d5a335 100644 --- a/@xen-orchestra/lite/src/types/injection-keys.ts +++ b/@xen-orchestra/lite/src/types/injection-keys.ts @@ -1,56 +1,42 @@ -import type { FetchedStats, Stat } from "@/composables/fetch-stats.composable"; -import type { HostStats, VmStats } from "@/libs/xapi-stats"; -import type { XenApiHost } from "@/libs/xen-api/xen-api.types"; -import type { ValueFormatter } from "@/types/chart"; -import type { ModalController } from "@/types/index"; -import type { ComputedRef, InjectionKey } from "vue"; +import type { FetchedStats, Stat } from '@/composables/fetch-stats.composable' +import type { HostStats, VmStats } from '@/libs/xapi-stats' +import type { XenApiHost } from '@/libs/xen-api/xen-api.types' +import type { ValueFormatter } from '@/types/chart' +import type { ModalController } from '@/types/index' +import type { ComputedRef, InjectionKey } from 'vue' -export const IK_MENU_TELEPORTED = Symbol() as InjectionKey; +export const IK_MENU_TELEPORTED = Symbol('IK_MENU_TELEPORTED') as InjectionKey -export const IK_CHART_VALUE_FORMATTER = Symbol() as InjectionKey< - ComputedRef ->; +export const IK_CHART_VALUE_FORMATTER = Symbol('IK_CHART_VALUE_FORMATTER') as InjectionKey> -export const IK_INPUT_TYPE = Symbol() as InjectionKey<"select" | "textarea">; +export const IK_INPUT_TYPE = Symbol('IK_INPUT_TYPE') as InjectionKey<'select' | 'textarea'> -export const IK_CHECKBOX_TYPE = Symbol() as InjectionKey< - "checkbox" | "radio" | "toggle" ->; +export const IK_CHECKBOX_TYPE = Symbol('IK_CHECKBOX_TYPE') as InjectionKey<'checkbox' | 'radio' | 'toggle'> -export const IK_FORM_HAS_LABEL = Symbol() as InjectionKey>; +export const IK_FORM_HAS_LABEL = Symbol('IK_FORM_HAS_LABEL') as InjectionKey> -export const IK_MENU_HORIZONTAL = Symbol() as InjectionKey< - ComputedRef ->; +export const IK_MENU_HORIZONTAL = Symbol('IK_MENU_HORIZONTAL') as InjectionKey> -export const IK_CLOSE_MENU = Symbol() as InjectionKey<() => void>; +export const IK_CLOSE_MENU = Symbol('IK_CLOSE_MENU') as InjectionKey<() => void> -export const IK_HOST_STATS = Symbol() as InjectionKey< - ComputedRef[]> ->; +export const IK_HOST_STATS = Symbol('IK_HOST_STATS') as InjectionKey[]>> -export const IK_VM_STATS = Symbol() as InjectionKey< - ComputedRef[]> ->; +export const IK_VM_STATS = Symbol('IK_VM_STATS') as InjectionKey[]>> -export const IK_HOST_LAST_WEEK_STATS = Symbol() as InjectionKey< +export const IK_HOST_LAST_WEEK_STATS = Symbol('IK_HOST_LAST_WEEK_STATS') as InjectionKey< FetchedStats ->; +> -export const IK_BUTTON_GROUP_OUTLINED = Symbol() as InjectionKey< - ComputedRef ->; +export const IK_BUTTON_GROUP_OUTLINED = Symbol('IK_BUTTON_GROUP_OUTLINED') as InjectionKey> -export const IK_BUTTON_GROUP_TRANSPARENT = Symbol() as InjectionKey< - ComputedRef ->; +export const IK_BUTTON_GROUP_TRANSPARENT = Symbol('IK_BUTTON_GROUP_TRANSPARENT') as InjectionKey> -export const IK_CARD_GROUP_VERTICAL = Symbol() as InjectionKey; +export const IK_CARD_GROUP_VERTICAL = Symbol('IK_CARD_GROUP_VERTICAL') as InjectionKey -export const IK_INPUT_ID = Symbol() as InjectionKey>; +export const IK_INPUT_ID = Symbol('IK_INPUT_ID') as InjectionKey> -export const IK_MODAL_CLOSE = Symbol() as InjectionKey<() => void>; +export const IK_MODAL_CLOSE = Symbol('IK_MODAL_CLOSE') as InjectionKey<() => void> -export const IK_MODAL_NESTED = Symbol() as InjectionKey; +export const IK_MODAL_NESTED = Symbol('IK_MODAL_NESTED') as InjectionKey -export const IK_MODAL = Symbol() as InjectionKey; +export const IK_MODAL = Symbol('IK_MODAL') as InjectionKey diff --git a/@xen-orchestra/lite/src/types/iterable-backoff.d.ts b/@xen-orchestra/lite/src/types/iterable-backoff.d.ts index d19a804e468..f25af5b37e3 100644 --- a/@xen-orchestra/lite/src/types/iterable-backoff.d.ts +++ b/@xen-orchestra/lite/src/types/iterable-backoff.d.ts @@ -1 +1 @@ -declare module "iterable-backoff"; +declare module 'iterable-backoff' diff --git a/@xen-orchestra/lite/src/types/limit-concurrency-decorator.d.ts b/@xen-orchestra/lite/src/types/limit-concurrency-decorator.d.ts index 9dc88bdb356..e316b4c44c4 100644 --- a/@xen-orchestra/lite/src/types/limit-concurrency-decorator.d.ts +++ b/@xen-orchestra/lite/src/types/limit-concurrency-decorator.d.ts @@ -1,3 +1,3 @@ -declare module "limit-concurrency-decorator" { - export const limitConcurrency: any; +declare module 'limit-concurrency-decorator' { + export const limitConcurrency: any } diff --git a/@xen-orchestra/lite/src/types/novnc.d.ts b/@xen-orchestra/lite/src/types/novnc.d.ts index 81afe7b4da7..3f1f77f7617 100644 --- a/@xen-orchestra/lite/src/types/novnc.d.ts +++ b/@xen-orchestra/lite/src/types/novnc.d.ts @@ -4,17 +4,19 @@ // Maksim Ovcharik // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -declare module "@novnc/novnc/core/rfb" { +/* eslint-disable no-use-before-define */ + +declare module '@novnc/novnc/core/rfb' { /** * An `object` specifying the credentials to provide to the server when authenticating. */ interface NoVncCredentials { /** The user that authenticates */ - username: string; + username: string /** Password for the user */ - password: string; + password: string /** Target machine or session */ - target: string; + target: string } /** @@ -25,20 +27,20 @@ declare module "@novnc/novnc/core/rfb" { * A `boolean` indicating if the remote server should be shared or if any other connected * clients should be disconnected. Enabled by default. */ - shared?: boolean; + shared?: boolean /** * An `object` specifying the credentials to provide to the server when authenticating. */ - credentials?: NoVncCredentials; + credentials?: NoVncCredentials /** * A `string` specifying the ID to provide to any VNC repeater encountered. */ - repeaterID?: string; + repeaterID?: string /** * An `Array` of `string`s specifying the sub-protocols to use in the WebSocket connection. * Empty by default. */ - wsProtocols?: string[]; + wsProtocols?: string[] } interface NoVncEvents { @@ -47,7 +49,7 @@ declare module "@novnc/novnc/core/rfb" { * connection is fully established. After this event the `NoVncClient` object is ready to * receive graphics updates and to send input. */ - connect: CustomEvent>; + connect: CustomEvent> /** * The `disconnect` event is fired when the connection has been terminated. The `detail` @@ -55,14 +57,14 @@ declare module "@novnc/novnc/core/rfb" { * if the termination was clean or not. In the event of an unexpected termination or an error * `clean` will be set to false. */ - disconnect: CustomEvent<{ clean: boolean }>; + disconnect: CustomEvent<{ clean: boolean }> /** * The `credentialsrequired` event is fired when the server requests more credentials than were * specified to {@link NoVncClient}. The `detail` property is an `object` containing the * property `types` which is an `Array` of `string` listing the credentials that are required. */ - credentialsrequired: CustomEvent<{ types: Array }>; + credentialsrequired: CustomEvent<{ types: Array }> /** * The `securityfailure` event is fired when the handshaking process with the server fails @@ -82,58 +84,46 @@ declare module "@novnc/novnc/core/rfb" { * will probably send English strings. The server can choose to not send a reason and in these * cases the `reason` property will be omitted. */ - securityfailure: CustomEvent<{ status: number; reason?: string }>; + securityfailure: CustomEvent<{ status: number; reason?: string }> /** * The `clipboard` event is fired when the server has sent clipboard data. The `detail` property * is an `object` containing the property `text` which is a `string` with the clipboard data. */ - clipboard: CustomEvent<{ text: string }>; + clipboard: CustomEvent<{ text: string }> /** * The `bell` event is fired when the server has requested an audible bell. */ - bell: CustomEvent>; + bell: CustomEvent> /** * The `desktopname` event is fired when the name of the remote desktop changes. The `detail` * property is an `object` with the property `name` which is a `string` specifying the new name. */ - desktopname: CustomEvent<{ name: string }>; + desktopname: CustomEvent<{ name: string }> /** * The `capabilities` event is fired whenever an entry is added or removed from `capabilities`. * The `detail` property is an `object` with the property `capabilities` containing the new * value of `capabilities`. */ - capabilities: CustomEvent<{ capabilities: NoVncClient["capabilities"] }>; + capabilities: CustomEvent<{ capabilities: NoVncClient['capabilities'] }> } - type NoVncEventType = keyof NoVncEvents; - type NoVncEvent = NoVncEvents[NoVncEventType]; + type NoVncEventType = keyof NoVncEvents + type NoVncEvent = NoVncEvents[NoVncEventType] class NoVncEventTarget extends EventTarget { - protected _listeners: Map void>; - - addEventListener( - type: T, - listener: (event: NoVncEvents[T]) => void - ): void; - addEventListener( - type: string, - listener: (event: CustomEvent) => void - ): void; - - removeEventListener( - type: T, - listener: (event: NoVncEvents[T]) => void - ): void; - removeEventListener( - type: string, - listener: (event: CustomEvent) => void - ): void; - - dispatchEvent(event: NoVncEvent | CustomEvent): boolean; + protected _listeners: Map void> + + addEventListener(type: T, listener: (event: NoVncEvents[T]) => void): void + addEventListener(type: string, listener: (event: CustomEvent) => void): void + + removeEventListener(type: T, listener: (event: NoVncEvents[T]) => void): void + removeEventListener(type: string, listener: (event: CustomEvent) => void): void + + dispatchEvent(event: NoVncEvent | CustomEvent): boolean } /** @@ -141,9 +131,9 @@ declare module "@novnc/novnc/core/rfb" { * a WebSocket that must provide a standard NoVncClient protocol stream. */ export default class NoVncClient extends NoVncEventTarget { - readonly _rfbConnectionState: string; - readonly _target: Element; - readonly _url: string | null; + readonly _rfbConnectionState: string + readonly _target: Element + readonly _url: string | null /** * Returns a new `NoVncClient` object and initiates a new connection to a specified VNC server. @@ -156,67 +146,63 @@ declare module "@novnc/novnc/core/rfb" { * @param options - An {@link NoVncOptions} specifying extra details about how the connection * should be made. */ - constructor( - target: Element, - url: string | WebSocket | RTCDataChannel, - options?: NoVncOptions - ); + constructor(target: Element, url: string | WebSocket | RTCDataChannel, options?: NoVncOptions) /** * Is a `boolean` indicating if any events (e.g. key presses or mouse movement) should be * prevented from being sent to the server. Disabled by default. */ - viewOnly: boolean; + viewOnly: boolean /** * Is a `boolean` indicating if keyboard focus should automatically be moved to the remote * session when a `mousedown` or `touchstart` event is received. Enabled by default. */ - focusOnClick: boolean; + focusOnClick: boolean /** * Is a `boolean` indicating if the remote session should be clipped to its container. When * disabled scrollbars will be shown to handle the resulting overflow. Disabled by default. */ - clipViewport: boolean; + clipViewport: boolean /** * Is a `boolean` indicating if mouse events should control the relative position of a clipped * remote session. Only relevant if `clipViewport` is enabled. Disabled by default. */ - dragViewport: boolean; + dragViewport: boolean /** * Is a `boolean` indicating if the remote session should be scaled locally so it fits its * container. When disabled it will be centered if the remote session is smaller than its * container, or handled according to `clipViewport` if it is larger. Disabled by default. */ - scaleViewport: boolean; + scaleViewport: boolean /** * Is a `boolean` indicating if a request to resize the remote session should be sent whenever * the container changes dimensions. Disabled by default. */ - resizeSession: boolean; + resizeSession: boolean /** * Is a `boolean` indicating whether a dot cursor should be shown instead of a zero-sized or * fully-transparent cursor if the server sets such invisible cursor. Disabled by default. */ - showDotCursor: boolean; + showDotCursor: boolean /** * Is a valid CSS [background](https://developer.mozilla.org/en-US/docs/Web/CSS/background) * style value indicating which background style should be applied to the element containing the * remote session screen. The default value is `rgb(40, 40, 40)` (solid gray color). */ - background: string; + background: string /** * Is an `int` in range `[0-9]` controlling the desired JPEG quality. Value `0` implies low * quality and `9` implies high quality. Default value is `6`. */ - qualityLevel: number; + qualityLevel: number /** * Is an `int` in range `[0-9]` controlling the desired compression level. Value `0` means no @@ -224,7 +210,7 @@ declare module "@novnc/novnc/core/rfb" { * while level 9 offers best compression but is slow in terms of CPU consumption on the server * side. Use high levels with very slow network connections. Default value is `2`. */ - compressionLevel: number; + compressionLevel: number /** * Is an `object` indicating which optional extensions are available on the server. Some methods @@ -237,13 +223,13 @@ declare module "@novnc/novnc/core/rfb" { */ readonly capabilities: { /** Machine power control is available */ - power: boolean; - }; + power: boolean + } /** * Disconnect from the server. */ - disconnect(): void; + disconnect(): void /** * Send credentials to server. Should be called after the @@ -252,7 +238,7 @@ declare module "@novnc/novnc/core/rfb" { * @param credentials An {@link NoVncCredentials} specifying the credentials to provide to the * server when authenticating. */ - sendCredentials(credentials: NoVncCredentials): void; + sendCredentials(credentials: NoVncCredentials): void /** * Send a key event to the server. @@ -265,13 +251,13 @@ declare module "@novnc/novnc/core/rfb" { * @param down A `boolean` specifying if a press or a release event should be sent. If omitted * then both a press and release event are sent. */ - sendKey(keysym: number, code: string | null, down?: boolean): void; + sendKey(keysym: number, code: string | null, down?: boolean): void /** * Send the key sequence *left Control*, *left Alt*, *Delete*. This is a convenience wrapper * around {@link sendKey}. */ - sendCtrlAltDel(): void; + sendCtrlAltDel(): void /** * Sets the keyboard focus on the remote session. Keyboard events will be sent to the remote @@ -280,67 +266,69 @@ declare module "@novnc/novnc/core/rfb" { * @param options A {@link FocusOptions} providing options to control how the focus will be * performed. Please see {@link HTMLElement.focus} for available options. */ - focus(options?: FocusOptions): void; + focus(options?: FocusOptions): void /** * Remove keyboard focus on the remote session. Keyboard events will no longer be sent to the * remote server after this point. */ - blur(): void; + blur(): void /** * Request to shut down the remote machine. The capability `power` must be set for this method * to have any effect. */ - machineShutdown(): void; + machineShutdown(): void /** * Request a clean reboot of the remote machine. The capability `power` must be set for this * method to have any effect. */ - machineReboot(): void; + machineReboot(): void /** * Request a forced reset of the remote machine. The capability `power` must be set for this * method to have any effect. */ - machineReset(): void; + machineReset(): void /** * Send clipboard data to the remote server. * * @param text A `string` specifying the clipboard data to send. */ - clipboardPasteFrom(text: string): void; + clipboardPasteFrom(text: string): void } } -declare module "@novnc/novnc/core/util/browser" { - let isTouchDevice: boolean; - let dragThreshold: number; +declare module '@novnc/novnc/core/util/browser' { + let isTouchDevice: boolean + let dragThreshold: number - const supportsCursorURIs: boolean; - const hasScrollbarGutter: boolean; + const supportsCursorURIs: boolean + const hasScrollbarGutter: boolean - function isMac(): boolean; - function isWindows(): boolean; - function isIOS(): boolean; - function isSafari(): boolean; - function isFirefox(): boolean; + function isMac(): boolean + function isWindows(): boolean + function isIOS(): boolean + function isSafari(): boolean + function isFirefox(): boolean } -declare module "@novnc/novnc/core/input/util" { +declare module '@novnc/novnc/core/input/util' { interface KeyboardEventBase { - char?: string; - charCode?: number; - code: string; - key: string; - keyCode?: number; - location?: number; - type?: string; + char?: string + charCode?: number + code: string + key: string + keyCode?: number + location?: number + type?: string } - function getKeycode(event: KeyboardEventBase): string; - function getKey(event: KeyboardEventBase): string; - function getKeysym(event: KeyboardEventBase): number; + function getKeycode(event: KeyboardEventBase): string + function getKey(event: KeyboardEventBase): string + function getKeysym(event: KeyboardEventBase): number } + +/* eslint-enable no-use-before-define */ diff --git a/@xen-orchestra/lite/src/types/router.d.ts b/@xen-orchestra/lite/src/types/router.d.ts index 6a4107cc9a8..71a72c1a631 100644 --- a/@xen-orchestra/lite/src/types/router.d.ts +++ b/@xen-orchestra/lite/src/types/router.d.ts @@ -1,9 +1,9 @@ -declare module "vue-router" { +declare module 'vue-router' { interface RouteMeta { - hasStoryNav?: boolean; - isStory?: boolean; - storyTitle?: string; - storyMdLoader?: () => Promise; + hasStoryNav?: boolean + isStory?: boolean + storyTitle?: string + storyMdLoader?: () => Promise } } -export {}; +export {} diff --git a/@xen-orchestra/lite/src/types/sort.ts b/@xen-orchestra/lite/src/types/sort.ts index ab3b29b616e..abf4180deac 100644 --- a/@xen-orchestra/lite/src/types/sort.ts +++ b/@xen-orchestra/lite/src/types/sort.ts @@ -1,24 +1,24 @@ -import type { IconDefinition } from "@fortawesome/fontawesome-common-types"; +import type { IconDefinition } from '@fortawesome/fontawesome-common-types' interface Sort { - label?: string; - icon?: IconDefinition; + label?: string + icon?: IconDefinition } export interface Sorts { - [key: string]: Sort; + [key: string]: Sort } -export type ActiveSorts = Map; +export type ActiveSorts = Map -export type InitialSorts = `${"-" | ""}${Extract}`[]; +export type InitialSorts = `${'-' | ''}${Extract}`[] export interface SortConfig { - queryStringParam?: string; - initialSorts?: InitialSorts; + queryStringParam?: string + initialSorts?: InitialSorts } export type NewSort = { - property: string; - isAscending: boolean; -}; + property: string + isAscending: boolean +} diff --git a/@xen-orchestra/lite/src/types/stat.ts b/@xen-orchestra/lite/src/types/stat.ts index ff6ea4fd927..15570292fac 100644 --- a/@xen-orchestra/lite/src/types/stat.ts +++ b/@xen-orchestra/lite/src/types/stat.ts @@ -1,7 +1,7 @@ export interface StatData { - id: string; - value: number; - label?: string; - badgeLabel?: string; - maxValue?: number; + id: string + value: number + label?: string + badgeLabel?: string + maxValue?: number } diff --git a/@xen-orchestra/lite/src/types/stories.d.ts b/@xen-orchestra/lite/src/types/stories.d.ts index 06e78ca2877..569f7af4d1b 100644 --- a/@xen-orchestra/lite/src/types/stories.d.ts +++ b/@xen-orchestra/lite/src/types/stories.d.ts @@ -1,5 +1,5 @@ -declare module "virtual:stories" { - import type { RouteRecordRaw } from "vue-router"; - const routes: RouteRecordRaw[]; - export default routes; +declare module 'virtual:stories' { + import type { RouteRecordRaw } from 'vue-router' + const routes: RouteRecordRaw[] + export default routes } diff --git a/@xen-orchestra/lite/src/types/xen-api.ts b/@xen-orchestra/lite/src/types/xen-api.ts index f25ad24499f..eb72d2b0000 100644 --- a/@xen-orchestra/lite/src/types/xen-api.ts +++ b/@xen-orchestra/lite/src/types/xen-api.ts @@ -1,42 +1,38 @@ -import type { - RawObjectType, - XenApiMessage, -} from "@/libs/xen-api/xen-api.types"; +import type { RawObjectType, XenApiMessage } from '@/libs/xen-api/xen-api.types' export type XenApiAlarmType = - | "cpu_usage" - | "network_usage" - | "disk_usage" - | "fs_usage" - | "log_fs_usage" - | "mem_usage" - | "physical_utilisation" - | "sr_io_throughput_total_per_host" - | "memory_free_kib" - | "unknown"; + | 'cpu_usage' + | 'network_usage' + | 'disk_usage' + | 'fs_usage' + | 'log_fs_usage' + | 'mem_usage' + | 'physical_utilisation' + | 'sr_io_throughput_total_per_host' + | 'memory_free_kib' + | 'unknown' -export interface XenApiAlarm - extends XenApiMessage { - level: number; - triggerLevel: number; - type: XenApiAlarmType; +export interface XenApiAlarm extends XenApiMessage { + level: number + triggerLevel: number + type: XenApiAlarmType } export type XenApiPatch = { - $id: string; - name: string; - description: string; - license: string; - release: string; - size: number; - url: string; - version: string; + $id: string + name: string + description: string + license: string + release: string + size: number + url: string + version: string changelog: | null | undefined | { - date: number; - description: string; - author: string; - }; -}; + date: number + description: string + author: string + } +} diff --git a/@xen-orchestra/lite/src/views/HomeView.vue b/@xen-orchestra/lite/src/views/HomeView.vue index 97555e08f64..c97a1410eef 100644 --- a/@xen-orchestra/lite/src/views/HomeView.vue +++ b/@xen-orchestra/lite/src/views/HomeView.vue @@ -1,21 +1,21 @@ diff --git a/@xen-orchestra/lite/src/views/ObjectNotFoundView.vue b/@xen-orchestra/lite/src/views/ObjectNotFoundView.vue index a109ffda353..8246642d618 100644 --- a/@xen-orchestra/lite/src/views/ObjectNotFoundView.vue +++ b/@xen-orchestra/lite/src/views/ObjectNotFoundView.vue @@ -1,26 +1,24 @@ diff --git a/@xen-orchestra/lite/src/views/host/HostDashboardView.vue b/@xen-orchestra/lite/src/views/host/HostDashboardView.vue index 1c4e6b75ab4..9617c404933 100644 --- a/@xen-orchestra/lite/src/views/host/HostDashboardView.vue +++ b/@xen-orchestra/lite/src/views/host/HostDashboardView.vue @@ -3,9 +3,9 @@ diff --git a/@xen-orchestra/lite/src/views/host/HostRootView.vue b/@xen-orchestra/lite/src/views/host/HostRootView.vue index 53ab265df9a..62b9860857c 100644 --- a/@xen-orchestra/lite/src/views/host/HostRootView.vue +++ b/@xen-orchestra/lite/src/views/host/HostRootView.vue @@ -5,25 +5,23 @@ diff --git a/@xen-orchestra/lite/src/views/pool/PoolAlarmsView.vue b/@xen-orchestra/lite/src/views/pool/PoolAlarmsView.vue index 5300c397e24..fda3d54ec55 100644 --- a/@xen-orchestra/lite/src/views/pool/PoolAlarmsView.vue +++ b/@xen-orchestra/lite/src/views/pool/PoolAlarmsView.vue @@ -3,9 +3,9 @@ diff --git a/@xen-orchestra/lite/src/views/pool/PoolDashboardView.vue b/@xen-orchestra/lite/src/views/pool/PoolDashboardView.vue index b2940c03aa4..136c03392c0 100644 --- a/@xen-orchestra/lite/src/views/pool/PoolDashboardView.vue +++ b/@xen-orchestra/lite/src/views/pool/PoolDashboardView.vue @@ -26,92 +26,85 @@ - - + + diff --git a/@xen-orchestra/lite/src/views/pool/PoolStatsView.vue b/@xen-orchestra/lite/src/views/pool/PoolStatsView.vue index 3f0fc3be7da..1ac842fa2b0 100644 --- a/@xen-orchestra/lite/src/views/pool/PoolStatsView.vue +++ b/@xen-orchestra/lite/src/views/pool/PoolStatsView.vue @@ -3,9 +3,9 @@ diff --git a/@xen-orchestra/lite/src/views/pool/PoolStorageView.vue b/@xen-orchestra/lite/src/views/pool/PoolStorageView.vue index 52fcc877b50..043bc3d21e5 100644 --- a/@xen-orchestra/lite/src/views/pool/PoolStorageView.vue +++ b/@xen-orchestra/lite/src/views/pool/PoolStorageView.vue @@ -3,9 +3,9 @@ diff --git a/@xen-orchestra/lite/src/views/pool/PoolSystemView.vue b/@xen-orchestra/lite/src/views/pool/PoolSystemView.vue index 2405b8e1bef..e57718e175d 100644 --- a/@xen-orchestra/lite/src/views/pool/PoolSystemView.vue +++ b/@xen-orchestra/lite/src/views/pool/PoolSystemView.vue @@ -3,9 +3,9 @@ diff --git a/@xen-orchestra/lite/src/views/pool/PoolTasksView.vue b/@xen-orchestra/lite/src/views/pool/PoolTasksView.vue index 668fa0a36d0..77169e0deea 100644 --- a/@xen-orchestra/lite/src/views/pool/PoolTasksView.vue +++ b/@xen-orchestra/lite/src/views/pool/PoolTasksView.vue @@ -1,7 +1,7 @@