Rule chain page
This commit is contained in:
		
							parent
							
								
									3d6b058b9d
								
							
						
					
					
						commit
						aa1a43fcea
					
				
							
								
								
									
										103
									
								
								ui-ngx/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										103
									
								
								ui-ngx/package-lock.json
									
									
									
										generated
									
									
									
								
							@ -5140,9 +5140,9 @@
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "handlebars": {
 | 
			
		||||
      "version": "4.5.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.1.tgz",
 | 
			
		||||
      "integrity": "sha512-C29UoFzHe9yM61lOsIlCE5/mQVGrnIOrOq7maQl76L7tYPCgC1og0Ajt6uWnX4ZTxBPnjw+CUvawphwCfJgUnA==",
 | 
			
		||||
      "version": "4.5.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.2.tgz",
 | 
			
		||||
      "integrity": "sha512-29Zxv/cynYB7mkT1rVWQnV7mGX6v7H/miQ6dbEpYTKq5eJBN7PsRB+ViYJlcT6JINTSu4dVB9kOqEun78h6Exg==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "neo-async": "^2.6.0",
 | 
			
		||||
@ -7411,6 +7411,97 @@
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/ngx-color-picker/-/ngx-color-picker-8.2.0.tgz",
 | 
			
		||||
      "integrity": "sha512-rzR+cByjNG9M/UskU5vNoH7cUc6oM8STTDFKOZmnlX4ALOuM1+61CBjsNTGETWfo9a/h5mbGX02oh5/iNAa7vA=="
 | 
			
		||||
    },
 | 
			
		||||
    "ngx-flowchart": {
 | 
			
		||||
      "version": "git://github.com/thingsboard/ngx-flowchart.git#d26ee52089a6d9cf8147c5f162144825fceb3009",
 | 
			
		||||
      "from": "git://github.com/thingsboard/ngx-flowchart.git#master",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "@angular/animations": "~8.0.0",
 | 
			
		||||
        "@angular/common": "~8.0.0",
 | 
			
		||||
        "@angular/compiler": "~8.0.0",
 | 
			
		||||
        "@angular/core": "~8.0.0",
 | 
			
		||||
        "@angular/forms": "~8.0.0",
 | 
			
		||||
        "@angular/platform-browser": "~8.0.0",
 | 
			
		||||
        "@angular/platform-browser-dynamic": "~8.0.0",
 | 
			
		||||
        "@angular/router": "~8.0.0",
 | 
			
		||||
        "rxjs": "~6.4.0",
 | 
			
		||||
        "tslib": "^1.9.0",
 | 
			
		||||
        "zone.js": "~0.9.1"
 | 
			
		||||
      },
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@angular/animations": {
 | 
			
		||||
          "version": "8.0.3",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-8.0.3.tgz",
 | 
			
		||||
          "integrity": "sha512-9zciJ4YRR0bodFSYgsgXdYMz8wKKyVjch7XZADGkWubXT8mGuwlpdPMlQ6n9Cwj8Ebu0u52WxMeQsX76K9RlYA==",
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "tslib": "^1.9.0"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "@angular/common": {
 | 
			
		||||
          "version": "8.0.3",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/@angular/common/-/common-8.0.3.tgz",
 | 
			
		||||
          "integrity": "sha512-2YLYGVUf9eJZcocRmD3/9UHj4qFHt2t4ftDWJmrFM9zo2PZF+G5O9fASO7qoBbwpx3KFZtQO4dprKl2dFugRjg==",
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "tslib": "^1.9.0"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "@angular/compiler": {
 | 
			
		||||
          "version": "8.0.3",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-8.0.3.tgz",
 | 
			
		||||
          "integrity": "sha512-1/vF8D6l1O6IfWiDtaj6nC+B8CtkVtFgXgooDzLBO6XAkaCuJCnhKT1HnpWG5GtVsGaY9MGoTl1vE9ZMDbRQjg==",
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "tslib": "^1.9.0"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "@angular/core": {
 | 
			
		||||
          "version": "8.0.3",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/@angular/core/-/core-8.0.3.tgz",
 | 
			
		||||
          "integrity": "sha512-IIxrtIPNuv2+HudER9J1nmPGiGJ4aRpeiFM9V4lSiSFv50RzuaoG60XqYIpUyuBdgvyKigcrfSbu9+x1vyN0hw==",
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "tslib": "^1.9.0"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "@angular/forms": {
 | 
			
		||||
          "version": "8.0.3",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-8.0.3.tgz",
 | 
			
		||||
          "integrity": "sha512-22s82QDRQ72K4vMYuNh3NAN+da9uanwoydnfKlp2rb9dZAb2QVX9NN6gSoMrkSSr2O9KTP6pWiw6A3/MW8sGRA==",
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "tslib": "^1.9.0"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "@angular/platform-browser": {
 | 
			
		||||
          "version": "8.0.3",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-8.0.3.tgz",
 | 
			
		||||
          "integrity": "sha512-ceAPP2Ijmk2sZ1rnOU/WNlE3DtT6K6ljpjO9oUfXKMoSMdWirJKAraT3m/BAzmYwMSXpPBxA7c3paZjiLL6t5A==",
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "tslib": "^1.9.0"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "@angular/platform-browser-dynamic": {
 | 
			
		||||
          "version": "8.0.3",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-8.0.3.tgz",
 | 
			
		||||
          "integrity": "sha512-ZjQjSYslSQAKzM4llvyMFxnSjFpbhT1U9FOdKwscPe475zAKX0087qsHrP2CRwkJRfwtdcmj9wMUQIPlzMpHLA==",
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "tslib": "^1.9.0"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "@angular/router": {
 | 
			
		||||
          "version": "8.0.3",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/@angular/router/-/router-8.0.3.tgz",
 | 
			
		||||
          "integrity": "sha512-CU5pLTfQVUnTN93mdIKJrVjXiNldUkk30DPz4lpdxpZjYOqFGXeeSeQWmToHSofLPodNcAB4kkZ41VyXvlBu7w==",
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "tslib": "^1.9.0"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "rxjs": {
 | 
			
		||||
          "version": "6.4.0",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz",
 | 
			
		||||
          "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==",
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "tslib": "^1.9.0"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "ngx-hm-carousel": {
 | 
			
		||||
      "version": "1.7.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/ngx-hm-carousel/-/ngx-hm-carousel-1.7.2.tgz",
 | 
			
		||||
@ -10796,9 +10887,9 @@
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "uglify-js": {
 | 
			
		||||
      "version": "3.6.8",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.8.tgz",
 | 
			
		||||
      "integrity": "sha512-XhHJ3S3ZyMwP8kY1Gkugqx3CJh2C3O0y8NPiSxtm1tyD/pktLAkFZsFGpuNfTZddKDQ/bbDBLAd2YyA1pbi8HQ==",
 | 
			
		||||
      "version": "3.6.9",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.9.tgz",
 | 
			
		||||
      "integrity": "sha512-pcnnhaoG6RtrvHJ1dFncAe8Od6Nuy30oaJ82ts6//sGSXOP5UjBMEthiProjXmMNHOfd93sqlkztifFMcb+4yw==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "optional": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
 | 
			
		||||
@ -59,6 +59,7 @@
 | 
			
		||||
    "moment": "^2.24.0",
 | 
			
		||||
    "ngx-clipboard": "^12.2.0",
 | 
			
		||||
    "ngx-color-picker": "^8.2.0",
 | 
			
		||||
    "ngx-flowchart": "git://github.com/thingsboard/ngx-flowchart.git#master",
 | 
			
		||||
    "ngx-hm-carousel": "^1.7.2",
 | 
			
		||||
    "ngx-translate-messageformat-compiler": "^4.5.0",
 | 
			
		||||
    "objectpath": "^1.2.2",
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,19 @@
 | 
			
		||||
<!--
 | 
			
		||||
 | 
			
		||||
    Copyright © 2016-2019 The Thingsboard Authors
 | 
			
		||||
 | 
			
		||||
    Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
    you may not use this file except in compliance with the License.
 | 
			
		||||
    You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
        http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
    Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
    distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
    See the License for the specific language governing permissions and
 | 
			
		||||
    limitations under the License.
 | 
			
		||||
 | 
			
		||||
-->
 | 
			
		||||
<div>Rule chain</div>
 | 
			
		||||
<fc-canvas></fc-canvas>
 | 
			
		||||
@ -0,0 +1,62 @@
 | 
			
		||||
///
 | 
			
		||||
/// Copyright © 2016-2019 The Thingsboard Authors
 | 
			
		||||
///
 | 
			
		||||
/// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
/// you may not use this file except in compliance with the License.
 | 
			
		||||
/// You may obtain a copy of the License at
 | 
			
		||||
///
 | 
			
		||||
///     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
///
 | 
			
		||||
/// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
/// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
/// See the License for the specific language governing permissions and
 | 
			
		||||
/// limitations under the License.
 | 
			
		||||
///
 | 
			
		||||
 | 
			
		||||
import {Component, OnInit} from '@angular/core';
 | 
			
		||||
import {UserService} from '@core/http/user.service';
 | 
			
		||||
import {User} from '@shared/models/user.model';
 | 
			
		||||
import {Authority} from '@shared/models/authority.enum';
 | 
			
		||||
import {PageComponent} from '@shared/components/page.component';
 | 
			
		||||
import {Store} from '@ngrx/store';
 | 
			
		||||
import {AppState} from '@core/core.state';
 | 
			
		||||
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
 | 
			
		||||
import {HasConfirmForm} from '@core/guards/confirm-on-exit.guard';
 | 
			
		||||
import {ActionAuthUpdateUserDetails} from '@core/auth/auth.actions';
 | 
			
		||||
import {environment as env} from '@env/environment';
 | 
			
		||||
import {TranslateService} from '@ngx-translate/core';
 | 
			
		||||
import {ActionSettingsChangeLanguage} from '@core/settings/settings.actions';
 | 
			
		||||
import {ChangePasswordDialogComponent} from '@modules/home/pages/profile/change-password-dialog.component';
 | 
			
		||||
import {MatDialog} from '@angular/material';
 | 
			
		||||
import {DialogService} from '@core/services/dialog.service';
 | 
			
		||||
import {AuthService} from '@core/auth/auth.service';
 | 
			
		||||
import {ActivatedRoute} from '@angular/router';
 | 
			
		||||
import { Dashboard } from '@shared/models/dashboard.models';
 | 
			
		||||
import { RuleChain } from '@shared/models/rule-chain.models';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'tb-rulechain-page',
 | 
			
		||||
  templateUrl: './rulechain-page.component.html',
 | 
			
		||||
  styleUrls: []
 | 
			
		||||
})
 | 
			
		||||
export class RuleChainPageComponent extends PageComponent implements OnInit {
 | 
			
		||||
 | 
			
		||||
  ruleChain: RuleChain;
 | 
			
		||||
 | 
			
		||||
  constructor(protected store: Store<AppState>,
 | 
			
		||||
              private route: ActivatedRoute,
 | 
			
		||||
              private userService: UserService,
 | 
			
		||||
              private authService: AuthService,
 | 
			
		||||
              private translate: TranslateService,
 | 
			
		||||
              public dialog: MatDialog,
 | 
			
		||||
              public dialogService: DialogService,
 | 
			
		||||
              public fb: FormBuilder) {
 | 
			
		||||
    super(store);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ngOnInit() {
 | 
			
		||||
    this.ruleChain = this.route.snapshot.data.ruleChain;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -14,12 +14,44 @@
 | 
			
		||||
/// limitations under the License.
 | 
			
		||||
///
 | 
			
		||||
 | 
			
		||||
import {NgModule} from '@angular/core';
 | 
			
		||||
import {RouterModule, Routes} from '@angular/router';
 | 
			
		||||
import { Injectable, NgModule } from '@angular/core';
 | 
			
		||||
import { ActivatedRouteSnapshot, Resolve, RouterModule, Routes } from '@angular/router';
 | 
			
		||||
 | 
			
		||||
import {EntitiesTableComponent} from '../../components/entity/entities-table.component';
 | 
			
		||||
import {Authority} from '@shared/models/authority.enum';
 | 
			
		||||
import {RuleChainsTableConfigResolver} from '@modules/home/pages/rulechain/rulechains-table-config.resolver';
 | 
			
		||||
import { Dashboard } from '@shared/models/dashboard.models';
 | 
			
		||||
import { DashboardService } from '@core/http/dashboard.service';
 | 
			
		||||
import { DashboardUtilsService } from '@core/services/dashboard-utils.service';
 | 
			
		||||
import { Observable } from 'rxjs';
 | 
			
		||||
import { map } from 'rxjs/operators';
 | 
			
		||||
import { BreadCrumbConfig, BreadCrumbLabelFunction } from '@shared/components/breadcrumb';
 | 
			
		||||
import { RuleChain } from '@shared/models/rule-chain.models';
 | 
			
		||||
import { RuleChainService } from '@core/http/rule-chain.service';
 | 
			
		||||
import { DashboardPageComponent } from '@home/pages/dashboard/dashboard-page.component';
 | 
			
		||||
import { dashboardBreadcumbLabelFunction, DashboardResolver } from '@home/pages/dashboard/dashboard-routing.module';
 | 
			
		||||
import { RuleChainPageComponent } from '@home/pages/rulechain/rulechain-page.component';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
export class RuleChainResolver implements Resolve<RuleChain> {
 | 
			
		||||
 | 
			
		||||
  constructor(private ruleChainService: RuleChainService) {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  resolve(route: ActivatedRouteSnapshot): Observable<RuleChain> {
 | 
			
		||||
    const ruleChainId = route.params.ruleChainId;
 | 
			
		||||
    return this.ruleChainService.getRuleChain(ruleChainId);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const ruleChainBreadcumbLabelFunction: BreadCrumbLabelFunction = ((route, translate, component) => {
 | 
			
		||||
  let label: string = component.ruleChain.name;
 | 
			
		||||
  if (component.ruleChain.root) {
 | 
			
		||||
    label += ` (${translate.instant('rulechain.root')})`;
 | 
			
		||||
  }
 | 
			
		||||
  return label;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const routes: Routes = [
 | 
			
		||||
  {
 | 
			
		||||
@ -41,6 +73,22 @@ const routes: Routes = [
 | 
			
		||||
        resolve: {
 | 
			
		||||
          entitiesTableConfig: RuleChainsTableConfigResolver
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        path: ':ruleChainId',
 | 
			
		||||
        component: RuleChainPageComponent,
 | 
			
		||||
        data: {
 | 
			
		||||
          breadcrumb: {
 | 
			
		||||
            labelFunction: ruleChainBreadcumbLabelFunction,
 | 
			
		||||
            icon: 'settings_ethernet'
 | 
			
		||||
          } as BreadCrumbConfig,
 | 
			
		||||
          auth: [Authority.TENANT_ADMIN],
 | 
			
		||||
          title: 'rulechain.rulechain',
 | 
			
		||||
          widgetEditMode: false
 | 
			
		||||
        },
 | 
			
		||||
        resolve: {
 | 
			
		||||
          ruleChain: RuleChainResolver
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
@ -50,7 +98,8 @@ const routes: Routes = [
 | 
			
		||||
  imports: [RouterModule.forChild(routes)],
 | 
			
		||||
  exports: [RouterModule],
 | 
			
		||||
  providers: [
 | 
			
		||||
    RuleChainsTableConfigResolver
 | 
			
		||||
    RuleChainsTableConfigResolver,
 | 
			
		||||
    RuleChainResolver
 | 
			
		||||
  ]
 | 
			
		||||
})
 | 
			
		||||
export class RuleChainRoutingModule { }
 | 
			
		||||
 | 
			
		||||
@ -21,6 +21,7 @@ import {RuleChainComponent} from '@modules/home/pages/rulechain/rulechain.compon
 | 
			
		||||
import {RuleChainRoutingModule} from '@modules/home/pages/rulechain/rulechain-routing.module';
 | 
			
		||||
import {HomeComponentsModule} from '@modules/home/components/home-components.module';
 | 
			
		||||
import { RuleChainTabsComponent } from '@home/pages/rulechain/rulechain-tabs.component';
 | 
			
		||||
import { RuleChainPageComponent } from './rulechain-page.component';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
  entryComponents: [
 | 
			
		||||
@ -29,7 +30,8 @@ import { RuleChainTabsComponent } from '@home/pages/rulechain/rulechain-tabs.com
 | 
			
		||||
  ],
 | 
			
		||||
  declarations: [
 | 
			
		||||
    RuleChainComponent,
 | 
			
		||||
    RuleChainTabsComponent
 | 
			
		||||
    RuleChainTabsComponent,
 | 
			
		||||
    RuleChainPageComponent
 | 
			
		||||
  ],
 | 
			
		||||
  imports: [
 | 
			
		||||
    CommonModule,
 | 
			
		||||
 | 
			
		||||
@ -128,9 +128,7 @@ export class RuleChainsTableConfigResolver implements Resolve<EntityTableConfig<
 | 
			
		||||
    if ($event) {
 | 
			
		||||
      $event.stopPropagation();
 | 
			
		||||
    }
 | 
			
		||||
    // TODO:
 | 
			
		||||
    // this.router.navigateByUrl(`customers/${customer.id.id}/users`);
 | 
			
		||||
    this.dialogService.todo();
 | 
			
		||||
    this.router.navigateByUrl(`ruleChains/${ruleChain.id.id}`);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  exportRuleChain($event: Event, ruleChain: RuleChain) {
 | 
			
		||||
 | 
			
		||||
@ -21,6 +21,7 @@ import { LogoComponent } from './components/logo.component';
 | 
			
		||||
import { TbSnackBarComponent, ToastDirective } from './components/toast.directive';
 | 
			
		||||
import { BreadcrumbComponent } from '@app/shared/components/breadcrumb.component';
 | 
			
		||||
import { NgxFlowModule, FlowInjectionToken } from '@flowjs/ngx-flow';
 | 
			
		||||
import { NgxFlowchartModule } from 'ngx-flowchart/dist/ngx-flowchart';
 | 
			
		||||
import Flow from '@flowjs/flow.js';
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
@ -235,7 +236,8 @@ import { FileInputComponent } from './components/file-input.component';
 | 
			
		||||
    HotkeyModule,
 | 
			
		||||
    ColorPickerModule,
 | 
			
		||||
    NgxHmCarouselModule,
 | 
			
		||||
    NgxFlowModule
 | 
			
		||||
    NgxFlowModule,
 | 
			
		||||
    NgxFlowchartModule
 | 
			
		||||
  ],
 | 
			
		||||
  exports: [
 | 
			
		||||
    FooterComponent,
 | 
			
		||||
@ -317,6 +319,7 @@ import { FileInputComponent } from './components/file-input.component';
 | 
			
		||||
    HotkeyModule,
 | 
			
		||||
    ColorPickerModule,
 | 
			
		||||
    NgxHmCarouselModule,
 | 
			
		||||
    NgxFlowchartModule,
 | 
			
		||||
    ColorPickerDialogComponent,
 | 
			
		||||
    MaterialIconsDialogComponent,
 | 
			
		||||
    ColorInputComponent,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user