Files
boursecu_admin/src/pages/menuPages/configuration/SettingValueField.vue
T
2026-07-07 21:10:23 +03:30

227 lines
5.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="setting-value-field">
<a-switch
v-if="fieldType === 'switch'"
:checked="switchChecked"
:disabled="disabled"
@change="onSwitchChange"
>
<template #checkedChildren>{{ labels.on }}</template>
<template #unCheckedChildren>{{ labels.off }}</template>
</a-switch>
<MainWalletProductsField
v-else-if="isMainWalletProducts"
:model-value="modelValue"
:disabled="disabled"
@update:value="emit('update:value', $event)"
/>
<ZaarboxPriceKeyField
v-else-if="isZaarboxPriceKey"
:model-value="modelValue"
:disabled="disabled"
@update:value="emit('update:value', $event)"
/>
<a-select
v-else-if="fieldType === 'select'"
:value="modelValue || undefined"
:disabled="disabled"
allow-clear
placeholder="انتخاب کنید"
class="w-full"
@update:value="onSelectChange"
>
<a-select-option v-for="opt in selectItems" :key="opt.key" :value="opt.key">
{{ opt.value }}
</a-select-option>
</a-select>
<a-select
v-else-if="fieldType === 'multiselect'"
:value="multiSelectValue"
:disabled="disabled"
mode="multiple"
allow-clear
placeholder="انتخاب کنید"
class="w-full"
@update:value="onMultiSelectChange"
>
<a-select-option v-for="opt in selectItems" :key="opt.key" :value="opt.key">
{{ opt.value }}
</a-select-option>
</a-select>
<a-time-picker
v-else-if="fieldType === 'time'"
:value="modelValue || undefined"
:disabled="disabled"
class="w-full"
format="HH:mm"
value-format="HH:mm:ss"
:minute-step="5"
placeholder="انتخاب ساعت"
@update:value="onTimeChange"
/>
<a-input-number
v-else-if="fieldType === 'price'"
:value="priceValue"
:disabled="disabled"
class="w-full"
:formatter="(v: string) => `${v}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')"
:parser="(v: string) => v.replace(/,/g, '')"
@update:value="onPriceChange"
/>
<a-input
v-else-if="fieldType === 'number'"
:value="modelValue"
:disabled="disabled"
inputmode="numeric"
allow-clear
class="w-full"
@update:value="onPlainNumberChange"
@blur="emit('blur')"
/>
<a-textarea
v-else-if="fieldType === 'longtext'"
:value="modelValue"
:disabled="disabled"
:rows="rows"
class="w-full font-mono text-sm"
@update:value="emit('update:value', $event)"
@blur="emit('blur')"
/>
<a-input
v-else
:value="modelValue"
:disabled="disabled"
allow-clear
@update:value="emit('update:value', $event)"
@blur="emit('blur')"
/>
</div>
</template>
<script setup lang="ts">
import MainWalletProductsField from './MainWalletProductsField.vue'
import ZaarboxPriceKeyField from './ZaarboxPriceKeyField.vue'
import {
parseSelectOptions,
resolveSettingFieldType,
resolveSwitchChecked,
switchLabels,
switchValueFromChecked,
type SettingFieldType
} from './settingTypes'
const props = withDefaults(
defineProps<{
modelValue: string
settingKey?: string
settingType?: string
description?: string
disabled?: boolean
rows?: number
}>(),
{ disabled: false, rows: 10 }
)
const emit = defineEmits<{
'update:value': [value: string]
blur: []
}>()
const fieldType = computed<SettingFieldType>(() =>
resolveSettingFieldType({
key: props.settingKey,
type: props.settingType
})
)
const isZaarboxPriceKey = computed(() => props.settingKey === 'zaarbox_price_key')
const isMainWalletProducts = computed(() => props.settingKey === 'main_wallet_products')
const selectItems = computed(() =>
parseSelectOptions({
key: props.settingKey,
description: props.description,
type: props.settingType
})
)
const labels = computed(() => switchLabels(props.settingKey))
const switchChecked = computed(() => resolveSwitchChecked(props.settingKey, props.modelValue))
function onSwitchChange(checked: boolean) {
emit('update:value', switchValueFromChecked(props.settingKey, checked))
}
function onSelectChange(val: string | undefined) {
emit('update:value', val ?? '')
}
const multiSelectValue = computed<string[]>(() =>
String(props.modelValue || '')
.split(',')
.map((s) => s.trim())
.filter((s) => s !== '')
)
function onMultiSelectChange(val: string[] | undefined) {
const list = Array.isArray(val) ? val.map((s) => s.trim()).filter((s) => s !== '') : []
emit('update:value', list.join(','))
}
function onTimeChange(val: string | string[] | undefined) {
const v = Array.isArray(val) ? val[0] : val
emit('update:value', v ?? '')
emit('blur')
}
const priceValue = computed(() => {
const n = parseFloat(String(props.modelValue || '').replace(/,/g, ''))
return Number.isFinite(n) ? n : undefined
})
function onPriceChange(val: number | string | null) {
if (val === null || val === undefined || val === '') {
emit('update:value', '')
return
}
emit('update:value', String(val))
}
function normalizePlainNumberInput(value: string): string {
const latin = value.replace(/[۰-۹]/g, (d) => String('۰۱۲۳۴۵۶۷۸۹'.indexOf(d)))
let out = ''
let hasDot = false
for (const ch of latin.replace(/,/g, '')) {
if (ch >= '0' && ch <= '9') out += ch
else if (ch === '.' && !hasDot) {
hasDot = true
out += ch
}
}
return out
}
function onPlainNumberChange(val: string) {
emit('update:value', normalizePlainNumberInput(val ?? ''))
}
</script>
<style scoped>
.setting-value-field {
width: 100%;
}
.setting-value-field :deep(.ant-input-number) {
width: 100%;
}
</style>