Skip to main content

Custom Project Views

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 3 main steps:

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

1. 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.


2. 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
    }
    }

3. 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.