mirror of https://github.com/nocodb/nocodb
Wing-Kam Wong
2 years ago
21 changed files with 469 additions and 148 deletions
@ -1,100 +1,28 @@
|
||||
<script setup lang="ts"> |
||||
import { computed, inject, onMounted, ref } from '#imports' |
||||
import { inject, onMounted, ref } from '#imports' |
||||
|
||||
interface Props { |
||||
modelValue: any |
||||
} |
||||
|
||||
const { modelValue: value } = defineProps<Props>() |
||||
const props = defineProps<Props>() |
||||
|
||||
const emit = defineEmits(['update:modelValue']) |
||||
const emits = defineEmits(['update:modelValue']) |
||||
|
||||
const editEnabled = inject<boolean>('editEnabled', false) |
||||
|
||||
const root = ref<HTMLInputElement>() |
||||
|
||||
const localState = computed({ |
||||
get: () => value, |
||||
set: (val) => emit('update:modelValue', val), |
||||
}) |
||||
const vModel = useVModel(props, 'modelValue', emits) |
||||
|
||||
onMounted(() => { |
||||
root.value?.focus() |
||||
}) |
||||
|
||||
/* export default { |
||||
name: 'TextCell', |
||||
props: { |
||||
value: [String, Object, Number, Boolean, Array], |
||||
}, |
||||
computed: { |
||||
localState: { |
||||
get() { |
||||
return this.value |
||||
}, |
||||
set(val) { |
||||
this.$emit('input', val) |
||||
}, |
||||
}, |
||||
parentListeners() { |
||||
const $listeners = {} |
||||
|
||||
if (this.$listeners.blur) { |
||||
$listeners.blur = this.$listeners.blur |
||||
} |
||||
if (this.$listeners.focus) { |
||||
$listeners.focus = this.$listeners.focus |
||||
} |
||||
|
||||
if (this.$listeners.cancel) { |
||||
$listeners.cancel = this.$listeners.cancel |
||||
} |
||||
|
||||
return $listeners |
||||
}, |
||||
}, |
||||
mounted() { |
||||
this.$el.focus() |
||||
}, |
||||
} */ |
||||
const onSetRef = (el: HTMLInputElement) => { |
||||
el.focus() |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<input v-if="editEnabled" ref="root" v-model="localState" /> |
||||
<span v-else>{{ localState }}</span> |
||||
<!-- v-on="parentListeners" /> --> |
||||
<input v-if="editEnabled" :ref="onSetRef" v-model="vModel" class="h-full w-full outline-none" /> |
||||
<span v-else>{{ vModel }}</span> |
||||
</template> |
||||
|
||||
<style scoped> |
||||
input, |
||||
textarea { |
||||
width: 100%; |
||||
height: 100%; |
||||
color: var(--v-textColor-base); |
||||
outline: none; |
||||
} |
||||
</style> |
||||
<!-- |
||||
/** |
||||
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||
* |
||||
* @author Naveen MR <oof1lab@gmail.com> |
||||
* @author Pranav C Balan <pranavxc@gmail.com> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
--> |
||||
<style scoped></style> |
||||
|
@ -0,0 +1,100 @@
|
||||
<script setup lang="ts"> |
||||
import { useColumnCreateStoreOrThrow, useProject } from '#imports' |
||||
import { currencyCodes, currencyLocales, validateCurrencyCode, validateCurrencyLocale } from '@/utils' |
||||
|
||||
interface Option { |
||||
label: string |
||||
value: string |
||||
} |
||||
|
||||
const { formState, validateInfos, setAdditionalValidations, sqlUi, onDataTypeChange, onAlter } = useColumnCreateStoreOrThrow() |
||||
|
||||
const validators = { |
||||
'meta.currency_locale': [ |
||||
{ |
||||
validator: (_: any, locale: any) => { |
||||
return new Promise<void>((resolve, reject) => { |
||||
if (!validateCurrencyLocale(locale)) { |
||||
return reject(new Error('Invalid locale')) |
||||
} |
||||
resolve() |
||||
}) |
||||
}, |
||||
}, |
||||
], |
||||
'meta.currency_code': [ |
||||
{ |
||||
validator: (_: any, currencyCode: any) => { |
||||
return new Promise<void>((resolve, reject) => { |
||||
if (!validateCurrencyCode(currencyCode)) { |
||||
return reject(new Error('Invalid Currency Code')) |
||||
} |
||||
resolve() |
||||
}) |
||||
}, |
||||
}, |
||||
], |
||||
} |
||||
|
||||
// set additional validations |
||||
setAdditionalValidations({ |
||||
...validators, |
||||
}) |
||||
|
||||
const { isPg } = useProject() |
||||
|
||||
const currencyList = currencyCodes || [] |
||||
|
||||
const currencyLocaleList = currencyLocales() || [] |
||||
|
||||
const isMoney = computed(() => formState.value.dt === 'money') |
||||
|
||||
const message = computed(() => { |
||||
if (isMoney.value && isPg) return "PostgreSQL 'money' type has own currency settings" |
||||
return '' |
||||
}) |
||||
|
||||
function filterOption(input: string, option: Option) { |
||||
return option.value.toUpperCase().includes(input.toUpperCase()) |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<a-row> |
||||
<a-col :span="12"> |
||||
<a-form-item v-bind="validateInfos['meta.currency_locale']" label="Currency Locale"> |
||||
<a-select |
||||
v-model:value="formState.meta.currency_locale" |
||||
size="small" |
||||
class="w-52" |
||||
show-search |
||||
:filter-option="filterOption" |
||||
:disabled="isMoney && isPg" |
||||
> |
||||
<a-select-option v-for="(currencyLocale, i) of currencyLocaleList" :key="i" :value="currencyLocale.value"> |
||||
{{ currencyLocale.text }} |
||||
</a-select-option> |
||||
</a-select> |
||||
</a-form-item> |
||||
</a-col> |
||||
<a-col :span="12"> |
||||
<a-form-item v-bind="validateInfos['meta.currency_code']" label="Currency Code"> |
||||
<a-select |
||||
v-model:value="formState.meta.currency_code" |
||||
class="w-52" |
||||
show-search |
||||
:filter-option="filterOption" |
||||
size="small" |
||||
:disabled="isMoney && isPg" |
||||
> |
||||
<a-select-option v-for="(currencyCode, i) of currencyList" :key="i" :value="currencyCode"> |
||||
{{ currencyCode }} |
||||
</a-select-option> |
||||
</a-select> |
||||
</a-form-item> |
||||
</a-col> |
||||
<a-col v-if="isMoney && isPg"> |
||||
<span class="text-[#FB8C00]">{{ message }}</span> |
||||
</a-col> |
||||
</a-row> |
||||
</template> |
@ -0,0 +1,9 @@
|
||||
<script setup lang="ts"> |
||||
// TODO: wait for Count Column implementation |
||||
</script> |
||||
|
||||
<template> |
||||
<span class="prose-sm"></span> |
||||
</template> |
||||
|
||||
<style scoped lang="scss"></style> |
@ -0,0 +1,220 @@
|
||||
import locale from 'locale-codes' |
||||
|
||||
export const currencyCodes = [ |
||||
'AED', |
||||
'AFN', |
||||
'ALL', |
||||
'AMD', |
||||
'ANG', |
||||
'AOA', |
||||
'ARS', |
||||
'AUD', |
||||
'AWG', |
||||
'AZN', |
||||
'BAM', |
||||
'BBD', |
||||
'BDT', |
||||
'BGN', |
||||
'BHD', |
||||
'BIF', |
||||
'BMD', |
||||
'BND', |
||||
'BOB', |
||||
'BOV', |
||||
'BRL', |
||||
'BSD', |
||||
'BTN', |
||||
'BWP', |
||||
'BYR', |
||||
'BZD', |
||||
'CAD', |
||||
'CDF', |
||||
'CHE', |
||||
'CHF', |
||||
'CHW', |
||||
'CLF', |
||||
'CLP', |
||||
'CNY', |
||||
'COP', |
||||
'COU', |
||||
'CRC', |
||||
'CUP', |
||||
'CVE', |
||||
'CYP', |
||||
'CZK', |
||||
'DJF', |
||||
'DKK', |
||||
'DOP', |
||||
'DZD', |
||||
'EEK', |
||||
'EGP', |
||||
'ERN', |
||||
'ETB', |
||||
'EUR', |
||||
'FJD', |
||||
'FKP', |
||||
'GBP', |
||||
'GEL', |
||||
'GHC', |
||||
'GIP', |
||||
'GMD', |
||||
'GNF', |
||||
'GTQ', |
||||
'GYD', |
||||
'HKD', |
||||
'HNL', |
||||
'HRK', |
||||
'HTG', |
||||
'HUF', |
||||
'IDR', |
||||
'ILS', |
||||
'INR', |
||||
'IQD', |
||||
'IRR', |
||||
'ISK', |
||||
'JMD', |
||||
'JOD', |
||||
'JPY', |
||||
'KES', |
||||
'KGS', |
||||
'KHR', |
||||
'KMF', |
||||
'KPW', |
||||
'KRW', |
||||
'KWD', |
||||
'KYD', |
||||
'KZT', |
||||
'LAK', |
||||
'LBP', |
||||
'LKR', |
||||
'LRD', |
||||
'LSL', |
||||
'LTL', |
||||
'LVL', |
||||
'LYD', |
||||
'MAD', |
||||
'MDL', |
||||
'MGA', |
||||
'MKD', |
||||
'MMK', |
||||
'MNT', |
||||
'MOP', |
||||
'MRO', |
||||
'MTL', |
||||
'MUR', |
||||
'MVR', |
||||
'MWK', |
||||
'MXN', |
||||
'MXV', |
||||
'MYR', |
||||
'MZN', |
||||
'NAD', |
||||
'NGN', |
||||
'NIO', |
||||
'NOK', |
||||
'NPR', |
||||
'NZD', |
||||
'OMR', |
||||
'PAB', |
||||
'PEN', |
||||
'PGK', |
||||
'PHP', |
||||
'PKR', |
||||
'PLN', |
||||
'PYG', |
||||
'QAR', |
||||
'ROL', |
||||
'RON', |
||||
'RSD', |
||||
'RUB', |
||||
'RWF', |
||||
'SAR', |
||||
'SBD', |
||||
'SCR', |
||||
'SDD', |
||||
'SEK', |
||||
'SGD', |
||||
'SHP', |
||||
'SIT', |
||||
'SKK', |
||||
'SLL', |
||||
'SOS', |
||||
'SRD', |
||||
'STD', |
||||
'SYP', |
||||
'SZL', |
||||
'THB', |
||||
'TJS', |
||||
'TMM', |
||||
'TND', |
||||
'TOP', |
||||
'TRY', |
||||
'TTD', |
||||
'TWD', |
||||
'TZS', |
||||
'UAH', |
||||
'UGX', |
||||
'USD', |
||||
'USN', |
||||
'USS', |
||||
'UYU', |
||||
'UZS', |
||||
'VEB', |
||||
'VND', |
||||
'VUV', |
||||
'WST', |
||||
'XAF', |
||||
'XAG', |
||||
'XAU', |
||||
'XBA', |
||||
'XBB', |
||||
'XBC', |
||||
'XBD', |
||||
'XCD', |
||||
'XDR', |
||||
'XFO', |
||||
'XFU', |
||||
'XOF', |
||||
'XPD', |
||||
'XPF', |
||||
'XPT', |
||||
'XTS', |
||||
'XXX', |
||||
'YER', |
||||
'ZAR', |
||||
'ZMK', |
||||
'ZWD', |
||||
] |
||||
|
||||
export function validateCurrencyCode(v: string) { |
||||
return currencyCodes.includes(v) |
||||
} |
||||
|
||||
export function currencyLocales() { |
||||
const localeList = locale.all |
||||
.filter((l: Record<string, any>) => { |
||||
try { |
||||
if (Intl.NumberFormat.supportedLocalesOf(l.tag).length > 0) { |
||||
return true |
||||
} |
||||
return false |
||||
} catch (e) { |
||||
return false |
||||
} |
||||
}) |
||||
.map((l: Record<string, any>) => { |
||||
return { |
||||
text: `${l.name} (${l.tag})`, |
||||
value: l.tag, |
||||
} |
||||
}) |
||||
return localeList |
||||
} |
||||
|
||||
export function validateCurrencyLocale(v: string) { |
||||
try { |
||||
return Intl.NumberFormat.supportedLocalesOf(v).length > 0 |
||||
} catch (e) { |
||||
return false |
||||
} |
||||
} |
Loading…
Reference in new issue