mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-24 05:48:59 +08:00
refactor(editor): enable the noUncheckedIndexedAccess rule for the data-view package (#9351)
close: BS-2230
This commit is contained in:
@@ -53,6 +53,12 @@ export const kanbanViewModel = kanbanViewType.createModel<KanbanViewData>({
|
||||
return 1;
|
||||
};
|
||||
const columnId = allowList.sort((a, b) => getWeight(b) - getWeight(a))[0];
|
||||
if (!columnId) {
|
||||
throw new BlockSuiteError(
|
||||
ErrorCode.DatabaseBlockError,
|
||||
'no groupable column found'
|
||||
);
|
||||
}
|
||||
const type = viewManager.dataSource.propertyTypeGet(columnId);
|
||||
const meta = type && viewManager.dataSource.propertyMetaGet(type);
|
||||
const data = viewManager.dataSource.propertyDataGet(columnId);
|
||||
|
||||
@@ -285,6 +285,9 @@ export class KanbanSingleView extends SingleViewBase<KanbanViewData> {
|
||||
}
|
||||
const columns = [...view.columns];
|
||||
const [column] = columns.splice(columnIndex, 1);
|
||||
if (!column) {
|
||||
return {};
|
||||
}
|
||||
const index = insertPositionToIndex(toAfterOfColumn, columns);
|
||||
columns.splice(index, 0, column);
|
||||
return {
|
||||
@@ -297,12 +300,12 @@ export class KanbanSingleView extends SingleViewBase<KanbanViewData> {
|
||||
this.dataSource.rowMove(rowId, position);
|
||||
}
|
||||
|
||||
override rowNextGet(rowId: string): string {
|
||||
override rowNextGet(rowId: string): string | undefined {
|
||||
const index = this.rows$.value.indexOf(rowId);
|
||||
return this.rows$.value[index + 1];
|
||||
}
|
||||
|
||||
override rowPrevGet(rowId: string): string {
|
||||
override rowPrevGet(rowId: string): string | undefined {
|
||||
const index = this.rows$.value.indexOf(rowId);
|
||||
return this.rows$.value[index - 1];
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ export class KanbanSelectionController implements ReactiveController {
|
||||
if (selection.selectionType === 'card') {
|
||||
const card = getSelectedCards(this.host, selection)[0];
|
||||
const cell = card?.querySelector('affine-data-view-kanban-cell');
|
||||
if (cell) {
|
||||
if (card && cell) {
|
||||
this.selection = {
|
||||
groupKey: card.groupKey,
|
||||
cardId: card.cardId,
|
||||
@@ -209,11 +209,9 @@ export class KanbanSelectionController implements ReactiveController {
|
||||
const index = kanbanCells.findIndex(
|
||||
cell => cell.column.id === selection.columnId
|
||||
);
|
||||
const { cell, cardId, groupKey } = this.getNextFocusCell(
|
||||
selection,
|
||||
index,
|
||||
position
|
||||
);
|
||||
const result = this.getNextFocusCell(selection, index, position);
|
||||
if (!result) return;
|
||||
const { cell, cardId, groupKey } = result;
|
||||
if (cell instanceof KanbanCell) {
|
||||
this.selection = {
|
||||
...selection,
|
||||
@@ -234,7 +232,9 @@ export class KanbanSelectionController implements ReactiveController {
|
||||
const index = cardElements.findIndex(
|
||||
card => card.cardId === selection.cards[0].cardId
|
||||
);
|
||||
const { card, cards } = this.getNextFocusCard(selection, index, position);
|
||||
const result = this.getNextFocusCard(selection, index, position);
|
||||
if (!result) return;
|
||||
const { card, cards } = result;
|
||||
if (card instanceof KanbanCard) {
|
||||
const newCards = cards ?? selection.cards;
|
||||
this.selection = atLeastOne(newCards)
|
||||
@@ -286,10 +286,12 @@ export class KanbanSelectionController implements ReactiveController {
|
||||
selection: KanbanCardSelection,
|
||||
index: number,
|
||||
nextPosition: 'up' | 'down' | 'left' | 'right'
|
||||
): {
|
||||
card: KanbanCard;
|
||||
cards: KanbanCardSelectionCard[];
|
||||
} {
|
||||
):
|
||||
| {
|
||||
card: KanbanCard;
|
||||
cards: KanbanCardSelectionCard[];
|
||||
}
|
||||
| undefined {
|
||||
const group = this.host.querySelector(
|
||||
`affine-data-view-kanban-group[data-key="${selection.cards[0].groupKey}"]`
|
||||
);
|
||||
@@ -301,7 +303,7 @@ export class KanbanSelectionController implements ReactiveController {
|
||||
const nextIndex = index - 1;
|
||||
const nextCardIndex = nextIndex < 0 ? kanbanCards.length - 1 : nextIndex;
|
||||
const card = kanbanCards[nextCardIndex];
|
||||
|
||||
if (!card) return;
|
||||
return {
|
||||
card,
|
||||
cards: [
|
||||
@@ -317,7 +319,7 @@ export class KanbanSelectionController implements ReactiveController {
|
||||
const nextIndex = index + 1;
|
||||
const nextCardIndex = nextIndex > kanbanCards.length - 1 ? 0 : nextIndex;
|
||||
const card = kanbanCards[nextCardIndex];
|
||||
|
||||
if (!card) return;
|
||||
return {
|
||||
card,
|
||||
cards: [
|
||||
@@ -360,11 +362,13 @@ export class KanbanSelectionController implements ReactiveController {
|
||||
selection: KanbanCellSelection,
|
||||
index: number,
|
||||
nextPosition: 'up' | 'down' | 'left' | 'right'
|
||||
): {
|
||||
cell: KanbanCell;
|
||||
cardId?: string;
|
||||
groupKey?: string;
|
||||
} {
|
||||
):
|
||||
| {
|
||||
cell: KanbanCell;
|
||||
cardId?: string;
|
||||
groupKey?: string;
|
||||
}
|
||||
| undefined {
|
||||
const kanbanCells = getCardCellsBySelection(this.host, selection);
|
||||
const group = this.host.querySelector(
|
||||
`affine-data-view-kanban-group[data-key="${selection.groupKey}"]`
|
||||
@@ -384,11 +388,14 @@ export class KanbanSelectionController implements ReactiveController {
|
||||
cardIndex => (cardIndex === 0 ? cards.length - 1 : cardIndex - 1)
|
||||
);
|
||||
} else {
|
||||
const cell = kanbanCells[kanbanCells.length - 1];
|
||||
if (!cell) return;
|
||||
return {
|
||||
cell: kanbanCells[kanbanCells.length - 1],
|
||||
cell,
|
||||
};
|
||||
}
|
||||
}
|
||||
if (!kanbanCells[nextIndex]) return;
|
||||
return {
|
||||
cell: kanbanCells[nextIndex],
|
||||
};
|
||||
@@ -405,11 +412,14 @@ export class KanbanSelectionController implements ReactiveController {
|
||||
cardIndex => (cardIndex === cards.length - 1 ? 0 : cardIndex + 1)
|
||||
);
|
||||
} else {
|
||||
const cell = kanbanCells[0];
|
||||
if (!cell) return;
|
||||
return {
|
||||
cell: kanbanCells[0],
|
||||
cell,
|
||||
};
|
||||
}
|
||||
}
|
||||
if (!kanbanCells[nextIndex]) return;
|
||||
return {
|
||||
cell: kanbanCells[nextIndex],
|
||||
};
|
||||
@@ -569,19 +579,19 @@ function getNextGroupFocusElement(
|
||||
groups: KanbanGroup[],
|
||||
selection: KanbanCellSelection,
|
||||
getNextGroupIndex: (groupIndex: number) => number
|
||||
): NextFocusCell;
|
||||
): NextFocusCell | undefined;
|
||||
function getNextGroupFocusElement(
|
||||
viewElement: Element,
|
||||
groups: KanbanGroup[],
|
||||
selection: KanbanCardSelection,
|
||||
getNextGroupIndex: (groupIndex: number) => number
|
||||
): NextFocusCard;
|
||||
): NextFocusCard | undefined;
|
||||
function getNextGroupFocusElement(
|
||||
viewElement: Element,
|
||||
groups: KanbanGroup[],
|
||||
selection: KanbanCellSelection | KanbanCardSelection,
|
||||
getNextGroupIndex: (groupIndex: number) => number
|
||||
): NextFocusCell | NextFocusCard {
|
||||
): NextFocusCell | NextFocusCard | undefined {
|
||||
const groupIndex = groups.findIndex(group => {
|
||||
if (selection.selectionType === 'cell') {
|
||||
return group.group.key === selection.groupKey;
|
||||
@@ -591,10 +601,11 @@ function getNextGroupFocusElement(
|
||||
|
||||
let nextGroupIndex = getNextGroupIndex(groupIndex);
|
||||
let nextGroup = groups[nextGroupIndex];
|
||||
while (nextGroup.group.rows.length === 0) {
|
||||
while (nextGroup?.group.rows.length === 0) {
|
||||
nextGroupIndex = getNextGroupIndex(nextGroupIndex);
|
||||
nextGroup = groups[nextGroupIndex];
|
||||
}
|
||||
if (!nextGroup) return;
|
||||
|
||||
const element =
|
||||
selection.selectionType === 'cell'
|
||||
@@ -621,6 +632,7 @@ function getNextGroupFocusElement(
|
||||
});
|
||||
const nextCard = nextCards[cardPos.index];
|
||||
|
||||
if (!nextCard) return;
|
||||
if (selection.selectionType === 'card') {
|
||||
return {
|
||||
card: nextCard,
|
||||
@@ -652,6 +664,7 @@ function getNextGroupFocusElement(
|
||||
});
|
||||
const nextCell = cells[cellPos.index];
|
||||
|
||||
if (!nextCell) return;
|
||||
return {
|
||||
cell: nextCell,
|
||||
cardId: nextCard.cardId,
|
||||
@@ -664,17 +677,21 @@ function getNextCardFocusCell(
|
||||
cards: KanbanCard[],
|
||||
selection: KanbanCellSelection,
|
||||
getNextCardIndex: (cardIndex: number) => number
|
||||
): {
|
||||
cell: KanbanCell;
|
||||
cardId: string;
|
||||
} {
|
||||
):
|
||||
| {
|
||||
cell: KanbanCell;
|
||||
cardId: string;
|
||||
}
|
||||
| undefined {
|
||||
const cardIndex = cards.findIndex(card => card.cardId === selection.cardId);
|
||||
const nextCardIndex = getNextCardIndex(cardIndex);
|
||||
const nextCard = cards[nextCardIndex];
|
||||
if (!nextCard) return;
|
||||
const nextCells = Array.from(
|
||||
nextCard.querySelectorAll('affine-data-view-kanban-cell')
|
||||
);
|
||||
const nextCellIndex = nextPosition === 'up' ? nextCells.length - 1 : 0;
|
||||
if (!nextCells[nextCellIndex]) return;
|
||||
return {
|
||||
cell: nextCells[nextCellIndex],
|
||||
cardId: nextCard.cardId,
|
||||
|
||||
@@ -101,13 +101,15 @@ export class KanbanGroup extends SignalWatcher(
|
||||
requestAnimationFrame(() => {
|
||||
const kanban = this.closest('affine-data-view-kanban');
|
||||
if (kanban) {
|
||||
const columnId =
|
||||
this.view.mainProperties$.value.titleColumn ||
|
||||
this.view.propertyIds$.value[0];
|
||||
if (!columnId) return;
|
||||
kanban.selectionController.selection = {
|
||||
selectionType: 'cell',
|
||||
groupKey: this.group.key,
|
||||
cardId: id,
|
||||
columnId:
|
||||
this.view.mainProperties$.value.titleColumn ||
|
||||
this.view.propertyIds$.value[0],
|
||||
columnId,
|
||||
isEditing: true,
|
||||
};
|
||||
}
|
||||
@@ -119,13 +121,15 @@ export class KanbanGroup extends SignalWatcher(
|
||||
requestAnimationFrame(() => {
|
||||
const kanban = this.closest('affine-data-view-kanban');
|
||||
if (kanban) {
|
||||
const columnId =
|
||||
this.view.mainProperties$.value.titleColumn ||
|
||||
this.view.propertyIds$.value[0];
|
||||
if (!columnId) return;
|
||||
kanban.selectionController.selection = {
|
||||
selectionType: 'cell',
|
||||
groupKey: this.group.key,
|
||||
cardId: id,
|
||||
columnId:
|
||||
this.view.mainProperties$.value.titleColumn ||
|
||||
this.view.propertyIds$.value[0],
|
||||
columnId,
|
||||
isEditing: true,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -166,8 +166,8 @@ export class DataViewKanban extends DataViewBase<
|
||||
const activeId = evt.active.id;
|
||||
const groups = this.groupManager.groupsDataList$.value;
|
||||
if (over && over.id !== activeId && groups) {
|
||||
const activeIndex = groups.findIndex(data => data.key === activeId);
|
||||
const overIndex = groups.findIndex(data => data.key === over.id);
|
||||
const activeIndex = groups.findIndex(data => data?.key === activeId);
|
||||
const overIndex = groups.findIndex(data => data?.key === over.id);
|
||||
|
||||
this.groupManager.moveGroupTo(
|
||||
activeId,
|
||||
@@ -192,7 +192,11 @@ export class DataViewKanban extends DataViewBase<
|
||||
},
|
||||
],
|
||||
items: computed(() => {
|
||||
return this.groupManager.groupsDataList$.value?.map(v => v.key) ?? [];
|
||||
return (
|
||||
this.groupManager.groupsDataList$.value?.map(
|
||||
v => v?.key ?? 'default key'
|
||||
) ?? []
|
||||
);
|
||||
}),
|
||||
strategy: horizontalListSortingStrategy,
|
||||
});
|
||||
@@ -268,8 +272,9 @@ export class DataViewKanban extends DataViewBase<
|
||||
>
|
||||
${repeat(
|
||||
groups,
|
||||
group => group.key,
|
||||
group => group?.key ?? 'default key',
|
||||
group => {
|
||||
if (!group) return;
|
||||
return html` <affine-data-view-kanban-group
|
||||
${sortable(group.key)}
|
||||
data-key="${group.key}"
|
||||
|
||||
@@ -197,7 +197,7 @@ function getSelectedArea(
|
||||
const { rowsSelection, columnsSelection, groupKey } = selection;
|
||||
const data: SelectedArea = [];
|
||||
const rows = groupKey
|
||||
? view.groupTrait.groupDataMap$.value?.[groupKey].rows
|
||||
? view.groupTrait.groupDataMap$.value?.[groupKey]?.rows
|
||||
: view.rows$.value;
|
||||
const columns = view.propertyIds$.value;
|
||||
if (!rows) {
|
||||
@@ -208,8 +208,14 @@ function getSelectedArea(
|
||||
cells: [],
|
||||
};
|
||||
const rowId = rows[i];
|
||||
if (rowId == null) {
|
||||
continue;
|
||||
}
|
||||
for (let j = columnsSelection.start; j <= columnsSelection.end; j++) {
|
||||
const columnId = columns[j];
|
||||
if (columnId == null) {
|
||||
continue;
|
||||
}
|
||||
const cell = view.cellGet(rowId, columnId);
|
||||
row.cells.push(cell);
|
||||
}
|
||||
@@ -237,7 +243,7 @@ function getTargetRangeFromSelection(
|
||||
},
|
||||
column: {
|
||||
start: focus.columnIndex,
|
||||
length: data[0].length,
|
||||
length: data[0]?.length ?? 0,
|
||||
},
|
||||
}
|
||||
: {
|
||||
@@ -258,7 +264,7 @@ function pasteToCells(
|
||||
selection: TableAreaSelection
|
||||
) {
|
||||
const srcRowLength = rows.length;
|
||||
const srcColumnLength = rows[0].length;
|
||||
const srcColumnLength = rows[0]?.length ?? 0;
|
||||
const targetRange = getTargetRangeFromSelection(selection, rows);
|
||||
for (let i = 0; i < targetRange.row.length; i++) {
|
||||
for (let j = 0; j < targetRange.column.length; j++) {
|
||||
@@ -267,7 +273,7 @@ function pasteToCells(
|
||||
|
||||
const srcRowIndex = i % srcRowLength;
|
||||
const srcColumnIndex = j % srcColumnLength;
|
||||
const dataString = rows[srcRowIndex][srcColumnIndex];
|
||||
const dataString = rows[srcRowIndex]?.[srcColumnIndex];
|
||||
|
||||
const targetContainer = table.selectionController.getCellContainer(
|
||||
selection.groupKey,
|
||||
@@ -278,7 +284,7 @@ function pasteToCells(
|
||||
const columnId = targetContainer?.dataset.columnId;
|
||||
|
||||
if (rowId && columnId) {
|
||||
targetContainer?.column.valueSetFromString(rowId, dataString);
|
||||
targetContainer?.column.valueSetFromString(rowId, dataString ?? '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,7 +333,8 @@ export class TableHotkeysController implements ReactiveController {
|
||||
this.selectionController.selection = TableRowSelection.create({
|
||||
rows:
|
||||
this.host.props.view.groupTrait.groupsDataList$.value?.flatMap(
|
||||
group => group.rows.map(id => ({ groupKey: group.key, id }))
|
||||
group =>
|
||||
group?.rows.map(id => ({ groupKey: group.key, id })) ?? []
|
||||
) ??
|
||||
this.host.props.view.rows$.value.map(id => ({
|
||||
groupKey: undefined,
|
||||
|
||||
@@ -234,7 +234,7 @@ export class TableSelectionController implements ReactiveController {
|
||||
}
|
||||
const rows =
|
||||
groupKey != null
|
||||
? this.view.groupTrait.groupDataMap$.value?.[groupKey].rows
|
||||
? this.view.groupTrait.groupDataMap$.value?.[groupKey]?.rows
|
||||
: this.view.rows$.value;
|
||||
requestAnimationFrame(() => {
|
||||
const index = this.host.props.view.properties$.value.findIndex(
|
||||
@@ -285,7 +285,8 @@ export class TableSelectionController implements ReactiveController {
|
||||
length: selection.rowsSelection.end - selection.rowsSelection.start + 1,
|
||||
})
|
||||
.map((_, index) => index + selection.rowsSelection.start)
|
||||
.map(row => rows[row]?.rowId);
|
||||
.map(row => rows[row]?.rowId)
|
||||
.filter((id): id is string => id != null);
|
||||
return ids.map(id => ({ id, groupKey: selection.groupKey }));
|
||||
}
|
||||
|
||||
@@ -314,6 +315,7 @@ export class TableSelectionController implements ReactiveController {
|
||||
};
|
||||
for (let i = 0; i < rowOffsets.length; i++) {
|
||||
const offset = rowOffsets[i];
|
||||
if (offset == null) continue;
|
||||
if (offset < startY) {
|
||||
row.start = i;
|
||||
}
|
||||
@@ -323,6 +325,7 @@ export class TableSelectionController implements ReactiveController {
|
||||
}
|
||||
for (let i = 0; i < columnOffsets.length; i++) {
|
||||
const offset = columnOffsets[i];
|
||||
if (offset == null) continue;
|
||||
if (offset < startX) {
|
||||
column.start = i;
|
||||
}
|
||||
@@ -544,20 +547,21 @@ export class TableSelectionController implements ReactiveController {
|
||||
if (!TableRowSelection.is(this.selection)) return;
|
||||
const rows = this.selection.rows;
|
||||
const lastRow = rows[rows.length - 1];
|
||||
if (!lastRow) return;
|
||||
const lastRowIndex =
|
||||
(
|
||||
this.getGroup(lastRow.groupKey)?.querySelector(
|
||||
`data-view-table-row[data-row-id='${lastRow.id}']`
|
||||
this.getGroup(lastRow?.groupKey)?.querySelector(
|
||||
`data-view-table-row[data-row-id='${lastRow?.id}']`
|
||||
) as TableRow | null
|
||||
)?.rowIndex ?? 0;
|
||||
const getRowByIndex = (index: number) => {
|
||||
const tableRow = this.rows(lastRow.groupKey)?.item(index);
|
||||
const tableRow = this.rows(lastRow?.groupKey)?.item(index);
|
||||
if (!tableRow) {
|
||||
return;
|
||||
}
|
||||
return {
|
||||
id: tableRow.rowId,
|
||||
groupKey: lastRow.groupKey,
|
||||
groupKey: lastRow?.groupKey,
|
||||
};
|
||||
};
|
||||
const prevRow = getRowByIndex(lastRowIndex - 1);
|
||||
@@ -621,10 +625,15 @@ export class TableSelectionController implements ReactiveController {
|
||||
add.forEach(row => rows.add(key(row)));
|
||||
const result = [...rows]
|
||||
.map(r => r.split('.'))
|
||||
.map(([id, groupKey]) => ({
|
||||
id,
|
||||
groupKey: groupKey ? groupKey : undefined,
|
||||
}));
|
||||
.flatMap(([id, groupKey]) => {
|
||||
if (id == null) return [];
|
||||
return [
|
||||
{
|
||||
id,
|
||||
groupKey: groupKey ? groupKey : undefined,
|
||||
},
|
||||
];
|
||||
});
|
||||
this.selection = TableRowSelection.create({
|
||||
rows: result,
|
||||
});
|
||||
|
||||
@@ -79,6 +79,7 @@ export const popRowMenu = (
|
||||
return;
|
||||
}
|
||||
const row = selection.rows[0];
|
||||
if (!row) return;
|
||||
popFilterableSimpleMenu(ele, [
|
||||
menu.action({
|
||||
name: 'Expand Row',
|
||||
|
||||
@@ -94,12 +94,15 @@ export class DatabaseColumnStatsCell extends SignalWatcher(
|
||||
if (!groups[func.group]) {
|
||||
groups[func.group] = {};
|
||||
}
|
||||
const oldFunc = groups[func.group][func.type];
|
||||
const oldFunc = groups[func.group]?.[func.type];
|
||||
if (!oldFunc || typeSystem.unify(func.dataType, oldFunc.dataType)) {
|
||||
if (!func.impl) {
|
||||
delete groups[func.group][func.type];
|
||||
delete groups[func.group]?.[func.type];
|
||||
} else {
|
||||
groups[func.group][func.type] = func;
|
||||
const group = groups[func.group];
|
||||
if (group) {
|
||||
group[func.type] = func;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -306,6 +306,7 @@ export class TableSingleView extends SingleViewBase<TableViewData> {
|
||||
}
|
||||
const columns = [...this.computedColumns$.value];
|
||||
const [column] = columns.splice(columnIndex, 1);
|
||||
if (!column) return {};
|
||||
const index = insertPositionToIndex(toAfterOfColumn, columns);
|
||||
columns.splice(index, 0, column);
|
||||
return {
|
||||
@@ -356,12 +357,12 @@ export class TableSingleView extends SingleViewBase<TableViewData> {
|
||||
this.groupTrait.moveCardTo(rowId, fromGroup, toGroup, position);
|
||||
}
|
||||
|
||||
override rowNextGet(rowId: string): string {
|
||||
override rowNextGet(rowId: string): string | undefined {
|
||||
const index = this.rows$.value.indexOf(rowId);
|
||||
return this.rows$.value[index + 1];
|
||||
}
|
||||
|
||||
override rowPrevGet(rowId: string): string {
|
||||
override rowPrevGet(rowId: string): string | undefined {
|
||||
const index = this.rows$.value.indexOf(rowId);
|
||||
return this.rows$.value[index - 1];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user