yanzhen-design-vue
Version:
311 lines (310 loc) • 10.2 kB
JavaScript
import { toRefs, useSlots, ref, useModel, computed, isRef } from "vue";
import { isArray, isEmptyValue, isEmptyArray, toPairs } from "@yanzhen-libs/utils";
import { unref } from "@yanzhen-libs/utils-vue";
import { flattenDeep, has, isBoolean } from "lodash-es";
import { Contacts } from "./constants/contacts.mjs";
import "./enum/index.mjs";
import { useContactsConfig } from "./hook/use-contacts-config.mjs";
import { useSelectedIds } from "./hook/use-contacts-common-props.mjs";
import { useContactsSelectedData, useContactsSelectedGroup } from "./hook/use-contacts-selected-data.mjs";
import { useContactsVModels } from "./hook/use-contacts-model-value.mjs";
import { useContactsOptions } from "./hook/use-contacts-options.mjs";
import { handleTreeNode } from "./utils/handleTreeNode.mjs";
import { handleActiveTabKey } from "./utils/handleActiveTabKey.mjs";
import { handleDataTypeKey } from "./utils/handleDataType.mjs";
import { getContactsLabel } from "./enum/contacts.mjs";
const useContacts = (props, emit) => {
const { disableIds, multiple, title, allExpand } = toRefs(props);
const {
_loading,
_query,
_contactsTabs,
_activeTab,
_userTabs,
_userActiveTab,
_isTreeMode,
_noMore,
_dataSource,
dataSource,
searchQueryList,
handleLoadMore,
handleSearch
} = useContactsConfig(props);
const slots = useSlots();
const _ref = ref();
const { value: _modelValue, ...vModels } = useContactsVModels(null, emit);
const modelValue = useModel(props, "value");
const _rightElRef = ref();
const _leftElRef = ref();
const _selectedIds = useSelectedIds();
const { selectedValue: _selectedValue } = useContactsSelectedData(null, emit);
const { selectedGroupMap } = useContactsSelectedGroup(_selectedIds);
const { optionsDisabledIds } = useContactsOptions();
const _disabledIds = computed(() => {
const ids = [unref(optionsDisabledIds), unref(disableIds)];
return flattenDeep(ids);
});
const _placeholder = computed(() => {
const labels = [];
for (const { value: activeTab } of unref(_contactsTabs)) {
let label;
switch (activeTab) {
case Contacts.USUALLY:
case Contacts.USER:
label = getContactsLabel(Contacts.USER);
break;
default:
label = getContactsLabel(activeTab);
}
if (!labels.includes(label)) labels.push(label);
}
return `请输入${labels.join("、")}.`;
});
const _listScrollRef = ref();
const _props = computed(() => {
return {
title: props.title,
multiple: props.multiple,
isTreeMode: unref(_isTreeMode)
};
});
function ifAddSelectedValue(item) {
const selectedValue = unref(_selectedValue);
return selectedValue.some(({ value, type }) => {
if (item.type && type) {
switch (true) {
case (value === item.value && type === item.type):
case (value === item.value && item.type === Contacts.USUALLY && type === Contacts.USER):
return true;
}
return false;
}
return value === item.value;
});
}
function handleTriggerItem(items, isDelete = false, force = false) {
var _a;
const multiple2 = unref(_props).multiple;
let selectedValue = unref(_selectedValue);
if (!multiple2) {
selectedValue = isDelete || ifAddSelectedValue(items == null ? void 0 : items[0]) ? [] : [...items];
} else {
if (items.length === 1) {
selectedValue = isDelete || ifAddSelectedValue(items == null ? void 0 : items[0]) ? selectedValue.filter(({ value }) => items[0].value !== value) : selectedValue.concat([...items]);
} else if (force !== true && items.some((item) => item.checked !== true)) {
selectedValue = selectedValue.concat([...items]);
} else if (isDelete) {
const itemIds = items.map((item) => item.value);
selectedValue = selectedValue.filter(({ value }) => !itemIds.includes(value));
} else {
selectedValue = selectedValue.concat([...items]);
}
}
const form = {
value: multiple2 ? selectedValue.map(({ value }) => value) : ((_a = selectedValue == null ? void 0 : selectedValue[0]) == null ? void 0 : _a.value) ?? void 0
};
function handleAsyncValue(type, item) {
const key = `${type}List`;
if (has(vModels, key)) {
let list = form[key];
if (multiple2) {
if (!isArray(list)) list = [];
form[key] = list.concat(item.value);
} else if (isEmptyValue(list)) {
form[key] = item.value;
}
}
}
if (!isEmptyArray(selectedValue)) {
for (const item of selectedValue) {
handleAsyncValue(item.type, item);
if (item.type === Contacts.USUALLY) {
handleAsyncValue(Contacts.USER, item);
}
}
}
_selectedValue.value = selectedValue;
for (const [key, ref2] of toPairs(vModels)) {
if (isRef(ref2)) ref2.value = form[key];
}
if (isRef(_modelValue)) {
_modelValue.value = form.value;
} else {
modelValue.value = form.value;
}
return selectedValue;
}
function isDisableItem(item) {
switch (true) {
case item.disabled:
case item.disableCheckbox:
case unref(_disabledIds).includes(item.value):
return true;
}
return false;
}
function handleExtractItems(item, options) {
if (isArray(item)) {
return flattenDeep(item.map((value) => handleExtractItems(value, options)));
}
const deep = isBoolean(options) ? options : (options == null ? void 0 : options.deep) ?? true;
const excludeDisabled = isBoolean(options) ? true : (options == null ? void 0 : options.excludeDisabled) ?? true;
if (excludeDisabled && isDisableItem(item)) return [];
const multiple2 = props.multiple;
const activeTab = unref(_activeTab);
let items = [];
const isKeywords = unref(_query).keywords.length !== 0;
switch (true) {
case isKeywords:
case item.type === activeTab:
case (activeTab === Contacts.USUALLY && [Contacts.USER, Contacts.USUALLY].includes(item.type)):
items = [handleTreeNode(item, _selectedIds)];
break;
}
const flag = deep && multiple2 && !(item == null ? void 0 : item.isLeaf) && isArray(item.children);
if (flag && !isKeywords) {
const children = item.children.map((value) => handleExtractItems(value, options));
return items.concat(flattenDeep(children));
}
return items;
}
const handleTrigger = (item, isDelete = false) => {
const items = handleExtractItems(item);
if (items.length === 0) return;
const values = handleTriggerItem(items, isDelete);
emit("change", values);
};
function handleDelete(item) {
if (isDisableItem(item)) return;
const values = handleTriggerItem([item], true);
emit("change", values);
}
function handleAllDelete() {
for (const item of unref(_selectedValue)) {
if (isDisableItem(item)) return;
handleTriggerItem([item], true);
}
emit("change", unref(_selectedValue));
}
const handleItemClick = (item) => {
return handleTrigger(item, item == null ? void 0 : item.checked);
};
const handleTreeExpand = async (expandedKeys, info) => {
const dataRef = info.node.dataRef;
if (info.expanded && dataRef && isEmptyArray(dataRef.children)) {
dataRef.loading = true;
await handleLoadMore({ parent: info.node });
dataRef.loading = false;
}
};
const handleTreeSelect = async (selectedKeys, info) => {
if (info.node) handleItemClick(info.node);
};
const selectState = computed(() => {
var _a;
const state = {
show: unref(_isTreeMode) !== true,
checked: false,
indeterminate: false,
dataSource: []
};
if (!state.show) {
return state;
}
state.dataSource = handleExtractItems(unref(_dataSource), {
deep: false,
excludeDisabled: false
});
if (state.dataSource.length === 0) {
return state;
}
const activeKey = handleActiveTabKey({ activeTab: _activeTab, userActiveTab: _userActiveTab });
const key = handleDataTypeKey(activeKey);
const ids = state.dataSource.map(({ value }) => value);
const items = ((_a = unref(selectedGroupMap[key])) == null ? void 0 : _a.children) ?? [];
const selectedValue = items.filter(({ value }) => ids.includes(value));
if (selectedValue.length === 0) {
return state;
}
state.checked = selectedValue.length >= state.dataSource.length;
state.indeterminate = !state.checked && unref(selectedValue).length > 0;
return state;
});
function handleAllSelectTrigger(_state) {
const { show, checked, indeterminate } = unref(selectState);
if (!show) return;
let values;
const dataSource2 = handleExtractItems(unref(_dataSource), {
deep: false
});
switch (true) {
case (!indeterminate && checked):
values = handleTriggerItem(dataSource2, true, true);
break;
default:
values = handleTriggerItem(dataSource2, false);
break;
}
emit("change", values);
}
const handleTabChange = (key) => {
var _a, _b;
if (!isEmptyValue(key)) {
_activeTab.value = key;
} else {
_activeTab.value = (_b = (_a = unref(_contactsTabs)) == null ? void 0 : _a[0]) == null ? void 0 : _b.value;
}
if (unref(_isTreeMode)) {
handleLoadMore({
force: false
}).then((r) => r);
}
};
const ctx = {
multiple,
allExpand,
title,
_ref,
_noMore,
_modelValue,
_dataSource,
dataSource,
searchQueryList,
_query,
_placeholder,
_contactsTabs,
_activeTab,
_userTabs,
_userActiveTab,
_props,
_loading,
_rightElRef,
_leftElRef,
_listScrollRef,
_selectedValue,
_selectedIds,
_disabledIds,
_isTreeMode,
selectState
};
const methods = {
handleSearch,
handleLoadMore,
handleTreeExpand,
handleTreeSelect,
handleDelete,
handleAllDelete,
handleItemClick,
handleTabChange,
handleAllSelectTrigger
};
return {
slots,
ctx,
methods,
...methods
};
};
export {
useContacts
};