Skip to content

Creating new panels

jmacura edited this page May 7, 2024 · 20 revisions

In version 9.1.0 and higher

Creating custom panels in the sidebar is possible in the Angular part of the application. Your custom panel's component must extend HsPanelBaseComponent like this:

import { HsPanelBaseComponent } from 'hslayers-ng/common/panels';

export class MyCoolComponent extends HsPanelBaseComponent implements OnInit {
  name = 'cool';
  constructor(private hsLayoutService: HsLayoutService, private hsSidebarService: HsSidebarService) { 
     super(hsLayoutService);
  }

  ngOnInit(): void {
    this.hsSidebarService.addButton(
      {
        panel: 'cool',
        module: 'hs.legend',
        order: 1,
        fits: true,
        title: 'PANEL_HEADER.COOL',
        description: 'SIDEBAR.descriptions.COOL',
        icon: 'icon-dotlist',
      }
    );
   }
}

And then in your main.service.ts:

import { Injectable } from '@angular/core';
import { HsSidebarService } from 'hslayers-ng/services/sidebar';
import { HsPanelContainerService } from 'hslayers-ng/services/panels';
import { MyCoolComponent } from './cool.component';

@Injectable({providedIn: 'root'})
export class MainService {
  constructor(
    private hsPanelContainerService: HsPanelContainerService
  ) { }

  init(): void {    
    this.hsPanelContainerService.create(MyCoolComponent, {});
  }
}

Alternatively, you can initiate your component along with its button from app.component/service using:

...

this.hsPanelConstructorService.createPanelAndButton(
  SomeComponent,
  {
    panel: 'custom',
    module: 'some',
    order: 0,
    title: 'Custom panel',
    description: 'Custom panel with some fancy features',
    icon: 'icon-analytics-piechart',
  },
  {},
);

...

Your new panel's template then can use structure like follows:

<div *ngIf="isVisible$ | async"  class="card mainpanel" [ngClass]="panelWidthClass">
  <!-- 
       Empty string as a translationModule to overwrite default PANEL_HEADER to satisfy traslationOverrides definition
       Another possibility would be to define panelName using PANEL_HEADER obj in config
   -->
  <hs-panel-header name="custom" [panelTabs]="'My Cool Panel'" [translationModule]="''">
  </hs-panel-header>
  <div class="card-body">
    Put your panel content here.
  </div>
</div>

Just don't forget to

  • add [ngClass]="panelWidthClass" which makes sure value set in HsConfig.panelWidths is reflected (panelWidths key and name property of your component should match)
  • add *ngIf="isVisible$ | async" to make sure your panel visibility is controlled by value of HsLayoutService.mainpanel$ subject (controlled by sidebar buttons)

To learn more about panel-header component see Panel header page.

Icon

For the new panel you will need to have an icon set to be displayed in the sidebar. In the above example 'icon-dotlist' was used, which is one of the predefined icons present in whhg.css files which is automatically included with hslayers-ng.

If you would like to have a custom icon such as in this example:

this.hsSidebarService.addButton(
      {
        panel: 'statistics',
        visible: true,
        title: 'PANEL_HEADER.STATISTICS',
        description: 'SIDEBAR.descriptions.STATISTICS',
        icon: 'statistics-icon-barchartasc',
      },
      this.data.app
    );

you will need to provide a font and icon definition in a separate css file. It provides WebHostingHub-GlyphsStatistics font not to conflict with WebHostingHub-Glyphs which is already included in hslayers-ng. Notice also that icon class is different: statistics-icon-barchartasc instead of icon-barchartasc. The fonts *.ttf file is encoded into base64 string using https://www.giftofspeed.com/base64-encoder/.

Angular.json for the project would have content similar to:

"styles": [
              "./node_modules/hslayers-ng/css/hslayers-ng.css",
              "./projects/example-project/src/styles.scss"
            ]

And styles.scss needs to include the css file providing custom WebHostingHub-GlyphsStatistics font:

@import "../css/whhg-font/css/whhg.css"

Font subset

You could include the whole webhosting-hub-glyphs.ttf file, but that would be inefficient. The custom font containing only the needed glyphs can be build from webhostinghub-glyphs.ttf using pyftsubset script (provided by fonttools and ttf2eot utility. Here is an example script to compile the font.

The resulting subset.ttf file can be then uploaded into the aforementioned https://www.giftofspeed.com/base64-encoder/ to convert it to base64 encoded font which can be copied into whhg.css file.

See also How to add new icon from the WHHG font in the Development Guidelines.

In older versions

NOTE: Older versions of hslayers-ng are not actively maintained!

In version 2.3.0 to 9.0.0

Creating custom panels in the sidebar is possible in the Angular part of the application. Your custom panel's component must implement HsPanelComponent like this:

export class MyCoolComponent implements HsPanelComponent {
  data: any;
  viewRef: ViewRef;
  constructor(private hsLayoutService: HsLayoutService) { }
  isVisible() {
    return this.hsLayoutService.panelVisible('cool');
  }
}

And then in your main.service.ts:

import { Injectable } from '@angular/core';
import { HsSidebarService } from 'hslayers-ng/components/sidebar/sidebar.service';
import { HsPanelContainerService } from 'hslayers-ng/components/layout/panels/panel-container.service';
import { MyCoolComponent } from './cool.component';
@Injectable({providedIn: 'root'})
export class MainService {
  constructor(
    private hsSidebarService: HsSidebarService,
    private hsPanelContainerService: HsPanelContainerService
  ) { }
  init(): void {
    this.hsSidebarService.buttons.push({
      panel: 'cool',
      module: '',
      order: 7,
      title: 'My Cool Panel',
      description: 'Open My Cool Panel',
      icon: 'icon-time'
    });
    this.hsPanelContainerService.create(MyCoolComponent, {});
  }
}
Clone this wiki locally