Skip to content

Commit

Permalink
[2568] Allow developers to change the content of the explorer on the …
Browse files Browse the repository at this point in the history
…frontend

Bug: #2568
Signed-off-by: William Piers <william.piers@obeo.fr>
  • Loading branch information
wpiers authored and sbegaudeau committed Nov 15, 2023
1 parent 639fe06 commit 78bf5b4
Show file tree
Hide file tree
Showing 12 changed files with 226 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.adoc
Expand Up @@ -16,6 +16,7 @@
- [ADR-113] Add support for multiple IObjectService
- [ADR-114] Add support for multiple IEditService
- [ADR-115] Split the Sirius Web frontend
- [ADR-116] Add support for changing the content of the explorer

=== Breaking changes

Expand Down Expand Up @@ -115,6 +116,7 @@ That includes the support during the direct edit.
The user can use 'shift+enter' to insert a line break.
- https://github.com/eclipse-sirius/sirius-web/issues/2522[#2522] [diagram] Add the support for rotatable border node.
- https://github.com/eclipse-sirius/sirius-web/issues/2255[#2255] [diagram] Add the possibility to specify a ratio on node to guarantee its aspect.
- https://github.com/eclipse-sirius/sirius-web/issues/2568[#2568] [trees] Allow developers to modify the content of the explorer view

=== Improvements

Expand Down
@@ -0,0 +1,97 @@
= ADR-115 - Add support for changing the content of the explorer

== Context

The Explorer view displays the same version of a tree to all subscribers.
There is no way for the frontend to change the tree for a specific subscriber.

== Decision

Addition of a TreeConverter API allowing to redefine the tree content (/packages/trees/frontend/sirius-components-trees/src/views/TreeConverter.types.ts)

[source,typescript]
----
interface TreeConverter {
convert(tree: GQLTree): GQLTree;
)
----

Addition of an ExplorerViewContext providing a default TreeConverter (/packages/trees/frontend/sirius-components-trees/src/views/ExplorerViewContext.tsx)

[source,typescript]
----
const converter: TreeConverter = {
convert: (tree) => tree;
};
const defaultContext: ExplorerViewContextValue = {
converter
};
export const ExplorerViewContext = React.createContext(defaultContext);
----

Addition of an ExplorerViewConfiguration providing the context to children (/packages/trees/frontend/sirius-components-trees/src/views/ExplorerViewConfiguration.tsx)

[source,typescript]
----
export const ExplorerViewConfiguration = ({ children, converter }: ExplorerViewConfigurationProps) => {
return (
<ExplorerViewContext.Provider value={{ converter }}>
{children}
</ExplorerViewContext.Provider>
);
}
----

Addition of an useExplorerViewConfiguration function to provide the configuration to interested components (/packages/trees/frontend/sirius-components-trees/src/views/useExplorerViewConfiguration.ts)

[source,typescript]
----
export const useExplorerViewConfiguration = (): UseExplorerViewConfigurationValue => {
const { converter } = useContext(ExplorerViewContext);
return {
converter
};
}
----

Update of the ExplorerView to use the converter (/packages/trees/frontend/sirius-components-trees/src/views/ExplorerView.tsx)

[source,typescript]
----
const { converter } = useExplorerViewConfiguration();
<TreeView converter={converter} ... />
----

Update of the TreeView to use the converter (/packages/trees/frontend/sirius-components-trees/src/views/TreeView.tsx)

[source,typescript]
----
<Tree tree={converter.convert(tree)} ... />
----

Export new APIs (/packages/trees/frontend/sirius-components-trees/src/index.ts):

[source,typescript]
----
ExplorerViewConfiguration
ExplorerViewConfigurationProps
TreeConverter
----

A sirius consumer may encapsulate its components in a ExplorerViewConfiguration which will provide the required filters.

[source,typescript]
----
<ExplorerViewConfiguration converter={MyCustomTreeConverter}>
<Workbench ... />
</ExplorerViewConfiguration>
----

== Status

Accepted

== Consequences

None, by default the Explorer works as before.
Expand Up @@ -43,6 +43,9 @@ export const ModelBrowserTreeView = ({
const classes = useTreeStyle();

const [state, setState] = useState<ModelBrowserTreeViewState>({ filterBarText: '' });
const converter = {
convert: (tree) => tree,
};

return (
<>
Expand All @@ -68,6 +71,7 @@ export const ModelBrowserTreeView = ({
textToFilter={state.filterBarText}
textToHighlight={state.filterBarText}
markedItemIds={markedItemIds}
converter={converter}
/>
</div>
</>
Expand Down
5 changes: 4 additions & 1 deletion packages/trees/frontend/sirius-components-trees/src/index.ts
Expand Up @@ -18,7 +18,10 @@ export * from './treeitems/TreeItemContextMenu';
export * from './treeitems/TreeItemContextMenu.types';
export * from './treeitems/TreeItemContextMenuContribution';
export * from './treeitems/TreeItemContextMenuContribution.types';
export * from './treeitems/filterTreeItem';
export * from './views/ExplorerView';
export * from './views/ExplorerViewConfiguration';
export * from './views/ExplorerViewConfiguration.types';
export * from './views/TreeConverter.types';
export * from './views/TreeView';
export * from './views/TreeView.types';
export * from './treeitems/filterTreeItem';
Expand Up @@ -18,6 +18,7 @@ import { TreeToolBarContext } from '../toolbar/TreeToolBarContext';
import { TreeToolBarContextValue } from '../toolbar/TreeToolBarContext.types';
import { FilterBar } from '../trees/FilterBar';
import { ExplorerViewState } from './ExplorerView.types';
import { useExplorerViewConfiguration } from './ExplorerViewConfiguration';
import { TreeView } from './TreeView';

const useStyles = makeStyles((theme) => ({
Expand All @@ -34,6 +35,7 @@ const useStyles = makeStyles((theme) => ({

export const ExplorerView = (props: WorkbenchViewComponentProps) => {
const styles = useStyles();
const { converter } = useExplorerViewConfiguration();
const initialState: ExplorerViewState = {
synchronizedWithSelection: true,
filterBar: false,
Expand Down Expand Up @@ -112,6 +114,7 @@ export const ExplorerView = (props: WorkbenchViewComponentProps) => {
synchronizedWithSelection={state.synchronizedWithSelection}
textToHighlight={state.filterBarText}
textToFilter={state.filterBarTreeFiltering ? state.filterBarText : null}
converter={converter}
/>
</div>
</div>
Expand Down
@@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2023 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
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/

import { useContext } from 'react';
import { ExplorerViewConfigurationProps, UseExplorerViewConfigurationValue } from './ExplorerViewConfiguration.types';
import { ExplorerViewContext } from './ExplorerViewContext';

export const ExplorerViewConfiguration = ({ children, converter }: ExplorerViewConfigurationProps) => {
return <ExplorerViewContext.Provider value={{ converter }}>{children}</ExplorerViewContext.Provider>;
};

export const useExplorerViewConfiguration = (): UseExplorerViewConfigurationValue => {
const { converter } = useContext<UseExplorerViewConfigurationValue>(ExplorerViewContext);
return {
converter,
};
};
@@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2023 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
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/

import { ReactNode } from 'react';
import { TreeConverter } from './TreeConverter.types';

export interface ExplorerViewConfigurationProps {
converter: TreeConverter;
children: ReactNode;
}

export interface UseExplorerViewConfigurationValue {
converter: TreeConverter;
}
@@ -0,0 +1,25 @@
/*******************************************************************************
* Copyright (c) 2023 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
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
import React from 'react';
import { TreeConverter } from './TreeConverter.types';
import { ExplorerViewContextValue } from './ExplorerViewContext.types';

const converter: TreeConverter = {
convert: (tree) => tree,
};

const defaultContext: ExplorerViewContextValue = {
converter,
};

export const ExplorerViewContext = React.createContext(defaultContext);
@@ -0,0 +1,18 @@
/*******************************************************************************
* Copyright (c) 2023 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
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/

import { TreeConverter } from './TreeConverter.types';

export interface ExplorerViewContextValue {
converter: TreeConverter;
}
@@ -0,0 +1,18 @@
/*******************************************************************************
* Copyright (c) 2023 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
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/

import { GQLTree } from './TreeView.types';

export interface TreeConverter {
convert(tree: GQLTree): GQLTree;
}
Expand Up @@ -80,6 +80,7 @@ export const TreeView = ({
textToHighlight,
textToFilter,
markedItemIds = [],
converter,
}: TreeViewComponentProps) => {
const [{ value, context }, dispatch] = useMachine<TreeViewContext, TreeViewEvent>(treeViewMachine, {
context: {
Expand Down Expand Up @@ -217,7 +218,7 @@ export const TreeView = ({
{tree ? (
<Tree
editingContextId={editingContextId}
tree={tree}
tree={converter.convert(tree)}
onExpand={onExpand}
onExpandAll={onExpandAll}
selection={selection}
Expand Down
Expand Up @@ -12,6 +12,7 @@
*******************************************************************************/

import { WorkbenchViewComponentProps } from '@eclipse-sirius/sirius-components-core';
import { TreeConverter } from './TreeConverter.types';

export interface TreeViewComponentProps extends WorkbenchViewComponentProps {
treeId: string;
Expand All @@ -20,6 +21,7 @@ export interface TreeViewComponentProps extends WorkbenchViewComponentProps {
textToHighlight: string | null;
textToFilter: string | null;
markedItemIds?: string[];
converter: TreeConverter;
}

export interface GQLTreeEventVariables {
Expand Down

0 comments on commit 78bf5b4

Please sign in to comment.