mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-02 18:09:58 +08:00
refactor(editor): add runtime type checks to database cell values (#10770)
This commit is contained in:
@@ -13,7 +13,11 @@ import {
|
||||
selectPropertyModelConfig,
|
||||
} from './define.js';
|
||||
|
||||
export class SelectCell extends BaseCellRenderer<string, SelectPropertyData> {
|
||||
export class SelectCell extends BaseCellRenderer<
|
||||
string,
|
||||
string,
|
||||
SelectPropertyData
|
||||
> {
|
||||
closePopup?: () => void;
|
||||
private readonly popTagSelect = () => {
|
||||
this.closePopup = popTagSelect(popupTargetFromElement(this), {
|
||||
|
||||
@@ -2,23 +2,66 @@ import { nanoid } from '@blocksuite/store';
|
||||
import zod from 'zod';
|
||||
|
||||
import { getTagColor } from '../../core/component/tags/colors.js';
|
||||
import { type SelectTag, t } from '../../core/index.js';
|
||||
import { type SelectTag, SelectTagSchema, t } from '../../core/index.js';
|
||||
import { propertyType } from '../../core/property/property-config.js';
|
||||
export const selectPropertyType = propertyType('select');
|
||||
|
||||
export type SelectPropertyData = {
|
||||
options: SelectTag[];
|
||||
};
|
||||
export const selectPropertyModelConfig = selectPropertyType.modelConfig<
|
||||
string | undefined,
|
||||
SelectPropertyData
|
||||
>({
|
||||
export const SelectPropertySchema = zod.object({
|
||||
options: zod.array(SelectTagSchema),
|
||||
});
|
||||
export type SelectPropertyData = zod.infer<typeof SelectPropertySchema>;
|
||||
export const selectPropertyModelConfig = selectPropertyType.modelConfig({
|
||||
name: 'Select',
|
||||
valueSchema: zod.string().optional(),
|
||||
type: ({ data }) => t.tag.instance(data.options),
|
||||
defaultData: () => ({
|
||||
options: [],
|
||||
}),
|
||||
propertyData: {
|
||||
schema: SelectPropertySchema,
|
||||
default: () => ({
|
||||
options: [],
|
||||
}),
|
||||
},
|
||||
jsonValue: {
|
||||
schema: zod.string().nullable(),
|
||||
isEmpty: ({ value }) => value == null,
|
||||
type: ({ data }) => t.tag.instance(data.options),
|
||||
},
|
||||
rawValue: {
|
||||
schema: zod.string().nullable(),
|
||||
default: () => null,
|
||||
toString: ({ value, data }) =>
|
||||
data.options.find(v => v.id === value)?.value ?? '',
|
||||
fromString: ({ value: oldValue, data }) => {
|
||||
if (!oldValue) {
|
||||
return { value: null, data: data };
|
||||
}
|
||||
const optionMap = Object.fromEntries(data.options.map(v => [v.value, v]));
|
||||
const name = oldValue
|
||||
.split(',')
|
||||
.map(v => v.trim())
|
||||
.filter(v => v)[0];
|
||||
if (!name) {
|
||||
return { value: null, data: data };
|
||||
}
|
||||
|
||||
let value: string | undefined;
|
||||
const option = optionMap[name];
|
||||
if (!option) {
|
||||
const newOption: SelectTag = {
|
||||
id: nanoid(),
|
||||
value: name,
|
||||
color: getTagColor(),
|
||||
};
|
||||
data.options.push(newOption);
|
||||
value = newOption.id;
|
||||
} else {
|
||||
value = option.id;
|
||||
}
|
||||
|
||||
return {
|
||||
value,
|
||||
data: data,
|
||||
};
|
||||
},
|
||||
toJson: ({ value }) => value,
|
||||
fromJson: ({ value }) => value,
|
||||
},
|
||||
addGroup: ({ text, oldData }) => {
|
||||
return {
|
||||
options: [
|
||||
@@ -27,41 +70,4 @@ export const selectPropertyModelConfig = selectPropertyType.modelConfig<
|
||||
],
|
||||
};
|
||||
},
|
||||
cellToString: ({ value, data }) =>
|
||||
data.options.find(v => v.id === value)?.value ?? '',
|
||||
cellFromString: ({ value: oldValue, data }) => {
|
||||
if (!oldValue) {
|
||||
return { value: null, data: data };
|
||||
}
|
||||
const optionMap = Object.fromEntries(data.options.map(v => [v.value, v]));
|
||||
const name = oldValue
|
||||
.split(',')
|
||||
.map(v => v.trim())
|
||||
.filter(v => v)[0];
|
||||
if (!name) {
|
||||
return { value: null, data: data };
|
||||
}
|
||||
|
||||
let value: string | undefined;
|
||||
const option = optionMap[name];
|
||||
if (!option) {
|
||||
const newOption: SelectTag = {
|
||||
id: nanoid(),
|
||||
value: name,
|
||||
color: getTagColor(),
|
||||
};
|
||||
data.options.push(newOption);
|
||||
value = newOption.id;
|
||||
} else {
|
||||
value = option.id;
|
||||
}
|
||||
|
||||
return {
|
||||
value,
|
||||
data: data,
|
||||
};
|
||||
},
|
||||
cellToJson: ({ value }) => value ?? null,
|
||||
cellFromJson: ({ value }) => (typeof value !== 'string' ? undefined : value),
|
||||
isEmpty: ({ value }) => value == null,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user