Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev
commit
b55c291af1
|
@ -43,12 +43,10 @@ const emits = defineEmits<{
|
||||||
|
|
||||||
const wrapperClass = computed(() => {
|
const wrapperClass = computed(() => {
|
||||||
const cls = ['flex'];
|
const cls = ['flex'];
|
||||||
if (props.layout === 'vertical') {
|
if (props.layout === 'inline') {
|
||||||
cls.push(props.compact ? 'gap-x-2' : 'gap-x-4', 'flex-col grid');
|
cls.push('flex-wrap gap-x-2');
|
||||||
} else if (props.layout === 'inline') {
|
|
||||||
cls.push('flex-wrap gap-2');
|
|
||||||
} else {
|
} 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);
|
return cn(...cls, props.wrapperClass);
|
||||||
});
|
});
|
||||||
|
|
|
@ -107,7 +107,6 @@ export class ModalApi {
|
||||||
this.store.setState((prev) => ({
|
this.store.setState((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
submitting: false,
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -162,7 +161,11 @@ export class ModalApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
open() {
|
open() {
|
||||||
this.store.setState((prev) => ({ ...prev, isOpen: true }));
|
this.store.setState((prev) => ({
|
||||||
|
...prev,
|
||||||
|
isOpen: true,
|
||||||
|
submitting: false,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
setData<T>(payload: T) {
|
setData<T>(payload: T) {
|
||||||
|
|
|
@ -8,12 +8,7 @@ import { computed, ref } from 'vue';
|
||||||
import { cn } from '@vben-core/shared/utils';
|
import { cn } from '@vben-core/shared/utils';
|
||||||
|
|
||||||
import { X } from 'lucide-vue-next';
|
import { X } from 'lucide-vue-next';
|
||||||
import {
|
import { DialogClose, DialogContent, useForwardPropsEmits } from 'radix-vue';
|
||||||
DialogClose,
|
|
||||||
DialogContent,
|
|
||||||
DialogPortal,
|
|
||||||
useForwardPropsEmits,
|
|
||||||
} from 'radix-vue';
|
|
||||||
|
|
||||||
import DialogOverlay from './DialogOverlay.vue';
|
import DialogOverlay from './DialogOverlay.vue';
|
||||||
|
|
||||||
|
@ -87,7 +82,7 @@ defineExpose({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<DialogPortal :to="appendTo">
|
<Teleport defer :to="appendTo">
|
||||||
<Transition name="fade">
|
<Transition name="fade">
|
||||||
<DialogOverlay
|
<DialogOverlay
|
||||||
v-if="open && modal"
|
v-if="open && modal"
|
||||||
|
@ -132,5 +127,5 @@ defineExpose({
|
||||||
<X class="h-4 w-4" />
|
<X class="h-4 w-4" />
|
||||||
</DialogClose>
|
</DialogClose>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</DialogPortal>
|
</Teleport>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { computed, ref } from 'vue';
|
||||||
|
|
||||||
import { cn } from '@vben-core/shared/utils';
|
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 { sheetVariants } from './sheet';
|
||||||
import SheetOverlay from './SheetOverlay.vue';
|
import SheetOverlay from './SheetOverlay.vue';
|
||||||
|
@ -73,7 +73,7 @@ function onAnimationEnd(event: AnimationEvent) {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<DialogPortal :to="appendTo">
|
<Teleport defer :to="appendTo">
|
||||||
<Transition name="fade">
|
<Transition name="fade">
|
||||||
<SheetOverlay
|
<SheetOverlay
|
||||||
v-if="open && modal"
|
v-if="open && modal"
|
||||||
|
@ -103,5 +103,5 @@ function onAnimationEnd(event: AnimationEvent) {
|
||||||
<Cross2Icon class="h-5 w-" />
|
<Cross2Icon class="h-5 w-" />
|
||||||
</DialogClose> -->
|
</DialogClose> -->
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</DialogPortal>
|
</Teleport>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -103,10 +103,15 @@ function updateTreeValue() {
|
||||||
treeValue.value = undefined;
|
treeValue.value = undefined;
|
||||||
} else {
|
} else {
|
||||||
if (Array.isArray(val)) {
|
if (Array.isArray(val)) {
|
||||||
const filteredValues = val.filter((v) => {
|
let filteredValues = val.filter((v) => {
|
||||||
const item = getItemByValue(v);
|
const item = getItemByValue(v);
|
||||||
return item && !get(item, props.disabledField);
|
return item && !get(item, props.disabledField);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!props.checkStrictly && props.autoCheckParent) {
|
||||||
|
filteredValues = processParentSelection(filteredValues);
|
||||||
|
}
|
||||||
|
|
||||||
treeValue.value = filteredValues.map((v) => getItemByValue(v));
|
treeValue.value = filteredValues.map((v) => getItemByValue(v));
|
||||||
|
|
||||||
if (filteredValues.length !== val.length) {
|
if (filteredValues.length !== val.length) {
|
||||||
|
@ -123,7 +128,35 @@ function updateTreeValue() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function processParentSelection(
|
||||||
|
selectedValues: Array<number | string>,
|
||||||
|
): Array<number | string> {
|
||||||
|
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<Recordable<any>>) {
|
function updateModelValue(val: Arrayable<Recordable<any>>) {
|
||||||
if (Array.isArray(val)) {
|
if (Array.isArray(val)) {
|
||||||
const filteredVal = val.filter((v) => !get(v, props.disabledField));
|
const filteredVal = val.filter((v) => !get(v, props.disabledField));
|
||||||
|
|
|
@ -104,7 +104,7 @@ function selectColor() {
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => [modelValue.value, props.isDark] as [BuiltinThemeType, boolean],
|
() => [modelValue.value, props.isDark] as [BuiltinThemeType, boolean],
|
||||||
([themeType, isDark]) => {
|
([themeType, isDark], [_, isDarkPrev]) => {
|
||||||
const theme = builtinThemePresets.value.find(
|
const theme = builtinThemePresets.value.find(
|
||||||
(item) => item.type === themeType,
|
(item) => item.type === themeType,
|
||||||
);
|
);
|
||||||
|
@ -113,7 +113,9 @@ watch(
|
||||||
? theme.darkPrimaryColor || theme.primaryColor
|
? theme.darkPrimaryColor || theme.primaryColor
|
||||||
: theme.primaryColor;
|
: theme.primaryColor;
|
||||||
|
|
||||||
themeColorPrimary.value = primaryColor || theme.color;
|
if (!(theme.type === 'custom' && isDark !== isDarkPrev)) {
|
||||||
|
themeColorPrimary.value = primaryColor || theme.color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,7 +5,7 @@ import type { Recordable } from '@vben/types';
|
||||||
|
|
||||||
import type { SystemRoleApi } from '#/api/system/role';
|
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 { useVbenDrawer, VbenTree } from '@vben/common-ui';
|
||||||
import { IconifyIcon } from '@vben/icons';
|
import { IconifyIcon } from '@vben/icons';
|
||||||
|
@ -47,20 +47,27 @@ const [Drawer, drawerApi] = useVbenDrawer({
|
||||||
drawerApi.unlock();
|
drawerApi.unlock();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
async onOpenChange(isOpen) {
|
async onOpenChange(isOpen) {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
const data = drawerApi.getData<SystemRoleApi.SystemRole>();
|
const data = drawerApi.getData<SystemRoleApi.SystemRole>();
|
||||||
formApi.resetForm();
|
formApi.resetForm();
|
||||||
if (permissions.value.length === 0) {
|
|
||||||
await loadPermissions();
|
|
||||||
}
|
|
||||||
if (data) {
|
if (data) {
|
||||||
formData.value = data;
|
formData.value = data;
|
||||||
id.value = data.id;
|
id.value = data.id;
|
||||||
formApi.setValues(data);
|
|
||||||
} else {
|
} else {
|
||||||
id.value = undefined;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue