diff --git a/packages/@core/ui-kit/form-ui/src/form-render/form.vue b/packages/@core/ui-kit/form-ui/src/form-render/form.vue index ff18972ad..752fc6928 100644 --- a/packages/@core/ui-kit/form-ui/src/form-render/form.vue +++ b/packages/@core/ui-kit/form-ui/src/form-render/form.vue @@ -43,12 +43,10 @@ const emits = defineEmits<{ const wrapperClass = computed(() => { const cls = ['flex']; - if (props.layout === 'vertical') { - cls.push(props.compact ? 'gap-x-2' : 'gap-x-4', 'flex-col grid'); - } else if (props.layout === 'inline') { - cls.push('flex-wrap gap-2'); + if (props.layout === 'inline') { + cls.push('flex-wrap gap-x-2'); } else { - cls.push('gap-2 flex-col grid'); + cls.push(props.compact ? 'gap-x-2' : 'gap-x-4', 'flex-col grid'); } return cn(...cls, props.wrapperClass); }); diff --git a/packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts b/packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts index 18dc90c4a..f60870b3f 100644 --- a/packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts +++ b/packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts @@ -107,7 +107,6 @@ export class ModalApi { this.store.setState((prev) => ({ ...prev, isOpen: false, - submitting: false, })); } } @@ -162,7 +161,11 @@ export class ModalApi { } open() { - this.store.setState((prev) => ({ ...prev, isOpen: true })); + this.store.setState((prev) => ({ + ...prev, + isOpen: true, + submitting: false, + })); } setData(payload: T) { diff --git a/packages/@core/ui-kit/shadcn-ui/src/ui/dialog/DialogContent.vue b/packages/@core/ui-kit/shadcn-ui/src/ui/dialog/DialogContent.vue index 22ed845af..ae656b979 100644 --- a/packages/@core/ui-kit/shadcn-ui/src/ui/dialog/DialogContent.vue +++ b/packages/@core/ui-kit/shadcn-ui/src/ui/dialog/DialogContent.vue @@ -8,12 +8,7 @@ import { computed, ref } from 'vue'; import { cn } from '@vben-core/shared/utils'; import { X } from 'lucide-vue-next'; -import { - DialogClose, - DialogContent, - DialogPortal, - useForwardPropsEmits, -} from 'radix-vue'; +import { DialogClose, DialogContent, useForwardPropsEmits } from 'radix-vue'; import DialogOverlay from './DialogOverlay.vue'; @@ -87,7 +82,7 @@ defineExpose({ diff --git a/packages/@core/ui-kit/shadcn-ui/src/ui/sheet/SheetContent.vue b/packages/@core/ui-kit/shadcn-ui/src/ui/sheet/SheetContent.vue index b9d8baf40..cab9c5a5b 100644 --- a/packages/@core/ui-kit/shadcn-ui/src/ui/sheet/SheetContent.vue +++ b/packages/@core/ui-kit/shadcn-ui/src/ui/sheet/SheetContent.vue @@ -7,7 +7,7 @@ import { computed, ref } from 'vue'; import { cn } from '@vben-core/shared/utils'; -import { DialogContent, DialogPortal, useForwardPropsEmits } from 'radix-vue'; +import { DialogContent, useForwardPropsEmits } from 'radix-vue'; import { sheetVariants } from './sheet'; import SheetOverlay from './SheetOverlay.vue'; @@ -73,7 +73,7 @@ function onAnimationEnd(event: AnimationEvent) { diff --git a/packages/@core/ui-kit/shadcn-ui/src/ui/tree/tree.vue b/packages/@core/ui-kit/shadcn-ui/src/ui/tree/tree.vue index c6c4df7d9..3e497c51a 100644 --- a/packages/@core/ui-kit/shadcn-ui/src/ui/tree/tree.vue +++ b/packages/@core/ui-kit/shadcn-ui/src/ui/tree/tree.vue @@ -103,10 +103,15 @@ function updateTreeValue() { treeValue.value = undefined; } else { if (Array.isArray(val)) { - const filteredValues = val.filter((v) => { + let filteredValues = val.filter((v) => { const item = getItemByValue(v); return item && !get(item, props.disabledField); }); + + if (!props.checkStrictly && props.autoCheckParent) { + filteredValues = processParentSelection(filteredValues); + } + treeValue.value = filteredValues.map((v) => getItemByValue(v)); if (filteredValues.length !== val.length) { @@ -123,7 +128,35 @@ function updateTreeValue() { } } } +function processParentSelection( + selectedValues: Array, +): Array { + if (props.checkStrictly) return selectedValues; + const result = [...selectedValues]; + + for (let i = result.length - 1; i >= 0; i--) { + const currentValue = result[i]; + if (currentValue === undefined) continue; + const currentItem = getItemByValue(currentValue); + + if (!currentItem) continue; + + const children = get(currentItem, props.childrenField); + if (Array.isArray(children) && children.length > 0) { + const hasSelectedChildren = children.some((child) => { + const childValue = get(child, props.valueField); + return result.includes(childValue); + }); + + if (!hasSelectedChildren) { + result.splice(i, 1); + } + } + } + + return result; +} function updateModelValue(val: Arrayable>) { if (Array.isArray(val)) { const filteredVal = val.filter((v) => !get(v, props.disabledField)); diff --git a/packages/effects/layouts/src/widgets/preferences/blocks/theme/builtin.vue b/packages/effects/layouts/src/widgets/preferences/blocks/theme/builtin.vue index 27dfd28ae..d70bb2321 100644 --- a/packages/effects/layouts/src/widgets/preferences/blocks/theme/builtin.vue +++ b/packages/effects/layouts/src/widgets/preferences/blocks/theme/builtin.vue @@ -104,7 +104,7 @@ function selectColor() { watch( () => [modelValue.value, props.isDark] as [BuiltinThemeType, boolean], - ([themeType, isDark]) => { + ([themeType, isDark], [_, isDarkPrev]) => { const theme = builtinThemePresets.value.find( (item) => item.type === themeType, ); @@ -113,7 +113,9 @@ watch( ? theme.darkPrimaryColor || theme.primaryColor : theme.primaryColor; - themeColorPrimary.value = primaryColor || theme.color; + if (!(theme.type === 'custom' && isDark !== isDarkPrev)) { + themeColorPrimary.value = primaryColor || theme.color; + } } }, ); diff --git a/playground/src/views/system/role/modules/form.vue b/playground/src/views/system/role/modules/form.vue index 25b6fedca..e3c1d02dc 100644 --- a/playground/src/views/system/role/modules/form.vue +++ b/playground/src/views/system/role/modules/form.vue @@ -5,7 +5,7 @@ import type { Recordable } from '@vben/types'; import type { SystemRoleApi } from '#/api/system/role'; -import { computed, ref } from 'vue'; +import { computed, nextTick, ref } from 'vue'; import { useVbenDrawer, VbenTree } from '@vben/common-ui'; import { IconifyIcon } from '@vben/icons'; @@ -47,20 +47,27 @@ const [Drawer, drawerApi] = useVbenDrawer({ drawerApi.unlock(); }); }, + async onOpenChange(isOpen) { if (isOpen) { const data = drawerApi.getData(); formApi.resetForm(); - if (permissions.value.length === 0) { - await loadPermissions(); - } + if (data) { formData.value = data; id.value = data.id; - formApi.setValues(data); } else { id.value = undefined; } + + if (permissions.value.length === 0) { + await loadPermissions(); + } + // Wait for Vue to flush DOM updates (form fields mounted) + await nextTick(); + if (data) { + formApi.setValues(data); + } } }, });