mirror of
https://github.com/unraid/api.git
synced 2026-01-05 16:09:49 -06:00
refactor: code readability for callbacks feedback
This commit is contained in:
@@ -20,9 +20,9 @@ const accountStore = useAccountStore();
|
||||
const callbackActionsStore = useCallbackActionsStore();
|
||||
const installKeyStore = useInstallKeyStore();
|
||||
|
||||
const { updating, updateSuccess } = storeToRefs(accountStore);
|
||||
const { accountUpdating, accountSuccess } = storeToRefs(accountStore);
|
||||
const { callbackLoading } = storeToRefs(callbackActionsStore);
|
||||
const { keyUrl, keyType, installing, success } = storeToRefs(installKeyStore);
|
||||
const { keyUrl, keyType, keyInstalling, keySuccess } = storeToRefs(installKeyStore);
|
||||
|
||||
const heading = computed(() => callbackLoading.value ? 'Performing actions' : 'Finished performing actions');
|
||||
const subheading = computed(() => callbackLoading.value ? 'Please keep this window open' : '');
|
||||
@@ -44,8 +44,8 @@ const { text, copy, copied, isSupported } = useClipboard({ source: keyUrl.value
|
||||
<Modal
|
||||
:open="open"
|
||||
max-width="max-w-640px"
|
||||
:error="!callbackLoading && (success === false || updateSuccess === false)"
|
||||
:success="!callbackLoading && (success === true || updateSuccess === true)"
|
||||
:error="!callbackLoading && (keySuccess === false || accountSuccess === false)"
|
||||
:success="!callbackLoading && (keySuccess === true || accountSuccess === true)"
|
||||
>
|
||||
<div class="text-16px text-center relative w-full min-h-[20vh] flex flex-col justify-between gap-y-16px">
|
||||
<header>
|
||||
@@ -55,14 +55,14 @@ const { text, copy, copied, isSupported } = useClipboard({ source: keyUrl.value
|
||||
|
||||
<BrandLoading v-if="callbackLoading" class="w-90px mx-auto" />
|
||||
|
||||
<template v-if="installing !== undefined">
|
||||
<p v-if="success === undefined || callbackLoading">Installing {{ keyType }} License Key…</p>
|
||||
<template v-if="keyInstalling !== undefined">
|
||||
<p v-if="keySuccess === undefined || callbackLoading">keyInstalling {{ keyType }} License Key…</p>
|
||||
<template v-else>
|
||||
<div v-if="success === true" class="flex items-center justify-center gap-x-8px">
|
||||
<div v-if="keySuccess === true" class="flex items-center justify-center gap-x-8px">
|
||||
<CheckCircleIcon class="fill-green-600 w-24px" />
|
||||
<p>Installed {{ keyType }} License Key</p>
|
||||
</div>
|
||||
<template v-else-if="success === false">
|
||||
<template v-else-if="keySuccess === false">
|
||||
<div class="flex items-center justify-center gap-x-8px">
|
||||
<XCircleIcon class="fill-unraid-red w-24px" />
|
||||
<p class="text-unraid-red italic">{{ keyType }} License Key Install Failed</p>
|
||||
@@ -79,14 +79,14 @@ const { text, copy, copied, isSupported } = useClipboard({ source: keyUrl.value
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template v-if="updating !== undefined">
|
||||
<p v-if="updateSuccess === undefined || callbackLoading">Updating Connect account config…</p>
|
||||
<template v-if="accountUpdating !== undefined">
|
||||
<p v-if="accountSuccess === undefined || callbackLoading">Updating Connect account config…</p>
|
||||
<template v-else>
|
||||
<div v-if="updateSuccess === true" class="flex items-center justify-center gap-x-8px">
|
||||
<div v-if="accountSuccess === true" class="flex items-center justify-center gap-x-8px">
|
||||
<CheckCircleIcon class="fill-green-600 w-24px" />
|
||||
<p>Connect config updated</p>
|
||||
</div>
|
||||
<div v-else-if="updateSuccess === false" class="flex items-center justify-center gap-x-8px">
|
||||
<div v-else-if="accountSuccess === false" class="flex items-center justify-center gap-x-8px">
|
||||
<XCircleIcon class="fill-unraid-red w-24px" />
|
||||
<p class="text-unraid-red italic">Connect config update failed</p>
|
||||
</div>
|
||||
@@ -94,7 +94,7 @@ const { text, copy, copied, isSupported } = useClipboard({ source: keyUrl.value
|
||||
</template>
|
||||
|
||||
<footer>
|
||||
<div v-if="!callbackLoading && (success === true || updateSuccess === true)" class="w-full max-w-xs flex flex-col gap-y-16px mx-auto">
|
||||
<div v-if="!callbackLoading && (keySuccess === true || accountSuccess === true)" class="w-full max-w-xs flex flex-col gap-y-16px mx-auto">
|
||||
<button
|
||||
@click="reload"
|
||||
class="opacity-75 hover:opacity-100 focus:opacity-100 underline transition"
|
||||
|
||||
@@ -15,8 +15,8 @@ export const useAccountStore = defineStore('account', () => {
|
||||
const serverStore = useServerStore();
|
||||
|
||||
// State
|
||||
const updating = ref<boolean | undefined>(undefined);
|
||||
const updateSuccess = ref<boolean | undefined>(undefined);
|
||||
const accountUpdating = ref<boolean | undefined>(undefined);
|
||||
const accountSuccess = ref<boolean | undefined>(undefined);
|
||||
|
||||
// Actions
|
||||
const recover = () => {
|
||||
@@ -70,7 +70,7 @@ export const useAccountStore = defineStore('account', () => {
|
||||
*/
|
||||
const updatePluginConfig = async (action: CallbackAction) => {
|
||||
console.debug('[accountStore.updatePluginConfig]', action);
|
||||
updating.value = true;
|
||||
accountUpdating.value = true;
|
||||
const userPayload = {
|
||||
...(action.user
|
||||
? {
|
||||
@@ -101,26 +101,26 @@ export const useAccountStore = defineStore('account', () => {
|
||||
.post()
|
||||
.res(res => {
|
||||
console.debug('[accountStore.updatePluginConfig] WebguiUpdate res', res);
|
||||
updateSuccess.value = true;
|
||||
accountSuccess.value = true;
|
||||
})
|
||||
.catch(err => {
|
||||
console.debug('[accountStore.updatePluginConfig] WebguiUpdate err', err);
|
||||
updateSuccess.value = false;
|
||||
accountSuccess.value = false;
|
||||
});
|
||||
return response;
|
||||
} finally {
|
||||
updating.value = false;
|
||||
accountUpdating.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
watch(updating, (newV, oldV) => {
|
||||
console.debug('[updating.watch]', newV, oldV);
|
||||
watch(accountUpdating, (newV, oldV) => {
|
||||
console.debug('[accountUpdating.watch]', newV, oldV);
|
||||
});
|
||||
|
||||
return {
|
||||
// State
|
||||
updating,
|
||||
updateSuccess,
|
||||
accountUpdating,
|
||||
accountSuccess,
|
||||
// Actions
|
||||
recover,
|
||||
replace,
|
||||
|
||||
@@ -2,20 +2,23 @@ import { defineStore } from 'pinia';
|
||||
|
||||
import { useAccountStore } from './account';
|
||||
import { useInstallKeyStore } from './installKey';
|
||||
import { useCallbackStoreGeneric, type UpcActions, type QueryPayloads } from './callback';
|
||||
import { useServerStore } from './server';
|
||||
import { useCallbackStoreGeneric, type ExternalPayload, type QueryPayloads } from './callback';
|
||||
// import { useServerStore } from './server';
|
||||
|
||||
export const useCallbackActionsStore = defineStore(
|
||||
'callbackActions',
|
||||
() => {
|
||||
const accountStore = useAccountStore();
|
||||
const installKeyStore = useInstallKeyStore();
|
||||
const serverStore = useServerStore();
|
||||
// const serverStore = useServerStore();
|
||||
|
||||
const callbackData = ref<ExternalPayload>();
|
||||
const callbackError = ref();
|
||||
const callbackLoading = ref(false);
|
||||
const callbackFeedbackVisible = ref<boolean>(false);
|
||||
|
||||
const callbackKeyAction = ref<CallbackAction>();
|
||||
|
||||
const redirectToCallbackType = (decryptedData: QueryPayloads) => {
|
||||
console.debug('[redirectToCallbackType]', { decryptedData });
|
||||
|
||||
@@ -25,14 +28,16 @@ export const useCallbackActionsStore = defineStore(
|
||||
}
|
||||
|
||||
// Display the feedback modal
|
||||
callbackData.value = decryptedData;
|
||||
callbackFeedbackVisible.value = true;
|
||||
callbackLoading.value = true;
|
||||
// Parse the data and perform actions
|
||||
decryptedData.actions.forEach(async (action, index, array) => {
|
||||
callbackData.value.actions.forEach(async (action, index, array) => {
|
||||
console.debug('[action]', action);
|
||||
if (action?.keyUrl) {
|
||||
await installKeyStore.install(action);
|
||||
}
|
||||
/** @todo add oemSignOut */
|
||||
if (action?.user || action.type === 'signOut') {
|
||||
await accountStore.updatePluginConfig(action);
|
||||
}
|
||||
@@ -74,6 +79,7 @@ export const useCallbackActionsStore = defineStore(
|
||||
|
||||
return {
|
||||
redirectToCallbackType,
|
||||
callbackData,
|
||||
callbackFeedbackVisible,
|
||||
callbackLoading,
|
||||
closeCallbackFeedback,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { defineStore, createPinia, setActivePinia } from 'pinia';
|
||||
import { delay } from 'wretch/middlewares';
|
||||
import { WebguiInstallKey, WebguiUpdateDns } from '~/composables/services/webgui';
|
||||
import { useServerStore } from './server';
|
||||
import type { CallbackAction } from '~/types/callback';
|
||||
import { useServerStore } from '~/store/server';
|
||||
import type { ExternalKeyActions } from '~/store/callback';
|
||||
import type { ServerStateDataKeyActions } from '~/types/server'
|
||||
/**
|
||||
* @see https://stackoverflow.com/questions/73476371/using-pinia-with-vue-js-web-components
|
||||
* @see https://github.com/vuejs/pinia/discussions/1085
|
||||
@@ -12,54 +13,61 @@ setActivePinia(createPinia());
|
||||
export const useInstallKeyStore = defineStore('installKey', () => {
|
||||
const serverStore = useServerStore();
|
||||
|
||||
// "https://keys.lime-technology.com/unraid/c9785e151ae3b0f056238e403809fd28b82eb4ad/Plus.key"
|
||||
const keyActionType = ref<ServerStateDataKeyActions>();
|
||||
const keyInstalling = ref<boolean | undefined>();
|
||||
const keyUrl = ref<string>('');
|
||||
const installing = ref<boolean | undefined>();
|
||||
const success = ref<boolean | undefined>();
|
||||
const keySuccess = ref<boolean | undefined>();
|
||||
|
||||
/**
|
||||
* Extracts key type from key url. Works for both .key and .unkey.
|
||||
*/
|
||||
const keyType = computed((): string | undefined => {
|
||||
if (!keyUrl.value) return undefined;
|
||||
const parts = keyUrl.value.split('/');
|
||||
return parts[parts.length - 1].replace('.key', '');
|
||||
return parts[parts.length - 1].replace(/\.key|\.unkey/g, '');
|
||||
});
|
||||
|
||||
const install = async (action: CallbackAction) => {
|
||||
const install = async (action: ExternalKeyActions) => {
|
||||
console.debug('[install]');
|
||||
installing.value = true;
|
||||
keyUrl.value = action.keyUrl ?? '';
|
||||
keyInstalling.value = true;
|
||||
keyActionType.value = action.type;
|
||||
keyUrl.value = action.keyUrl;
|
||||
|
||||
if (!keyUrl.value) return console.error('[install] no key to install');
|
||||
|
||||
try {
|
||||
const response = await WebguiInstallKey
|
||||
const installResponse = await WebguiInstallKey
|
||||
.query({ url: keyUrl.value })
|
||||
.get();
|
||||
console.log('[install] WebguiInstallKey response', response);
|
||||
success.value = true;
|
||||
console.log('[install] WebguiInstallKey installResponse', installResponse);
|
||||
|
||||
keySuccess.value = true;
|
||||
|
||||
try {
|
||||
const response = await WebguiUpdateDns
|
||||
const updateDnsResponse = await WebguiUpdateDns
|
||||
.middlewares([
|
||||
delay(1500)
|
||||
])
|
||||
.formUrl({ csrf_token: serverStore.csrf })
|
||||
.post();
|
||||
console.log('[install] WebguiUpdateDns response', response);
|
||||
console.log('[install] WebguiUpdateDns updateDnsResponse', updateDnsResponse);
|
||||
} catch (error) {
|
||||
console.error('[install] WebguiUpdateDns error', error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[install] WebguiInstallKey error', error);
|
||||
success.value = false;
|
||||
keySuccess.value = false;
|
||||
} finally {
|
||||
installing.value = false;
|
||||
keyInstalling.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
// State
|
||||
keyActionType,
|
||||
keyInstalling,
|
||||
keySuccess,
|
||||
keyUrl,
|
||||
installing,
|
||||
success,
|
||||
// getters
|
||||
keyType,
|
||||
// Actions
|
||||
|
||||
@@ -82,7 +82,11 @@ export interface ServerPurchaseCallbackSendPayload {
|
||||
site: string;
|
||||
}
|
||||
|
||||
export type ServerStateDataActionType = 'signIn'|'signOut'|'purchase'|'redeem'|'upgrade'|'recover'|'replace'|'trialExtend'|'trialStart';
|
||||
export type ServerStateDataKeyActions = 'purchase'|'redeem'|'upgrade'|'recover'|'replace'|'trialExtend'|'trialStart';
|
||||
|
||||
export type ServerStateDataAccountActions = 'signIn'|'signOut'|'troubleshoot';
|
||||
|
||||
export type ServerStateDataActionType = ServerStateDataKeyActions | ServerStateDataAccountActions;
|
||||
|
||||
export interface ServerStateDataAction extends UserProfileLink {
|
||||
name: ServerStateDataActionType;
|
||||
|
||||
Reference in New Issue
Block a user