diff --git a/apps/app-frontend/src/components/ui/modal/ServerSettingsModal.vue b/apps/app-frontend/src/components/ui/modal/ServerSettingsModal.vue new file mode 100644 index 0000000000..3e05f033fe --- /dev/null +++ b/apps/app-frontend/src/components/ui/modal/ServerSettingsModal.vue @@ -0,0 +1,256 @@ + + + diff --git a/apps/app-frontend/src/locales/en-US/index.json b/apps/app-frontend/src/locales/en-US/index.json index f7f558ae65..d93726e438 100644 --- a/apps/app-frontend/src/locales/en-US/index.json +++ b/apps/app-frontend/src/locales/en-US/index.json @@ -185,6 +185,9 @@ "app.modal.update-to-play.update-required-description": { "message": "An update is required to play {name}. Please update to the latest version to launch the game." }, + "app.server-settings.failed-to-load-server": { + "message": "Failed to load server settings" + }, "app.settings.developer-mode-enabled": { "message": "Developer mode enabled." }, @@ -598,5 +601,11 @@ }, "search.filter.locked.server-loader.title": { "message": "Loader is provided by the server" + }, + "servers.busy.installing": { + "message": "Server is installing" + }, + "servers.busy.syncing-content": { + "message": "Content sync in progress" } } diff --git a/apps/app-frontend/src/pages/hosting/manage/Backups.vue b/apps/app-frontend/src/pages/hosting/manage/Backups.vue new file mode 100644 index 0000000000..59f00d03ea --- /dev/null +++ b/apps/app-frontend/src/pages/hosting/manage/Backups.vue @@ -0,0 +1,9 @@ + + + diff --git a/apps/app-frontend/src/pages/hosting/manage/Content.vue b/apps/app-frontend/src/pages/hosting/manage/Content.vue new file mode 100644 index 0000000000..02742246de --- /dev/null +++ b/apps/app-frontend/src/pages/hosting/manage/Content.vue @@ -0,0 +1,7 @@ + + + diff --git a/apps/app-frontend/src/pages/hosting/manage/Files.vue b/apps/app-frontend/src/pages/hosting/manage/Files.vue new file mode 100644 index 0000000000..532c9b1392 --- /dev/null +++ b/apps/app-frontend/src/pages/hosting/manage/Files.vue @@ -0,0 +1,7 @@ + + + diff --git a/apps/app-frontend/src/pages/hosting/manage/Index.vue b/apps/app-frontend/src/pages/hosting/manage/Index.vue new file mode 100644 index 0000000000..3fa9a8b674 --- /dev/null +++ b/apps/app-frontend/src/pages/hosting/manage/Index.vue @@ -0,0 +1,348 @@ + + + diff --git a/apps/app-frontend/src/pages/hosting/manage/index.js b/apps/app-frontend/src/pages/hosting/manage/index.js new file mode 100644 index 0000000000..127c22afce --- /dev/null +++ b/apps/app-frontend/src/pages/hosting/manage/index.js @@ -0,0 +1,6 @@ +import Backups from './Backups.vue' +import Content from './Content.vue' +import Files from './Files.vue' +import Index from './Index.vue' + +export { Backups, Content, Files, Index } diff --git a/apps/app-frontend/src/routes.js b/apps/app-frontend/src/routes.js index 18c6df173c..456cc68991 100644 --- a/apps/app-frontend/src/routes.js +++ b/apps/app-frontend/src/routes.js @@ -2,6 +2,7 @@ import { ServersManagePageIndex } from '@modrinth/ui' import { createRouter, createWebHistory } from 'vue-router' import * as Pages from '@/pages' +import * as Hosting from '@/pages/hosting/manage' import * as Instance from '@/pages/instance' import * as Library from '@/pages/library' import * as Project from '@/pages/project' @@ -36,6 +37,36 @@ export default new createRouter({ breadcrumb: [{ name: 'Servers' }], }, }, + { + path: '/hosting/manage/:id', + name: 'ServerManage', + component: Hosting.Index, + children: [ + { + path: '', + redirect: (to) => { + const rawId = Array.isArray(to.params.id) ? to.params.id[0] : to.params.id + if (!rawId) return '/hosting/manage' + return `/hosting/manage/${encodeURIComponent(rawId)}/content` + }, + }, + { + path: 'content', + name: 'ServerManageContent', + component: Hosting.Content, + }, + { + path: 'files', + name: 'ServerManageFiles', + component: Hosting.Files, + }, + { + path: 'backups', + name: 'ServerManageBackups', + component: Hosting.Backups, + }, + ], + }, { path: '/browse/:projectType', name: 'Discover content', diff --git a/apps/frontend/src/assets/styles/components.scss b/apps/frontend/src/assets/styles/components.scss index 9ac5ec5b91..b04291d4c7 100644 --- a/apps/frontend/src/assets/styles/components.scss +++ b/apps/frontend/src/assets/styles/components.scss @@ -841,6 +841,23 @@ button { opacity: 0.5; box-shadow: none; flex-shrink: 0; + user-select: none; + } + + .text-input-wrapper__after { + display: flex; + color: var(--color-text); + padding: 0.5rem 1rem 0.5rem 0; + font-weight: var(--font-weight-medium); + min-height: 36px; + box-sizing: border-box; + width: fit-content; + align-items: center; + filter: grayscale(50%); + opacity: 0.5; + box-shadow: none; + flex-shrink: 0; + user-select: none; } input, diff --git a/apps/frontend/src/components/ui/servers/SaveBanner.vue b/apps/frontend/src/components/ui/servers/SaveBanner.vue index d06b16f6bf..a43e4dd1f1 100644 --- a/apps/frontend/src/components/ui/servers/SaveBanner.vue +++ b/apps/frontend/src/components/ui/servers/SaveBanner.vue @@ -1,36 +1,5 @@ - - - + diff --git a/apps/frontend/src/locales/en-US/index.json b/apps/frontend/src/locales/en-US/index.json index f91c60de95..47a0d0a3c6 100644 --- a/apps/frontend/src/locales/en-US/index.json +++ b/apps/frontend/src/locales/en-US/index.json @@ -1301,60 +1301,6 @@ "hosting-marketing.why.your-favorite-mods.description": { "message": "Choose between Vanilla, Fabric, Forge, Quilt and NeoForge. If it's on Modrinth, it can run on your server." }, - "hosting.loader.failed-to-change-version": { - "message": "Failed to change modpack version" - }, - "hosting.loader.failed-to-load-versions": { - "message": "Failed to load versions" - }, - "hosting.loader.failed-to-reinstall": { - "message": "Failed to reinstall modpack" - }, - "hosting.loader.failed-to-repair": { - "message": "Failed to repair server" - }, - "hosting.loader.failed-to-reset-to-onboarding": { - "message": "Failed to reset server to onboarding" - }, - "hosting.loader.failed-to-save-settings": { - "message": "Failed to save installation settings" - }, - "hosting.loader.failed-to-unlink": { - "message": "Failed to unlink modpack" - }, - "hosting.loader.loader-version": { - "message": "{loader, select, null {Loader} other {{loader}}} version" - }, - "hosting.loader.repair-started-text": { - "message": "Your server installation has been repaired." - }, - "hosting.loader.repair-started-title": { - "message": "Repair completed" - }, - "hosting.loader.reset-server": { - "message": "Reset server" - }, - "hosting.loader.reset-server-description": { - "message": "Removes all data on your server, including your worlds, mods, and configuration files. Backups will remain and can be restored." - }, - "hosting.loader.reset-to-onboarding-button": { - "message": "Reset to onboarding" - }, - "hosting.loader.reset-to-onboarding-modal-description": { - "message": "This will send the server back into onboarding so setup can be completed again. Are you sure you want to continue?" - }, - "hosting.loader.reset-to-onboarding-modal-title": { - "message": "Reset to onboarding" - }, - "hosting.loader.reset-to-onboarding-success-description": { - "message": "The server has been returned to the onboarding flow." - }, - "hosting.loader.reset-to-onboarding-success-title": { - "message": "Server reset to onboarding" - }, - "hosting.loader.support-options-title": { - "message": "Support options" - }, "hosting.plan.out-of-stock": { "message": "Out of stock" }, diff --git a/apps/frontend/src/pages/hosting/manage/[id]/options.vue b/apps/frontend/src/pages/hosting/manage/[id]/options.vue index 9d4697de05..6fa28b857f 100644 --- a/apps/frontend/src/pages/hosting/manage/[id]/options.vue +++ b/apps/frontend/src/pages/hosting/manage/[id]/options.vue @@ -5,18 +5,13 @@ diff --git a/apps/frontend/src/pages/hosting/manage/[id]/options/advanced.vue b/apps/frontend/src/pages/hosting/manage/[id]/options/advanced.vue new file mode 100644 index 0000000000..2c84c0b81c --- /dev/null +++ b/apps/frontend/src/pages/hosting/manage/[id]/options/advanced.vue @@ -0,0 +1,7 @@ + + + diff --git a/apps/frontend/src/pages/hosting/manage/[id]/options/billing.vue b/apps/frontend/src/pages/hosting/manage/[id]/options/billing.vue index db707f8a1e..45455232a0 100644 --- a/apps/frontend/src/pages/hosting/manage/[id]/options/billing.vue +++ b/apps/frontend/src/pages/hosting/manage/[id]/options/billing.vue @@ -1,12 +1,7 @@ - - + + diff --git a/apps/frontend/src/pages/hosting/manage/[id]/options/index.vue b/apps/frontend/src/pages/hosting/manage/[id]/options/index.vue index 09d45c96bc..7eae2979d9 100644 --- a/apps/frontend/src/pages/hosting/manage/[id]/options/index.vue +++ b/apps/frontend/src/pages/hosting/manage/[id]/options/index.vue @@ -1,335 +1,7 @@ - - + + diff --git a/apps/frontend/src/pages/hosting/manage/[id]/options/info.vue b/apps/frontend/src/pages/hosting/manage/[id]/options/info.vue deleted file mode 100644 index 35f89ad0ba..0000000000 --- a/apps/frontend/src/pages/hosting/manage/[id]/options/info.vue +++ /dev/null @@ -1,154 +0,0 @@ - - - diff --git a/apps/frontend/src/pages/hosting/manage/[id]/options/loader.vue b/apps/frontend/src/pages/hosting/manage/[id]/options/loader.vue index 247ddffd47..35da56c216 100644 --- a/apps/frontend/src/pages/hosting/manage/[id]/options/loader.vue +++ b/apps/frontend/src/pages/hosting/manage/[id]/options/loader.vue @@ -1,695 +1,15 @@ - - + + diff --git a/apps/frontend/src/pages/hosting/manage/[id]/options/network.vue b/apps/frontend/src/pages/hosting/manage/[id]/options/network.vue index f9fd5f60eb..f7436993c6 100644 --- a/apps/frontend/src/pages/hosting/manage/[id]/options/network.vue +++ b/apps/frontend/src/pages/hosting/manage/[id]/options/network.vue @@ -1,507 +1,7 @@ - - + + diff --git a/apps/frontend/src/pages/hosting/manage/[id]/options/preferences.vue b/apps/frontend/src/pages/hosting/manage/[id]/options/preferences.vue deleted file mode 100644 index d3c84bf5b0..0000000000 --- a/apps/frontend/src/pages/hosting/manage/[id]/options/preferences.vue +++ /dev/null @@ -1,113 +0,0 @@ - - - diff --git a/apps/frontend/src/pages/hosting/manage/[id]/options/properties.vue b/apps/frontend/src/pages/hosting/manage/[id]/options/properties.vue index ae73daf967..3776217bbe 100644 --- a/apps/frontend/src/pages/hosting/manage/[id]/options/properties.vue +++ b/apps/frontend/src/pages/hosting/manage/[id]/options/properties.vue @@ -1,292 +1,7 @@ - - + + diff --git a/apps/frontend/src/pages/hosting/manage/[id]/options/startup.vue b/apps/frontend/src/pages/hosting/manage/[id]/options/startup.vue deleted file mode 100644 index d8fd8c9859..0000000000 --- a/apps/frontend/src/pages/hosting/manage/[id]/options/startup.vue +++ /dev/null @@ -1,287 +0,0 @@ - - - diff --git a/packages/ui/src/components/base/ButtonStyled.vue b/packages/ui/src/components/base/ButtonStyled.vue index 30b7eb9aca..8efe520a4d 100644 --- a/packages/ui/src/components/base/ButtonStyled.vue +++ b/packages/ui/src/components/base/ButtonStyled.vue @@ -263,7 +263,7 @@ const fontSize = computed(() => { > *:first-child > *:first-child > :is(button, a, .button-like):first-child { - @apply flex cursor-pointer flex-row items-center justify-center border-solid border-2 border-transparent bg-[--_bg] text-[--_text] h-[--_height] min-w-[--_width] rounded-[--_radius] px-[--_padding-x] py-[--_padding-y] gap-[--_gap] font-[--_font-weight] whitespace-nowrap; + @apply flex cursor-pointer flex-row items-center justify-center border-solid border border-transparent bg-[--_bg] text-[--_text] h-[--_height] min-w-[--_width] rounded-[--_radius] px-[--_padding-x] py-[--_padding-y] gap-[--_gap] font-[--_font-weight] whitespace-nowrap; box-shadow: var(--_box-shadow, inset 0 0 0 transparent); transition: scale 0.125s ease-in-out, diff --git a/packages/ui/src/components/base/CopyCode.vue b/packages/ui/src/components/base/CopyCode.vue index f046b5f12c..0c30d7e5c0 100644 --- a/packages/ui/src/components/base/CopyCode.vue +++ b/packages/ui/src/components/base/CopyCode.vue @@ -57,12 +57,11 @@ async function copyText() { } &:hover { - filter: brightness(0.85); + filter: brightness(1.25); } &:active { transform: scale(0.95); - filter: brightness(0.8); } } diff --git a/packages/ui/src/components/base/Table.vue b/packages/ui/src/components/base/Table.vue index b84f5a54c2..d952a5337b 100644 --- a/packages/ui/src/components/base/Table.vue +++ b/packages/ui/src/components/base/Table.vue @@ -1,7 +1,7 @@ diff --git a/packages/ui/src/layouts/shared/server-settings/index.ts b/packages/ui/src/layouts/shared/server-settings/index.ts new file mode 100644 index 0000000000..5f1ecde43b --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/index.ts @@ -0,0 +1,3 @@ +export * from './pages' +export * from './providers' +export * from './tabs' diff --git a/packages/ui/src/layouts/shared/server-settings/pages/admin-billing.vue b/packages/ui/src/layouts/shared/server-settings/pages/admin-billing.vue new file mode 100644 index 0000000000..7277ec2904 --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/pages/admin-billing.vue @@ -0,0 +1,27 @@ + + + diff --git a/packages/ui/src/layouts/shared/server-settings/pages/advanced.vue b/packages/ui/src/layouts/shared/server-settings/pages/advanced.vue new file mode 100644 index 0000000000..5d7dfc6273 --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/pages/advanced.vue @@ -0,0 +1,383 @@ + + + diff --git a/packages/ui/src/layouts/shared/server-settings/pages/billing.vue b/packages/ui/src/layouts/shared/server-settings/pages/billing.vue new file mode 100644 index 0000000000..3b240cbde6 --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/pages/billing.vue @@ -0,0 +1,25 @@ + + + diff --git a/packages/ui/src/layouts/shared/server-settings/pages/general.vue b/packages/ui/src/layouts/shared/server-settings/pages/general.vue new file mode 100644 index 0000000000..df2741bd43 --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/pages/general.vue @@ -0,0 +1,425 @@ + + + diff --git a/packages/ui/src/layouts/shared/server-settings/pages/index.ts b/packages/ui/src/layouts/shared/server-settings/pages/index.ts new file mode 100644 index 0000000000..5e6a1b05f3 --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/pages/index.ts @@ -0,0 +1,7 @@ +export { default as ServerSettingsAdminBillingPage } from './admin-billing.vue' +export { default as ServerSettingsAdvancedPage } from './advanced.vue' +export { default as ServerSettingsBillingPage } from './billing.vue' +export { default as ServerSettingsGeneralPage } from './general.vue' +export { default as ServerSettingsInstallationPage } from './installation.vue' +export { default as ServerSettingsNetworkPage } from './network.vue' +export { default as ServerSettingsPropertiesPage } from './properties.vue' diff --git a/packages/ui/src/layouts/shared/server-settings/pages/installation.vue b/packages/ui/src/layouts/shared/server-settings/pages/installation.vue new file mode 100644 index 0000000000..874919beb5 --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/pages/installation.vue @@ -0,0 +1,697 @@ + + + diff --git a/packages/ui/src/layouts/shared/server-settings/pages/network.vue b/packages/ui/src/layouts/shared/server-settings/pages/network.vue new file mode 100644 index 0000000000..dedecd90ef --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/pages/network.vue @@ -0,0 +1,438 @@ + + + diff --git a/packages/ui/src/layouts/shared/server-settings/pages/properties.vue b/packages/ui/src/layouts/shared/server-settings/pages/properties.vue new file mode 100644 index 0000000000..c3eced98dd --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/pages/properties.vue @@ -0,0 +1,525 @@ + + + diff --git a/packages/ui/src/layouts/shared/server-settings/providers/index.ts b/packages/ui/src/layouts/shared/server-settings/providers/index.ts new file mode 100644 index 0000000000..5b5bed990a --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/providers/index.ts @@ -0,0 +1 @@ +export * from './server-settings' diff --git a/packages/ui/src/layouts/shared/server-settings/providers/server-settings.ts b/packages/ui/src/layouts/shared/server-settings/providers/server-settings.ts new file mode 100644 index 0000000000..e5bb553ada --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/providers/server-settings.ts @@ -0,0 +1,21 @@ +import type { Ref } from 'vue' + +import { createContext } from '#ui/providers/create-context' + +export interface ServerSettingsBrowseModpacksArgs { + serverId: string + worldId: string | null + from: 'reset-server' +} + +export interface ServerSettingsContext { + isApp: Ref + currentUserId: Ref + currentUserRole: Ref + browseModpacks: (args: ServerSettingsBrowseModpacksArgs) => void | Promise +} + +export const [injectServerSettings, provideServerSettings] = createContext( + 'ServerSettings', + 'serverSettingsContext', +) diff --git a/packages/ui/src/layouts/shared/server-settings/tabs.ts b/packages/ui/src/layouts/shared/server-settings/tabs.ts new file mode 100644 index 0000000000..82427d4288 --- /dev/null +++ b/packages/ui/src/layouts/shared/server-settings/tabs.ts @@ -0,0 +1,98 @@ +import type { Archon } from '@modrinth/api-client' +import { + CardIcon, + ListIcon, + ModrinthIcon, + SettingsIcon, + TextQuoteIcon, + VersionIcon, + WrenchIcon, +} from '@modrinth/assets' +import type { Component } from 'vue' + +export type ServerSettingsTabId = + | 'general' + | 'installation' + | 'network' + | 'properties' + | 'advanced' + | 'billing' + | 'admin-billing' + +export interface ServerSettingsTabContext { + serverId: string + ownerId: string + serverStatus?: Archon.Servers.v0.Status | null + isOwner: boolean + isAdmin: boolean +} + +export interface ServerSettingsTabDefinition { + id: ServerSettingsTabId + label: string + icon: Component + href: (ctx: ServerSettingsTabContext) => string + external?: boolean + shown?: (ctx: ServerSettingsTabContext) => boolean +} + +export const serverSettingsTabDefinitions: ServerSettingsTabDefinition[] = [ + { + id: 'general', + label: 'General', + icon: SettingsIcon, + href: ({ serverId }) => `/hosting/manage/${serverId}/options`, + }, + { + id: 'installation', + label: 'Installation', + icon: WrenchIcon, + href: ({ serverId }) => `/hosting/manage/${serverId}/options/loader`, + }, + { + id: 'network', + label: 'Network', + icon: VersionIcon, + href: ({ serverId }) => `/hosting/manage/${serverId}/options/network`, + }, + { + id: 'properties', + label: 'Properties', + icon: ListIcon, + href: ({ serverId }) => `/hosting/manage/${serverId}/options/properties`, + shown: ({ serverStatus }) => serverStatus !== 'installing', + }, + { + id: 'advanced', + label: 'Advanced', + icon: TextQuoteIcon, + href: ({ serverId }) => `/hosting/manage/${serverId}/options/advanced`, + }, + { + id: 'billing', + label: 'Billing', + icon: CardIcon, + href: ({ serverId }) => `/settings/billing#server-${serverId}`, + external: true, + shown: ({ isOwner }) => isOwner, + }, + { + id: 'admin-billing', + label: 'Admin Billing', + icon: ModrinthIcon, + href: ({ ownerId }) => `/admin/billing/${ownerId}`, + external: true, + shown: ({ isAdmin }) => isAdmin, + }, +] + +export function getServerSettingsNavLinks(ctx: ServerSettingsTabContext) { + return serverSettingsTabDefinitions.map((tab) => ({ + id: tab.id, + icon: tab.icon, + label: tab.label, + href: tab.href(ctx), + external: tab.external, + shown: tab.shown ? tab.shown(ctx) : true, + })) +} diff --git a/packages/ui/src/locales/en-US/index.json b/packages/ui/src/locales/en-US/index.json index 78548f369f..544eef277d 100644 --- a/packages/ui/src/locales/en-US/index.json +++ b/packages/ui/src/locales/en-US/index.json @@ -905,6 +905,60 @@ "hosting.content.failed-to-upload": { "defaultMessage": "Failed to upload file" }, + "hosting.loader.failed-to-change-version": { + "defaultMessage": "Failed to change modpack version" + }, + "hosting.loader.failed-to-load-versions": { + "defaultMessage": "Failed to load versions" + }, + "hosting.loader.failed-to-reinstall": { + "defaultMessage": "Failed to reinstall modpack" + }, + "hosting.loader.failed-to-repair": { + "defaultMessage": "Failed to repair server" + }, + "hosting.loader.failed-to-reset-to-onboarding": { + "defaultMessage": "Failed to reset server to onboarding" + }, + "hosting.loader.failed-to-save-settings": { + "defaultMessage": "Failed to save installation settings" + }, + "hosting.loader.failed-to-unlink": { + "defaultMessage": "Failed to unlink modpack" + }, + "hosting.loader.loader-version": { + "defaultMessage": "{loader, select, null {Loader} other {{loader}}} version" + }, + "hosting.loader.repair-started-text": { + "defaultMessage": "Your server installation has been repaired." + }, + "hosting.loader.repair-started-title": { + "defaultMessage": "Repair completed" + }, + "hosting.loader.reset-server": { + "defaultMessage": "Reset server" + }, + "hosting.loader.reset-server-description": { + "defaultMessage": "Removes all data on your server, including your worlds, mods, and configuration files. Backups will remain and can be restored." + }, + "hosting.loader.reset-to-onboarding-button": { + "defaultMessage": "Reset to onboarding" + }, + "hosting.loader.reset-to-onboarding-modal-description": { + "defaultMessage": "This will send the server back into onboarding so setup can be completed again. Are you sure you want to continue?" + }, + "hosting.loader.reset-to-onboarding-modal-title": { + "defaultMessage": "Reset to onboarding" + }, + "hosting.loader.reset-to-onboarding-success-description": { + "defaultMessage": "The server has been returned to the onboarding flow." + }, + "hosting.loader.reset-to-onboarding-success-title": { + "defaultMessage": "Server reset to onboarding" + }, + "hosting.loader.support-options-title": { + "defaultMessage": "Support options" + }, "hosting.specs.burst": { "defaultMessage": "Bursts up to {cpus} CPUs" }, diff --git a/packages/ui/src/stories/servers/SaveBanner.stories.ts b/packages/ui/src/stories/servers/SaveBanner.stories.ts new file mode 100644 index 0000000000..4985ef73ac --- /dev/null +++ b/packages/ui/src/stories/servers/SaveBanner.stories.ts @@ -0,0 +1,37 @@ +import type { Meta, StoryObj } from '@storybook/vue3-vite' + +import SaveBanner from '../../components/servers/SaveBanner.vue' + +const meta = { + title: 'Servers/SaveBanner', + component: SaveBanner, + parameters: { + layout: 'fullscreen', + }, + args: { + isVisible: true, + isUpdating: false, + restart: false, + serverId: 'server_123', + save: () => {}, + reset: () => {}, + }, +} satisfies Meta + +export default meta + +type Story = StoryObj + +export const Default: Story = {} + +export const Saving: Story = { + args: { + isUpdating: true, + }, +} + +export const WithRestart: Story = { + args: { + restart: true, + }, +}