Frontend Component
Plugins may or may not contain a frontend component and are instantiated by the Angular compiler. See the @icepanel/core-frontend package for frontend specific helper services.
Frontend plugin instances are created each time a view is loaded in the browser and are unique each time they are opened.
For information about communicating between frontend and backend components please see Plugin Communication.
Anguar module
Ensure the default export for your module is an Angular module so that IcePanel can instantiate it. Use methods defined in IFrontendModule to specify which Angular component should be used as the entry point for each view.
- environmentComponent - Displayed on the right sidebar when viewing environment nodes
- prototypeComponent - Displayed on the right sidebar when editing prototype nodes
- setupComponent - Only used for Engine setup dialogs.
See below an example frontend Angular module.
import { CommonModule } from '@angular/common'
import { NgModule } from '@angular/core'
import { IModel, PluginType } from '@icepanel/core'
import { IcePanelFrontendModule, IFrontendModule } from '@icepanel/core-frontend'
import { PrototypeAppComponent } from './prototype-app'
import { EnvironmentAppComponent } from './environment-app'
import { SetupComponent } from './setup'
@NgModule({
imports: [
CommonModule,
IcePanelFrontendModule
],
declarations: [
PrototypeAppComponent,
EnvironmentAppComponent,
SetupComponent
],
// including the component in entryComponents allows it to be bootstrapped by IcePanel
entryComponents: [
PrototypeAppComponent,
EnvironmentAppComponent,
SetupComponent
]
})
export default class FrontendModule implements IFrontendModule {
environmentComponent(model: IModel) {
switch (model.plugin.type) {
case PluginType.App:
return EnvironmentAppComponent
default:
return null
}
}
prototypeComponent(model: IModel) {
switch (model.plugin.type) {
case PluginType.App:
return PrototypeAppComponent
default:
return null
}
}
setupComponent() {
return SetupComponent
}
}
Accessing and modifying models
You can access and modify the prototype model by injecting the PrototypeService class into your Angular component.
See the example below for how to set the name of the current model in context inside the prototype.
import { Component } from '@angular/core'
import { IAppModel } from '@icepanel/core'
import { PrototypeService } from '@icepanel/core-frontend'
// create an Angular component
@Component({
styleUrls: ['./style.scss'], // sass is compiled by the sass-loader and node-sass
templateUrl: './template.html' // html template is compiled by the angular2-template-loader dependency
})
export class PrototypeAppComponent {
// using private in the constructor generates class properties automatically
constructor(private prototypeService: PrototypeService<IAppModel>) {}
saveName(name: string) {
this.prototypeService.model.name = name
this.prototypeService.sync()
}
}
After the prototype has been deployed you can use the EnvironmentService class to access readonly values about the environment.
import { Component, OnInit } from '@angular/core'
import { IAppModel } from '@icepanel/core'
import { EnvironmentAppComponent } from '@icepanel/core-frontend'
@Component({
styleUrls: ['./style.scss'],
templateUrl: './template.html'
})
export class EnvironmentAppComponent implements OnInit {
constructor(private environmentService: EnvironmentAppComponent<IAppModel>) {}
// ngOnInit is an Anguar lifecycle hook for when the component has loaded
ngOnInit() {
const name = this.environmentService.model.name
console.log(`the name of this model is ${name}`)
}
}
Backend communication
You can communicate with either the engine plugin using EngineService or the plugin itself using PluginService.
See the below example for how to call a method which has been exported by the backend plugin.
import { Component, OnInit } from '@angular/core'
import { IAppStatus } from '@icepanel/core'
import { PluginService } from '@icepanel/core-frontend'
@Component({
styleUrls: ['./style.scss'],
templateUrl: './template.html'
})
export class EnvironmentAppComponent implements OnInit {
status: IAppStatus
constructor(private pluginService: PluginService) {}
async ngOnInit() {
this.status = await this.pluginService.method('getStatus')()
console.log(`this plugins status is ${this.status}`)
}
}
See below how to subscribe to a PubSub topic on the backend engine plugin.
import { Component, OnInit } from '@angular/core'
import { IAppStatus, IAppModel } from '@icepanel/core'
import { EnvironmentService, EngineService, ViewSubscription } from '@icepanel/core-frontend'
@Component({
styleUrls: ['./style.scss'],
templateUrl: './template.html'
})
export class EnvironmentAppComponent implements OnInit {
status: IAppStatus
statusSub: ViewSubscription<{ status: IAppStatus }>
constructor(
private environmentService: EnvironmentService<IAppModel>,
private engineService: EngineService
) {}
async ngOnInit() {
// generate the PubSub topic name which has been created
const environmentId = this.environmentService.environment.id
const modelId = this.environmentService.model.id
const topicName = `status.${environmentId}.${modelId}`
// listen for messages on the PubSub topic
this.statusSub = await this.engineService.subscribe(topicName)
this.statusSub.on('message', data => {
this.status = data.status
console.log(`this plugins status has changed to ${this.status}`)
})
}
}