diff --git a/web/_data/osReleases.ts b/web/_data/osReleases.ts index 4c1cd5b43..1a5225796 100644 --- a/web/_data/osReleases.ts +++ b/web/_data/osReleases.ts @@ -43,32 +43,32 @@ const testOsReleasesResponse: OsReleasesResponse = { } ], "stable": [ - // { - // "version": "6.12.5", - // "name": "Unraid Server 6.12.5", - // "basefile": "unRAIDServer-6.12.5-x86_64.zip", - // "date": "2023-08-31", - // "url": "https://dl.stable.unraid.net/unRAIDServer-6.12.5-x86_64.zip", - // "changelog": "https://unraid.net/blog/unraid-os-6.12.5-release-notes", - // "md5": "FAKEbddcf415f2d0518804e551c16125", - // "size": 12345122, - // "sha256": "fda177bb1336270b24e4df0fd0c1dd0596c44699204f57c83ce70a0f19173be4", - // "plugin_url": "https://dl.stable.unraid.net/unRAIDServer-6.12.5.plg", - // "plugin_sha256": "83850536ed6982bd582ed107d977d59e9b9b786363e698b14d1daf52e2dec2d9" - // }, - // { - // "version": "6.12.4", - // "name": "Unraid Server 6.12.4", - // "basefile": "unRAIDServer-6.12.4-x86_64.zip", - // "date": "2023-08-31", - // "url": "https://dl.stable.unraid.net/unRAIDServer-6.12.4-x86_64.zip", - // "changelog": "https://unraid.net/blog/unraid-os-6.12.4-release-notes", - // "md5": "9050bddcf415f2d0518804e551c1be98", - // "size": 12345122, - // "sha256": "fda177bb1336270b24e4df0fd0c1dd0596c44699204f57c83ce70a0f19173be4", - // "plugin_url": "https://dl.stable.unraid.net/unRAIDServer-6.12.4.plg", - // "plugin_sha256": "83850536ed6982bd582ed107d977d59e9b9b786363e698b14d1daf52e2dec2d9" - // }, + { + "version": "6.12.5", + "name": "Unraid Server 6.12.5", + "basefile": "unRAIDServer-6.12.5-x86_64.zip", + "date": "2023-08-31", + "url": "https://dl.stable.unraid.net/unRAIDServer-6.12.5-x86_64.zip", + "changelog": "https://unraid.net/blog/unraid-os-6.12.5-release-notes", + "md5": "FAKEbddcf415f2d0518804e551c16125", + "size": 12345122, + "sha256": "fda177bb1336270b24e4df0fd0c1dd0596c44699204f57c83ce70a0f19173be4", + "plugin_url": "https://dl.stable.unraid.net/unRAIDServer-6.12.5.plg", + "plugin_sha256": "83850536ed6982bd582ed107d977d59e9b9b786363e698b14d1daf52e2dec2d9" + }, + { + "version": "6.12.4", + "name": "Unraid Server 6.12.4", + "basefile": "unRAIDServer-6.12.4-x86_64.zip", + "date": "2023-08-31", + "url": "https://dl.stable.unraid.net/unRAIDServer-6.12.4-x86_64.zip", + "changelog": "https://unraid.net/blog/unraid-os-6.12.4-release-notes", + "md5": "9050bddcf415f2d0518804e551c1be98", + "size": 12345122, + "sha256": "fda177bb1336270b24e4df0fd0c1dd0596c44699204f57c83ce70a0f19173be4", + "plugin_url": "https://dl.stable.unraid.net/unRAIDServer-6.12.4.plg", + "plugin_sha256": "83850536ed6982bd582ed107d977d59e9b9b786363e698b14d1daf52e2dec2d9" + }, { "version": "6.12.3", "name": "Unraid Server 6.12.3", diff --git a/web/_data/serverState.ts b/web/_data/serverState.ts index db56cfe01..87136e908 100644 --- a/web/_data/serverState.ts +++ b/web/_data/serverState.ts @@ -53,7 +53,7 @@ export const serverState: Server = { guid: randomGuid, // "guid": "0781-5583-8355-81071A2B0211", inIframe: false, - keyfile: 'DUMMY_KEYFILE', + // keyfile: 'DUMMY_KEYFILE', lanIp: '192.168.254.36', license: '', locale: 'en_US', // en_US, ja diff --git a/web/components/HeaderOsVersion.ce.vue b/web/components/HeaderOsVersion.ce.vue new file mode 100644 index 000000000..1bb6b6c19 --- /dev/null +++ b/web/components/HeaderOsVersion.ce.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/web/components/Ui/Badge.vue b/web/components/Ui/Badge.vue index 40b104882..1db0dca11 100644 --- a/web/components/Ui/Badge.vue +++ b/web/components/Ui/Badge.vue @@ -4,14 +4,16 @@ import BrandLoading from '~/components/Brand/Loading.vue'; import BrandLoadingWhite from '~/components/Brand/LoadingWhite.vue'; const props = withDefaults(defineProps<{ - color?: 'gray' | 'red' | 'yellow' | 'green' | 'blue' | 'indigo' | 'purple' | 'pink' | 'orange' | 'black' | 'white' | 'transparent' | 'current'; + color?: 'alpha' | 'beta' | 'gamma' | 'gray' | 'red' | 'yellow' | 'green' | 'blue' | 'indigo' | 'purple' | 'pink' | 'orange' | 'black' | 'white' | 'transparent' | 'current' | 'custom'; icon?: typeof XCircleIcon | typeof BrandLoading | typeof BrandLoadingWhite; iconRight?: typeof XCircleIcon | typeof BrandLoading | typeof BrandLoadingWhite; + iconStyles?: string; size?: '12px' | '14px' | '16px' | '18px' | '20px' | '24px'; }>(), { color: 'gray', icon: undefined, iconRight: undefined, + iconStyles: '', size: '16px', }); @@ -20,6 +22,15 @@ const computedStyleClasses = computed(() => { let textSize = ''; let iconSize = ''; switch (props.color) { + case 'alpha': + colorClasses = 'bg-alpha text-white group-hover:opacity-75 group-focus:opacity-75'; + break; + case 'beta': + colorClasses = 'bg-beta text-white group-hover:opacity-75 group-focus:opacity-75'; + break; + case 'gamma': + colorClasses = 'bg-gamma text-white group-hover:opacity-75 group-focus:opacity-75'; + break; case 'red': colorClasses = 'bg-unraid-red text-white group-hover:bg-orange-dark group-focus:bg-orange-dark'; break; @@ -27,7 +38,7 @@ const computedStyleClasses = computed(() => { colorClasses = 'bg-yellow-100 text-yellow-800 group-hover:bg-yellow-200 group-focus:bg-yellow-200'; break; case 'green': - colorClasses = 'bg-green-100 text-green-800 group-hover:bg-green-200 group-focus:bg-green-200'; + colorClasses = 'bg-green-200 text-green-800 group-hover:bg-green-300 group-focus:bg-green-300'; break; case 'blue': colorClasses = 'bg-blue-100 text-blue-800 group-hover:bg-blue-200 group-focus:bg-blue-200'; @@ -59,37 +70,40 @@ const computedStyleClasses = computed(() => { case 'gray': colorClasses = 'bg-gray-200 text-gray-800 group-hover:bg-gray-300 group-focus:bg-gray-300'; break; + case 'custom': + colorClasses = ''; + break; } switch (props.size) { case '12px': - textSize = 'text-12px px-8px py-4px'; + textSize = 'text-12px px-8px py-4px gap-4px'; iconSize = 'w-12px'; break; case '14px': - textSize = 'text-14px px-8px py-4px'; + textSize = 'text-14px px-8px py-4px gap-8px'; iconSize = 'w-14px'; break; case '16px': - textSize = 'text-16px px-12px py-8px'; + textSize = 'text-16px px-12px py-8px gap-8px'; iconSize = 'w-16px'; break; case '18px': - textSize = 'text-18px px-12px py-8px'; + textSize = 'text-18px px-12px py-8px gap-8px'; iconSize = 'w-18px'; break; case '20px': - textSize = 'text-20px px-16px py-12px'; + textSize = 'text-20px px-16px py-12px gap-8px'; iconSize = 'w-20px'; break; case '24px': - textSize = 'text-24px px-16px py-12px'; + textSize = 'text-24px px-16px py-12px gap-8px'; iconSize = 'w-24px'; break; } return { badge: `${textSize} ${colorClasses}`, - icon: iconSize, + icon: `${iconSize} ${props.iconStyles}`, }; }); @@ -99,7 +113,6 @@ const computedStyleClasses = computed(() => { class="inline-flex items-center rounded-full font-semibold leading-none transition-all duration-200 ease-in-out" :class="[ computedStyleClasses.badge, - icon || iconRight ? 'gap-8px' : '', ]" > diff --git a/web/components/UpdateOs.ce.vue b/web/components/UpdateOs.ce.vue index 86d08e625..d9020eb0c 100644 --- a/web/components/UpdateOs.ce.vue +++ b/web/components/UpdateOs.ce.vue @@ -4,12 +4,9 @@ * @todo require keyfile to update * @todo require valid guid / server state to update */ -import dayjs, { extend } from 'dayjs'; -import relativeTime from 'dayjs/plugin/relativeTime'; -import { storeToRefs } from 'pinia'; import { useI18n } from 'vue-i18n'; -import { useUpdateOsStore } from '~/store/updateOsActions'; +import { useUpdateOsActionsStore } from '~/store/updateOsActions'; import 'tailwindcss/tailwind.css'; import '~/assets/main.css'; @@ -17,30 +14,31 @@ import '~/assets/main.css'; const { t } = useI18n(); export interface Props { + rebootType?: 'downgrade' | 'upgrade' | 'none'; restoreVersion?: string; } -withDefaults(defineProps(), { +const props = withDefaults(defineProps(), { + rebootType: 'none', restoreVersion: '', }); -const updateOsStore = useUpdateOsStore(); -const { cachedReleasesTimestamp } = storeToRefs(updateOsStore); +const updateOsActionsStore = useUpdateOsActionsStore(); -extend(relativeTime); -const parsedReleaseTimestamp = computed(() => { - if (!cachedReleasesTimestamp.value) { return ''; } - return { - formatted: dayjs(cachedReleasesTimestamp.value).format('YYYY-MM-DD HH:mm:ss'), - relative: dayjs().to(dayjs(cachedReleasesTimestamp.value)), - }; +onBeforeMount(() => { + updateOsActionsStore.setRebootType(props.rebootType); }); diff --git a/web/components/UpdateOs/CheckButton.vue b/web/components/UpdateOs/CheckButton.vue index 8951a5429..55fa8546d 100644 --- a/web/components/UpdateOs/CheckButton.vue +++ b/web/components/UpdateOs/CheckButton.vue @@ -7,34 +7,27 @@ */ import { Switch, SwitchGroup, SwitchLabel } from '@headlessui/vue'; import { storeToRefs } from 'pinia'; -import { ref, watchEffect } from 'vue'; +import { ref } from 'vue'; import 'tailwindcss/tailwind.css'; import '~/assets/main.css'; import { useServerStore } from '~/store/server'; -import { useUpdateOsStore, useUpdateOsActionsStore } from '~/store/updateOsActions'; -import type { UserProfileLink } from '~/types/userProfile'; -import { stat } from 'fs'; +import { useUpdateOsStore } from '~/store/updateOsActions'; const props = defineProps<{ - releaseCheckTime: { - formatted: string; - relative: string; - }; t: any; }>(); const serverStore = useServerStore(); const updateOsStore = useUpdateOsStore(); -const updateOsActionsStore = useUpdateOsActionsStore(); const { guid, keyfile, osVersion } = storeToRefs(serverStore); -const { available } = storeToRefs(updateOsStore); +const { parsedReleaseTimestamp } = storeToRefs(updateOsStore); const includeNext = ref(false); -const status = ref<'ready' | 'checking'>('ready'); +const status = ref<'ready' | 'checking' | 'ineligible'>('ready'); const buttonText = computed(() => { if (status.value === 'checking') { @@ -44,6 +37,10 @@ const buttonText = computed(() => { }); const check = async () => { + if (status.value === 'ineligible') { + return; + } + status.value = 'checking'; await updateOsStore.checkForUpdate({ @@ -57,32 +54,74 @@ const check = async () => { status.value = 'ready'; }) }; + +watchEffect(() => { + if (!guid.value || !keyfile.value) { + status.value = 'ineligible'; + } else { + status.value = 'ready'; + } +}); diff --git a/web/components/UpdateOs/Downgrade.vue b/web/components/UpdateOs/Downgrade.vue index c95b04518..8c1537586 100644 --- a/web/components/UpdateOs/Downgrade.vue +++ b/web/components/UpdateOs/Downgrade.vue @@ -1,11 +1,17 @@ diff --git a/web/components/UpdateOs/Update.vue b/web/components/UpdateOs/Update.vue index 7fddb850c..0fa0d38d8 100644 --- a/web/components/UpdateOs/Update.vue +++ b/web/components/UpdateOs/Update.vue @@ -3,7 +3,6 @@ * @todo require keyfile to be set before allowing user to check for updates * @todo require keyfile to update * @todo require valid guid / server state to update - * @todo detect downgrade possibility */ import { Switch, SwitchGroup, SwitchLabel } from '@headlessui/vue' import { @@ -23,10 +22,6 @@ import { useUpdateOsStore, useUpdateOsActionsStore } from '~/store/updateOsActio import type { UserProfileLink } from '~/types/userProfile'; const props = defineProps<{ - releaseCheckTime: { - formatted: string; - relative: string; - }; t: any; }>(); @@ -37,8 +32,6 @@ const updateOsActionsStore = useUpdateOsActionsStore(); const { guid, keyfile, osVersion } = storeToRefs(serverStore); const { available } = storeToRefs(updateOsStore); -const includeNext = ref(false); - const updateButton = ref(); const availableText = computed(() => { @@ -47,16 +40,7 @@ const availableText = computed(() => { } }); -const check = () => { - updateOsStore.checkForUpdate({ - cache: true, - guid: guid.value, - includeNext: includeNext.value, - keyfile: keyfile.value, - osVersion: osVersion.value, - skipCache: true, - }); -}; +const ineligible = computed(() => !guid.value || !keyfile.value || !osVersion.value); watchEffect(() => { if (available.value) { @@ -79,13 +63,18 @@ watchEffect(() => {
-

{{ t('Receive the latest and greatest for Unraid OS. Whether it new features, security patches, or bug fixes – keeping your server up-to-date ensures the best experience that Unraid has to offer.') }}

+

{{ t('A valid keyfile and USB Flash boot device are required to check for updates.') }} {{ t('Please fix any errors and try again.') }}

+

{{ t('Receive the latest and greatest for Unraid OS. Whether it new features, security patches, or bug fixes – keeping your server up-to-date ensures the best experience that Unraid has to offer.') }}

- + { let copyIpInterval: string | number | NodeJS.Timeout | undefined; const { copy, copied, isSupported } = useClipboard({ source: lanIp.value ?? '' }); const showCopyNotSupported = ref(false); -const copyLanIp = () => { - if (!isSupported) { showCopyNotSupported.value = true; } +const copyLanIp = () => { // if http then clipboard is not supported + if (!isSupported || window.location.protocol === 'http:') { + showCopyNotSupported.value = true; + return; + } copy(lanIp.value ?? ''); }; watch(showCopyNotSupported, (newVal, oldVal) => { @@ -86,13 +89,17 @@ onBeforeMount(() => { callbackStore.watcher(); - updateOsStore.checkForUpdate({ - cache: true, - guid: guid.value, - includeNext: isOsVersionStable.value, // @todo ensure this is correct - keyfile: keyfile.value, - osVersion: osVersion.value, - }); + if (guid.value && keyfile.value) { + updateOsStore.checkForUpdate({ + cache: true, + guid: guid.value, + includeNext: isOsVersionStable.value, // @todo ensure this is correct + keyfile: keyfile.value, + osVersion: osVersion.value, + }); + } else { + console.warn('A valid keyfile and USB Flash boot device are required to check for updates.'); + } }); diff --git a/web/helpers/urls.ts b/web/helpers/urls.ts index 84b6b074f..5eaf4c808 100644 --- a/web/helpers/urls.ts +++ b/web/helpers/urls.ts @@ -1,13 +1,12 @@ -/** - * @todo setup .env - */ const ACCOUNT = new URL(import.meta.env.VITE_ACCOUNT ?? 'https://account.unraid.net'); +const FORUMS = new URL('https://forums.unraid.net'); const UNRAID_NET = new URL(import.meta.env.VITE_UNRAID_NET ?? 'https://unraid.net'); const ACCOUNT_CALLBACK = new URL('c', ACCOUNT); +const FORUMS_BUG_REPORT = new URL('/bug-reports', FORUMS); const CONNECT_DOCS = new URL('https://docs.unraid.net/category/unraid-connect'); const CONNECT_DASHBOARD = new URL(import.meta.env.VITE_CONNECT ?? 'https://connect.myunraid.net'); -const CONNECT_FORUMS = new URL('https://forums.unraid.net/forum/94-connect-plugin-support/'); +const CONNECT_FORUMS = new URL('/forum/94-connect-plugin-support/', FORUMS); const CONTACT = new URL('/contact', UNRAID_NET); const DISCORD = new URL('https://discord.gg/unraid'); const GRAPHQL = new URL('/graphql', import.meta.env.VITE_GRAPHQL ?? window.location.origin); @@ -26,6 +25,8 @@ export { CONNECT_FORUMS, CONTACT, DISCORD, + FORUMS, + FORUMS_BUG_REPORT, GRAPHQL, PURCHASE_CALLBACK, PLUGIN_SETTINGS, diff --git a/web/locales/en_US.json b/web/locales/en_US.json index fbb9cc8c0..0e7c07d86 100644 --- a/web/locales/en_US.json +++ b/web/locales/en_US.json @@ -210,6 +210,7 @@ "Please confirm the update details below": "Please confirm the update details below", "Current Version {0}": "Current Version {0}", "New Version: {0}": "New Version: {0}", + "Version: {0}": "Version: {0}", "This update will require a reboot": "This update will require a reboot", "Confirm and start update": "Confirm and start update", "Update Unraid OS": "Update Unraid OS", @@ -219,13 +220,25 @@ "Begin restore to Unraid {0}": "Begin restore to Unraid {0}", "Version available for restore {0}": "Version available for restore {0}", "Check for Updates": "Check for Updates", - "Include Prereleases": "Include Prereleases", + "Check Prereleases": "Check Prereleases", "Receive the latest and greatest for Unraid OS. Whether it new features, security patches, or bug fixes – keeping your server up-to-date ensures the best experience that Unraid has to offer.": "Receive the latest and greatest for Unraid OS. Whether it new features, security patches, or bug fixes – keeping your server up-to-date ensures the best experience that Unraid has to offer.", "Check For Updates": "Check For Updates", "Checking...": "Checking...", - "View changelog for current version {0}": "View changelog for current version {0}", + "View release notes": "View release notes", "View Changelog for {0}": "View Changelog for {0}", "View changelog & update": "View changelog & update", "{0} Release Notes": "{0} Release Notes", - "Unable to open release notes": "Unable to open release notes" + "Unable to open release notes": "Unable to open release notes", + "Downgrades are only recommended if you're unable to solve a critical issue. In the rare event you need to downgrade we ask that you please provide us with Diagnostics so we can investigate your issue. You will be prompted with the option to download the Diagnostics zip once the downgrade process is started. From there please open a bug report on our forums with a description of the issue and include your diagnostics.": "Downgrades are only recommended if you're unable to solve a critical issue. In the rare event you need to downgrade we ask that you please provide us with Diagnostics so we can investigate your issue. You will be prompted with the option to download the Diagnostics zip once the downgrade process is started. From there please open a bug report on our forums with a description of the issue and include your diagnostics.", + "Reboot Now to Downgrade": "Reboot Now to Downgrade", + "Reboot Now to Update": "Reboot Now to Update", + "Reboot Required for Downgrade": "Reboot Required for Downgrade", + "Reboot Required for Update": "Reboot Required for Update", + "Update Available": "Update Available", + "Up-to-date": "Up-to-date", + "Open a bug report": "Open a bug report", + "Go to Tools > Update": "Go to Tools > Update", + "A valid keyfile and USB Flash boot device are required to check for updates.": "A valid keyfile and USB Flash boot device are required to check for updates.", + "Please fix any errors and try again.": "Please fix any errors and try again.", + "Go to Tools > Registration": "Go to Tools > Registration" } diff --git a/web/nuxt.config.ts b/web/nuxt.config.ts index 45e1531ed..d975ace9f 100644 --- a/web/nuxt.config.ts +++ b/web/nuxt.config.ts @@ -84,6 +84,10 @@ export default defineNuxtConfig({ name: 'UnraidDownloadApiLogs', path: '@/components/DownloadApiLogs.ce', }, + { + name: 'UnraidHeaderOsVersion', + path: '@/components/HeaderOsVersion.ce', + }, { name: 'UnraidKeyActions', path: '@/components/KeyActions.ce', diff --git a/web/pages/index.vue b/web/pages/index.vue index 398261b04..5cc92521f 100644 --- a/web/pages/index.vue +++ b/web/pages/index.vue @@ -42,6 +42,11 @@ onBeforeMount(() => {
+

+ HeaderOsVersion +

+ +

UpdateOsCe

diff --git a/web/pages/webComponents.vue b/web/pages/webComponents.vue index bfed4f373..2200d1ad5 100644 --- a/web/pages/webComponents.vue +++ b/web/pages/webComponents.vue @@ -40,6 +40,11 @@ onBeforeMount(() => {
+

+ HeaderOsVersion +

+ +

UpdateOsCe

diff --git a/web/store/server.ts b/web/store/server.ts index 0aeec2795..e0c58f810 100644 --- a/web/store/server.ts +++ b/web/store/server.ts @@ -327,7 +327,7 @@ export const useServerStore = defineStore('server', () => { return { actions: [ ...(!registered.value && connectPluginInstalled.value ? [signInAction.value] : []), - ...([purchaseAction, redeemAction, trialStartAction]), + ...([purchaseAction, redeemAction, trialStartAction, recoverAction]), ...(registered.value && connectPluginInstalled.value ? [signOutAction.value] : []), ], humanReadable: 'No Keyfile', diff --git a/web/store/updateOs.ts b/web/store/updateOs.ts index a9414ffb8..2a668d384 100644 --- a/web/store/updateOs.ts +++ b/web/store/updateOs.ts @@ -1,5 +1,7 @@ import testReleasesResponse from '~/_data/osReleases'; // test data +import dayjs, { extend } from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; import { defineStore, createPinia, setActivePinia } from 'pinia'; import gt from 'semver/functions/gt'; import prerelease from 'semver/functions/prerelease'; @@ -49,6 +51,8 @@ export interface UpdateOsActionStore { */ setActivePinia(createPinia()); +extend(relativeTime); + export const RELEASES_LOCAL_STORAGE_KEY = 'unraidReleasesResponse'; export const useUpdateOsStoreGeneric = ( @@ -58,8 +62,8 @@ export const useUpdateOsStoreGeneric = ( defineStore('updateOs', () => { // 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(''); + const releases = ref(localStorage.getItem(RELEASES_LOCAL_STORAGE_KEY) ? JSON.parse(localStorage.getItem(RELEASES_LOCAL_STORAGE_KEY) ?? '') : undefined); if (useUpdateOsActions !== undefined) { const updateOsActions = useUpdateOsActions(); @@ -69,7 +73,13 @@ export const useUpdateOsStoreGeneric = ( } // getters - const cachedReleasesTimestamp = computed(() => releases.value?.timestamp); + const parsedReleaseTimestamp = computed(() => { + if (!releases.value?.timestamp) { return undefined; } + return { + formatted: dayjs(releases.value?.timestamp).format('YYYY-MM-DD HH:mm:ss'), + relative: dayjs().to(dayjs(releases.value?.timestamp)), + }; + }); const isOsVersionStable = computed(() => !isVersionStable(osVersion.value)); const isAvailableStable = computed(() => { if (!available.value) return undefined; @@ -263,7 +273,7 @@ export const useUpdateOsStoreGeneric = ( available, releases, // getters - cachedReleasesTimestamp, + parsedReleaseTimestamp, isOsVersionStable, isAvailableStable, filteredStableReleases, diff --git a/web/store/updateOsActions.ts b/web/store/updateOsActions.ts index ee5844ee5..e3d140d33 100644 --- a/web/store/updateOsActions.ts +++ b/web/store/updateOsActions.ts @@ -1,15 +1,9 @@ -import testOsReleasesResponse from '~/_data/osReleases'; // test data - import { BellAlertIcon } from '@heroicons/vue/24/solid'; import { defineStore, createPinia, setActivePinia } from 'pinia'; -import gt from 'semver/functions/gt'; -import coerce from 'semver/functions/coerce'; -import type { SemVer } from 'semver'; import useInstallPlugin from '~/composables/installPlugin'; -import { request } from '~/composables/services/request'; -import { ACCOUNT_CALLBACK, OS_RELEASES } from '~/helpers/urls'; +import { ACCOUNT_CALLBACK } from '~/helpers/urls'; import { useCallbackStore } from '~/store/callbackActions'; import { useErrorsStore } from '~/store/errors'; @@ -17,13 +11,9 @@ import { useServerStore } from '~/store/server'; import { useUpdateOsStoreGeneric, type Release, - type ReleasesResponse, - type CachedReleasesResponse, type UpdateOsActionStore, } from '~/store/updateOs'; -import type { InstallPluginPayload } from '~/composables/installPlugin'; -import type { ServerStateDataAction } from '~/types/server'; import type { UserProfileLink } from '~/types/userProfile'; /** @@ -44,7 +34,8 @@ export const useUpdateOsActionsStore = defineStore('updateOsActions', () => { // State const osVersion = computed(() => serverStore.osVersion); /** used when coming back from callback, this will be the release to install */ - const status = ref<'confirming' | 'failed' | 'ready' | 'success' | 'updating' | 'downgrading'>('ready'); + const rebootType = ref<'downgrade' | 'upgrade' | 'none'>('none'); + const status = ref<'confirming' | 'checking' | 'ineligible' | 'failed' | 'ready' | 'success' | 'updating' | 'downgrading'>('ready'); const callbackUpdateRelease = ref(null); // Actions @@ -98,25 +89,46 @@ export const useUpdateOsActionsStore = defineStore('updateOsActions', () => { }); }; - const downgradeOs = async () => { - setStatus('downgrading'); + const rebootServer = async () => { + // @ts-ignore • global set in the webgui + document.rebootNow.submit(); + }; + + const viewCurrentReleaseNotes = (text: string) => { + // @ts-ignore – this is a global function provided by the webgui + if (typeof openChanges === 'function') { + // @ts-ignore + openChanges( + 'showchanges /var/tmp/unRAIDServer.txt', + text, + ); + } else { + alert('Unable to open release notes'); + } }; const setStatus = (payload: typeof status.value) => { status.value = payload; }; + const setRebootType = (payload: typeof rebootType.value) => { + rebootType.value = payload; + }; + return { // State - osVersion, callbackUpdateRelease, + osVersion, + rebootType, status, // Actions confirmUpdateOs, - downgradeOs, installOsUpdate, initUpdateOsCallback, + rebootServer, setStatus, + setRebootType, + viewCurrentReleaseNotes, }; }); diff --git a/web/tailwind.config.ts b/web/tailwind.config.ts index b2788dcf1..c02ac66a7 100644 --- a/web/tailwind.config.ts +++ b/web/tailwind.config.ts @@ -54,6 +54,7 @@ export default >{ '4px': '4px', '6px': '6px', '8px': '8px', + '10px': '10px', '12px': '12px', '14px': '14px', '16px': '16px',