Browse Source

feat: label and tooltip corrections

pull/8708/head
Pranav C 6 months ago
parent
commit
3820e91a1b
  1. 6
      packages/nc-gui/components/dashboard/TreeView/index.vue
  2. 51
      packages/nc-gui/components/dashboard/settings/data-sources/CreateBase.vue
  3. 51
      packages/nc-gui/components/dashboard/settings/data-sources/EditBase.vue
  4. 17
      packages/nc-gui/components/smartsheet/column/EditOrAdd.vue
  5. 7
      packages/nc-gui/components/smartsheet/column/UITypesOptionsWithSearch.vue
  6. 24
      packages/nc-gui/components/smartsheet/header/Menu.vue
  7. 2
      packages/nc-gui/components/smartsheet/toolbar/Calendar/Range.vue
  8. 10
      packages/nc-gui/composables/useRoles/index.ts
  9. 1
      packages/nc-gui/composables/useViewFilters.ts
  10. 4
      packages/nc-gui/lang/en.json

6
packages/nc-gui/components/dashboard/TreeView/index.vue

@ -15,7 +15,7 @@ const basesStore = useBases()
const { createProject: _createProject, updateProject } = basesStore const { createProject: _createProject, updateProject } = basesStore
const { bases, basesList, activeProjectId, b } = storeToRefs(basesStore) const { bases, basesList, activeProjectId } = storeToRefs(basesStore)
const { isWorkspaceLoading } = storeToRefs(useWorkspace()) const { isWorkspaceLoading } = storeToRefs(useWorkspace())
@ -248,9 +248,9 @@ watch(
ghost-class="ghost" ghost-class="ghost"
@change="onMove($event)" @change="onMove($event)"
> >
<template #item="{ element: base }"> <template #item="{ element: base1 }">
<div :key="base.id"> <div :key="base.id">
<ProjectWrapper :base-role="base.project_role" :base="base"> <ProjectWrapper :base-role="base1.project_role" :base="base1">
<DashboardTreeViewProjectNode /> <DashboardTreeViewProjectNode />
</ProjectWrapper> </ProjectWrapper>
</div> </div>

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

@ -399,6 +399,22 @@ watch(
const toggleModal = (val: boolean) => { const toggleModal = (val: boolean) => {
vOpen.value = val vOpen.value = val
} }
const allowMetaWrite = computed({
get: () => !formState.value.meta[SourceRestriction.META_READONLY],
set: (v) => {
formState.value.meta = formState.value.meta || {}
formState.value.meta[SourceRestriction.META_READONLY] = !v
},
})
const allowDataWrite = computed({
get: () => !formState.value.meta[SourceRestriction.DATA_READONLY],
set: (v) => {
formState.value.meta = formState.value.meta || {}
formState.value.meta[SourceRestriction.DATA_READONLY] = !v
},
})
</script> </script>
<template> <template>
@ -514,12 +530,37 @@ const toggleModal = (val: boolean) => {
> >
<a-input v-model:value="formState.dataSource.searchPath[0]" /> <a-input v-model:value="formState.dataSource.searchPath[0]" />
</a-form-item> </a-form-item>
<a-form-item>
<a-form-item label="Readonly Schema"> <template #label>
<a-switch v-model:checked="formState.meta[SourceRestriction.META_READONLY]" size="small"></a-switch> <div class="flex gap-1 justify-end">
<span>
{{ $t('labels.allowMetaWrite') }}
</span>
<NcTooltip>
<template #title>
<span>{{ $t('tooltip.allowMetaWrite') }}</span>
</template>
<GeneralIcon class="text-gray-500" icon="info" />
</NcTooltip>
</div>
</template>
<a-switch v-model:checked="allowMetaWrite" size="small"></a-switch>
</a-form-item> </a-form-item>
<a-form-item label="Readonly Data"> <a-form-item>
<a-switch v-model:checked="formState.meta[SourceRestriction.DATA_READONLY]" size="small"></a-switch> <template #label>
<div class="flex gap-1 justify-end">
<span>
{{ $t('labels.allowDataWrite') }}
</span>
<NcTooltip>
<template #title>
<span>{{ $t('tooltip.allowDataWrite') }}</span>
</template>
<GeneralIcon class="text-gray-500" icon="info" />
</NcTooltip>
</div>
</template>
<a-switch v-model:checked="allowDataWrite" size="small"></a-switch>
</a-form-item> </a-form-item>
<div class="flex items-right justify-end gap-2"> <div class="flex items-right justify-end gap-2">

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

@ -367,6 +367,22 @@ watch(
immediate: true, immediate: true,
}, },
) )
const allowMetaWrite = computed({
get: () => !formState.value.meta[SourceRestriction.META_READONLY],
set: (v) => {
formState.value.meta = formState.value.meta || {}
formState.value.meta[SourceRestriction.META_READONLY] = !v
},
})
const allowDataWrite = computed({
get: () => !formState.value.meta[SourceRestriction.DATA_READONLY],
set: (v) => {
formState.value.meta = formState.value.meta || {}
formState.value.meta[SourceRestriction.DATA_READONLY] = !v
},
})
</script> </script>
<template> <template>
@ -536,13 +552,38 @@ watch(
<a-input v-model:value="formState.dataSource.searchPath[0]" /> <a-input v-model:value="formState.dataSource.searchPath[0]" />
</a-form-item> </a-form-item>
<a-form-item label="Readonly Schema"> <a-form-item>
<a-switch v-model:checked="formState.meta[SourceRestriction.META_READONLY]" size="small"></a-switch> <template #label>
<div class="flex gap-1 justify-end">
<span>
{{ $t('labels.allowMetaWrite') }}
</span>
<NcTooltip>
<template #title>
<span>{{ $t('tooltip.allowMetaWrite') }}</span>
</template>
<GeneralIcon class="text-gray-500" icon="info" />
</NcTooltip>
</div>
</template>
<a-switch v-model:checked="allowMetaWrite" size="small"></a-switch>
</a-form-item> </a-form-item>
<a-form-item label="Readonly Data"> <a-form-item>
<a-switch v-model:checked="formState.meta[SourceRestriction.DATA_READONLY]" size="small"></a-switch> <template #label>
<div class="flex gap-1 justify-end">
<span>
{{ $t('labels.allowDataWrite') }}
</span>
<NcTooltip>
<template #title>
<span>{{ $t('tooltip.allowDataWrite') }}</span>
</template>
<GeneralIcon class="text-gray-500" icon="info" />
</NcTooltip>
</div>
</template>
<a-switch v-model:checked="allowDataWrite" size="small"></a-switch>
</a-form-item> </a-form-item>
<!-- Use Connection URL --> <!-- Use Connection URL -->
<div class="flex justify-end gap-2"> <div class="flex justify-end gap-2">
<NcButton size="small" type="ghost" class="nc-extdb-btn-import-url !rounded-md" @click.stop="importURLDlg = true"> <NcButton size="small" type="ghost" class="nc-extdb-btn-import-url !rounded-md" @click.stop="importURLDlg = true">

17
packages/nc-gui/components/smartsheet/column/EditOrAdd.vue

@ -1,6 +1,14 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { ColumnReqType, ColumnType } from 'nocodb-sdk' import type { ColumnReqType, ColumnType } from 'nocodb-sdk'
import { UITypes, UITypesName, isLinksOrLTAR, isSelfReferencingTableColumn, isSystemColumn, isVirtualCol, readonlyMetaAllowedTypes } from 'nocodb-sdk' import {
UITypes,
UITypesName,
isLinksOrLTAR,
isSelfReferencingTableColumn,
isSystemColumn,
isVirtualCol,
readonlyMetaAllowedTypes,
} from 'nocodb-sdk'
import MdiPlusIcon from '~icons/mdi/plus-circle-outline' import MdiPlusIcon from '~icons/mdi/plus-circle-outline'
import MdiMinusIcon from '~icons/mdi/minus-circle-outline' import MdiMinusIcon from '~icons/mdi/minus-circle-outline'
import MdiIdentifierIcon from '~icons/mdi/identifier' import MdiIdentifierIcon from '~icons/mdi/identifier'
@ -397,7 +405,12 @@ const filterOption = (input: string, option: { value: UITypes }) => {
v-model:value="formState.uidt" v-model:value="formState.uidt"
show-search show-search
class="nc-column-type-input !rounded-lg" class="nc-column-type-input !rounded-lg"
:disabled="(isMetaReadOnly && !readonlyMetaAllowedTypes.includes(formState.uidt)) || isKanban || readOnly || (isEdit && !!onlyNameUpdateOnEditColumns.includes(column?.uidt))" :disabled="
(isMetaReadOnly && !readonlyMetaAllowedTypes.includes(formState.uidt)) ||
isKanban ||
readOnly ||
(isEdit && !!onlyNameUpdateOnEditColumns.includes(column?.uidt))
"
dropdown-class-name="nc-dropdown-column-type border-1 !rounded-lg border-gray-200" dropdown-class-name="nc-dropdown-column-type border-1 !rounded-lg border-gray-200"
:filter-option="filterOption" :filter-option="filterOption"
@dropdown-visible-change="onDropdownChange" @dropdown-visible-change="onDropdownChange"

7
packages/nc-gui/components/smartsheet/column/UITypesOptionsWithSearch.vue

@ -111,14 +111,17 @@ const isDisabledUIType = (type: UITypes) => {
'hover:bg-gray-100 cursor-pointer': !isDisabledUIType(option.name), 'hover:bg-gray-100 cursor-pointer': !isDisabledUIType(option.name),
'bg-gray-100 nc-column-list-option-active': activeFieldIndex === index && !isDisabledUIType(option.name), 'bg-gray-100 nc-column-list-option-active': activeFieldIndex === index && !isDisabledUIType(option.name),
'!text-gray-400 cursor-not-allowed': isDisabledUIType(option.name), '!text-gray-400 cursor-not-allowed': isDisabledUIType(option.name),
}, },
]" ]"
:data-testid="option.name" :data-testid="option.name"
@click="onClick(option.name)" @click="onClick(option.name)"
> >
<div class="flex gap-2 items-center"> <div class="flex gap-2 items-center">
<component :is="option.icon" class="w-4 h-4" :class="isDisabledUIType(option.name) ? '!text-gray-400' : 'text-gray-700' "/> <component
:is="option.icon"
class="w-4 h-4"
:class="isDisabledUIType(option.name) ? '!text-gray-400' : 'text-gray-700'"
/>
<div class="flex-1 text-sm">{{ UITypesName[option.name] }}</div> <div class="flex-1 text-sm">{{ UITypesName[option.name] }}</div>
<span v-if="option.deprecated" class="!text-xs !text-gray-300">({{ $t('general.deprecated') }})</span> <span v-if="option.deprecated" class="!text-xs !text-gray-300">({{ $t('general.deprecated') }})</span>
</div> </div>

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

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { ColumnReqType } from 'nocodb-sdk' import { type ColumnReqType, readonlyMetaAllowedTypes } from 'nocodb-sdk'
import { PlanLimitTypes, RelationTypes, UITypes, isLinksOrLTAR, isSystemColumn } from 'nocodb-sdk' import { PlanLimitTypes, RelationTypes, UITypes, isLinksOrLTAR, isSystemColumn } from 'nocodb-sdk'
import { SmartsheetStoreEvents } from '#imports' import { SmartsheetStoreEvents } from '#imports'
@ -43,7 +43,7 @@ const { gridViewCols } = useViewColumnsOrThrow()
const { fieldsToGroupBy, groupByLimit } = useViewGroupByOrThrow(view) const { fieldsToGroupBy, groupByLimit } = useViewGroupByOrThrow(view)
const { isUIAllowed } = useRoles() const { isUIAllowed, isMetaReadOnly } = useRoles()
const isLoading = ref<'' | 'hideOrShow' | 'setDisplay'>('') const isLoading = ref<'' | 'hideOrShow' | 'setDisplay'>('')
@ -354,6 +354,11 @@ const filterOrGroupByThisField = (event: SmartsheetStoreEvents) => {
} }
isOpen.value = false isOpen.value = false
} }
const isColumnCRUDAllowed = computed(() => {
if (isMetaReadOnly.value && !readonlyMetaAllowedTypes.includes(column.value?.uidt)) return false
return true
})
</script> </script>
<template> <template>
@ -376,7 +381,11 @@ const filterOrGroupByThisField = (event: SmartsheetStoreEvents) => {
'min-w-[256px]': isExpandedForm, 'min-w-[256px]': isExpandedForm,
}" }"
> >
<NcMenuItem v-if="isUIAllowed('fieldAlter')" :disabled="column?.pk || isSystemColumn(column)" @click="onEditPress"> <NcMenuItem
v-if="isUIAllowed('fieldAlter') && isColumnCRUDAllowed"
:disabled="column?.pk || isSystemColumn(column)"
@click="onEditPress"
>
<div class="nc-column-edit nc-header-menu-item"> <div class="nc-column-edit nc-header-menu-item">
<component :is="iconMap.ncEdit" class="text-gray-700" /> <component :is="iconMap.ncEdit" class="text-gray-700" />
<!-- Edit --> <!-- Edit -->
@ -471,13 +480,15 @@ const filterOrGroupByThisField = (event: SmartsheetStoreEvents) => {
<NcTooltip <NcTooltip
:disabled="(isGroupBySupported && !isGroupByLimitExceeded) || isGroupedByThisField || !(isEeUI && !isPublic)" :disabled="(isGroupBySupported && !isGroupByLimitExceeded) || isGroupedByThisField || !(isEeUI && !isPublic)"
> >
<template #title>{{ <template #title
>{{
!isGroupBySupported !isGroupBySupported
? "This field type doesn't support grouping" ? "This field type doesn't support grouping"
: isGroupByLimitExceeded : isGroupByLimitExceeded
? 'Group by limit exceeded' ? 'Group by limit exceeded'
: '' : ''
}}</template> }}
</template>
<NcMenuItem <NcMenuItem
:disabled="isEeUI && !isPublic && (!isGroupBySupported || isGroupByLimitExceeded) && !isGroupedByThisField" :disabled="isEeUI && !isPublic && (!isGroupBySupported || isGroupByLimitExceeded) && !isGroupedByThisField"
@click=" @click="
@ -521,7 +532,7 @@ const filterOrGroupByThisField = (event: SmartsheetStoreEvents) => {
<a-divider v-if="!column?.pv" class="!my-0" /> <a-divider v-if="!column?.pv" class="!my-0" />
<NcMenuItem <NcMenuItem
v-if="!column?.pv && isUIAllowed('fieldDelete')" v-if="!column?.pv && isUIAllowed('fieldDelete') && isColumnCRUDAllowed"
:disabled="!isDeleteAllowed" :disabled="!isDeleteAllowed"
class="!hover:bg-red-50" class="!hover:bg-red-50"
@click="handleDelete" @click="handleDelete"
@ -559,6 +570,7 @@ const filterOrGroupByThisField = (event: SmartsheetStoreEvents) => {
:deep(.ant-dropdown-menu-item:not(.ant-dropdown-menu-item-disabled)) { :deep(.ant-dropdown-menu-item:not(.ant-dropdown-menu-item-disabled)) {
@apply !hover:text-black text-gray-700; @apply !hover:text-black text-gray-700;
} }
:deep(.ant-dropdown-menu-item.ant-dropdown-menu-item-disabled .nc-icon) { :deep(.ant-dropdown-menu-item.ant-dropdown-menu-item-disabled .nc-icon) {
@apply text-current; @apply text-current;
} }

2
packages/nc-gui/components/smartsheet/toolbar/Calendar/Range.vue

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { type CalendarRangeType, UITypes, ViewTypes, isSystemColumn } from 'nocodb-sdk' import { type CalendarRangeType, UITypes, isSystemColumn } from 'nocodb-sdk'
import type { SelectProps } from 'ant-design-vue' import type { SelectProps } from 'ant-design-vue'
const meta = inject(MetaInj, ref()) const meta = inject(MetaInj, ref())

10
packages/nc-gui/composables/useRoles/index.ts

@ -185,10 +185,20 @@ export const useRoles = () => {
const currentSource = inject(ActiveSourceInj, ref()) const currentSource = inject(ActiveSourceInj, ref())
const useRolesRes = useRolesShared() const useRolesRes = useRolesShared()
const isMetaReadOnly = computed(() => {
return currentSource.value?.meta?.[SourceRestriction.META_READONLY] || false
})
const isDataReadOnly = computed(() => {
return currentSource.value?.meta?.[SourceRestriction.DATA_READONLY] || false
})
return { return {
...useRolesRes, ...useRolesRes,
isUIAllowed: (...args: IsUIAllowedParams) => { isUIAllowed: (...args: IsUIAllowedParams) => {
return useRolesRes.isUIAllowed(args[0], { source: currentSource, ...(args[1] || {}) }) return useRolesRes.isUIAllowed(args[0], { source: currentSource, ...(args[1] || {}) })
}, },
isDataReadOnly,
isMetaReadOnly,
} }
} }

1
packages/nc-gui/composables/useViewFilters.ts

@ -10,7 +10,6 @@ import type { ComputedRef, Ref } from 'vue'
import type { SelectProps } from 'ant-design-vue' import type { SelectProps } from 'ant-design-vue'
import { UITypes, isSystemColumn } from 'nocodb-sdk' import { UITypes, isSystemColumn } from 'nocodb-sdk'
type ColumnFilterType = FilterType & { status?: string; id?: string; children?: ColumnFilterType[]; is_group?: boolean } type ColumnFilterType = FilterType & { status?: string; id?: string; children?: ColumnFilterType[]; is_group?: boolean }
export function useViewFilters( export function useViewFilters(

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

@ -456,6 +456,8 @@
"looksLikeThisStackIsEmpty": "Looks like this stack does not have any records" "looksLikeThisStackIsEmpty": "Looks like this stack does not have any records"
}, },
"labels": { "labels": {
"allowMetaWrite" : "Allow Schema Change",
"allowDataWrite" : "Allow Data Write/Edit",
"selectView": "Select a View", "selectView": "Select a View",
"connectionDetails": "Connection Details", "connectionDetails": "Connection Details",
"metaSync": "Meta Sync", "metaSync": "Meta Sync",
@ -1038,6 +1040,8 @@
"group": "Group" "group": "Group"
}, },
"tooltip": { "tooltip": {
"allowMetaWrite": "Enable this option to allow modifications to the database schema, including adding, altering, or deleting tables and columns. Use with caution, as changes may affect application functionality.",
"allowDataWrite": "Enable this option to allow updating, deleting, or inserting data within the database tables. Ideal for administrative users who need to manage data directly.",
"reachedSourceLimit": "Limited to only one data source for the moment", "reachedSourceLimit": "Limited to only one data source for the moment",
"saveChanges": "Save changes", "saveChanges": "Save changes",
"xcDB": "Create a new base", "xcDB": "Create a new base",

Loading…
Cancel
Save