diff --git a/packages/nc-gui/components/cell/DatePicker.vue b/packages/nc-gui/components/cell/DatePicker.vue
index f3287edb01..abf01f6584 100644
--- a/packages/nc-gui/components/cell/DatePicker.vue
+++ b/packages/nc-gui/components/cell/DatePicker.vue
@@ -185,6 +185,14 @@ useSelectedCellKeyupListener(active, (e: KeyboardEvent) => {
}
})
+const isOpen = computed(() => {
+ if (readOnly.value) return false
+
+ return ((readOnly.value || (localState.value && isPk)) && !active.value && !editable.value) || isLockedMode.value
+ ? false
+ : open.value
+})
+
// use the default date picker open sync only to close the picker
const updateOpen = (next: boolean) => {
if (open.value && !next) {
@@ -222,7 +230,7 @@ const clickHandler = () => {
:allow-clear="!readOnly && !localState && !isPk"
:input-read-only="true"
:dropdown-class-name="`${randomClass} nc-picker-date ${open ? 'active' : ''}`"
- :open="((readOnly || (localState && isPk)) && !active && !editable) || isLockedMode ? false : open"
+ :open="isOpen"
@click="clickHandler"
@update:open="updateOpen"
>
diff --git a/packages/nc-gui/components/cell/DateTimePicker.vue b/packages/nc-gui/components/cell/DateTimePicker.vue
index a7f816c720..11ccba81b6 100644
--- a/packages/nc-gui/components/cell/DateTimePicker.vue
+++ b/packages/nc-gui/components/cell/DateTimePicker.vue
@@ -123,6 +123,14 @@ const localState = computed({
const open = ref(false)
+const isOpen = computed(() => {
+ if (readOnly.value) return false
+
+ return readOnly.value || (localState.value && isPk) || isLockedMode.value
+ ? false
+ : open.value && (active.value || editable.value)
+})
+
const randomClass = `picker_${Math.floor(Math.random() * 99999)}`
watch(
open,
@@ -270,7 +278,7 @@ const isColDisabled = computed(() => {
:allow-clear="!readOnly && !localState && !isPk"
:input-read-only="true"
:dropdown-class-name="`${randomClass} nc-picker-datetime ${open ? 'active' : ''}`"
- :open="readOnly || (localState && isPk) || isLockedMode ? false : open && (active || editable)"
+ :open="isOpen"
@click="clickHandler"
@ok="open = !open"
>
diff --git a/packages/nc-gui/components/cell/TimePicker.vue b/packages/nc-gui/components/cell/TimePicker.vue
index 257d1d7cf1..89a076541f 100644
--- a/packages/nc-gui/components/cell/TimePicker.vue
+++ b/packages/nc-gui/components/cell/TimePicker.vue
@@ -101,6 +101,12 @@ const placeholder = computed(() => {
}
})
+const isOpen = computed(() => {
+ if (readOnly.value) return false
+
+ return (readOnly.value || (localState.value && isPk)) && !active.value && !editable.value ? false : open.value
+})
+
useSelectedCellKeyupListener(active, (e: KeyboardEvent) => {
switch (e.key) {
case 'Enter':
@@ -129,7 +135,7 @@ useSelectedCellKeyupListener(active, (e: KeyboardEvent) => {
:placeholder="placeholder"
:allow-clear="!readOnly && !localState && !isPk"
:input-read-only="true"
- :open="(readOnly || (localState && isPk)) && !active && !editable ? false : open"
+ :open="isOpen"
:popup-class-name="`${randomClass} nc-picker-time ${open ? 'active' : ''}`"
@click="open = (active || editable) && !open"
@ok="open = !open"
diff --git a/packages/nc-gui/components/cell/YearPicker.vue b/packages/nc-gui/components/cell/YearPicker.vue
index b2204fff9f..f5c5c80709 100644
--- a/packages/nc-gui/components/cell/YearPicker.vue
+++ b/packages/nc-gui/components/cell/YearPicker.vue
@@ -88,6 +88,12 @@ const placeholder = computed(() => {
}
})
+const isOpen = computed(() => {
+ if (readOnly.value) return false
+
+ return (readOnly.value || (localState.value && isPk)) && !active.value && !editable.value ? false : open.value
+})
+
useSelectedCellKeyupListener(active, (e: KeyboardEvent) => {
switch (e.key) {
case 'Enter':
@@ -114,7 +120,7 @@ useSelectedCellKeyupListener(active, (e: KeyboardEvent) => {
:placeholder="placeholder"
:allow-clear="(!readOnly && !localState && !isPk) || isEditColumn"
:input-read-only="true"
- :open="(readOnly || (localState && isPk)) && !active && !editable ? false : open"
+ :open="isOpen"
:dropdown-class-name="`${randomClass} nc-picker-year ${open ? 'active' : ''}`"
@click="open = (active || editable) && !open"
@change="open = (active || editable) && !open"
diff --git a/packages/nc-gui/components/smartsheet/grid/Table.vue b/packages/nc-gui/components/smartsheet/grid/Table.vue
index e12620dd12..79871ce31c 100644
--- a/packages/nc-gui/components/smartsheet/grid/Table.vue
+++ b/packages/nc-gui/components/smartsheet/grid/Table.vue
@@ -181,7 +181,7 @@ const gridRect = useElementBounding(gridWrapper)
// #Permissions
const { isUIAllowed } = useRoles()
-const hasEditPermission = computed(() => isUIAllowed('dataEdit'))
+const hasEditPermission = computed(() => isUIAllowed('dataEdit') && !isLocked.value)
const isAddingColumnAllowed = computed(() => !readOnly.value && !isLocked.value && isUIAllowed('fieldAdd') && !isSqlView.value)
const { onDrag, onDragStart, draggedCol, dragColPlaceholderDomRef, toBeDroppedColId } = useColumnDrag({
@@ -223,9 +223,7 @@ const _contextMenu = ref(false)
const contextMenu = computed({
get: () => _contextMenu.value,
set: (val) => {
- if (hasEditPermission.value) {
- _contextMenu.value = val
- }
+ _contextMenu.value = val
},
})
const contextMenuClosing = ref(false)
@@ -1549,14 +1547,12 @@ onKeyStroke('ArrowDown', onDown)
@@ -1608,7 +1604,7 @@ onKeyStroke('ArrowDown', onDown)
"
:row-index="rowIndex"
:active="activeCell.col === colIndex && activeCell.row === rowIndex"
- :read-only="readOnly"
+ :read-only="!hasEditPermission"
@update:edit-enabled="editEnabled = $event"
@save="updateOrSaveRow?.(row, columnObj.title, state)"
@navigate="onNavigate"
@@ -1658,7 +1654,7 @@ onKeyStroke('ArrowDown', onDown)
/>
-
+
diff --git a/packages/nc-gui/composables/useMultiSelect/index.ts b/packages/nc-gui/composables/useMultiSelect/index.ts
index 86ee0f8326..664601fd3c 100644
--- a/packages/nc-gui/composables/useMultiSelect/index.ts
+++ b/packages/nc-gui/composables/useMultiSelect/index.ts
@@ -116,6 +116,8 @@ export function useMultiSelect(
if (typeof textToCopy === 'object') {
textToCopy = JSON.stringify(textToCopy)
+ } else {
+ textToCopy = textToCopy.toString()
}
if (columnObj.uidt === UITypes.Formula) {
diff --git a/tests/playwright/pages/Dashboard/common/Cell/index.ts b/tests/playwright/pages/Dashboard/common/Cell/index.ts
index c24c5da97e..1e35e1622a 100644
--- a/tests/playwright/pages/Dashboard/common/Cell/index.ts
+++ b/tests/playwright/pages/Dashboard/common/Cell/index.ts
@@ -381,25 +381,25 @@ export class CellPageObject extends BasePage {
async verifyRoleAccess(param: { role: string }) {
const role = param.role.toLowerCase();
- const count = role === 'creator' || role === 'editor' || role === 'owner' ? 1 : 0;
+ const isEditAccess = role === 'creator' || role === 'editor' || role === 'owner';
// normal text cell
const cell = this.get({ index: 0, columnHeader: 'Country' });
// editable cell
await cell.dblclick();
- await expect(cell.locator(`input`)).toHaveCount(count);
+ await expect(cell.locator(`input`)).toHaveCount(isEditAccess ? 1 : 0);
// press escape to close the input
await cell.press('Escape');
await cell.press('Escape');
await cell.click({ button: 'right', clickCount: 1 });
- await expect(this.rootPage.locator(`.nc-dropdown-grid-context-menu:visible`)).toHaveCount(count);
+ await expect(this.rootPage.locator(`.nc-dropdown-grid-context-menu:visible`)).toHaveCount(1);
// virtual cell
const vCell = this.get({ index: 0, columnHeader: 'Cities' });
await vCell.hover();
// in-cell add
- await expect(vCell.locator('.nc-action-icon.nc-plus:visible')).toHaveCount(count);
+ await expect(vCell.locator('.nc-action-icon.nc-plus:visible')).toHaveCount(isEditAccess ? 1 : 0);
// virtual cell link text
const linkText = await getTextExcludeIconText(vCell);