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
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
* Resolve anchors and image thumbnail URLs in `StandardEntity`, `ClassicEntity` and `SelectionActionAnchor`;
* Add `useResolvedAssetUrl()` helper hook to simplify resolving asset URLs from components;
- Support conditionally rendering `WorkspaceLayout*` child components by passing `null` instead of a child to remove it:
* Allow to hide left and right panels in `ClassicWorkspace` by passing `null` to the corresponding props.
* Allow to hide left and right panels in `ClassicWorkspace` by passing `null` to the corresponding props;
* Allow to provide `className` and `style` to `WorkspaceLayout*` components.

#### 💅 Polish
- Expose `useAsync()` utility hook to simplify data loading from via a single Promise-returning task.
- Provide `onlySelected` property to link templates the same way as for element templates.
- Allow to configure whether `ClassTree` and `SearchSectionElementTypes` tree items should be draggable.
- Allow to configure `SparqlDataProvider.lookup()` via `lookupQuery` and `filterInnerPrelude` settings.
- Add separate translation keys for input placeholders on every search input field.

#### 🔧 Maintenance
- Preparations to extract generic scrollable paper component `Paper` from diagram-specific state and logic:
Expand Down
5 changes: 5 additions & 0 deletions i18n/i18n.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
"entities.no_results": { "$ref": "#/$defs/Value" },
"entities.truncated_results": { "$ref": "#/$defs/Value" },
"entities.truncated_results_expand": { "$ref": "#/$defs/Value" },
"input.placeholder": { "$ref": "#/$defs/Value" },
"link.both_navigate_title": { "$ref": "#/$defs/Value" },
"link.both_title": { "$ref": "#/$defs/Value" },
"link.source_navigate_title": { "$ref": "#/$defs/Value" },
Expand Down Expand Up @@ -234,6 +235,7 @@
"additionalProperties": false,
"properties": {
"drag_create.title": { "$ref": "#/$defs/Value" },
"input.placeholder": { "$ref": "#/$defs/Value" },
"no_results": { "$ref": "#/$defs/Value" },
"refresh_progress.title": { "$ref": "#/$defs/Value" },
"show_only_creatable": { "$ref": "#/$defs/Value" }
Expand All @@ -252,6 +254,7 @@
"criteria_connected_via": { "$ref": "#/$defs/Value" },
"criteria_connected_to_source": { "$ref": "#/$defs/Value" },
"criteria_connected_to_target": { "$ref": "#/$defs/Value" },
"input.placeholder": { "$ref": "#/$defs/Value" },
"place_elements.command": { "$ref": "#/$defs/Value" },
"query_progress.title": { "$ref": "#/$defs/Value" },
"show_more_results.label": { "$ref": "#/$defs/Value" },
Expand All @@ -266,6 +269,7 @@
"heading_connected": { "$ref": "#/$defs/Value" },
"heading_connected_single": { "$ref": "#/$defs/Value" },
"heading_other": { "$ref": "#/$defs/Value" },
"input.placeholder": { "$ref": "#/$defs/Value" },
"no_results": { "$ref": "#/$defs/Value" },
"switch.command": { "$ref": "#/$defs/Value" },
"switch_all.label": { "$ref": "#/$defs/Value" },
Expand Down Expand Up @@ -399,6 +403,7 @@
"rename_link.dialog.caption": { "$ref": "#/$defs/Value" },
"rename_link.label.label": { "$ref": "#/$defs/Value" },
"select_entity.entity_type.label": { "$ref": "#/$defs/Value" },
"select_entity.input.placeholder": { "$ref": "#/$defs/Value" },
"select_entity.type.label": { "$ref": "#/$defs/Value" },
"select_entity.type.placeholder": { "$ref": "#/$defs/Value" },
"select_entity.results.aria_label": { "$ref": "#/$defs/Value" },
Expand Down
5 changes: 5 additions & 0 deletions i18n/translations/en.reactodia-translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"entities.no_results": "No results",
"entities.truncated_results": "Only the first {{limit}} entities are shown",
"entities.truncated_results_expand": "Only the first {{limit}} entities are shown,\nclick here for the full results",
"input.placeholder": "Search for...",
"link.both_navigate_title": "Navigate to all connected elements",
"link.both_title": "all connected",
"link.source_navigate_title": "Navigate to source \"{{relation}}\" elements",
Expand Down Expand Up @@ -159,6 +160,7 @@
},
"search_element_types": {
"drag_create.title": "Click or drag to create new entity of this type",
"input.placeholder": "Search for...",
"no_results": "No element types found.",
"refresh_progress.title": "Loading element type tree",
"show_only_creatable": "Show only constructible"
Expand All @@ -173,6 +175,7 @@
"criteria_connected_via": "Connected to {{entity}} through {{relationType}}",
"criteria_connected_to_source": "Connected to {{entity}} through {{relationType}} as {{sourceIcon}}\u00A0source",
"criteria_connected_to_target": "Connected to {{entity}} through {{relationType}} as {{targetIcon}}\u00A0target",
"input.placeholder": "Search for...",
"place_elements.command": "Add selected elements",
"query_progress.title": "Querying for entities",
"show_more_results.label": "Show more",
Expand All @@ -183,6 +186,7 @@
"heading_connected": "Connected to selected entities",
"heading_connected_single": "Connected to {{entity}}",
"heading_other": "Other links",
"input.placeholder": "Search for...",
"no_results": "No links found.",
"switch.command": "Change link types visibility",
"switch_all.label": "Switch all",
Expand Down Expand Up @@ -287,6 +291,7 @@
"rename_link.dialog.caption": "Rename Link",
"rename_link.label.label": "Label",
"select_entity.entity_type.label": "{{type}}",
"select_entity.input.placeholder": "Search for...",
"select_entity.type.label": "Entity Type",
"select_entity.type.placeholder": "Select entity type",
"select_entity.results.aria_label": "Select an existing element to put on a diagram",
Expand Down
1 change: 1 addition & 0 deletions src/forms/elementTypeSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ export class ElementTypeSelectorInner extends React.Component<ElementTypeSelecto
inputProps={{
className: `${CLASS_NAME}__search-input`,
name: 'reactodia-element-type-selector-search',
placeholder: t.text('visual_authoring.select_entity.input.placeholder'),
autoFocus: true,
}}>
<span className={`${CLASS_NAME}__search-icon`} />
Expand Down
1 change: 1 addition & 0 deletions src/widgets/classTree/classTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ class ClassTreeInner extends React.Component<ClassTreeInnerProps, State> {
<SearchInput store={searchStore}
inputProps={{
name: 'reactodia-class-tree-filter',
placeholder: t.text('search_element_types.input.placeholder'),
}}
/>
)}
Expand Down
5 changes: 3 additions & 2 deletions src/widgets/connectionsMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ class ConnectionsMenuInner extends React.Component<ConnectionsMenuInnerProps, Me
}

render() {
const {connectionSearch, objectSearch} = this.props;
const {connectionSearch, objectSearch, translation: t} = this.props;
const {panel} = this.state;
return (
<div className={CLASS_NAME}>
Expand All @@ -589,6 +589,7 @@ class ConnectionsMenuInner extends React.Component<ConnectionsMenuInnerProps, Me
store={panel === 'connections' ? connectionSearch : objectSearch}
inputProps={{
name: 'reactodia-connection-menu-filter',
placeholder: t.text('connections_menu.input.placeholder'),
}}>
{this.renderSortSwitches()}
</SearchInput>
Expand Down Expand Up @@ -1234,7 +1235,7 @@ class ObjectsPanel extends React.Component<ObjectsPanelProps, ObjectsPanelState>
disabled={nonPresented.length === 0}
title={t.text('connections_menu.select_all.title')}
/>
{t.text('connections_menu.select_all.label')}
<span>{t.text('connections_menu.select_all.label')}</span>
</label>
<div className={`${CLASS_NAME}__objects-spacer`} aria-hidden='true' />
{this.renderCounter(active.length)}
Expand Down
1 change: 1 addition & 0 deletions src/widgets/instancesSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ class InstancesSearchInner extends React.Component<InstancesSearchInnerProps, St
className={`${CLASS_NAME}__text-criteria`}
inputProps={{
name: 'reactodia-instances-search-text',
placeholder: t.text('search_entities.input.placeholder'),
}}
/>
)}
Expand Down
1 change: 1 addition & 0 deletions src/widgets/linksToolbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ class LinkTypesToolboxInner extends React.Component<LinkTypesToolboxInnerProps,
className={`${CLASS_NAME}__filter`}
inputProps={{
name: 'reactodia-link-types-filter',
placeholder: t.text('search_link_types.input.placeholder'),
}}
/>
)}
Expand Down
18 changes: 13 additions & 5 deletions src/workspace/accordion.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import * as React from 'react';
import cx from 'clsx';

import { AccordionItem, AccordionItemProps, ItemProvidedProps } from './accordionItem';

export interface AccordionProps {
className?: string;
style?: React.CSSProperties;
onStartResize?: (direction: 'vertical' | 'horizontal') => void;
onResize?: (direction: 'vertical' | 'horizontal') => void;
/** AccordionItem[] */
Expand Down Expand Up @@ -170,13 +173,18 @@ export class Accordion extends React.Component<AccordionProps, State> {
}

render() {
const {direction} = this.props;
const {className, style, direction} = this.props;
const {resizing} = this.state;
const resizingClassName = resizing ? `${CLASS_NAME}--resizing` : '';
const scrollableClassName = this.isScrollable ? `${CLASS_NAME}--scrollable` : '';
return (
<div className={`${CLASS_NAME} ${CLASS_NAME}--${direction} ${resizingClassName} ${scrollableClassName}`}
ref={this.onElementMount}>
<div ref={this.onElementMount}
className={cx(
CLASS_NAME,
`${CLASS_NAME}--${direction}`,
resizing ? `${CLASS_NAME}--resizing` : undefined,
this.isScrollable ? `${CLASS_NAME}--scrollable` : undefined,
className
)}
style={style}>
{this.renderItems()}
</div>
);
Expand Down
25 changes: 15 additions & 10 deletions src/workspace/accordionItem.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import cx from 'clsx';

import { DraggableHandle } from '../widgets/utility/draggableHandle';

Expand All @@ -10,6 +11,8 @@ export enum DockSide {
export interface AccordionItemProps extends ItemProvidedProps {
id: string;
heading?: React.ReactNode;
className?: string;
style?: React.CSSProperties;
bodyClassName?: string;
bodyRef?: (body: HTMLDivElement) => void;
children?: React.ReactNode;
Expand Down Expand Up @@ -69,31 +72,33 @@ export class AccordionItem extends React.Component<AccordionItemProps, State> {

render() {
const {
heading, bodyClassName, children, bodyRef,
heading, className, style, bodyClassName, children, bodyRef,
collapsed, size, direction, onBeginDragHandle, onDragHandle, onEndDragHandle, dockSide,
} = this.props;
const {resizing} = this.state;
const shouldRenderHandle = onBeginDragHandle && onDragHandle && onEndDragHandle;
const style: React.CSSProperties = this.isVertical ? {height: size} : {width: size};
const providedStyle: React.CSSProperties = this.isVertical ? {height: size} : {width: size};

// unmount child component when the accordion item is collapsed and has dockSide
const isMounted = !(collapsed && dockSide);
return (
<div
className={
`${CLASS_NAME} ${CLASS_NAME}--${collapsed ? 'collapsed' : 'expanded'} ${CLASS_NAME}--${direction}
${resizing ? `${CLASS_NAME}--resizing` : ''}`
}
ref={this._element}
style={style}>
<div ref={this._element}
className={cx(
CLASS_NAME,
collapsed ? `${CLASS_NAME}--collapsed`: `${CLASS_NAME}--expanded`,
`${CLASS_NAME}--${direction}`,
resizing ? `${CLASS_NAME}--resizing` : undefined,
className
)}
style={{...style, ...providedStyle}}>
<div className={`${CLASS_NAME}__inner`}>
{heading ? <div className={`${CLASS_NAME}__header`}
ref={this._header}
onClick={() => this.props.onChangeCollapsed!(!collapsed)}>{heading}</div> : null}
<div className={`${CLASS_NAME}__body`}>
{children && isMounted
? children
: <div ref={bodyRef} className={`${bodyClassName || ''}`} />}
: <div ref={bodyRef} className={bodyClassName} />}
</div>
</div>
{shouldRenderHandle ? (
Expand Down
26 changes: 22 additions & 4 deletions src/workspace/workspaceLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ import { AccordionItem, DockSide } from './accordionItem';
const DEFAULT_HORIZONTAL_COLLAPSED_SIZE = 28;

interface CommonWorkspaceLayoutProps {
/**
* Additional CSS class for the component.
*/
className?: string;
/**
* Additional CSS styles for the component.
*/
style?: React.CSSProperties;
/**
* Default size for the layout component.
*
Expand Down Expand Up @@ -160,7 +168,7 @@ export interface WorkspaceLayoutResizeContext {
export const WorkspaceLayoutResizeContext = React.createContext<WorkspaceLayoutResizeContext | null>(null);

function renderContainer(props: WorkspaceLayoutContainerProps, type: 'row' | 'column') {
const {animationDuration, children} = props;
const {className, style, animationDuration, children} = props;
const resizeContext = React.useContext(WorkspaceLayoutResizeContext);
const childCount = React.Children.count(children);
const items = React.Children.map(children, (child, index) => {
Expand All @@ -184,8 +192,16 @@ function renderContainer(props: WorkspaceLayoutContainerProps, type: 'row' | 'co
<AccordionItem
id={childId}
key={childId}
heading={child.type === WorkspaceLayoutItem
? (child.props as WorkspaceLayoutItemProps).heading : undefined
className={
child.type === WorkspaceLayoutItem ? child.props.className : undefined
}
style={
child.type === WorkspaceLayoutItem ? child.props.style : undefined
}
heading={
child.type === WorkspaceLayoutItem
? (child.props as WorkspaceLayoutItemProps).heading
: undefined
}
dockSide={dockSide}
defaultSize={child.props.defaultSize}
Expand All @@ -197,7 +213,9 @@ function renderContainer(props: WorkspaceLayoutContainerProps, type: 'row' | 'co
);
});
return (
<Accordion direction={type === 'row' ? 'horizontal' : 'vertical'}
<Accordion className={className}
style={style}
direction={type === 'row' ? 'horizontal' : 'vertical'}
onStartResize={resizeContext?.onStartResize}
onResize={resizeContext?.onResize ?? (() => undefined)}
animationDuration={animationDuration}>
Expand Down
Loading