feat(web): WIP updateOs callback

This commit is contained in:
Zack Spear
2023-09-12 17:21:24 -07:00
committed by Zack Spear
parent 313736e3c6
commit 6fb916eccd
3 changed files with 124 additions and 55 deletions

View File

@@ -1,6 +1,6 @@
<script lang="ts" setup>
import { useClipboard } from '@vueuse/core';
import { ClipboardIcon, CogIcon } from '@heroicons/vue/24/solid';
import { ChevronDoubleDownIcon, ClipboardIcon, CogIcon } from '@heroicons/vue/24/solid';
import { storeToRefs } from 'pinia';
import 'tailwindcss/tailwind.css';
import '~/assets/main.css';
@@ -10,6 +10,7 @@ import { useCallbackActionsStore } from '~/store/callbackActions';
import { useInstallKeyStore } from '~/store/installKey';
// import { usePromoStore } from '~/store/promo';
import { useServerStore } from '~/store/server';
import { useUpdateOsStore } from '~/store/updateOs';
export interface Props {
open?: boolean;
@@ -25,6 +26,7 @@ const callbackActionsStore = useCallbackActionsStore();
const installKeyStore = useInstallKeyStore();
// const promoStore = usePromoStore();
const serverStore = useServerStore();
const updateOsStore = useUpdateOsStore();
const {
accountAction,
@@ -45,7 +47,12 @@ const {
connectPluginInstalled,
refreshServerStateStatus,
username,
osVersion,
} = storeToRefs(serverStore);
const {
status: updateOsStatus,
callbackUpdateRelease,
} = storeToRefs(updateOsStore);
/**
* Post sign in success state:
* If we're on the Connect settings page in the webGUI
@@ -59,6 +66,9 @@ const isSettingsPage = ref<boolean>(document.location.pathname === '/Settings/Ma
// const showPromoCta = computed(() => callbackStatus.value === 'success' && !connectPluginInstalled.value);
const heading = computed(() => {
if (updateOsStatus.value === 'confirming') {
return props.t('Update Unraid OS confirmation required');
}
switch (callbackStatus.value) {
case 'error':
return props.t('Error');
@@ -69,6 +79,9 @@ const heading = computed(() => {
}
});
const subheading = computed(() => {
if (updateOsStatus.value === 'confirming') {
return props.t('Please confirm the update details below');
}
if (callbackStatus.value === 'error') {
return props.t('Something went wrong'); /** @todo show actual error messages */
}
@@ -95,13 +108,16 @@ const close = () => {
: window.location.reload();
};
const cancelUpdateOs = () => {
updateOsStore.setStatus('ready');
callbackActionsStore.setCallbackStatus('ready')
};
// const promoClick = () => {
// promoStore.openOnNextLoad();
// close();
// };
const { copy, copied, isSupported } = useClipboard({ source: keyUrl.value });
const keyInstallStatusCopy = computed((): { text: string; } => {
let txt1 = props.t('Installing');
let txt2 = props.t('Installed');
@@ -167,6 +183,8 @@ const accountActionStatusCopy = computed((): { text: string; } => {
};
}
});
const { copy, copied, isSupported } = useClipboard({ source: keyUrl.value });
</script>
<template>
@@ -237,38 +255,69 @@ const accountActionStatusCopy = computed((): { text: string; } => {
:text="t('Enhance your experience with Unraid Connect')"
/> -->
</div>
<template v-if="updateOsStatus === 'confirming'">
<div class="text-center flex flex-col gap-y-8px my-16px">
<div class="flex flex-col gap-y-4px">
<p class="text-18px">
{{ t('Current Version: Unraid {0}', [osVersion]) }}
</p>
<ChevronDoubleDownIcon class="w-32px h-32px mx-auto fill-current opacity-50" />
<p class="text-18px">
{{ t('New Version: {0}', [callbackUpdateRelease?.name]) }}
</p>
<p class="text-14px italic opacity-75">
{{ t('This update will require a reboot') }}
</p>
</div>
</div>
</template>
</template>
<template v-if="callbackStatus === 'success'" #footer>
<template v-if="callbackStatus === 'success' || updateOsStatus === 'confirming'" #footer>
<div class="flex flex-row justify-center gap-16px">
<BrandButton
btn-style="underline"
:text="closeText"
@click="close"
/>
<template v-if="connectPluginInstalled && accountActionType === 'signIn'">
<template v-if="callbackStatus === 'success'">
<BrandButton
v-if="isSettingsPage"
:icon="CogIcon"
:text="t('Configure Connect Features')"
class="grow-0"
btn-style="underline"
:text="closeText"
@click="close"
/>
<BrandButton
v-else
:href="PLUGIN_SETTINGS.toString()"
:icon="CogIcon"
:text="t('Configure Connect Features')"
class="grow-0"
/>
<template v-if="connectPluginInstalled && accountActionType === 'signIn'">
<BrandButton
v-if="isSettingsPage"
:icon="CogIcon"
:text="t('Configure Connect Features')"
class="grow-0"
@click="close"
/>
<BrandButton
v-else
:href="PLUGIN_SETTINGS.toString()"
:icon="CogIcon"
:text="t('Configure Connect Features')"
class="grow-0"
/>
</template>
<!-- <BrandButton
v-if="showPromoCta"
:text="t('Learn More')"
@click="promoClick"
/> -->
</template>
<!-- <BrandButton
v-if="showPromoCta"
:text="t('Learn More')"
@click="promoClick"
/> -->
<template v-if="updateOsStatus === 'confirming'">
<BrandButton
btn-style="underline"
:text="t('Cancel')"
@click="cancelUpdateOs"
/>
<BrandButton
:text="t('Confirm and start update')"
@click="updateOsStore.installOsUpdate()"
/>
</template>
</div>
</template>
</Modal>

View File

@@ -60,6 +60,7 @@
"No thanks": "No thanks",
"Learn more": "Learn more",
"Install Connect": "Install Connect",
"Installing Connect": "Installing Connect",
"Close Modal": "Close Modal",
"Close": "Close",
"Reload": "Reload",
@@ -203,5 +204,11 @@
"Signing Out": "Signing Out",
"Sign In requires the local unraid-api to be running": "Sign In requires the local unraid-api to be running",
"Sign Out requires the local unraid-api to be running": "Sign Out requires the local unraid-api to be running",
"Unraid OS Update Available": "Unraid OS Update Available"
"Unraid OS Update Available": "Unraid OS Update Available",
"Update Unraid OS confirmation required": "Update Unraid OS confirmation required",
"Please confirm the update details below": "Please confirm the update details below",
"Current Version: Unraid {0}": "Current Version: Unraid {0}",
"New Version: {0}": "New Version: {0}",
"This update will require a reboot": "This update will require a reboot",
"Confirm and start update": "Confirm and start update"
}

View File

@@ -2,11 +2,14 @@ import { BellAlertIcon } from '@heroicons/vue/24/solid';
import { defineStore, createPinia, setActivePinia } from 'pinia';
import gt from 'semver/functions/gt';
import useInstallPlugin from '~/composables/installPlugin';
import { request } from '~/composables/services/request';
import { ACCOUNT_CALLBACK, OS_RELEASES } from '~/helpers/urls';
import { useCallbackStore } from '~/store/callbackActions';
import { useErrorsStore } from '~/store/errors';
import { useServerStore } from '~/store/server';
import type { InstallPluginPayload } from '~/composables/installPlugin';
import type { OsRelease } from '~/store/callback';
import type { ServerStateDataAction } from '~/types/server';
/**
@@ -15,29 +18,17 @@ import type { ServerStateDataAction } from '~/types/server';
*/
setActivePinia(createPinia());
export interface OsRelease {
basefile: string; // "unRAIDServer-6.12.4-x86_64.zip"
changelog: string; // "https://unraid-dl.sfo2.cdn.digitaloceanspaces.com/stable/unRAIDServer-6.12.4-x86_64.txt"
date: string; // "2023-08-31"
md5: string; // "df6e5859d28c14617efde36d59458206"
name: string; // "Unraid 6.12.4"
size: string; // "439999418"
url: string; // "https://unraid-dl.sfo2.cdn.digitaloceanspaces.com/stable/unRAIDServer-6.12.4-x86_64.zip"
}
export const useUpdateOsStore = defineStore('updateOs', () => {
const callbackStore = useCallbackStore();
const errorsStore = useErrorsStore();
const serverStore = useServerStore();
const { install: installPlugin } = useInstallPlugin();
// State
const status = ref<'failed' | 'ready' | 'success' | 'updating' | 'downgrading'>('ready');
const updateAvailable = ref<OsRelease | undefined>();
watchEffect(() => {
if (updateAvailable.value) {
console.debug('[useUpdateOsStore] updateAvailable', updateAvailable.value);
}
});
const status = ref<'confirming' | 'failed' | 'ready' | 'success' | 'updating' | 'downgrading'>('ready');
const callbackUpdateRelease = ref<OsRelease | undefined>(); // used when coming back from callback, this will be the release to install
const updateAvailable = ref<OsRelease | undefined>(); // used locally to show update action button
const downgradeAvailable = ref<boolean>(false);
// Getters
@@ -66,16 +57,6 @@ export const useUpdateOsStore = defineStore('updateOs', () => {
}
};
const downgradeOs = async () => {
console.debug('[downgradeOs]');
status.value = 'downgrading';
};
const installOsUpdate = (plgUrl: string) => {
console.debug('[installOsUpdate]', plgUrl);
status.value = 'updating';
};
const initUpdateOsCallback = computed((): ServerStateDataAction => {
return {
click: () => {
@@ -98,14 +79,46 @@ export const useUpdateOsStore = defineStore('updateOs', () => {
}
});
const confirmUpdateOs = (payload: OsRelease) => {
console.debug('[confirmUpdateOs]');
callbackUpdateRelease.value = payload;
setStatus('confirming');
};
const installOsUpdate = () => {
console.debug('[installOsUpdate]', callbackUpdateRelease.value);
if (!callbackUpdateRelease.value) {
return console.error('[installOsUpdate] release not found');
}
status.value = 'updating';
installPlugin({
modalTitle: `${callbackUpdateRelease.value.name} Update`,
pluginUrl: callbackUpdateRelease.value.url,
update: true,
});
};
const downgradeOs = async () => {
console.debug('[downgradeOs]');
setStatus('downgrading');
};
const setStatus = (payload: typeof status.value) => {
status.value = payload;
};
return {
// State
callbackUpdateRelease,
status,
updateAvailable,
// Actions
checkForOsUpdate,
confirmUpdateOs,
downgradeOs,
installOsUpdate,
initUpdateOsCallback,
setStatus,
};
});