two column list item selection supports filtering content (#38)

This commit is contained in:
MaysWind
2025-02-06 22:37:02 +08:00
parent 29d7ee09c8
commit b6efa91879
14 changed files with 177 additions and 36 deletions
@@ -1,4 +1,6 @@
import { type Ref } from 'vue';
import { type Ref, ref, computed } from 'vue';
import { useI18n } from '@/locales/helpers.ts';
import { getItemByKeyValue, getPrimaryValueBySecondaryValue } from '@/lib/common.ts';
@@ -29,12 +31,94 @@ export interface CommonTwoColumnListItemSelectionProps {
secondaryIconType?: string;
secondaryColorField?: string;
secondaryHiddenField?: string;
items: unknown[];
enableFilter?: boolean;
filterPlaceholder?: string;
filterNoItemsText?: string;
items: Record<string, unknown>[];
}
export function useTwoColumnListItemSelectionBase(props: CommonTwoColumnListItemSelectionProps) {
const { ti } = useI18n();
const filterContent = ref<string>('');
const filteredItems = computed<Record<string, unknown>[]>(() => {
const finalItems: Record<string, unknown>[] = [];
const items = props.items;
for (const item of items) {
if (props.primaryHiddenField && item[props.primaryHiddenField]) {
continue;
}
if (!props.enableFilter || !filterContent.value) {
finalItems.push(item);
continue;
}
if (props.primaryTitleField) {
const title = ti(item[props.primaryTitleField] as string, !!props.primaryTitleI18n);
if (title.toLowerCase().indexOf(filterContent.value.toLowerCase()) >= 0) {
finalItems.push(item);
continue;
}
}
if (props.primarySubItemsField) {
if (getFilteredSubItems(item).length > 0) {
finalItems.push(item);
}
}
}
return finalItems;
});
function getFilteredSubItems(selectedPrimaryItem: unknown): Record<string, unknown>[] {
const finalItems: Record<string, unknown>[] = [];
if (!selectedPrimaryItem || !props.primarySubItemsField) {
return finalItems;
}
const subItems = (selectedPrimaryItem as Record<string, unknown>)[props.primarySubItemsField] as Record<string, unknown>[];
let primaryTitleHasFilterContent = false;
if (props.primaryTitleField) {
const title = ti((selectedPrimaryItem as Record<string, unknown>)[props.primaryTitleField] as string, !!props.primaryTitleI18n);
primaryTitleHasFilterContent = title.toLowerCase().indexOf(filterContent.value.toLowerCase()) >= 0;
}
for (const subItem of subItems) {
if (props.secondaryHiddenField && subItem[props.secondaryHiddenField]) {
continue;
}
if (!props.enableFilter || !filterContent.value) {
finalItems.push(subItem);
continue;
}
if (primaryTitleHasFilterContent) {
finalItems.push(subItem);
continue;
}
if (props.secondaryTitleField && filterContent.value) {
const title = ti(subItem[props.secondaryTitleField] as string, !!props.secondaryTitleI18n);
if (title.toLowerCase().indexOf(filterContent.value.toLowerCase()) >= 0) {
finalItems.push(subItem);
}
}
}
return finalItems;
}
function getCurrentPrimaryValueBySecondaryValue(secondaryValue: unknown): unknown {
return getPrimaryValueBySecondaryValue(props.items as Record<string, Record<string, unknown>[]>[] | Record<string, Record<string, Record<string, unknown>[]>>, props.primarySubItemsField, props.primaryValueField, props.primaryHiddenField, props.secondaryValueField, props.secondaryHiddenField, secondaryValue);
return getPrimaryValueBySecondaryValue(props.items as Record<string, Record<string, unknown>[]>[], props.primarySubItemsField, props.primaryValueField, props.primaryHiddenField, props.secondaryValueField, props.secondaryHiddenField, secondaryValue);
}
function isSecondaryValueSelected(currentSecondaryValue: unknown, subItem: unknown): boolean {
@@ -45,17 +129,17 @@ export function useTwoColumnListItemSelectionBase(props: CommonTwoColumnListItem
}
}
function getSelectedPrimaryItem(currentPrimaryValue: unknown) {
function getSelectedPrimaryItem(currentPrimaryValue: unknown): unknown {
if (props.primaryValueField) {
return getItemByKeyValue(props.items as Record<string, unknown>[] | Record<string, Record<string, unknown>>, currentPrimaryValue, props.primaryValueField);
return getItemByKeyValue(props.items, currentPrimaryValue, props.primaryValueField);
} else {
return currentPrimaryValue;
}
}
function getSelectedSecondaryItem(currentSecondaryValue: unknown, selectedPrimaryItem: unknown) {
function getSelectedSecondaryItem(currentSecondaryValue: unknown, selectedPrimaryItem: unknown): unknown {
if (currentSecondaryValue && selectedPrimaryItem && (selectedPrimaryItem as Record<string, unknown>)[props.primarySubItemsField]) {
return getItemByKeyValue((selectedPrimaryItem as Record<string, unknown>)[props.primarySubItemsField] as Record<string, unknown>[] | Record<string, Record<string, unknown>>, currentSecondaryValue, props.secondaryValueField as string);
return getItemByKeyValue((selectedPrimaryItem as Record<string, unknown>)[props.primarySubItemsField] as Record<string, unknown>[], currentSecondaryValue, props.secondaryValueField as string);
} else {
return null;
}
@@ -78,7 +162,12 @@ export function useTwoColumnListItemSelectionBase(props: CommonTwoColumnListItem
}
return {
// states
filterContent,
// computed states
filteredItems,
// functions
getFilteredSubItems,
getCurrentPrimaryValueBySecondaryValue,
isSecondaryValueSelected,
getSelectedPrimaryItem,