fix(editor): table block readonly support (#10224)

close: BS-2597
This commit is contained in:
zzj3720
2025-02-17 10:19:00 +00:00
parent 29d8824479
commit e4f2223a2a
4 changed files with 32 additions and 18 deletions
@@ -29,6 +29,9 @@ export class SelectionController implements ReactiveController {
this.host.addController(this); this.host.addController(this);
} }
hostConnected() { hostConnected() {
if (this.dataManager.readonly$.value) {
return;
}
this.dragListener(); this.dragListener();
this.host.handleEvent('copy', this.onCopy); this.host.handleEvent('copy', this.onCopy);
this.host.handleEvent('cut', this.onCut); this.host.handleEvent('cut', this.onCut);
@@ -340,7 +343,6 @@ export class SelectionController implements ReactiveController {
}; };
onCopy = () => { onCopy = () => {
const selection = this.getSelected(); const selection = this.getSelected();
console.log('selection', selection);
if (!selection || selection.type !== 'area') { if (!selection || selection.type !== 'area') {
return false; return false;
} }
@@ -171,7 +171,7 @@ export class TableBlockComponent extends CaptionedBlockComponent<TableBlockModel
} }
)} )}
</tbody> </tbody>
${IS_MOBILE ${IS_MOBILE || this.dataManager.readonly$.value
? nothing ? nothing
: html`<affine-table-add-button : html`<affine-table-add-button
style="display: contents;" style="display: contents;"
@@ -68,8 +68,9 @@ export class TableCell extends SignalWatcher(
@property({ attribute: false }) @property({ attribute: false })
accessor text: Text | undefined = undefined; accessor text: Text | undefined = undefined;
@property({ type: Boolean }) get readonly() {
accessor readonly = false; return this.dataManager.readonly$.value;
}
@property({ attribute: false }) @property({ attribute: false })
accessor dataManager!: TableDataManager; accessor dataManager!: TableDataManager;
@@ -644,6 +645,9 @@ export class TableCell extends SignalWatcher(
override connectedCallback() { override connectedCallback() {
super.connectedCallback(); super.connectedCallback();
if (this.readonly) {
return;
}
const selectAll = (e: KeyboardEvent) => { const selectAll = (e: KeyboardEvent) => {
if (e.key === 'a' && (IS_MAC ? e.metaKey : e.ctrlKey)) { if (e.key === 'a' && (IS_MAC ? e.metaKey : e.ctrlKey)) {
e.stopPropagation(); e.stopPropagation();
@@ -666,6 +670,9 @@ export class TableCell extends SignalWatcher(
} }
override firstUpdated() { override firstUpdated() {
if (this.readonly) {
return;
}
this.richText$.value?.updateComplete this.richText$.value?.updateComplete
.then(() => { .then(() => {
this.disposables.add( this.disposables.add(
@@ -1,40 +1,45 @@
import type { TableBlockModel, TableCell } from '@blocksuite/affine-model'; import type { TableBlockModel, TableCell } from '@blocksuite/affine-model';
import { generateFractionalIndexingKeyBetween } from '@blocksuite/affine-shared/utils'; import { generateFractionalIndexingKeyBetween } from '@blocksuite/affine-shared/utils';
import { nanoid, Text } from '@blocksuite/store'; import { nanoid, Text } from '@blocksuite/store';
import { computed, signal } from '@preact/signals-core'; import { computed, type ReadonlySignal, signal } from '@preact/signals-core';
import type { TableAreaSelection } from './selection-schema'; import type { TableAreaSelection } from './selection-schema';
export class TableDataManager { export class TableDataManager {
constructor(private readonly model: TableBlockModel) {} constructor(private readonly model: TableBlockModel) {}
ui = { readonly readonly$: ReadonlySignal<boolean> = computed(() => {
return this.model.doc.readonly;
});
readonly ui = {
columnIndicatorIndex$: signal<number>(), columnIndicatorIndex$: signal<number>(),
rowIndicatorIndex$: signal<number>(), rowIndicatorIndex$: signal<number>(),
}; };
hoverColumnIndex$ = signal<number>(); readonly hoverColumnIndex$ = signal<number>();
hoverRowIndex$ = signal<number>(); readonly hoverRowIndex$ = signal<number>();
hoverDragHandleColumnId$ = signal<string>(); readonly hoverDragHandleColumnId$ = signal<string>();
widthAdjustColumnId$ = signal<string>(); readonly widthAdjustColumnId$ = signal<string>();
virtualColumnCount$ = signal<number>(0); readonly virtualColumnCount$ = signal<number>(0);
virtualRowCount$ = signal<number>(0); readonly virtualRowCount$ = signal<number>(0);
virtualWidth$ = signal<{ columnId: string; width: number } | undefined>(); readonly virtualWidth$ = signal<
cellCountTips$ = computed( { columnId: string; width: number } | undefined
>();
readonly cellCountTips$ = computed(
() => () =>
`${this.virtualRowCount$.value + this.rows$.value.length} x ${this.virtualColumnCount$.value + this.columns$.value.length}` `${this.virtualRowCount$.value + this.rows$.value.length} x ${this.virtualColumnCount$.value + this.columns$.value.length}`
); );
rows$ = computed(() => { readonly rows$ = computed(() => {
return Object.values(this.model.props.rows$.value).sort((a, b) => return Object.values(this.model.props.rows$.value).sort((a, b) =>
a.order > b.order ? 1 : -1 a.order > b.order ? 1 : -1
); );
}); });
columns$ = computed(() => { readonly columns$ = computed(() => {
return Object.values(this.model.props.columns$.value).sort((a, b) => return Object.values(this.model.props.columns$.value).sort((a, b) =>
a.order > b.order ? 1 : -1 a.order > b.order ? 1 : -1
); );
}); });
uiRows$ = computed(() => { readonly uiRows$ = computed(() => {
const virtualRowCount = this.virtualRowCount$.value; const virtualRowCount = this.virtualRowCount$.value;
const rows = this.rows$.value; const rows = this.rows$.value;
if (virtualRowCount === 0) { if (virtualRowCount === 0) {
@@ -52,7 +57,7 @@ export class TableDataManager {
return rows.slice(0, rows.length + virtualRowCount); return rows.slice(0, rows.length + virtualRowCount);
}); });
uiColumns$ = computed(() => { readonly uiColumns$ = computed(() => {
const virtualColumnCount = this.virtualColumnCount$.value; const virtualColumnCount = this.virtualColumnCount$.value;
const columns = this.columns$.value; const columns = this.columns$.value;
if (virtualColumnCount === 0) { if (virtualColumnCount === 0) {