diff --git a/web/components/UserProfile/DropdownContent.vue b/web/components/UserProfile/DropdownContent.vue
index 8d7814c19..1333d3238 100644
--- a/web/components/UserProfile/DropdownContent.vue
+++ b/web/components/UserProfile/DropdownContent.vue
@@ -13,11 +13,11 @@ const props = defineProps<{ t: any; }>();
const errorsStore = useErrorsStore();
// const promoStore = usePromoStore();
+const updateOsActionsStore = useUpdateOsActionsStore();
const { errors } = storeToRefs(errorsStore);
const { keyActions, connectPluginInstalled, registered, stateData } = storeToRefs(useServerStore());
const { available: osUpdateAvailable } = storeToRefs(useUpdateOsStore());
-const { initUpdateOsCallback } = storeToRefs(useUpdateOsActionsStore());
const signInAction = computed(() => stateData.value.actions?.filter((act: { name: string; }) => act.name === 'signIn') ?? []);
const signOutAction = computed(() => stateData.value.actions?.filter((act: { name: string; }) => act.name === 'signOut') ?? []);
@@ -96,7 +96,7 @@ const showKeyline = computed(() => showConnectStatus.value && (keyActions.value?
-
+
diff --git a/web/components/UserProfile/DropdownItem.vue b/web/components/UserProfile/DropdownItem.vue
index f99f717ba..c5363bd2e 100644
--- a/web/components/UserProfile/DropdownItem.vue
+++ b/web/components/UserProfile/DropdownItem.vue
@@ -4,6 +4,7 @@ import type { ServerStateDataAction } from '~/types/server';
import type { UserProfileLink } from '~/types/userProfile';
export interface Props {
+ clickParams?: any; // so we can pass in params to the click handler
item: ServerStateDataAction | UserProfileLink;
rounded?: boolean;
t: any;
@@ -32,11 +33,11 @@ const showExternalIconOnHover = computed(() => props.item?.external && props.ite
'rounded-md': rounded,
'disabled:opacity-50 disabled:hover:opacity-50 disabled:focus:opacity-50 disabled:cursor-not-allowed': item?.disabled,
}"
- @click.stop="item?.click ? item?.click() : null"
+ @click.stop="item?.click ? item?.click(clickParams) : null"
>
- {{ t(item?.text) }}
+ {{ t(item?.text, item?.textParams) }}
UpdateOsActionStore,
+ useUpdateOsActions?: () => UpdateOsActionStore,
+ currentOsVersion?: SemVer | string,
) =>
defineStore('updateOs', () => {
- const updateOsActions = useUpdateOsActions();
// state
const available = ref('');
const releases = ref(localStorage.getItem(RELEASES_LOCAL_STORAGE_KEY) ? JSON.parse(localStorage.getItem(RELEASES_LOCAL_STORAGE_KEY) ?? '') : undefined);
- const osVersion = ref(updateOsActions.osVersion);
+ const osVersion = ref('');
+
+ if (useUpdateOsActions !== undefined) {
+ const updateOsActions = useUpdateOsActions();
+ osVersion.value = updateOsActions.osVersion;
+ } else if (currentOsVersion !== undefined && (typeof currentOsVersion === 'string' || currentOsVersion instanceof SemVer)) {
+ osVersion.value = currentOsVersion;
+ }
+
// getters
const isOsVersionStable = computed(() => {
const hasPrerelease = prerelease(osVersion.value);
return !hasPrerelease;
});
+
+ const filteredStableReleases = computed(() => {
+ if (!osVersion.value) return undefined;
+
+ if (releases.value?.response?.stable) {
+ return releases.value?.response?.stable.filter(release => {
+ console.debug('stable: ', release.version, osVersion.value);
+ return gt(release.version, osVersion.value as string);
+ });
+ }
+ return undefined;
+ });
+
+ const filteredNextReleases = computed(() => {
+ if (!osVersion.value) return undefined;
+
+ if (releases.value?.response?.next) {
+ return releases.value?.response?.next.filter(release => {
+ console.debug('next: ', release.version, osVersion.value);
+ return gt(release.version, osVersion.value as string);
+ });
+ }
+ return undefined;
+ });
+
+ const allFilteredReleases = computed(() => {
+ if (!filteredStableReleases.value && !filteredNextReleases.value) return undefined;
+
+ return {
+ ...(filteredStableReleases.value && { stable: [...filteredStableReleases.value] }),
+ ...(filteredNextReleases.value && { next: [...filteredNextReleases.value] }),
+ }
+ });
// actions
const setReleasesState = (response: ReleasesResponse) => {
releases.value = {
@@ -203,6 +244,9 @@ export const useUpdateOsStoreGeneric = (
releases,
// getters
isOsVersionStable,
+ filteredStableReleases,
+ filteredNextReleases,
+ allFilteredReleases,
// actions
checkForUpdate,
findReleaseByMd5,
diff --git a/web/store/updateOsActions.ts b/web/store/updateOsActions.ts
index 5fba937df..ac2661fe0 100644
--- a/web/store/updateOsActions.ts
+++ b/web/store/updateOsActions.ts
@@ -35,7 +35,8 @@ export const useUpdateOsActionsStore = defineStore('updateOsActions', () => {
const callbackStore = useCallbackStore();
const errorsStore = useErrorsStore();
const serverStore = useServerStore();
- const updateOsStoreGeneric = useUpdateOsStoreGeneric();
+ const useUpdateOsStore = useUpdateOsStoreGeneric();
+ const updateOsStore = useUpdateOsStore();
const { install: installPlugin } = useInstallPlugin();
@@ -46,14 +47,19 @@ export const useUpdateOsActionsStore = defineStore('updateOsActions', () => {
const callbackUpdateRelease = ref(null);
// Actions
- const initUpdateOsCallback = computed((): ServerStateDataAction => {
+ const initUpdateOsCallback = (includeNextReleases: boolean = false) => {
return {
- click: () => {
+ click: (includeNext: boolean = includeNextReleases) => {
callbackStore.send(
ACCOUNT_CALLBACK.toString(),
[{
server: {
...serverStore.serverAccountPayload,
+ /**
+ * Prefer the param in the event for when a user is on stable and wants to see Next releases.
+ * Otherwise if the os version is NOT stable, we'll include next releases
+ */
+ includeNext: includeNext ?? !updateOsStore.isOsVersionStable,
},
type: 'updateOs',
}],
@@ -64,9 +70,11 @@ export const useUpdateOsActionsStore = defineStore('updateOsActions', () => {
external: true,
icon: BellAlertIcon,
name: 'updateOs',
- text: 'Unraid OS Update Available',
+ text: 'Unraid OS {0} Update Available',
+ textParams: [updateOsStore.available],
}
- });
+ };
+
/**
* @description When receiving the callback the Account update page we'll use the provided releaseMd5 to find the release in the releases cache.
*/
diff --git a/web/types/server.ts b/web/types/server.ts
index 13d201e1a..4078f61cc 100644
--- a/web/types/server.ts
+++ b/web/types/server.ts
@@ -52,6 +52,7 @@ export interface Server {
flashVendor?: string;
guid?: string;
inIframe?: boolean;
+ includeNext?: boolean;
keyfile?: string;
lanIp?: string;
license?: string;
diff --git a/web/types/userProfile.ts b/web/types/userProfile.ts
index d50b28693..de3c6c364 100644
--- a/web/types/userProfile.ts
+++ b/web/types/userProfile.ts
@@ -9,6 +9,7 @@ export interface UserProfileLink {
icon?: typeof ArrowTopRightOnSquareIcon;
name?: string;
text: string;
+ textParams?: string|number[];
title?: string;
}