Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
- Fix `SelectionAction*` components not updating on selection change when provided as children to `Halo`.

#### 💅 Polish
- Allow to control the placement of newly created entity elements from `ClassTree` and `SearchSectionElementTypes` via `placeCreatedEntity` prop.
- Expose `fixedElements` option for `performLayout()` to be able to constrain elements not to move (if supported by the layout function).
- Improve ARIA-attributes and other accessibility interaction:
* Allow to resize and toggle `WorkspaceLayout*` with a keyboard;
* Change `WorkspaceLayout*` to be `<section>` elements with `aria-label` (i.e. regions);
Expand Down
20 changes: 18 additions & 2 deletions src/widgets/classTree/classTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import { Element } from '../../diagram/elements';
import { Vector, SizeProvider } from '../../diagram/geometry';
import { HtmlSpinner } from '../../diagram/spinner';

import { DataDiagramModel } from '../../editor/dataDiagramModel';
import type { DataDiagramModel } from '../../editor/dataDiagramModel';
import type { EntityElement } from '../../editor/dataElements';

import { NoSearchResults } from '../utility/noSearchResults';
import { ProgressBar, ProgressState } from '../utility/progressBar';
Expand Down Expand Up @@ -65,6 +66,13 @@ export interface ClassTreeProps {
* @default true
*/
draggableItems?: boolean;
/**
* Handler to place newly created entity from a tree.
*/
placeCreatedEntity?: (
element: EntityElement,
dropEvent: CanvasDropEvent | undefined
) => Promise<void>;
}

/**
Expand Down Expand Up @@ -428,7 +436,11 @@ class ClassTreeInner extends React.Component<ClassTreeInnerProps, State> {
elementType: ElementTypeIri,
dropEvent?: CanvasDropEvent
): Promise<void> {
const {workspace: {model, view, editor, getCommandBus}, translation: t} = this.props;
const {
placeCreatedEntity,
workspace: {model, view, editor, getCommandBus},
translation: t,
} = this.props;
const batch = model.history.startBatch();

this.createElementCancellation.abort();
Expand Down Expand Up @@ -469,6 +481,10 @@ class ClassTreeInner extends React.Component<ClassTreeInnerProps, State> {
moveElementCenterToPosition(element, targetPosition, canvas.renderingState);
}

if (placeCreatedEntity) {
await placeCreatedEntity(element, dropEvent);
}

batch.store();
model.setSelection([element]);
getCommandBus(VisualAuthoringTopic)
Expand Down
18 changes: 17 additions & 1 deletion src/widgets/unifiedSearch/builtinSearchSections.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import * as React from 'react';

import { EventObserver } from '../../coreUtils/events';

import type { CanvasDropEvent } from '../../diagram/canvasApi';
import type { EntityElement } from '../../editor/dataElements';

import { ClassTree } from '../classTree';
import { InstancesSearch, SearchCriteria } from '../instancesSearch';
import { LinkTypesToolbox } from '../linksToolbox';
Expand Down Expand Up @@ -37,8 +40,20 @@ export function SearchSectionElementTypes(props: {
* @default true
*/
draggableItems?: boolean;
/**
* Handler to place newly created entity from an element type tree.
*/
placeCreatedEntity?: (
element: EntityElement,
dropEvent: CanvasDropEvent | undefined
) => Promise<void>;
}) {
const {searchTimeout = 200, minSearchTermLength = 2, draggableItems} = props;
const {
searchTimeout = 200,
minSearchTermLength = 2,
draggableItems,
placeCreatedEntity,
} = props;
const {searchStore, shouldRender} = useUnifiedSearchSection({
searchTimeout,
allowSubmit: term => term.length >= minSearchTermLength,
Expand All @@ -48,6 +63,7 @@ export function SearchSectionElementTypes(props: {
<ClassTree className={SECTION_ELEMENT_TYPES_CLASS}
searchStore={searchStore}
draggableItems={draggableItems}
placeCreatedEntity={placeCreatedEntity}
/>
) : null;
}
Expand Down
34 changes: 17 additions & 17 deletions src/workspace/defaultWorkspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,23 +147,23 @@ export interface DefaultWorkspaceProps extends BaseDefaultWorkspaceProps {
* {
* sections: [
* {
* key: 'elementTypes',
* label: t.text('default_workspace.search_section_entity_types.label'),
* title: t.text('default_workspace.search_section_entity_types.title'),
* component: <SearchSectionElementTypes />,
* },
* {
* key: 'entities',
* label: t.text('default_workspace.search_section_entities.label'),
* title: t.text('default_workspace.search_section_entities.title'),
* component: <SearchSectionEntities />,
* },
* {
* key: 'linkTypes',
* label: t.text('default_workspace.search_section_link_types.label'),
* title: t.text('default_workspace.search_section_link_types.title'),
* component: <SearchSectionLinkTypes />,
* }
* key: 'elementTypes',
* label: t.text('default_workspace.search_section_entity_types.label'),
* title: t.text('default_workspace.search_section_entity_types.title'),
* component: <SearchSectionElementTypes />,
* },
* {
* key: 'entities',
* label: t.text('default_workspace.search_section_entities.label'),
* title: t.text('default_workspace.search_section_entities.title'),
* component: <SearchSectionEntities />,
* },
* {
* key: 'linkTypes',
* label: t.text('default_workspace.search_section_link_types.label'),
* title: t.text('default_workspace.search_section_link_types.title'),
* component: <SearchSectionLinkTypes />,
* },
* ]
* }
* ```
Expand Down
5 changes: 3 additions & 2 deletions src/workspace/workspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -389,8 +389,8 @@ export class Workspace extends React.Component<WorkspaceProps> {

private onPerformLayout: WorkspaceContext['performLayout'] = async params => {
const {
canvas: targetCanvas, layoutFunction, selectedElements, animate, signal,
zoomToFit = true,
canvas: targetCanvas, layoutFunction, selectedElements, fixedElements,
animate, signal, zoomToFit = true,
} = params;
const {model, view, overlay, disposeSignal} = this.workspaceContext;
const t = this.translation;
Expand All @@ -412,6 +412,7 @@ export class Workspace extends React.Component<WorkspaceProps> {
layoutFunction: layoutFunction ?? view.defaultLayout,
model,
selectedElements,
fixedElements,
sizeProvider: canvas.renderingState,
typeProvider: this.layoutTypeProvider,
signal: signal ?? disposeSignal,
Expand Down
5 changes: 5 additions & 0 deletions src/workspace/workspaceContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@ export interface WorkspacePerformLayoutParams {
* Restrict the layout application to the subset of graph elements.
*/
selectedElements?: ReadonlySet<Element>;
/**
* Set of elements which should not be moved by layout algorithm
* (if supported).
*/
fixedElements?: ReadonlySet<Element>;
/**
* Whether moving elements to final layout positions should be animated.
*
Expand Down
Loading