Skip to content

Commit

Permalink
feat(toolbox): refactor context toolbar into a better and reusable to…
Browse files Browse the repository at this point in the history
…olbox
  • Loading branch information
cbourget committed Feb 22, 2019
1 parent 6a3b8cc commit 64e078d
Show file tree
Hide file tree
Showing 24 changed files with 731 additions and 4 deletions.
1 change: 1 addition & 0 deletions demo/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ <h1>{{title}}</h1>
<a mat-list-item routerLink="entity-table">Entity Table</a>
<a mat-list-item routerLink="form">Form</a>
<a mat-list-item routerLink="table">Table</a>
<a mat-list-item routerLink="tool">Tool</a>
<a mat-list-item routerLink="widget">Widget</a>

<hr>
Expand Down
2 changes: 2 additions & 0 deletions demo/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { AppDynamicComponentModule } from './common/dynamic-component/dynamic-co
import { AppEntityTableModule } from './common/entity-table/entity-table.module';
import { AppFormModule } from './common/form/form.module';
import { AppTableModule } from './common/table/table.module';
import { AppToolModule } from './common/tool/tool.module';
import { AppWidgetModule } from './common/widget/widget.module';

import { AppAuthFormModule } from './auth/auth-form/auth-form.module';
Expand Down Expand Up @@ -67,6 +68,7 @@ import { AppComponent } from './app.component';
AppEntityTableModule,
AppFormModule,
AppTableModule,
AppToolModule,
AppWidgetModule,

AppAuthFormModule,
Expand Down
7 changes: 5 additions & 2 deletions demo/src/app/common/action/action.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,11 @@ export class AppActionComponent implements OnInit, OnDestroy {
title: 'Edit',
icon: 'edit',
tooltip: 'Edit Tooltip',
handler: () => alert('Edit!'),
conditions: [added]
handler: (item: string) => {
alert(`Edit item ${item}!`);
},
conditions: [added],
args: ['1']
},
{
id: 'delete',
Expand Down
15 changes: 15 additions & 0 deletions demo/src/app/common/tool/tool-routing.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Routes, RouterModule } from '@angular/router';
import { ModuleWithProviders } from '@angular/core';

import { AppToolComponent } from './tool.component';

const routes: Routes = [
{
path: 'tool',
component: AppToolComponent
}
];

export const AppToolRoutingModule: ModuleWithProviders = RouterModule.forChild(
routes
);
36 changes: 36 additions & 0 deletions demo/src/app/common/tool/tool.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<mat-card>
<mat-card-subtitle>Common</mat-card-subtitle>
<mat-card-title>Tool</mat-card-title>
<mat-card-content>
See the <a href="https://github.com/infra-geo-ouverte/igo2-lib/tree/master/demo/src/app/common/tool">code of this example</a>
</mat-card-content>

<igo-panel [title]="panelTitle">
<button
mat-icon-button
panelLeftButton
(click)="toolbox.activatePreviousTool()"
*ngIf="activeTool$ | async">
<mat-icon>arrow_back</mat-icon>
</button>

<button
mat-icon-button
panelRightButton
(click)="toolbox.deactivateTool()"
*ngIf="activeTool$ | async">
<mat-icon>menu</mat-icon>
</button>

<igo-toolbox [toolbox]="toolbox" [animate]="true"></igo-toolbox>
</igo-panel>

<button
mat-flat-button
type="button"
color="primary"
(click)="activateSalutationTool()">
Activate Salutation Tool
</button>

</mat-card>
12 changes: 12 additions & 0 deletions demo/src/app/common/tool/tool.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
pre,
code {
font-family: monospace, monospace;
}
pre {
overflow: auto;
}
pre > code {
display: block;
padding: 1rem;
word-wrap: normal;
}
90 changes: 90 additions & 0 deletions demo/src/app/common/tool/tool.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import {
Component,
OnInit,
OnDestroy,
Input,
ChangeDetectionStrategy,
ChangeDetectorRef
} from '@angular/core';

import { BehaviorSubject } from 'rxjs';

import {
OnUpdateInputs,
Tool,
Toolbox,
ToolComponent,
ToolService
} from '@igo2/common';

@ToolComponent({
name: 'salutation',
title: 'Salutation',
icon: 'person',
options: {name: 'Jack'}
})
@Component({
selector: 'app-salutation-tool',
template: `
<p>Hello, my name is {{name}}.</p>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppSalutationToolComponent implements OnUpdateInputs {

@Input() name: string;

constructor(private cdRef: ChangeDetectorRef) {}

onUpdateInputs() {
this.cdRef.detectChanges();
}

}

@ToolComponent({
name: 'about',
title: 'About',
icon: 'info'
})
@Component({
selector: 'app-about-tool',
template: `
<p>I'm a tool inside a toolbox.</p>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppAboutToolComponent {}

@Component({
selector: 'app-tool',
templateUrl: './tool.component.html',
styleUrls: ['./tool.component.scss']
})
export class AppToolComponent implements OnInit, OnDestroy {

toolbox = new Toolbox();

get activeTool$(): BehaviorSubject<Tool> {
return this.toolbox.activeTool$;
}

get panelTitle(): string {
return this.activeTool$.value ? this.activeTool$.value.title : 'Toolbox';
}

constructor(private toolService: ToolService) {}

ngOnInit() {
this.toolbox.setTools(this.toolService.getTools());
}

ngOnDestroy() {
this.toolbox.destroy();
}

activateSalutationTool() {
this.toolbox.activateTool('salutation', {name: 'Bob'});
}

}
35 changes: 35 additions & 0 deletions demo/src/app/common/tool/tool.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatButtonModule, MatIconModule, MatCardModule } from '@angular/material';

import { IgoPanelModule, IgoToolModule } from '@igo2/common';

import {
AppToolComponent,
AppSalutationToolComponent,
AppAboutToolComponent
} from './tool.component';
import { AppToolRoutingModule } from './tool-routing.module';

@NgModule({
declarations: [
AppToolComponent,
AppSalutationToolComponent,
AppAboutToolComponent
],
imports: [
CommonModule,
AppToolRoutingModule,
MatButtonModule,
MatIconModule,
MatCardModule,
IgoPanelModule,
IgoToolModule.forRoot()
],
exports: [AppToolComponent],
entryComponents: [
AppSalutationToolComponent,
AppAboutToolComponent
]
})
export class AppToolModule {}
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ export class DynamicOutletComponent implements OnChanges, OnDestroy {
/**
* The dynamic component inputs
*/
@Input() inputs: {[key: string]: any};
@Input() inputs: {[key: string]: any} = {};

/**
* The subscribers to the dynamic component outputs
*/
@Input() subscribers: {[key: string]: (event: any) => void};
@Input() subscribers: {[key: string]: (event: any) => void} = {};

/**
* The dynamic component
Expand Down
5 changes: 5 additions & 0 deletions packages/common/src/lib/form/shared/form-field.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { Injectable } from '@angular/core';

/**
* Service where all available form fields are registered.
*/
@Injectable({
providedIn: 'root'
})
export class FormFieldService {

static fields: {[key: string]: any} = {};
Expand Down
3 changes: 3 additions & 0 deletions packages/common/src/public_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export * from './lib/sidenav/sidenav.module';
export * from './lib/spinner/spinner.module';
export * from './lib/stop-propagation/stop-propagation.module';
export * from './lib/table/table.module';
export * from './lib/tool/tool.module';
export * from './lib/tool/toolbox/toolbox.module';
export * from './lib/widget/widget.module';
export * from './lib/widget/widget-outlet/widget-outlet.module';

Expand All @@ -53,4 +55,5 @@ export * from './lib/sidenav';
export * from './lib/spinner';
export * from './lib/stop-propagation';
export * from './lib/table';
export * from './lib/tool';
export * from './lib/widget';
1 change: 1 addition & 0 deletions projects/common/src/lib/tool/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './shared';
4 changes: 4 additions & 0 deletions projects/common/src/lib/tool/shared/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './tool.interface';
export * from './tool.service';
export * from './tool-component';
export * from './toolbox';
10 changes: 10 additions & 0 deletions projects/common/src/lib/tool/shared/tool-component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Tool } from './tool.interface';
import { ToolService } from './tool.service';

export function ToolComponent(tool: Partial<Tool>): (cls: any) => any {
return function (compType: any) {
ToolService.register(Object.assign({}, tool, {
component: compType
} as Tool));
};
}
9 changes: 9 additions & 0 deletions projects/common/src/lib/tool/shared/tool.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export interface Tool {
name: string;
component: any;
title?: string;
icon?: string;
iconImage?: string;
tooltip?: string;
options?: { [key: string]: any };
}
17 changes: 17 additions & 0 deletions projects/common/src/lib/tool/shared/tool.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { TestBed, inject } from '@angular/core/testing';
import { HttpClientModule } from '@angular/common/http';

import { ToolService } from './tool.service';

describe('ToolService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientModule],
providers: [ToolService]
});
});

it('should ...', inject([ToolService], (service: ToolService) => {
expect(service).toBeTruthy();
}));
});
38 changes: 38 additions & 0 deletions projects/common/src/lib/tool/shared/tool.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Injectable } from '@angular/core';

import { Tool } from './tool.interface';

/**
* Service where runtime tool configurations are registered
*/
@Injectable({
providedIn: 'root'
})
export class ToolService {

static tools: {[key: string]: Tool} = {};

static register(tool: Tool) {
ToolService.tools[tool.name] = tool;
}

constructor() {}

/**
* Return a tool
* @param name Tool name
* @returns tool Tool
*/
getTool(name: string): Tool {
return ToolService.tools[name];
}

/**
* Return all tools
* @returns tTols
*/
getTools(): Tool[] {
return Object.values(ToolService.tools);
}

}
Loading

0 comments on commit 64e078d

Please sign in to comment.