-
+
-
-
+
-
+
{
data-testid="nc-token-input"
@press-enter="generateToken"
/>
- {{ errorMessage }}
+ {{ errorMessage }}
+
@@ -220,13 +237,20 @@ const handleCancel = () => {
-
-
+
+
-
+
{{ el.description }}
@@ -241,39 +265,42 @@ const handleCancel = () => {
{{ el.token }}
- **************************************
+ ************************************
-
-
-
+
-
- show or hide
-
-
-
- copy
-
-
-
- delete
-
-
-
-
+
+
+ {{ $t('labels.showOrHide') }}
+
+
+
+ {{ $t('general.copy') }}
+
+
+
+ {{ $t('general.delete') }}
+
+
+
+
+
{
-
@@ -300,3 +331,9 @@ const handleCancel = () => {
+
+
diff --git a/packages/nc-gui/components/account/UserList.vue b/packages/nc-gui/components/account/UserList.vue
index 0b0ce5250a..4d29a0ed5e 100644
--- a/packages/nc-gui/components/account/UserList.vue
+++ b/packages/nc-gui/components/account/UserList.vue
@@ -1,11 +1,14 @@
-
-
-
User Management
-
-
-
-
-
- {
- showUserModal = true
- userMadalKey++
- }
- "
- >
-
+
-
- Invite new user
-
-
+
+
-
+
{{ $t('title.userManagement') }}
+
+
+
+
+
+
+
-
+
+
+
+
+
+ {{ $t('activity.inviteUser') }}
+
+
+
-
-
-
-
-
-
+
+
+
+
-
+
+
+
+
+
diff --git a/packages/nc-gui/components/account/UsersModal.vue b/packages/nc-gui/components/account/UsersModal.vue
index 2ea494980e..8c03f48ccc 100644
--- a/packages/nc-gui/components/account/UsersModal.vue
+++ b/packages/nc-gui/components/account/UsersModal.vue
@@ -79,8 +79,8 @@ const copyUrl = async () => {
try {
await copy(inviteUrl.value)
- // Copied shareable base url to clipboard!
- message.success(t('msg.success.shareableURLCopied'))
+ // Copied shareable source url to clipboard!
+ message.success(t('msg.toast.inviteUrlCopy'))
} catch (e: any) {
message.error(e.message)
}
@@ -110,7 +110,7 @@ const emailInput: VNodeRef = (el) => (el as HTMLInputElement)?.focus()
>
+
+
+ {{ $t('labels.email') }}
+
+ {{ $t('objects.role') }}
+
+ {{ $t('labels.action') }}
+
+
+
+
+
+
- {{ text }}
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+ {{ el.email }}
+
-
-
-
-
-
-
+
-
@@ -210,94 +231,88 @@ const copyPasswordResetUrl = async (user: User) => {
:value="OrgUserRoles.VIEWER"
:label="$t(`objects.roleType.orgLevelViewer`)"
>
-
-
-
- Super Admin
-
+ {{ $t('labels.superAdmin') }}
+
+ {{ $t(`objects.roleType.orgLevelCreator`) }}
-
+ {{ $t(`objects.roleType.orgLevelCreator`) }}
+
{{ $t('msg.info.roles.orgCreator') }}
{{ $t(`objects.roleType.orgLevelViewer`) }}
-
+ {{ $t(`objects.roleType.orgLevelViewer`) }}
+
{{ $t('msg.info.roles.orgViewer') }}
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('general.remove') }} {{ $t('objects.user') }}
+
+
+
+
+
+
+
-
-
-
- {{ $t('activity.resendInvite') }}
-
-
-
- {{ $t('activity.copyInviteURL') }}
-
-
-
- {{ $t('activity.copyPasswordResetURL') }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ record.email }}
-
- {{ $t('general.delete') }}
- {{ $t('activity.resendInvite') }}
+ {{ $t('activity.copyInviteURL') }}
+ {{ $t('activity.copyPasswordResetURL') }}
+
+
+
+
+
+
-
-
-
+ {{ deleteModalInfo?.email }}
+
- {{ $t('activity.inviteUser') }}
+ {{ $t('activity.inviteUser') }}
@@ -124,13 +124,13 @@ const emailInput: VNodeRef = (el) => (el as HTMLInputElement)?.focus()
-
Copy Invite Token
+ {{ $t('activity.copyInviteURL') }}
-
+ (el as HTMLInputElement)?.focus()
-
(el as HTMLInputElement)?.focus()
:value="OrgUserRoles.CREATOR"
:label="$t(`objects.roleType.orgLevelCreator`)"
>
-
@@ -210,8 +210,8 @@ const emailInput: VNodeRef = (el) => (el as HTMLInputElement)?.focus()
:value="OrgUserRoles.VIEWER"
:label="$t(`objects.roleType.orgLevelViewer`)"
>
-
-
diff --git a/packages/nc-gui/components/api-client/Headers.vue b/packages/nc-gui/components/api-client/Headers.vue
index ad4f826526..4d76134580 100644
--- a/packages/nc-gui/components/api-client/Headers.vue
+++ b/packages/nc-gui/components/api-client/Headers.vue
@@ -66,10 +66,10 @@ const filterOption = (input: string, option: Option) => option.value.toUpperCase
-
-
@@ -87,9 +87,9 @@ const filterOption = (input: string, option: Option) => option.value.toUpperCase
@@ -97,7 +97,11 @@ const filterOption = (input: string, option: Option) => option.value.toUpperCase
-
+
@@ -120,7 +124,7 @@ const filterOption = (input: string, option: Option) => option.value.toUpperCase
diff --git a/packages/nc-gui/components/api-client/Params.vue b/packages/nc-gui/components/api-client/Params.vue
index 61aa3f1f2c..70fbb5be89 100644
--- a/packages/nc-gui/components/api-client/Params.vue
+++ b/packages/nc-gui/components/api-client/Params.vue
@@ -24,11 +24,11 @@ const deleteParamRow = (i: number) => {
-
-
@@ -41,13 +41,13 @@ const deleteParamRow = (i: number) => {
-
+
-
+
@@ -69,7 +69,7 @@ const deleteParamRow = (i: number) => {
diff --git a/packages/nc-gui/components/cell/Checkbox.vue b/packages/nc-gui/components/cell/Checkbox.vue
index 5445c3e983..be70d8d314 100644
--- a/packages/nc-gui/components/cell/Checkbox.vue
+++ b/packages/nc-gui/components/cell/Checkbox.vue
@@ -8,7 +8,7 @@ import {
getMdiIcon,
inject,
parseProp,
- useProject,
+ useBase,
useSelectedCellKeyupListener,
} from '#imports'
@@ -28,7 +28,7 @@ const emits = defineEmits()
const active = inject(ActiveCellInj, ref(false))
-const { isMssql } = useProject()
+const { isMssql } = useBase()
const column = inject(ColumnInj)
@@ -40,6 +40,8 @@ const isGallery = inject(IsGalleryInj, ref(false))
const readOnly = inject(ReadonlyInj)
+const isExpandedFormOpen = inject(IsExpandedFormOpenInj, ref(false))
+
const checkboxMeta = computed(() => {
return {
icon: {
@@ -53,7 +55,7 @@ const checkboxMeta = computed(() => {
const vModel = computed({
get: () => !!props.modelValue && props.modelValue !== '0' && props.modelValue !== 0 && props.modelValue !== 'false',
- set: (val: any) => emits('update:modelValue', isMssql(column?.value?.base_id) ? +val : val),
+ set: (val: any) => emits('update:modelValue', isMssql(column?.value?.source_id) ? +val : val),
})
function onClick(force?: boolean, event?: MouseEvent) {
@@ -80,27 +82,29 @@ useSelectedCellKeyupListener(active, (e) => {
!isExpandedFormOpen.value && !isEditColumn.value
class="outline-none px-1 border-none w-full h-full text-sm"
type="number"
step="0.1"
- :placeholder="isEditColumn ? '(Optional)' : ''"
+ :placeholder="isEditColumn ? $t('labels.optional') : ''"
@blur="editEnabled = false"
@keydown.down.stop
@keydown.left.stop
@@ -63,7 +63,7 @@ const focus: VNodeRef = (el) => !isExpandedFormOpen.value && !isEditColumn.value
@selectstart.capture.stop
@mousedown.stop
/>
- NULL
+ {{ $t('general.null') }}
{{ vModel }}
diff --git a/packages/nc-gui/components/cell/Integer.vue b/packages/nc-gui/components/cell/Integer.vue
index 477232670a..5c0bf8944a 100644
--- a/packages/nc-gui/components/cell/Integer.vue
+++ b/packages/nc-gui/components/cell/Integer.vue
@@ -87,8 +87,11 @@ function onKeyDown(e: any) {
v-model="vModel"
class="outline-none py-2 px-1 border-none w-full h-full text-sm"
type="number"
+ :class="{
+ 'pl-2': isExpandedFormOpen,
+ }"
style="letter-spacing: 0.06rem"
- :placeholder="isEditColumn ? '(Optional)' : ''"
+ :placeholder="isEditColumn ? $t('labels.optional') : ''"
@blur="editEnabled = false"
@keydown="onKeyDown"
@keydown.down.stop
@@ -99,7 +102,7 @@ function onKeyDown(e: any) {
@selectstart.capture.stop
@mousedown.stop
/>
- NULL
+ {{ $t('general.null') }}
{{ displayValue }}
diff --git a/packages/nc-gui/components/cell/Json.vue b/packages/nc-gui/components/cell/Json.vue
index 1206b4b5b2..18326296f9 100644
--- a/packages/nc-gui/components/cell/Json.vue
+++ b/packages/nc-gui/components/cell/Json.vue
@@ -1,10 +1,12 @@
-
+
{{ inviteUrl }}
@@ -143,7 +143,7 @@ const emailInput: VNodeRef = (el) => (el as HTMLInputElement)?.focus()
-
+
-
@@ -177,7 +177,7 @@ const emailInput: VNodeRef = (el) => (el as HTMLInputElement)?.focus()
name="emails"
:rules="[{ required: true, message: 'Please input email' }]"
>
-
{{ $t('msg.info.userInviteNoSMTP') }}
{{ usersData.invitationToken && usersData.emails }}
@@ -153,7 +153,7 @@ const emailInput: VNodeRef = (el) => (el as HTMLInputElement)?.focus()
{{ $t('activity.inviteMore') }}
+ {{ $t('activity.inviteMore') }}
{{ $t('datatype.Email') }}:
+ {{ $t('datatype.Email') }}:
{{ $t('labels.selectUserRole') }}
+ {{ $t('labels.selectUserRole') }}
{{ $t(`objects.roleType.orgLevelCreator`) }}
-
+ {{ $t(`objects.roleType.orgLevelCreator`) }}
+
{{ $t('msg.info.roles.orgCreator') }}
{{ $t(`objects.roleType.orgLevelViewer`) }}
-
+ {{ $t(`objects.roleType.orgLevelViewer`) }}
+
{{ $t('msg.info.roles.orgViewer') }}
@@ -224,7 +224,7 @@ const emailInput: VNodeRef = (el) => (el as HTMLInputElement)?.focus()
{{ $t('activity.invite') }}
+ {{ $t('activity.invite') }}
Header Name
+ {{ $t('labels.headerName') }}
Value
+ {{ $t('placeholder.value') }}
-
Add Header
+ {{ $t('labels.addHeader') }}
Parameter Name
+ {{ $t('title.parameterName') }}
Value
+ {{ $t('placeholder.value') }}
-
Add Parameter
+ {{ $t('activity.addParameter') }}
- ()
const emit = defineEmits(['update:modelValue'])
+const { t } = useI18n()
+
const { showNull } = useGlobal()
const columnMeta = inject(ColumnInj, null)!
@@ -84,11 +86,11 @@ watch(
const placeholder = computed(() => {
if (isEditColumn.value && (modelValue === '' || modelValue === null)) {
- return '(Optional)'
+ return t('labels.optional')
} else if (modelValue === null && showNull.value) {
- return 'NULL'
+ return t('general.null')
} else if (isDateInvalid.value) {
- return 'Invalid date'
+ return t('msg.invalidDate')
} else {
return ''
}
diff --git a/packages/nc-gui/components/cell/DateTimePicker.vue b/packages/nc-gui/components/cell/DateTimePicker.vue
index c0a3960d23..984806908e 100644
--- a/packages/nc-gui/components/cell/DateTimePicker.vue
+++ b/packages/nc-gui/components/cell/DateTimePicker.vue
@@ -13,7 +13,7 @@ import {
parseProp,
ref,
timeFormats,
- useProject,
+ useBase,
useSelectedCellKeyupListener,
watch,
} from '#imports'
@@ -28,7 +28,7 @@ const { modelValue, isPk, isUpdatedFromCopyNPaste } = defineProps()
const emit = defineEmits(['update:modelValue'])
-const { isMssql, isXcdbBase } = useProject()
+const { isMssql, isXcdbBase } = useBase()
const { showNull } = useGlobal()
@@ -40,6 +40,8 @@ const editable = inject(EditModeInj, ref(false))
const isLockedMode = inject(IsLockedInj, ref(false))
+const { t } = useI18n()
+
const isEditColumn = inject(EditColumnInj, ref(false))
const column = inject(ColumnInj)!
@@ -65,7 +67,7 @@ const localState = computed({
return undefined
}
- const isXcDB = isXcdbBase(column.value.base_id)
+ const isXcDB = isXcdbBase(column.value.source_id)
// cater copy and paste
// when copying a datetime cell, the copied value would be local time
@@ -81,7 +83,7 @@ const localState = computed({
return /^\d+$/.test(modelValue) ? dayjs(+modelValue) : dayjs(modelValue)
}
- if (isMssql(column.value.base_id)) {
+ if (isMssql(column.value.source_id)) {
// e.g. 2023-04-29T11:41:53.000Z
return dayjs(modelValue)
}
@@ -137,11 +139,11 @@ watch(
const placeholder = computed(() => {
if (isEditColumn.value && (modelValue === '' || modelValue === null)) {
- return '(Optional)'
+ return t('labels.optional')
} else if (modelValue === null && showNull.value) {
- return 'NULL'
+ return t('general.null')
} else if (isDateInvalid.value) {
- return 'Invalid date'
+ return t('msg.invalidDate')
} else {
return ''
}
diff --git a/packages/nc-gui/components/cell/Decimal.vue b/packages/nc-gui/components/cell/Decimal.vue
index 547f14a227..80a7e9fc01 100644
--- a/packages/nc-gui/components/cell/Decimal.vue
+++ b/packages/nc-gui/components/cell/Decimal.vue
@@ -97,7 +97,7 @@ watch(isExpandedFormOpen, () => {
class="outline-none !py-2 !px-1 border-none rounded-md w-full h-full !text-sm"
type="number"
:step="precision"
- :placeholder="isEditColumn ? '(Optional)' : ''"
+ :placeholder="isEditColumn ? $t('labels.optional') : ''"
style="letter-spacing: 0.06rem"
@blur="editEnabled = false"
@keydown.down.stop="onKeyDown"
@@ -110,7 +110,7 @@ watch(isExpandedFormOpen, () => {
@selectstart.capture.stop
@mousedown.stop
/>
- NULL
+ {{ $t('general.null') }}
{{ displayValue }}
diff --git a/packages/nc-gui/components/cell/Duration.vue b/packages/nc-gui/components/cell/Duration.vue
index 34cc923bf1..c3bc7bb3ea 100644
--- a/packages/nc-gui/components/cell/Duration.vue
+++ b/packages/nc-gui/components/cell/Duration.vue
@@ -23,6 +23,8 @@ const { modelValue, showValidationError = true } = defineProps()
const emit = defineEmits(['update:modelValue'])
+const { t } = useI18n()
+
const { showNull } = useGlobal()
const column = inject(ColumnInj)
@@ -39,7 +41,9 @@ const isEditColumn = inject(EditColumnInj, ref(false))
const durationType = computed(() => parseProp(column?.value?.meta)?.duration || 0)
-const durationPlaceholder = computed(() => (isEditColumn.value ? '(Optional)' : durationOptions[durationType.value].title))
+const durationPlaceholder = computed(() =>
+ isEditColumn.value ? `(${t('labels.optional')})` : durationOptions[durationType.value].title,
+)
const localState = computed({
get: () => convertMS2Duration(modelValue, durationType.value),
@@ -105,13 +109,12 @@ const focus: VNodeRef = (el) => !isExpandedFormOpen.value && !isEditColumn.value
@mousedown.stop
/>
- NULL
+ {{ $t('general.null') }}
{{ localState }}
diff --git a/packages/nc-gui/components/cell/Email.vue b/packages/nc-gui/components/cell/Email.vue
index 434dd0a1fc..385fecb852 100644
--- a/packages/nc-gui/components/cell/Email.vue
+++ b/packages/nc-gui/components/cell/Email.vue
@@ -71,7 +71,7 @@ watch(
:ref="focus"
v-model="vModel"
class="w-full outline-none text-sm px-1 py-2"
- :placeholder="isEditColumn ? '(Optional)' : ''"
+ :placeholder="isEditColumn ? $t('labels.optional') : ''"
@blur="editEnabled = false"
@keydown.down.stop
@keydown.left.stop
@@ -84,7 +84,7 @@ watch(
@mousedown.stop
/>
- NULL
+ {{ $t('general.null') }}
-
diff --git a/packages/nc-gui/components/cell/Currency.vue b/packages/nc-gui/components/cell/Currency.vue
index fc67d9274a..1b5d363969 100644
--- a/packages/nc-gui/components/cell/Currency.vue
+++ b/packages/nc-gui/components/cell/Currency.vue
@@ -79,7 +79,7 @@ onMounted(() => {
v-model="vModel"
type="number"
class="w-full h-full text-sm border-none rounded-md outline-none"
- :placeholder="isEditColumn ? '(Optional)' : ''"
+ :placeholder="isEditColumn ? $t('labels.optional') : ''"
@blur="submitCurrency"
@keydown.down.stop
@keydown.left.stop
@@ -93,7 +93,7 @@ onMounted(() => {
@contextmenu.stop
/>
- NULL
+ {{ $t('general.null') }}
{{ currency }}
diff --git a/packages/nc-gui/components/cell/DatePicker.vue b/packages/nc-gui/components/cell/DatePicker.vue
index 991fa52903..e1f2f79433 100644
--- a/packages/nc-gui/components/cell/DatePicker.vue
+++ b/packages/nc-gui/components/cell/DatePicker.vue
@@ -25,6 +25,8 @@ const { modelValue, isPk } = defineProps
-
-
-
-
+
+
+
+
-
- Please enter a number
+ {{ $t('msg.plsEnterANumber') }}
-
+
- {
- NULL
+ {{ $t('general.null') }}
- {{ vModel }}
+
diff --git a/packages/nc-gui/components/cell/MultiSelect.vue b/packages/nc-gui/components/cell/MultiSelect.vue
index ae68ab7aad..7a64c35a1a 100644
--- a/packages/nc-gui/components/cell/MultiSelect.vue
+++ b/packages/nc-gui/components/cell/MultiSelect.vue
@@ -23,9 +23,9 @@ import {
onMounted,
reactive,
ref,
+ useBase,
useEventListener,
useMetas,
- useProject,
useRoles,
useSelectedCellKeyupListener,
watch,
@@ -43,6 +43,8 @@ const { modelValue, disableOptionCreation } = defineProps()
const emit = defineEmits(['update:modelValue'])
+const { isMobileMode } = useGlobal()
+
const column = inject(ColumnInj)!
const readOnly = inject(ReadonlyInj)!
@@ -81,7 +83,7 @@ const { getMeta } = useMetas()
const { isUIAllowed } = useRoles()
-const { isPg, isMysql } = useProject()
+const { isPg, isMysql } = useBase()
// a variable to keep newly created options value
// temporary until it's add the option to column meta
@@ -133,7 +135,7 @@ const vModel = computed({
const selectedTitles = computed(() =>
modelValue
? typeof modelValue === 'string'
- ? isMysql(column.value.base_id)
+ ? isMysql(column.value.source_id)
? modelValue.split(',').sort((a, b) => {
const opa = options.value.find((el) => el.title === a)
const opb = options.value.find((el) => el.title === b)
@@ -142,8 +144,8 @@ const selectedTitles = computed(() =>
}
return 0
})
- : modelValue.split(',')
- : modelValue
+ : modelValue.split(',').map((el) => el.trim())
+ : modelValue.map((el) => el.trim())
: [],
)
@@ -247,7 +249,7 @@ async function addIfMissingAndSave() {
// todo: refactor and avoid repetition
if (updatedColMeta.cdf) {
// Postgres returns default value wrapped with single quotes & casted with type so we have to get value between single quotes to keep it unified for all databases
- if (isPg(column.value.base_id)) {
+ if (isPg(column.value.source_id)) {
updatedColMeta.cdf = updatedColMeta.cdf.substring(
updatedColMeta.cdf.indexOf(`'`) + 1,
updatedColMeta.cdf.lastIndexOf(`'`),
@@ -255,7 +257,7 @@ async function addIfMissingAndSave() {
}
// Mysql escapes single quotes with backslash so we keep quotes but others have to unescaped
- if (!isMysql(column.value.base_id)) {
+ if (!isMysql(column.value.source_id) && !isPg(column.value.source_id)) {
updatedColMeta.cdf = updatedColMeta.cdf.replace(/''/g, "'")
}
}
@@ -321,6 +323,8 @@ const handleClose = (e: MouseEvent) => {
!aselect.value.$el.contains(e.target) &&
!document.querySelector('.nc-dropdown-multi-select-cell.active')?.contains(e.target as Node)
) {
+ // loose focus when clicked outside
+ isEditable.value = false
isOpen.value = false
}
}
@@ -378,10 +382,10 @@ const selectedOpts = computed(() => {
v-model:value="vModel"
mode="multiple"
class="w-full overflow-hidden"
- :placeholder="isEditColumn ? '(Optional)' : ''"
+ :placeholder="isEditColumn ? $t('labels.optional') : ''"
:bordered="false"
clear-icon
- show-search
+ :show-search="!isMobileMode"
:show-arrow="editAllowed && !(readOnly || isLockedMode)"
:open="isOpen && editAllowed"
:disabled="readOnly || !editAllowed || isLockedMode"
@@ -390,6 +394,9 @@ const selectedOpts = computed(() => {
@search="search"
@keydown.stop
>
+
+
+
{
diff --git a/packages/nc-gui/components/cell/Percent.vue b/packages/nc-gui/components/cell/Percent.vue
index 5fec5b0412..55b6188e56 100644
--- a/packages/nc-gui/components/cell/Percent.vue
+++ b/packages/nc-gui/components/cell/Percent.vue
@@ -42,7 +42,7 @@ const focus: VNodeRef = (el) => !isExpandedFormOpen.value && !isEditColumn.value
class="w-full !text-sm !border-none !outline-none focus:ring-0 text-base p-1"
:class="{ '!px-2': editEnabled }"
type="number"
- :placeholder="isEditColumn ? '(Optional)' : ''"
+ :placeholder="isEditColumn ? $t('labels.optional') : ''"
@blur="editEnabled = false"
@keydown.down.stop
@keydown.left.stop
@@ -54,6 +54,6 @@ const focus: VNodeRef = (el) => !isExpandedFormOpen.value && !isEditColumn.value
@selectstart.capture.stop
@mousedown.stop
/>
- NULL
+ {{ $t('general.null') }}
{{ vModel }}
diff --git a/packages/nc-gui/components/cell/PhoneNumber.vue b/packages/nc-gui/components/cell/PhoneNumber.vue
index 42f2f37f25..24c3c8ef36 100644
--- a/packages/nc-gui/components/cell/PhoneNumber.vue
+++ b/packages/nc-gui/components/cell/PhoneNumber.vue
@@ -15,6 +15,8 @@ const rowHeight = inject(RowHeightInj, ref(undefined))
const { showNull } = useGlobal()
+const { t } = useI18n()
+
const editEnabled = inject(EditModeInj)!
const isEditColumn = inject(EditColumnInj, ref(false))
@@ -46,7 +48,7 @@ watch(
() => editEnabled.value,
() => {
if (parseProp(column.value.meta)?.validate && !editEnabled.value && localState.value && !isMobilePhone(localState.value)) {
- message.error('Invalid Phone Number')
+ message.error(t('msg.invalidPhoneNumber'))
localState.value = undefined
return
}
@@ -61,7 +63,7 @@ watch(
:ref="focus"
v-model="vModel"
class="w-full outline-none text-sm px-1 py-2"
- :placeholder="isEditColumn ? '(Optional)' : ''"
+ :placeholder="isEditColumn ? $t('labels.optional') : ''"
@blur="editEnabled = false"
@keydown.down.stop
@keydown.left.stop
@@ -74,7 +76,7 @@ watch(
@mousedown.stop
/>
- NULL
+ {{ $t('general.null') }}
diff --git a/packages/nc-gui/components/cell/SingleSelect.vue b/packages/nc-gui/components/cell/SingleSelect.vue
index 4e357d1cb2..6d132cf0b0 100644
--- a/packages/nc-gui/components/cell/SingleSelect.vue
+++ b/packages/nc-gui/components/cell/SingleSelect.vue
@@ -20,8 +20,8 @@ import {
inject,
isDrawerOrModalExist,
ref,
+ useBase,
useEventListener,
- useProject,
useRoles,
useSelectedCellKeyupListener,
watch,
@@ -37,6 +37,8 @@ const { modelValue, disableOptionCreation } = defineProps()
const emit = defineEmits(['update:modelValue'])
+const { isMobileMode } = useGlobal()
+
const column = inject(ColumnInj)!
const readOnly = inject(ReadonlyInj)!
@@ -71,7 +73,7 @@ const { getMeta } = useMetas()
const { isUIAllowed } = useRoles()
-const { isPg, isMysql } = useProject()
+const { isPg, isMysql } = useBase()
// a variable to keep newly created option value
// temporary until it's add the option to column meta
@@ -102,7 +104,7 @@ const hasEditRoles = computed(() => isUIAllowed('dataEdit'))
const editAllowed = computed(() => (hasEditRoles.value || isForm.value) && active.value)
const vModel = computed({
- get: () => tempSelectedOptState.value ?? modelValue,
+ get: () => tempSelectedOptState.value ?? modelValue?.trim(),
set: (val) => {
if (val && isNewOptionCreateEnabled.value && (options.value ?? []).every((op) => op.title !== val)) {
tempSelectedOptState.value = val
@@ -175,7 +177,7 @@ async function addIfMissingAndSave() {
// todo: refactor and avoid repetition
if (updatedColMeta.cdf) {
// Postgres returns default value wrapped with single quotes & casted with type so we have to get value between single quotes to keep it unified for all databases
- if (isPg(column.value.base_id)) {
+ if (isPg(column.value.source_id)) {
updatedColMeta.cdf = updatedColMeta.cdf.substring(
updatedColMeta.cdf.indexOf(`'`) + 1,
updatedColMeta.cdf.lastIndexOf(`'`),
@@ -183,7 +185,7 @@ async function addIfMissingAndSave() {
}
// Mysql escapes single quotes with backslash so we keep quotes but others have to unescaped
- if (!isMysql(column.value.base_id)) {
+ if (!isMysql(column.value.source_id) && !isPg(column.value.source_id)) {
updatedColMeta.cdf = updatedColMeta.cdf.replace(/''/g, "'")
}
}
@@ -202,6 +204,8 @@ async function addIfMissingAndSave() {
}
const search = () => {
+ if (isMobileMode.value) return
+
searchVal.value = aselect.value?.$el?.querySelector('.ant-select-selection-search-input')?.value
}
@@ -217,6 +221,7 @@ const onKeydown = (e: KeyboardEvent) => {
const onSelect = () => {
isOpen.value = false
+ isEditable.value = false
}
const cellClickHook = inject(CellClickHookInj, null)
@@ -284,16 +289,16 @@ const selectedOpt = computed(() => {
v-else
ref="aselect"
v-model:value="vModel"
- class="w-full overflow-hidden"
+ class="w-full overflow-hidden xs:min-h-12"
:class="{ 'caret-transparent': !hasEditRoles }"
- :placeholder="isEditColumn ? '(Optional)' : ''"
+ :placeholder="isEditColumn ? $t('labels.optional') : ''"
:allow-clear="!column.rqd && editAllowed"
:bordered="false"
:open="isOpen && editAllowed"
:disabled="readOnly || !editAllowed || isLockedMode"
:show-arrow="hasEditRoles && !(readOnly || isLockedMode) && active && vModel === null"
:dropdown-class-name="`nc-dropdown-single-select-cell ${isOpen && active ? 'active' : ''}`"
- :show-search="isOpen && active"
+ :show-search="!isMobileMode && isOpen && active"
@select="onSelect"
@keydown="onKeydown($event)"
@search="search"
@@ -324,7 +329,7 @@ const selectedOpt = computed(() => {
diff --git a/packages/nc-gui/components/cell/Text.vue b/packages/nc-gui/components/cell/Text.vue
index 9fc0b9209e..e3ec8698a6 100644
--- a/packages/nc-gui/components/cell/Text.vue
+++ b/packages/nc-gui/components/cell/Text.vue
@@ -33,7 +33,10 @@ const focus: VNodeRef = (el) => !isExpandedFormOpen.value && !isEditColumn.value
:ref="focus"
v-model="vModel"
class="h-full w-full outline-none p-2 bg-transparent"
- :placeholder="isEditColumn ? '(Optional)' : ''"
+ :placeholder="isEditColumn ? $t('labels.optional') : ''"
+ :class="{
+ 'px-1': isExpandedFormOpen,
+ }"
@blur="editEnabled = false"
@keydown.down.stop
@keydown.left.stop
@@ -46,7 +49,7 @@ const focus: VNodeRef = (el) => !isExpandedFormOpen.value && !isEditColumn.value
@mousedown.stop
/>
- NULL
+ {{ $t('general.null') }}
diff --git a/packages/nc-gui/components/cell/TextArea.vue b/packages/nc-gui/components/cell/TextArea.vue
index 0ebd53ae86..6cf430bd22 100644
--- a/packages/nc-gui/components/cell/TextArea.vue
+++ b/packages/nc-gui/components/cell/TextArea.vue
@@ -28,6 +28,8 @@ const isEditColumn = inject(EditColumnInj, ref(false))
const rowHeight = inject(RowHeightInj, ref(1 as const))
+const isForm = inject(IsFormInj, ref(false))
+
const { showNull } = useGlobal()
const vModel = useVModel(props, 'modelValue', emits, { defaultValue: '' })
@@ -68,10 +70,11 @@ onClickOutside(inputWrapperRef, (e) => {
-
+
Cancel
+
-
{{ $t('general.cancel') }}
Save
+ {{ $t('general.save') }}
- Create new option named {{ searchVal }}
+ {{ $t('msg.selectOption.createNewOptionNamed') }} {{ searchVal }}
- Create new option named {{ searchVal }}
+ {{ $t('msg.selectOption.createNewOptionNamed') }} {{ searchVal }}