@xen-orchestra/web-core 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,29 @@
1
+ <template>
2
+ <UiInfo :accent="currentStatus.accent">
3
+ {{ currentStatus.text }}
4
+ </UiInfo>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import UiInfo, { type InfoAccent } from '@core/components/ui/info/UiInfo.vue'
9
+ import { computed, type ComputedRef } from 'vue'
10
+ import { useI18n } from 'vue-i18n'
11
+
12
+ type ConnectionStatus = 'connected' | 'disconnected' | 'partially-connected' | 'disconnected-from-physical-device'
13
+ type ConnectionStatusesMap = Record<ConnectionStatus, { text: string; accent: InfoAccent }>
14
+
15
+ const { status } = defineProps<{
16
+ status: ConnectionStatus
17
+ }>()
18
+
19
+ const { t } = useI18n()
20
+
21
+ const statuses: ComputedRef<ConnectionStatusesMap> = computed(() => ({
22
+ connected: { text: t('connected'), accent: 'success' },
23
+ disconnected: { text: t('disconnected'), accent: 'danger' },
24
+ 'partially-connected': { text: t('partially-connected'), accent: 'warning' },
25
+ 'disconnected-from-physical-device': { text: t('disconnected-from-physical-device'), accent: 'warning' },
26
+ }))
27
+
28
+ const currentStatus = computed(() => statuses.value[status])
29
+ </script>
@@ -2,7 +2,7 @@
2
2
  <template>
3
3
  <div class="ui-info">
4
4
  <VtsIcon :accent class="icon" :icon="faCircle" :overlay-icon="icon" />
5
- <p class="message">
5
+ <p v-tooltip="!wrap" class="typo p3-regular" :class="{ 'text-ellipsis': !wrap }">
6
6
  <slot />
7
7
  </p>
8
8
  </div>
@@ -10,6 +10,7 @@
10
10
 
11
11
  <script lang="ts" setup>
12
12
  import VtsIcon from '@core/components/icon/VtsIcon.vue'
13
+ import { vTooltip } from '@core/directives/tooltip.directive'
13
14
  import {
14
15
  faCheck,
15
16
  faCircle,
@@ -20,24 +21,25 @@ import {
20
21
  } from '@fortawesome/free-solid-svg-icons'
21
22
  import { computed } from 'vue'
22
23
 
23
- type Props = {
24
- accent: 'info' | 'success' | 'warning' | 'danger'
25
- }
24
+ export type InfoAccent = 'info' | 'success' | 'warning' | 'danger'
26
25
 
27
- const props = defineProps<Props>()
26
+ const { accent } = defineProps<{
27
+ accent: InfoAccent
28
+ wrap?: boolean
29
+ }>()
28
30
 
29
31
  defineSlots<{
30
32
  default(): any
31
33
  }>()
32
34
 
33
- const iconByAccent: Record<Props['accent'], IconDefinition> = {
35
+ const iconByAccent: Record<InfoAccent, IconDefinition> = {
34
36
  info: faInfo,
35
37
  success: faCheck,
36
38
  warning: faExclamation,
37
39
  danger: faXmark,
38
40
  }
39
41
 
40
- const icon = computed(() => iconByAccent[props.accent])
42
+ const icon = computed(() => iconByAccent[accent])
41
43
  </script>
42
44
 
43
45
  <style lang="postcss" scoped>
@@ -49,9 +51,5 @@ const icon = computed(() => iconByAccent[props.accent])
49
51
  .icon {
50
52
  font-size: 1.6rem;
51
53
  }
52
-
53
- .message {
54
- font-size: 1.2rem;
55
- }
56
54
  }
57
55
  </style>
@@ -1,141 +1,170 @@
1
- <!-- WIP -->
1
+ <!-- v5 -->
2
2
  <template>
3
- <div class="ui-input">
4
- <VtsIcon :icon accent="current" class="before" />
5
- <input :id v-model.trim="modelValue" class="typo p1-regular input" type="search" v-bind="attrs" />
6
- <VtsIcon
7
- v-if="!attrs.disabled && modelValue"
8
- :icon="faXmark"
9
- class="after"
10
- accent="info"
11
- @click="modelValue = ''"
12
- />
3
+ <div class="ui-input" :class="toVariants({ accent })">
4
+ <UiLabel v-if="slots.default || label" :accent="labelAccent" :required :icon="labelIcon" :href :for="id">
5
+ <slot>{{ label }}</slot>
6
+ </UiLabel>
7
+ <div>
8
+ <VtsIcon :icon accent="current" class="before" />
9
+ <input :id v-model.trim="modelValue" class="typo p1-regular input text-ellipsis" :type :disabled v-bind="attrs" />
10
+ <VtsIcon
11
+ v-if="!attrs.disabled && modelValue && clearable"
12
+ :icon="faXmark"
13
+ class="after"
14
+ accent="info"
15
+ @click="modelValue = ''"
16
+ />
17
+ </div>
18
+ <UiInfo v-if="slots.info || info" :accent>
19
+ <slot name="info">{{ info }}</slot>
20
+ </UiInfo>
13
21
  </div>
14
22
  </template>
15
23
 
16
24
  <script lang="ts" setup>
17
25
  import VtsIcon from '@core/components/icon/VtsIcon.vue'
18
- import { uniqueId } from '@core/utils/unique-id.util'
26
+ import UiInfo from '@core/components/ui/info/UiInfo.vue'
27
+ import UiLabel from '@core/components/ui/label/UiLabel.vue'
28
+ import { toVariants } from '@core/utils/to-variants.util'
19
29
  import type { IconDefinition } from '@fortawesome/fontawesome-common-types'
20
30
  import { faXmark } from '@fortawesome/free-solid-svg-icons'
21
- import { computed, useAttrs } from 'vue'
31
+ import { computed, useAttrs, useId } from 'vue'
32
+
33
+ type InputAccent = 'info' | 'warning' | 'danger'
34
+ type InputType = 'text' | 'number' | 'password' | 'search'
22
35
 
23
36
  defineOptions({
24
37
  inheritAttrs: false,
25
38
  })
26
39
 
27
- defineProps<{
40
+ const { accent, id = useId() } = defineProps<{
41
+ accent: InputAccent
42
+ label?: string
43
+ info?: string
44
+ id?: string
45
+ disabled?: boolean
46
+ clearable?: boolean
47
+ href?: string
48
+ required?: boolean
49
+ labelIcon?: IconDefinition
28
50
  icon?: IconDefinition
51
+ type?: InputType
29
52
  }>()
30
53
 
31
- const modelValue = defineModel<string>({ required: true })
54
+ const modelValue = defineModel<string | number>({ required: true })
55
+
56
+ const slots = defineSlots<{
57
+ default?(): any
58
+ info?(): any
59
+ }>()
32
60
 
33
61
  const attrs = useAttrs()
34
62
 
35
- const id = computed(() => uniqueId('input-'))
63
+ const labelAccent = computed(() => (accent === 'info' ? 'neutral' : accent))
36
64
  </script>
37
65
 
38
66
  <style lang="postcss" scoped>
39
- /* COLOR VARIANTS */
40
- .input {
41
- & {
42
- --border-color: var(--color-neutral-border);
43
- --background-color: var(--color-neutral-background-primary);
67
+ /* IMPLEMENTATION */
68
+ .ui-input {
69
+ position: relative;
70
+ display: flex;
71
+ flex-direction: column;
72
+ gap: 0.4rem;
73
+
74
+ .input {
75
+ border-radius: 0.4rem;
76
+ border-width: 0.1rem;
77
+ border-style: solid;
78
+ background-color: var(--color-neutral-background-primary);
79
+ color: var(--color-neutral-txt-primary);
80
+ height: 4rem;
81
+ outline: none;
82
+ width: 100%;
83
+ padding-block: 0.8rem;
84
+ padding-inline: 1.6rem;
85
+
86
+ &::placeholder {
87
+ color: var(--color-neutral-txt-secondary);
88
+ }
89
+
90
+ &:focus {
91
+ border-width: 0.2rem;
92
+ }
93
+
94
+ &:has(+ .after) {
95
+ padding-inline-end: 4.8rem;
96
+ }
44
97
  }
45
98
 
46
- &:is(:hover, :focus-visible) {
47
- --border-color: var(--color-info-item-hover);
48
- --background-color: var(--color-neutral-background-primary);
49
- }
99
+ /* VARIANT */
50
100
 
51
- &:focus {
52
- --border-color: var(--color-info-item-base);
53
- --background-color: var(--color-neutral-background-primary);
54
- }
101
+ &.accent--info {
102
+ .input {
103
+ border-color: var(--color-neutral-border);
55
104
 
56
- &:active {
57
- --border-color: var(--color-info-item-active);
58
- --background-color: var(--color-neutral-background-primary);
59
- }
105
+ &:hover {
106
+ border-color: var(--color-info-item-hover);
107
+ }
60
108
 
61
- &:disabled {
62
- --border-color: var(--color-neutral-border);
63
- --background-color: var(--color-neutral-background-disabled);
64
- }
65
- }
109
+ &:focus {
110
+ border-color: var(--color-info-item-base);
111
+ }
66
112
 
67
- /* BORDER VARIANTS */
68
- .input {
69
- --border-width: 0.1rem;
113
+ &:active {
114
+ border-color: var(--color-info-item-active);
115
+ }
70
116
 
71
- &:is(:hover, :focus-visible) {
72
- --border-width: 0.1rem;
117
+ &:disabled {
118
+ border-color: var(--color-neutral-border);
119
+ background-color: var(--color-neutral-background-disabled);
120
+ }
121
+ }
73
122
  }
74
123
 
75
- &:focus {
76
- --border-width: 0.2rem;
77
- }
124
+ &.accent--warning {
125
+ .input {
126
+ border-color: var(--color-warning-item-base);
78
127
 
79
- &:active {
80
- --border-width: 0.1rem;
128
+ &:disabled {
129
+ border-color: var(--color-neutral-border);
130
+ background-color: var(--color-neutral-background-disabled);
131
+ }
132
+ }
81
133
  }
82
134
 
83
- &:disabled {
84
- --border-width: 0.1rem;
135
+ &.accent--danger {
136
+ .input {
137
+ border-color: var(--color-danger-item-base);
138
+
139
+ &:disabled {
140
+ border-color: var(--color-neutral-border);
141
+ background-color: var(--color-neutral-background-disabled);
142
+ }
143
+ }
85
144
  }
86
- }
87
145
 
88
- /* IMPLEMENTATION */
89
- .ui-input {
90
- position: relative;
146
+ /* ICON POSITION */
91
147
 
92
148
  .before + .input {
93
149
  padding-inline-start: 4.8rem;
94
150
  }
95
- }
96
-
97
- .input {
98
- border: var(--border-width) solid var(--border-color);
99
- border-radius: 0.8rem;
100
- outline: none;
101
- width: 100%;
102
- height: 4rem;
103
- padding: 0.8rem 1.6rem;
104
- color: var(--color-neutral-txt-primary);
105
- background-color: var(--background-color);
106
-
107
- &:has(+ .after) {
108
- padding-inline-end: 4.8rem;
109
- }
110
151
 
111
- &:disabled {
112
- cursor: not-allowed;
152
+ .before,
153
+ .after {
154
+ position: absolute;
155
+ inset-block: 1.2rem;
113
156
  }
114
157
 
115
- &::placeholder {
158
+ .before {
116
159
  color: var(--color-neutral-txt-secondary);
160
+ inset-inline-start: 1.6rem;
161
+ pointer-events: none;
162
+ z-index: 1;
117
163
  }
118
164
 
119
- &[type='search']::-webkit-search-cancel-button {
120
- display: none;
165
+ .after {
166
+ inset-inline-end: 1.6rem;
167
+ cursor: pointer;
121
168
  }
122
169
  }
123
-
124
- .before,
125
- .after {
126
- position: absolute;
127
- inset-block: 1.2rem;
128
- }
129
-
130
- .before {
131
- color: var(--color-neutral-txt-secondary);
132
- inset-inline-start: 1.6rem;
133
- pointer-events: none;
134
- z-index: 1;
135
- }
136
-
137
- .after {
138
- inset-inline-end: 1.6rem;
139
- cursor: pointer;
140
- }
141
170
  </style>
@@ -1,24 +1,23 @@
1
- <!-- WIP -->
1
+ <!-- v1 -->
2
2
  <template>
3
3
  <div :class="toVariants({ accent })" class="ui-label">
4
- <VtsIcon accent="current" :icon class="left-icon" />
5
- <span :class="{ required }" class="typo c2-semi-bold label"><slot /></span>
6
- <!-- @TODO: Replace it by the VtsLink component when available -->
7
- <a v-if="href" :href class="link">
8
- <span class="typo p3-regular-underline">{{ $t('learn-more') }}</span>
9
- <VtsIcon accent="current" :icon="faUpRightFromSquare" class="link-icon" />
10
- </a>
4
+ <VtsIcon accent="current" :icon class="icon" />
5
+ <label :for="htmlFor" :class="{ required }" class="typo c2-semi-bold label">
6
+ <slot />
7
+ </label>
8
+ <UiLink v-if="href" class="learn-more-link" size="small" :href>{{ $t('learn-more') }}</UiLink>
11
9
  </div>
12
10
  </template>
13
11
 
14
12
  <script lang="ts" setup>
15
13
  import VtsIcon from '@core/components/icon/VtsIcon.vue'
14
+ import UiLink from '@core/components/ui/link/UiLink.vue'
16
15
  import { toVariants } from '@core/utils/to-variants.util'
17
16
  import type { IconDefinition } from '@fortawesome/fontawesome-common-types'
18
- import { faUpRightFromSquare } from '@fortawesome/free-solid-svg-icons'
19
17
 
20
- defineProps<{
18
+ const { for: htmlFor } = defineProps<{
21
19
  accent: 'neutral' | 'warning' | 'danger'
20
+ for?: string
22
21
  icon?: IconDefinition
23
22
  required?: boolean
24
23
  href?: string
@@ -30,7 +29,7 @@ defineProps<{
30
29
  display: flex;
31
30
  align-items: center;
32
31
 
33
- .left-icon {
32
+ .icon {
34
33
  margin-right: 0.8rem;
35
34
  }
36
35
 
@@ -42,17 +41,10 @@ defineProps<{
42
41
  }
43
42
  }
44
43
 
45
- .link {
46
- display: flex;
47
- align-items: center;
48
- gap: 0.8rem;
44
+ .learn-more-link {
49
45
  margin-left: auto;
50
46
  }
51
47
 
52
- .link-icon {
53
- font-size: 0.8rem;
54
- }
55
-
56
48
  /* ACCENT VARIANTS */
57
49
 
58
50
  &.accent--neutral {
@@ -7,6 +7,8 @@
7
7
  <UiInput
8
8
  :id
9
9
  v-model="value"
10
+ type="text"
11
+ accent="info"
10
12
  :aria-label="uiStore.isMobile ? $t('core.query-search-bar.label') : undefined"
11
13
  :icon="uiStore.isDesktop ? faMagnifyingGlass : undefined"
12
14
  :placeholder="$t('core.query-search-bar.placeholder')"
@@ -0,0 +1,33 @@
1
+ <template>
2
+ <UiButtonIcon :disabled accent="info" class="pagination-button" size="small" :icon />
3
+ </template>
4
+
5
+ <script setup lang="ts">
6
+ import UiButtonIcon from '@core/components/ui/button-icon/UiButtonIcon.vue'
7
+ import type { IconDefinition } from '@fortawesome/fontawesome-common-types'
8
+
9
+ const { disabled, icon } = defineProps<{
10
+ disabled: boolean
11
+ icon: IconDefinition
12
+ }>()
13
+ </script>
14
+
15
+ <style scoped lang="postcss">
16
+ .pagination-button.accent--info {
17
+ border: 0.1rem solid var(--color-neutral-border);
18
+ font-size: 1rem;
19
+
20
+ &:hover {
21
+ border-color: var(--color-info-item-hover);
22
+ }
23
+
24
+ &:active {
25
+ border-color: var(--color-info-item-active);
26
+ }
27
+
28
+ &:disabled {
29
+ background-color: var(--color-neutral-background-disabled);
30
+ border-color: transparent;
31
+ }
32
+ }
33
+ </style>
@@ -0,0 +1,178 @@
1
+ <!-- v2 -->
2
+ <template>
3
+ <div class="ui-table-pagination">
4
+ <div class="buttons-container">
5
+ <PaginationButton :disabled="isFirstPage || disabled" :icon="faAngleDoubleLeft" @click="goToFirstPage()" />
6
+ <PaginationButton :disabled="isFirstPage || disabled" :icon="faAngleLeft" @click="goToPreviousPage()" />
7
+ <PaginationButton :disabled="isLastPage || disabled" :icon="faAngleRight" @click="goToNextPage()" />
8
+ <PaginationButton :disabled="isLastPage || disabled" :icon="faAngleDoubleRight" @click="goToLastPage()" />
9
+ </div>
10
+ <span class="typo p3-regular label">
11
+ {{ $t('core.select.n-object-of', { from: startIndex, to: endIndex, total: totalItems }) }}
12
+ </span>
13
+ <span class="typo p3-regular label show">{{ $t('core.show-by') }}</span>
14
+ <div class="dropdown-wrapper">
15
+ <select v-model="pageSize" :disabled class="dropdown typo c3-regular" @change="goToFirstPage">
16
+ <option v-for="option in pageSizeOptions" :key="option" :value="option" class="typo p2-medium">
17
+ {{ option }}
18
+ </option>
19
+ </select>
20
+ <VtsIcon class="icon" accent="current" :icon="faAngleDown" />
21
+ </div>
22
+ </div>
23
+ </template>
24
+
25
+ <script setup lang="ts">
26
+ import VtsIcon from '@core/components/icon/VtsIcon.vue'
27
+ import PaginationButton from '@core/components/ui/table-pagination/PaginationButton.vue'
28
+ import {
29
+ faAngleDoubleLeft,
30
+ faAngleDoubleRight,
31
+ faAngleDown,
32
+ faAngleLeft,
33
+ faAngleRight,
34
+ } from '@fortawesome/free-solid-svg-icons'
35
+ import { useOffsetPagination } from '@vueuse/core'
36
+ import { computed, ref, watch } from 'vue'
37
+
38
+ export type PaginationPayload = {
39
+ currentPage: number
40
+ pageSize: number
41
+ startIndex: number
42
+ endIndex: number
43
+ }
44
+
45
+ const { totalItems, disabled = false } = defineProps<{
46
+ totalItems: number
47
+ disabled?: boolean
48
+ }>()
49
+
50
+ const emit = defineEmits<{
51
+ change: [payload: PaginationPayload]
52
+ }>()
53
+
54
+ const pageSize = ref(50)
55
+ const pageSizeOptions = [10, 50, 100, 150, 200]
56
+ const {
57
+ currentPage,
58
+ currentPageSize,
59
+ pageCount,
60
+ isFirstPage,
61
+ isLastPage,
62
+ prev: goToPreviousPage,
63
+ next: goToNextPage,
64
+ } = useOffsetPagination({
65
+ total: () => totalItems,
66
+ pageSize,
67
+ })
68
+ const startIndex = computed(() => (currentPage.value - 1) * currentPageSize.value + 1)
69
+ const endIndex = computed(() => Math.min(currentPage.value * currentPageSize.value, totalItems))
70
+
71
+ const goToFirstPage = () => {
72
+ currentPage.value = 1
73
+ }
74
+ const goToLastPage = () => {
75
+ currentPage.value = pageCount.value
76
+ }
77
+
78
+ watch([currentPage, currentPageSize], ([newPage, newPageSize]) => {
79
+ emit('change', {
80
+ currentPage: newPage,
81
+ pageSize: newPageSize,
82
+ startIndex: startIndex.value,
83
+ endIndex: endIndex.value,
84
+ })
85
+ })
86
+ </script>
87
+
88
+ <style scoped lang="postcss">
89
+ .ui-table-pagination {
90
+ display: flex;
91
+ align-items: center;
92
+ gap: 0.8rem;
93
+
94
+ .buttons-container {
95
+ display: flex;
96
+ gap: 0.2rem;
97
+ }
98
+
99
+ .label {
100
+ color: var(--color-neutral-txt-secondary);
101
+ }
102
+
103
+ .show::before {
104
+ content: '-';
105
+ margin-right: 0.8rem;
106
+ }
107
+
108
+ .dropdown-wrapper {
109
+ position: relative;
110
+
111
+ .dropdown {
112
+ cursor: pointer;
113
+ padding: 0.2rem 0.6rem;
114
+ height: 2.6rem;
115
+ width: 4.8rem;
116
+ appearance: none;
117
+ border-radius: 0.4rem;
118
+ color: var(--color-info-txt-base);
119
+ border: 0.1rem solid var(--color-neutral-border);
120
+ background-color: var(--color-neutral-background-primary);
121
+
122
+ &:hover {
123
+ border-color: var(--color-info-item-hover);
124
+ background-color: var(--color-info-background-hover);
125
+ color: var(--color-info-txt-hover);
126
+
127
+ + .icon {
128
+ color: var(--color-info-txt-hover);
129
+ }
130
+ }
131
+
132
+ &:disabled {
133
+ cursor: not-allowed;
134
+ background-color: var(--color-neutral-background-disabled);
135
+ color: var(--color-neutral-txt-secondary);
136
+ border-color: transparent;
137
+
138
+ + .icon {
139
+ color: var(--color-neutral-txt-secondary);
140
+ }
141
+ }
142
+
143
+ &:active {
144
+ background-color: var(--color-info-background-active);
145
+ border-color: var(--color-info-item-active);
146
+ }
147
+
148
+ &:focus-visible {
149
+ outline: 0.1rem solid var(--color-info-item-base);
150
+ border: 0.1rem solid var(--color-info-item-base);
151
+ color: var(--color-info-txt-base);
152
+ background-color: var(--color-info-background-selected);
153
+
154
+ + .icon {
155
+ color: var(--color-info-txt-base);
156
+ }
157
+ }
158
+
159
+ option {
160
+ background-color: var(--color-neutral-background-primary);
161
+ border: 0.1rem solid var(--color-neutral-border);
162
+ border-radius: 0.4rem;
163
+ color: var(--color-neutral-txt-primary);
164
+ }
165
+ }
166
+
167
+ .icon {
168
+ position: absolute;
169
+ top: 50%;
170
+ right: 0.8rem;
171
+ transform: translateY(-50%);
172
+ pointer-events: none;
173
+ font-size: 1rem;
174
+ color: var(--color-info-txt-base);
175
+ }
176
+ }
177
+ }
178
+ </style>
@@ -21,6 +21,7 @@
21
21
  "core.quick-actions": "Quick actions",
22
22
 
23
23
  "core.search": "Search",
24
+ "core.show-by": "Show by",
24
25
 
25
26
  "core.query-search-bar.label": "Search Engine",
26
27
  "core.query-search-bar.placeholder": "Write your query…",
@@ -29,6 +30,7 @@
29
30
  "core.select.all": "Select all",
30
31
  "core.select.none": "Select none",
31
32
  "core.select.unselect": "Unselect all",
33
+ "core.select.n-object-of": "{from} - {to} of {total} objects",
32
34
  "core.select.n-selected-of": "{count} selected of {total} objects",
33
35
  "core.sidebar.close": "Close sidebar",
34
36
  "core.sidebar.lock": "Lock sidebar open",
@@ -43,7 +45,10 @@
43
45
  "dark-mode.auto": "Auto dark mode",
44
46
 
45
47
  "access-forum": "Access forum",
48
+ "connected": "Connected",
46
49
  "dashboard": "Dashboard",
50
+ "disconnected": "Disconnected",
51
+ "disconnected-from-physical-device": "Disconnected from physical device",
47
52
  "documentation-name": "{name} documentation",
48
53
  "error-no-data": "Error, can't collect data.",
49
54
  "exit-fullscreen": "Exit fullscreen",
@@ -61,6 +66,7 @@
61
66
  "open-console-in-new-tab": "Open console in new tab",
62
67
  "other": "Other",
63
68
  "page-not-found": "This page is not to be found…",
69
+ "partially-connected": "Partially connected",
64
70
  "patches": "Patches",
65
71
  "power-on-vm-for-console": "Power on your VM to access its console",
66
72
  "power-on-host-for-console": "Power on your host to access its console",
@@ -21,6 +21,7 @@
21
21
  "core.quick-actions": "Actions rapides",
22
22
 
23
23
  "core.search": "Rechercher",
24
+ "core.show-by": "Afficher par",
24
25
 
25
26
  "core.query-search-bar.label": "Moteur de recherche",
26
27
  "core.query-search-bar.placeholder": "Écrivez votre requête…",
@@ -29,6 +30,7 @@
29
30
  "core.select.all": "Tout sélectionner",
30
31
  "core.select.none": "Tout désélectionner",
31
32
  "core.select.unselect": "Tout désélectionner",
33
+ "core.select.n-object-of": "{from} - {to} de {total} objets",
32
34
  "core.select.n-selected-of": "{count} objet sélectionné sur {total} | {count} objet sélectionné sur {total} | {count} objets sélectionnés sur {total}",
33
35
  "core.sidebar.close": "Fermer la barre latérale",
34
36
  "core.sidebar.lock": "Verrouiller la barre latérale",
@@ -43,7 +45,10 @@
43
45
  "dark-mode.auto": "Mode sombre automatique",
44
46
 
45
47
  "access-forum": "Accès au forum",
48
+ "connected": "Connecté",
46
49
  "dashboard": "Tableau de bord",
50
+ "disconnected": "Déconnecté",
51
+ "disconnected-from-physical-device": "Déconnecté de l'appareil physique",
47
52
  "documentation-name": "Documentation {name}",
48
53
  "error-no-data": "Erreur, impossible de collecter les données.",
49
54
  "exit-fullscreen": "Quitter le plein écran",
@@ -61,6 +66,7 @@
61
66
  "open-console-in-new-tab": "Ouvrir la console dans un nouvel onglet",
62
67
  "other": "Autre",
63
68
  "page-not-found": "Cette page est introuvable…",
69
+ "partially-connected": "Partiellement connecté",
64
70
  "patches": "Patches",
65
71
  "power-on-vm-for-console": "Allumez votre VM pour accéder à sa console",
66
72
  "power-on-host-for-console": "Allumez votre hôte pour accéder à sa console",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xen-orchestra/web-core",
3
3
  "type": "module",
4
- "version": "0.8.0",
4
+ "version": "0.10.0",
5
5
  "private": false,
6
6
  "exports": {
7
7
  "./*": {