Skip to content

Commit

Permalink
[3553] Add a representationFactory extension point
Browse files Browse the repository at this point in the history
Bug: eclipse-sirius#3553
Signed-off-by: William Piers <[email protected]>
  • Loading branch information
wpiers authored and sbegaudeau committed Jun 11, 2024
1 parent 3cbb5fd commit aa92a04
Show file tree
Hide file tree
Showing 19 changed files with 206 additions and 242 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

- https://github.com/eclipse-sirius/sirius-web/issues/3562[#3562] [sirius-web] Update displayed default model creation action.
+ Projects that have a nature and need the action to create an empty model will need to register the empty model action like it is done in `StudioEditingContextActionProvider`.
- https://github.com/eclipse-sirius/sirius-web/issues/3553[#3553] [core] Remove the concepts `RepresentationContext`, `RepresentationContextProvider` and their types which were used to contribute representations for the Sirius Components workbench in favor of an API based on the extension registry.
This is one of the first existing API used to extend Sirius Web deprecated in favor of the new extension registry.
More existing APIs will be migrated to this new common pattern.

=== Dependency update

Expand Down Expand Up @@ -54,6 +57,7 @@
- https://github.com/eclipse-sirius/sirius-web/issues/3550[#3550] [core] Add ExtensionRegistry merge strategy
- https://github.com/eclipse-sirius/sirius-web/issues/3563[#3563] [sirius-web] Improve NavigationBar extensibility to allow the contribution of components on the left and right of the navigation bar.
- https://github.com/eclipse-sirius/sirius-web/issues/3344[#3344] [core] Add support for reloading representations from the database
- https://github.com/eclipse-sirius/sirius-web/issues/3553[#3553] [core] Add RepresentationFactory extension point

=== Improvements

Expand Down
2 changes: 0 additions & 2 deletions packages/core/frontend/sirius-components-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ export * from './toast/MultiToast';
export * from './toast/Toast';
export * from './toast/useReporting';
export * from './workbench/Panels';
export * from './workbench/RepresentationContext';
export * from './workbench/RepresentationContext.types';
export * from './workbench/Workbench';
export * from './workbench/Workbench.types';
export * from './workbench/WorkbenchExtensionPoints';

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2019, 2023 Obeo.
* Copyright (c) 2019, 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
Expand All @@ -15,7 +15,7 @@ import Tabs from '@material-ui/core/Tabs';
import { makeStyles } from '@material-ui/core/styles';
import CloseIcon from '@material-ui/icons/Close';
import { RepresentationNavigationProps } from './RepresentationNavigation.types';
import { Representation } from './Workbench.types';
import { RepresentationMetadata } from './Workbench.types';

const useRepresentationNavigationStyles = makeStyles((theme) => ({
tabsRoot: {
Expand Down Expand Up @@ -63,7 +63,7 @@ export const RepresentationNavigation = ({
const representationSelected = representations.find((representation) => representation.id === value);
if (representationSelected) {
const { id, label, kind } = representationSelected;
const representation: Representation = {
const representation: RepresentationMetadata = {
id,
label,
kind,
Expand All @@ -72,7 +72,7 @@ export const RepresentationNavigation = ({
}
};

const onRepresentationClose = (event: React.MouseEvent<SVGSVGElement>, representation: Representation) => {
const onRepresentationClose = (event: React.MouseEvent<SVGSVGElement>, representation: RepresentationMetadata) => {
event.stopPropagation();
onClose(representation);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2021, 2022 Obeo.
* Copyright (c) 2021, 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
Expand All @@ -10,11 +10,11 @@
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
import { Representation } from './Workbench.types';
import { RepresentationMetadata } from './Workbench.types';

export type RepresentationNavigationProps = {
representations: Representation[];
displayedRepresentation: Representation;
onRepresentationClick: (representation: Representation) => void;
onClose: (representation: Representation) => void;
representations: RepresentationMetadata[];
displayedRepresentation: RepresentationMetadata;
onRepresentationClick: (representation: RepresentationMetadata) => void;
onClose: (representation: RepresentationMetadata) => void;
};
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,25 @@
import { gql, useSubscription } from '@apollo/client';
import { makeStyles } from '@material-ui/core/styles';
import { useMachine } from '@xstate/react';
import { useContext, useEffect } from 'react';
import { useEffect } from 'react';
import { useComponent } from '../extension/useComponent';
import { useData } from '../extension/useData';
import { useSelection } from '../selection/useSelection';
import { Toast } from '../toast/Toast';
import { Panels } from './Panels';
import { RepresentationContext } from './RepresentationContext';
import { RepresentationContextValue } from './RepresentationContext.types';
import { RepresentationNavigation } from './RepresentationNavigation';
import {
GQLEditingContextEventSubscription,
Representation,
RepresentationComponentProps,
RepresentationMetadata,
WorkbenchProps,
WorkbenchViewContribution,
} from './Workbench.types';
import { workbenchMainAreaExtensionPoint, workbenchViewContributionExtensionPoint } from './WorkbenchExtensionPoints';
import {
representationFactoryExtensionPoint,
workbenchMainAreaExtensionPoint,
workbenchViewContributionExtensionPoint,
} from './WorkbenchExtensionPoints';
import {
HandleCompleteEvent,
HandleSubscriptionResultEvent,
Expand Down Expand Up @@ -76,7 +78,6 @@ export const Workbench = ({
readOnly,
}: WorkbenchProps) => {
const classes = useWorkbenchStyles();
const { registry } = useContext<RepresentationContextValue>(RepresentationContext);
const [{ value, context }, dispatch] = useMachine<WorkbenchContext, WorkbenchEvent>(workbenchMachine, {
context: {
displayedRepresentation: initialRepresentationSelected,
Expand All @@ -86,6 +87,7 @@ export const Workbench = ({
const { toast } = value as SchemaValue;
const { id, representations, displayedRepresentation, message } = context;
const { selection, setSelection } = useSelection();
const { data: representationFactories } = useData(representationFactoryExtensionPoint);

const { error } = useSubscription<GQLEditingContextEventSubscription>(editingContextEventSubscription, {
variables: {
Expand Down Expand Up @@ -117,7 +119,7 @@ export const Workbench = ({
}, [error, dispatch]);

useEffect(() => {
const representations: Representation[] = selection.entries.filter((entry) =>
const representations: RepresentationMetadata[] = selection.entries.filter((entry) =>
entry.kind.startsWith('siriusComponents://representation')
);
const updateSelectedRepresentation: UpdateSelectedRepresentationEvent = {
Expand All @@ -127,11 +129,11 @@ export const Workbench = ({
dispatch(updateSelectedRepresentation);
}, [selection, dispatch]);

const onRepresentationClick = (representation: Representation) => {
const onRepresentationClick = (representation: RepresentationMetadata) => {
setSelection({ entries: [{ id: representation.id, label: representation.label, kind: representation.kind }] });
};

const onClose = (representation: Representation) => {
const onClose = (representation: RepresentationMetadata) => {
const hideRepresentationEvent: HideRepresentationEvent = { type: 'HIDE_REPRESENTATION', representation };
dispatch(hideRepresentationEvent);
};
Expand Down Expand Up @@ -160,7 +162,9 @@ export const Workbench = ({
let main = <MainComponent editingContextId={editingContextId} readOnly={readOnly} />;

if (displayedRepresentation) {
const RepresentationComponent = registry.getComponent(displayedRepresentation);
const RepresentationComponent = representationFactories
.map((representationFactory) => representationFactory(displayedRepresentation))
.find((component) => component != null);
const props: RepresentationComponentProps = {
editingContextId,
readOnly,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export type GQLEditingContextEventSubscription = {
editingContextEvent: GQLEditingContextEventPayload;
};

export type Representation = {
export type RepresentationMetadata = {
id: string;
label: string;
kind: string;
Expand All @@ -53,8 +53,8 @@ export interface MainAreaComponentProps {

export type WorkbenchProps = {
editingContextId: string;
initialRepresentationSelected: Representation | null;
onRepresentationSelected: (representation: Representation | null) => void;
initialRepresentationSelected: RepresentationMetadata | null;
onRepresentationSelected: (representation: RepresentationMetadata | null) => void;
readOnly: boolean;
};

Expand All @@ -65,3 +65,7 @@ export type RepresentationComponentProps = {
};

export type RepresentationComponent = React.ComponentType<RepresentationComponentProps>;

export type RepresentationComponentFactory = {
(representationMetadata: RepresentationMetadata): RepresentationComponent | null;
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*******************************************************************************/

import { ComponentExtensionPoint, DataExtensionPoint } from '../extension/ExtensionRegistry.types';
import { MainAreaComponentProps, WorkbenchViewContribution } from './Workbench.types';
import { MainAreaComponentProps, RepresentationComponentFactory, WorkbenchViewContribution } from './Workbench.types';

export const workbenchMainAreaExtensionPoint: ComponentExtensionPoint<MainAreaComponentProps> = {
identifier: 'workbench#mainArea',
Expand All @@ -23,3 +23,8 @@ export const workbenchViewContributionExtensionPoint: DataExtensionPoint<Array<W
identifier: 'workbench#viewContribution',
fallback: [],
};

export const representationFactoryExtensionPoint: DataExtensionPoint<Array<RepresentationComponentFactory>> = {
identifier: 'workbench#representationFactory',
fallback: [],
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2021, 2023 Obeo.
* Copyright (c) 2021, 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
Expand All @@ -16,7 +16,7 @@ import {
GQLEditingContextEventPayload,
GQLEditingContextEventSubscription,
GQLRepresentationRenamedEventPayload,
Representation,
RepresentationMetadata,
} from './Workbench.types';

export interface WorkbenchStateSchema {
Expand All @@ -43,15 +43,15 @@ export type SchemaValue = {

export interface WorkbenchContext {
id: string;
representations: Representation[];
displayedRepresentation: Representation | null;
representations: RepresentationMetadata[];
displayedRepresentation: RepresentationMetadata | null;
message: string | null;
}

export type HideRepresentationEvent = { type: 'HIDE_REPRESENTATION'; representation: Representation };
export type HideRepresentationEvent = { type: 'HIDE_REPRESENTATION'; representation: RepresentationMetadata };
export type UpdateSelectedRepresentationEvent = {
type: 'UPDATE_SELECTED_REPRESENTATION';
representations: Representation[];
representations: RepresentationMetadata[];
};

export type ShowToastEvent = { type: 'SHOW_TOAST'; message: string };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@

import {
RepresentationComponentProps,
RepresentationContext,
RepresentationContextValue,
representationFactoryExtensionPoint,
useData,
} from '@eclipse-sirius/sirius-components-core';
import IconButton from '@material-ui/core/IconButton';
import Typography from '@material-ui/core/Typography';
import { makeStyles } from '@material-ui/core/styles';
import CloseOutlinedIcon from '@material-ui/icons/CloseOutlined';
import { useContext } from 'react';
import { RepresentationFrameProps } from './RepresentationFrame.types';

const useFrameStyles = makeStyles((theme) => ({
Expand Down Expand Up @@ -59,8 +58,10 @@ export const RepresentationFrame = ({
portalMode,
onDelete,
}: RepresentationFrameProps) => {
const { registry } = useContext<RepresentationContextValue>(RepresentationContext);
const RepresentationComponent = registry.getComponent(representation);
const { data: representationFactories } = useData(representationFactoryExtensionPoint);
const RepresentationComponent = representationFactories
.map((representationFactory) => representationFactory(representation))
.find((component) => component != null);

if (RepresentationComponent) {
const classes = useFrameStyles();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
import { Representation } from '@eclipse-sirius/sirius-components-core';
import { RepresentationMetadata } from '@eclipse-sirius/sirius-components-core';
import { PortalRepresentationMode } from './PortalRepresentation.types';

export type RepresentationFrameProps = {
editingContextId: string;
representation: Representation;
representation: RepresentationMetadata;
onDelete: () => void;
portalMode: PortalRepresentationMode;
};
Loading

0 comments on commit aa92a04

Please sign in to comment.