mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 12:55:00 +00: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;
|
let width = 0;
|
||||||
for (let i = 0; i < this.items.length; i++) {
|
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;
|
// Try to calculate the width occupied by rendering n+1 items;
|
||||||
// if it exceeds the limit, render n items(in i++ round).
|
// if it exceeds the limit, render n items(in i++ round).
|
||||||
const totalWidth =
|
const totalWidth =
|
||||||
|
|||||||
@@ -74,12 +74,13 @@ const selectTagColorPoll = selectOptionColors.map(color => color.color);
|
|||||||
|
|
||||||
function tagColorHelper() {
|
function tagColorHelper() {
|
||||||
let colors = [...selectTagColorPoll];
|
let colors = [...selectTagColorPoll];
|
||||||
return () => {
|
return (): string => {
|
||||||
if (colors.length === 0) {
|
if (colors.length === 0) {
|
||||||
colors = [...selectTagColorPoll];
|
colors = [...selectTagColorPoll];
|
||||||
}
|
}
|
||||||
const index = Math.floor(Math.random() * colors.length);
|
const index = Math.floor(Math.random() * colors.length);
|
||||||
const color = colors.splice(index, 1)[0];
|
const color = colors.splice(index, 1)[0];
|
||||||
|
if (!color) return '';
|
||||||
return color;
|
return color;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -243,7 +243,10 @@ export class MultiTagSelect extends SignalWatcher(
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
const inputValue = this.text.value.trim();
|
const inputValue = this.text.value.trim();
|
||||||
if (event.key === 'Backspace' && inputValue === '') {
|
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) {
|
} else if (event.key === 'Enter' && !event.isComposing) {
|
||||||
this.selectedTag$.value?.select();
|
this.selectedTag$.value?.select();
|
||||||
} else if (event.key === 'ArrowUp') {
|
} else if (event.key === 'ArrowUp') {
|
||||||
|
|||||||
@@ -87,6 +87,9 @@ export class DataViewRenderer extends SignalWatcher(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const view = this.viewMap$.value[currentViewId];
|
const view = this.viewMap$.value[currentViewId];
|
||||||
|
if (!view) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
view: view,
|
view: view,
|
||||||
selection$: computed(() => {
|
selection$: computed(() => {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export const evalFilter = (
|
|||||||
for (let i = 0; i < expectArgLen; i++) {
|
for (let i = 0; i < expectArgLen; i++) {
|
||||||
const argValue = evalValue(filter.args[i]);
|
const argValue = evalValue(filter.args[i]);
|
||||||
const argType = func.args[i];
|
const argType = func.args[i];
|
||||||
if (argValue == null) {
|
if (argValue == null || argType == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!argType.valueValidate(argValue)) {
|
if (!argType.valueValidate(argValue)) {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export type FilterConfig<
|
|||||||
) => boolean;
|
) => boolean;
|
||||||
defaultValue?: (args: {
|
defaultValue?: (args: {
|
||||||
[K in keyof Args]: ValueTypeOf<ReplaceVar<Args[K], Vars>>;
|
[K in keyof Args]: ValueTypeOf<ReplaceVar<Args[K], Vars>>;
|
||||||
}) => ValueTypeOf<ReplaceVar<Self, Vars>>;
|
}) => ValueTypeOf<ReplaceVar<Self, Vars>> | undefined;
|
||||||
};
|
};
|
||||||
type FindVar<
|
type FindVar<
|
||||||
Vars extends TypeVarDefinitionInstance[],
|
Vars extends TypeVarDefinitionInstance[],
|
||||||
|
|||||||
@@ -23,7 +23,13 @@ export const multiTagFilter = [
|
|||||||
}
|
}
|
||||||
return value.some(v => self.includes(v));
|
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({
|
createFilter({
|
||||||
name: 'doesNotContainOneOf',
|
name: 'doesNotContainOneOf',
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ export function generateDefaultValues(
|
|||||||
for (const [propertyId, conditions] of propertyConditions) {
|
for (const [propertyId, conditions] of propertyConditions) {
|
||||||
if (conditions.length === 1) {
|
if (conditions.length === 1) {
|
||||||
const condition = conditions[0];
|
const condition = conditions[0];
|
||||||
|
if (!condition) continue;
|
||||||
const filterConfig = filterMatcher.getFilterByName(condition.function);
|
const filterConfig = filterMatcher.getFilterByName(condition.function);
|
||||||
if (filterConfig?.defaultValue) {
|
if (filterConfig?.defaultValue) {
|
||||||
const argValues = condition.args.map(arg => arg.value);
|
const argValues = condition.args.map(arg => arg.value);
|
||||||
|
|||||||
@@ -27,9 +27,16 @@ export const firstFilterByRef = (
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
export const firstFilter = (vars: Variable[]): SingleFilter => {
|
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 = {
|
const ref: VariableRef = {
|
||||||
type: 'ref',
|
type: 'ref',
|
||||||
name: vars[0].id,
|
name: variable.id,
|
||||||
};
|
};
|
||||||
const filter = firstFilterName(vars, ref);
|
const filter = firstFilterName(vars, ref);
|
||||||
if (!filter) {
|
if (!filter) {
|
||||||
|
|||||||
@@ -78,8 +78,8 @@ export class GroupSetting extends SignalWatcher(
|
|||||||
const activeId = evt.active.id;
|
const activeId = evt.active.id;
|
||||||
const groups = this.groups$.value;
|
const groups = this.groups$.value;
|
||||||
if (over && over.id !== activeId && groups) {
|
if (over && over.id !== activeId && groups) {
|
||||||
const activeIndex = groups.findIndex(data => data.key === activeId);
|
const activeIndex = groups.findIndex(data => data?.key === activeId);
|
||||||
const overIndex = groups.findIndex(data => data.key === over.id);
|
const overIndex = groups.findIndex(data => data?.key === over.id);
|
||||||
|
|
||||||
this.groupTrait.moveGroupTo(
|
this.groupTrait.moveGroupTo(
|
||||||
activeId,
|
activeId,
|
||||||
@@ -104,7 +104,11 @@ export class GroupSetting extends SignalWatcher(
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
items: computed(() => {
|
items: computed(() => {
|
||||||
return this.groupTrait.groupsDataList$.value?.map(v => v.key) ?? [];
|
return (
|
||||||
|
this.groupTrait.groupsDataList$.value?.map(
|
||||||
|
v => v?.key ?? 'default key'
|
||||||
|
) ?? []
|
||||||
|
);
|
||||||
}),
|
}),
|
||||||
strategy: verticalListSortingStrategy,
|
strategy: verticalListSortingStrategy,
|
||||||
});
|
});
|
||||||
@@ -136,8 +140,9 @@ export class GroupSetting extends SignalWatcher(
|
|||||||
>
|
>
|
||||||
${repeat(
|
${repeat(
|
||||||
groups,
|
groups,
|
||||||
group => group.key,
|
group => group?.key ?? 'default key',
|
||||||
group => {
|
group => {
|
||||||
|
if (!group) return;
|
||||||
const props: GroupRenderProps = {
|
const props: GroupRenderProps = {
|
||||||
value: group.value,
|
value: group.value,
|
||||||
data: group.property.data$.value,
|
data: group.property.data$.value,
|
||||||
|
|||||||
@@ -110,9 +110,12 @@ export class GroupTrait {
|
|||||||
}
|
}
|
||||||
const sortedGroup = this.ops.sortGroup(Object.keys(groupMap));
|
const sortedGroup = this.ops.sortGroup(Object.keys(groupMap));
|
||||||
sortedGroup.forEach(key => {
|
sortedGroup.forEach(key => {
|
||||||
|
if (!groupMap[key]) return;
|
||||||
groupMap[key].rows = this.ops.sortRow(key, groupMap[key].rows);
|
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(() => {
|
groupsDataList$ = computed(() => {
|
||||||
@@ -166,7 +169,7 @@ export class GroupTrait {
|
|||||||
}
|
}
|
||||||
const addTo = this.config$.value?.addToGroup ?? (value => value);
|
const addTo = this.config$.value?.addToGroup ?? (value => value);
|
||||||
const newValue = addTo(
|
const newValue = addTo(
|
||||||
groupMap[key].value,
|
groupMap[key]?.value,
|
||||||
this.view.cellJsonValueGet(rowId, propertyId)
|
this.view.cellJsonValueGet(rowId, propertyId)
|
||||||
);
|
);
|
||||||
this.view.cellValueSet(rowId, propertyId, newValue);
|
this.view.cellValueSet(rowId, propertyId, newValue);
|
||||||
@@ -240,10 +243,10 @@ export class GroupTrait {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
const addTo = this.config$.value?.addToGroup ?? (value => value);
|
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);
|
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);
|
const index = insertPositionToIndex(position, rows, id => id);
|
||||||
rows.splice(index, 0, rowId);
|
rows.splice(index, 0, rowId);
|
||||||
this.changeCardSort(toGroupKey, rows);
|
this.changeCardSort(toGroupKey, rows);
|
||||||
@@ -275,7 +278,7 @@ export class GroupTrait {
|
|||||||
}
|
}
|
||||||
const remove = this.config$.value?.removeFromGroup ?? (() => undefined);
|
const remove = this.config$.value?.removeFromGroup ?? (() => undefined);
|
||||||
const newValue = remove(
|
const newValue = remove(
|
||||||
groupMap[key].value,
|
groupMap[key]?.value,
|
||||||
this.view.cellJsonValueGet(rowId, propertyId)
|
this.view.cellJsonValueGet(rowId, propertyId)
|
||||||
);
|
);
|
||||||
this.view.cellValueSet(rowId, propertyId, newValue);
|
this.view.cellValueSet(rowId, propertyId, newValue);
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export class TypeVarReferenceInstance<Name extends string = string>
|
|||||||
constructor(readonly varName: Name) {}
|
constructor(readonly varName: Name) {}
|
||||||
|
|
||||||
subst(ctx: TypeVarContext): void | TypeInstance {
|
subst(ctx: TypeVarContext): void | TypeInstance {
|
||||||
return ctx[this.varName].type;
|
return ctx[this.varName]?.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
unify(_ctx: TypeVarContext, _type: TypeInstance, _unify: Unify): boolean {
|
unify(_ctx: TypeVarContext, _type: TypeInstance, _unify: Unify): boolean {
|
||||||
|
|||||||
@@ -34,7 +34,12 @@ const compareList = <T>(
|
|||||||
) => {
|
) => {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
while (i < listA.length && i < listB.length) {
|
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) {
|
if (result !== 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,12 +41,15 @@ export const numberStatsFunctions: StatisticsConfig[] = [
|
|||||||
dataType: t.number.instance(),
|
dataType: t.number.instance(),
|
||||||
impl: data => {
|
impl: data => {
|
||||||
const arr = withoutNull(data).sort((a, b) => a - b);
|
const arr = withoutNull(data).sort((a, b) => a - b);
|
||||||
let result = 0;
|
let result: number | undefined = undefined;
|
||||||
if (arr.length % 2 === 1) {
|
if (arr.length % 2 === 1) {
|
||||||
result = arr[(arr.length - 1) / 2];
|
result = arr[(arr.length - 1) / 2];
|
||||||
} else {
|
} else {
|
||||||
const index = arr.length / 2;
|
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';
|
return result?.toString() ?? 'None';
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -77,14 +77,18 @@ export function hasViewportRelativeCoordinates(
|
|||||||
const getEventCoordinates = (event: Event) => {
|
const getEventCoordinates = (event: Event) => {
|
||||||
if (event instanceof TouchEvent) {
|
if (event instanceof TouchEvent) {
|
||||||
if (event.touches && event.touches.length) {
|
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 {
|
return {
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
};
|
};
|
||||||
} else if (event.changedTouches && event.changedTouches.length) {
|
} 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 {
|
return {
|
||||||
x,
|
x,
|
||||||
|
|||||||
@@ -68,7 +68,10 @@ export class SortContext extends DndContext {
|
|||||||
overIndex: list.findIndex(v => v.id === this.overId$.value),
|
overIndex: list.findIndex(v => v.id === this.overId$.value),
|
||||||
});
|
});
|
||||||
transforms.forEach((transform, i) => {
|
transforms.forEach((transform, i) => {
|
||||||
const node = list[i].node;
|
const node = list[i]?.node;
|
||||||
|
if (!node) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (transform != null) {
|
if (transform != null) {
|
||||||
node.style.transform = `translate3d(${Math.round(transform.x)}px,${Math.round(transform.y)}px,0)
|
node.style.transform = `translate3d(${Math.round(transform.x)}px,${Math.round(transform.y)}px,0)
|
||||||
scaleX(${transform.scaleX}) scaleY(${transform.scaleY})`;
|
scaleX(${transform.scaleX}) scaleY(${transform.scaleY})`;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export const horizontalListSortingStrategy: SortingStrategy = ({
|
|||||||
overIndex,
|
overIndex,
|
||||||
}) => {
|
}) => {
|
||||||
const activeNodeRect = rects[activeIndex] ?? fallbackActiveRect;
|
const activeNodeRect = rects[activeIndex] ?? fallbackActiveRect;
|
||||||
|
if (!activeNodeRect) return [];
|
||||||
const strategy = (index: number) => {
|
const strategy = (index: number) => {
|
||||||
const itemGap = getItemGap(rects, index, activeIndex);
|
const itemGap = getItemGap(rects, index, activeIndex);
|
||||||
|
|
||||||
@@ -73,12 +74,22 @@ function getItemGap(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (activeIndex < index) {
|
if (activeIndex < index) {
|
||||||
return previousRect
|
if (previousRect) {
|
||||||
? currentRect.left - (previousRect.left + previousRect.width)
|
return currentRect.left - (previousRect.left + previousRect.width);
|
||||||
: nextRect.left - (currentRect.left + currentRect.width);
|
}
|
||||||
|
if (nextRect) {
|
||||||
|
return nextRect.left - (currentRect.left + currentRect.width);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nextRect
|
if (nextRect) {
|
||||||
? nextRect.left - (currentRect.left + currentRect.width)
|
return nextRect.left - (currentRect.left + currentRect.width);
|
||||||
: currentRect.left - (previousRect.left + previousRect.width);
|
}
|
||||||
|
|
||||||
|
if (previousRect) {
|
||||||
|
return currentRect.left - (previousRect.left + previousRect.width);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export const verticalListSortingStrategy: SortingStrategy = ({
|
|||||||
overIndex,
|
overIndex,
|
||||||
}) => {
|
}) => {
|
||||||
const activeNodeRect = rects[activeIndex] ?? fallbackActiveRect;
|
const activeNodeRect = rects[activeIndex] ?? fallbackActiveRect;
|
||||||
|
if (!activeNodeRect) return [];
|
||||||
const strategy = (index: number) => {
|
const strategy = (index: number) => {
|
||||||
if (index === activeIndex) {
|
if (index === activeIndex) {
|
||||||
const overIndexRect = rects[overIndex];
|
const overIndexRect = rects[overIndex];
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
*/
|
*/
|
||||||
export function arrayMove<T>(array: T[], from: number, to: number): T[] {
|
export function arrayMove<T>(array: T[], from: number, to: number): T[] {
|
||||||
const newArray = array.slice();
|
const newArray = array.slice();
|
||||||
newArray.splice(
|
const value = newArray.splice(from, 1)[0];
|
||||||
to < 0 ? newArray.length + to : to,
|
if (value == null) {
|
||||||
0,
|
return newArray;
|
||||||
newArray.splice(from, 1)[0]
|
}
|
||||||
);
|
newArray.splice(to < 0 ? newArray.length + to : to, 0, value);
|
||||||
|
|
||||||
return newArray;
|
return newArray;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,9 +76,9 @@ export interface SingleView {
|
|||||||
|
|
||||||
rowGet(rowId: string): Row;
|
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[];
|
readonly propertyMetas: PropertyMetaConfig[];
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@ export interface SingleView {
|
|||||||
|
|
||||||
propertyIndexGet(propertyId: string): number;
|
propertyIndexGet(propertyId: string): number;
|
||||||
|
|
||||||
propertyIdGetByIndex(index: number): string;
|
propertyIdGetByIndex(index: number): string | undefined;
|
||||||
|
|
||||||
propertyReadonlyGet(propertyId: string): boolean;
|
propertyReadonlyGet(propertyId: string): boolean;
|
||||||
|
|
||||||
@@ -387,7 +387,7 @@ export abstract class SingleViewBase<
|
|||||||
return this.dataSource.propertyMetaGet(type).renderer.icon;
|
return this.dataSource.propertyMetaGet(type).renderer.icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
propertyIdGetByIndex(index: number): string {
|
propertyIdGetByIndex(index: number): string | undefined {
|
||||||
return this.propertyIds$.value[index];
|
return this.propertyIds$.value[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,9 +410,10 @@ export abstract class SingleViewBase<
|
|||||||
}
|
}
|
||||||
|
|
||||||
propertyNextGet(propertyId: string): Property | undefined {
|
propertyNextGet(propertyId: string): Property | undefined {
|
||||||
return this.propertyGet(
|
const index = this.propertyIndexGet(propertyId);
|
||||||
this.propertyIdGetByIndex(this.propertyIndexGet(propertyId) + 1)
|
const nextId = this.propertyIdGetByIndex(index + 1);
|
||||||
);
|
if (!nextId) return;
|
||||||
|
return this.propertyGet(nextId);
|
||||||
}
|
}
|
||||||
|
|
||||||
propertyParseValueFromString(propertyId: string, cellData: string) {
|
propertyParseValueFromString(propertyId: string, cellData: string) {
|
||||||
@@ -430,9 +431,10 @@ export abstract class SingleViewBase<
|
|||||||
}
|
}
|
||||||
|
|
||||||
propertyPreGet(propertyId: string): Property | undefined {
|
propertyPreGet(propertyId: string): Property | undefined {
|
||||||
return this.propertyGet(
|
const index = this.propertyIndexGet(propertyId);
|
||||||
this.propertyIdGetByIndex(this.propertyIndexGet(propertyId) - 1)
|
const prevId = this.propertyIdGetByIndex(index - 1);
|
||||||
);
|
if (!prevId) return;
|
||||||
|
return this.propertyGet(prevId);
|
||||||
}
|
}
|
||||||
|
|
||||||
propertyReadonlyGet(propertyId: string): boolean {
|
propertyReadonlyGet(propertyId: string): boolean {
|
||||||
@@ -463,9 +465,9 @@ export abstract class SingleViewBase<
|
|||||||
this.dataSource.rowMove(rowId, position);
|
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[] {
|
protected rowsMapping(rows: string[]): string[] {
|
||||||
return this.searchRowsMapping(rows, this.searchString.value);
|
return this.searchRowsMapping(rows, this.searchString.value);
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ export interface ViewManager {
|
|||||||
dataSource: DataSource;
|
dataSource: DataSource;
|
||||||
readonly$: ReadonlySignal<boolean>;
|
readonly$: ReadonlySignal<boolean>;
|
||||||
|
|
||||||
currentViewId$: ReadonlySignal<string>;
|
currentViewId$: ReadonlySignal<string | undefined>;
|
||||||
currentView$: ReadonlySignal<SingleView>;
|
currentView$: ReadonlySignal<SingleView | undefined>;
|
||||||
|
|
||||||
setCurrentView(id: string): void;
|
setCurrentView(id: string): void;
|
||||||
|
|
||||||
@@ -49,7 +49,9 @@ export class ViewManagerBase implements ViewManager {
|
|||||||
});
|
});
|
||||||
|
|
||||||
currentView$ = computed(() => {
|
currentView$ = computed(() => {
|
||||||
return this.viewGet(this.currentViewId$.value);
|
const id = this.currentViewId$.value;
|
||||||
|
if (!id) return;
|
||||||
|
return this.viewGet(id);
|
||||||
});
|
});
|
||||||
|
|
||||||
readonly$ = computed(() => {
|
readonly$ = computed(() => {
|
||||||
@@ -66,7 +68,7 @@ export class ViewManagerBase implements ViewManager {
|
|||||||
this.dataSource.viewDataMoveTo(id, position);
|
this.dataSource.viewDataMoveTo(id, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
setCurrentView(id: string): void {
|
setCurrentView(id: string | undefined): void {
|
||||||
this._currentViewId$.value = id;
|
this._currentViewId$.value = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ export const selectPropertyModelConfig = selectPropertyType.modelConfig<
|
|||||||
.split(',')
|
.split(',')
|
||||||
.map(v => v.trim())
|
.map(v => v.trim())
|
||||||
.filter(v => v)[0];
|
.filter(v => v)[0];
|
||||||
|
if (!name) {
|
||||||
|
return { value: null, data: data };
|
||||||
|
}
|
||||||
|
|
||||||
let value: string | undefined;
|
let value: string | undefined;
|
||||||
const option = optionMap[name];
|
const option = optionMap[name];
|
||||||
|
|||||||
@@ -53,6 +53,12 @@ export const kanbanViewModel = kanbanViewType.createModel<KanbanViewData>({
|
|||||||
return 1;
|
return 1;
|
||||||
};
|
};
|
||||||
const columnId = allowList.sort((a, b) => getWeight(b) - getWeight(a))[0];
|
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 type = viewManager.dataSource.propertyTypeGet(columnId);
|
||||||
const meta = type && viewManager.dataSource.propertyMetaGet(type);
|
const meta = type && viewManager.dataSource.propertyMetaGet(type);
|
||||||
const data = viewManager.dataSource.propertyDataGet(columnId);
|
const data = viewManager.dataSource.propertyDataGet(columnId);
|
||||||
|
|||||||
@@ -285,6 +285,9 @@ export class KanbanSingleView extends SingleViewBase<KanbanViewData> {
|
|||||||
}
|
}
|
||||||
const columns = [...view.columns];
|
const columns = [...view.columns];
|
||||||
const [column] = columns.splice(columnIndex, 1);
|
const [column] = columns.splice(columnIndex, 1);
|
||||||
|
if (!column) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
const index = insertPositionToIndex(toAfterOfColumn, columns);
|
const index = insertPositionToIndex(toAfterOfColumn, columns);
|
||||||
columns.splice(index, 0, column);
|
columns.splice(index, 0, column);
|
||||||
return {
|
return {
|
||||||
@@ -297,12 +300,12 @@ export class KanbanSingleView extends SingleViewBase<KanbanViewData> {
|
|||||||
this.dataSource.rowMove(rowId, position);
|
this.dataSource.rowMove(rowId, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
override rowNextGet(rowId: string): string {
|
override rowNextGet(rowId: string): string | undefined {
|
||||||
const index = this.rows$.value.indexOf(rowId);
|
const index = this.rows$.value.indexOf(rowId);
|
||||||
return this.rows$.value[index + 1];
|
return this.rows$.value[index + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
override rowPrevGet(rowId: string): string {
|
override rowPrevGet(rowId: string): string | undefined {
|
||||||
const index = this.rows$.value.indexOf(rowId);
|
const index = this.rows$.value.indexOf(rowId);
|
||||||
return this.rows$.value[index - 1];
|
return this.rows$.value[index - 1];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ export class KanbanSelectionController implements ReactiveController {
|
|||||||
if (selection.selectionType === 'card') {
|
if (selection.selectionType === 'card') {
|
||||||
const card = getSelectedCards(this.host, selection)[0];
|
const card = getSelectedCards(this.host, selection)[0];
|
||||||
const cell = card?.querySelector('affine-data-view-kanban-cell');
|
const cell = card?.querySelector('affine-data-view-kanban-cell');
|
||||||
if (cell) {
|
if (card && cell) {
|
||||||
this.selection = {
|
this.selection = {
|
||||||
groupKey: card.groupKey,
|
groupKey: card.groupKey,
|
||||||
cardId: card.cardId,
|
cardId: card.cardId,
|
||||||
@@ -209,11 +209,9 @@ export class KanbanSelectionController implements ReactiveController {
|
|||||||
const index = kanbanCells.findIndex(
|
const index = kanbanCells.findIndex(
|
||||||
cell => cell.column.id === selection.columnId
|
cell => cell.column.id === selection.columnId
|
||||||
);
|
);
|
||||||
const { cell, cardId, groupKey } = this.getNextFocusCell(
|
const result = this.getNextFocusCell(selection, index, position);
|
||||||
selection,
|
if (!result) return;
|
||||||
index,
|
const { cell, cardId, groupKey } = result;
|
||||||
position
|
|
||||||
);
|
|
||||||
if (cell instanceof KanbanCell) {
|
if (cell instanceof KanbanCell) {
|
||||||
this.selection = {
|
this.selection = {
|
||||||
...selection,
|
...selection,
|
||||||
@@ -234,7 +232,9 @@ export class KanbanSelectionController implements ReactiveController {
|
|||||||
const index = cardElements.findIndex(
|
const index = cardElements.findIndex(
|
||||||
card => card.cardId === selection.cards[0].cardId
|
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) {
|
if (card instanceof KanbanCard) {
|
||||||
const newCards = cards ?? selection.cards;
|
const newCards = cards ?? selection.cards;
|
||||||
this.selection = atLeastOne(newCards)
|
this.selection = atLeastOne(newCards)
|
||||||
@@ -286,10 +286,12 @@ export class KanbanSelectionController implements ReactiveController {
|
|||||||
selection: KanbanCardSelection,
|
selection: KanbanCardSelection,
|
||||||
index: number,
|
index: number,
|
||||||
nextPosition: 'up' | 'down' | 'left' | 'right'
|
nextPosition: 'up' | 'down' | 'left' | 'right'
|
||||||
): {
|
):
|
||||||
card: KanbanCard;
|
| {
|
||||||
cards: KanbanCardSelectionCard[];
|
card: KanbanCard;
|
||||||
} {
|
cards: KanbanCardSelectionCard[];
|
||||||
|
}
|
||||||
|
| undefined {
|
||||||
const group = this.host.querySelector(
|
const group = this.host.querySelector(
|
||||||
`affine-data-view-kanban-group[data-key="${selection.cards[0].groupKey}"]`
|
`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 nextIndex = index - 1;
|
||||||
const nextCardIndex = nextIndex < 0 ? kanbanCards.length - 1 : nextIndex;
|
const nextCardIndex = nextIndex < 0 ? kanbanCards.length - 1 : nextIndex;
|
||||||
const card = kanbanCards[nextCardIndex];
|
const card = kanbanCards[nextCardIndex];
|
||||||
|
if (!card) return;
|
||||||
return {
|
return {
|
||||||
card,
|
card,
|
||||||
cards: [
|
cards: [
|
||||||
@@ -317,7 +319,7 @@ export class KanbanSelectionController implements ReactiveController {
|
|||||||
const nextIndex = index + 1;
|
const nextIndex = index + 1;
|
||||||
const nextCardIndex = nextIndex > kanbanCards.length - 1 ? 0 : nextIndex;
|
const nextCardIndex = nextIndex > kanbanCards.length - 1 ? 0 : nextIndex;
|
||||||
const card = kanbanCards[nextCardIndex];
|
const card = kanbanCards[nextCardIndex];
|
||||||
|
if (!card) return;
|
||||||
return {
|
return {
|
||||||
card,
|
card,
|
||||||
cards: [
|
cards: [
|
||||||
@@ -360,11 +362,13 @@ export class KanbanSelectionController implements ReactiveController {
|
|||||||
selection: KanbanCellSelection,
|
selection: KanbanCellSelection,
|
||||||
index: number,
|
index: number,
|
||||||
nextPosition: 'up' | 'down' | 'left' | 'right'
|
nextPosition: 'up' | 'down' | 'left' | 'right'
|
||||||
): {
|
):
|
||||||
cell: KanbanCell;
|
| {
|
||||||
cardId?: string;
|
cell: KanbanCell;
|
||||||
groupKey?: string;
|
cardId?: string;
|
||||||
} {
|
groupKey?: string;
|
||||||
|
}
|
||||||
|
| undefined {
|
||||||
const kanbanCells = getCardCellsBySelection(this.host, selection);
|
const kanbanCells = getCardCellsBySelection(this.host, selection);
|
||||||
const group = this.host.querySelector(
|
const group = this.host.querySelector(
|
||||||
`affine-data-view-kanban-group[data-key="${selection.groupKey}"]`
|
`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)
|
cardIndex => (cardIndex === 0 ? cards.length - 1 : cardIndex - 1)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
const cell = kanbanCells[kanbanCells.length - 1];
|
||||||
|
if (!cell) return;
|
||||||
return {
|
return {
|
||||||
cell: kanbanCells[kanbanCells.length - 1],
|
cell,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!kanbanCells[nextIndex]) return;
|
||||||
return {
|
return {
|
||||||
cell: kanbanCells[nextIndex],
|
cell: kanbanCells[nextIndex],
|
||||||
};
|
};
|
||||||
@@ -405,11 +412,14 @@ export class KanbanSelectionController implements ReactiveController {
|
|||||||
cardIndex => (cardIndex === cards.length - 1 ? 0 : cardIndex + 1)
|
cardIndex => (cardIndex === cards.length - 1 ? 0 : cardIndex + 1)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
const cell = kanbanCells[0];
|
||||||
|
if (!cell) return;
|
||||||
return {
|
return {
|
||||||
cell: kanbanCells[0],
|
cell,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!kanbanCells[nextIndex]) return;
|
||||||
return {
|
return {
|
||||||
cell: kanbanCells[nextIndex],
|
cell: kanbanCells[nextIndex],
|
||||||
};
|
};
|
||||||
@@ -569,19 +579,19 @@ function getNextGroupFocusElement(
|
|||||||
groups: KanbanGroup[],
|
groups: KanbanGroup[],
|
||||||
selection: KanbanCellSelection,
|
selection: KanbanCellSelection,
|
||||||
getNextGroupIndex: (groupIndex: number) => number
|
getNextGroupIndex: (groupIndex: number) => number
|
||||||
): NextFocusCell;
|
): NextFocusCell | undefined;
|
||||||
function getNextGroupFocusElement(
|
function getNextGroupFocusElement(
|
||||||
viewElement: Element,
|
viewElement: Element,
|
||||||
groups: KanbanGroup[],
|
groups: KanbanGroup[],
|
||||||
selection: KanbanCardSelection,
|
selection: KanbanCardSelection,
|
||||||
getNextGroupIndex: (groupIndex: number) => number
|
getNextGroupIndex: (groupIndex: number) => number
|
||||||
): NextFocusCard;
|
): NextFocusCard | undefined;
|
||||||
function getNextGroupFocusElement(
|
function getNextGroupFocusElement(
|
||||||
viewElement: Element,
|
viewElement: Element,
|
||||||
groups: KanbanGroup[],
|
groups: KanbanGroup[],
|
||||||
selection: KanbanCellSelection | KanbanCardSelection,
|
selection: KanbanCellSelection | KanbanCardSelection,
|
||||||
getNextGroupIndex: (groupIndex: number) => number
|
getNextGroupIndex: (groupIndex: number) => number
|
||||||
): NextFocusCell | NextFocusCard {
|
): NextFocusCell | NextFocusCard | undefined {
|
||||||
const groupIndex = groups.findIndex(group => {
|
const groupIndex = groups.findIndex(group => {
|
||||||
if (selection.selectionType === 'cell') {
|
if (selection.selectionType === 'cell') {
|
||||||
return group.group.key === selection.groupKey;
|
return group.group.key === selection.groupKey;
|
||||||
@@ -591,10 +601,11 @@ function getNextGroupFocusElement(
|
|||||||
|
|
||||||
let nextGroupIndex = getNextGroupIndex(groupIndex);
|
let nextGroupIndex = getNextGroupIndex(groupIndex);
|
||||||
let nextGroup = groups[nextGroupIndex];
|
let nextGroup = groups[nextGroupIndex];
|
||||||
while (nextGroup.group.rows.length === 0) {
|
while (nextGroup?.group.rows.length === 0) {
|
||||||
nextGroupIndex = getNextGroupIndex(nextGroupIndex);
|
nextGroupIndex = getNextGroupIndex(nextGroupIndex);
|
||||||
nextGroup = groups[nextGroupIndex];
|
nextGroup = groups[nextGroupIndex];
|
||||||
}
|
}
|
||||||
|
if (!nextGroup) return;
|
||||||
|
|
||||||
const element =
|
const element =
|
||||||
selection.selectionType === 'cell'
|
selection.selectionType === 'cell'
|
||||||
@@ -621,6 +632,7 @@ function getNextGroupFocusElement(
|
|||||||
});
|
});
|
||||||
const nextCard = nextCards[cardPos.index];
|
const nextCard = nextCards[cardPos.index];
|
||||||
|
|
||||||
|
if (!nextCard) return;
|
||||||
if (selection.selectionType === 'card') {
|
if (selection.selectionType === 'card') {
|
||||||
return {
|
return {
|
||||||
card: nextCard,
|
card: nextCard,
|
||||||
@@ -652,6 +664,7 @@ function getNextGroupFocusElement(
|
|||||||
});
|
});
|
||||||
const nextCell = cells[cellPos.index];
|
const nextCell = cells[cellPos.index];
|
||||||
|
|
||||||
|
if (!nextCell) return;
|
||||||
return {
|
return {
|
||||||
cell: nextCell,
|
cell: nextCell,
|
||||||
cardId: nextCard.cardId,
|
cardId: nextCard.cardId,
|
||||||
@@ -664,17 +677,21 @@ function getNextCardFocusCell(
|
|||||||
cards: KanbanCard[],
|
cards: KanbanCard[],
|
||||||
selection: KanbanCellSelection,
|
selection: KanbanCellSelection,
|
||||||
getNextCardIndex: (cardIndex: number) => number
|
getNextCardIndex: (cardIndex: number) => number
|
||||||
): {
|
):
|
||||||
cell: KanbanCell;
|
| {
|
||||||
cardId: string;
|
cell: KanbanCell;
|
||||||
} {
|
cardId: string;
|
||||||
|
}
|
||||||
|
| undefined {
|
||||||
const cardIndex = cards.findIndex(card => card.cardId === selection.cardId);
|
const cardIndex = cards.findIndex(card => card.cardId === selection.cardId);
|
||||||
const nextCardIndex = getNextCardIndex(cardIndex);
|
const nextCardIndex = getNextCardIndex(cardIndex);
|
||||||
const nextCard = cards[nextCardIndex];
|
const nextCard = cards[nextCardIndex];
|
||||||
|
if (!nextCard) return;
|
||||||
const nextCells = Array.from(
|
const nextCells = Array.from(
|
||||||
nextCard.querySelectorAll('affine-data-view-kanban-cell')
|
nextCard.querySelectorAll('affine-data-view-kanban-cell')
|
||||||
);
|
);
|
||||||
const nextCellIndex = nextPosition === 'up' ? nextCells.length - 1 : 0;
|
const nextCellIndex = nextPosition === 'up' ? nextCells.length - 1 : 0;
|
||||||
|
if (!nextCells[nextCellIndex]) return;
|
||||||
return {
|
return {
|
||||||
cell: nextCells[nextCellIndex],
|
cell: nextCells[nextCellIndex],
|
||||||
cardId: nextCard.cardId,
|
cardId: nextCard.cardId,
|
||||||
|
|||||||
@@ -101,13 +101,15 @@ export class KanbanGroup extends SignalWatcher(
|
|||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
const kanban = this.closest('affine-data-view-kanban');
|
const kanban = this.closest('affine-data-view-kanban');
|
||||||
if (kanban) {
|
if (kanban) {
|
||||||
|
const columnId =
|
||||||
|
this.view.mainProperties$.value.titleColumn ||
|
||||||
|
this.view.propertyIds$.value[0];
|
||||||
|
if (!columnId) return;
|
||||||
kanban.selectionController.selection = {
|
kanban.selectionController.selection = {
|
||||||
selectionType: 'cell',
|
selectionType: 'cell',
|
||||||
groupKey: this.group.key,
|
groupKey: this.group.key,
|
||||||
cardId: id,
|
cardId: id,
|
||||||
columnId:
|
columnId,
|
||||||
this.view.mainProperties$.value.titleColumn ||
|
|
||||||
this.view.propertyIds$.value[0],
|
|
||||||
isEditing: true,
|
isEditing: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -119,13 +121,15 @@ export class KanbanGroup extends SignalWatcher(
|
|||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
const kanban = this.closest('affine-data-view-kanban');
|
const kanban = this.closest('affine-data-view-kanban');
|
||||||
if (kanban) {
|
if (kanban) {
|
||||||
|
const columnId =
|
||||||
|
this.view.mainProperties$.value.titleColumn ||
|
||||||
|
this.view.propertyIds$.value[0];
|
||||||
|
if (!columnId) return;
|
||||||
kanban.selectionController.selection = {
|
kanban.selectionController.selection = {
|
||||||
selectionType: 'cell',
|
selectionType: 'cell',
|
||||||
groupKey: this.group.key,
|
groupKey: this.group.key,
|
||||||
cardId: id,
|
cardId: id,
|
||||||
columnId:
|
columnId,
|
||||||
this.view.mainProperties$.value.titleColumn ||
|
|
||||||
this.view.propertyIds$.value[0],
|
|
||||||
isEditing: true,
|
isEditing: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,8 +166,8 @@ export class DataViewKanban extends DataViewBase<
|
|||||||
const activeId = evt.active.id;
|
const activeId = evt.active.id;
|
||||||
const groups = this.groupManager.groupsDataList$.value;
|
const groups = this.groupManager.groupsDataList$.value;
|
||||||
if (over && over.id !== activeId && groups) {
|
if (over && over.id !== activeId && groups) {
|
||||||
const activeIndex = groups.findIndex(data => data.key === activeId);
|
const activeIndex = groups.findIndex(data => data?.key === activeId);
|
||||||
const overIndex = groups.findIndex(data => data.key === over.id);
|
const overIndex = groups.findIndex(data => data?.key === over.id);
|
||||||
|
|
||||||
this.groupManager.moveGroupTo(
|
this.groupManager.moveGroupTo(
|
||||||
activeId,
|
activeId,
|
||||||
@@ -192,7 +192,11 @@ export class DataViewKanban extends DataViewBase<
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
items: computed(() => {
|
items: computed(() => {
|
||||||
return this.groupManager.groupsDataList$.value?.map(v => v.key) ?? [];
|
return (
|
||||||
|
this.groupManager.groupsDataList$.value?.map(
|
||||||
|
v => v?.key ?? 'default key'
|
||||||
|
) ?? []
|
||||||
|
);
|
||||||
}),
|
}),
|
||||||
strategy: horizontalListSortingStrategy,
|
strategy: horizontalListSortingStrategy,
|
||||||
});
|
});
|
||||||
@@ -268,8 +272,9 @@ export class DataViewKanban extends DataViewBase<
|
|||||||
>
|
>
|
||||||
${repeat(
|
${repeat(
|
||||||
groups,
|
groups,
|
||||||
group => group.key,
|
group => group?.key ?? 'default key',
|
||||||
group => {
|
group => {
|
||||||
|
if (!group) return;
|
||||||
return html` <affine-data-view-kanban-group
|
return html` <affine-data-view-kanban-group
|
||||||
${sortable(group.key)}
|
${sortable(group.key)}
|
||||||
data-key="${group.key}"
|
data-key="${group.key}"
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ function getSelectedArea(
|
|||||||
const { rowsSelection, columnsSelection, groupKey } = selection;
|
const { rowsSelection, columnsSelection, groupKey } = selection;
|
||||||
const data: SelectedArea = [];
|
const data: SelectedArea = [];
|
||||||
const rows = groupKey
|
const rows = groupKey
|
||||||
? view.groupTrait.groupDataMap$.value?.[groupKey].rows
|
? view.groupTrait.groupDataMap$.value?.[groupKey]?.rows
|
||||||
: view.rows$.value;
|
: view.rows$.value;
|
||||||
const columns = view.propertyIds$.value;
|
const columns = view.propertyIds$.value;
|
||||||
if (!rows) {
|
if (!rows) {
|
||||||
@@ -208,8 +208,14 @@ function getSelectedArea(
|
|||||||
cells: [],
|
cells: [],
|
||||||
};
|
};
|
||||||
const rowId = rows[i];
|
const rowId = rows[i];
|
||||||
|
if (rowId == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (let j = columnsSelection.start; j <= columnsSelection.end; j++) {
|
for (let j = columnsSelection.start; j <= columnsSelection.end; j++) {
|
||||||
const columnId = columns[j];
|
const columnId = columns[j];
|
||||||
|
if (columnId == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const cell = view.cellGet(rowId, columnId);
|
const cell = view.cellGet(rowId, columnId);
|
||||||
row.cells.push(cell);
|
row.cells.push(cell);
|
||||||
}
|
}
|
||||||
@@ -237,7 +243,7 @@ function getTargetRangeFromSelection(
|
|||||||
},
|
},
|
||||||
column: {
|
column: {
|
||||||
start: focus.columnIndex,
|
start: focus.columnIndex,
|
||||||
length: data[0].length,
|
length: data[0]?.length ?? 0,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
@@ -258,7 +264,7 @@ function pasteToCells(
|
|||||||
selection: TableAreaSelection
|
selection: TableAreaSelection
|
||||||
) {
|
) {
|
||||||
const srcRowLength = rows.length;
|
const srcRowLength = rows.length;
|
||||||
const srcColumnLength = rows[0].length;
|
const srcColumnLength = rows[0]?.length ?? 0;
|
||||||
const targetRange = getTargetRangeFromSelection(selection, rows);
|
const targetRange = getTargetRangeFromSelection(selection, rows);
|
||||||
for (let i = 0; i < targetRange.row.length; i++) {
|
for (let i = 0; i < targetRange.row.length; i++) {
|
||||||
for (let j = 0; j < targetRange.column.length; j++) {
|
for (let j = 0; j < targetRange.column.length; j++) {
|
||||||
@@ -267,7 +273,7 @@ function pasteToCells(
|
|||||||
|
|
||||||
const srcRowIndex = i % srcRowLength;
|
const srcRowIndex = i % srcRowLength;
|
||||||
const srcColumnIndex = j % srcColumnLength;
|
const srcColumnIndex = j % srcColumnLength;
|
||||||
const dataString = rows[srcRowIndex][srcColumnIndex];
|
const dataString = rows[srcRowIndex]?.[srcColumnIndex];
|
||||||
|
|
||||||
const targetContainer = table.selectionController.getCellContainer(
|
const targetContainer = table.selectionController.getCellContainer(
|
||||||
selection.groupKey,
|
selection.groupKey,
|
||||||
@@ -278,7 +284,7 @@ function pasteToCells(
|
|||||||
const columnId = targetContainer?.dataset.columnId;
|
const columnId = targetContainer?.dataset.columnId;
|
||||||
|
|
||||||
if (rowId && 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({
|
this.selectionController.selection = TableRowSelection.create({
|
||||||
rows:
|
rows:
|
||||||
this.host.props.view.groupTrait.groupsDataList$.value?.flatMap(
|
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 => ({
|
this.host.props.view.rows$.value.map(id => ({
|
||||||
groupKey: undefined,
|
groupKey: undefined,
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ export class TableSelectionController implements ReactiveController {
|
|||||||
}
|
}
|
||||||
const rows =
|
const rows =
|
||||||
groupKey != null
|
groupKey != null
|
||||||
? this.view.groupTrait.groupDataMap$.value?.[groupKey].rows
|
? this.view.groupTrait.groupDataMap$.value?.[groupKey]?.rows
|
||||||
: this.view.rows$.value;
|
: this.view.rows$.value;
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
const index = this.host.props.view.properties$.value.findIndex(
|
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,
|
length: selection.rowsSelection.end - selection.rowsSelection.start + 1,
|
||||||
})
|
})
|
||||||
.map((_, index) => index + selection.rowsSelection.start)
|
.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 }));
|
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++) {
|
for (let i = 0; i < rowOffsets.length; i++) {
|
||||||
const offset = rowOffsets[i];
|
const offset = rowOffsets[i];
|
||||||
|
if (offset == null) continue;
|
||||||
if (offset < startY) {
|
if (offset < startY) {
|
||||||
row.start = i;
|
row.start = i;
|
||||||
}
|
}
|
||||||
@@ -323,6 +325,7 @@ export class TableSelectionController implements ReactiveController {
|
|||||||
}
|
}
|
||||||
for (let i = 0; i < columnOffsets.length; i++) {
|
for (let i = 0; i < columnOffsets.length; i++) {
|
||||||
const offset = columnOffsets[i];
|
const offset = columnOffsets[i];
|
||||||
|
if (offset == null) continue;
|
||||||
if (offset < startX) {
|
if (offset < startX) {
|
||||||
column.start = i;
|
column.start = i;
|
||||||
}
|
}
|
||||||
@@ -544,20 +547,21 @@ export class TableSelectionController implements ReactiveController {
|
|||||||
if (!TableRowSelection.is(this.selection)) return;
|
if (!TableRowSelection.is(this.selection)) return;
|
||||||
const rows = this.selection.rows;
|
const rows = this.selection.rows;
|
||||||
const lastRow = rows[rows.length - 1];
|
const lastRow = rows[rows.length - 1];
|
||||||
|
if (!lastRow) return;
|
||||||
const lastRowIndex =
|
const lastRowIndex =
|
||||||
(
|
(
|
||||||
this.getGroup(lastRow.groupKey)?.querySelector(
|
this.getGroup(lastRow?.groupKey)?.querySelector(
|
||||||
`data-view-table-row[data-row-id='${lastRow.id}']`
|
`data-view-table-row[data-row-id='${lastRow?.id}']`
|
||||||
) as TableRow | null
|
) as TableRow | null
|
||||||
)?.rowIndex ?? 0;
|
)?.rowIndex ?? 0;
|
||||||
const getRowByIndex = (index: number) => {
|
const getRowByIndex = (index: number) => {
|
||||||
const tableRow = this.rows(lastRow.groupKey)?.item(index);
|
const tableRow = this.rows(lastRow?.groupKey)?.item(index);
|
||||||
if (!tableRow) {
|
if (!tableRow) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
id: tableRow.rowId,
|
id: tableRow.rowId,
|
||||||
groupKey: lastRow.groupKey,
|
groupKey: lastRow?.groupKey,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
const prevRow = getRowByIndex(lastRowIndex - 1);
|
const prevRow = getRowByIndex(lastRowIndex - 1);
|
||||||
@@ -621,10 +625,15 @@ export class TableSelectionController implements ReactiveController {
|
|||||||
add.forEach(row => rows.add(key(row)));
|
add.forEach(row => rows.add(key(row)));
|
||||||
const result = [...rows]
|
const result = [...rows]
|
||||||
.map(r => r.split('.'))
|
.map(r => r.split('.'))
|
||||||
.map(([id, groupKey]) => ({
|
.flatMap(([id, groupKey]) => {
|
||||||
id,
|
if (id == null) return [];
|
||||||
groupKey: groupKey ? groupKey : undefined,
|
return [
|
||||||
}));
|
{
|
||||||
|
id,
|
||||||
|
groupKey: groupKey ? groupKey : undefined,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
});
|
||||||
this.selection = TableRowSelection.create({
|
this.selection = TableRowSelection.create({
|
||||||
rows: result,
|
rows: result,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ export const popRowMenu = (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const row = selection.rows[0];
|
const row = selection.rows[0];
|
||||||
|
if (!row) return;
|
||||||
popFilterableSimpleMenu(ele, [
|
popFilterableSimpleMenu(ele, [
|
||||||
menu.action({
|
menu.action({
|
||||||
name: 'Expand Row',
|
name: 'Expand Row',
|
||||||
|
|||||||
@@ -94,12 +94,15 @@ export class DatabaseColumnStatsCell extends SignalWatcher(
|
|||||||
if (!groups[func.group]) {
|
if (!groups[func.group]) {
|
||||||
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 (!oldFunc || typeSystem.unify(func.dataType, oldFunc.dataType)) {
|
||||||
if (!func.impl) {
|
if (!func.impl) {
|
||||||
delete groups[func.group][func.type];
|
delete groups[func.group]?.[func.type];
|
||||||
} else {
|
} 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 columns = [...this.computedColumns$.value];
|
||||||
const [column] = columns.splice(columnIndex, 1);
|
const [column] = columns.splice(columnIndex, 1);
|
||||||
|
if (!column) return {};
|
||||||
const index = insertPositionToIndex(toAfterOfColumn, columns);
|
const index = insertPositionToIndex(toAfterOfColumn, columns);
|
||||||
columns.splice(index, 0, column);
|
columns.splice(index, 0, column);
|
||||||
return {
|
return {
|
||||||
@@ -356,12 +357,12 @@ export class TableSingleView extends SingleViewBase<TableViewData> {
|
|||||||
this.groupTrait.moveCardTo(rowId, fromGroup, toGroup, position);
|
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);
|
const index = this.rows$.value.indexOf(rowId);
|
||||||
return this.rows$.value[index + 1];
|
return this.rows$.value[index + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
override rowPrevGet(rowId: string): string {
|
override rowPrevGet(rowId: string): string | undefined {
|
||||||
const index = this.rows$.value.indexOf(rowId);
|
const index = this.rows$.value.indexOf(rowId);
|
||||||
return this.rows$.value[index - 1];
|
return this.rows$.value[index - 1];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -233,9 +233,12 @@ export class FilterConditionView extends SignalWatcher(ShadowlessElement) {
|
|||||||
if (!type || !argValues || !data) {
|
if (!type || !argValues || !data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const argDataList = argValues.map((v, i) =>
|
const argDataList = argValues.map((v, i) => {
|
||||||
v ? { value: v, type: type.args[i + 1] } : undefined
|
if (v == null) return undefined;
|
||||||
);
|
const argType = type.args[i + 1];
|
||||||
|
if (!argType) return undefined;
|
||||||
|
return { value: v, type: argType };
|
||||||
|
});
|
||||||
const valueString = data.shortString?.(...argDataList) ?? '';
|
const valueString = data.shortString?.(...argDataList) ?? '';
|
||||||
if (valueString) {
|
if (valueString) {
|
||||||
return `${name}${valueString}`;
|
return `${name}${valueString}`;
|
||||||
|
|||||||
@@ -262,6 +262,9 @@ export class FilterGroupView extends SignalWatcher(ShadowlessElement) {
|
|||||||
|
|
||||||
private _clickConditionOps(target: HTMLElement, i: number) {
|
private _clickConditionOps(target: HTMLElement, i: number) {
|
||||||
const filter = this.filterGroup.value.conditions[i];
|
const filter = this.filterGroup.value.conditions[i];
|
||||||
|
if (!filter) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
popFilterableSimpleMenu(popupTargetFromElement(target), [
|
popFilterableSimpleMenu(popupTargetFromElement(target), [
|
||||||
menu.group({
|
menu.group({
|
||||||
items: [
|
items: [
|
||||||
|
|||||||
@@ -202,6 +202,9 @@ export class FilterRootView extends SignalWatcher(ShadowlessElement) {
|
|||||||
|
|
||||||
private _clickConditionOps(target: HTMLElement, i: number) {
|
private _clickConditionOps(target: HTMLElement, i: number) {
|
||||||
const filter = this.filterGroup.value.conditions[i];
|
const filter = this.filterGroup.value.conditions[i];
|
||||||
|
if (!filter) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
popFilterableSimpleMenu(popupTargetFromElement(target), [
|
popFilterableSimpleMenu(popupTargetFromElement(target), [
|
||||||
menu.action({
|
menu.action({
|
||||||
name: filter.type === 'filter' ? 'Turn into group' : 'Wrap in group',
|
name: filter.type === 'filter' ? 'Turn into group' : 'Wrap in group',
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ export const popViewOptions = (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const isSelected =
|
const isSelected =
|
||||||
meta.type === view.manager.currentView$.value.type;
|
meta.type === view.manager.currentView$.value?.type;
|
||||||
const iconStyle = styleMap({
|
const iconStyle = styleMap({
|
||||||
fontSize: '24px',
|
fontSize: '24px',
|
||||||
color: isSelected
|
color: isSelected
|
||||||
@@ -285,10 +285,11 @@ export const popViewOptions = (
|
|||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
select: () => {
|
select: () => {
|
||||||
view.manager.viewChangeType(
|
const id = view.manager.currentViewId$.value;
|
||||||
view.manager.currentViewId$.value,
|
if (!id) {
|
||||||
meta.type
|
return;
|
||||||
);
|
}
|
||||||
|
view.manager.viewChangeType(id, meta.type);
|
||||||
dataViewInstance.clearSelection();
|
dataViewInstance.clearSelection();
|
||||||
},
|
},
|
||||||
class: {},
|
class: {},
|
||||||
|
|||||||
@@ -148,7 +148,11 @@ export class DataViewHeaderViews extends WidgetBase {
|
|||||||
}
|
}
|
||||||
const views = this.viewManager.views$.value;
|
const views = this.viewManager.views$.value;
|
||||||
const index = views.findIndex(v => v === id);
|
const index = views.findIndex(v => v === id);
|
||||||
const view = this.viewManager.viewGet(views[index]);
|
const viewId = views[index];
|
||||||
|
if (!viewId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const view = this.viewManager.viewGet(viewId);
|
||||||
if (!view) {
|
if (!view) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"rootDir": "./src/",
|
"rootDir": "./src/",
|
||||||
"outDir": "./dist/",
|
"outDir": "./dist/",
|
||||||
"noEmit": false
|
"noEmit": false,
|
||||||
|
"noUncheckedIndexedAccess": true
|
||||||
},
|
},
|
||||||
"include": ["./src"],
|
"include": ["./src"],
|
||||||
"references": [
|
"references": [
|
||||||
|
|||||||
2
packages/common/env/src/ua-helper.ts
vendored
2
packages/common/env/src/ua-helper.ts
vendored
@@ -19,7 +19,7 @@ export class UaHelper {
|
|||||||
console.error('Cannot get chrome version');
|
console.error('Cannot get chrome version');
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return parseInt(raw[2], 10);
|
return parseInt(raw[2] ?? '', 10);
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(private readonly navigator: Navigator) {
|
constructor(private readonly navigator: Navigator) {
|
||||||
|
|||||||
Reference in New Issue
Block a user