Skip to main content

Project Views

Project Views are a fundamental aspect of customizing the editor's user interface. They define how your model is presented to the user, including the layout of the editing area, the types of visual representations available (like diagrams), and the navigation options within the project.

By configuring Project Views, you can tailor the editor experience to the specific needs of different metamodels and user workflows.

Project View Components: Defining Editor Layouts

Project View Components dictate the primary layout of the editor's main editing area. They are activated when a user selects a model element in the project navigation (typically a root element like a program or module). The user can then switch between views provided by the ProjectViewComponents.

Each projectViewComponent targets a specific ElementClass (the type of model element it applies to) and a category (which defines the structural layout of the view).

  • ProjectViewComponents are typically designed to target model root elements, such as programs or modules, as they define the overall view for a significant part of the model.
  • The editor provides three standard, built-in view categories:
    • tree-detail: This is a two-pane layout, featuring the model's tree view on the left and the details panel of the selected element on the right.
    • 3-pane: This layout offers three panes: the tree view on the left, the element details on the right, and a central pane typically used for a diagrammatic representation of the model.
    • diagram: This view dedicates the entire editing area to a full-size diagram of the model, maximizing the visual workspace.
  • If more than one projectViewComponent is applicable to the currently selected model element and view category, the editor will display tabs, allowing the user to easily switch between these different view implementations.
  • If autogenerate is enabled, the expanders will generate a default implementation for each view.
<editorModelExtension xmlns="https://schemas.normalizedsystems.org/xsd/editorElements/4/0/0">
<name>application-project</name>
<projectViewComponents>
<projectViewComponent>
<name>ComponentTreeDetail</name>
<autogenerate>true</autogenerate>
<category>tree-detail</category>
<elementClass>elements::Component</elementClass>
</projectViewComponent>
<projectViewComponent>
<name>Component3Pane</name>
<autogenerate>true</autogenerate>
<category>3-pane</category>
<elementClass>elements::Component</elementClass>
</projectViewComponent>
<projectViewComponent>
<name>ComponentDiagram</name>
<autogenerate>true</autogenerate>
<category>diagram</category>
<elementClass>elements::Component</elementClass>
</projectViewComponent>
</projectViewComponents>
</editorModelExtension>

In this example, three different view components are defined for the elements::Component element class, each corresponding to a standard view category.

Project Facets: Enhancing Project Navigation

Project Facets provide the navigation options presented within the project navigation sidebar.

The editor automatically creates a navigation option for each program in the project by matching projectFacets that target that program element. If no specific facet is defined for a program, the editor will utilize a default navigation implementation.

<editorModelExtension xmlns="https://schemas.normalizedsystems.org/xsd/editorElements/4/0/0">
<name>application-project</name>
<projectFacets>
<projectFacet>
<name>Application</name>
<!-- This facet provide navigation for Application -->
<elementClass>elements::Application</elementClass>
<views>
<!-- define view categories for this facet -->
<projectViewCategory>tree-detail</projectViewCategory>
<projectViewCategory>3-pane</projectViewCategory>
<projectViewCategory>diagram</projectViewCategory>
</views>
<options>
<!-- Define an icon with the option -->
<mrp.material.symbols.icon>monitor</mrp.material.symbols.icon>
</options>
</projectFacet>
</projectFacets>
</editorModelExtension>

In this configuration:

  • A projectFacet named Application is defined for elements::Application elements.
  • When an elements::Application instance is present in the project, a navigation entry for that Application will appear.
  • Clicking this navigation entry will expose the tree-detail, 3-pane, and diagram views, assuming corresponding projectViewComponents are defined. A monitor icon from the Material Symbols library will be displayed in the navigation option.

Diagram Components: Visualizing Your Model

Diagram Components are essential for providing visual representations of your model. When defined, the editor generates a customizable component that can render diagrams. These diagrams are typically displayed within the 3-pane and diagram views, offering users an intuitive way to understand complex model structures.

<editorModelExtension xmlns="https://schemas.normalizedsystems.org/xsd/editorElements/4/0/0">
<name>prime-diagrams</name>
<diagramComponents>
<diagramComponent>
<name>DataElementsClass</name>
<title>Data Elements</title>
<projectViews>
<elementClass>elements::Component</elementClass>
</projectViews>
</diagramComponent>
</diagramComponents>
</editorModelExtension>

Custom Views: Beyond Standard Layouts

While the standard views cover many use cases, you might occasionally need to create entirely custom editor views that don't fit these predefined layouts. This section outlines a common pattern for implementing such custom views.

The pattern involves three main steps:

  • Create a new custom view category: This separates your custom view from the standard categories, providing a unique identifier.
  • Create a customized facet: This facet will link your custom view to a specific navigation entry, potentially always present or conditionally active.
  • Create a ProjectViewComponent to implement the custom editor view: This component will contain the actual logic and UI for your specialized view.

Custom Project View Categories

To define a new view category for your custom view, you'll need to:

a. Define a settings directory: Ensure your expansionSettings.xml includes a settingsDirectory that points to where your view category XML file will reside.

conf/expansionSettings.xml
<expansionSettings>
<!-- ... -->
<settingsDirectories>
<settingsDirectory>
<directory>../conf</directory>
</settingsDirectory>
</settingsDirectories>
</expansionSettings>

b. Define the ProjectViewCategory XML: Create an XML file within your conf/projectViewCategory/ directory (or wherever your settingsDirectory points) to define your new category.

conf/projectViewCategory/build-expand.xml
<projectViewCategory xmlns="https://schemas.normalizedsystems.org/xsd/editorElements/4/0/0">
<name>build-expand</name>
<title>Expand</title>
<options>
<!-- Define icon with option -->
<mrp.material.symbols.icon>construction</mrp.material.symbols.icon>
</options>
</projectViewCategory>

Here, build-expand is the internal name, and "Expand" is the user-facing title.

Customized Facet

To make your custom view accessible, you'll typically define a ProjectFacet that targets your new projectViewCategory. If you omit the elementClass for a projectFacet, it will always be present in the project navigation, making it a good choice for global custom tools or views.

<editorModelExtension xmlns="https://schemas.normalizedsystems.org/xsd/editorElements/4/0/0">
<name>build-pages</name>
<projectFacets>
<projectFacet>
<name>build</name>
<views>
<!-- Target your custom view category -->
<projectViewCategory>build-expand</projectViewCategory>
</views>
<options>
<mrp.material.symbols.icon>build</mrp.material.symbols.icon>
</options>
</projectFacet>
</projectFacets>
</editorModelExtension>

This build facet will always appear in the navigation, and when selected, it will show the build-expand view.

Customizing Facet Behavior (TypeScript):

Generated facets will have methods that you can customize in TypeScript to control their applicability and the model they represent.

  • isApplicable() method: This method determines if the facet should be shown in the navigation for a given project. You can add custom logic to make it conditional.

    export class BuildFacet implements ProjectFacet {

    //...

    static async isApplicable(project: ProjectData): Promise<boolean> {
    // anchor:custom-is-applicable:start
    // Add custom logic here to determine if this facet is applicable.
    // For example, check for specific elements in the project or flags.
    // anchor:custom-is-applicable:end
    return true
    }
    }
  • model() method: This method is crucial. It defines the ModelProjection that the facet represents when selected. The selection must be a valid element that your custom ProjectViewComponent is designed to handle.

    export class BuildFacet implements ProjectFacet {
    //...
    async model(): Promise<ModelProjection> {
    // anchor:custom-model:start
    // Return a representation of the 'model' that your custom view expects.
    // In this case, we have a Project ElementClass that acts as target element.
    return new ProjectModel({
    name: this.project.name,
    baseUrl: this.project.baseUrl
    })
    // anchor:custom-model:end
    }
    }

Custom project view

Finally, you need to create the ProjectViewComponent that will implement the actual UI and logic for your custom editor view. This component targets your custom projectViewCategory and the ElementClass that your facet's model() method returns.

<editorModelExtension xmlns="https://schemas.normalizedsystems.org/xsd/editorElements/4/0/0">
<name>build-pages</name>
<projectViewComponents>
<projectViewComponent>
<name>Expand</name>
<autogenerate>false</autogenerate>
<category>build-expand</category>
<elementClass>build::Project</elementClass>
</projectViewComponent>
</projectViewComponents>
</editorModelExtension>

The ProjectViewComponent is expanded as an Angular Component and can be customized as necessary.