Files
AFFiNE-Mirror/blocksuite/affine/data-view/src/property-presets/select/define.ts
DarkSky 8192a492d9 feat: improve kanban grouping & data materialization (#14393)
fix #13512 
fix #13255
fix #9743 

#### PR Dependency Tree


* **PR #14393** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Enhanced Kanban view grouping support for additional property types:
checkboxes, select fields, multi-select fields, members, and created-by
information.
* Improved drag-and-drop visual feedback with more precise drop
indicators in Kanban views.

* **Bug Fixes**
* Refined grouping logic to ensure only compatible properties appear in
group-by options.
* Enhanced column visibility and ordering consistency when managing
Kanban views.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-08 03:48:12 +08:00

78 lines
2.1 KiB
TypeScript

import { nanoid } from '@blocksuite/store';
import zod from 'zod';
import { getTagColor } from '../../core/component/tags/colors.js';
import { type SelectTag, SelectTagSchema, t } from '../../core/index.js';
import { propertyType } from '../../core/property/property-config.js';
export const selectPropertyType = propertyType('select');
export const SelectPropertySchema = zod.object({
options: zod.array(SelectTagSchema),
});
export type SelectPropertyData = zod.infer<typeof SelectPropertySchema>;
export const selectPropertyModelConfig = selectPropertyType.modelConfig({
name: 'Select',
kanbanGroup: {
enabled: true,
mutable: true,
},
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())
.find(v => v);
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: [
...(oldData.options ?? []),
{ id: nanoid(), value: text, color: getTagColor() },
],
};
},
});