Browse Source

feat: handle in fields

pull/8708/head
Pranav C 4 months ago
parent
commit
234037d26c
  1. 29
      packages/nc-gui/components/dashboard/settings/data-sources/CreateBase.vue
  2. 3
      packages/nc-gui/components/dashboard/settings/data-sources/EditBase.vue
  3. 15
      packages/nc-gui/components/smartsheet/details/Fields.vue
  4. 8
      packages/nc-gui/components/smartsheet/header/Menu.vue
  5. 1
      packages/nc-gui/lang/en.json
  6. 4
      packages/nocodb-sdk/src/lib/UITypes.ts
  7. 7
      packages/nocodb/tests/unit/rest/tests/readOnlySource.test.ts

29
packages/nc-gui/components/dashboard/settings/data-sources/CreateBase.vue

@ -404,6 +404,7 @@ const allowMetaWrite = computed({
get: () => !formState.value.is_schema_readonly,
set: (v) => {
formState.value.is_schema_readonly = !v
$e('c:source:schema-write-toggle', {allowed: !v})
},
})
@ -411,6 +412,7 @@ const allowDataWrite = computed({
get: () => !formState.value.is_data_readonly,
set: (v) => {
formState.value.is_data_readonly = !v
$e('c:source:data-write-toggle', { allowed: !v })
},
})
</script>
@ -499,7 +501,8 @@ const allowDataWrite = computed({
<!-- Username -->
<a-form-item :label="$t('labels.username')" v-bind="validateInfos['dataSource.connection.user']">
<a-input v-model:value="(formState.dataSource.connection as DefaultConnection).user" class="nc-extdb-host-user" />
<a-input v-model:value="(formState.dataSource.connection as DefaultConnection).user"
class="nc-extdb-host-user"/>
</a-form-item>
<!-- Password -->
@ -563,7 +566,8 @@ const allowDataWrite = computed({
<div class="flex items-right justify-end gap-2">
<!-- Use Connection URL -->
<NcButton type="ghost" size="small" class="nc-extdb-btn-import-url !rounded-md" @click.stop="importURLDlg = true">
<NcButton type="ghost" size="small" class="nc-extdb-btn-import-url !rounded-md"
@click.stop="importURLDlg = true">
{{ $t('activity.useConnectionUrl') }}
</NcButton>
</div>
@ -601,7 +605,8 @@ const allowDataWrite = computed({
<span>{{ $t('tooltip.clientCert') }}</span>
</template>
<NcButton size="small" :disabled="!sslFilesRequired" class="shadow" @click="certFileInput?.click()">
<NcButton size="small" :disabled="!sslFilesRequired" class="shadow"
@click="certFileInput?.click()">
{{ $t('labels.clientCert') }}
</NcButton>
</a-tooltip>
@ -611,7 +616,8 @@ const allowDataWrite = computed({
<template #title>
<span>{{ $t('tooltip.clientKey') }}</span>
</template>
<NcButton size="small" :disabled="!sslFilesRequired" class="shadow" @click="keyFileInput?.click()">
<NcButton size="small" :disabled="!sslFilesRequired" class="shadow"
@click="keyFileInput?.click()">
{{ $t('labels.clientKey') }}
</NcButton>
</a-tooltip>
@ -622,18 +628,22 @@ const allowDataWrite = computed({
<span>{{ $t('tooltip.clientCA') }}</span>
</template>
<NcButton size="small" :disabled="!sslFilesRequired" class="shadow" @click="caFileInput?.click()">
<NcButton size="small" :disabled="!sslFilesRequired" class="shadow"
@click="caFileInput?.click()">
{{ $t('labels.serverCA') }}
</NcButton>
</a-tooltip>
</div>
</a-form-item>
<input ref="caFileInput" type="file" class="!hidden" @change="onFileSelect(CertTypes.ca, caFileInput)" />
<input ref="caFileInput" type="file" class="!hidden"
@change="onFileSelect(CertTypes.ca, caFileInput)"/>
<input ref="certFileInput" type="file" class="!hidden" @change="onFileSelect(CertTypes.cert, certFileInput)" />
<input ref="certFileInput" type="file" class="!hidden"
@change="onFileSelect(CertTypes.cert, certFileInput)"/>
<input ref="keyFileInput" type="file" class="!hidden" @change="onFileSelect(CertTypes.key, keyFileInput)" />
<input ref="keyFileInput" type="file" class="!hidden"
@change="onFileSelect(CertTypes.key, keyFileInput)"/>
<a-divider/>
@ -693,7 +703,8 @@ const allowDataWrite = computed({
dropdown-class-name="nc-dropdown-inflection-column-name"
>
<a-select-option v-for="tp in inflectionTypes" :key="tp" :value="tp"
><div class="flex items-center gap-2 justify-between">
>
<div class="flex items-center gap-2 justify-between">
<div>{{ tp }}</div>
<component
:is="iconMap.check"

3
packages/nc-gui/components/dashboard/settings/data-sources/EditBase.vue

@ -1,6 +1,5 @@
<script lang="ts" setup>
import type { SourceType } from 'nocodb-sdk'
import { SourceRestriction } from 'nocodb-sdk'
import { Form, message } from 'ant-design-vue'
import type { SelectHandler } from 'ant-design-vue/es/vc-select/Select'
import {
@ -370,6 +369,7 @@ const allowMetaWrite = computed({
get: () => !formState.value.is_schema_readonly,
set: (v) => {
formState.value.is_schema_readonly = !v
$e('c:source:schema-write-toggle', { allowed: !v, edit: true })
},
})
@ -377,6 +377,7 @@ const allowDataWrite = computed({
get: () => !formState.value.is_data_readonly,
set: (v) => {
formState.value.is_data_readonly = !v
$e('c:source:data-write-toggle', { allowed: !v, edit: true })
},
})
</script>

15
packages/nc-gui/components/smartsheet/details/Fields.vue

@ -1,7 +1,7 @@
<script setup lang="ts">
import { diff } from 'deep-object-diff'
import { message } from 'ant-design-vue'
import { UITypes, isLinksOrLTAR, isSystemColumn, isVirtualCol } from 'nocodb-sdk'
import { UITypes, isLinksOrLTAR, isSystemColumn, isVirtualCol, readonlyMetaAllowedTypes } from 'nocodb-sdk'
import type { ColumnType, FilterType, SelectOptionsType } from 'nocodb-sdk'
import Draggable from 'vuedraggable'
import { onKeyDown, useMagicKeys } from '@vueuse/core'
@ -182,7 +182,18 @@ const setFieldMoveHook = (field: TableExplorerColumn, before = false) => {
}
}
const { isMetaReadOnly } = useRoles()
const isColumnUpdateAllowed = (column: ColumnType) => {
if (isMetaReadOnly.value && !readonlyMetaAllowedTypes.includes(column?.uidt)) return false
return true
}
const changeField = (field?: TableExplorerColumn, event?: MouseEvent) => {
if (!isColumnUpdateAllowed(field)) {
return message.info(t('msg.info.schemaReadOnly'))
}
if (field && field?.pk) {
// Editing primary key not supported
message.info(t('msg.info.editingPKnotSupported'))
@ -1003,7 +1014,7 @@ watch(
<div
v-if="field.title.toLowerCase().includes(searchQuery.toLowerCase()) && !field.pv"
class="flex px-2 hover:bg-gray-100 first:rounded-t-lg border-b-1 last:rounded-b-none border-gray-200 pl-5 group"
:class="` ${compareCols(field, activeField) ? 'selected' : ''}`"
:class="{ 'selected': compareCols(field, activeField), 'cursor-not-allowed': !isColumnUpdateAllowed(field) }"
:data-testid="`nc-field-item-${fieldState(field)?.title || field.title}`"
@click="changeField(field, $event)"
>

8
packages/nc-gui/components/smartsheet/header/Menu.vue

@ -355,7 +355,7 @@ const filterOrGroupByThisField = (event: SmartsheetStoreEvents) => {
isOpen.value = false
}
const isColumnCRUDAllowed = computed(() => {
const isColumnUpdateAllowed = computed(() => {
if (isMetaReadOnly.value && !readonlyMetaAllowedTypes.includes(column.value?.uidt)) return false
return true
})
@ -382,7 +382,7 @@ const isColumnCRUDAllowed = computed(() => {
}"
>
<NcMenuItem
v-if="isUIAllowed('fieldAlter') && isColumnCRUDAllowed"
v-if="isUIAllowed('fieldAlter') && isColumnUpdateAllowed"
:disabled="column?.pk || isSystemColumn(column)"
@click="onEditPress"
>
@ -393,7 +393,7 @@ const isColumnCRUDAllowed = computed(() => {
</div>
</NcMenuItem>
<NcMenuItem
v-if="isUIAllowed('duplicateColumn') && isExpandedForm && !column?.pk && isColumnCRUDAllowed"
v-if="isUIAllowed('duplicateColumn') && isExpandedForm && !column?.pk && isColumnUpdateAllowed"
:disabled="!isDuplicateAllowed"
@click="openDuplicateDlg"
>
@ -532,7 +532,7 @@ const isColumnCRUDAllowed = computed(() => {
<a-divider v-if="!column?.pv" class="!my-0" />
<NcMenuItem
v-if="!column?.pv && isUIAllowed('fieldDelete') && isColumnCRUDAllowed"
v-if="!column?.pv && isUIAllowed('fieldDelete') && isColumnUpdateAllowed"
:disabled="!isDeleteAllowed"
class="!hover:bg-red-50"
@click="handleDelete"

1
packages/nc-gui/lang/en.json

@ -1264,6 +1264,7 @@
}
},
"info": {
"schemaReadOnly": "Schema alterations are disabled for this source",
"enterWorkspaceName": "Enter workspace name",
"enterBaseName": "Enter base name",
"idpPaste": "Paste these URL in your Identity Providers console",

4
packages/nocodb-sdk/src/lib/UITypes.ts

@ -255,12 +255,10 @@ export const isSelectTypeCol = (
};
export default UITypes;
export const readonlyMetaAllowedTypes = [
UITypes.Lookup,
UITypes.Rollup,
UITypes.Formula,
UITypes.Barcode,
UITypes.QrCode,
]
];

7
packages/nocodb/tests/unit/rest/tests/readOnlySource.test.ts

@ -44,7 +44,7 @@ function sourceTest() {
base_id: base.id,
};
const countryColumns = await countryTable.getColumns(sakilaCtx);
const countryColumns = (await countryTable.getColumns(sakilaCtx)).filter(c => !c.pk);
const rowAttributes = Array(99)
.fill(0)
.map((index) =>
@ -84,7 +84,7 @@ function sourceTest() {
base_id: base.id,
};
const countryColumns = await countryTable.getColumns(sakilaCtx);
const countryColumns = (await countryTable.getColumns(sakilaCtx)).filter(c => !c.pk);
const rowAttributes = Array(99)
.fill(0)
.map((index) =>
@ -96,7 +96,6 @@ function sourceTest() {
.set('xc-auth', context.token)
.send(rowAttributes)
.expect(200);
await request(context.app)
.post(`/api/v1/db/meta/projects/${base.id}/tables`)
.set('xc-auth', context.token)
@ -123,7 +122,7 @@ function sourceTest() {
base_id: base.id,
};
const countryColumns = await countryTable.getColumns(sakilaCtx);
const countryColumns = (await countryTable.getColumns(sakilaCtx)).filter(c => !c.pk);
const rowAttributes = Array(99)
.fill(0)
.map((index) =>

Loading…
Cancel
Save