From 157988247590550c0db2cef5d270bc1a215f201a Mon Sep 17 00:00:00 2001 From: MaysWind Date: Thu, 6 Feb 2025 00:15:04 +0800 Subject: [PATCH] code refactor --- .../base/TwoColumnListItemSelectionBase.ts | 89 +++++++++++++++++++ src/components/desktop/TwoColumnSelect.vue | 85 +++++------------- .../TwoColumnListItemSelectionSheet.vue | 78 ++++------------ 3 files changed, 127 insertions(+), 125 deletions(-) create mode 100644 src/components/base/TwoColumnListItemSelectionBase.ts diff --git a/src/components/base/TwoColumnListItemSelectionBase.ts b/src/components/base/TwoColumnListItemSelectionBase.ts new file mode 100644 index 00000000..919a8de4 --- /dev/null +++ b/src/components/base/TwoColumnListItemSelectionBase.ts @@ -0,0 +1,89 @@ +import { type Ref } from 'vue'; + +import { getItemByKeyValue, getPrimaryValueBySecondaryValue } from '@/lib/common.ts'; + +export interface CommonTwoColumnListItemSelectionProps { + modelValue: unknown; + primaryKeyField?: string; + primaryValueField?: string; + primaryTitleField?: string; + primaryTitleI18n?: boolean; + primaryHeaderField?: string; + primaryHeaderI18n?: boolean; + primaryFooterField?: string; + primaryFooterI18n?: boolean; + primaryIconField?: string; + primaryIconType?: string; + primaryColorField?: string; + primaryHiddenField?: string; + primarySubItemsField: string; + secondaryKeyField?: string; + secondaryValueField?: string; + secondaryTitleField?: string; + secondaryTitleI18n?: boolean; + secondaryHeaderField?: string; + secondaryHeaderI18n?: boolean; + secondaryFooterField?: string; + secondaryFooterI18n?: boolean; + secondaryIconField?: string; + secondaryIconType?: string; + secondaryColorField?: string; + secondaryHiddenField?: string; + items: unknown[]; +} + +export function useTwoColumnListItemSelectionBase(props: CommonTwoColumnListItemSelectionProps) { + function getCurrentPrimaryValueBySecondaryValue(secondaryValue: unknown): unknown { + return getPrimaryValueBySecondaryValue(props.items as Record[]>[] | Record[]>>, props.primarySubItemsField, props.primaryValueField, props.primaryHiddenField, props.secondaryValueField, props.secondaryHiddenField, secondaryValue); + } + + function isSecondaryValueSelected(currentSecondaryValue: unknown, subItem: unknown): boolean { + if (props.secondaryValueField) { + return currentSecondaryValue === (subItem as Record)[props.secondaryValueField]; + } else { + return currentSecondaryValue === subItem; + } + } + + function getSelectedPrimaryItem(currentPrimaryValue: unknown) { + if (props.primaryValueField) { + return getItemByKeyValue(props.items as Record[] | Record>, currentPrimaryValue, props.primaryValueField); + } else { + return currentPrimaryValue; + } + } + + function getSelectedSecondaryItem(currentSecondaryValue: unknown, selectedPrimaryItem: unknown) { + if (currentSecondaryValue && selectedPrimaryItem && (selectedPrimaryItem as Record)[props.primarySubItemsField]) { + return getItemByKeyValue((selectedPrimaryItem as Record)[props.primarySubItemsField] as Record[] | Record>, currentSecondaryValue, props.secondaryValueField as string); + } else { + return null; + } + } + + function updateCurrentPrimaryValue(currentPrimaryValue: Ref, item: unknown): void { + if (props.primaryValueField) { + currentPrimaryValue.value = (item as Record)[props.primaryValueField]; + } else { + currentPrimaryValue.value = item; + } + } + + function updateCurrentSecondaryValue(currentSecondaryValue: Ref, subItem: unknown): void { + if (props.secondaryValueField) { + currentSecondaryValue.value = (subItem as Record)[props.secondaryValueField]; + } else { + currentSecondaryValue.value = subItem; + } + } + + return { + // functions + getCurrentPrimaryValueBySecondaryValue, + isSecondaryValueSelected, + getSelectedPrimaryItem, + getSelectedSecondaryItem, + updateCurrentPrimaryValue, + updateCurrentSecondaryValue + }; +} diff --git a/src/components/desktop/TwoColumnSelect.vue b/src/components/desktop/TwoColumnSelect.vue index 54b17e47..2e41c981 100644 --- a/src/components/desktop/TwoColumnSelect.vue +++ b/src/components/desktop/TwoColumnSelect.vue @@ -77,12 +77,12 @@ import { ref, computed, useTemplateRef, nextTick } from 'vue'; import { useI18n } from '@/locales/helpers.ts'; +import { type CommonTwoColumnListItemSelectionProps, useTwoColumnListItemSelectionBase } from '@/components/base/TwoColumnListItemSelectionBase.ts'; import { getFirstVisibleItem, getItemByKeyValue, - getNameByKeyValue, - getPrimaryValueBySecondaryValue + getNameByKeyValue } from '@/lib/common.ts'; import { scrollToSelectedItem } from '@/lib/ui/desktop.ts'; @@ -90,8 +90,7 @@ import { mdiChevronRight } from '@mdi/js'; -const props = defineProps<{ - modelValue: unknown; +interface DesktopTwoColumnListItemSelectionProps extends CommonTwoColumnListItemSelectionProps { density?: string; variant?: string; disabled?: boolean; @@ -101,34 +100,10 @@ const props = defineProps<{ showSelectionSecondaryIcon?: boolean; customSelectionPrimaryText?: string; customSelectionSecondaryText?: string; - primaryKeyField?: string; - primaryValueField?: string; - primaryTitleField?: string; - primaryTitleI18n?: boolean; - primaryHeaderField?: string; - primaryHeaderI18n?: boolean; - primaryFooterField?: string; - primaryFooterI18n?: boolean; - primaryIconField?: string; - primaryIconType?: string; - primaryColorField?: string; - primaryHiddenField?: string; - primarySubItemsField: string; - secondaryKeyField?: string; - secondaryValueField?: string; - secondaryTitleField?: string; - secondaryTitleI18n?: boolean; - secondaryHeaderField?: string; - secondaryHeaderI18n?: boolean; - secondaryFooterField?: string; - secondaryFooterI18n?: boolean; - secondaryIconField?: string; - secondaryIconType?: string; - secondaryColorField?: string; - secondaryHiddenField?: string; - items: unknown[]; noItemText?: string; -}>(); +} + +const props = defineProps(); const emit = defineEmits<{ (e: 'update:modelValue', value: unknown): void; @@ -136,6 +111,15 @@ const emit = defineEmits<{ const { tt, ti } = useI18n(); +const { + getCurrentPrimaryValueBySecondaryValue, + isSecondaryValueSelected, + getSelectedPrimaryItem, + getSelectedSecondaryItem, + updateCurrentPrimaryValue, + updateCurrentSecondaryValue +} = useTwoColumnListItemSelectionBase(props); + const icons = { chevronRight: mdiChevronRight }; @@ -175,21 +159,8 @@ const currentSecondaryValue = computed({ } }); -const selectedPrimaryItem = computed(() => { - if (props.primaryValueField) { - return getItemByKeyValue(props.items as Record[] | Record>, currentPrimaryValue.value, props.primaryValueField); - } else { - return currentPrimaryValue.value; - } -}); - -const selectedSecondaryItem = computed(() => { - if (currentSecondaryValue.value && selectedPrimaryItem.value && (selectedPrimaryItem.value as Record)[props.primarySubItemsField]) { - return getItemByKeyValue((selectedPrimaryItem.value as Record)[props.primarySubItemsField] as Record[] | Record>, currentSecondaryValue.value, props.secondaryValueField as string); - } else { - return null; - } -}); +const selectedPrimaryItem = computed(() => getSelectedPrimaryItem(currentPrimaryValue.value)); +const selectedSecondaryItem = computed(() => getSelectedSecondaryItem(currentSecondaryValue.value, selectedPrimaryItem.value)); const noSelectionText = computed(() => props.noItemText ? props.noItemText : tt('None')); @@ -217,32 +188,16 @@ const selectionSecondaryItemText = computed(() => { } }); -function getCurrentPrimaryValueBySecondaryValue(secondaryValue: unknown): unknown { - return getPrimaryValueBySecondaryValue(props.items as Record[]>[] | Record[]>>, props.primarySubItemsField, props.primaryValueField, props.primaryHiddenField, props.secondaryValueField, props.secondaryHiddenField, secondaryValue); -} - function isSecondarySelected(subItem: unknown): boolean { - if (props.secondaryValueField) { - return currentSecondaryValue.value === (subItem as Record)[props.secondaryValueField]; - } else { - return currentSecondaryValue.value === subItem; - } + return isSecondaryValueSelected(currentSecondaryValue.value, subItem); } function onPrimaryItemClicked(item: unknown): void { - if (props.primaryValueField) { - currentPrimaryValue.value = (item as Record)[props.primaryValueField]; - } else { - currentPrimaryValue.value = item; - } + updateCurrentPrimaryValue(currentPrimaryValue, item); } function onSecondaryItemClicked(subItem: unknown): void { - if (props.secondaryValueField) { - currentSecondaryValue.value = (subItem as Record)[props.secondaryValueField]; - } else { - currentSecondaryValue.value = subItem; - } + updateCurrentSecondaryValue(currentSecondaryValue, subItem); } function onMenuStateChanged(state: boolean): void { diff --git a/src/components/mobile/TwoColumnListItemSelectionSheet.vue b/src/components/mobile/TwoColumnListItemSelectionSheet.vue index 2270292d..ce47ee9e 100644 --- a/src/components/mobile/TwoColumnListItemSelectionSheet.vue +++ b/src/components/mobile/TwoColumnListItemSelectionSheet.vue @@ -65,43 +65,15 @@ import { ref, computed } from 'vue'; import { useI18n } from '@/locales/helpers.ts'; +import { type CommonTwoColumnListItemSelectionProps, useTwoColumnListItemSelectionBase } from '@/components/base/TwoColumnListItemSelectionBase.ts'; -import { - getItemByKeyValue, - getPrimaryValueBySecondaryValue -} from '@/lib/common.ts'; import { type Framework7Dom, scrollToSelectedItem } from '@/lib/ui/mobile.ts'; -const props = defineProps<{ - modelValue: unknown; - primaryKeyField?: string; - primaryValueField?: string; - primaryTitleField?: string; - primaryTitleI18n?: boolean; - primaryHeaderField?: string; - primaryHeaderI18n?: boolean; - primaryFooterField?: string; - primaryFooterI18n?: boolean; - primaryIconField?: string; - primaryIconType?: string; - primaryColorField?: string; - primaryHiddenField?: string; - primarySubItemsField: string; - secondaryKeyField?: string; - secondaryValueField?: string; - secondaryTitleField?: string; - secondaryTitleI18n?: boolean; - secondaryHeaderField?: string; - secondaryHeaderI18n?: boolean; - secondaryFooterField?: string; - secondaryFooterI18n?: boolean; - secondaryIconField?: string; - secondaryIconType?: string; - secondaryColorField?: string; - secondaryHiddenField?: string; - items: unknown[]; +interface MobileTwoColumnListItemSelectionProps extends CommonTwoColumnListItemSelectionProps { show: boolean; -}>(); +} + +const props = defineProps(); const emit = defineEmits<{ (e: 'update:modelValue', value: unknown): void; @@ -110,48 +82,34 @@ const emit = defineEmits<{ const { tt, ti } = useI18n(); +const { + getCurrentPrimaryValueBySecondaryValue, + isSecondaryValueSelected, + getSelectedPrimaryItem, + updateCurrentPrimaryValue, + updateCurrentSecondaryValue +} = useTwoColumnListItemSelectionBase(props); + + const currentPrimaryValue = ref(getCurrentPrimaryValueBySecondaryValue(props.modelValue)); const currentSecondaryValue = ref(props.modelValue); -function getCurrentPrimaryValueBySecondaryValue(secondaryValue: unknown): unknown { - return getPrimaryValueBySecondaryValue(props.items as Record[]>[] | Record[]>>, props.primarySubItemsField, props.primaryValueField, props.primaryHiddenField, props.secondaryValueField, props.secondaryHiddenField, secondaryValue); -} +const selectedPrimaryItem = computed(() => getSelectedPrimaryItem(currentPrimaryValue.value)); function isSecondarySelected(subItem: unknown): boolean { - if (props.secondaryValueField) { - return currentSecondaryValue.value === (subItem as Record)[props.secondaryValueField]; - } else { - return currentSecondaryValue.value === subItem; - } + return isSecondaryValueSelected(currentSecondaryValue.value, subItem); } -const selectedPrimaryItem = computed(() => { - if (props.primaryValueField) { - return getItemByKeyValue(props.items as Record[] | Record>, currentPrimaryValue.value, props.primaryValueField); - } else { - return currentPrimaryValue.value; - } -}); - function close(): void { emit('update:show', false); } function onPrimaryItemClicked(item: unknown): void { - if (props.primaryValueField) { - currentPrimaryValue.value = (item as Record)[props.primaryValueField]; - } else { - currentPrimaryValue.value = item; - } + updateCurrentPrimaryValue(currentPrimaryValue, item); } function onSecondaryItemClicked(subItem: unknown): void { - if (props.secondaryValueField) { - currentSecondaryValue.value = (subItem as Record)[props.secondaryValueField]; - } else { - currentSecondaryValue.value = subItem; - } - + updateCurrentSecondaryValue(currentSecondaryValue, subItem); emit('update:modelValue', currentSecondaryValue.value); close(); }