Compare commits
1 Commits
feat_retry
...
lite/xo-un
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de14528dd4 |
3
.prettierignore
Normal file
3
.prettierignore
Normal file
@@ -0,0 +1,3 @@
|
||||
@xen-orchestra/web
|
||||
@xen-orchestra/web-core
|
||||
@xen-orchestra/web-lite
|
||||
14
@xen-orchestra/web-core/eslint.config.js
Normal file
14
@xen-orchestra/web-core/eslint.config.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import antfu from '@antfu/eslint-config'
|
||||
|
||||
export default antfu({
|
||||
rules: {
|
||||
'import/order': ['error', { alphabetize: { order: 'asc', orderImportKind: 'asc' } }],
|
||||
},
|
||||
overrides: {
|
||||
vue: {
|
||||
'vue/component-api-style': 'error',
|
||||
'vue/no-empty-component-block': 'error',
|
||||
'vue/block-order': ['error', { order: ['template', 'script', 'style'] }],
|
||||
},
|
||||
},
|
||||
})
|
||||
121
@xen-orchestra/web-core/lib/assets/css/_colors.pcss
Normal file
121
@xen-orchestra/web-core/lib/assets/css/_colors.pcss
Normal file
@@ -0,0 +1,121 @@
|
||||
:root {
|
||||
--color-grey-000: #000000;
|
||||
--color-grey-100: #1a1b38;
|
||||
--color-grey-200: #595a6f;
|
||||
--color-grey-300: #9899a5;
|
||||
--color-grey-400: #bfbfc6;
|
||||
--color-grey-500: #e5e5e7;
|
||||
--color-grey-600: #ffffff;
|
||||
|
||||
--color-background-primary: #ffffff;
|
||||
--color-background-secondary: #f6f6f7;
|
||||
|
||||
--color-purple-base: #8f84ff;
|
||||
--color-purple-d20: color(#8f84ff blend(black 20%));
|
||||
--color-purple-d40: color(#8f84ff blend(black 40%));
|
||||
--color-purple-d60: color(#8f84ff blend(black 60%));
|
||||
--color-purple-l20: color(#8f84ff blend(white 20%));
|
||||
--color-purple-l40: color(#8f84ff blend(white 40%));
|
||||
--color-purple-l60: color(#8f84ff blend(white 60%));
|
||||
--color-background-purple-10: color(white blend(#8f84ff 10%));
|
||||
--color-background-purple-20: color(white blend(#8f84ff 20%));
|
||||
--color-background-purple-30: color(white blend(#8f84ff 30%));
|
||||
--color-background-purple-60: color(white blend(#8f84ff 60%));
|
||||
|
||||
--color-green-base: #2ca878;
|
||||
--color-green-d20: color(#2ca878 blend(black 20%));
|
||||
--color-green-d40: color(#2ca878 blend(black 40%));
|
||||
--color-green-d60: color(#2ca878 blend(black 60%));
|
||||
--color-green-l20: color(#2ca878 blend(white 20%));
|
||||
--color-green-l40: color(#2ca878 blend(white 40%));
|
||||
--color-green-l60: color(#2ca878 blend(white 60%));
|
||||
--color-background-green-10: color(white blend(#2ca878 10%));
|
||||
--color-background-green-20: color(white blend(#2ca878 20%));
|
||||
--color-background-green-30: color(white blend(#2ca878 30%));
|
||||
--color-background-green-60: color(white blend(#2ca878 60%));
|
||||
|
||||
--color-orange-base: #ef7f18;
|
||||
--color-orange-d20: color(#ef7f18 blend(black 20%));
|
||||
--color-orange-d40: color(#ef7f18 blend(black 40%));
|
||||
--color-orange-d60: color(#ef7f18 blend(black 60%));
|
||||
--color-orange-l20: color(#ef7f18 blend(white 20%));
|
||||
--color-orange-l40: color(#ef7f18 blend(white 40%));
|
||||
--color-orange-l60: color(#ef7f18 blend(white 60%));
|
||||
--color-background-orange-10: color(white blend(#ef7f18 10%));
|
||||
--color-background-orange-20: color(white blend(#ef7f18 20%));
|
||||
--color-background-orange-30: color(white blend(#ef7f18 30%));
|
||||
--color-background-orange-60: color(white blend(#ef7f18 60%));
|
||||
|
||||
--color-red-base: #be1621;
|
||||
--color-red-d20: color(#be1621 blend(black 20%));
|
||||
--color-red-d40: color(#be1621 blend(black 40%));
|
||||
--color-red-d60: color(#be1621 blend(black 60%));
|
||||
--color-red-l20: color(#be1621 blend(white 20%));
|
||||
--color-red-l40: color(#be1621 blend(white 40%));
|
||||
--color-red-l60: color(#be1621 blend(white 60%));
|
||||
--color-background-red-10: color(white blend(#be1621 10%));
|
||||
--color-background-red-20: color(white blend(#be1621 20%));
|
||||
--color-background-red-30: color(white blend(#be1621 30%));
|
||||
--color-background-red-60: color(white blend(#be1621 60%));
|
||||
}
|
||||
|
||||
:root.dark {
|
||||
--color-grey-000: #ffffff;
|
||||
--color-grey-100: #e5e5e7;
|
||||
--color-grey-400: #595a6f;
|
||||
--color-grey-200: #bfbfc6;
|
||||
--color-grey-300: #9899a5;
|
||||
--color-grey-500: #1a1b38;
|
||||
--color-grey-600: #000000;
|
||||
|
||||
--color-background-primary: #14141e;
|
||||
--color-background-secondary: #17182b;
|
||||
|
||||
--color-purple-base: #8f84ff;
|
||||
--color-purple-d20: color(#8f84ff blend(white 20%));
|
||||
--color-purple-d40: color(#8f84ff blend(white 40%));
|
||||
--color-purple-d60: color(#8f84ff blend(white 60%));
|
||||
--color-purple-l20: color(#8f84ff blend(black 20%));
|
||||
--color-purple-l40: color(#8f84ff blend(black 40%));
|
||||
--color-purple-l60: color(#8f84ff blend(black 60%));
|
||||
--color-background-purple-10: color(#17182b blend(#8f84ff 25%));
|
||||
--color-background-purple-20: color(#17182b blend(#8f84ff 35%));
|
||||
--color-background-purple-30: color(#17182b blend(#8f84ff 45%));
|
||||
--color-background-purple-60: color(#17182b blend(#8f84ff 85%));
|
||||
|
||||
--color-green-base: #2ca878;
|
||||
--color-green-d20: color(#2ca878 blend(white 20%));
|
||||
--color-green-d40: color(#2ca878 blend(white 40%));
|
||||
--color-green-d60: color(#2ca878 blend(white 60%));
|
||||
--color-green-l20: color(#2ca878 blend(black 20%));
|
||||
--color-green-l40: color(#2ca878 blend(black 40%));
|
||||
--color-green-l60: color(#2ca878 blend(black 60%));
|
||||
--color-background-green-10: color(#17182b blend(#2ca878 25%));
|
||||
--color-background-green-20: color(#17182b blend(#2ca878 35%));
|
||||
--color-background-green-30: color(#17182b blend(#2ca878 45%));
|
||||
--color-background-green-60: color(#17182b blend(#2ca878 85%));
|
||||
|
||||
--color-orange-base: #ef7f18;
|
||||
--color-orange-d20: color(#ef7f18 blend(white 20%));
|
||||
--color-orange-d40: color(#ef7f18 blend(white 40%));
|
||||
--color-orange-d60: color(#ef7f18 blend(white 60%));
|
||||
--color-orange-l20: color(#ef7f18 blend(black 20%));
|
||||
--color-orange-l40: color(#ef7f18 blend(black 40%));
|
||||
--color-orange-l60: color(#ef7f18 blend(black 60%));
|
||||
--color-background-orange-10: color(#17182b blend(#ef7f18 25%));
|
||||
--color-background-orange-20: color(#17182b blend(#ef7f18 35%));
|
||||
--color-background-orange-30: color(#17182b blend(#ef7f18 45%));
|
||||
--color-background-orange-60: color(#17182b blend(#ef7f18 85%));
|
||||
|
||||
--color-red-base: #be1621;
|
||||
--color-red-d20: color(#be1621 blend(white 20%));
|
||||
--color-red-d40: color(#be1621 blend(white 40%));
|
||||
--color-red-d60: color(#be1621 blend(white 60%));
|
||||
--color-red-l20: color(#be1621 blend(black 20%));
|
||||
--color-red-l40: color(#be1621 blend(black 40%));
|
||||
--color-red-l60: color(#be1621 blend(black 60%));
|
||||
--color-background-red-10: color(#17182b blend(#be1621 25%));
|
||||
--color-background-red-20: color(#17182b blend(#be1621 35%));
|
||||
--color-background-red-30: color(#17182b blend(#be1621 45%));
|
||||
--color-background-red-60: color(#17182b blend(#be1621 85%));
|
||||
}
|
||||
47
@xen-orchestra/web-core/lib/assets/css/_context.pcss
Normal file
47
@xen-orchestra/web-core/lib/assets/css/_context.pcss
Normal file
@@ -0,0 +1,47 @@
|
||||
.context-color-success {
|
||||
color: var(--color-green-base);
|
||||
}
|
||||
|
||||
.context-color-error {
|
||||
color: var(--color-red-base);
|
||||
}
|
||||
|
||||
.context-color-warning {
|
||||
color: var(--color-orange-base);
|
||||
}
|
||||
|
||||
.context-color-info {
|
||||
color: var(--color-purple-base);
|
||||
}
|
||||
|
||||
.context-background-color-success {
|
||||
background-color: var(--color-background-green-10);
|
||||
}
|
||||
|
||||
.context-background-color-error {
|
||||
background-color: var(--color-background-red-10);
|
||||
}
|
||||
|
||||
.context-background-color-warning {
|
||||
background-color: var(--color-background-orange-10);
|
||||
}
|
||||
|
||||
.context-background-color-info {
|
||||
background-color: var(--color-background-purple-10);
|
||||
}
|
||||
|
||||
.context-border-color-success {
|
||||
border-color: var(--color-green-base);
|
||||
}
|
||||
|
||||
.context-border-color-error {
|
||||
border-color: var(--color-red-base);
|
||||
}
|
||||
|
||||
.context-border-color-warning {
|
||||
border-color: var(--color-orange-base);
|
||||
}
|
||||
|
||||
.context-border-color-info {
|
||||
border-color: var(--color-purple-base);
|
||||
}
|
||||
6
@xen-orchestra/web-core/lib/assets/css/_fonts.pcss
Normal file
6
@xen-orchestra/web-core/lib/assets/css/_fonts.pcss
Normal file
@@ -0,0 +1,6 @@
|
||||
@import '@fontsource/poppins/400.css';
|
||||
@import '@fontsource/poppins/500.css';
|
||||
@import '@fontsource/poppins/600.css';
|
||||
@import '@fontsource/poppins/700.css';
|
||||
@import '@fontsource/poppins/900.css';
|
||||
@import '@fontsource/poppins/400-italic.css';
|
||||
42
@xen-orchestra/web-core/lib/assets/css/_reset.pcss
Normal file
42
@xen-orchestra/web-core/lib/assets/css/_reset.pcss
Normal file
@@ -0,0 +1,42 @@
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: inherit;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
font-family: Poppins, sans-serif;
|
||||
}
|
||||
|
||||
body,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
p,
|
||||
ol,
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
25
@xen-orchestra/web-core/lib/assets/css/_shadows.pcss
Normal file
25
@xen-orchestra/web-core/lib/assets/css/_shadows.pcss
Normal file
@@ -0,0 +1,25 @@
|
||||
:root {
|
||||
--shadow-100: 0 0.1rem 0.1rem 0 rgba(26, 27, 56, 0.06);
|
||||
|
||||
--shadow-200: 0 0.1rem 0.1rem 0 rgba(26, 27, 56, 0.08), 0 0.2rem 0.1rem 0 rgba(26, 27, 56, 0.06),
|
||||
0 0.1rem 0.3rem 0 rgba(26, 27, 56, 0.1);
|
||||
|
||||
--shadow-300: 0 0.6rem 1rem 0 rgba(26, 27, 56, 0.08), 0 0.1rem 1.8rem 0 rgba(26, 27, 56, 0.06),
|
||||
0 0.3rem 0.5rem 0 rgba(26, 27, 56, 0.1);
|
||||
|
||||
--shadow-400: 0 2.4rem 3.8rem 0 rgba(26, 27, 56, 0.04), 0 0.9rem 4.6rem 0 rgba(26, 27, 56, 0.06),
|
||||
0 1.1rem 1.5rem 0 rgba(26, 27, 56, 0.1);
|
||||
}
|
||||
|
||||
:root.dark {
|
||||
--shadow-100: 0 0.1rem 0.1rem 0 rgba(0, 0, 0, 0.12);
|
||||
|
||||
--shadow-200: 0 0.1rem 0.1rem 0 rgba(0, 0, 0, 0.16), 0 0.2rem 0.1rem 0 rgba(0, 0, 0, 0.12),
|
||||
0 0.1rem 0.3rem 0 rgba(0, 0, 0, 0.2);
|
||||
|
||||
--shadow-300: 0 0.6rem 1rem 0 rgba(0, 0, 0, 0.16), 0 0.1rem 1.8rem 0 rgba(0, 0, 0, 0.12),
|
||||
0 0.3rem 0.5rem 0 rgba(0, 0, 0, 0.2);
|
||||
|
||||
--shadow-400: 0 2.4rem 3.8rem 0 rgba(0, 0, 0, 0.08), 0 0.9rem 4.6rem 0 rgba(0, 0, 0, 0.12),
|
||||
0 1.1rem 1.5rem 0 rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
112
@xen-orchestra/web-core/lib/assets/css/_typography.pcss
Normal file
112
@xen-orchestra/web-core/lib/assets/css/_typography.pcss
Normal file
@@ -0,0 +1,112 @@
|
||||
.h1,
|
||||
.h2,
|
||||
.h3,
|
||||
.h4,
|
||||
.h5,
|
||||
.h6,
|
||||
.h7,
|
||||
.p1,
|
||||
.p2,
|
||||
.p3,
|
||||
.p4,
|
||||
.c1,
|
||||
.c2,
|
||||
.c3,
|
||||
.c4,
|
||||
.c5 {
|
||||
font-weight: 400;
|
||||
|
||||
&.black {
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
&.semi-bold {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&.medium {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
&.underline {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
&.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
.h4,
|
||||
.h5,
|
||||
.h6,
|
||||
.h7,
|
||||
.p1,
|
||||
.p2,
|
||||
.p3,
|
||||
.p4,
|
||||
.c1,
|
||||
.c2,
|
||||
.c3,
|
||||
.c4,
|
||||
.c5 {
|
||||
line-height: 1.5em;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
.h1 {
|
||||
font-size: 4.8rem;
|
||||
line-height: 6rem;
|
||||
}
|
||||
|
||||
.h2 {
|
||||
font-size: 3.6rem;
|
||||
line-height: 6rem;
|
||||
}
|
||||
|
||||
.h3 {
|
||||
font-size: 2.4rem;
|
||||
line-height: 3.2rem;
|
||||
}
|
||||
|
||||
.h4 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.h5 {
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
.h6,
|
||||
.p1,
|
||||
.c1 {
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
|
||||
.h7,
|
||||
.p2,
|
||||
.c2 {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.p3,
|
||||
.c3 {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.p4,
|
||||
.c4 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.c5 {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.c1,
|
||||
.c2,
|
||||
.c3,
|
||||
.c4,
|
||||
.c5 {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
15
@xen-orchestra/web-core/lib/assets/css/base.pcss
Normal file
15
@xen-orchestra/web-core/lib/assets/css/base.pcss
Normal file
@@ -0,0 +1,15 @@
|
||||
@import '_colors.pcss';
|
||||
@import '_reset.pcss';
|
||||
@import '_fonts.pcss';
|
||||
@import '_context.pcss';
|
||||
@import '_shadows.pcss';
|
||||
@import '_typography.pcss';
|
||||
|
||||
:root {
|
||||
color: var(--color-grey-100);
|
||||
background-color: var(--color-background-primary);
|
||||
|
||||
&.dark {
|
||||
color-scheme: dark;
|
||||
}
|
||||
}
|
||||
38
@xen-orchestra/web-core/lib/components/ui/UiCard.vue
Normal file
38
@xen-orchestra/web-core/lib/components/ui/UiCard.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<div :class="classProp" class="ui-card">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import { useContext } from '../../composables/context.composable'
|
||||
import type { Color } from '../../types/color'
|
||||
import { ColorContext } from '../../utils/context'
|
||||
|
||||
const props = defineProps<{
|
||||
color?: Color
|
||||
}>()
|
||||
|
||||
const { name: contextColor, backgroundClass } = useContext(ColorContext, () => props.color)
|
||||
|
||||
// We don't want to inherit "info" color
|
||||
const classProp = computed(() => {
|
||||
if (props.color === undefined && contextColor.value === 'info')
|
||||
return 'bg-primary'
|
||||
|
||||
return backgroundClass.value
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
.ui-card {
|
||||
padding: 2.1rem;
|
||||
border-radius: 0.8rem;
|
||||
box-shadow: var(--shadow-200);
|
||||
}
|
||||
|
||||
.bg-primary {
|
||||
background-color: var(--background-color-primary);
|
||||
}
|
||||
</style>
|
||||
19
@xen-orchestra/web-core/lib/components/ui/UiIcon.vue
Normal file
19
@xen-orchestra/web-core/lib/components/ui/UiIcon.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<UiSpinner v-if="busy" class="ui-icon" />
|
||||
<FontAwesomeIcon v-else-if="icon !== undefined" :icon="icon" class="ui-icon" :fixed-width="fixedWidth" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { IconDefinition } from '@fortawesome/fontawesome-common-types'
|
||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
||||
import UiSpinner from './UiSpinner.vue'
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
busy?: boolean
|
||||
icon?: IconDefinition
|
||||
fixedWidth?: boolean
|
||||
}>(),
|
||||
{ fixedWidth: true },
|
||||
)
|
||||
</script>
|
||||
47
@xen-orchestra/web-core/lib/components/ui/UiSpinner.vue
Normal file
47
@xen-orchestra/web-core/lib/components/ui/UiSpinner.vue
Normal file
@@ -0,0 +1,47 @@
|
||||
<!-- Adapted from https://www.benmvp.com/blog/how-to-create-circle-svg-gradient-loading-spinner/ -->
|
||||
|
||||
<template>
|
||||
<svg class="ui-spinner" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400" fill="none">
|
||||
<defs>
|
||||
<linearGradient :id="secondHalfId">
|
||||
<stop offset="0%" stop-opacity="0" stop-color="currentColor" />
|
||||
<stop offset="100%" stop-opacity="0.5" stop-color="currentColor" />
|
||||
</linearGradient>
|
||||
<linearGradient :id="firstHalfId">
|
||||
<stop offset="0%" stop-opacity="1" stop-color="currentColor" />
|
||||
<stop offset="100%" stop-opacity="0.5" stop-color="currentColor" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<g stroke-width="40">
|
||||
<path d="M 30 200 A 170 170 180 0 1 370 200" :stroke="`url(#${secondHalfId})`" />
|
||||
<path d="M 370 200 A 170 170 0 0 1 30 200" :stroke="`url(#${firstHalfId})`" />
|
||||
<path stroke="currentColor" stroke-linecap="round" d="M 30 200 A 170 170 180 0 1 30 200" />
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { uniqueId } from 'lodash-es'
|
||||
|
||||
const firstHalfId = uniqueId('spinner-first-half-')
|
||||
const secondHalfId = uniqueId('spinner-second-half-')
|
||||
</script>
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
.ui-spinner {
|
||||
width: 1.2em;
|
||||
height: 1.2em;
|
||||
animation: rotate 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,36 @@
|
||||
import type { ComputedRef, InjectionKey, MaybeRefOrGetter } from 'vue'
|
||||
import { computed, inject, provide, toValue } from 'vue'
|
||||
|
||||
type Context<T = any, Output = any> = ReturnType<typeof createContext<T, Output>>
|
||||
|
||||
type ContextOutput<Ctx extends Context> = Ctx extends Context<any, infer Output> ? Output : never
|
||||
|
||||
type ContextValue<Ctx extends Context> = Ctx extends Context<infer T> ? T : never
|
||||
|
||||
export function createContext<T, Output = ComputedRef<T>>(
|
||||
initialValue: MaybeRefOrGetter<T>,
|
||||
customBuilder?: (value: ComputedRef<T>) => Output,
|
||||
) {
|
||||
return {
|
||||
id: Symbol('context') as InjectionKey<MaybeRefOrGetter<T>>,
|
||||
initialValue,
|
||||
builder: customBuilder ?? (value => value as Output),
|
||||
}
|
||||
}
|
||||
|
||||
export function useContext<Ctx extends Context, T extends ContextValue<Ctx>>(
|
||||
context: Ctx,
|
||||
newValue?: MaybeRefOrGetter<T | undefined>,
|
||||
): ContextOutput<Ctx> {
|
||||
const currentValue = inject(context.id, context.initialValue)
|
||||
|
||||
const build = (value: MaybeRefOrGetter<T>) => context.builder(computed(() => toValue(value)))
|
||||
|
||||
if (newValue !== undefined) {
|
||||
const updatedValue = () => toValue(newValue) ?? toValue(currentValue)
|
||||
provide(context.id, updatedValue)
|
||||
return build(updatedValue)
|
||||
}
|
||||
|
||||
return build(currentValue)
|
||||
}
|
||||
1
@xen-orchestra/web-core/lib/types/color.ts
Normal file
1
@xen-orchestra/web-core/lib/types/color.ts
Normal file
@@ -0,0 +1 @@
|
||||
export type Color = 'info' | 'error' | 'warning' | 'success'
|
||||
12
@xen-orchestra/web-core/lib/utils/context.ts
Normal file
12
@xen-orchestra/web-core/lib/utils/context.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { computed } from 'vue'
|
||||
import { createContext } from '../composables/context.composable'
|
||||
import type { Color } from '../types/color'
|
||||
|
||||
export const DisabledContext = createContext(false)
|
||||
|
||||
export const ColorContext = createContext('info' as Color, color => ({
|
||||
name: color,
|
||||
textClass: computed(() => `context-color-${color.value}`),
|
||||
backgroundClass: computed(() => `context-background-color-${color.value}`),
|
||||
borderClass: computed(() => `context-border-color-${color.value}`),
|
||||
}))
|
||||
51
@xen-orchestra/web-core/package.json
Normal file
51
@xen-orchestra/web-core/package.json
Normal file
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"name": "@xen-orchestra/web-core",
|
||||
"type": "module",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"exports": {
|
||||
"./*": {
|
||||
"types": "./lib/*",
|
||||
"import": "./lib/*"
|
||||
},
|
||||
"./eslint": {
|
||||
"import": "./eslint.config.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"scripts": {
|
||||
"lint": "eslint",
|
||||
"lint:fix": "eslint --fix"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^2.4.6",
|
||||
"@fontsource/poppins": "^5.0.8",
|
||||
"@fortawesome/fontawesome-common-types": "^6.5.1",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.5.1",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.5.1",
|
||||
"@fortawesome/vue-fontawesome": "^3.0.5",
|
||||
"@tsconfig/node18": "^18.2.2",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^18.19.3",
|
||||
"@vitejs/plugin-vue": "^5.0.0-beta.1",
|
||||
"@vue/tsconfig": "^0.5.1",
|
||||
"@vueuse/core": "^10.7.0",
|
||||
"eslint": "^8.56.0",
|
||||
"glob": "^10.3.10",
|
||||
"lodash-es": "^4.17.21",
|
||||
"npm-run-all2": "^6.1.1",
|
||||
"pinia": "^2.1.7",
|
||||
"typescript": "~5.3.3",
|
||||
"vite": "^5.0.10",
|
||||
"vite-plugin-dts": "^3.6.4",
|
||||
"vite-plugin-lib-inject-css": "^1.3.0",
|
||||
"vue": "^3.4.0-beta.4",
|
||||
"vue-router": "^4.2.5",
|
||||
"vue-tsc": "^1.8.25"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*": "eslint --fix"
|
||||
}
|
||||
}
|
||||
10
@xen-orchestra/web-core/tsconfig.json
Normal file
10
@xen-orchestra/web-core/tsconfig.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": ["@vue/tsconfig/tsconfig.dom.json"],
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"module": "ESNext",
|
||||
"noEmit": true
|
||||
},
|
||||
"include": ["env.d.ts", "eslint.config.js", "lib/**/*", "lib/**/*.vue"],
|
||||
"exclude": ["lib/**/__tests__/*"]
|
||||
}
|
||||
31
@xen-orchestra/web-lite/.gitignore
vendored
Normal file
31
@xen-orchestra/web-lite/.gitignore
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
coverage
|
||||
*.local
|
||||
|
||||
/cypress/videos/
|
||||
/cypress/screenshots/
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
*.tsbuildinfo
|
||||
typed-router.d.ts
|
||||
3
@xen-orchestra/web-lite/.vscode/extensions.json
vendored
Normal file
3
@xen-orchestra/web-lite/.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
|
||||
}
|
||||
40
@xen-orchestra/web-lite/README.md
Normal file
40
@xen-orchestra/web-lite/README.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# web-lite
|
||||
|
||||
This template should help get you started developing with Vue 3 in Vite.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
|
||||
|
||||
## Type Support for `.vue` Imports in TS
|
||||
|
||||
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
|
||||
|
||||
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
|
||||
|
||||
1. Disable the built-in TypeScript Extension
|
||||
1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette
|
||||
2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
|
||||
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
|
||||
|
||||
## Customize configuration
|
||||
|
||||
See [Vite Configuration Reference](https://vitejs.dev/config/).
|
||||
|
||||
## Project Setup
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compile and Hot-Reload for Development
|
||||
|
||||
```sh
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Type-Check, Compile and Minify for Production
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
```
|
||||
1
@xen-orchestra/web-lite/env.d.ts
vendored
Normal file
1
@xen-orchestra/web-lite/env.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
||||
1
@xen-orchestra/web-lite/eslint.config.js
Normal file
1
@xen-orchestra/web-lite/eslint.config.js
Normal file
@@ -0,0 +1 @@
|
||||
export { default } from '@xen-orchestra/web-core/eslint'
|
||||
13
@xen-orchestra/web-lite/index.html
Normal file
13
@xen-orchestra/web-lite/index.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
40
@xen-orchestra/web-lite/package.json
Normal file
40
@xen-orchestra/web-lite/package.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "@xen-orchestra/web-lite",
|
||||
"type": "module",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "run-p type-check \"build-only {@}\" --",
|
||||
"preview": "vite preview",
|
||||
"build-only": "vite build",
|
||||
"type-check": "vue-tsc --build --force",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint . --fix"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^2.4.6",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.5.1",
|
||||
"@tsconfig/node18": "^18.2.2",
|
||||
"@types/node": "^18.19.3",
|
||||
"@vitejs/plugin-vue": "^5.0.0-beta.1",
|
||||
"@vue/tsconfig": "^0.5.1",
|
||||
"@vueuse/core": "^10.7.0",
|
||||
"@xen-orchestra/web-core": "^0.0.1",
|
||||
"eslint": "^8.56.0",
|
||||
"npm-run-all2": "^6.1.1",
|
||||
"pinia": "^2.1.7",
|
||||
"postcss-apply": "^0.12.0",
|
||||
"postcss-color-function": "^4.1.0",
|
||||
"postcss-nested": "^6.0.1",
|
||||
"typescript": "~5.3.3",
|
||||
"unplugin-vue-router": "^0.7.0",
|
||||
"vite": "^5.0.10",
|
||||
"vue": "^3.4.0-beta.4",
|
||||
"vue-router": "^4.2.5",
|
||||
"vue-tsc": "^1.8.25"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*": "eslint --fix"
|
||||
}
|
||||
}
|
||||
9
@xen-orchestra/web-lite/postcss.config.cjs
Normal file
9
@xen-orchestra/web-lite/postcss.config.cjs
Normal file
@@ -0,0 +1,9 @@
|
||||
'use strict'
|
||||
|
||||
module.exports = {
|
||||
plugins: {
|
||||
'postcss-apply': {},
|
||||
'postcss-nested': {},
|
||||
'postcss-color-function': {},
|
||||
},
|
||||
}
|
||||
0
@xen-orchestra/web-lite/public/favicon.ico
Normal file
0
@xen-orchestra/web-lite/public/favicon.ico
Normal file
3
@xen-orchestra/web-lite/src/App.vue
Normal file
3
@xen-orchestra/web-lite/src/App.vue
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<RouterView />
|
||||
</template>
|
||||
19
@xen-orchestra/web-lite/src/layouts/MainLayout.vue
Normal file
19
@xen-orchestra/web-lite/src/layouts/MainLayout.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<div class="main-layout">
|
||||
<div>XO Lite Main Layout</div>
|
||||
<div class="content">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
.main-layout {
|
||||
font-size: 2rem;
|
||||
padding: 4rem;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 1rem 2rem;
|
||||
}
|
||||
</style>
|
||||
18
@xen-orchestra/web-lite/src/main.ts
Normal file
18
@xen-orchestra/web-lite/src/main.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import '@xen-orchestra/web-core/assets/css/base.pcss'
|
||||
import { createPinia } from 'pinia'
|
||||
|
||||
import { createApp } from 'vue'
|
||||
import { createRouter, createWebHashHistory } from 'vue-router/auto'
|
||||
|
||||
import App from './App.vue'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
})
|
||||
|
||||
app.use(createPinia())
|
||||
app.use(router)
|
||||
|
||||
app.mount('#app')
|
||||
30
@xen-orchestra/web-lite/src/pages/index.vue
Normal file
30
@xen-orchestra/web-lite/src/pages/index.vue
Normal file
@@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<MainLayout>
|
||||
<UiCard color="info">
|
||||
<div>Welcome on XO Lite main page</div>
|
||||
<div>
|
||||
Demo icon from web-core:
|
||||
<UiIcon :icon="faShip" />
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
@click="toggleDark()"
|
||||
>
|
||||
Toggle Dark Mode {{ isDark ? 'OFF' : 'ON' }}
|
||||
</button>
|
||||
</div>
|
||||
</UiCard>
|
||||
</MainLayout>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { faShip } from '@fortawesome/free-solid-svg-icons/faShip'
|
||||
import { useDark, useToggle } from '@vueuse/core'
|
||||
import UiCard from '@xen-orchestra/web-core/components/ui/UiCard.vue'
|
||||
import UiIcon from '@xen-orchestra/web-core/components/ui/UiIcon.vue'
|
||||
import MainLayout from '@/layouts/MainLayout.vue'
|
||||
|
||||
const isDark = useDark()
|
||||
const toggleDark = useToggle(isDark)
|
||||
</script>
|
||||
22
@xen-orchestra/web-lite/tsconfig.app.json
Normal file
22
@xen-orchestra/web-lite/tsconfig.app.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"baseUrl": ".",
|
||||
"rootDir": "..",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"],
|
||||
"@xen-orchestra/web-core/*": ["../web-core/lib/*"]
|
||||
},
|
||||
"noEmit": true
|
||||
},
|
||||
"include": [
|
||||
"env.d.ts",
|
||||
"typed-router.d.ts",
|
||||
"src/**/*",
|
||||
"src/**/*.vue",
|
||||
"../web-core/lib/**/*",
|
||||
"../web-core/lib/**/*.vue"
|
||||
],
|
||||
"exclude": ["src/**/__tests__/*"]
|
||||
}
|
||||
11
@xen-orchestra/web-lite/tsconfig.json
Normal file
11
@xen-orchestra/web-lite/tsconfig.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.node.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.app.json"
|
||||
}
|
||||
],
|
||||
"files": []
|
||||
}
|
||||
11
@xen-orchestra/web-lite/tsconfig.node.json
Normal file
11
@xen-orchestra/web-lite/tsconfig.node.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "@tsconfig/node18/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"types": ["node"],
|
||||
"noEmit": true
|
||||
},
|
||||
"include": ["vite.config.*", "vitest.config.*", "cypress.config.*", "nightwatch.conf.*", "playwright.config.*"]
|
||||
}
|
||||
15
@xen-orchestra/web-lite/vite.config.ts
Normal file
15
@xen-orchestra/web-lite/vite.config.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { URL, fileURLToPath } from 'node:url'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import vueRouter from 'unplugin-vue-router/vite'
|
||||
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [vueRouter(), vue()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
||||
},
|
||||
},
|
||||
})
|
||||
31
@xen-orchestra/web/.gitignore
vendored
Normal file
31
@xen-orchestra/web/.gitignore
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
coverage
|
||||
*.local
|
||||
|
||||
/cypress/videos/
|
||||
/cypress/screenshots/
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
*.tsbuildinfo
|
||||
typed-router.d.ts
|
||||
3
@xen-orchestra/web/.vscode/extensions.json
vendored
Normal file
3
@xen-orchestra/web/.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
|
||||
}
|
||||
40
@xen-orchestra/web/README.md
Normal file
40
@xen-orchestra/web/README.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# web
|
||||
|
||||
This template should help get you started developing with Vue 3 in Vite.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
|
||||
|
||||
## Type Support for `.vue` Imports in TS
|
||||
|
||||
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
|
||||
|
||||
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
|
||||
|
||||
1. Disable the built-in TypeScript Extension
|
||||
1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette
|
||||
2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
|
||||
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
|
||||
|
||||
## Customize configuration
|
||||
|
||||
See [Vite Configuration Reference](https://vitejs.dev/config/).
|
||||
|
||||
## Project Setup
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compile and Hot-Reload for Development
|
||||
|
||||
```sh
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Type-Check, Compile and Minify for Production
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
```
|
||||
1
@xen-orchestra/web/env.d.ts
vendored
Normal file
1
@xen-orchestra/web/env.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
||||
1
@xen-orchestra/web/eslint.config.js
Normal file
1
@xen-orchestra/web/eslint.config.js
Normal file
@@ -0,0 +1 @@
|
||||
export { default } from '@xen-orchestra/web-core/eslint'
|
||||
13
@xen-orchestra/web/index.html
Normal file
13
@xen-orchestra/web/index.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
38
@xen-orchestra/web/package.json
Normal file
38
@xen-orchestra/web/package.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "@xen-orchestra/web",
|
||||
"type": "module",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "run-p type-check \"build-only {@}\" --",
|
||||
"preview": "vite preview",
|
||||
"build-only": "vite build",
|
||||
"type-check": "vue-tsc --build --force",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint . --fix"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^2.4.6",
|
||||
"@tsconfig/node18": "^18.2.2",
|
||||
"@types/node": "^18.19.3",
|
||||
"@vitejs/plugin-vue": "^5.0.0-beta.1",
|
||||
"@vue/tsconfig": "^0.5.1",
|
||||
"@xen-orchestra/web-core": "^0.0.1",
|
||||
"eslint": "^8.56.0",
|
||||
"npm-run-all2": "^6.1.1",
|
||||
"pinia": "^2.1.7",
|
||||
"postcss-apply": "^0.12.0",
|
||||
"postcss-color-function": "^4.1.0",
|
||||
"postcss-nested": "^6.0.1",
|
||||
"typescript": "~5.3.3",
|
||||
"unplugin-vue-router": "^0.7.0",
|
||||
"vite": "^5.0.10",
|
||||
"vue": "^3.4.0-beta.4",
|
||||
"vue-router": "^4.2.5",
|
||||
"vue-tsc": "^1.8.25"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*": "eslint --fix"
|
||||
}
|
||||
}
|
||||
9
@xen-orchestra/web/postcss.config.js
Normal file
9
@xen-orchestra/web/postcss.config.js
Normal file
@@ -0,0 +1,9 @@
|
||||
'use strict'
|
||||
|
||||
module.exports = {
|
||||
plugins: {
|
||||
'postcss-apply': {},
|
||||
'postcss-nested': {},
|
||||
'postcss-color-function': {},
|
||||
},
|
||||
}
|
||||
0
@xen-orchestra/web/public/favicon.ico
Normal file
0
@xen-orchestra/web/public/favicon.ico
Normal file
3
@xen-orchestra/web/src/App.vue
Normal file
3
@xen-orchestra/web/src/App.vue
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<RouterView />
|
||||
</template>
|
||||
20
@xen-orchestra/web/src/layouts/MainLayout.vue
Normal file
20
@xen-orchestra/web/src/layouts/MainLayout.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<div class="main-layout">
|
||||
<div>XO 6 Main Layout</div>
|
||||
<div class="content">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
.main-layout {
|
||||
padding: 8rem;
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 2rem 4rem;
|
||||
border-bottom: 2px solid black;
|
||||
}
|
||||
</style>
|
||||
18
@xen-orchestra/web/src/main.ts
Normal file
18
@xen-orchestra/web/src/main.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import '@xen-orchestra/web-core/assets/css/base.pcss'
|
||||
import { createPinia } from 'pinia'
|
||||
|
||||
import { createApp } from 'vue'
|
||||
import { createRouter, createWebHashHistory } from 'vue-router/auto'
|
||||
|
||||
import App from './App.vue'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
})
|
||||
|
||||
app.use(createPinia())
|
||||
app.use(router)
|
||||
|
||||
app.mount('#app')
|
||||
27
@xen-orchestra/web/src/pages/index.vue
Normal file
27
@xen-orchestra/web/src/pages/index.vue
Normal file
@@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<MainLayout>
|
||||
<UiCard color="info">
|
||||
<div>Welcome on XO 6 main page</div>
|
||||
<div>
|
||||
Demo icon from web-core:
|
||||
<UiIcon :icon="faRocket" />
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" @click="toggleDark()">
|
||||
Toggle Dark Mode {{ isDark ? 'OFF' : 'ON' }}
|
||||
</button>
|
||||
</div>
|
||||
</UiCard>
|
||||
</MainLayout>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { faRocket } from '@fortawesome/free-solid-svg-icons/faRocket'
|
||||
import { useDark, useToggle } from '@vueuse/core'
|
||||
import UiCard from '@xen-orchestra/web-core/components/ui/UiCard.vue'
|
||||
import UiIcon from '@xen-orchestra/web-core/components/ui/UiIcon.vue'
|
||||
import MainLayout from '@/layouts/MainLayout.vue'
|
||||
|
||||
const isDark = useDark()
|
||||
const toggleDark = useToggle(isDark)
|
||||
</script>
|
||||
22
@xen-orchestra/web/tsconfig.app.json
Normal file
22
@xen-orchestra/web/tsconfig.app.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"baseUrl": ".",
|
||||
"rootDir": "..",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"],
|
||||
"@xen-orchestra/web-core/*": ["../web-core/lib/*"]
|
||||
},
|
||||
"noEmit": true
|
||||
},
|
||||
"include": [
|
||||
"env.d.ts",
|
||||
"typed-router.d.ts",
|
||||
"src/**/*",
|
||||
"src/**/*.vue",
|
||||
"../web-core/lib/**/*",
|
||||
"../web-core/lib/**/*.vue"
|
||||
],
|
||||
"exclude": ["src/**/__tests__/*"]
|
||||
}
|
||||
11
@xen-orchestra/web/tsconfig.json
Normal file
11
@xen-orchestra/web/tsconfig.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.node.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.app.json"
|
||||
}
|
||||
],
|
||||
"files": []
|
||||
}
|
||||
11
@xen-orchestra/web/tsconfig.node.json
Normal file
11
@xen-orchestra/web/tsconfig.node.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "@tsconfig/node18/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"types": ["node"],
|
||||
"noEmit": true
|
||||
},
|
||||
"include": ["vite.config.*", "vitest.config.*", "cypress.config.*", "nightwatch.conf.*", "playwright.config.*"]
|
||||
}
|
||||
15
@xen-orchestra/web/vite.config.ts
Normal file
15
@xen-orchestra/web/vite.config.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { URL, fileURLToPath } from 'node:url'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import vueRouter from 'unplugin-vue-router/vite'
|
||||
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [vueRouter(), vue()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
||||
},
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user