@formicoidea/labre-core 0.24.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_pkgs/affine-block-database/database-block.js +7 -2
- package/dist/_pkgs/affine-block-database/service/index.d.ts +12 -1
- package/dist/_pkgs/affine-block-database/service/index.js +1 -0
- package/dist/_pkgs/affine-components/toolbar/toolbar.js +10 -2
- package/dist/_pkgs/affine-gfx-mindmap/toolbar/mindmap-menu.js +1 -1
- package/dist/_pkgs/affine-gfx-mindmap/toolbar/mindmap-tool-button.js +0 -19
- package/dist/_pkgs/affine-model/blocks/database/database-model.d.ts +1 -0
- package/dist/_pkgs/affine-model/blocks/database/database-model.js +2 -1
- package/dist/_pkgs/affine-widget-edgeless-toolbar/edgeless-toolbar.js +6 -0
- package/dist/_pkgs/affine-widget-toolbar/utils.js +5 -1
- package/dist/_pkgs/std/effects.js +12 -5
- package/dist/extensions/view.js +0 -6
- package/dist/flags.d.ts +1 -1
- package/dist/flags.js +0 -4
- package/package.json +1 -1
- package/dist/_pkgs/affine-gfx-ddd/core-domain/consts.d.ts +0 -32
- package/dist/_pkgs/affine-gfx-ddd/core-domain/consts.js +0 -30
- package/dist/_pkgs/affine-gfx-ddd/core-domain/element-renderer.d.ts +0 -12
- package/dist/_pkgs/affine-gfx-ddd/core-domain/element-renderer.js +0 -93
- package/dist/_pkgs/affine-gfx-ddd/core-domain/element-view.d.ts +0 -11
- package/dist/_pkgs/affine-gfx-ddd/core-domain/element-view.js +0 -20
- package/dist/_pkgs/affine-gfx-ddd/core-domain/legend.d.ts +0 -18
- package/dist/_pkgs/affine-gfx-ddd/core-domain/legend.js +0 -69
- package/dist/_pkgs/affine-gfx-ddd/core-domain/toolbar-config.d.ts +0 -1
- package/dist/_pkgs/affine-gfx-ddd/core-domain/toolbar-config.js +0 -45
- package/dist/_pkgs/affine-gfx-ddd/effects.d.ts +0 -17
- package/dist/_pkgs/affine-gfx-ddd/effects.js +0 -21
- package/dist/_pkgs/affine-gfx-ddd/index.d.ts +0 -2
- package/dist/_pkgs/affine-gfx-ddd/index.js +0 -2
- package/dist/_pkgs/affine-gfx-ddd/shared/consts.d.ts +0 -180
- package/dist/_pkgs/affine-gfx-ddd/shared/consts.js +0 -92
- package/dist/_pkgs/affine-gfx-ddd/shared/prefabs.d.ts +0 -71
- package/dist/_pkgs/affine-gfx-ddd/shared/prefabs.js +0 -214
- package/dist/_pkgs/affine-gfx-ddd/shared/utils.d.ts +0 -10
- package/dist/_pkgs/affine-gfx-ddd/shared/utils.js +0 -9
- package/dist/_pkgs/affine-gfx-ddd/templates/components.d.ts +0 -7
- package/dist/_pkgs/affine-gfx-ddd/templates/components.js +0 -158
- package/dist/_pkgs/affine-gfx-ddd/templates/index.d.ts +0 -11
- package/dist/_pkgs/affine-gfx-ddd/templates/index.js +0 -108
- package/dist/_pkgs/affine-gfx-ddd/toolbar/context-map-menu.d.ts +0 -10
- package/dist/_pkgs/affine-gfx-ddd/toolbar/context-map-menu.js +0 -109
- package/dist/_pkgs/affine-gfx-ddd/toolbar/core-domain-menu.d.ts +0 -11
- package/dist/_pkgs/affine-gfx-ddd/toolbar/core-domain-menu.js +0 -118
- package/dist/_pkgs/affine-gfx-ddd/toolbar/event-storming-menu.d.ts +0 -9
- package/dist/_pkgs/affine-gfx-ddd/toolbar/event-storming-menu.js +0 -78
- package/dist/_pkgs/affine-gfx-ddd/toolbar/icons.d.ts +0 -6
- package/dist/_pkgs/affine-gfx-ddd/toolbar/icons.js +0 -20
- package/dist/_pkgs/affine-gfx-ddd/toolbar/menu-base.d.ts +0 -23
- package/dist/_pkgs/affine-gfx-ddd/toolbar/menu-base.js +0 -62
- package/dist/_pkgs/affine-gfx-ddd/toolbar/senior-buttons.d.ts +0 -34
- package/dist/_pkgs/affine-gfx-ddd/toolbar/senior-buttons.js +0 -114
- package/dist/_pkgs/affine-gfx-ddd/toolbar/senior-tool.d.ts +0 -6
- package/dist/_pkgs/affine-gfx-ddd/toolbar/senior-tool.js +0 -23
- package/dist/_pkgs/affine-gfx-ddd/view.d.ts +0 -35
- package/dist/_pkgs/affine-gfx-ddd/view.js +0 -95
|
@@ -24,6 +24,7 @@ import { databaseBlockStyles, databaseContentStyles, databaseHeaderBarStyles, da
|
|
|
24
24
|
import { BlockRenderer } from './detail-panel/block-renderer.js';
|
|
25
25
|
import { NoteRenderer } from './detail-panel/note-renderer.js';
|
|
26
26
|
import { DatabaseSelection } from './selection.js';
|
|
27
|
+
import { DatabaseDataSourceProvider } from './service/index.js';
|
|
27
28
|
import { currentViewStorage } from './utils/current-view.js';
|
|
28
29
|
import { getSingleDocIdFromText } from './utils/title-doc.js';
|
|
29
30
|
export class DatabaseBlockComponent extends CaptionedBlockComponent {
|
|
@@ -88,14 +89,18 @@ export class DatabaseBlockComponent extends CaptionedBlockComponent {
|
|
|
88
89
|
});
|
|
89
90
|
};
|
|
90
91
|
this.dataSource = lazy(() => {
|
|
91
|
-
const
|
|
92
|
+
const initFn = (dataSource) => {
|
|
92
93
|
dataSource.serviceSet(EditorHostKey, this.host);
|
|
93
94
|
this.std.provider
|
|
94
95
|
.getAll(ExternalGroupByConfigProvider)
|
|
95
96
|
.forEach(config => {
|
|
96
97
|
dataSource.serviceSet(ExternalGroupByConfigProvider(config.name), config);
|
|
97
98
|
});
|
|
98
|
-
}
|
|
99
|
+
};
|
|
100
|
+
const provider = this.std.getOptional(DatabaseDataSourceProvider);
|
|
101
|
+
const dataSource = provider && this.model.props.externalSourceId
|
|
102
|
+
? provider.createDataSource(this.model, initFn)
|
|
103
|
+
: new DatabaseBlockDataSource(this.model, initFn);
|
|
99
104
|
const id = currentViewStorage.getCurrentView(this.model.id);
|
|
100
105
|
if (id && dataSource.viewManager.viewGet(id)) {
|
|
101
106
|
dataSource.viewManager.setCurrentView(id);
|
|
@@ -1,5 +1,16 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DatabaseBlockModel } from '../../affine-model/index.js';
|
|
2
|
+
import type { DataSourceBase, PropertyMetaConfig } from '../../data-view/index.js';
|
|
2
3
|
export interface DatabaseBlockConfigService {
|
|
3
4
|
propertiesPresets: PropertyMetaConfig[];
|
|
4
5
|
}
|
|
5
6
|
export declare const DatabaseBlockConfigService: import("../../global/di/types.js").ServiceIdentifier<DatabaseBlockConfigService> & (<U extends DatabaseBlockConfigService = DatabaseBlockConfigService>(variant: import("../../global/di/types.js").ServiceVariant) => import("../../global/di/types.js").ServiceIdentifier<U>);
|
|
7
|
+
/**
|
|
8
|
+
* Injection seam: a host app may register this provider to back an
|
|
9
|
+
* `affine:database` block with its own data source (e.g. an external
|
|
10
|
+
* collection). Only used when the block carries an `externalSourceId`; with no
|
|
11
|
+
* provider registered the block falls back to the inline blob source.
|
|
12
|
+
*/
|
|
13
|
+
export interface DatabaseDataSourceProvider {
|
|
14
|
+
createDataSource(model: DatabaseBlockModel, init?: (ds: DataSourceBase) => void): DataSourceBase;
|
|
15
|
+
}
|
|
16
|
+
export declare const DatabaseDataSourceProvider: import("../../global/di/types.js").ServiceIdentifier<DatabaseDataSourceProvider> & (<U extends DatabaseDataSourceProvider = DatabaseDataSourceProvider>(variant: import("../../global/di/types.js").ServiceVariant) => import("../../global/di/types.js").ServiceIdentifier<U>);
|
|
@@ -6,8 +6,14 @@ export class EditorToolbar extends WithDisposable(LitElement) {
|
|
|
6
6
|
static { this.styles = css `
|
|
7
7
|
${panelBaseStyle(':host')}
|
|
8
8
|
:host {
|
|
9
|
-
height: 36px;
|
|
9
|
+
min-height: 36px;
|
|
10
10
|
box-sizing: content-box;
|
|
11
|
+
/* ponytail: wrap to a second row instead of overflowing on mobile. The
|
|
12
|
+
width is capped to availableWidth by floating-ui's size middleware;
|
|
13
|
+
wrapping (not scrolling) keeps the "More" dropdown clickable — it is a
|
|
14
|
+
descendant of this toolbar, so an overflow container would clip it. */
|
|
15
|
+
flex-wrap: wrap;
|
|
16
|
+
row-gap: 4px;
|
|
11
17
|
}
|
|
12
18
|
|
|
13
19
|
:host([data-without-bg]) {
|
|
@@ -18,7 +24,9 @@ export class EditorToolbar extends WithDisposable(LitElement) {
|
|
|
18
24
|
|
|
19
25
|
::slotted(*) {
|
|
20
26
|
display: flex;
|
|
21
|
-
height
|
|
27
|
+
/* fixed row height (not 100%) so each item stays one row tall when the
|
|
28
|
+
toolbar wraps to multiple rows */
|
|
29
|
+
height: 36px;
|
|
22
30
|
justify-content: center;
|
|
23
31
|
align-items: center;
|
|
24
32
|
gap: 8px;
|
|
@@ -77,11 +77,6 @@ let EdgelessMindmapToolButton = (() => {
|
|
|
77
77
|
display: flex;
|
|
78
78
|
justify-content: center;
|
|
79
79
|
align-items: center;
|
|
80
|
-
/* Make this button the containing block of the popup's clip wrapper so
|
|
81
|
-
the "Others" sub-menu anchors to THIS button (not the whole toolbar)
|
|
82
|
-
and can be right-aligned to it — mirrors the framework senior buttons.
|
|
83
|
-
Without this the menu drifts when senior buttons are hidden. */
|
|
84
|
-
position: relative;
|
|
85
80
|
}
|
|
86
81
|
.partial-clip {
|
|
87
82
|
flex-shrink: 0;
|
|
@@ -196,20 +191,6 @@ let EdgelessMindmapToolButton = (() => {
|
|
|
196
191
|
});
|
|
197
192
|
},
|
|
198
193
|
});
|
|
199
|
-
// Right-align the menu's right edge to this button's right edge, like the
|
|
200
|
-
// framework senior buttons. Stays correct however many buttons are hidden.
|
|
201
|
-
const el = menu.element;
|
|
202
|
-
const wrap = el.parentElement;
|
|
203
|
-
if (wrap) {
|
|
204
|
-
wrap.style.overflow = 'visible';
|
|
205
|
-
wrap.style.justifyContent = 'flex-end';
|
|
206
|
-
}
|
|
207
|
-
Object.assign(el.style, {
|
|
208
|
-
position: 'static',
|
|
209
|
-
width: 'max-content',
|
|
210
|
-
maxWidth: 'calc(100vw - 16px)',
|
|
211
|
-
marginLeft: '0',
|
|
212
|
-
});
|
|
213
194
|
}
|
|
214
195
|
initDragController() {
|
|
215
196
|
if (!this.edgeless || !this.toolbarContainer)
|
|
@@ -9,10 +9,11 @@ export const DatabaseBlockSchema = defineBlockSchema({
|
|
|
9
9
|
cells: Object.create(null),
|
|
10
10
|
columns: [],
|
|
11
11
|
comments: undefined,
|
|
12
|
+
externalSourceId: undefined,
|
|
12
13
|
}),
|
|
13
14
|
metadata: {
|
|
14
15
|
role: 'hub',
|
|
15
|
-
version:
|
|
16
|
+
version: 4,
|
|
16
17
|
parent: ['affine:note'],
|
|
17
18
|
children: ['affine:paragraph', 'affine:list'],
|
|
18
19
|
},
|
|
@@ -65,6 +65,10 @@ const SENIOR_TOOL_NAV_SIZE = 20;
|
|
|
65
65
|
const DIVIDER_WIDTH = 8;
|
|
66
66
|
const DIVIDER_SPACE = 8;
|
|
67
67
|
const SAFE_AREA_WIDTH = 64;
|
|
68
|
+
// Cap the whole toolbar width so the centered senior sub-menus land close to
|
|
69
|
+
// the buttons. The ResizeObserver reads the host width, so the senior-tool
|
|
70
|
+
// scroll adapts to this cap; on viewports narrower than it, it has no effect.
|
|
71
|
+
const TOOLBAR_MAX_WIDTH = 900;
|
|
68
72
|
export const EDGELESS_TOOLBAR_WIDGET = 'edgeless-toolbar-widget';
|
|
69
73
|
let EdgelessToolbarWidget = (() => {
|
|
70
74
|
let _classSuper = WidgetComponent;
|
|
@@ -109,6 +113,8 @@ let EdgelessToolbarWidget = (() => {
|
|
|
109
113
|
-webkit-user-select: none;
|
|
110
114
|
user-select: none;
|
|
111
115
|
width: 100%;
|
|
116
|
+
/* cap + center the toolbar so centered senior sub-menus stay near the buttons */
|
|
117
|
+
max-width: ${unsafeCSS(TOOLBAR_MAX_WIDTH)}px;
|
|
112
118
|
pointer-events: none;
|
|
113
119
|
}
|
|
114
120
|
.edgeless-toolbar-wrapper {
|
|
@@ -46,8 +46,12 @@ export function autoUpdatePosition(signal, toolbar, referenceElement, flavour, p
|
|
|
46
46
|
middleware: [
|
|
47
47
|
offset(10 + offsetY),
|
|
48
48
|
size({
|
|
49
|
-
|
|
49
|
+
padding: 10,
|
|
50
|
+
apply: ({ elements, availableWidth }) => {
|
|
50
51
|
elements.floating.style.width = 'fit-content';
|
|
52
|
+
// ponytail: cap to viewport so the toolbar scrolls instead of
|
|
53
|
+
// overflowing off-screen on mobile; drop into "⋮" if scroll feels off
|
|
54
|
+
elements.floating.style.maxWidth = `${availableWidth}px`;
|
|
51
55
|
},
|
|
52
56
|
}),
|
|
53
57
|
isInline ? inline() : undefined,
|
|
@@ -3,11 +3,18 @@ import { VElement, VLine, VText } from './inline/index.js';
|
|
|
3
3
|
import { EditorHost } from './view/index.js';
|
|
4
4
|
export function effects() {
|
|
5
5
|
// editor host
|
|
6
|
-
|
|
6
|
+
define('editor-host', EditorHost);
|
|
7
7
|
// gfx
|
|
8
|
-
|
|
8
|
+
define('gfx-viewport', GfxViewportElement);
|
|
9
9
|
// inline
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
define('v-element', VElement);
|
|
11
|
+
define('v-line', VLine);
|
|
12
|
+
define('v-text', VText);
|
|
13
|
+
}
|
|
14
|
+
// ponytail: idempotent so effects() can run more than once (e.g. across browser
|
|
15
|
+
// unit-test files sharing a registry) without throwing on re-registration.
|
|
16
|
+
function define(name, ctor) {
|
|
17
|
+
if (!customElements.get(name)) {
|
|
18
|
+
customElements.define(name, ctor);
|
|
19
|
+
}
|
|
13
20
|
}
|
package/dist/extensions/view.js
CHANGED
|
@@ -25,7 +25,6 @@ import { FramePanelViewExtension } from '../_pkgs/affine-fragment-frame-panel/vi
|
|
|
25
25
|
import { OutlineViewExtension } from '../_pkgs/affine-fragment-outline/view.js';
|
|
26
26
|
import { BrushViewExtension } from '../_pkgs/affine-gfx-brush/view.js';
|
|
27
27
|
import { ConnectorViewExtension } from '../_pkgs/affine-gfx-connector/view.js';
|
|
28
|
-
import { DddContextMapViewExtension, DddCoreDomainRenderViewExtension, DddCoreDomainViewExtension, DddEventStormingViewExtension, DddTemplatesViewExtension, } from '../_pkgs/affine-gfx-ddd/view.js';
|
|
29
28
|
import { GroupViewExtension } from '../_pkgs/affine-gfx-group/view.js';
|
|
30
29
|
import { LinkViewExtension as GfxLinkViewExtension } from '../_pkgs/affine-gfx-link/view.js';
|
|
31
30
|
import { MindmapRenderViewExtension, MindmapToolViewExtension, OtherToolViewExtension, } from '../_pkgs/affine-gfx-mindmap/view.js';
|
|
@@ -81,11 +80,6 @@ export function getInternalViewExtensions(flags) {
|
|
|
81
80
|
...(on('template') ? [TemplateViewExtension] : []),
|
|
82
81
|
...(on('link') ? [GfxLinkViewExtension] : []),
|
|
83
82
|
// Core Domain rendering is always on; the flag gates only the senior button.
|
|
84
|
-
DddCoreDomainRenderViewExtension,
|
|
85
|
-
...(on('ddd-event-storming') ? [DddEventStormingViewExtension] : []),
|
|
86
|
-
...(on('ddd-core-domain') ? [DddCoreDomainViewExtension] : []),
|
|
87
|
-
...(on('ddd-context-map') ? [DddContextMapViewExtension] : []),
|
|
88
|
-
...(on('ddd-templates') ? [DddTemplatesViewExtension] : []),
|
|
89
83
|
// Block
|
|
90
84
|
...(on('attachment') ? [AttachmentViewExtension] : []),
|
|
91
85
|
...(on('bookmark') ? [BookmarkViewExtension] : []),
|
package/dist/flags.d.ts
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
* - `latex` controls both the latex block and inline latex.
|
|
24
24
|
* - `frame` also controls the frame panel fragment.
|
|
25
25
|
*/
|
|
26
|
-
export declare const OPTIONAL_BLOCKS: readonly ["attachment", "bookmark", "callout", "code", "data-view", "database", "divider", "edgeless-text", "embed", "embed-doc", "frame", "image", "latex", "list", "surface-ref", "table", "brush", "mindmap", "other", "template", "link"
|
|
26
|
+
export declare const OPTIONAL_BLOCKS: readonly ["attachment", "bookmark", "callout", "code", "data-view", "database", "divider", "edgeless-text", "embed", "embed-doc", "frame", "image", "latex", "list", "surface-ref", "table", "brush", "mindmap", "other", "template", "link"];
|
|
27
27
|
export type OptionalBlock = (typeof OPTIONAL_BLOCKS)[number];
|
|
28
28
|
/** Map of optional block -> enabled. Missing keys default to enabled. */
|
|
29
29
|
export type BlockFlags = Partial<Record<OptionalBlock, boolean>>;
|
package/dist/flags.js
CHANGED
package/package.json
CHANGED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Visual constants for the Core Domain Chart background (DDD Crew). Authored in
|
|
3
|
-
* a fixed reference space (900 × 820) and scaled uniformly to the element bounds
|
|
4
|
-
* by the renderer. Reproduces the supplied template: two axes (Complexity ×
|
|
5
|
-
* Business differentiation), Low/High ticks and the translucent Generic /
|
|
6
|
-
* Supporting / Core zone bands. The "Notation" legend is a separate prefab group.
|
|
7
|
-
*/
|
|
8
|
-
export declare const REF_W = 900;
|
|
9
|
-
export declare const REF_H = 820;
|
|
10
|
-
export declare const COLORS: {
|
|
11
|
-
readonly axis: "#000000";
|
|
12
|
-
readonly zoneLabel: "#ffffff";
|
|
13
|
-
readonly tick: "#777777";
|
|
14
|
-
readonly title: "#000000";
|
|
15
|
-
};
|
|
16
|
-
/** Translucent zone bands (drawn at 0.6 alpha), back-to-front. */
|
|
17
|
-
export declare const ZONES: ReadonlyArray<{
|
|
18
|
-
x: number;
|
|
19
|
-
y: number;
|
|
20
|
-
w: number;
|
|
21
|
-
h: number;
|
|
22
|
-
fill: string;
|
|
23
|
-
}>;
|
|
24
|
-
/** Zone names (centred): [text, x, y, fontSize]. */
|
|
25
|
-
export declare const ZONE_LABELS: ReadonlyArray<readonly [string, number, number, number]>;
|
|
26
|
-
/** Axis frame: origin (ox, oy) bottom-left, up to `top`, right to `right`. */
|
|
27
|
-
export declare const AXIS: {
|
|
28
|
-
readonly ox: 60;
|
|
29
|
-
readonly oy: 770;
|
|
30
|
-
readonly top: 24;
|
|
31
|
-
readonly right: 846;
|
|
32
|
-
};
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Visual constants for the Core Domain Chart background (DDD Crew). Authored in
|
|
3
|
-
* a fixed reference space (900 × 820) and scaled uniformly to the element bounds
|
|
4
|
-
* by the renderer. Reproduces the supplied template: two axes (Complexity ×
|
|
5
|
-
* Business differentiation), Low/High ticks and the translucent Generic /
|
|
6
|
-
* Supporting / Core zone bands. The "Notation" legend is a separate prefab group.
|
|
7
|
-
*/
|
|
8
|
-
export const REF_W = 900;
|
|
9
|
-
export const REF_H = 820;
|
|
10
|
-
export const COLORS = {
|
|
11
|
-
axis: '#000000',
|
|
12
|
-
zoneLabel: '#ffffff',
|
|
13
|
-
tick: '#777777',
|
|
14
|
-
title: '#000000',
|
|
15
|
-
};
|
|
16
|
-
/** Translucent zone bands (drawn at 0.6 alpha), back-to-front. */
|
|
17
|
-
export const ZONES = [
|
|
18
|
-
{ x: 70, y: 30, w: 150, h: 720, fill: '#b3b3b3' },
|
|
19
|
-
{ x: 220, y: 30, w: 220, h: 720, fill: '#9933ff' },
|
|
20
|
-
{ x: 440, y: 30, w: 400, h: 360, fill: '#4d9900' },
|
|
21
|
-
{ x: 440, y: 390, w: 400, h: 360, fill: '#9933ff' },
|
|
22
|
-
];
|
|
23
|
-
/** Zone names (centred): [text, x, y, fontSize]. */
|
|
24
|
-
export const ZONE_LABELS = [
|
|
25
|
-
['Core', 640, 214, 26],
|
|
26
|
-
['Supporting', 340, 474, 20],
|
|
27
|
-
['Generic', 150, 474, 20],
|
|
28
|
-
];
|
|
29
|
-
/** Axis frame: origin (ox, oy) bottom-left, up to `top`, right to `right`. */
|
|
30
|
-
export const AXIS = { ox: 60, oy: 770, top: 24, right: 846 };
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { type ElementRenderer } from '../../affine-block-surface/index.js';
|
|
2
|
-
import type { CoreDomainChartElementModel } from '../../affine-model/index.js';
|
|
3
|
-
/**
|
|
4
|
-
* Canvas renderer for the Core Domain Chart background — the translucent
|
|
5
|
-
* Generic / Supporting / Core zone bands, the two axes with arrow heads and the
|
|
6
|
-
* Low/High ticks + zone names. Drawn in the fixed reference space and scaled
|
|
7
|
-
* uniformly to the element bounds.
|
|
8
|
-
*/
|
|
9
|
-
export declare const coreDomain: ElementRenderer<CoreDomainChartElementModel>;
|
|
10
|
-
export declare const CoreDomainRendererExtension: import("../../store/index.js").ExtensionType & {
|
|
11
|
-
identifier: import("../../global/di/types.js").ServiceIdentifier<ElementRenderer<CoreDomainChartElementModel>>;
|
|
12
|
-
};
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { ElementRendererExtension, } from '../../affine-block-surface/index.js';
|
|
2
|
-
import { FONT_FAMILY, refScale } from '../shared/utils';
|
|
3
|
-
import { AXIS, COLORS, REF_H, REF_W, ZONE_LABELS, ZONES } from './consts';
|
|
4
|
-
/**
|
|
5
|
-
* Canvas renderer for the Core Domain Chart background — the translucent
|
|
6
|
-
* Generic / Supporting / Core zone bands, the two axes with arrow heads and the
|
|
7
|
-
* Low/High ticks + zone names. Drawn in the fixed reference space and scaled
|
|
8
|
-
* uniformly to the element bounds.
|
|
9
|
-
*/
|
|
10
|
-
export const coreDomain = (model, ctx, matrix) => {
|
|
11
|
-
const [, , w, h] = model.deserializedXYWH;
|
|
12
|
-
const cx = w / 2;
|
|
13
|
-
const cy = h / 2;
|
|
14
|
-
ctx.setTransform(matrix.translateSelf(cx, cy).rotateSelf(model.rotate).translateSelf(-cx, -cy));
|
|
15
|
-
const { s, ox, oy } = refScale(w, h, REF_W, REF_H);
|
|
16
|
-
ctx.translate(ox, oy);
|
|
17
|
-
ctx.scale(s, s);
|
|
18
|
-
// ── Translucent zone bands ──────────────────────────────────────────
|
|
19
|
-
if (model.showZones) {
|
|
20
|
-
ctx.globalAlpha = 0.6;
|
|
21
|
-
for (const z of ZONES) {
|
|
22
|
-
ctx.fillStyle = z.fill;
|
|
23
|
-
ctx.fillRect(z.x, z.y, z.w, z.h);
|
|
24
|
-
}
|
|
25
|
-
ctx.globalAlpha = 1;
|
|
26
|
-
}
|
|
27
|
-
// ── Axes with arrow heads ───────────────────────────────────────────
|
|
28
|
-
ctx.strokeStyle = COLORS.axis;
|
|
29
|
-
ctx.fillStyle = COLORS.axis;
|
|
30
|
-
ctx.lineWidth = 2;
|
|
31
|
-
ctx.lineJoin = 'round';
|
|
32
|
-
// Y axis (up)
|
|
33
|
-
ctx.beginPath();
|
|
34
|
-
ctx.moveTo(AXIS.ox, AXIS.oy);
|
|
35
|
-
ctx.lineTo(AXIS.ox, AXIS.top + 6);
|
|
36
|
-
ctx.stroke();
|
|
37
|
-
arrow(ctx, AXIS.ox, AXIS.top, 0);
|
|
38
|
-
// X axis (right)
|
|
39
|
-
ctx.beginPath();
|
|
40
|
-
ctx.moveTo(AXIS.ox, AXIS.oy);
|
|
41
|
-
ctx.lineTo(AXIS.right - 6, AXIS.oy);
|
|
42
|
-
ctx.stroke();
|
|
43
|
-
arrow(ctx, AXIS.right, AXIS.oy, 90);
|
|
44
|
-
ctx.textBaseline = 'alphabetic';
|
|
45
|
-
// ── Zone names ──────────────────────────────────────────────────────
|
|
46
|
-
ctx.textAlign = 'center';
|
|
47
|
-
for (const [text, x, y, size] of ZONE_LABELS) {
|
|
48
|
-
ctx.fillStyle = COLORS.zoneLabel;
|
|
49
|
-
ctx.font = `700 ${size}px ${FONT_FAMILY}`;
|
|
50
|
-
ctx.fillText(text, x, y);
|
|
51
|
-
}
|
|
52
|
-
// ── Axis titles + Low/High ticks ────────────────────────────────────
|
|
53
|
-
if (model.showLabels) {
|
|
54
|
-
ctx.fillStyle = COLORS.title;
|
|
55
|
-
ctx.font = `600 14px ${FONT_FAMILY}`;
|
|
56
|
-
ctx.save();
|
|
57
|
-
ctx.translate(28, 400);
|
|
58
|
-
ctx.rotate(-Math.PI / 2);
|
|
59
|
-
ctx.fillText('Complexity', 0, 0);
|
|
60
|
-
ctx.restore();
|
|
61
|
-
ctx.fillText('Business differentiation', 450, 800);
|
|
62
|
-
ctx.fillStyle = COLORS.tick;
|
|
63
|
-
ctx.font = `12px ${FONT_FAMILY}`;
|
|
64
|
-
// X ticks
|
|
65
|
-
ctx.fillText('Low', 84, 792);
|
|
66
|
-
ctx.fillText('High', 838, 792);
|
|
67
|
-
// Y ticks
|
|
68
|
-
ctx.save();
|
|
69
|
-
ctx.translate(48, 758);
|
|
70
|
-
ctx.rotate(-Math.PI / 2);
|
|
71
|
-
ctx.fillText('Low', 0, 0);
|
|
72
|
-
ctx.restore();
|
|
73
|
-
ctx.save();
|
|
74
|
-
ctx.translate(38, 44);
|
|
75
|
-
ctx.rotate(-Math.PI / 2);
|
|
76
|
-
ctx.fillText('High', 0, 0);
|
|
77
|
-
ctx.restore();
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
/** Filled triangular arrow head at (x, y); `deg` rotates it (0 = pointing up). */
|
|
81
|
-
function arrow(ctx, x, y, deg) {
|
|
82
|
-
ctx.save();
|
|
83
|
-
ctx.translate(x, y);
|
|
84
|
-
ctx.rotate((deg * Math.PI) / 180);
|
|
85
|
-
ctx.beginPath();
|
|
86
|
-
ctx.moveTo(0, 0);
|
|
87
|
-
ctx.lineTo(-5, 9);
|
|
88
|
-
ctx.lineTo(5, 9);
|
|
89
|
-
ctx.closePath();
|
|
90
|
-
ctx.fill();
|
|
91
|
-
ctx.restore();
|
|
92
|
-
}
|
|
93
|
-
export const CoreDomainRendererExtension = ElementRendererExtension('coreDomain', coreDomain);
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { CoreDomainChartElementModel } from '../../affine-model/index.js';
|
|
2
|
-
import { GfxElementModelView } from '../../std/gfx/index.js';
|
|
3
|
-
/**
|
|
4
|
-
* View for the Core Domain Chart background. Registering it ensures
|
|
5
|
-
* `gfx.view.get(model)` returns a view (required so move / select work).
|
|
6
|
-
*/
|
|
7
|
-
export declare class CoreDomainView extends GfxElementModelView<CoreDomainChartElementModel> {
|
|
8
|
-
static type: string;
|
|
9
|
-
}
|
|
10
|
-
/** Resize gating: handles hidden unless `model.resizeEnabled` (toolbar toggle). */
|
|
11
|
-
export declare const CoreDomainInteraction: import("../../store/index.js").ExtensionType;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { GfxElementModelView, GfxViewInteractionExtension, } from '../../std/gfx/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* View for the Core Domain Chart background. Registering it ensures
|
|
4
|
-
* `gfx.view.get(model)` returns a view (required so move / select work).
|
|
5
|
-
*/
|
|
6
|
-
export class CoreDomainView extends GfxElementModelView {
|
|
7
|
-
static { this.type = 'coreDomain'; }
|
|
8
|
-
}
|
|
9
|
-
/** Resize gating: handles hidden unless `model.resizeEnabled` (toolbar toggle). */
|
|
10
|
-
export const CoreDomainInteraction = GfxViewInteractionExtension(CoreDomainView.type, {
|
|
11
|
-
handleResize({ model }) {
|
|
12
|
-
return {
|
|
13
|
-
beforeResize({ set }) {
|
|
14
|
-
if (!model.resizeEnabled) {
|
|
15
|
-
set({ allowedHandlers: [] });
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
|
-
};
|
|
19
|
-
},
|
|
20
|
-
});
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { type CoreDomainChartElementModel } from '../../affine-model/index.js';
|
|
2
|
-
import type { BlockStdScope } from '../../std/index.js';
|
|
3
|
-
import { type LegendSection } from '../shared/prefabs';
|
|
4
|
-
/**
|
|
5
|
-
* Build the Notation legend sections. When `present` is given (a content-aware
|
|
6
|
-
* scan of the background), only the sub-domain types / team-topology modes /
|
|
7
|
-
* movement actually used are listed; otherwise the full notation is shown.
|
|
8
|
-
*/
|
|
9
|
-
export declare function coreDomainLegendSections(present?: {
|
|
10
|
-
fills: Set<string>;
|
|
11
|
-
movement: boolean;
|
|
12
|
-
}): LegendSection[];
|
|
13
|
-
/**
|
|
14
|
-
* Insert a content-aware legend next to a Core Domain background: scans the
|
|
15
|
-
* shapes/connectors inside the background's perimeter and lists only the
|
|
16
|
-
* notation actually present. Triggered from the element's contextual toolbar.
|
|
17
|
-
*/
|
|
18
|
-
export declare function createCoreDomainLegend(std: BlockStdScope, bg: CoreDomainChartElementModel): void;
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { ConnectorElementModel, ShapeElementModel, StrokeStyle, } from '../../affine-model/index.js';
|
|
2
|
-
import { Bound } from '../../global/gfx/index.js';
|
|
3
|
-
import { GfxControllerIdentifier } from '../../std/gfx/index.js';
|
|
4
|
-
import { CD_SUBDOMAINS, MOVEMENT_COLOR, TEAM_TOPOLOGIES, } from '../shared/consts';
|
|
5
|
-
import { addLegend } from '../shared/prefabs';
|
|
6
|
-
/**
|
|
7
|
-
* Build the Notation legend sections. When `present` is given (a content-aware
|
|
8
|
-
* scan of the background), only the sub-domain types / team-topology modes /
|
|
9
|
-
* movement actually used are listed; otherwise the full notation is shown.
|
|
10
|
-
*/
|
|
11
|
-
export function coreDomainLegendSections(present) {
|
|
12
|
-
const has = (c) => !present || present.fills.has(c.toLowerCase());
|
|
13
|
-
const subRows = CD_SUBDOMAINS.filter(s => has(s.fill)).map(s => ({
|
|
14
|
-
swatch: 'dot',
|
|
15
|
-
color: s.fill,
|
|
16
|
-
label: s.label,
|
|
17
|
-
}));
|
|
18
|
-
const ttRows = TEAM_TOPOLOGIES.filter(t => has(t.fill)).map(t => ({
|
|
19
|
-
swatch: 'square',
|
|
20
|
-
color: t.fill,
|
|
21
|
-
letter: t.letter,
|
|
22
|
-
label: t.label,
|
|
23
|
-
}));
|
|
24
|
-
const sections = [];
|
|
25
|
-
if (subRows.length)
|
|
26
|
-
sections.push({ title: 'Sub-domains', rows: subRows });
|
|
27
|
-
if (ttRows.length)
|
|
28
|
-
sections.push({ title: 'Team topologies', rows: ttRows });
|
|
29
|
-
if (!present || present.movement) {
|
|
30
|
-
sections.push({
|
|
31
|
-
title: 'Movement',
|
|
32
|
-
rows: [{ swatch: 'line', color: MOVEMENT_COLOR, label: 'Movement over time' }],
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
// Content-aware scan found nothing recognizable → fall back to the full legend.
|
|
36
|
-
if (present && sections.length === 0)
|
|
37
|
-
return coreDomainLegendSections();
|
|
38
|
-
return sections;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Insert a content-aware legend next to a Core Domain background: scans the
|
|
42
|
-
* shapes/connectors inside the background's perimeter and lists only the
|
|
43
|
-
* notation actually present. Triggered from the element's contextual toolbar.
|
|
44
|
-
*/
|
|
45
|
-
export function createCoreDomainLegend(std, bg) {
|
|
46
|
-
const gfx = std.get(GfxControllerIdentifier);
|
|
47
|
-
const surface = gfx.surface;
|
|
48
|
-
if (!surface)
|
|
49
|
-
return;
|
|
50
|
-
const fills = new Set();
|
|
51
|
-
let movement = false;
|
|
52
|
-
for (const el of gfx.getElementsByBound(Bound.deserialize(bg.xywh), {
|
|
53
|
-
type: 'canvas',
|
|
54
|
-
})) {
|
|
55
|
-
if (el instanceof ConnectorElementModel) {
|
|
56
|
-
if (el.strokeStyle === StrokeStyle.Dash)
|
|
57
|
-
movement = true;
|
|
58
|
-
}
|
|
59
|
-
else if (el instanceof ShapeElementModel) {
|
|
60
|
-
if (typeof el.fillColor === 'string')
|
|
61
|
-
fills.add(el.fillColor.toLowerCase());
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
const [bx, by, bw] = bg.deserializedXYWH;
|
|
65
|
-
addLegend(surface, std, bx + bw + 30, by, {
|
|
66
|
-
title: 'Légende',
|
|
67
|
-
sections: coreDomainLegendSections({ fills, movement }),
|
|
68
|
-
});
|
|
69
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const coreDomainToolbarExtension: import("../../store/index.js").ExtensionType;
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { CoreDomainChartElementModel } from '../../affine-model/index.js';
|
|
2
|
-
import { TelemetryProvider, ToolbarModuleExtension, } from '../../affine-shared/services/index.js';
|
|
3
|
-
import { BlockFlavourIdentifier } from '../../std/index.js';
|
|
4
|
-
import { html } from 'lit';
|
|
5
|
-
import { createCoreDomainLegend } from './legend';
|
|
6
|
-
const legendIcon = html `<svg
|
|
7
|
-
width="24"
|
|
8
|
-
height="24"
|
|
9
|
-
viewBox="0 0 24 24"
|
|
10
|
-
fill="none"
|
|
11
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
12
|
-
>
|
|
13
|
-
<rect x="3" y="4" width="18" height="16" rx="2" stroke="currentColor" stroke-width="1.6" />
|
|
14
|
-
<circle cx="7" cy="9" r="1.6" fill="currentColor" />
|
|
15
|
-
<circle cx="7" cy="14" r="1.6" fill="currentColor" />
|
|
16
|
-
<path d="M11 9 H18 M11 14 H18" stroke="currentColor" stroke-width="1.4" />
|
|
17
|
-
</svg>`;
|
|
18
|
-
/** Contextual toolbar for a selected Core Domain background: insert its legend. */
|
|
19
|
-
const coreDomainToolbarConfig = {
|
|
20
|
-
actions: [
|
|
21
|
-
{
|
|
22
|
-
id: 'a.legend',
|
|
23
|
-
tooltip: 'Insert legend (notation present in the chart)',
|
|
24
|
-
icon: legendIcon,
|
|
25
|
-
run(ctx) {
|
|
26
|
-
const bg = ctx.getSurfaceModelsByType(CoreDomainChartElementModel)[0];
|
|
27
|
-
if (!bg)
|
|
28
|
-
return;
|
|
29
|
-
createCoreDomainLegend(ctx.std, bg);
|
|
30
|
-
ctx.std.getOptional(TelemetryProvider)?.track('FrameworkLegendCreated', {
|
|
31
|
-
framework: 'core-domain',
|
|
32
|
-
element: 'legend',
|
|
33
|
-
page: 'whiteboard editor',
|
|
34
|
-
segment: 'element toolbar',
|
|
35
|
-
module: 'core-domain toolbar',
|
|
36
|
-
});
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
],
|
|
40
|
-
when: ctx => ctx.getSurfaceModelsByType(CoreDomainChartElementModel).length > 0,
|
|
41
|
-
};
|
|
42
|
-
export const coreDomainToolbarExtension = ToolbarModuleExtension({
|
|
43
|
-
id: BlockFlavourIdentifier('affine:surface:coreDomain'),
|
|
44
|
-
config: coreDomainToolbarConfig,
|
|
45
|
-
});
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { EdgelessDddContextMapMenu } from './toolbar/context-map-menu';
|
|
2
|
-
import { EdgelessDddCoreDomainMenu } from './toolbar/core-domain-menu';
|
|
3
|
-
import { EdgelessDddEventStormingMenu } from './toolbar/event-storming-menu';
|
|
4
|
-
import { EdgelessDddContextMapSeniorButton, EdgelessDddCoreDomainSeniorButton, EdgelessDddEventStormingSeniorButton } from './toolbar/senior-buttons';
|
|
5
|
-
export declare function eventStormingEffects(): void;
|
|
6
|
-
export declare function coreDomainEffects(): void;
|
|
7
|
-
export declare function contextMapEffects(): void;
|
|
8
|
-
declare global {
|
|
9
|
-
interface HTMLElementTagNameMap {
|
|
10
|
-
'edgeless-ddd-event-storming-menu': EdgelessDddEventStormingMenu;
|
|
11
|
-
'edgeless-ddd-event-storming-senior-button': EdgelessDddEventStormingSeniorButton;
|
|
12
|
-
'edgeless-ddd-core-domain-menu': EdgelessDddCoreDomainMenu;
|
|
13
|
-
'edgeless-ddd-core-domain-senior-button': EdgelessDddCoreDomainSeniorButton;
|
|
14
|
-
'edgeless-ddd-context-map-menu': EdgelessDddContextMapMenu;
|
|
15
|
-
'edgeless-ddd-context-map-senior-button': EdgelessDddContextMapSeniorButton;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { EdgelessDddContextMapMenu } from './toolbar/context-map-menu';
|
|
2
|
-
import { EdgelessDddCoreDomainMenu } from './toolbar/core-domain-menu';
|
|
3
|
-
import { EdgelessDddEventStormingMenu } from './toolbar/event-storming-menu';
|
|
4
|
-
import { EdgelessDddContextMapSeniorButton, EdgelessDddCoreDomainSeniorButton, EdgelessDddEventStormingSeniorButton, } from './toolbar/senior-buttons';
|
|
5
|
-
/** Define a custom element once (each tool's effect may run more than once). */
|
|
6
|
-
function define(tag, ctor) {
|
|
7
|
-
if (!customElements.get(tag))
|
|
8
|
-
customElements.define(tag, ctor);
|
|
9
|
-
}
|
|
10
|
-
export function eventStormingEffects() {
|
|
11
|
-
define('edgeless-ddd-event-storming-menu', EdgelessDddEventStormingMenu);
|
|
12
|
-
define('edgeless-ddd-event-storming-senior-button', EdgelessDddEventStormingSeniorButton);
|
|
13
|
-
}
|
|
14
|
-
export function coreDomainEffects() {
|
|
15
|
-
define('edgeless-ddd-core-domain-menu', EdgelessDddCoreDomainMenu);
|
|
16
|
-
define('edgeless-ddd-core-domain-senior-button', EdgelessDddCoreDomainSeniorButton);
|
|
17
|
-
}
|
|
18
|
-
export function contextMapEffects() {
|
|
19
|
-
define('edgeless-ddd-context-map-menu', EdgelessDddContextMapMenu);
|
|
20
|
-
define('edgeless-ddd-context-map-senior-button', EdgelessDddContextMapSeniorButton);
|
|
21
|
-
}
|