Files
AFFiNE-Mirror/blocksuite/affine/data-view/src/property-presets/multi-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

81 lines
2.2 KiB
TypeScript

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 { propertyType } from '../../core/property/property-config.js';
import { SelectPropertySchema } from '../select/define.js';
export const multiSelectPropertyType = propertyType('multi-select');
export const multiSelectPropertyModelConfig =
multiSelectPropertyType.modelConfig({
name: 'Multi-select',
kanbanGroup: {
enabled: true,
mutable: true,
},
propertyData: {
schema: SelectPropertySchema,
default: () => ({
options: [],
}),
},
jsonValue: {
schema: zod.array(zod.string()),
isEmpty: ({ value }) => value.length === 0,
type: ({ data }) => t.array.instance(t.tag.instance(data.options)),
},
rawValue: {
schema: zod.array(zod.string()),
default: () => [],
toString: ({ value, data }) =>
value.map(id => data.options.find(v => v.id === id)?.value).join(','),
fromString: ({ value: oldValue, data }) => {
const optionMap = Object.fromEntries(
data.options.map(v => [v.value, v])
);
const optionNames = oldValue
.split(',')
.map(v => v.trim())
.filter(v => v);
const value: string[] = [];
optionNames.forEach(name => {
if (!optionMap[name]) {
const newOption: SelectTag = {
id: nanoid(),
value: name,
color: getTagColor(),
};
data.options.push(newOption);
value.push(newOption.id);
} else {
value.push(optionMap[name].id);
}
});
return {
value,
data: data,
};
},
toJson: ({ value }) => value ?? null,
fromJson: ({ value }) =>
Array.isArray(value) && value.every(v => typeof v === 'string')
? value
: undefined,
},
addGroup: ({ text, oldData }) => {
return {
options: [
...(oldData.options ?? []),
{
id: nanoid(),
value: text,
color: getTagColor(),
},
],
};
},
});