import type { UseDrawerReturnType, DrawerInstance, ReturnMethods, DrawerProps, UseDrawerInnerReturnType } from './typing';
import { ref, getCurrentInstance, unref, reactive, watchEffect, nextTick, toRaw, computed } from 'vue';
import { isProdMode } from '/@/utils/env';
import { isFunction } from '/@/utils/is';
import { tryOnUnmounted } from '@vueuse/core';
import { isEqual } from 'lodash-es';
import { error } from '/@/utils/log';
const dataTransferRef = reactive<any>({});
const visibleData = reactive<{ [key: number]: boolean }>({});
/**
* @description: Applicable to separate drawer and call outside
*/
export function useDrawer(): UseDrawerReturnType {
if (!getCurrentInstance()) {
throw new Error('useDrawer() can only be used inside setup() or functional components!');
}
const drawer = ref<DrawerInstance | null>(null);
const loaded = ref<Nullable<boolean>>(false);
const uid = ref<string>('');
function register(drawerInstance: DrawerInstance, uuid: string) {
isProdMode() &&
tryOnUnmounted(() => {
drawer.value = null;
loaded.value = null;
dataTransferRef[unref(uid)] = null;
});
if (unref(loaded) && isProdMode() && drawerInstance === unref(drawer)) {
return;
}
uid.value = uuid;
drawer.value = drawerInstance;
loaded.value = true;
drawerInstance.emitVisible = (visible: boolean, uid: number) => {
visibleData[uid] = visible;
};
}
const getInstance = () => {
const instance = unref(drawer);
if (!instance) {
error('useDrawer instance is undefined!');
}
return instance;
};
const methods: ReturnMethods = {
setDrawerProps: (props: Partial<DrawerProps>): void => {
getInstance()?.setDrawerProps(props);
},
getVisible: computed((): boolean => {
return visibleData[~~unref(uid)];
}),
getOpen: computed((): boolean => {
return visibleData[~~unref(uid)];
}),
openDrawer: <T = any>(visible = true, data?: T, openOnSet = true): void => {
// update-begin--author:liaozhiyang---date:20231218---for:【QQYUN-6366】升级到antd4.x
getInstance()?.setDrawerProps({
open: visible,
});
// update-end--author:liaozhiyang---date:20231218---for:【QQYUN-6366】升级到antd4.x
if (!data) return;
if (openOnSet) {
dataTransferRef[unref(uid)] = null;
dataTransferRef[unref(uid)] = toRaw(data);
return;
}
const equal = isEqual(toRaw(dataTransferRef[unref(uid)]), toRaw(data));
if (!equal) {
dataTransferRef[unref(uid)] = toRaw(data);
}
},
closeDrawer: () => {
// update-begin--author:liaozhiyang---date:20231218---for:【QQYUN-6366】升级到antd4.x
getInstance()?.setDrawerProps({ open: false });
// update-end--author:liaozhiyang---date:20231218---for:【QQYUN-6366】升级到antd4.x
},
};
return [register, methods];
}
export const useDrawerInner = (callbackFn?: Fn): UseDrawerInnerReturnType => {
const drawerInstanceRef = ref<Nullable<DrawerInstance>>(null);
const currentInstance = getCurrentInstance();
const uidRef = ref<string>('');
if (!getCurrentInstance()) {
throw new Error('useDrawerInner() can only be used inside setup() or functional components!');
}
const getInstance = () => {
const instance = unref(drawerInstanceRef);
if (!instance) {
error('useDrawerInner instance is undefined!');
return;
}
return instance;
};
const register = (modalInstance: DrawerInstance, uuid: string) => {
isProdMode() &&
tryOnUnmounted(() => {
drawerInstanceRef.value = null;
});
uidRef.value = uuid;
drawerInstanceRef.value = modalInstance;
currentInstance?.emit('register', modalInstance, uuid);
};
watchEffect(() => {
const data = dataTransferRef[unref(uidRef)];
if (!data) return;
if (!callbackFn || !isFunction(callbackFn)) return;
nextTick(() => {
callbackFn(data);
});
});
return [
register,
{
changeLoading: (loading = true) => {
getInstance()?.setDrawerProps({ loading });
},
changeOkLoading: (loading = true) => {
getInstance()?.setDrawerProps({ confirmLoading: loading });
},
getVisible: computed((): boolean => {
return visibleData[~~unref(uidRef)];
}),
getOpen: computed((): boolean => {
return visibleData[~~unref(uidRef)];
}),
closeDrawer: () => {
getInstance()?.setDrawerProps({ open: false });
},
setDrawerProps: (props: Partial<DrawerProps>) => {
getInstance()?.setDrawerProps(props);
},
},
];
};