Compare commits
2 Commits
fix_stats_
...
lite/conso
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72454ac593 | ||
|
|
4a45e78c1c |
@@ -1,5 +1,9 @@
|
|||||||
# ChangeLog
|
# ChangeLog
|
||||||
|
|
||||||
|
## **next**
|
||||||
|
|
||||||
|
- Add ability to open VM console in new window (PR [#6827](https://github.com/vatesfr/xen-orchestra/pull/6827))
|
||||||
|
|
||||||
## **0.2.0**
|
## **0.2.0**
|
||||||
|
|
||||||
- Invalidate sessionId token after logout (PR [#6480](https://github.com/vatesfr/xen-orchestra/pull/6480))
|
- Invalidate sessionId token after logout (PR [#6480](https://github.com/vatesfr/xen-orchestra/pull/6480))
|
||||||
|
|||||||
@@ -24,9 +24,9 @@
|
|||||||
<AppLogin />
|
<AppLogin />
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<AppHeader />
|
<AppHeader v-if="uiStore.hasUi" />
|
||||||
<div style="display: flex">
|
<div style="display: flex">
|
||||||
<AppNavigation />
|
<AppNavigation v-if="uiStore.hasUi" />
|
||||||
<main class="main">
|
<main class="main">
|
||||||
<RouterView />
|
<RouterView />
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="vmConsoleContainer" class="vm-console" />
|
<div ref="consoleContainer" class="remote-console" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@@ -19,7 +19,7 @@ const props = defineProps<{
|
|||||||
isConsoleAvailable: boolean;
|
isConsoleAvailable: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const vmConsoleContainer = ref<HTMLDivElement>();
|
const consoleContainer = ref<HTMLDivElement>();
|
||||||
const xenApiStore = useXenApiStore();
|
const xenApiStore = useXenApiStore();
|
||||||
const url = computed(() => {
|
const url = computed(() => {
|
||||||
if (xenApiStore.currentSessionId == null) {
|
if (xenApiStore.currentSessionId == null) {
|
||||||
@@ -78,7 +78,7 @@ const createVncConnection = async () => {
|
|||||||
await promiseTimeout(FIBONACCI_MS_ARRAY[nConnectionAttempts - 1]);
|
await promiseTimeout(FIBONACCI_MS_ARRAY[nConnectionAttempts - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
vncClient = new VncClient(vmConsoleContainer.value!, url.value!.toString(), {
|
vncClient = new VncClient(consoleContainer.value!, url.value!.toString(), {
|
||||||
wsProtocols: ["binary"],
|
wsProtocols: ["binary"],
|
||||||
});
|
});
|
||||||
vncClient.scaleViewport = true;
|
vncClient.scaleViewport = true;
|
||||||
@@ -91,7 +91,7 @@ watch(url, clearVncClient);
|
|||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
if (
|
if (
|
||||||
url.value === undefined ||
|
url.value === undefined ||
|
||||||
vmConsoleContainer.value === undefined ||
|
consoleContainer.value === undefined ||
|
||||||
!props.isConsoleAvailable
|
!props.isConsoleAvailable
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
@@ -107,8 +107,8 @@ onBeforeUnmount(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="postcss" scoped>
|
<style lang="postcss" scoped>
|
||||||
.vm-console {
|
.remote-console {
|
||||||
height: 80rem;
|
height: 100%;
|
||||||
|
|
||||||
& > :deep(div) {
|
& > :deep(div) {
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { useBreakpoints, useColorMode } from "@vueuse/core";
|
import { useBreakpoints, useColorMode } from "@vueuse/core";
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { computed, ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
|
import { useRoute } from "vue-router";
|
||||||
|
|
||||||
export const useUiStore = defineStore("ui", () => {
|
export const useUiStore = defineStore("ui", () => {
|
||||||
const currentHostOpaqueRef = ref();
|
const currentHostOpaqueRef = ref();
|
||||||
@@ -13,10 +14,15 @@ export const useUiStore = defineStore("ui", () => {
|
|||||||
|
|
||||||
const isMobile = computed(() => !isDesktop.value);
|
const isMobile = computed(() => !isDesktop.value);
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
|
||||||
|
const hasUi = computed(() => route.query.ui !== "0");
|
||||||
|
|
||||||
return {
|
return {
|
||||||
colorMode,
|
colorMode,
|
||||||
currentHostOpaqueRef,
|
currentHostOpaqueRef,
|
||||||
isDesktop,
|
isDesktop,
|
||||||
isMobile,
|
isMobile,
|
||||||
|
hasUi,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,20 +1,34 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="!isReady">Loading...</div>
|
<div v-if="!isReady">Loading...</div>
|
||||||
<div v-else-if="!isVmRunning">Console is only available for running VMs.</div>
|
<div v-else-if="!isVmRunning">Console is only available for running VMs.</div>
|
||||||
<RemoteConsole
|
<template v-else-if="vm && vmConsole">
|
||||||
v-else-if="vm && vmConsole"
|
<RemoteConsole
|
||||||
:location="vmConsole.location"
|
:is-console-available="!isOperationsPending(vm, STOP_OPERATIONS)"
|
||||||
:is-console-available="!isOperationsPending(vm, STOP_OPERATIONS)"
|
:location="vmConsole.location"
|
||||||
/>
|
class="remote-console"
|
||||||
|
/>
|
||||||
|
<RouterLink
|
||||||
|
v-if="uiStore.hasUi"
|
||||||
|
:to="{ query: { ui: '0' } }"
|
||||||
|
class="open-link"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<UiIcon :icon="faArrowUpRightFromSquare" />
|
||||||
|
Open in new window
|
||||||
|
</RouterLink>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import RemoteConsole from "@/components/RemoteConsole.vue";
|
||||||
|
import UiIcon from "@/components/ui/icon/UiIcon.vue";
|
||||||
|
import { isOperationsPending } from "@/libs/utils";
|
||||||
|
import { useConsoleStore } from "@/stores/console.store";
|
||||||
|
import { useUiStore } from "@/stores/ui.store";
|
||||||
|
import { useVmStore } from "@/stores/vm.store";
|
||||||
|
import { faArrowUpRightFromSquare } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
import RemoteConsole from "@/components/RemoteConsole.vue";
|
|
||||||
import { useConsoleStore } from "@/stores/console.store";
|
|
||||||
import { useVmStore } from "@/stores/vm.store";
|
|
||||||
import { isOperationsPending } from "@/libs/utils";
|
|
||||||
|
|
||||||
const STOP_OPERATIONS = [
|
const STOP_OPERATIONS = [
|
||||||
"shutdown",
|
"shutdown",
|
||||||
@@ -26,6 +40,7 @@ const STOP_OPERATIONS = [
|
|||||||
"suspend",
|
"suspend",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const uiStore = useUiStore();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
const { isReady: isVmReady, getByUuid: getVmByUuid } = useVmStore().subscribe();
|
const { isReady: isVmReady, getByUuid: getVmByUuid } = useVmStore().subscribe();
|
||||||
@@ -49,3 +64,31 @@ const vmConsole = computed(() => {
|
|||||||
return getConsoleByOpaqueRef(consoleOpaqueRef);
|
return getConsoleByOpaqueRef(consoleOpaqueRef);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="postcss" scoped>
|
||||||
|
.open-link {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
background-color: var(--color-extra-blue-base);
|
||||||
|
color: var(--color-blue-scale-500);
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 1.5rem;
|
||||||
|
font-size: 1.6rem;
|
||||||
|
border-radius: 0 0 0 0.8rem;
|
||||||
|
position: absolute;
|
||||||
|
top: 8rem;
|
||||||
|
right: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
transform: translateX(calc(100% - 4.5rem));
|
||||||
|
transition: transform 0.2s ease-in-out;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.remote-console {
|
||||||
|
height: calc(100% - 8rem);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<ObjectNotFoundWrapper :is-ready="isReady" :uuid-checker="hasUuid">
|
<ObjectNotFoundWrapper :is-ready="isReady" :uuid-checker="hasUuid">
|
||||||
<VmHeader />
|
<VmHeader v-if="uiStore.hasUi" />
|
||||||
<RouterView />
|
<RouterView />
|
||||||
</ObjectNotFoundWrapper>
|
</ObjectNotFoundWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user