diff --git a/packages/nc-gui/components/cell/DatePicker.vue b/packages/nc-gui/components/cell/DatePicker.vue
index d543d592c7..9fae66cc85 100644
--- a/packages/nc-gui/components/cell/DatePicker.vue
+++ b/packages/nc-gui/components/cell/DatePicker.vue
@@ -12,7 +12,7 @@ const emit = defineEmits(['update:modelValue'])
const columnMeta = inject(ColumnInj, null)!
-const readOnly = inject(ReadonlyInj, false)
+const readOnly = inject(ReadonlyInj, ref(false))
let isDateInvalid = $ref(false)
diff --git a/packages/nc-gui/components/cell/DateTimePicker.vue b/packages/nc-gui/components/cell/DateTimePicker.vue
index fb192cfc8c..d444494c8c 100644
--- a/packages/nc-gui/components/cell/DateTimePicker.vue
+++ b/packages/nc-gui/components/cell/DateTimePicker.vue
@@ -12,7 +12,7 @@ const emit = defineEmits(['update:modelValue'])
const { isMysql } = useProject()
-const readOnly = inject(ReadonlyInj, false)
+const readOnly = inject(ReadonlyInj, ref(false))
let isDateInvalid = $ref(false)
diff --git a/packages/nc-gui/components/cell/Text.vue b/packages/nc-gui/components/cell/Text.vue
index 832ddb7ff4..53e7aa02b1 100644
--- a/packages/nc-gui/components/cell/Text.vue
+++ b/packages/nc-gui/components/cell/Text.vue
@@ -1,6 +1,6 @@
+
+
+
+
+
+
diff --git a/packages/nc-gui/components/smartsheet/expanded-form/index.vue b/packages/nc-gui/components/smartsheet/expanded-form/index.vue
index 3dbb20469f..a3acbd571b 100644
--- a/packages/nc-gui/components/smartsheet/expanded-form/index.vue
+++ b/packages/nc-gui/components/smartsheet/expanded-form/index.vue
@@ -9,6 +9,8 @@ import {
MetaInj,
ReloadRowDataHookInj,
computedInject,
+ createEventHook,
+ inject,
message,
provide,
ref,
diff --git a/packages/nc-gui/components/tabs/Smartsheet.vue b/packages/nc-gui/components/tabs/Smartsheet.vue
index db6aad701d..392fa50c43 100644
--- a/packages/nc-gui/components/tabs/Smartsheet.vue
+++ b/packages/nc-gui/components/tabs/Smartsheet.vue
@@ -7,6 +7,7 @@ import {
IsLockedInj,
MetaInj,
OpenNewRecordFormHookInj,
+ ReadonlyInj,
ReloadViewDataHookInj,
ReloadViewMetaHookInj,
TabMetaInj,
@@ -18,6 +19,7 @@ import {
useMetas,
useProvideKanbanViewStore,
useProvideSmartsheetStore,
+ useUIPermission,
} from '#imports'
import type { TabItem } from '~/lib'
@@ -25,6 +27,8 @@ const props = defineProps<{
activeTab: TabItem
}>()
+const { isUIAllowed } = useUIPermission()
+
const { metas } = useMetas()
const activeTab = toRef(props, 'activeTab')
@@ -55,6 +59,10 @@ provide(OpenNewRecordFormHookInj, openNewRecordFormHook)
provide(FieldsInj, fields)
provide(IsFormInj, isForm)
provide(TabMetaInj, activeTab)
+provide(
+ ReadonlyInj,
+ computed(() => !isUIAllowed('xcDatatableEditable')),
+)
@@ -79,6 +87,8 @@ provide(TabMetaInj, activeTab)
+
+
diff --git a/packages/nc-gui/components/virtual-cell/BelongsTo.vue b/packages/nc-gui/components/virtual-cell/BelongsTo.vue
index e7f14fd3d4..8a2eaed14f 100644
--- a/packages/nc-gui/components/virtual-cell/BelongsTo.vue
+++ b/packages/nc-gui/components/virtual-cell/BelongsTo.vue
@@ -31,7 +31,7 @@ const row = inject(RowInj)!
const active = inject(ActiveCellInj)!
-const readOnly = inject(ReadonlyInj, false)
+const readOnly = inject(ReadonlyInj, ref(false))
const isForm = inject(IsFormInj, ref(false))
diff --git a/packages/nc-gui/components/virtual-cell/HasMany.vue b/packages/nc-gui/components/virtual-cell/HasMany.vue
index c4f063ea03..82d7cbbb06 100644
--- a/packages/nc-gui/components/virtual-cell/HasMany.vue
+++ b/packages/nc-gui/components/virtual-cell/HasMany.vue
@@ -27,7 +27,7 @@ const reloadRowTrigger = inject(ReloadRowDataHookInj, createEventHook())
const isForm = inject(IsFormInj)
-const readOnly = inject(ReadonlyInj, false)
+const readOnly = inject(ReadonlyInj, ref(false))
const isLocked = inject(IsLockedInj)
diff --git a/packages/nc-gui/components/virtual-cell/Lookup.vue b/packages/nc-gui/components/virtual-cell/Lookup.vue
index 5f2530d9f2..789ff99187 100644
--- a/packages/nc-gui/components/virtual-cell/Lookup.vue
+++ b/packages/nc-gui/components/virtual-cell/Lookup.vue
@@ -17,7 +17,7 @@ import {
const { metas, getMeta } = useMetas()
-provide(ReadonlyInj, true)
+provide(ReadonlyInj, ref(true))
const column = inject(ColumnInj)! as Ref
diff --git a/packages/nc-gui/components/virtual-cell/ManyToMany.vue b/packages/nc-gui/components/virtual-cell/ManyToMany.vue
index 30fdbe9f7f..3464471789 100644
--- a/packages/nc-gui/components/virtual-cell/ManyToMany.vue
+++ b/packages/nc-gui/components/virtual-cell/ManyToMany.vue
@@ -28,7 +28,7 @@ const reloadRowTrigger = inject(ReloadRowDataHookInj, createEventHook())
const isForm = inject(IsFormInj)
-const readOnly = inject(ReadonlyInj, false)
+const readOnly = inject(ReadonlyInj, ref(false))
const isLocked = inject(IsLockedInj)
diff --git a/packages/nc-gui/components/virtual-cell/components/ItemChip.vue b/packages/nc-gui/components/virtual-cell/components/ItemChip.vue
index fe11b08950..6665dd9187 100644
--- a/packages/nc-gui/components/virtual-cell/components/ItemChip.vue
+++ b/packages/nc-gui/components/virtual-cell/components/ItemChip.vue
@@ -1,5 +1,15 @@