From 05369a49a494bce41153acb448d7c356a9d0d9d0 Mon Sep 17 00:00:00 2001 From: Zack Spear Date: Wed, 27 Sep 2023 21:09:15 -0700 Subject: [PATCH] refactor(web): registration ux/ui button placement --- web/components/Brand/Button.vue | 4 ++- web/components/KeyActions.vue | 10 ++++-- web/components/Registration.ce.vue | 8 +++-- web/components/Registration/ReplaceCheck.vue | 34 ++++++++++--------- .../Registration/UpgradeExpiration.vue | 31 ++++++++++++++--- web/helpers/urls.ts | 8 ++++- web/locales/en_US.json | 1 + web/store/server.ts | 12 +++++++ 8 files changed, 81 insertions(+), 27 deletions(-) diff --git a/web/components/Brand/Button.vue b/web/components/Brand/Button.vue index d81d472a4..e39afbaf3 100644 --- a/web/components/Brand/Button.vue +++ b/web/components/Brand/Button.vue @@ -4,7 +4,7 @@ import BrandLoading from '~/components/Brand/Loading.vue'; import BrandLoadingWhite from '~/components/Brand/LoadingWhite.vue'; export interface ButtonProps { - btnStyle?: 'fill' | 'outline' | 'underline'; + btnStyle?: 'fill' | 'gray' | 'outline' | 'underline'; btnType?: 'button' | 'submit' | 'reset'; click?: () => void; disabled?: boolean; @@ -31,6 +31,8 @@ const classes = computed(() => { switch (props.btnStyle) { case 'fill': return 'text-white bg-gradient-to-r from-unraid-red to-orange shadow-none hover:from-unraid-red/60 hover:to-orange/60 focus:from-unraid-red/60 focus:to-orange/60 hover:shadow-md focus:shadow-md'; + case 'gray': + return 'text-black bg-grey shadow-none transition hover:text-white focus:text-white hover:bg-grey-mid focus:bg-grey-mid hover:shadow-md focus:shadow-md'; case 'outline': return 'text-orange bg-gradient-to-r from-transparent to-transparent border-2 border-solid border-orange shadow-none hover:text-white focus:text-white hover:from-unraid-red hover:to-orange focus:from-unraid-red focus:to-orange hover:shadow-md focus:shadow-md'; case 'underline': diff --git a/web/components/KeyActions.vue b/web/components/KeyActions.vue index 3daf438db..ba537b18e 100644 --- a/web/components/KeyActions.vue +++ b/web/components/KeyActions.vue @@ -2,8 +2,10 @@ import { storeToRefs } from 'pinia'; import { useServerStore } from '~/store/server'; +import type { ServerStateDataAction } from '~/types/server'; const props = defineProps<{ + actions: ServerStateDataAction[]; filterBy?: string[] | undefined; filterOut?: string[] | undefined; t: any; @@ -11,10 +13,12 @@ const props = defineProps<{ const { keyActions } = storeToRefs(useServerStore()); -const filteredKeyActions = computed(() => { - if (!keyActions.value || (!props.filterOut && !props.filterBy)) return keyActions.value; +const computedActions = computed((): ServerStateDataAction[] | undefined => props.actions ? props.actions : keyActions.value); - return keyActions.value.filter((action: { name: string; }) => { +const filteredKeyActions = computed((): ServerStateDataAction[] | undefined => { + if (!computedActions.value || (!props.filterOut && !props.filterBy)) return computedActions.value; + + return computedActions.value.filter((action: { name: string; }) => { return props.filterOut ? !props.filterOut?.includes(action.name) : props.filterBy?.includes(action.name); diff --git a/web/components/Registration.ce.vue b/web/components/Registration.ce.vue index e6963a54d..982569357 100644 --- a/web/components/Registration.ce.vue +++ b/web/components/Registration.ce.vue @@ -146,10 +146,14 @@ const items = computed((): RegistrationItemProps[] => { component: RegistrationReplaceCheck, componentProps: { t: t }, }] : []), - ...(keyActions.value ? [{ + // filter out renew action and only display other key actions + ...(!keyActions.value?.filter(action => !['renew'].includes(action.name)) ? [{ label: t('License key actions'), component: KeyActions, - componentProps: { t: t }, + componentProps: { + filterOut: ['renew'], + t, + }, }] : []), ]; diff --git a/web/components/Registration/ReplaceCheck.vue b/web/components/Registration/ReplaceCheck.vue index f827b1544..871c38a41 100644 --- a/web/components/Registration/ReplaceCheck.vue +++ b/web/components/Registration/ReplaceCheck.vue @@ -5,6 +5,7 @@ import { } from '@heroicons/vue/24/solid'; import { storeToRefs } from 'pinia'; +import { DOCS_REGISTRATION_REPLACE_KEY } from '~/helpers/urls'; import BrandLoadingWhite from '~/components/Brand/LoadingWhite.vue'; import { useReplaceCheckStore } from '~/store/replaceCheck'; @@ -17,30 +18,31 @@ const props = defineProps<{ diff --git a/web/components/Registration/UpgradeExpiration.vue b/web/components/Registration/UpgradeExpiration.vue index d9a9e1b1d..71b1f21c2 100644 --- a/web/components/Registration/UpgradeExpiration.vue +++ b/web/components/Registration/UpgradeExpiration.vue @@ -1,7 +1,9 @@ diff --git a/web/helpers/urls.ts b/web/helpers/urls.ts index 1cc871b0b..c611f7bac 100644 --- a/web/helpers/urls.ts +++ b/web/helpers/urls.ts @@ -1,10 +1,11 @@ const ACCOUNT = new URL(import.meta.env.VITE_ACCOUNT ?? 'https://account.unraid.net'); +const DOCS = new URL('https://docs.unraid.net'); const FORUMS = new URL('https://forums.unraid.net'); const UNRAID_NET = new URL(localStorage.getItem('craftUrl') ?? 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_DOCS = new URL('category/unraid-connect', DOCS); const CONNECT_DASHBOARD = new URL(import.meta.env.VITE_CONNECT ?? 'https://connect.myunraid.net'); const CONNECT_FORUMS = new URL('/forum/94-connect-plugin-support/', FORUMS); const CONTACT = new URL('/contact', UNRAID_NET); @@ -17,6 +18,9 @@ const PLUGIN_SETTINGS = new URL('#UnraidNetSettings', SETTINGS_MANAGMENT_ACCESS) const OS_RELEASES = new URL('https://s3.amazonaws.com/dnld.lime-technology.com/stable/releases.json'); +const DOCS_REGISTRATION_LICENSING = new URL('/unraid-os/faq/licensing-faq', DOCS); +const DOCS_REGISTRATION_REPLACE_KEY = new URL('/unraid-os/manual/changing-the-flash-device/#notes-about-replacing-your-registration-key', DOCS); + export { ACCOUNT, ACCOUNT_CALLBACK, @@ -32,4 +36,6 @@ export { PLUGIN_SETTINGS, SETTINGS_MANAGMENT_ACCESS, OS_RELEASES, + DOCS_REGISTRATION_LICENSING, + DOCS_REGISTRATION_REPLACE_KEY, }; diff --git a/web/locales/en_US.json b/web/locales/en_US.json index fcdbbaa45..0bcf8574b 100644 --- a/web/locales/en_US.json +++ b/web/locales/en_US.json @@ -276,6 +276,7 @@ "Unleashed": "Unleashed", "Lifetime": "Lifetime", "Renew your license key to continue receiving OS updates.": "Renew your license key to continue receiving OS updates.", + "Renew Key": "Renew Key", "A valid GUID is required to check for updates.": "A valid GUID is required to check for updates.", "A valid keyfile is required to check for updates.": "A valid keyfile is required to check for updates.", "A valid OS version is required to check for updates.": "A valid OS version is required to check for updates.", diff --git a/web/store/server.ts b/web/store/server.ts index 94eeb29d0..68f407e8f 100644 --- a/web/store/server.ts +++ b/web/store/server.ts @@ -35,6 +35,7 @@ import type { ServerStateDataAction, ServerconnectPluginInstalled, ServerDateTimeFormat, + ServerStateDataKeyActions, } from '~/types/server'; /** @@ -852,6 +853,16 @@ export const useServerStore = defineStore('server', () => { }, refreshTimeout); }; + const filteredKeyActions = (filterType: 'by' | 'out', filters: ServerStateDataKeyActions[]): ServerStateDataAction[] | undefined => { + if (!stateData.value.actions) { return; } + + return stateData.value.actions.filter((action) => { + return filterType === 'out' + ? !filters.includes(action.name) + : filters.includes(action.name); + }); + }; + return { // state apiKey, @@ -908,5 +919,6 @@ export const useServerStore = defineStore('server', () => { setServer, fetchServerFromApi, refreshServerState, + filteredKeyActions, }; });