mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-14 16:46:22 +08:00
refactor(editor): enable the noUncheckedIndexedAccess rule for the data-view package (#9351)
close: BS-2230
This commit is contained in:
@@ -56,7 +56,9 @@ export class Overflow extends SignalWatcher(WithDisposable(ShadowlessElement)) {
|
||||
|
||||
let width = 0;
|
||||
for (let i = 0; i < this.items.length; i++) {
|
||||
const itemWidth = this.items[i].getBoundingClientRect().width;
|
||||
const item = this.items[i];
|
||||
if (!item) continue;
|
||||
const itemWidth = item.getBoundingClientRect().width;
|
||||
// Try to calculate the width occupied by rendering n+1 items;
|
||||
// if it exceeds the limit, render n items(in i++ round).
|
||||
const totalWidth =
|
||||
|
||||
@@ -74,12 +74,13 @@ const selectTagColorPoll = selectOptionColors.map(color => color.color);
|
||||
|
||||
function tagColorHelper() {
|
||||
let colors = [...selectTagColorPoll];
|
||||
return () => {
|
||||
return (): string => {
|
||||
if (colors.length === 0) {
|
||||
colors = [...selectTagColorPoll];
|
||||
}
|
||||
const index = Math.floor(Math.random() * colors.length);
|
||||
const color = colors.splice(index, 1)[0];
|
||||
if (!color) return '';
|
||||
return color;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -243,7 +243,10 @@ export class MultiTagSelect extends SignalWatcher(
|
||||
event.stopPropagation();
|
||||
const inputValue = this.text.value.trim();
|
||||
if (event.key === 'Backspace' && inputValue === '') {
|
||||
this.tagManager.deleteTag(this.value.value[this.value.value.length - 1]);
|
||||
const lastId = this.value.value[this.value.value.length - 1];
|
||||
if (lastId) {
|
||||
this.tagManager.deleteTag(lastId);
|
||||
}
|
||||
} else if (event.key === 'Enter' && !event.isComposing) {
|
||||
this.selectedTag$.value?.select();
|
||||
} else if (event.key === 'ArrowUp') {
|
||||
|
||||
@@ -87,6 +87,9 @@ export class DataViewRenderer extends SignalWatcher(
|
||||
return;
|
||||
}
|
||||
const view = this.viewMap$.value[currentViewId];
|
||||
if (!view) {
|
||||
return;
|
||||
}
|
||||
return {
|
||||
view: view,
|
||||
selection$: computed(() => {
|
||||
|
||||
@@ -25,7 +25,7 @@ export const evalFilter = (
|
||||
for (let i = 0; i < expectArgLen; i++) {
|
||||
const argValue = evalValue(filter.args[i]);
|
||||
const argType = func.args[i];
|
||||
if (argValue == null) {
|
||||
if (argValue == null || argType == null) {
|
||||
return true;
|
||||
}
|
||||
if (!argType.valueValidate(argValue)) {
|
||||
|
||||
@@ -32,7 +32,7 @@ export type FilterConfig<
|
||||
) => boolean;
|
||||
defaultValue?: (args: {
|
||||
[K in keyof Args]: ValueTypeOf<ReplaceVar<Args[K], Vars>>;
|
||||
}) => ValueTypeOf<ReplaceVar<Self, Vars>>;
|
||||
}) => ValueTypeOf<ReplaceVar<Self, Vars>> | undefined;
|
||||
};
|
||||
type FindVar<
|
||||
Vars extends TypeVarDefinitionInstance[],
|
||||
|
||||
@@ -23,7 +23,13 @@ export const multiTagFilter = [
|
||||
}
|
||||
return value.some(v => self.includes(v));
|
||||
},
|
||||
defaultValue: args => [args[0][0]],
|
||||
defaultValue: args => {
|
||||
const value = args[0][0];
|
||||
if (value != null) {
|
||||
return [value];
|
||||
}
|
||||
return;
|
||||
},
|
||||
}),
|
||||
createFilter({
|
||||
name: 'doesNotContainOneOf',
|
||||
|
||||
@@ -28,6 +28,7 @@ export function generateDefaultValues(
|
||||
for (const [propertyId, conditions] of propertyConditions) {
|
||||
if (conditions.length === 1) {
|
||||
const condition = conditions[0];
|
||||
if (!condition) continue;
|
||||
const filterConfig = filterMatcher.getFilterByName(condition.function);
|
||||
if (filterConfig?.defaultValue) {
|
||||
const argValues = condition.args.map(arg => arg.value);
|
||||
|
||||
@@ -27,9 +27,16 @@ export const firstFilterByRef = (
|
||||
};
|
||||
};
|
||||
export const firstFilter = (vars: Variable[]): SingleFilter => {
|
||||
const variable = vars[0];
|
||||
if (!variable) {
|
||||
throw new BlockSuiteError(
|
||||
ErrorCode.DatabaseBlockError,
|
||||
`can't find any variable`
|
||||
);
|
||||
}
|
||||
const ref: VariableRef = {
|
||||
type: 'ref',
|
||||
name: vars[0].id,
|
||||
name: variable.id,
|
||||
};
|
||||
const filter = firstFilterName(vars, ref);
|
||||
if (!filter) {
|
||||
|
||||
@@ -78,8 +78,8 @@ export class GroupSetting extends SignalWatcher(
|
||||
const activeId = evt.active.id;
|
||||
const groups = this.groups$.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.groupTrait.moveGroupTo(
|
||||
activeId,
|
||||
@@ -104,7 +104,11 @@ export class GroupSetting extends SignalWatcher(
|
||||
},
|
||||
],
|
||||
items: computed(() => {
|
||||
return this.groupTrait.groupsDataList$.value?.map(v => v.key) ?? [];
|
||||
return (
|
||||
this.groupTrait.groupsDataList$.value?.map(
|
||||
v => v?.key ?? 'default key'
|
||||
) ?? []
|
||||
);
|
||||
}),
|
||||
strategy: verticalListSortingStrategy,
|
||||
});
|
||||
@@ -136,8 +140,9 @@ export class GroupSetting extends SignalWatcher(
|
||||
>
|
||||
${repeat(
|
||||
groups,
|
||||
group => group.key,
|
||||
group => group?.key ?? 'default key',
|
||||
group => {
|
||||
if (!group) return;
|
||||
const props: GroupRenderProps = {
|
||||
value: group.value,
|
||||
data: group.property.data$.value,
|
||||
|
||||
@@ -110,9 +110,12 @@ export class GroupTrait {
|
||||
}
|
||||
const sortedGroup = this.ops.sortGroup(Object.keys(groupMap));
|
||||
sortedGroup.forEach(key => {
|
||||
if (!groupMap[key]) return;
|
||||
groupMap[key].rows = this.ops.sortRow(key, groupMap[key].rows);
|
||||
});
|
||||
return (this.preDataList = sortedGroup.map(key => groupMap[key]));
|
||||
return (this.preDataList = sortedGroup
|
||||
.map(key => groupMap[key])
|
||||
.filter((v): v is GroupData => v != null));
|
||||
});
|
||||
|
||||
groupsDataList$ = computed(() => {
|
||||
@@ -166,7 +169,7 @@ export class GroupTrait {
|
||||
}
|
||||
const addTo = this.config$.value?.addToGroup ?? (value => value);
|
||||
const newValue = addTo(
|
||||
groupMap[key].value,
|
||||
groupMap[key]?.value,
|
||||
this.view.cellJsonValueGet(rowId, propertyId)
|
||||
);
|
||||
this.view.cellValueSet(rowId, propertyId, newValue);
|
||||
@@ -240,10 +243,10 @@ export class GroupTrait {
|
||||
);
|
||||
}
|
||||
const addTo = this.config$.value?.addToGroup ?? (value => value);
|
||||
newValue = addTo(groupMap[toGroupKey].value, newValue);
|
||||
newValue = addTo(groupMap[toGroupKey]?.value, newValue);
|
||||
this.view.cellValueSet(rowId, propertyId, newValue);
|
||||
}
|
||||
const rows = groupMap[toGroupKey].rows.filter(id => id !== rowId);
|
||||
const rows = groupMap[toGroupKey]?.rows.filter(id => id !== rowId) ?? [];
|
||||
const index = insertPositionToIndex(position, rows, id => id);
|
||||
rows.splice(index, 0, rowId);
|
||||
this.changeCardSort(toGroupKey, rows);
|
||||
@@ -275,7 +278,7 @@ export class GroupTrait {
|
||||
}
|
||||
const remove = this.config$.value?.removeFromGroup ?? (() => undefined);
|
||||
const newValue = remove(
|
||||
groupMap[key].value,
|
||||
groupMap[key]?.value,
|
||||
this.view.cellJsonValueGet(rowId, propertyId)
|
||||
);
|
||||
this.view.cellValueSet(rowId, propertyId, newValue);
|
||||
|
||||
@@ -29,7 +29,7 @@ export class TypeVarReferenceInstance<Name extends string = string>
|
||||
constructor(readonly varName: Name) {}
|
||||
|
||||
subst(ctx: TypeVarContext): void | TypeInstance {
|
||||
return ctx[this.varName].type;
|
||||
return ctx[this.varName]?.type;
|
||||
}
|
||||
|
||||
unify(_ctx: TypeVarContext, _type: TypeInstance, _unify: Unify): boolean {
|
||||
|
||||
@@ -34,7 +34,12 @@ const compareList = <T>(
|
||||
) => {
|
||||
let i = 0;
|
||||
while (i < listA.length && i < listB.length) {
|
||||
const result = compare(listA[i], listB[i]);
|
||||
const a = listA[i];
|
||||
const b = listB[i];
|
||||
if (a == null || b == null) {
|
||||
continue;
|
||||
}
|
||||
const result = compare(a, b);
|
||||
if (result !== 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -41,12 +41,15 @@ export const numberStatsFunctions: StatisticsConfig[] = [
|
||||
dataType: t.number.instance(),
|
||||
impl: data => {
|
||||
const arr = withoutNull(data).sort((a, b) => a - b);
|
||||
let result = 0;
|
||||
let result: number | undefined = undefined;
|
||||
if (arr.length % 2 === 1) {
|
||||
result = arr[(arr.length - 1) / 2];
|
||||
} else {
|
||||
const index = arr.length / 2;
|
||||
result = (arr[index] + arr[index - 1]) / 2;
|
||||
const a = arr[index];
|
||||
const b = arr[index - 1];
|
||||
if (a == null || b == null) return 'None';
|
||||
result = (a + b) / 2;
|
||||
}
|
||||
return result?.toString() ?? 'None';
|
||||
},
|
||||
|
||||
@@ -77,14 +77,18 @@ export function hasViewportRelativeCoordinates(
|
||||
const getEventCoordinates = (event: Event) => {
|
||||
if (event instanceof TouchEvent) {
|
||||
if (event.touches && event.touches.length) {
|
||||
const { clientX: x, clientY: y } = event.touches[0];
|
||||
const touch = event.touches[0];
|
||||
if (!touch) return;
|
||||
const { clientX: x, clientY: y } = touch;
|
||||
|
||||
return {
|
||||
x,
|
||||
y,
|
||||
};
|
||||
} else if (event.changedTouches && event.changedTouches.length) {
|
||||
const { clientX: x, clientY: y } = event.changedTouches[0];
|
||||
const touch = event.changedTouches[0];
|
||||
if (!touch) return;
|
||||
const { clientX: x, clientY: y } = touch;
|
||||
|
||||
return {
|
||||
x,
|
||||
|
||||
@@ -68,7 +68,10 @@ export class SortContext extends DndContext {
|
||||
overIndex: list.findIndex(v => v.id === this.overId$.value),
|
||||
});
|
||||
transforms.forEach((transform, i) => {
|
||||
const node = list[i].node;
|
||||
const node = list[i]?.node;
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
if (transform != null) {
|
||||
node.style.transform = `translate3d(${Math.round(transform.x)}px,${Math.round(transform.y)}px,0)
|
||||
scaleX(${transform.scaleX}) scaleY(${transform.scaleY})`;
|
||||
|
||||
+17
-6
@@ -12,6 +12,7 @@ export const horizontalListSortingStrategy: SortingStrategy = ({
|
||||
overIndex,
|
||||
}) => {
|
||||
const activeNodeRect = rects[activeIndex] ?? fallbackActiveRect;
|
||||
if (!activeNodeRect) return [];
|
||||
const strategy = (index: number) => {
|
||||
const itemGap = getItemGap(rects, index, activeIndex);
|
||||
|
||||
@@ -73,12 +74,22 @@ function getItemGap(
|
||||
}
|
||||
|
||||
if (activeIndex < index) {
|
||||
return previousRect
|
||||
? currentRect.left - (previousRect.left + previousRect.width)
|
||||
: nextRect.left - (currentRect.left + currentRect.width);
|
||||
if (previousRect) {
|
||||
return currentRect.left - (previousRect.left + previousRect.width);
|
||||
}
|
||||
if (nextRect) {
|
||||
return nextRect.left - (currentRect.left + currentRect.width);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return nextRect
|
||||
? nextRect.left - (currentRect.left + currentRect.width)
|
||||
: currentRect.left - (previousRect.left + previousRect.width);
|
||||
if (nextRect) {
|
||||
return nextRect.left - (currentRect.left + currentRect.width);
|
||||
}
|
||||
|
||||
if (previousRect) {
|
||||
return currentRect.left - (previousRect.left + previousRect.width);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ export const verticalListSortingStrategy: SortingStrategy = ({
|
||||
overIndex,
|
||||
}) => {
|
||||
const activeNodeRect = rects[activeIndex] ?? fallbackActiveRect;
|
||||
|
||||
if (!activeNodeRect) return [];
|
||||
const strategy = (index: number) => {
|
||||
if (index === activeIndex) {
|
||||
const overIndexRect = rects[overIndex];
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
*/
|
||||
export function arrayMove<T>(array: T[], from: number, to: number): T[] {
|
||||
const newArray = array.slice();
|
||||
newArray.splice(
|
||||
to < 0 ? newArray.length + to : to,
|
||||
0,
|
||||
newArray.splice(from, 1)[0]
|
||||
);
|
||||
const value = newArray.splice(from, 1)[0];
|
||||
if (value == null) {
|
||||
return newArray;
|
||||
}
|
||||
newArray.splice(to < 0 ? newArray.length + to : to, 0, value);
|
||||
|
||||
return newArray;
|
||||
}
|
||||
|
||||
@@ -76,9 +76,9 @@ export interface SingleView {
|
||||
|
||||
rowGet(rowId: string): Row;
|
||||
|
||||
rowPrevGet(rowId: string): string;
|
||||
rowPrevGet(rowId: string): string | undefined;
|
||||
|
||||
rowNextGet(rowId: string): string;
|
||||
rowNextGet(rowId: string): string | undefined;
|
||||
|
||||
readonly propertyMetas: PropertyMetaConfig[];
|
||||
|
||||
@@ -116,7 +116,7 @@ export interface SingleView {
|
||||
|
||||
propertyIndexGet(propertyId: string): number;
|
||||
|
||||
propertyIdGetByIndex(index: number): string;
|
||||
propertyIdGetByIndex(index: number): string | undefined;
|
||||
|
||||
propertyReadonlyGet(propertyId: string): boolean;
|
||||
|
||||
@@ -387,7 +387,7 @@ export abstract class SingleViewBase<
|
||||
return this.dataSource.propertyMetaGet(type).renderer.icon;
|
||||
}
|
||||
|
||||
propertyIdGetByIndex(index: number): string {
|
||||
propertyIdGetByIndex(index: number): string | undefined {
|
||||
return this.propertyIds$.value[index];
|
||||
}
|
||||
|
||||
@@ -410,9 +410,10 @@ export abstract class SingleViewBase<
|
||||
}
|
||||
|
||||
propertyNextGet(propertyId: string): Property | undefined {
|
||||
return this.propertyGet(
|
||||
this.propertyIdGetByIndex(this.propertyIndexGet(propertyId) + 1)
|
||||
);
|
||||
const index = this.propertyIndexGet(propertyId);
|
||||
const nextId = this.propertyIdGetByIndex(index + 1);
|
||||
if (!nextId) return;
|
||||
return this.propertyGet(nextId);
|
||||
}
|
||||
|
||||
propertyParseValueFromString(propertyId: string, cellData: string) {
|
||||
@@ -430,9 +431,10 @@ export abstract class SingleViewBase<
|
||||
}
|
||||
|
||||
propertyPreGet(propertyId: string): Property | undefined {
|
||||
return this.propertyGet(
|
||||
this.propertyIdGetByIndex(this.propertyIndexGet(propertyId) - 1)
|
||||
);
|
||||
const index = this.propertyIndexGet(propertyId);
|
||||
const prevId = this.propertyIdGetByIndex(index - 1);
|
||||
if (!prevId) return;
|
||||
return this.propertyGet(prevId);
|
||||
}
|
||||
|
||||
propertyReadonlyGet(propertyId: string): boolean {
|
||||
@@ -463,9 +465,9 @@ export abstract class SingleViewBase<
|
||||
this.dataSource.rowMove(rowId, position);
|
||||
}
|
||||
|
||||
abstract rowNextGet(rowId: string): string;
|
||||
abstract rowNextGet(rowId: string): string | undefined;
|
||||
|
||||
abstract rowPrevGet(rowId: string): string;
|
||||
abstract rowPrevGet(rowId: string): string | undefined;
|
||||
|
||||
protected rowsMapping(rows: string[]): string[] {
|
||||
return this.searchRowsMapping(rows, this.searchString.value);
|
||||
|
||||
@@ -15,8 +15,8 @@ export interface ViewManager {
|
||||
dataSource: DataSource;
|
||||
readonly$: ReadonlySignal<boolean>;
|
||||
|
||||
currentViewId$: ReadonlySignal<string>;
|
||||
currentView$: ReadonlySignal<SingleView>;
|
||||
currentViewId$: ReadonlySignal<string | undefined>;
|
||||
currentView$: ReadonlySignal<SingleView | undefined>;
|
||||
|
||||
setCurrentView(id: string): void;
|
||||
|
||||
@@ -49,7 +49,9 @@ export class ViewManagerBase implements ViewManager {
|
||||
});
|
||||
|
||||
currentView$ = computed(() => {
|
||||
return this.viewGet(this.currentViewId$.value);
|
||||
const id = this.currentViewId$.value;
|
||||
if (!id) return;
|
||||
return this.viewGet(id);
|
||||
});
|
||||
|
||||
readonly$ = computed(() => {
|
||||
@@ -66,7 +68,7 @@ export class ViewManagerBase implements ViewManager {
|
||||
this.dataSource.viewDataMoveTo(id, position);
|
||||
}
|
||||
|
||||
setCurrentView(id: string): void {
|
||||
setCurrentView(id: string | undefined): void {
|
||||
this._currentViewId$.value = id;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user