@xen-orchestra/web-core 0.0.4 → 0.0.5

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.
package/env.d.ts CHANGED
@@ -1,2 +1 @@
1
- /// <reference types="novnc__novnc" />
2
1
  /// <reference types="vite/client" />
@@ -2,18 +2,24 @@
2
2
  <template>
3
3
  <div class="legend-title typo c3-semi-bold">
4
4
  <slot />
5
- <UiIcon v-tooltip="iconTooltip ?? false" :icon color="info" class="tooltip-icon" />
5
+ <UiIcon v-tooltip="iconTooltip ?? false" :icon color="info" />
6
6
  </div>
7
7
  </template>
8
8
 
9
- <script setup lang="ts">
9
+ <script lang="ts" setup>
10
10
  import UiIcon from '@core/components/icon/UiIcon.vue'
11
11
  import { vTooltip } from '@core/directives/tooltip.directive'
12
12
  import type { IconDefinition } from '@fortawesome/fontawesome-common-types'
13
13
 
14
- defineProps<{
14
+ export type LegendTitleProps = {
15
15
  iconTooltip?: string
16
16
  icon?: IconDefinition
17
+ }
18
+
19
+ defineProps<LegendTitleProps>()
20
+
21
+ defineSlots<{
22
+ default(): void
17
23
  }>()
18
24
  </script>
19
25
 
@@ -24,8 +30,4 @@ defineProps<{
24
30
  gap: 0.8rem;
25
31
  align-items: center;
26
32
  }
27
-
28
- .tooltip-icon {
29
- font-size: 1.2rem;
30
- }
31
33
  </style>
@@ -17,51 +17,47 @@
17
17
  </svg>
18
18
  </template>
19
19
 
20
- <script setup lang="ts">
20
+ <script lang="ts" setup>
21
21
  import UiIcon from '@core/components/icon/UiIcon.vue'
22
22
  import type { IconDefinition } from '@fortawesome/fontawesome-common-types'
23
23
  import { computed } from 'vue'
24
24
 
25
- type Segment = {
25
+ export type DonutSegmentColor = 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'disabled'
26
+
27
+ export type DonutSegment = {
26
28
  value: number
27
- color: 'success' | 'warning' | 'error' | 'unknown'
29
+ color: DonutSegmentColor
28
30
  }
29
31
 
30
- type ComputedSegment = {
31
- color: 'success' | 'warning' | 'error' | 'unknown'
32
- percent: number
33
- offset: number
32
+ export type DonutChartProps = {
33
+ segments: DonutSegment[]
34
+ icon?: IconDefinition
34
35
  }
35
36
 
36
- const props = defineProps<{
37
- segments: Segment[]
38
- maxValue?: number
39
- icon?: IconDefinition
40
- }>()
37
+ const props = defineProps<DonutChartProps>()
41
38
 
42
39
  const circumference = Math.PI * 80
43
40
 
44
- const totalValue = computed(() => {
45
- const sumOfValues = props.segments.reduce((acc, segment) => acc + segment.value, 0)
46
- return Math.max(props.maxValue ?? 0, sumOfValues)
47
- })
41
+ const totalValue = computed(() => props.segments.reduce((total, segment) => total + segment.value, 0))
48
42
 
49
- const computedSegments = computed<ComputedSegment[]>(() => {
43
+ const computedSegments = computed(() => {
50
44
  let nextOffset = circumference / 4
45
+
51
46
  return props.segments.map(segment => {
47
+ const offset = nextOffset
52
48
  const percent = (segment.value / totalValue.value) * circumference
53
- const currentSegment = {
49
+ nextOffset -= percent
50
+
51
+ return {
54
52
  color: segment.color,
55
53
  percent,
56
- offset: nextOffset,
54
+ offset,
57
55
  }
58
- nextOffset -= percent
59
- return currentSegment
60
56
  })
61
57
  })
62
58
  </script>
63
59
 
64
- <style scoped lang="postcss">
60
+ <style lang="postcss" scoped>
65
61
  .donut-chart {
66
62
  width: 100px;
67
63
  height: 100px;
@@ -73,6 +69,14 @@ const computedSegments = computed<ComputedSegment[]>(() => {
73
69
  fill: transparent;
74
70
  --stroke-color: var(--color-grey-100);
75
71
 
72
+ &.primary {
73
+ --stroke-color: var(--color-purple-base);
74
+ }
75
+
76
+ &.secondary {
77
+ --stroke-color: var(--color-grey-100);
78
+ }
79
+
76
80
  &.success {
77
81
  --stroke-color: var(--color-green-base);
78
82
  }
@@ -81,11 +85,11 @@ const computedSegments = computed<ComputedSegment[]>(() => {
81
85
  --stroke-color: var(--color-orange-base);
82
86
  }
83
87
 
84
- &.error {
88
+ &.danger {
85
89
  --stroke-color: var(--color-red-base);
86
90
  }
87
91
 
88
- &.unknown {
92
+ &.disabled {
89
93
  --stroke-color: var(--color-grey-400);
90
94
  }
91
95
  }
@@ -0,0 +1,27 @@
1
+ <template>
2
+ <div class="donut-chart-with-legend">
3
+ <DonutChart :icon :segments />
4
+ <LegendGroup :items="segments" :title />
5
+ </div>
6
+ </template>
7
+
8
+ <script lang="ts" setup>
9
+ import DonutChart, { type DonutChartProps } from '@core/components/donut-chart/DonutChart.vue'
10
+ import LegendGroup, { type LegendGroupProps } from '@core/components/legend/LegendGroup.vue'
11
+
12
+ export type DonutChartWithLegendProps = {
13
+ segments: (DonutChartProps['segments'][number] & LegendGroupProps['items'][number])[]
14
+ title?: LegendGroupProps['title']
15
+ icon?: DonutChartProps['icon']
16
+ }
17
+
18
+ defineProps<DonutChartWithLegendProps>()
19
+ </script>
20
+
21
+ <style lang="postcss" scoped>
22
+ .donut-chart-with-legend {
23
+ display: flex;
24
+ align-items: center;
25
+ gap: 3.2rem;
26
+ }
27
+ </style>
@@ -0,0 +1,44 @@
1
+ <template>
2
+ <div class="legend-group">
3
+ <LegendTitle v-if="title" :icon="title.icon" :icon-tooltip="title.iconTooltip">
4
+ {{ title.label }}
5
+ </LegendTitle>
6
+ <LegendList class="list">
7
+ <LegendItem
8
+ v-for="item in items"
9
+ :key="item.label"
10
+ :color="item.color"
11
+ :tooltip="item.tooltip"
12
+ :unit="item.unit"
13
+ :value="item.value"
14
+ >
15
+ {{ item.label }}
16
+ </LegendItem>
17
+ </LegendList>
18
+ </div>
19
+ </template>
20
+
21
+ <script lang="ts" setup>
22
+ import LegendItem, { type LegendItemProps } from '@core/components/legend/LegendItem.vue'
23
+ import LegendList from '@core/components/legend/LegendList.vue'
24
+ import LegendTitle, { type LegendTitleProps } from '@core/components/LegendTitle.vue'
25
+
26
+ export type LegendGroupProps = {
27
+ items: (LegendItemProps & { label: string })[]
28
+ title?: LegendTitleProps & { label: string }
29
+ }
30
+
31
+ defineProps<LegendGroupProps>()
32
+ </script>
33
+
34
+ <style lang="postcss" scoped>
35
+ .legend-group {
36
+ display: flex;
37
+ flex-direction: column;
38
+ gap: 0.8rem;
39
+ }
40
+
41
+ .list {
42
+ padding-left: 1.6rem;
43
+ }
44
+ </style>
@@ -1,67 +1,85 @@
1
1
  <!-- v1.0 -->
2
2
  <template>
3
- <li :class="color" class="ui-legend">
3
+ <li :class="color" class="legend-item">
4
4
  <UiIcon :icon="faCircle" class="circle-icon" />
5
5
  <span class="label typo p3-regular"><slot /></span>
6
6
  <UiIcon v-if="tooltip" v-tooltip="tooltip" :icon="faCircleInfo" class="tooltip-icon" color="info" />
7
-
8
- <span class="value-and-unit typo c3-semi-bold">{{ value }} {{ unit }}</span>
7
+ <span v-if="valueLabel" class="value-and-unit typo c3-semi-bold">{{ valueLabel }}</span>
9
8
  </li>
10
9
  </template>
11
10
 
12
- <script setup lang="ts">
11
+ <script lang="ts" setup>
13
12
  import UiIcon from '@core/components/icon/UiIcon.vue'
14
13
  import { vTooltip } from '@core/directives/tooltip.directive'
15
- import { faCircleInfo, faCircle } from '@fortawesome/free-solid-svg-icons'
14
+ import { faCircle, faCircleInfo } from '@fortawesome/free-solid-svg-icons'
15
+ import { computed } from 'vue'
16
16
 
17
- type LegendColor = 'default' | 'success' | 'warning' | 'error' | 'disabled' | 'dark-blue'
17
+ export type LegendItemColor = 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'disabled'
18
18
 
19
- defineProps<{
20
- color: LegendColor
19
+ export type LegendItemProps = {
20
+ color: LegendItemColor
21
21
  value?: number
22
22
  unit?: string
23
23
  tooltip?: string
24
+ }
25
+
26
+ const props = defineProps<LegendItemProps>()
27
+
28
+ defineSlots<{
29
+ default(): void
24
30
  }>()
31
+
32
+ const valueLabel = computed(() => [props.value, props.unit].join(' ').trim())
25
33
  </script>
26
34
 
27
35
  <style lang="postcss" scoped>
28
36
  /* COLOR VARIANTS */
29
- .ui-legend {
37
+ .legend-item {
38
+ &.primary {
39
+ --circle-color: var(--color-purple-base);
40
+ }
41
+
42
+ &.secondary {
43
+ --circle-color: var(--color-grey-100);
44
+ }
45
+
30
46
  &.success {
31
47
  --circle-color: var(--color-green-base);
32
48
  }
49
+
33
50
  &.warning {
34
51
  --circle-color: var(--color-orange-base);
35
52
  }
36
- &.error {
53
+
54
+ &.danger {
37
55
  --circle-color: var(--color-red-base);
38
56
  }
39
- &.default {
40
- --circle-color: var(--color-purple-base);
41
- }
57
+
42
58
  &.disabled {
43
59
  --circle-color: var(--color-grey-300);
44
60
  }
45
- &.dark-blue {
46
- --circle-color: var(--color-grey-100);
47
- }
48
61
  }
62
+
49
63
  /* IMPLEMENTATION */
50
- .ui-legend {
64
+ .legend-item {
51
65
  display: flex;
52
66
  align-items: center;
53
67
  gap: 0.8rem;
54
68
  }
69
+
55
70
  .circle-icon {
56
71
  font-size: 0.8rem;
57
72
  color: var(--circle-color);
58
73
  }
74
+
59
75
  .tooltip-icon {
60
76
  font-size: 1.2rem;
61
77
  }
78
+
62
79
  .label {
63
80
  color: var(--color-grey-000);
64
81
  }
82
+
65
83
  .value-and-unit {
66
84
  color: var(--color-grey-300);
67
85
  }
@@ -0,0 +1,19 @@
1
+ <template>
2
+ <ul class="legend-list">
3
+ <slot />
4
+ </ul>
5
+ </template>
6
+
7
+ <script lang="ts" setup>
8
+ defineSlots<{
9
+ default(): void
10
+ }>()
11
+ </script>
12
+
13
+ <style lang="postcss" scoped>
14
+ .legend-list {
15
+ display: flex;
16
+ flex-direction: column;
17
+ gap: 0.4rem;
18
+ }
19
+ </style>
@@ -1,9 +1,13 @@
1
1
  <template>
2
- <StateHero image="under-construction" class="coming-soon-hero">
2
+ <StateHero :type class="coming-soon-hero" image="under-construction">
3
3
  {{ $t('coming-soon') }}
4
4
  </StateHero>
5
5
  </template>
6
6
 
7
7
  <script lang="ts" setup>
8
- import StateHero from '@core/components/state-hero/StateHero.vue'
8
+ import StateHero, { type StateHeroType } from '@core/components/state-hero/StateHero.vue'
9
+
10
+ defineProps<{
11
+ type: StateHeroType
12
+ }>()
9
13
  </script>
@@ -1,9 +1,15 @@
1
1
  <template>
2
- <StateHero busy class="loading-hero">
2
+ <StateHero v-if="!disabled" :type busy class="loading-hero">
3
3
  {{ $t('loading-in-progress') }}
4
4
  </StateHero>
5
+ <slot v-else />
5
6
  </template>
6
7
 
7
8
  <script lang="ts" setup>
8
- import StateHero from '@core/components/state-hero/StateHero.vue'
9
+ import StateHero, { type StateHeroType } from '@core/components/state-hero/StateHero.vue'
10
+
11
+ defineProps<{
12
+ type: StateHeroType
13
+ disabled?: boolean
14
+ }>()
9
15
  </script>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <StateHero image="no-result" class="object-not-found-hero">
2
+ <StateHero class="object-not-found-hero" image="no-result" type="page">
3
3
  {{ $t('object-not-found', { id }) }}
4
4
  </StateHero>
5
5
  </template>
@@ -1,8 +1,8 @@
1
1
  <template>
2
- <div class="state-hero">
2
+ <div :class="type" class="state-hero">
3
3
  <UiSpinner v-if="busy" class="spinner" />
4
4
  <img v-else-if="imageSrc" :src="imageSrc" alt="" class="image" />
5
- <p v-if="$slots.default" class="typo h2-black text">
5
+ <p v-if="$slots.default" :class="typoClass" class="typo text">
6
6
  <slot />
7
7
  </p>
8
8
  </div>
@@ -12,42 +12,60 @@
12
12
  import UiSpinner from '@core/components/UiSpinner.vue'
13
13
  import { computed } from 'vue'
14
14
 
15
+ export type StateHeroType = 'page' | 'card'
16
+
15
17
  const props = defineProps<{
18
+ type: StateHeroType
16
19
  busy?: boolean
17
20
  image?: 'no-result' | 'under-construction' // TODO: 'offline' | 'no-data' | 'not-found' | 'all-good' | 'all-done' | 'error'
18
21
  }>()
19
22
 
23
+ const typoClass = computed(() => (props.type === 'page' ? 'h2-black' : 'h4-medium'))
24
+
20
25
  const imageSrc = computed(() => {
21
- try {
22
- return new URL(`../../assets/${props.image}.svg`, import.meta.url).href
23
- } catch {
26
+ if (!props.image) {
24
27
  return undefined
25
28
  }
29
+
30
+ return new URL(`../../assets/${props.image}.svg`, import.meta.url).href
26
31
  })
27
32
  </script>
28
33
 
29
34
  <style lang="postcss" scoped>
35
+ .state-hero {
36
+ &.page {
37
+ --image-width: 90%;
38
+ --spinner-size: 10rem;
39
+ --gap: 8.2rem;
40
+ }
41
+
42
+ &.card {
43
+ --image-width: 70%;
44
+ --spinner-size: 6rem;
45
+ --gap: 2rem;
46
+ }
47
+ }
48
+
30
49
  .state-hero {
31
50
  flex: 1;
32
51
  display: flex;
33
52
  flex-direction: column;
34
53
  align-items: center;
35
54
  justify-content: center;
36
- gap: 4.2rem;
55
+ gap: var(--gap);
37
56
  }
38
57
 
39
58
  .image {
40
- width: 90%;
59
+ width: var(--image-width);
41
60
  max-width: 55rem;
42
61
  }
43
62
 
44
63
  .spinner {
45
64
  color: var(--color-purple-base);
46
- font-size: 10rem;
65
+ font-size: var(--spinner-size);
47
66
  }
48
67
 
49
68
  .text {
50
69
  color: var(--color-purple-base);
51
- margin-top: 4rem;
52
70
  }
53
71
  </style>
@@ -0,0 +1,25 @@
1
+ # `useItemCounter`
2
+
3
+ This composable is meant to count items based on given filters then output the categorized count.
4
+
5
+ ## Usage
6
+
7
+ ```typescript
8
+ const collection = [
9
+ { id: 'a', size: 'S' },
10
+ { id: 'b', size: 'S' },
11
+ { id: 'c', size: 'XL' },
12
+ { id: 'd', size: 'M' },
13
+ { id: 'e', size: 'L' },
14
+ { id: 'f', size: 'S' },
15
+ ]
16
+
17
+ const count = useItemCounter(collection, {
18
+ small: item => item.size === 'S',
19
+ medium: item => item.size === 'M',
20
+ })
21
+
22
+ console.log(count.small) // 3
23
+ console.log(count.medium) // 1
24
+ console.log(count.$other) // 2
25
+ ```
@@ -0,0 +1,32 @@
1
+ import { computed, type MaybeRefOrGetter, toValue } from 'vue'
2
+
3
+ type Counters<TConfig> = { [K in keyof TConfig | '$other']: number }
4
+
5
+ export function useItemCounter<TItem, TConfig extends Record<string, (item: TItem) => boolean>>(
6
+ items: MaybeRefOrGetter<TItem[]>,
7
+ config: TConfig
8
+ ) {
9
+ const keys = Object.keys(config) as (keyof TConfig)[]
10
+
11
+ return computed(() => {
12
+ const counters = Object.fromEntries(keys.concat('$other').map(key => [key, 0])) as Counters<TConfig>
13
+
14
+ for (const item of toValue(items)) {
15
+ let matched = false
16
+
17
+ for (const key of keys) {
18
+ if (config[key](item)) {
19
+ matched = true
20
+ counters[key] += 1
21
+ break
22
+ }
23
+ }
24
+
25
+ if (!matched) {
26
+ counters.$other += 1
27
+ }
28
+ }
29
+
30
+ return counters
31
+ })
32
+ }
@@ -64,5 +64,6 @@
64
64
  "tasks.quick-view.failed": "Failed",
65
65
  "tasks.quick-view.in-progress": "In progress",
66
66
 
67
+ "total": "Total",
67
68
  "vms": "VMs"
68
69
  }
@@ -64,5 +64,6 @@
64
64
  "tasks.quick-view.failed": "Échouées",
65
65
  "tasks.quick-view.in-progress": "En cours",
66
66
 
67
+ "total": "Total",
67
68
  "vms": "VMs"
68
69
  }
@@ -0,0 +1,342 @@
1
+ // [WARNING] Temporary file to fix typecheck error
2
+ // Remove if this PR is merged: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/70022
3
+ // Type definitions for @novnc/novnc 1.5
4
+ // Project: https://github.com/novnc/noVNC
5
+ // Definitions by: Jake Jarvis <https://github.com/jakejarvis>
6
+ // Maksim Ovcharik <https://github.com/ovcharik>
7
+ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
8
+
9
+ /* eslint-disable no-use-before-define */
10
+
11
+ declare module '@novnc/novnc/lib/rfb' {
12
+ /**
13
+ * An `object` specifying the credentials to provide to the server when authenticating.
14
+ */
15
+ interface NoVncCredentials {
16
+ /** The user that authenticates */
17
+ username: string
18
+ /** Password for the user */
19
+ password: string
20
+ /** Target machine or session */
21
+ target: string
22
+ }
23
+
24
+ /**
25
+ * An `object` specifying extra details about how the connection should be made.
26
+ */
27
+ interface NoVncOptions {
28
+ /**
29
+ * A `boolean` indicating if the remote server should be shared or if any other connected
30
+ * clients should be disconnected. Enabled by default.
31
+ */
32
+ shared?: boolean
33
+ /**
34
+ * An `object` specifying the credentials to provide to the server when authenticating.
35
+ */
36
+ credentials?: NoVncCredentials
37
+ /**
38
+ * A `string` specifying the ID to provide to any VNC repeater encountered.
39
+ */
40
+ repeaterID?: string
41
+ /**
42
+ * An `Array` of `string`s specifying the sub-protocols to use in the WebSocket connection.
43
+ * Empty by default.
44
+ */
45
+ wsProtocols?: string[]
46
+ }
47
+
48
+ interface NoVncEvents {
49
+ /**
50
+ * The `connect` event is fired after all the handshaking with the server is completed and the
51
+ * connection is fully established. After this event the `NoVncClient` object is ready to
52
+ * receive graphics updates and to send input.
53
+ */
54
+ connect: CustomEvent<Record<string, never>>
55
+
56
+ /**
57
+ * The `disconnect` event is fired when the connection has been terminated. The `detail`
58
+ * property is an `object` that contains the property `clean`. `clean` is a `boolean` indicating
59
+ * if the termination was clean or not. In the event of an unexpected termination or an error
60
+ * `clean` will be set to false.
61
+ */
62
+ disconnect: CustomEvent<{ clean: boolean }>
63
+
64
+ /**
65
+ * The `credentialsrequired` event is fired when the server requests more credentials than were
66
+ * specified to {@link NoVncClient}. The `detail` property is an `object` containing the
67
+ * property `types` which is an `Array` of `string` listing the credentials that are required.
68
+ */
69
+ credentialsrequired: CustomEvent<{ types: Array<keyof NoVncCredentials> }>
70
+
71
+ /**
72
+ * The `securityfailure` event is fired when the handshaking process with the server fails
73
+ * during the security negotiation step. The `detail` property is an `object` containing the
74
+ * following properties:
75
+ *
76
+ * | Property | Type | Description
77
+ * | -------- | ----------- | -----------
78
+ * | `status` | `number` | The failure status code
79
+ * | `reason` | `string` | The **optional** reason for the failure
80
+ *
81
+ * The property `status` corresponds to the
82
+ * [SecurityResult](https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst#securityresult)
83
+ * status code in cases of failure. A status of zero will not be sent in this event since that
84
+ * indicates a successful security handshaking process. The optional property `reason` is
85
+ * provided by the server and thus the language of the string is not known. However most servers
86
+ * will probably send English strings. The server can choose to not send a reason and in these
87
+ * cases the `reason` property will be omitted.
88
+ */
89
+ securityfailure: CustomEvent<{ status: number; reason?: string }>
90
+
91
+ /**
92
+ * The `clipboard` event is fired when the server has sent clipboard data. The `detail` property
93
+ * is an `object` containing the property `text` which is a `string` with the clipboard data.
94
+ */
95
+ clipboard: CustomEvent<{ text: string }>
96
+
97
+ /**
98
+ * The `bell` event is fired when the server has requested an audible bell.
99
+ */
100
+ bell: CustomEvent<Record<string, never>>
101
+
102
+ /**
103
+ * The `desktopname` event is fired when the name of the remote desktop changes. The `detail`
104
+ * property is an `object` with the property `name` which is a `string` specifying the new name.
105
+ */
106
+ desktopname: CustomEvent<{ name: string }>
107
+
108
+ /**
109
+ * The `capabilities` event is fired whenever an entry is added or removed from `capabilities`.
110
+ * The `detail` property is an `object` with the property `capabilities` containing the new
111
+ * value of `capabilities`.
112
+ */
113
+ capabilities: CustomEvent<{ capabilities: NoVncClient['capabilities'] }>
114
+ }
115
+
116
+ type NoVncEventType = keyof NoVncEvents
117
+ type NoVncEvent = NoVncEvents[NoVncEventType]
118
+
119
+ class NoVncEventTarget extends EventTarget {
120
+ protected _listeners: Map<NoVncEventType, (event: Event) => void>
121
+
122
+ addEventListener<T extends NoVncEventType>(type: T, listener: (event: NoVncEvents[T]) => void): void
123
+ addEventListener(type: string, listener: (event: CustomEvent) => void): void
124
+
125
+ removeEventListener<T extends NoVncEventType>(type: T, listener: (event: NoVncEvents[T]) => void): void
126
+ removeEventListener(type: string, listener: (event: CustomEvent) => void): void
127
+
128
+ dispatchEvent(event: NoVncEvent | CustomEvent): boolean
129
+ }
130
+
131
+ /**
132
+ * The `NoVncClient` object represents a single connection to a VNC server. It communicates using
133
+ * a WebSocket that must provide a standard NoVncClient protocol stream.
134
+ */
135
+ export default class NoVncClient extends NoVncEventTarget {
136
+ readonly _rfbConnectionState: string
137
+ readonly _target: Element
138
+ readonly _url: string | null
139
+
140
+ /**
141
+ * Returns a new `NoVncClient` object and initiates a new connection to a specified VNC server.
142
+ *
143
+ * @param target - A block {@link HTMLElement} that specifies where the `NoVncClient` object
144
+ * should attach itself. The existing contents of the `HTMLElement` will be untouched, but new
145
+ * elements will be added during the lifetime of the `NoVncClient` object.
146
+ * @param url - A `string`, {@link WebSocket}, or {@link RTCDataChannel} specifying the VNC server to connect
147
+ * to. This must be a valid WebSocket URL.
148
+ * @param options - An {@link NoVncOptions} specifying extra details about how the connection
149
+ * should be made.
150
+ */
151
+ constructor(target: Element, url: string | WebSocket | RTCDataChannel, options?: NoVncOptions)
152
+
153
+ /**
154
+ * Is a `boolean` indicating if any events (e.g. key presses or mouse movement) should be
155
+ * prevented from being sent to the server. Disabled by default.
156
+ */
157
+ viewOnly: boolean
158
+
159
+ /**
160
+ * Is a `boolean` indicating if keyboard focus should automatically be moved to the remote
161
+ * session when a `mousedown` or `touchstart` event is received. Enabled by default.
162
+ */
163
+ focusOnClick: boolean
164
+
165
+ /**
166
+ * Is a `boolean` indicating if the remote session should be clipped to its container. When
167
+ * disabled scrollbars will be shown to handle the resulting overflow. Disabled by default.
168
+ */
169
+ clipViewport: boolean
170
+
171
+ /**
172
+ * Is a `boolean` indicating if mouse events should control the relative position of a clipped
173
+ * remote session. Only relevant if `clipViewport` is enabled. Disabled by default.
174
+ */
175
+ dragViewport: boolean
176
+
177
+ /**
178
+ * Is a `boolean` indicating if the remote session should be scaled locally so it fits its
179
+ * container. When disabled it will be centered if the remote session is smaller than its
180
+ * container, or handled according to `clipViewport` if it is larger. Disabled by default.
181
+ */
182
+ scaleViewport: boolean
183
+
184
+ /**
185
+ * Is a `boolean` indicating if a request to resize the remote session should be sent whenever
186
+ * the container changes dimensions. Disabled by default.
187
+ */
188
+ resizeSession: boolean
189
+
190
+ /**
191
+ * Is a `boolean` indicating whether a dot cursor should be shown instead of a zero-sized or
192
+ * fully-transparent cursor if the server sets such invisible cursor. Disabled by default.
193
+ */
194
+ showDotCursor: boolean
195
+
196
+ /**
197
+ * Is a valid CSS [background](https://developer.mozilla.org/en-US/docs/Web/CSS/background)
198
+ * style value indicating which background style should be applied to the element containing the
199
+ * remote session screen. The default value is `rgb(40, 40, 40)` (solid gray color).
200
+ */
201
+ background: string
202
+
203
+ /**
204
+ * Is an `int` in range `[0-9]` controlling the desired JPEG quality. Value `0` implies low
205
+ * quality and `9` implies high quality. Default value is `6`.
206
+ */
207
+ qualityLevel: number
208
+
209
+ /**
210
+ * Is an `int` in range `[0-9]` controlling the desired compression level. Value `0` means no
211
+ * compression. Level 1 uses a minimum of CPU resources and achieves weak compression ratios,
212
+ * while level 9 offers best compression but is slow in terms of CPU consumption on the server
213
+ * side. Use high levels with very slow network connections. Default value is `2`.
214
+ */
215
+ compressionLevel: number
216
+
217
+ /**
218
+ * Is an `object` indicating which optional extensions are available on the server. Some methods
219
+ * may only be called if the corresponding capability is set. The following capabilities are
220
+ * defined:
221
+ *
222
+ * | name | type | description
223
+ * | -------- | --------- | -----------
224
+ * | `power` | `boolean` | Machine power control is available
225
+ */
226
+ readonly capabilities: {
227
+ /** Machine power control is available */
228
+ power: boolean
229
+ }
230
+
231
+ /**
232
+ * Disconnect from the server.
233
+ */
234
+ disconnect(): void
235
+
236
+ /**
237
+ * Send credentials to server. Should be called after the
238
+ * {@link NoVncEventType.credentialsrequired} event has fired.
239
+ *
240
+ * @param credentials An {@link NoVncCredentials} specifying the credentials to provide to the
241
+ * server when authenticating.
242
+ */
243
+ sendCredentials(credentials: NoVncCredentials): void
244
+
245
+ /**
246
+ * Send a key event to the server.
247
+ *
248
+ * @param keysym A `number` specifying the NoVncClient keysym to send. Can be `0` if a valid
249
+ * **`code`** is specified.
250
+ * @param code A `string` specifying the physical key to send. Valid values are those that can
251
+ * be specified to {@link KeyboardEvent.code}. If the physical key cannot be determined then
252
+ * `null` shall be specified.
253
+ * @param down A `boolean` specifying if a press or a release event should be sent. If omitted
254
+ * then both a press and release event are sent.
255
+ */
256
+ sendKey(keysym: number, code: string | null, down?: boolean): void
257
+
258
+ /**
259
+ * Send the key sequence *left Control*, *left Alt*, *Delete*. This is a convenience wrapper
260
+ * around {@link sendKey}.
261
+ */
262
+ sendCtrlAltDel(): void
263
+
264
+ /**
265
+ * Sets the keyboard focus on the remote session. Keyboard events will be sent to the remote
266
+ * server after this point.
267
+ *
268
+ * @param options A {@link FocusOptions} providing options to control how the focus will be
269
+ * performed. Please see {@link HTMLElement.focus} for available options.
270
+ */
271
+ focus(options?: FocusOptions): void
272
+
273
+ /**
274
+ * Remove keyboard focus on the remote session. Keyboard events will no longer be sent to the
275
+ * remote server after this point.
276
+ */
277
+ blur(): void
278
+
279
+ /**
280
+ * Request to shut down the remote machine. The capability `power` must be set for this method
281
+ * to have any effect.
282
+ */
283
+ machineShutdown(): void
284
+
285
+ /**
286
+ * Request a clean reboot of the remote machine. The capability `power` must be set for this
287
+ * method to have any effect.
288
+ */
289
+ machineReboot(): void
290
+
291
+ /**
292
+ * Request a forced reset of the remote machine. The capability `power` must be set for this
293
+ * method to have any effect.
294
+ */
295
+ machineReset(): void
296
+
297
+ /**
298
+ * Send clipboard data to the remote server.
299
+ *
300
+ * @param text A `string` specifying the clipboard data to send.
301
+ */
302
+ clipboardPasteFrom(text: string): void
303
+ }
304
+ }
305
+
306
+ declare module '@novnc/novnc/core/util/browser' {
307
+ let isTouchDevice: boolean
308
+ let dragThreshold: number
309
+
310
+ const supportsCursorURIs: boolean
311
+ const hasScrollbarGutter: boolean
312
+
313
+ function isMac(): boolean
314
+
315
+ function isWindows(): boolean
316
+
317
+ function isIOS(): boolean
318
+
319
+ function isSafari(): boolean
320
+
321
+ function isFirefox(): boolean
322
+ }
323
+
324
+ declare module '@novnc/novnc/core/input/util' {
325
+ interface KeyboardEventBase {
326
+ char?: string
327
+ charCode?: number
328
+ code: string
329
+ key: string
330
+ keyCode?: number
331
+ location?: number
332
+ type?: string
333
+ }
334
+
335
+ function getKeycode(event: KeyboardEventBase): string
336
+
337
+ function getKey(event: KeyboardEventBase): string
338
+
339
+ function getKeysym(event: KeyboardEventBase): number
340
+ }
341
+
342
+ /* eslint-enable no-use-before-define */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xen-orchestra/web-core",
3
3
  "type": "module",
4
- "version": "0.0.4",
4
+ "version": "0.0.5",
5
5
  "private": false,
6
6
  "exports": {
7
7
  "./*": {