mirror of
https://github.com/unraid/api.git
synced 2026-05-20 07:59:13 -05:00
chore(web): add pinia store and select dropdown for dummy server state (#1143)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced an interactive server selector that lets users toggle between different server modes (e.g., Default and OEM Activation) via a dropdown. - Integrated reactive state management across key pages, ensuring dynamic UI updates. - Added new popover components for enhanced UI interactions. - Introduced a settings interface for developers, allowing access to server selection within a popover. - **Bug Fixes** - Restored functionality for the downgrade feature that was previously removed. <!-- 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/1209127325997642
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import type { PopoverRootEmits, PopoverRootProps } from 'radix-vue'
|
||||
import { PopoverRoot, useForwardPropsEmits } from 'radix-vue'
|
||||
|
||||
const props = defineProps<PopoverRootProps>()
|
||||
const emits = defineEmits<PopoverRootEmits>()
|
||||
|
||||
const forwarded = useForwardPropsEmits(props, emits)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PopoverRoot v-bind="forwarded">
|
||||
<slot />
|
||||
</PopoverRoot>
|
||||
</template>
|
||||
@@ -0,0 +1,49 @@
|
||||
<script setup lang="ts">
|
||||
import type { PopoverContentEmits, PopoverContentProps } from 'radix-vue'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
import {
|
||||
PopoverContent,
|
||||
|
||||
PopoverPortal,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue'
|
||||
import { computed } from 'vue'
|
||||
|
||||
defineOptions({
|
||||
inheritAttrs: false,
|
||||
})
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<PopoverContentProps & { class?: HTMLAttributes['class'] }>(),
|
||||
{
|
||||
align: 'center',
|
||||
sideOffset: 4,
|
||||
},
|
||||
)
|
||||
const emits = defineEmits<PopoverContentEmits>()
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props
|
||||
|
||||
return delegated
|
||||
})
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PopoverPortal>
|
||||
<PopoverContent
|
||||
v-bind="{ ...forwarded, ...$attrs }"
|
||||
:class="
|
||||
cn(
|
||||
'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
</PopoverContent>
|
||||
</PopoverPortal>
|
||||
</template>
|
||||
@@ -0,0 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import type { PopoverTriggerProps } from 'radix-vue'
|
||||
import { PopoverTrigger } from 'radix-vue'
|
||||
|
||||
const props = defineProps<PopoverTriggerProps>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PopoverTrigger v-bind="props">
|
||||
<slot />
|
||||
</PopoverTrigger>
|
||||
</template>
|
||||
@@ -0,0 +1,3 @@
|
||||
export { default as Popover } from './Popover.vue'
|
||||
export { default as PopoverContent } from './PopoverContent.vue'
|
||||
export { default as PopoverTrigger } from './PopoverTrigger.vue'
|
||||
@@ -155,3 +155,4 @@ export {
|
||||
type ButtonProps,
|
||||
};
|
||||
export { Toaster } from '@/components/common/toast';
|
||||
export * from '@/components/common/popover';
|
||||
|
||||
+32
-14
@@ -11,6 +11,7 @@ import type {
|
||||
ServerState,
|
||||
// ServerUpdateOsResponse,
|
||||
} from '~/types/server';
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
// dayjs plugins
|
||||
// extend(customParseFormat);
|
||||
@@ -132,20 +133,7 @@ const osVersionBranch = 'stable';
|
||||
// }
|
||||
// };
|
||||
|
||||
export const serverState: Server = {
|
||||
// activationCodeData: {
|
||||
// code: 'CC2KP3TDRF',
|
||||
// partnerName: 'OEM Partner',
|
||||
// partnerUrl: 'https://unraid.net/OEM+Partner',
|
||||
// sysModel: 'OEM Partner v1',
|
||||
// comment: 'OEM Partner NAS',
|
||||
// caseIcon: 'case-model.png',
|
||||
// header: '#ffffff',
|
||||
// headermetacolor: '#eeeeee',
|
||||
// background: '#000000',
|
||||
// showBannerGradient: 'yes',
|
||||
// partnerLogo: true,
|
||||
// },
|
||||
const baseServerState: Server = {
|
||||
avatar: 'https://source.unsplash.com/300x300/?portrait',
|
||||
config: {
|
||||
id: 'config-id',
|
||||
@@ -204,3 +192,33 @@ export const serverState: Server = {
|
||||
username: 'zspearmint',
|
||||
wanFQDN: '',
|
||||
};
|
||||
|
||||
export type ServerSelector = 'default' | 'oemActivation';
|
||||
const defaultServer: ServerSelector = 'default';
|
||||
|
||||
const servers: Record<ServerSelector, Server> = {
|
||||
default: baseServerState,
|
||||
/** shows oem activation flow */
|
||||
oemActivation: {
|
||||
...baseServerState,
|
||||
activationCodeData: {
|
||||
code: 'CC2KP3TDRF',
|
||||
partnerName: 'OEM Partner',
|
||||
partnerUrl: 'https://unraid.net/OEM+Partner',
|
||||
sysModel: 'OEM Partner v1',
|
||||
comment: 'OEM Partner NAS',
|
||||
caseIcon: 'case-model.png',
|
||||
header: '#ffffff',
|
||||
headermetacolor: '#eeeeee',
|
||||
background: '#000000',
|
||||
showBannerGradient: 'yes',
|
||||
partnerLogo: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const useDummyServerStore = defineStore('_dummyServer',() => {
|
||||
const selector = ref<ServerSelector>(defaultServer);
|
||||
const serverState = computed(() => servers[selector.value] ?? servers.default);
|
||||
return { selector, serverState };
|
||||
})
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
Button,
|
||||
} from '@unraid/ui';
|
||||
|
||||
import { CogIcon } from '@heroicons/vue/24/solid';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Popover>
|
||||
<PopoverTrigger as-child>
|
||||
<Button type="button" size="icon" class="fixed bottom-4 right-4 rounded-full bg-teal-500 z-50"><CogIcon class="size-6" /></Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<DummyServerSwitcher />
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<style lang="postcss">
|
||||
/* Import unraid-ui globals first */
|
||||
@import '@unraid/ui/styles';
|
||||
@import '../assets/main.css';
|
||||
</style>
|
||||
@@ -0,0 +1,36 @@
|
||||
<script lang="ts" setup>
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@unraid/ui';
|
||||
import { useDummyServerStore, type ServerSelector } from '~/_data/serverState';
|
||||
|
||||
const store = useDummyServerStore();
|
||||
const { selector, serverState } = storeToRefs(store);
|
||||
|
||||
const updateSelector = (val: string) => {
|
||||
selector.value = val as ServerSelector;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-2 border-solid border-2 p-2 border-r-2">
|
||||
<h1 class="text-lg">Server State Selection</h1>
|
||||
<details>
|
||||
<summary>Initial Server State: {{ selector }}</summary>
|
||||
<pre>{{ JSON.stringify(serverState, null, 4) }}</pre>
|
||||
</details>
|
||||
<Select v-model="selector" @update:model-value="updateSelector">
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select an initial state" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="default">Default</SelectItem>
|
||||
<SelectItem value="oemActiviation">OEM Activation</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="postcss">
|
||||
/* Import unraid-ui globals first */
|
||||
@import '@unraid/ui/styles';
|
||||
@import '../assets/main.css';
|
||||
</style>
|
||||
+4
-1
@@ -1,13 +1,15 @@
|
||||
<script lang="ts" setup>
|
||||
import { ExclamationTriangleIcon } from '@heroicons/vue/24/solid';
|
||||
import { BrandButton, BrandLogo } from '@unraid/ui';
|
||||
import { serverState } from '~/_data/serverState';
|
||||
import { useDummyServerStore } from '~/_data/serverState';
|
||||
import AES from 'crypto-js/aes';
|
||||
|
||||
import type { SendPayloads } from '~/store/callback';
|
||||
|
||||
import SsoButtonCe from '~/components/SsoButton.ce.vue';
|
||||
|
||||
const serverStore = useDummyServerStore();
|
||||
const { serverState } = storeToRefs(serverStore);
|
||||
const { registerEntry } = useCustomElements();
|
||||
onBeforeMount(() => {
|
||||
registerEntry('UnraidComponents');
|
||||
@@ -80,6 +82,7 @@ onMounted(() => {
|
||||
<div class="pb-12 mx-auto">
|
||||
<client-only>
|
||||
<div class="flex flex-col gap-6 p-6">
|
||||
<DummyServerSwitcher />
|
||||
<ColorSwitcherCe />
|
||||
<h2 class="text-xl font-semibold font-mono">Vue Components</h2>
|
||||
<h3 class="text-lg font-semibold font-mono">UserProfileCe</h3>
|
||||
|
||||
+26
-51
@@ -1,6 +1,8 @@
|
||||
<script lang="ts" setup>
|
||||
import { serverState } from '~/_data/serverState';
|
||||
import { useDummyServerStore } from '~/_data/serverState';
|
||||
|
||||
const serverStore = useDummyServerStore();
|
||||
const { serverState } = storeToRefs(serverStore);
|
||||
const { registerEntry } = useCustomElements();
|
||||
onBeforeMount(() => {
|
||||
registerEntry('UnraidComponents');
|
||||
@@ -12,12 +14,8 @@ onBeforeMount(() => {
|
||||
<unraid-i18n-host
|
||||
class="flex flex-col gap-6 p-6 mx-auto text-black bg-white dark:text-white dark:bg-black"
|
||||
>
|
||||
<h2 class="text-xl font-semibold font-mono">
|
||||
Web Components
|
||||
</h2>
|
||||
<h3 class="text-lg font-semibold font-mono">
|
||||
UserProfileCe
|
||||
</h3>
|
||||
<h2 class="text-xl font-semibold font-mono">Web Components</h2>
|
||||
<h3 class="text-lg font-semibold font-mono">UserProfileCe</h3>
|
||||
<header class="bg-header-background-color py-4 flex flex-row justify-between items-center">
|
||||
<div class="inline-flex flex-col gap-4 items-start px-4">
|
||||
<a href="https://unraid.net" target="_blank">
|
||||
@@ -27,59 +25,36 @@ onBeforeMount(() => {
|
||||
</div>
|
||||
<unraid-user-profile :server="JSON.stringify(serverState)" />
|
||||
</header>
|
||||
<hr class="border-black dark:border-white" >
|
||||
<hr class="border-black dark:border-white" />
|
||||
|
||||
<h3 class="text-lg font-semibold font-mono">
|
||||
ConnectSettingsCe
|
||||
</h3>
|
||||
<h3 class="text-lg font-semibold font-mono">ConnectSettingsCe</h3>
|
||||
<ConnectSettingsCe />
|
||||
<hr class="border-black dark:border-white">
|
||||
<h3 class="text-lg font-semibold font-mono">
|
||||
DownloadApiLogsCe
|
||||
</h3>
|
||||
<hr class="border-black dark:border-white" />
|
||||
<h3 class="text-lg font-semibold font-mono">DownloadApiLogsCe</h3>
|
||||
<unraid-download-api-logs />
|
||||
<hr class="border-black dark:border-white">
|
||||
<h3 class="text-lg font-semibold font-mono">
|
||||
AuthCe
|
||||
</h3>
|
||||
<hr class="border-black dark:border-white" />
|
||||
<h3 class="text-lg font-semibold font-mono">AuthCe</h3>
|
||||
<unraid-auth />
|
||||
<hr class="border-black dark:border-white">
|
||||
<h3 class="text-lg font-semibold font-mono">
|
||||
WanIpCheckCe
|
||||
</h3>
|
||||
<hr class="border-black dark:border-white" />
|
||||
<h3 class="text-lg font-semibold font-mono">WanIpCheckCe</h3>
|
||||
<unraid-wan-ip-check php-wan-ip="47.184.85.45" />
|
||||
<hr class="border-black dark:border-white">
|
||||
<h3 class="text-lg font-semibold font-mono">
|
||||
HeaderOsVersion
|
||||
</h3>
|
||||
<hr class="border-black dark:border-white" />
|
||||
<h3 class="text-lg font-semibold font-mono">HeaderOsVersion</h3>
|
||||
<unraid-header-os-version />
|
||||
<hr class="border-black dark:border-white">
|
||||
<h3 class="text-lg font-semibold font-mono">
|
||||
UpdateOsCe
|
||||
</h3>
|
||||
<hr class="border-black dark:border-white" />
|
||||
<h3 class="text-lg font-semibold font-mono">UpdateOsCe</h3>
|
||||
<unraid-update-os />
|
||||
<hr class="border-black dark:border-white">
|
||||
<h3 class="text-lg font-semibold font-mono">
|
||||
DowngradeOsCe
|
||||
</h3>
|
||||
<unraid-downgrade-os
|
||||
restore-release-date="2022-10-10"
|
||||
restore-version="6.11.2"
|
||||
/>
|
||||
<hr class="border-black dark:border-white">
|
||||
<h3 class="text-lg font-semibold font-mono">
|
||||
RegistrationCe
|
||||
</h3>
|
||||
<hr class="border-black dark:border-white" />
|
||||
<h3 class="text-lg font-semibold font-mono">DowngradeOsCe</h3>
|
||||
<unraid-downgrade-os restore-release-date="2022-10-10" restore-version="6.11.2" />
|
||||
<hr class="border-black dark:border-white" />
|
||||
<h3 class="text-lg font-semibold font-mono">RegistrationCe</h3>
|
||||
<unraid-registration />
|
||||
<hr class="border-black dark:border-white">
|
||||
<h3 class="text-lg font-semibold font-mono">
|
||||
ModalsCe
|
||||
</h3>
|
||||
<hr class="border-black dark:border-white" />
|
||||
<h3 class="text-lg font-semibold font-mono">ModalsCe</h3>
|
||||
<!-- uncomment to test modals <unraid-modals />-->
|
||||
<hr class="border-black dark:border-white">
|
||||
<h3 class="text-lg font-semibold font-mono">
|
||||
SSOSignInButtonCe
|
||||
</h3>
|
||||
<hr class="border-black dark:border-white" />
|
||||
<h3 class="text-lg font-semibold font-mono">SSOSignInButtonCe</h3>
|
||||
<unraid-sso-button :ssoenabled="serverState.ssoEnabled" />
|
||||
</unraid-i18n-host>
|
||||
</client-only>
|
||||
|
||||
Reference in New Issue
Block a user