Skip to content

Commit f315818

Browse files
authored
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
1 parent cba1551 commit f315818

File tree

10 files changed

+207
-66
lines changed

10 files changed

+207
-66
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script setup lang="ts">
2+
import type { PopoverRootEmits, PopoverRootProps } from 'radix-vue'
3+
import { PopoverRoot, useForwardPropsEmits } from 'radix-vue'
4+
5+
const props = defineProps<PopoverRootProps>()
6+
const emits = defineEmits<PopoverRootEmits>()
7+
8+
const forwarded = useForwardPropsEmits(props, emits)
9+
</script>
10+
11+
<template>
12+
<PopoverRoot v-bind="forwarded">
13+
<slot />
14+
</PopoverRoot>
15+
</template>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<script setup lang="ts">
2+
import type { PopoverContentEmits, PopoverContentProps } from 'radix-vue'
3+
import type { HTMLAttributes } from 'vue'
4+
import { cn } from '@/lib/utils'
5+
import {
6+
PopoverContent,
7+
8+
PopoverPortal,
9+
useForwardPropsEmits,
10+
} from 'radix-vue'
11+
import { computed } from 'vue'
12+
13+
defineOptions({
14+
inheritAttrs: false,
15+
})
16+
17+
const props = withDefaults(
18+
defineProps<PopoverContentProps & { class?: HTMLAttributes['class'] }>(),
19+
{
20+
align: 'center',
21+
sideOffset: 4,
22+
},
23+
)
24+
const emits = defineEmits<PopoverContentEmits>()
25+
26+
const delegatedProps = computed(() => {
27+
const { class: _, ...delegated } = props
28+
29+
return delegated
30+
})
31+
32+
const forwarded = useForwardPropsEmits(delegatedProps, emits)
33+
</script>
34+
35+
<template>
36+
<PopoverPortal>
37+
<PopoverContent
38+
v-bind="{ ...forwarded, ...$attrs }"
39+
:class="
40+
cn(
41+
'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',
42+
props.class,
43+
)
44+
"
45+
>
46+
<slot />
47+
</PopoverContent>
48+
</PopoverPortal>
49+
</template>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<script setup lang="ts">
2+
import type { PopoverTriggerProps } from 'radix-vue'
3+
import { PopoverTrigger } from 'radix-vue'
4+
5+
const props = defineProps<PopoverTriggerProps>()
6+
</script>
7+
8+
<template>
9+
<PopoverTrigger v-bind="props">
10+
<slot />
11+
</PopoverTrigger>
12+
</template>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { default as Popover } from './Popover.vue'
2+
export { default as PopoverContent } from './PopoverContent.vue'
3+
export { default as PopoverTrigger } from './PopoverTrigger.vue'

unraid-ui/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,4 @@ export {
155155
type ButtonProps,
156156
};
157157
export { Toaster } from '@/components/common/toast';
158+
export * from '@/components/common/popover';

web/_data/serverState.ts

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type {
1111
ServerState,
1212
// ServerUpdateOsResponse,
1313
} from '~/types/server';
14+
import { defineStore } from 'pinia'
1415

1516
// dayjs plugins
1617
// extend(customParseFormat);
@@ -132,20 +133,7 @@ const osVersionBranch = 'stable';
132133
// }
133134
// };
134135

135-
export const serverState: Server = {
136-
// activationCodeData: {
137-
// code: 'CC2KP3TDRF',
138-
// partnerName: 'OEM Partner',
139-
// partnerUrl: 'https://unraid.net/OEM+Partner',
140-
// sysModel: 'OEM Partner v1',
141-
// comment: 'OEM Partner NAS',
142-
// caseIcon: 'case-model.png',
143-
// header: '#ffffff',
144-
// headermetacolor: '#eeeeee',
145-
// background: '#000000',
146-
// showBannerGradient: 'yes',
147-
// partnerLogo: true,
148-
// },
136+
const baseServerState: Server = {
149137
avatar: 'https://source.unsplash.com/300x300/?portrait',
150138
config: {
151139
id: 'config-id',
@@ -204,3 +192,33 @@ export const serverState: Server = {
204192
username: 'zspearmint',
205193
wanFQDN: '',
206194
};
195+
196+
export type ServerSelector = 'default' | 'oemActivation';
197+
const defaultServer: ServerSelector = 'default';
198+
199+
const servers: Record<ServerSelector, Server> = {
200+
default: baseServerState,
201+
/** shows oem activation flow */
202+
oemActivation: {
203+
...baseServerState,
204+
activationCodeData: {
205+
code: 'CC2KP3TDRF',
206+
partnerName: 'OEM Partner',
207+
partnerUrl: 'https://unraid.net/OEM+Partner',
208+
sysModel: 'OEM Partner v1',
209+
comment: 'OEM Partner NAS',
210+
caseIcon: 'case-model.png',
211+
header: '#ffffff',
212+
headermetacolor: '#eeeeee',
213+
background: '#000000',
214+
showBannerGradient: 'yes',
215+
partnerLogo: true,
216+
},
217+
},
218+
};
219+
220+
export const useDummyServerStore = defineStore('_dummyServer',() => {
221+
const selector = ref<ServerSelector>(defaultServer);
222+
const serverState = computed(() => servers[selector.value] ?? servers.default);
223+
return { selector, serverState };
224+
})

web/components/DevSettings.vue

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<script lang="ts" setup>
2+
import {
3+
Popover,
4+
PopoverContent,
5+
PopoverTrigger,
6+
Button,
7+
} from '@unraid/ui';
8+
9+
import { CogIcon } from '@heroicons/vue/24/solid';
10+
</script>
11+
12+
<template>
13+
<Popover>
14+
<PopoverTrigger as-child>
15+
<Button type="button" size="icon" class="fixed bottom-4 right-4 rounded-full bg-teal-500 z-50"><CogIcon class="size-6" /></Button>
16+
</PopoverTrigger>
17+
<PopoverContent>
18+
<DummyServerSwitcher />
19+
</PopoverContent>
20+
</Popover>
21+
22+
23+
</template>
24+
25+
<style lang="postcss">
26+
/* Import unraid-ui globals first */
27+
@import '@unraid/ui/styles';
28+
@import '../assets/main.css';
29+
</style>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<script lang="ts" setup>
2+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@unraid/ui';
3+
import { useDummyServerStore, type ServerSelector } from '~/_data/serverState';
4+
5+
const store = useDummyServerStore();
6+
const { selector, serverState } = storeToRefs(store);
7+
8+
const updateSelector = (val: string) => {
9+
selector.value = val as ServerSelector;
10+
};
11+
</script>
12+
13+
<template>
14+
<div class="flex flex-col gap-2 border-solid border-2 p-2 border-r-2">
15+
<h1 class="text-lg">Server State Selection</h1>
16+
<details>
17+
<summary>Initial Server State: {{ selector }}</summary>
18+
<pre>{{ JSON.stringify(serverState, null, 4) }}</pre>
19+
</details>
20+
<Select v-model="selector" @update:model-value="updateSelector">
21+
<SelectTrigger>
22+
<SelectValue placeholder="Select an initial state" />
23+
</SelectTrigger>
24+
<SelectContent>
25+
<SelectItem value="default">Default</SelectItem>
26+
<SelectItem value="oemActiviation">OEM Activation</SelectItem>
27+
</SelectContent>
28+
</Select>
29+
</div>
30+
</template>
31+
32+
<style lang="postcss">
33+
/* Import unraid-ui globals first */
34+
@import '@unraid/ui/styles';
35+
@import '../assets/main.css';
36+
</style>

web/pages/index.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
<script lang="ts" setup>
22
import { ExclamationTriangleIcon } from '@heroicons/vue/24/solid';
33
import { BrandButton, BrandLogo } from '@unraid/ui';
4-
import { serverState } from '~/_data/serverState';
4+
import { useDummyServerStore } from '~/_data/serverState';
55
import AES from 'crypto-js/aes';
66
77
import type { SendPayloads } from '~/store/callback';
88
99
import SsoButtonCe from '~/components/SsoButton.ce.vue';
1010
11+
const serverStore = useDummyServerStore();
12+
const { serverState } = storeToRefs(serverStore);
1113
const { registerEntry } = useCustomElements();
1214
onBeforeMount(() => {
1315
registerEntry('UnraidComponents');
@@ -80,6 +82,7 @@ onMounted(() => {
8082
<div class="pb-12 mx-auto">
8183
<client-only>
8284
<div class="flex flex-col gap-6 p-6">
85+
<DummyServerSwitcher />
8386
<ColorSwitcherCe />
8487
<h2 class="text-xl font-semibold font-mono">Vue Components</h2>
8588
<h3 class="text-lg font-semibold font-mono">UserProfileCe</h3>

web/pages/webComponents.vue

Lines changed: 26 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<script lang="ts" setup>
2-
import { serverState } from '~/_data/serverState';
2+
import { useDummyServerStore } from '~/_data/serverState';
33
4+
const serverStore = useDummyServerStore();
5+
const { serverState } = storeToRefs(serverStore);
46
const { registerEntry } = useCustomElements();
57
onBeforeMount(() => {
68
registerEntry('UnraidComponents');
@@ -12,12 +14,8 @@ onBeforeMount(() => {
1214
<unraid-i18n-host
1315
class="flex flex-col gap-6 p-6 mx-auto text-black bg-white dark:text-white dark:bg-black"
1416
>
15-
<h2 class="text-xl font-semibold font-mono">
16-
Web Components
17-
</h2>
18-
<h3 class="text-lg font-semibold font-mono">
19-
UserProfileCe
20-
</h3>
17+
<h2 class="text-xl font-semibold font-mono">Web Components</h2>
18+
<h3 class="text-lg font-semibold font-mono">UserProfileCe</h3>
2119
<header class="bg-header-background-color py-4 flex flex-row justify-between items-center">
2220
<div class="inline-flex flex-col gap-4 items-start px-4">
2321
<a href="https://unraid.net" target="_blank">
@@ -27,59 +25,36 @@ onBeforeMount(() => {
2725
</div>
2826
<unraid-user-profile :server="JSON.stringify(serverState)" />
2927
</header>
30-
<hr class="border-black dark:border-white" >
28+
<hr class="border-black dark:border-white" />
3129

32-
<h3 class="text-lg font-semibold font-mono">
33-
ConnectSettingsCe
34-
</h3>
30+
<h3 class="text-lg font-semibold font-mono">ConnectSettingsCe</h3>
3531
<ConnectSettingsCe />
36-
<hr class="border-black dark:border-white">
37-
<h3 class="text-lg font-semibold font-mono">
38-
DownloadApiLogsCe
39-
</h3>
32+
<hr class="border-black dark:border-white" />
33+
<h3 class="text-lg font-semibold font-mono">DownloadApiLogsCe</h3>
4034
<unraid-download-api-logs />
41-
<hr class="border-black dark:border-white">
42-
<h3 class="text-lg font-semibold font-mono">
43-
AuthCe
44-
</h3>
35+
<hr class="border-black dark:border-white" />
36+
<h3 class="text-lg font-semibold font-mono">AuthCe</h3>
4537
<unraid-auth />
46-
<hr class="border-black dark:border-white">
47-
<h3 class="text-lg font-semibold font-mono">
48-
WanIpCheckCe
49-
</h3>
38+
<hr class="border-black dark:border-white" />
39+
<h3 class="text-lg font-semibold font-mono">WanIpCheckCe</h3>
5040
<unraid-wan-ip-check php-wan-ip="47.184.85.45" />
51-
<hr class="border-black dark:border-white">
52-
<h3 class="text-lg font-semibold font-mono">
53-
HeaderOsVersion
54-
</h3>
41+
<hr class="border-black dark:border-white" />
42+
<h3 class="text-lg font-semibold font-mono">HeaderOsVersion</h3>
5543
<unraid-header-os-version />
56-
<hr class="border-black dark:border-white">
57-
<h3 class="text-lg font-semibold font-mono">
58-
UpdateOsCe
59-
</h3>
44+
<hr class="border-black dark:border-white" />
45+
<h3 class="text-lg font-semibold font-mono">UpdateOsCe</h3>
6046
<unraid-update-os />
61-
<hr class="border-black dark:border-white">
62-
<h3 class="text-lg font-semibold font-mono">
63-
DowngradeOsCe
64-
</h3>
65-
<unraid-downgrade-os
66-
restore-release-date="2022-10-10"
67-
restore-version="6.11.2"
68-
/>
69-
<hr class="border-black dark:border-white">
70-
<h3 class="text-lg font-semibold font-mono">
71-
RegistrationCe
72-
</h3>
47+
<hr class="border-black dark:border-white" />
48+
<h3 class="text-lg font-semibold font-mono">DowngradeOsCe</h3>
49+
<unraid-downgrade-os restore-release-date="2022-10-10" restore-version="6.11.2" />
50+
<hr class="border-black dark:border-white" />
51+
<h3 class="text-lg font-semibold font-mono">RegistrationCe</h3>
7352
<unraid-registration />
74-
<hr class="border-black dark:border-white">
75-
<h3 class="text-lg font-semibold font-mono">
76-
ModalsCe
77-
</h3>
53+
<hr class="border-black dark:border-white" />
54+
<h3 class="text-lg font-semibold font-mono">ModalsCe</h3>
7855
<!-- uncomment to test modals <unraid-modals />-->
79-
<hr class="border-black dark:border-white">
80-
<h3 class="text-lg font-semibold font-mono">
81-
SSOSignInButtonCe
82-
</h3>
56+
<hr class="border-black dark:border-white" />
57+
<h3 class="text-lg font-semibold font-mono">SSOSignInButtonCe</h3>
8358
<unraid-sso-button :ssoenabled="serverState.ssoEnabled" />
8459
</unraid-i18n-host>
8560
</client-only>

0 commit comments

Comments
 (0)