refactor(editor): unify directories naming (#11516)

**Directory Structure Changes**

- Renamed multiple block-related directories by removing the "block-" prefix:
  - `block-attachment` → `attachment`
  - `block-bookmark` → `bookmark`
  - `block-callout` → `callout`
  - `block-code` → `code`
  - `block-data-view` → `data-view`
  - `block-database` → `database`
  - `block-divider` → `divider`
  - `block-edgeless-text` → `edgeless-text`
  - `block-embed` → `embed`
This commit is contained in:
Saul-Mirone
2025-04-07 12:34:40 +00:00
parent e1bd2047c4
commit 1f45cc5dec
893 changed files with 439 additions and 460 deletions
@@ -0,0 +1,240 @@
import type {
CellDataType,
ColumnDataType,
ColumnUpdater,
DatabaseBlockModel,
ViewBasicDataType,
} from '@blocksuite/affine-model';
import {
arrayMove,
insertPositionToIndex,
type InsertToPosition,
} from '@blocksuite/affine-shared/utils';
import type { BlockModel } from '@blocksuite/store';
export function addProperty(
model: DatabaseBlockModel,
position: InsertToPosition,
column: Omit<ColumnDataType, 'id'> & {
id?: string;
}
): string {
const id = column.id ?? model.doc.workspace.idGenerator();
if (model.props.columns.some(v => v.id === id)) {
return id;
}
model.doc.transact(() => {
const col: ColumnDataType = {
...column,
id,
};
model.props.columns.splice(
insertPositionToIndex(position, model.props.columns),
0,
col
);
});
return id;
}
export function copyCellsByProperty(
model: DatabaseBlockModel,
fromId: ColumnDataType['id'],
toId: ColumnDataType['id']
) {
model.doc.transact(() => {
Object.keys(model.props.cells).forEach(rowId => {
const cell = model.props.cells[rowId]?.[fromId];
if (cell && model.props.cells[rowId]) {
model.props.cells[rowId][toId] = {
...cell,
columnId: toId,
};
}
});
});
}
export function deleteColumn(
model: DatabaseBlockModel,
columnId: ColumnDataType['id']
) {
const index = model.props.columns.findIndex(v => v.id === columnId);
if (index < 0) return;
model.doc.transact(() => {
model.props.columns.splice(index, 1);
});
}
export function deleteRows(model: DatabaseBlockModel, rowIds: string[]) {
model.doc.transact(() => {
for (const rowId of rowIds) {
delete model.props.cells[rowId];
}
});
}
export function deleteView(model: DatabaseBlockModel, id: string) {
model.doc.captureSync();
model.doc.transact(() => {
model.props.views = model.props.views.filter(v => v.id !== id);
});
}
export function duplicateView(model: DatabaseBlockModel, id: string): string {
const newId = model.doc.workspace.idGenerator();
model.doc.transact(() => {
const index = model.props.views.findIndex(v => v.id === id);
const view = model.props.views[index];
if (view) {
model.props.views.splice(
index + 1,
0,
JSON.parse(JSON.stringify({ ...view, id: newId }))
);
}
});
return newId;
}
export function getCell(
model: DatabaseBlockModel,
rowId: BlockModel['id'],
columnId: ColumnDataType['id']
): CellDataType | null {
if (columnId === 'title') {
return {
columnId: 'title',
value: rowId,
};
}
const yRow = model.props.cells$.value[rowId];
const yCell = yRow?.[columnId] ?? null;
if (!yCell) return null;
return {
columnId: yCell.columnId,
value: yCell.value,
};
}
export function getProperty(
model: DatabaseBlockModel,
id: ColumnDataType['id']
): ColumnDataType | undefined {
return model.props.columns.find(v => v.id === id);
}
export function moveViewTo(
model: DatabaseBlockModel,
id: string,
position: InsertToPosition
) {
model.doc.transact(() => {
model.props.views = arrayMove(
model.props.views,
v => v.id === id,
arr => insertPositionToIndex(position, arr)
);
});
}
export function updateCell(
model: DatabaseBlockModel,
rowId: string,
cell: CellDataType
) {
model.doc.transact(() => {
const columnId = cell.columnId;
if (
rowId === '__proto__' ||
rowId === 'constructor' ||
rowId === 'prototype'
) {
console.error('Invalid rowId');
return;
}
if (
columnId === '__proto__' ||
columnId === 'constructor' ||
columnId === 'prototype'
) {
console.error('Invalid columnId');
return;
}
if (!model.props.cells[rowId]) {
model.props.cells[rowId] = Object.create(null);
}
if (model.props.cells[rowId]) {
model.props.cells[rowId][columnId] = {
columnId: columnId,
value: cell.value,
};
}
});
}
export function updateCells(
model: DatabaseBlockModel,
columnId: string,
cells: Record<string, unknown>
) {
model.doc.transact(() => {
Object.entries(cells).forEach(([rowId, value]) => {
if (
rowId === '__proto__' ||
rowId === 'constructor' ||
rowId === 'prototype'
) {
throw new Error('Invalid rowId');
}
if (!model.props.cells[rowId]) {
model.props.cells[rowId] = Object.create(null);
}
if (model.props.cells[rowId]) {
model.props.cells[rowId][columnId] = {
columnId,
value,
};
}
});
});
}
export function updateProperty(
model: DatabaseBlockModel,
id: string,
updater: ColumnUpdater,
defaultValue?: Record<string, unknown>
) {
const index = model.props.columns.findIndex(v => v.id === id);
if (index == null) {
return;
}
model.doc.transact(() => {
const column = model.props.columns[index];
if (!column) {
return;
}
const result = updater(column);
model.props.columns[index] = { ...defaultValue, ...column, ...result };
});
return id;
}
export const updateView = <ViewData extends ViewBasicDataType>(
model: DatabaseBlockModel,
id: string,
update: (data: ViewData) => Partial<ViewData>
) => {
model.doc.transact(() => {
model.props.views = model.props.views.map(v => {
if (v.id !== id) {
return v;
}
return { ...v, ...update(v as ViewData) };
});
});
};
export const DATABASE_CONVERT_WHITE_LIST = ['affine:list', 'affine:paragraph'];
@@ -0,0 +1,52 @@
import { z } from 'zod';
const currentViewListSchema = z.array(
z.object({
blockId: z.string(),
viewId: z.string(),
})
);
const maxLength = 20;
const currentViewListKey = 'blocksuite:databaseBlock:view:currentViewList';
const storage = globalThis.sessionStorage;
const createCurrentViewStorage = () => {
const getList = () => {
const string = storage?.getItem(currentViewListKey);
if (!string) {
return;
}
try {
const result = currentViewListSchema.safeParse(JSON.parse(string));
if (result.success) {
return result.data;
}
} catch {
// do nothing
}
return;
};
const saveList = () => {
storage.setItem(currentViewListKey, JSON.stringify(list));
};
const list = getList() ?? [];
return {
getCurrentView: (blockId: string) => {
return list.find(item => item.blockId === blockId)?.viewId;
},
setCurrentView: (blockId: string, viewId: string) => {
const configIndex = list.findIndex(item => item.blockId === blockId);
if (configIndex >= 0) {
list.splice(configIndex, 1);
}
if (list.length >= maxLength) {
list.pop();
}
list.unshift({ blockId, viewId });
saveList();
},
};
};
export const currentViewStorage = createCurrentViewStorage();
@@ -0,0 +1,30 @@
import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
import type { DeltaOperation, Text } from '@blocksuite/store';
export const getSingleDocIdFromText = (text?: Text) => {
const deltas = text?.deltas$.value;
if (!deltas) return;
let linkedDocId: string | undefined = undefined;
for (const delta of deltas) {
if (isLinkedDoc(delta)) {
if (linkedDocId) {
return;
}
linkedDocId = delta.attributes?.reference?.pageId as string;
} else if (delta.insert) {
return;
}
}
return linkedDocId;
};
export const isLinkedDoc = (delta: DeltaOperation) => {
const attributes: AffineTextAttributes | undefined = delta.attributes;
return attributes?.reference?.type === 'LinkedPage';
};
export const isPureText = (text?: Text): boolean => {
const deltas = text?.deltas$.value;
if (!deltas) return true;
return deltas.every(v => !isLinkedDoc(v));
};