mirror of
https://github.com/unraid/api.git
synced 2026-01-04 15:39:52 -06:00
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added new modal dialogs and UI components, including activation steps, OS update feedback, and expanded notification management. * Introduced a plugin to configure internationalization, state management, and Apollo client support in web components. * Added a new Log Viewer page with a streamlined interface for viewing logs. * **Improvements** * Centralized Pinia state management by consolidating all stores to use a shared global Pinia instance. * Simplified component templates by removing redundant internationalization host wrappers. * Enhanced ESLint configuration with stricter rules and global variable declarations. * Refined custom element build process to prevent jQuery conflicts and optimize minification. * Updated component imports and templates for consistent structure and maintainability. * Streamlined log viewer dropdowns using simplified select components with improved formatting. * Improved notification sidebar with filtering by importance and modular components. * Replaced legacy notification popups with new UI components and added automatic root session creation for localhost requests. * Updated OS version display and user profile UI with refined styling and component usage. * **Bug Fixes** * Fixed component tag capitalization and improved type annotations across components. * **Chores** * Updated development dependencies including ESLint plugins and build tools. * Removed deprecated log viewer patch class and cleaned up related test fixtures. * Removed unused imports and simplified Apollo client setup. * Cleaned up test mocks and removed obsolete i18n host component tests. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1210730229632804 --------- Co-authored-by: Pujit Mehrotra <pujit@lime-technology.com> Co-authored-by: Zack Spear <zackspear@users.noreply.github.com>
156 lines
5.2 KiB
TypeScript
156 lines
5.2 KiB
TypeScript
import { computed, ref } from 'vue';
|
|
import { defineStore } from 'pinia';
|
|
|
|
import dayjs, { extend } from 'dayjs';
|
|
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
|
import relativeTime from 'dayjs/plugin/relativeTime';
|
|
|
|
import type { ServerUpdateOsResponse } from '~/types/server';
|
|
|
|
import { WebguiCheckForUpdate, WebguiUpdateCancel } from '~/composables/services/webgui';
|
|
import { useServerStore } from '~/store/server';
|
|
import prerelease from 'semver/functions/prerelease';
|
|
import { useCallbackActionsStore } from '~/store/callbackActions';
|
|
|
|
/**
|
|
* Uses the shared global Pinia instance from ~/store/globalPinia.ts
|
|
* @see https://stackoverflow.com/questions/73476371/using-pinia-with-vue-js-web-components
|
|
* @see https://github.com/vuejs/pinia/discussions/1085
|
|
*/
|
|
import '~/store/globalPinia';
|
|
|
|
// dayjs plugins
|
|
extend(customParseFormat);
|
|
extend(relativeTime);
|
|
|
|
export const useUpdateOsStore = defineStore('updateOs', () => {
|
|
// state
|
|
const checkForUpdatesLoading = ref<boolean>(false);
|
|
const updateOsModalVisible = ref<boolean>(false);
|
|
const releaseForUpdate = ref<ServerUpdateOsResponse | null>(null);
|
|
const changelogModalVisible = computed(() => !!releaseForUpdate.value);
|
|
// getters from other stores
|
|
const serverStore = useServerStore();
|
|
|
|
const regExp = computed(() => serverStore.regExp);
|
|
const regUpdatesExpired = computed(() => serverStore.regUpdatesExpired);
|
|
const updateOsResponse = computed(() => serverStore.updateOsResponse);
|
|
const updateOsIgnoredReleases = computed(() => serverStore.updateOsIgnoredReleases);
|
|
// local getters
|
|
const available = computed(() => {
|
|
if (!updateOsResponse.value) {
|
|
return undefined;
|
|
}
|
|
// ignore any releases that are in the updateOsIgnoredReleases array
|
|
if (updateOsIgnoredReleases.value.includes(updateOsResponse.value.version)) {
|
|
return undefined;
|
|
}
|
|
return updateOsResponse.value.isNewer ? updateOsResponse.value.version : undefined;
|
|
});
|
|
const availableWithRenewal = computed((): string | undefined => {
|
|
if (!available.value || !updateOsResponse.value || !regExp.value || !regUpdatesExpired.value) {
|
|
return undefined;
|
|
}
|
|
|
|
return !updateOsResponse.value?.isEligible ? updateOsResponse.value.version : undefined;
|
|
});
|
|
|
|
const availableReleaseDate = computed(() =>
|
|
updateOsResponse.value?.date ? dayjs(updateOsResponse.value.date, 'YYYY-MM-DD') : undefined
|
|
);
|
|
|
|
/**
|
|
* If the updateOsResponse does not have a sha256, then the user is required to authenticate to download the update
|
|
*/
|
|
const availableRequiresAuth = computed((): boolean => !updateOsResponse.value?.sha256);
|
|
|
|
// Changelog logic
|
|
const changelogUrl = computed((): string => releaseForUpdate.value?.changelog || '');
|
|
const changelogPretty = computed(() => releaseForUpdate.value?.changelogPretty ?? null);
|
|
const setReleaseForUpdate = (release: ServerUpdateOsResponse | null) => {
|
|
releaseForUpdate.value = release;
|
|
};
|
|
// isReleaseForUpdateStable logic (true if no prerelease in version)
|
|
const isReleaseForUpdateStable = computed(() => {
|
|
if (!releaseForUpdate.value?.version) return false;
|
|
return !prerelease(releaseForUpdate.value.version);
|
|
});
|
|
// fetchAndConfirmInstall logic
|
|
const callbackStore = useCallbackActionsStore();
|
|
const fetchAndConfirmInstall = (sha256: string) => {
|
|
callbackStore.send(
|
|
window.location.href,
|
|
[
|
|
{
|
|
sha256,
|
|
type: 'updateOs',
|
|
},
|
|
],
|
|
undefined,
|
|
'forUpc'
|
|
);
|
|
};
|
|
|
|
// actions
|
|
const localCheckForUpdate = async (): Promise<void> => {
|
|
checkForUpdatesLoading.value = true;
|
|
setModalOpen(true);
|
|
try {
|
|
const response = await WebguiCheckForUpdate();
|
|
console.debug('[localCheckForUpdate] response', response);
|
|
serverStore.setUpdateOsResponse(response as ServerUpdateOsResponse);
|
|
checkForUpdatesLoading.value = false;
|
|
} catch (error) {
|
|
throw new Error('[localCheckForUpdate] Error checking for updates\n' + JSON.stringify(error));
|
|
}
|
|
};
|
|
|
|
const cancelUpdate = async (): Promise<void> => {
|
|
try {
|
|
const response = await WebguiUpdateCancel();
|
|
if (!response.success) {
|
|
throw new Error('Unable to cancel update');
|
|
}
|
|
// if current path is /Tools/Update, then we should redirect to /Tools
|
|
// otherwise it will redirect to the account update os page.
|
|
if (window.location.pathname === '/Tools/Update') {
|
|
window.location.href = '/Tools';
|
|
return;
|
|
}
|
|
// otherwise refresh the page
|
|
window.location.reload();
|
|
} catch (error) {
|
|
throw new Error(
|
|
`[cancelUpdate] Error cancelling update with error: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
);
|
|
}
|
|
};
|
|
|
|
const setModalOpen = (val: boolean) => {
|
|
updateOsModalVisible.value = val;
|
|
};
|
|
|
|
return {
|
|
// state
|
|
available,
|
|
availableWithRenewal,
|
|
checkForUpdatesLoading,
|
|
updateOsModalVisible,
|
|
changelogModalVisible,
|
|
releaseForUpdate,
|
|
updateOsIgnoredReleases,
|
|
// getters
|
|
availableReleaseDate,
|
|
availableRequiresAuth,
|
|
changelogUrl,
|
|
changelogPretty,
|
|
isReleaseForUpdateStable,
|
|
// actions
|
|
localCheckForUpdate,
|
|
cancelUpdate,
|
|
setModalOpen,
|
|
setReleaseForUpdate,
|
|
fetchAndConfirmInstall,
|
|
};
|
|
});
|