diff --git a/src/components/dialog/GlobalDialog.vue b/src/components/dialog/GlobalDialog.vue
index 67f21481d7..6abf62db22 100644
--- a/src/components/dialog/GlobalDialog.vue
+++ b/src/components/dialog/GlobalDialog.vue
@@ -8,9 +8,10 @@
@update:open="(open) => onRekaOpenChange(item.key, open)"
>
-
+
dialogStore.riseDialog({ key: item.key })"
>
-
-
-
- {{ item.title || ' ' }}
-
-
-
-
+
-
-
-
-
+
+
+
+
+
+ {{ item.title || ' ' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -55,7 +74,6 @@
v-model:visible="item.visible"
class="global-dialog"
v-bind="item.dialogComponentProps"
- :pt="getDialogPt(item)"
:aria-labelledby="item.key"
>
@@ -86,29 +104,20 @@
@@ -163,19 +160,6 @@ function getDialogPt(item: {
}
}
-/* Workspace mode: wider settings dialog */
-.settings-dialog-workspace {
- width: 100%;
- max-width: 1440px;
- height: 100%;
-}
-
-.settings-dialog-workspace .p-dialog-content {
- width: 100%;
- height: 100%;
- overflow-y: auto;
-}
-
.manager-dialog {
height: 80vh;
max-width: 1724px;
diff --git a/src/components/ui/dialog/DialogContent.vue b/src/components/ui/dialog/DialogContent.vue
index 4d89e5c0a2..c318107642 100644
--- a/src/components/ui/dialog/DialogContent.vue
+++ b/src/components/ui/dialog/DialogContent.vue
@@ -10,11 +10,13 @@ import { dialogContentVariants } from './dialog.variants'
const {
size,
+ maximized = false,
class: customClass = '',
...restProps
} = defineProps<
DialogContentProps & {
size?: DialogContentSize
+ maximized?: boolean
class?: HTMLAttributes['class']
}
>()
@@ -26,7 +28,7 @@ const forwarded = useForwardPropsEmits(restProps, emits)
diff --git a/src/components/ui/dialog/DialogMaximize.vue b/src/components/ui/dialog/DialogMaximize.vue
new file mode 100644
index 0000000000..dd66494de6
--- /dev/null
+++ b/src/components/ui/dialog/DialogMaximize.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
diff --git a/src/components/ui/dialog/dialog.variants.ts b/src/components/ui/dialog/dialog.variants.ts
index f3b7d1b61e..2ee8b7de2a 100644
--- a/src/components/ui/dialog/dialog.variants.ts
+++ b/src/components/ui/dialog/dialog.variants.ts
@@ -2,7 +2,7 @@ import type { VariantProps } from 'cva'
import { cva } from 'cva'
export const dialogContentVariants = cva({
- base: 'fixed top-1/2 left-1/2 z-1700 flex max-h-[85vh] w-[calc(100vw-1rem)] -translate-x-1/2 -translate-y-1/2 flex-col rounded-lg border border-border-subtle bg-base-background shadow-lg outline-none data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95',
+ base: 'fixed z-1700 flex flex-col rounded-lg border border-border-subtle bg-base-background shadow-lg outline-none data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95',
variants: {
size: {
sm: 'sm:max-w-sm',
@@ -10,10 +10,15 @@ export const dialogContentVariants = cva({
lg: 'sm:max-w-3xl',
xl: 'sm:max-w-5xl',
full: 'sm:max-w-[calc(100vw-1rem)]'
+ },
+ maximized: {
+ true: 'inset-2 top-2 left-2 size-auto max-h-none max-w-none sm:max-w-none',
+ false: 'top-1/2 left-1/2 max-h-[85vh] w-[calc(100vw-1rem)] -translate-1/2'
}
},
defaultVariants: {
- size: 'md'
+ size: 'md',
+ maximized: false
}
})
diff --git a/src/locales/en/main.json b/src/locales/en/main.json
index 85d6009b5f..709fb9fe74 100644
--- a/src/locales/en/main.json
+++ b/src/locales/en/main.json
@@ -138,6 +138,8 @@
"hideLeftPanel": "Hide left panel",
"showRightPanel": "Show right panel",
"hideRightPanel": "Hide right panel",
+ "maximizeDialog": "Maximize dialog",
+ "restoreDialog": "Restore dialog",
"or": "or",
"defaultBanner": "default banner",
"enableOrDisablePack": "Enable or disable pack",
diff --git a/src/platform/settings/composables/useSettingsDialog.test.ts b/src/platform/settings/composables/useSettingsDialog.test.ts
new file mode 100644
index 0000000000..836d457538
--- /dev/null
+++ b/src/platform/settings/composables/useSettingsDialog.test.ts
@@ -0,0 +1,92 @@
+/**
+ * Settings dialog migration regression net: `useSettingsDialog().show()` must
+ * open the Reka-renderer path with sizing that matches the previous
+ * `BaseModalLayout size="sm"` (960px × 80vh). Catches accidental reverts of
+ * the Phase 3 renderer flip.
+ */
+import { beforeEach, describe, expect, it, vi } from 'vitest'
+
+const showDialog = vi.hoisted(() => vi.fn())
+const teamWorkspacesFlag = vi.hoisted(() => ({ value: false }))
+const isCloudRef = vi.hoisted(() => ({ value: false }))
+
+vi.mock('@/stores/dialogStore', () => ({
+ useDialogStore: () => ({ showDialog, closeDialog: vi.fn() })
+}))
+
+vi.mock('@/composables/useFeatureFlags', () => ({
+ useFeatureFlags: () => ({
+ flags: {
+ get teamWorkspacesEnabled() {
+ return teamWorkspacesFlag.value
+ }
+ }
+ })
+}))
+
+vi.mock('@/platform/distribution/types', () => ({
+ get isCloud() {
+ return isCloudRef.value
+ }
+}))
+
+vi.mock('@/i18n', () => ({ t: (k: string) => k }))
+
+vi.mock('@/platform/telemetry', () => ({
+ useTelemetry: () => ({ trackEvent: vi.fn() })
+}))
+
+vi.mock('@/composables/billing/useBillingContext', () => ({
+ useBillingContext: () => ({
+ isActiveSubscription: { value: true },
+ isFreeTier: { value: false },
+ type: { value: 'legacy' }
+ })
+}))
+
+import { useSettingsDialog } from '@/platform/settings/composables/useSettingsDialog'
+
+describe('useSettingsDialog', () => {
+ beforeEach(() => {
+ showDialog.mockReset()
+ teamWorkspacesFlag.value = false
+ isCloudRef.value = false
+ })
+
+ it("show() opens the Reka renderer with size 'full' and 960px content sizing", () => {
+ useSettingsDialog().show()
+ const [args] = showDialog.mock.calls[0]
+ expect(args.key).toBe('global-settings')
+ expect(args.dialogComponentProps.renderer).toBe('reka')
+ expect(args.dialogComponentProps.size).toBe('full')
+ expect(args.dialogComponentProps.contentClass).toContain('max-w-[960px]')
+ expect(args.dialogComponentProps.contentClass).toContain('h-[80vh]')
+ })
+
+ it('show() omits overlayClass when not in workspace mode', () => {
+ useSettingsDialog().show()
+ const [args] = showDialog.mock.calls[0]
+ expect(args.dialogComponentProps.overlayClass).toBeUndefined()
+ })
+
+ it("show() sets overlayClass 'p-8' when isCloud && teamWorkspacesEnabled", () => {
+ isCloudRef.value = true
+ teamWorkspacesFlag.value = true
+
+ useSettingsDialog().show()
+ const [args] = showDialog.mock.calls[0]
+ expect(args.dialogComponentProps.overlayClass).toBe('p-8')
+ })
+
+ it('show(panel) forwards defaultPanel to the dialog props', () => {
+ useSettingsDialog().show('about')
+ const [args] = showDialog.mock.calls[0]
+ expect(args.props.defaultPanel).toBe('about')
+ })
+
+ it('showAbout() opens the about panel', () => {
+ useSettingsDialog().showAbout()
+ const [args] = showDialog.mock.calls[0]
+ expect(args.props.defaultPanel).toBe('about')
+ })
+})
diff --git a/src/platform/settings/composables/useSettingsDialog.ts b/src/platform/settings/composables/useSettingsDialog.ts
index bb8162ad38..730637c6c4 100644
--- a/src/platform/settings/composables/useSettingsDialog.ts
+++ b/src/platform/settings/composables/useSettingsDialog.ts
@@ -1,3 +1,5 @@
+import { useFeatureFlags } from '@/composables/useFeatureFlags'
+import { isCloud } from '@/platform/distribution/types'
import { useDialogService } from '@/services/dialogService'
import { useDialogStore } from '@/stores/dialogStore'
@@ -6,15 +8,20 @@ import type { SettingPanelType } from '@/platform/settings/types'
const DIALOG_KEY = 'global-settings'
+const SETTINGS_CONTENT_CLASS =
+ 'w-[90vw] max-w-[960px] sm:max-w-[960px] h-[80vh] max-h-none rounded-2xl overflow-hidden'
+
export function useSettingsDialog() {
const dialogService = useDialogService()
const dialogStore = useDialogStore()
+ const { flags } = useFeatureFlags()
function hide() {
dialogStore.closeDialog({ key: DIALOG_KEY })
}
function show(panel?: SettingPanelType, settingId?: string) {
+ const isWorkspaceMode = isCloud && flags.teamWorkspacesEnabled
dialogService.showLayoutDialog({
key: DIALOG_KEY,
component: SettingDialog,
@@ -22,6 +29,12 @@ export function useSettingsDialog() {
onClose: hide,
...(panel ? { defaultPanel: panel } : {}),
...(settingId ? { scrollToSettingId: settingId } : {})
+ },
+ dialogComponentProps: {
+ renderer: 'reka',
+ size: 'full',
+ contentClass: SETTINGS_CONTENT_CLASS,
+ overlayClass: isWorkspaceMode ? 'p-8' : undefined
}
})
}
diff --git a/src/stores/dialogStore.ts b/src/stores/dialogStore.ts
index 4bb3161391..e0447884dc 100644
--- a/src/stores/dialogStore.ts
+++ b/src/stores/dialogStore.ts
@@ -48,6 +48,11 @@ interface CustomDialogComponentProps {
* PrimeVue path — use `pt` for that renderer.
*/
contentClass?: HTMLAttributes['class']
+ /**
+ * Class applied to the Reka-UI `DialogOverlay` element. Ignored on the
+ * PrimeVue path — use `pt.mask` for that renderer.
+ */
+ overlayClass?: HTMLAttributes['class']
}
export type DialogComponentProps = ComponentAttrs &