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:
- 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
ProjectViewComponentto 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.
<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.
<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.