├── src ├── app │ ├── app.component.css │ ├── main-view │ │ ├── main-view.component.css │ │ ├── main-view.component.html │ │ └── main-view.component.ts │ ├── modules │ │ ├── share │ │ │ ├── general-list │ │ │ │ ├── general-list.component.html │ │ │ │ └── general-list.component.ts │ │ │ ├── index.ts │ │ │ ├── general-edit │ │ │ │ ├── general-edit.component.html │ │ │ │ └── general-edit.component.ts │ │ │ └── share.module.ts │ │ ├── dashboard │ │ │ ├── dashboard-view │ │ │ │ ├── dashboard-view-cell │ │ │ │ │ ├── dashboard-view-cell.component.css │ │ │ │ │ ├── dashboard-view-cell.component.html │ │ │ │ │ └── dashboard-view-cell.component.ts │ │ │ │ ├── dashboard-view-row │ │ │ │ │ ├── dashboard-view-row.component.html │ │ │ │ │ ├── dashboard-view-row.component.css │ │ │ │ │ └── dashboard-view-row.component.ts │ │ │ │ ├── dashboard-viewer │ │ │ │ │ ├── dashboard-viewer.component.html │ │ │ │ │ ├── dashboard-viewer.component.css │ │ │ │ │ └── dashboard-viewer.component.ts │ │ │ │ └── dashboard-view.module.ts │ │ │ ├── dashboard-share │ │ │ │ ├── base │ │ │ │ │ ├── widget-view-type.ts │ │ │ │ │ ├── dashboard-row.ts │ │ │ │ │ └── dashboard-cell.ts │ │ │ │ ├── dashboard-share.module.ts │ │ │ │ └── service │ │ │ │ │ ├── plugin.service.ts │ │ │ │ │ └── narik-dataSource.service.ts │ │ │ └── dashboard-design │ │ │ │ ├── dashboard-row │ │ │ │ ├── dashboard-row.component.css │ │ │ │ ├── dashboard-row.component.html │ │ │ │ └── dashboard-row.component.ts │ │ │ │ ├── dashboard-cell │ │ │ │ ├── dashboard-cell.component.css │ │ │ │ └── dashboard-cell.component.html │ │ │ │ ├── select-widget-type │ │ │ │ ├── select-widget-type.component.html │ │ │ │ └── select-widget-type.component.ts │ │ │ │ ├── dashboard-designer │ │ │ │ ├── dashboard-designer.component.html │ │ │ │ ├── dashboard-designer.component.css │ │ │ │ └── dashboard-designer.component.ts │ │ │ │ └── dashboard-design.module.ts │ │ └── narik-ngx-layout │ │ │ ├── index.ts │ │ │ ├── ngx-view-header │ │ │ ├── ngx-view-header.component.html │ │ │ ├── ngx-view-header.component.scss │ │ │ └── ngx-view-header.component.ts │ │ │ ├── ngx-main-view │ │ │ ├── ngx-main-view.component.html │ │ │ ├── ngx-main-view.component.scss │ │ │ └── ngx-main-view.component.ts │ │ │ └── narik-ngx-layout.module.ts │ ├── main │ │ ├── main.component.html │ │ └── main.component.ts │ ├── app.component.html │ ├── layouts │ │ ├── edit-layout.html │ │ ├── dashboard-design.layout.html │ │ ├── dashboard-view.layout.html │ │ └── list-layout.html │ ├── services │ │ └── command-processor.service.ts │ ├── app.component.ts │ ├── app.component.spec.ts │ ├── app-routing.module.ts │ └── app.module.ts ├── decl.d.ts ├── environments │ ├── environment.prod.ts │ └── environment.ts ├── favicon.ico ├── assets │ ├── images │ │ ├── logo.png │ │ └── user-avatar.png │ ├── app-config.json │ ├── i18n │ │ ├── fa │ │ │ ├── app.json │ │ │ ├── toolbar.json │ │ │ ├── main.json │ │ │ ├── material.json │ │ │ ├── narik.json │ │ │ └── dashboard.json │ │ └── en │ │ │ ├── app.json │ │ │ ├── toolbar.json │ │ │ ├── main.json │ │ │ ├── material.json │ │ │ ├── narik.json │ │ │ └── dashboard.json │ └── modules │ │ ├── base │ │ ├── data-info.json │ │ ├── ui-default-options.json │ │ └── tool-bars.json │ │ └── narik.json ├── styles │ ├── mat-custom-styles.scss │ ├── themes.scss │ ├── dashboard-designer.css │ ├── dashboard-viewer.css │ └── styles.scss ├── styles.scss ├── index.html ├── test.ts ├── main.ts └── polyfills.ts ├── plugins ├── chart │ ├── src │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── styles.css │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── main.ts │ │ └── app │ │ │ ├── app.module.ts │ │ │ ├── viewer │ │ │ ├── viewer.component.scss │ │ │ └── viewer.component.ts │ │ │ └── designer │ │ │ └── designer.component.ts │ ├── tsconfig.app.json │ ├── extra-webpack.config.js │ └── .browserslistrc ├── kpi │ ├── src │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── styles.css │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── app │ │ │ ├── designer │ │ │ │ ├── designer.component.ts │ │ │ │ └── designer.component.html │ │ │ ├── viewer │ │ │ │ ├── viewer.component.html │ │ │ │ └── viewer.component.ts │ │ │ ├── app.module.ts │ │ │ └── app.component.ts │ │ ├── main.ts │ │ └── polyfills.ts │ ├── tsconfig.app.json │ ├── extra-webpack.config.js │ └── .browserslistrc ├── link │ ├── src │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── styles.css │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── main.ts │ │ ├── app │ │ │ ├── viewer │ │ │ │ ├── viewer.component.ts │ │ │ │ └── viewer.component.html │ │ │ ├── designer │ │ │ │ ├── designer.component.ts │ │ │ │ └── designer.component.html │ │ │ ├── app.module.ts │ │ │ └── app.component.ts │ │ └── polyfills.ts │ ├── tsconfig.app.json │ ├── extra-webpack.config.js │ └── .browserslistrc ├── todo │ ├── src │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── app │ │ │ ├── app.component.css │ │ │ ├── app.component.html │ │ │ ├── viewer │ │ │ │ ├── viewer.component.css │ │ │ │ ├── viewer.component.html │ │ │ │ └── viewer.component.ts │ │ │ ├── app.component.ts │ │ │ ├── designer │ │ │ │ ├── designer.component.ts │ │ │ │ └── designer.component.html │ │ │ ├── app.component.spec.ts │ │ │ └── app.module.ts │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── styles.css │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── main.ts │ │ ├── test.ts │ │ └── polyfills.ts │ ├── tslint.json │ ├── e2e │ │ ├── src │ │ │ ├── app.po.ts │ │ │ └── app.e2e-spec.ts │ │ ├── tsconfig.json │ │ └── protractor.conf.js │ ├── tsconfig.app.json │ ├── tsconfig.spec.json │ ├── extra-webpack.config.js │ ├── .browserslistrc │ └── karma.conf.js ├── data-table │ ├── src │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── styles.css │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── app │ │ │ ├── designer │ │ │ │ ├── designer.component.ts │ │ │ │ └── designer.component.html │ │ │ ├── viewer │ │ │ │ ├── viewer.component.html │ │ │ │ └── viewer.component.ts │ │ │ ├── app.module.ts │ │ │ └── app.component.ts │ │ ├── main.ts │ │ └── polyfills.ts │ ├── tsconfig.app.json │ ├── extra-webpack.config.js │ └── .browserslistrc └── date-time │ ├── src │ ├── assets │ │ └── .gitkeep │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── styles.css │ ├── favicon.ico │ ├── index.html │ ├── app │ │ ├── viewer │ │ │ ├── viewer.component.html │ │ │ └── viewer.component.ts │ │ ├── designer │ │ │ ├── designer.component.ts │ │ │ └── designer.component.html │ │ ├── app.module.ts │ │ └── app.component.ts │ ├── main.ts │ └── polyfills.ts │ ├── tsconfig.app.json │ ├── extra-webpack.config.js │ └── .browserslistrc ├── projects └── dashboard-lib │ ├── src │ ├── lib │ │ ├── services │ │ │ ├── public-api.ts │ │ │ └── dataSource.service.ts │ │ └── base │ │ │ ├── public-api.ts │ │ │ ├── widget-model.ts │ │ │ ├── widget-design.ts │ │ │ └── widget-view.ts │ └── public-api.ts │ ├── ng-package.json │ ├── package.json │ ├── tsconfig.lib.prod.json │ ├── tslint.json │ ├── tsconfig.spec.json │ ├── tsconfig.lib.json │ ├── README.md │ └── karma.conf.js ├── proxy.config.json ├── e2e ├── tsconfig.json ├── src │ ├── app.po.ts │ └── app.e2e-spec.ts └── protractor.conf.js ├── tsconfig.app.json ├── tsconfig.spec.json ├── tsconfig.json ├── extra-webpack.config.js ├── .browserslistrc ├── .gitignore ├── README.md ├── LICENSE ├── karma.conf.js ├── tslint.json └── package.json /src/app/app.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /plugins/chart/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /plugins/kpi/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /plugins/link/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /plugins/todo/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /plugins/data-table/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /plugins/date-time/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /plugins/todo/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/main-view/main-view.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/decl.d.ts: -------------------------------------------------------------------------------- 1 | declare module "todo/Viewer"; 2 | -------------------------------------------------------------------------------- /plugins/todo/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 222222222222222222222222 2 | -------------------------------------------------------------------------------- /projects/dashboard-lib/src/lib/services/public-api.ts: -------------------------------------------------------------------------------- 1 | export * from "./dataSource.service"; 2 | -------------------------------------------------------------------------------- /src/app/modules/share/general-list/general-list.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-view/dashboard-view-cell/dashboard-view-cell.component.css: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NarikMe/narik-pluggable-dashboard-sample/HEAD/src/favicon.ico -------------------------------------------------------------------------------- /plugins/chart/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /plugins/chart/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /plugins/kpi/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /plugins/kpi/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /plugins/link/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /plugins/link/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /plugins/todo/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /plugins/todo/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /plugins/data-table/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /plugins/data-table/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /plugins/date-time/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /plugins/date-time/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /plugins/todo/src/app/viewer/viewer.component.css: -------------------------------------------------------------------------------- 1 | narik-checkbox.done { 2 | text-decoration: line-through; 3 | } 4 | -------------------------------------------------------------------------------- /src/app/main-view/main-view.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NarikMe/narik-pluggable-dashboard-sample/HEAD/src/assets/images/logo.png -------------------------------------------------------------------------------- /plugins/kpi/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NarikMe/narik-pluggable-dashboard-sample/HEAD/plugins/kpi/src/favicon.ico -------------------------------------------------------------------------------- /plugins/link/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NarikMe/narik-pluggable-dashboard-sample/HEAD/plugins/link/src/favicon.ico -------------------------------------------------------------------------------- /plugins/todo/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NarikMe/narik-pluggable-dashboard-sample/HEAD/plugins/todo/src/favicon.ico -------------------------------------------------------------------------------- /projects/dashboard-lib/src/public-api.ts: -------------------------------------------------------------------------------- 1 | export * from "./lib/base/public-api"; 2 | export * from "./lib/services/public-api"; 3 | -------------------------------------------------------------------------------- /plugins/chart/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NarikMe/narik-pluggable-dashboard-sample/HEAD/plugins/chart/src/favicon.ico -------------------------------------------------------------------------------- /plugins/date-time/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NarikMe/narik-pluggable-dashboard-sample/HEAD/plugins/date-time/src/favicon.ico -------------------------------------------------------------------------------- /src/assets/images/user-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NarikMe/narik-pluggable-dashboard-sample/HEAD/src/assets/images/user-avatar.png -------------------------------------------------------------------------------- /plugins/data-table/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NarikMe/narik-pluggable-dashboard-sample/HEAD/plugins/data-table/src/favicon.ico -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-share/base/widget-view-type.ts: -------------------------------------------------------------------------------- 1 | export enum WidgetViewType { 2 | View, 3 | Design, 4 | Preview 5 | } 6 | -------------------------------------------------------------------------------- /projects/dashboard-lib/src/lib/base/public-api.ts: -------------------------------------------------------------------------------- 1 | export * from './widget-design'; 2 | export * from './widget-view'; 3 | export * from './widget-model'; 4 | -------------------------------------------------------------------------------- /src/app/main/main.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /projects/dashboard-lib/src/lib/base/widget-model.ts: -------------------------------------------------------------------------------- 1 | export interface WidgetModel { 2 | title?: string; 3 | uniqueId?: string; 4 | widgetType?: string; 5 | } 6 | -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 |
7 |
8 | 9 | -------------------------------------------------------------------------------- /src/assets/app-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "modulesMetaDataRoot": "assets/modules", 3 | "dynamicResourcesPath": "assets", 4 | "translationsPath": "assets/i18n", 5 | "entityKeyField": "viewModelId" 6 | } 7 | -------------------------------------------------------------------------------- /projects/dashboard-lib/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/dashboard-lib", 4 | "lib": { 5 | "entryFile": "src/public-api.ts" 6 | } 7 | } -------------------------------------------------------------------------------- /proxy.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "/api": { 3 | "target": "http://185.2.100.176:1166", 4 | "secure": false 5 | }, 6 | "/odata": { 7 | "target": "http://185.2.100.176:1166", 8 | "secure": false 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/assets/i18n/fa/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "appplication-title": "ناریک", 3 | "search": "جستجو", 4 | "management": "مدیریت", 5 | "menu": "منو", 6 | "login": { 7 | "change_Pass": "تغییر کلمه عبور", 8 | "logout": "خروج" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/assets/i18n/en/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "appplication-title": "Narik", 3 | "search": "Search", 4 | "management": "Management", 5 | "menu": "Menu", 6 | "login": { 7 | "change_Pass": "Change Password", 8 | "logout": "Logout" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /projects/dashboard-lib/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dashboard-lib", 3 | "version": "0.0.1", 4 | "peerDependencies": { 5 | "@angular/common": "^11.0.1", 6 | "@angular/core": "^11.0.1" 7 | }, 8 | "dependencies": { 9 | "tslib": "^2.0.0" 10 | } 11 | } -------------------------------------------------------------------------------- /e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /plugins/todo/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.css'] 7 | }) 8 | export class AppComponent { 9 | title = 'todo'; 10 | } 11 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "types": [] 6 | }, 7 | "include": [ 8 | "src/**/*.ts" 9 | ], 10 | "exclude": [ 11 | "src/test.ts", 12 | "src/**/*.spec.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-view/dashboard-view-row/dashboard-view-row.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 |
6 |
7 | -------------------------------------------------------------------------------- /e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText() { 9 | return element(by.css('app-root h1')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /projects/dashboard-lib/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.lib.json", 4 | "compilerOptions": { 5 | "declarationMap": false 6 | }, 7 | "angularCompilerOptions": { 8 | "enableIvy": false 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/assets/i18n/en/toolbar.json: -------------------------------------------------------------------------------- 1 | { 2 | "new_command_tooltip": "New", 3 | "edit_command_tooltip": "Edit", 4 | "save_command_tooltip": "Save", 5 | "delete_command_tooltip": "Delete", 6 | "close_command_tooltip": "Close", 7 | "refresh_command_tooltip": "Refresh", 8 | "list_command_tooltip":"List" 9 | } 10 | -------------------------------------------------------------------------------- /src/assets/i18n/fa/toolbar.json: -------------------------------------------------------------------------------- 1 | { 2 | "new_command_tooltip": "جدید", 3 | "edit_command_tooltip": "ویرایش", 4 | "save_command_tooltip": "ذخیره", 5 | "delete_command_tooltip": "حذف", 6 | "close_command_tooltip": "بستن", 7 | "refresh_command_tooltip": "بروز رسانی", 8 | "list_command_tooltip": "لیست" 9 | } 10 | -------------------------------------------------------------------------------- /src/assets/i18n/fa/main.json: -------------------------------------------------------------------------------- 1 | { 2 | "branch": "شعیه", 3 | "address": "آدرس", 4 | "city": "شهر", 5 | "name": "نام", 6 | "state": "استان", 7 | "zipCode": "کد پستی", 8 | "isActive": "فعال", 9 | "linkTitle": "عنوان لینک", 10 | "link": "لینک", 11 | "add": "اضافه", 12 | "list": "فهرست", 13 | "new":"جدید" 14 | } 15 | -------------------------------------------------------------------------------- /src/app/modules/share/index.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from "@angular/core"; 2 | import { GeneralEditComponent } from "./general-edit/general-edit.component"; 3 | import { GeneralListComponent } from "./general-list/general-list.component"; 4 | 5 | export const COMPONENTS: Provider[] = [ 6 | GeneralEditComponent, 7 | GeneralListComponent 8 | ]; 9 | -------------------------------------------------------------------------------- /src/assets/i18n/en/main.json: -------------------------------------------------------------------------------- 1 | { 2 | "branch": "Branch", 3 | "address": "Address", 4 | "city": "City", 5 | "name": "Name", 6 | "state": "State", 7 | "zipCode": "ZipCode", 8 | "isActive": "Is Active", 9 | "linkTitle": "Link Title", 10 | "link": "Link", 11 | "add": "Add", 12 | "list": "List", 13 | "new":"New" 14 | } 15 | -------------------------------------------------------------------------------- /plugins/todo/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "app", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "app", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /plugins/todo/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | async navigateTo(): Promise { 5 | return browser.get(browser.baseUrl); 6 | } 7 | 8 | async getTitleText(): Promise { 9 | return element(by.css('app-root .content span')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /projects/dashboard-lib/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "lib", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "lib", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/app/modules/narik-ngx-layout/index.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from "@angular/core"; 2 | import { NgxHeaderComponent } from "./ngx-view-header/ngx-view-header.component"; 3 | import { NgxMainViewComponent } from "./ngx-main-view/ngx-main-view.component"; 4 | 5 | export const COMPONENTS: Provider[] = [ 6 | NgxHeaderComponent, 7 | NgxMainViewComponent 8 | ]; 9 | -------------------------------------------------------------------------------- /src/app/layouts/edit-layout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 |
8 |
9 |
10 | -------------------------------------------------------------------------------- /plugins/kpi/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Kpi 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /plugins/link/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Link 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /plugins/todo/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "../../../tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "../../../out-tsc/e2e", 6 | "module": "commonjs", 7 | "target": "es2018", 8 | "types": [ 9 | "jasmine", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /plugins/todo/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Todo 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/assets/i18n/fa/material.json: -------------------------------------------------------------------------------- 1 | { 2 | "ITEMS_PER_PAGE_LABEL": "رکورد در هر صفحه:", 3 | "NEXT_PAGE_LABEL": "صفحه بعد", 4 | "PREVIOUS_PAGE_LABEL": "صفحه قبل", 5 | "FIRST_PAGE_LABEL": "صفحه اول", 6 | "LAST_PAGE_LABEL": "صفحه آخر", 7 | "RANGE_PAGE_LABEL_1": "0 از {{length}}", 8 | "RANGE_PAGE_LABEL_2": "{{startIndex}} - {{endIndex}} از {{length}}" 9 | } 10 | -------------------------------------------------------------------------------- /tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /plugins/chart/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Chart 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-design/dashboard-row/dashboard-row.component.css: -------------------------------------------------------------------------------- 1 | :host { 2 | width: 100%; 3 | } 4 | 5 | .row-container { 6 | position: relative; 7 | min-height: 100px; 8 | } 9 | 10 | 11 | 12 | .row-content { 13 | min-height: 100px; 14 | margin-top: 20px; 15 | } 16 | 17 | .row-menu { 18 | cursor: pointer; 19 | margin-top: 5px; 20 | } 21 | -------------------------------------------------------------------------------- /plugins/date-time/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DateTime 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/app/services/command-processor.service.ts: -------------------------------------------------------------------------------- 1 | import { 2 | CommandProcessor, 3 | CommandHost, 4 | CommandInfo 5 | } from "@narik/infrastructure"; 6 | import { Injectable } from "@angular/core"; 7 | @Injectable() 8 | export class DemoCommandProcessor implements CommandProcessor { 9 | constructor() {} 10 | processCommand(sender: CommandHost, cmd: CommandInfo) {} 11 | } 12 | -------------------------------------------------------------------------------- /src/assets/i18n/en/material.json: -------------------------------------------------------------------------------- 1 | { 2 | "ITEMS_PER_PAGE_LABEL": "Items per page:", 3 | "NEXT_PAGE_LABEL": "Next Page", 4 | "PREVIOUS_PAGE_LABEL": "Previous page", 5 | "FIRST_PAGE_LABEL": "First Page", 6 | "LAST_PAGE_LABEL": "Last Page", 7 | "RANGE_PAGE_LABEL_1": "0 of {{length}}", 8 | "RANGE_PAGE_LABEL_2": "{{startIndex}} - {{endIndex}} from {{length}}" 9 | } 10 | -------------------------------------------------------------------------------- /plugins/data-table/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DataTable 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /plugins/kpi/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "../../tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "../../out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts", 10 | "src/polyfills.ts" 11 | ], 12 | "include": [ 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /plugins/link/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "../../tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "../../out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts", 10 | "src/polyfills.ts" 11 | ], 12 | "include": [ 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /plugins/todo/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "../../tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "../../out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts", 10 | "src/polyfills.ts" 11 | ], 12 | "include": [ 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /plugins/data-table/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "../../tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "../../out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts", 10 | "src/polyfills.ts" 11 | ], 12 | "include": [ 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /plugins/date-time/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "../../tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "../../out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts", 10 | "src/polyfills.ts" 11 | ], 12 | "include": [ 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /plugins/date-time/src/app/viewer/viewer.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ model.title }} 4 | 5 | 6 | 7 |
8 |

9 | {{ today | dfnsFormat: model.format || 'dddd Do MMM yyyy HH:mm:ss' }} 10 |

11 |
12 |
13 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-view/dashboard-view-row/dashboard-view-row.component.css: -------------------------------------------------------------------------------- 1 | :host { 2 | width: 100%; 3 | } 4 | 5 | .row-container { 6 | position: relative; 7 | } 8 | 9 | .row-toolbar { 10 | position: absolute; 11 | top: -5px; 12 | left: 6px; 13 | display: flex; 14 | } 15 | 16 | .row-content {} 17 | 18 | .row-menu { 19 | cursor: pointer; 20 | margin-top: 5px; 21 | } 22 | -------------------------------------------------------------------------------- /plugins/kpi/src/app/designer/designer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Injector } from '@angular/core'; 2 | import { WidgetDesign } from 'dashboard-lib'; 3 | 4 | @Component({ 5 | templateUrl: './designer.component.html', 6 | }) 7 | export class KpiDesignComponent extends WidgetDesign { 8 | needDataSource = true; 9 | 10 | constructor(injector: Injector) { 11 | super(injector); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /plugins/todo/src/app/designer/designer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Injector } from '@angular/core'; 2 | import { WidgetDesign } from 'dashboard-lib'; 3 | 4 | @Component({ 5 | templateUrl: './designer.component.html', 6 | }) 7 | export class TodoDesignComponent extends WidgetDesign { 8 | needDataSource = true; 9 | 10 | constructor(injector: Injector) { 11 | super(injector); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /plugins/data-table/src/app/designer/designer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Injector } from '@angular/core'; 2 | import { WidgetDesign } from 'dashboard-lib'; 3 | 4 | @Component({ 5 | templateUrl: './designer.component.html', 6 | }) 7 | export class DataTableDesignComponent extends WidgetDesign { 8 | needDataSource = true; 9 | 10 | constructor(injector: Injector) { 11 | super(injector); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /plugins/date-time/src/app/designer/designer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Injector } from '@angular/core'; 2 | import { WidgetDesign } from 'dashboard-lib'; 3 | 4 | @Component({ 5 | templateUrl: './designer.component.html', 6 | }) 7 | export class DateTimeDesignComponent extends WidgetDesign { 8 | displayTitle = false; 9 | 10 | constructor(injector: Injector) { 11 | super(injector); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-share/base/dashboard-row.ts: -------------------------------------------------------------------------------- 1 | import { DashboardCell } from './dashboard-cell'; 2 | 3 | export class DashboardRow { 4 | constructor(columsCount?: number) { 5 | columsCount = columsCount || 1; 6 | for (let index = 0; index < columsCount; index++) { 7 | this.cells.push(new DashboardCell(12 / columsCount)); 8 | } 9 | } 10 | cells: DashboardCell[] = []; 11 | } 12 | -------------------------------------------------------------------------------- /projects/dashboard-lib/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "../../tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "../../out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts" 12 | ], 13 | "include": [ 14 | "**/*.spec.ts", 15 | "**/*.d.ts" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /plugins/chart/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "../../tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "../../out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts", 10 | "src/app/viewer/viewer.component.ts", 11 | "src/app/designer/designer.component.ts" 12 | ], 13 | "include": ["src/**/*.d.ts"] 14 | } 15 | -------------------------------------------------------------------------------- /src/styles/mat-custom-styles.scss: -------------------------------------------------------------------------------- 1 | @import '~@angular/material/theming'; 2 | 3 | 4 | $custom-typography: mat-typography-config($font-family: 'Roboto,"Helvetica Neue",sans-serif'); 5 | @include mat-core($custom-typography); 6 | 7 | $custom-primary: mat-palette($mat-blue); 8 | $custom-accent: mat-palette($mat-red); 9 | $custom-theme: mat-light-theme($custom-primary, $custom-accent); 10 | @include angular-material-theme($custom-theme); 11 | -------------------------------------------------------------------------------- /plugins/kpi/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /plugins/link/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /plugins/data-table/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /plugins/date-time/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /plugins/todo/src/app/designer/designer.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{"dashboard.titles.todo" | translate}} 4 | 5 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /plugins/todo/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "../../tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "../../out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-design/dashboard-cell/dashboard-cell.component.css: -------------------------------------------------------------------------------- 1 | .cell-container { 2 | position: relative; 3 | min-height: 100px; 4 | } 5 | 6 | 7 | .config-container { 8 | display: flex; 9 | height: 60px; 10 | } 11 | 12 | .config-button { 13 | margin: auto; 14 | } 15 | 16 | .cell-menu { 17 | cursor: pointer; 18 | margin-top: auto; 19 | 20 | } 21 | 22 | .cell-toolbar:hover { 23 | opacity: 1; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | @import '~bootstrap/dist/css/bootstrap.css'; 3 | @import '~@fortawesome/fontawesome-free/css/all.min.css'; 4 | @import '~ngx-toastr/toastr.css'; 5 | @import './styles/styles.scss'; 6 | @import '~roboto-fontface/css/roboto/roboto-fontface.css'; 7 | @import '~typeface-exo/index.css'; 8 | @import '~@narik/ui-material/styles/narik-ui-material.css'; 9 | 10 | -------------------------------------------------------------------------------- /plugins/todo/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | 8 | if (environment.production) { 9 | enableProdMode(); 10 | } 11 | 12 | platformBrowserDynamic() 13 | .bootstrapModule(AppModule) 14 | .catch((err) => console.error(err)); 15 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-share/base/dashboard-cell.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFactory, Type } from '@angular/core'; 2 | 3 | export class DashboardCell { 4 | static colClasses = ['col-md-']; 5 | 6 | size: number; 7 | constructor(size?: number) { 8 | this.size = size || 12; 9 | } 10 | 11 | widgetInfo?: { 12 | widgetTypeKey?: string; 13 | widgetType?: Type | ComponentFactory; 14 | widgetModel?: any; 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /plugins/chart/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | // import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | // import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | // platformBrowserDynamic() 12 | // .bootstrapModule(AppModule) 13 | // .catch((err) => console.error(err)); 14 | -------------------------------------------------------------------------------- /plugins/link/src/app/viewer/viewer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Injector } from '@angular/core'; 2 | import { WidgetView } from 'dashboard-lib'; 3 | 4 | @Component({ 5 | templateUrl: './viewer.component.html', 6 | styles: [ 7 | ` 8 | a { 9 | color: #1a2138; 10 | } 11 | `, 12 | ], 13 | }) 14 | export class LinkViewComponent extends WidgetView { 15 | constructor(injector: Injector) { 16 | super(injector); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /plugins/kpi/src/app/designer/designer.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ 'dashboard.titles.kpi' | translate }} 4 | 5 | 6 | 7 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Narik Pluggable Dashboard 6 | 7 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/app/main/main.component.ts: -------------------------------------------------------------------------------- 1 | import { MetaDataService, MODULE_UI_KEY } from "@narik/infrastructure"; 2 | 3 | import { Component, Inject } from "@angular/core"; 4 | 5 | @Component({ 6 | templateUrl: "main.component.html" 7 | }) 8 | export class MainComponent { 9 | menuItems: any[]; 10 | 11 | /** 12 | * 13 | */ 14 | constructor( 15 | metaDataService: MetaDataService, 16 | @Inject(MODULE_UI_KEY) moduleKey: string 17 | ) { 18 | this.menuItems = metaDataService.getValue(moduleKey, "menuItems"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /projects/dashboard-lib/src/lib/services/dataSource.service.ts: -------------------------------------------------------------------------------- 1 | import { Observable } from 'rxjs/internal/Observable'; 2 | 3 | export interface DashboardDataSource { 4 | key: string; 5 | metaData: any; 6 | data: any; 7 | } 8 | 9 | export abstract class DataSourceService { 10 | abstract init(); 11 | abstract dataSourceList(): Observable; 12 | abstract dataSourceMetadata(dataSourceKey: string): Observable; 13 | abstract dataSourceData( 14 | dataSourceKey: string, 15 | parameters?: any[] 16 | ): Observable; 17 | } 18 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-design/select-widget-type/select-widget-type.component.html: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | -------------------------------------------------------------------------------- /plugins/kpi/extra-webpack.config.js: -------------------------------------------------------------------------------- 1 | const WebpackConfigHelper = require('./../../build-tools/webpack-config.helper'); 2 | 3 | module.exports = (config) => { 4 | WebpackConfigHelper.applyLayoutConfig(config, '/../../'); 5 | WebpackConfigHelper.applyFederationConfig(config, { 6 | uniqueName: 'kpi', 7 | filename: 'remoteEntry.js', 8 | exposes: { 9 | './Viewer': './plugins/kpi/src/app/viewer/viewer.component.ts', 10 | './Designer': './plugins/kpi/src/app/designer/designer.component.ts', 11 | }, 12 | }); 13 | return config; 14 | }; 15 | -------------------------------------------------------------------------------- /plugins/link/extra-webpack.config.js: -------------------------------------------------------------------------------- 1 | const WebpackConfigHelper = require('./../../build-tools/webpack-config.helper'); 2 | 3 | module.exports = (config) => { 4 | WebpackConfigHelper.applyLayoutConfig(config, '/../../'); 5 | WebpackConfigHelper.applyFederationConfig(config, { 6 | uniqueName: 'link', 7 | filename: 'remoteEntry.js', 8 | exposes: { 9 | './Viewer': './plugins/link/src/app/viewer/viewer.component.ts', 10 | './Designer': './plugins/link/src/app/designer/designer.component.ts', 11 | }, 12 | }); 13 | return config; 14 | }; 15 | -------------------------------------------------------------------------------- /plugins/todo/extra-webpack.config.js: -------------------------------------------------------------------------------- 1 | const WebpackConfigHelper = require('./../../build-tools/webpack-config.helper'); 2 | 3 | module.exports = (config) => { 4 | WebpackConfigHelper.applyLayoutConfig(config, '/../../'); 5 | WebpackConfigHelper.applyFederationConfig(config, { 6 | uniqueName: 'todo', 7 | filename: 'remoteEntry.js', 8 | exposes: { 9 | './Viewer': './plugins/todo/src/app/viewer/viewer.component.ts', 10 | './Designer': './plugins/todo/src/app/designer/designer.component.ts', 11 | }, 12 | }); 13 | return config; 14 | }; 15 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-view/dashboard-view-cell/dashboard-view-cell.component.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-view/dashboard-view-row/dashboard-view-row.component.ts: -------------------------------------------------------------------------------- 1 | import { DashboardRow } from "./../../dashboard-share/base/dashboard-row"; 2 | 3 | import { Component, Input, OnInit } from "@angular/core"; 4 | 5 | @Component({ 6 | selector: "dashboard-view-row", 7 | templateUrl: "dashboard-view-row.component.html", 8 | styleUrls: ["dashboard-view-row.component.css"] 9 | }) 10 | export class DashboardViewRowComponent implements OnInit { 11 | @Input() 12 | row: DashboardRow = new DashboardRow(); 13 | 14 | ngOnInit() {} 15 | } 16 | -------------------------------------------------------------------------------- /plugins/chart/extra-webpack.config.js: -------------------------------------------------------------------------------- 1 | const WebpackConfigHelper = require('./../../build-tools/webpack-config.helper'); 2 | 3 | module.exports = (config) => { 4 | WebpackConfigHelper.applyLayoutConfig(config, '/../../'); 5 | WebpackConfigHelper.applyFederationConfig(config, { 6 | uniqueName: 'chart', 7 | filename: 'remoteEntry.js', 8 | exposes: { 9 | './Viewer': './plugins/chart/src/app/viewer/viewer.component.ts', 10 | './Designer': './plugins/chart/src/app/designer/designer.component.ts', 11 | }, 12 | }); 13 | return config; 14 | }; 15 | -------------------------------------------------------------------------------- /src/app/main-view/main-view.component.ts: -------------------------------------------------------------------------------- 1 | import { HttpClient } from '@angular/common/http'; 2 | import { Component, OnInit } from '@angular/core'; 3 | 4 | @Component({ 5 | templateUrl: 'main-view.component.html', 6 | styleUrls: ['main-view.component.css'], 7 | }) 8 | export class MainViewComponent implements OnInit { 9 | rows: any[] = []; 10 | 11 | constructor(private httpClient: HttpClient) {} 12 | ngOnInit(): void { 13 | this.httpClient.get(`assets/samples/1.json`).subscribe((result: any) => { 14 | this.rows = result.rows; 15 | }); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /plugins/data-table/extra-webpack.config.js: -------------------------------------------------------------------------------- 1 | const WebpackConfigHelper = require('./../../build-tools/webpack-config.helper'); 2 | 3 | module.exports = (config) => { 4 | WebpackConfigHelper.applyLayoutConfig(config, '/../../'); 5 | WebpackConfigHelper.applyFederationConfig(config, { 6 | uniqueName: 'dataTable', 7 | filename: 'remoteEntry.js', 8 | exposes: { 9 | './Viewer': './plugins/data-table/src/app/viewer/viewer.component.ts', 10 | './Designer': './plugins/data-table/src/app/designer/designer.component.ts', 11 | }, 12 | }); 13 | return config; 14 | }; 15 | -------------------------------------------------------------------------------- /src/app/layouts/dashboard-design.layout.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | widget Title 4 |
5 | 12 | 13 | 14 |
15 | 16 | 21 | 22 |
23 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-view/dashboard-viewer/dashboard-viewer.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |
5 | 6 |
7 |
8 |
9 | 10 | -------------------------------------------------------------------------------- /plugins/date-time/extra-webpack.config.js: -------------------------------------------------------------------------------- 1 | const WebpackConfigHelper = require('./../../build-tools/webpack-config.helper'); 2 | 3 | module.exports = (config) => { 4 | WebpackConfigHelper.applyLayoutConfig(config, '/../../'); 5 | WebpackConfigHelper.applyFederationConfig(config, { 6 | uniqueName: 'dateTime', 7 | filename: 'remoteEntry.js', 8 | exposes: { 9 | './Viewer': './plugins/date-time/src/app/viewer/viewer.component.ts', 10 | './Designer': 11 | './plugins/date-time/src/app/designer/designer.component.ts', 12 | }, 13 | }); 14 | return config; 15 | }; 16 | -------------------------------------------------------------------------------- /src/app/layouts/dashboard-view.layout.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | {{isFullScreen ? "fullscreen_exit":"fullscreen"}} 5 | 6 |
7 |
8 |
9 | widget Title 10 |
11 |
12 |
13 |
14 | -------------------------------------------------------------------------------- /plugins/date-time/src/app/designer/designer.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ 'dashboard.titles.datetime' | translate }} 4 | 5 | 6 | 7 | 13 | help 14 | 15 | 16 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { Router, NavigationStart, NavigationEnd } from '@angular/router'; 3 | 4 | @Component({ 5 | selector: 'app-root', 6 | templateUrl: './app.component.html', 7 | }) 8 | export class AppComponent { 9 | isOnNavigation = false; 10 | constructor(router: Router) { 11 | router.events.subscribe((event: any) => { 12 | if (event instanceof NavigationStart) { 13 | this.isOnNavigation = true; 14 | } else if (event instanceof NavigationEnd) { 15 | this.isOnNavigation = false; 16 | } 17 | }); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "module": "esnext", 9 | "moduleResolution": "node", 10 | "emitDecoratorMetadata": true, 11 | "experimentalDecorators": true, 12 | "importHelpers": true, 13 | "skipLibCheck": true, 14 | "target": "es2015", 15 | "typeRoots": ["node_modules/@types"], 16 | "lib": ["es2018", "dom"], 17 | "paths": { 18 | "dashboard-lib": ["projects/dashboard-lib/src/public-api.ts"] 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /plugins/data-table/src/app/viewer/viewer.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ model.title }} 4 | 5 | 6 | 7 |
15 | 21 | 22 |
23 |
24 | -------------------------------------------------------------------------------- /src/styles/themes.scss: -------------------------------------------------------------------------------- 1 | @import "~@nebular/theme/styles/theming"; 2 | @import "~@nebular/theme/styles/themes"; 3 | @import "~@nebular/theme/styles/globals"; 4 | 5 | $nb-themes: nb-register-theme( 6 | ( 7 | // app wise variables for each theme 8 | sidebar-header-gap: 2rem, 9 | sidebar-header-height: initial, 10 | layout-content-width: 1400px, 11 | header-height: 5.45rem, 12 | font-family-primary: Roboto, 13 | font-family-secondary: Exo, 14 | card-height-tiny: 13.5rem 15 | ), 16 | default, 17 | default 18 | ); 19 | 20 | @include nb-install() { 21 | @include nb-theme-global(); 22 | } 23 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-design/dashboard-row/dashboard-row.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 5 |
6 |
7 | more_horiz 8 | 9 | 10 |
11 | 12 |
13 | -------------------------------------------------------------------------------- /src/app/modules/share/general-edit/general-edit.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 14 | 15 | -------------------------------------------------------------------------------- /src/styles/dashboard-designer.css: -------------------------------------------------------------------------------- 1 | .dashboard-body .narik-mat-toolbar{ 2 | border-bottom: 0px !important; 3 | background-color: transparent !important; 4 | opacity: 0.8; 5 | } 6 | 7 | .cell-toolbar { 8 | position: absolute; 9 | bottom: 5px; 10 | left: 5px; 11 | display: flex; 12 | opacity: 0.5; 13 | } 14 | 15 | 16 | 17 | [dir='rtl'] .cell-toolbar { 18 | left: initial !important; 19 | right: 5px; 20 | } 21 | 22 | .row-toolbar { 23 | position: absolute; 24 | top: -5px; 25 | left: 6px; 26 | display: flex; 27 | } 28 | 29 | [dir='rtl'] .row-toolbar { 30 | left: initial !important; 31 | right: 6px; 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /extra-webpack.config.js: -------------------------------------------------------------------------------- 1 | const WebpackConfigHelper = require('./build-tools/webpack-config.helper'); 2 | 3 | const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); 4 | const mf = require('@angular-architects/module-federation/webpack'); 5 | const path = require('path'); 6 | 7 | const sharedMappings = new mf.SharedMappings(); 8 | sharedMappings.register(path.join(__dirname, 'tsconfig.json'), [ 9 | 'dashboard-lib', 10 | ]); 11 | 12 | module.exports = (config) => { 13 | WebpackConfigHelper.applyLayoutConfig(config); 14 | WebpackConfigHelper.applyFederationConfig(config, { 15 | isHost: true, 16 | }); 17 | return config; 18 | }; 19 | -------------------------------------------------------------------------------- /src/app/layouts/list-layout.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 9 | 10 |
11 |
12 | -------------------------------------------------------------------------------- /projects/dashboard-lib/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "../../tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "../../out-tsc/lib", 6 | "target": "es2015", 7 | "declaration": true, 8 | "declarationMap": true, 9 | "inlineSources": true, 10 | "types": [], 11 | "lib": [ 12 | "dom", 13 | "es2018" 14 | ] 15 | }, 16 | "angularCompilerOptions": { 17 | "skipTemplateCodegen": true, 18 | "strictMetadataEmit": true, 19 | "enableResourceInlining": true 20 | }, 21 | "exclude": [ 22 | "src/test.ts", 23 | "**/*.spec.ts" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /src/app/modules/share/general-edit/general-edit.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, forwardRef, Injector } from '@angular/core'; 2 | 3 | import { DynamicComponent } from '@narik/core'; 4 | import { HOST_TOKEN } from '@narik/infrastructure'; 5 | import { NarikUiEditForm } from '@narik/ui-material'; 6 | 7 | @DynamicComponent('GeneralEditComponent') 8 | @Component({ 9 | templateUrl: 'general-edit.component.html', 10 | providers: [ 11 | { 12 | provide: HOST_TOKEN, 13 | useExisting: forwardRef(() => GeneralEditComponent), 14 | }, 15 | ], 16 | }) 17 | export class GeneralEditComponent extends NarikUiEditForm { 18 | constructor(injector: Injector) { 19 | super(injector); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/app/modules/share/general-list/general-list.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, forwardRef, Injector } from '@angular/core'; 2 | 3 | import { DynamicComponent } from '@narik/core'; 4 | import { HOST_TOKEN } from '@narik/infrastructure'; 5 | import { NarikUiListForm } from '@narik/ui-material'; 6 | 7 | @DynamicComponent('GeneralListComponent') 8 | @Component({ 9 | templateUrl: 'general-list.component.html', 10 | providers: [ 11 | { 12 | provide: HOST_TOKEN, 13 | useExisting: forwardRef(() => GeneralListComponent), 14 | }, 15 | ], 16 | }) 17 | export class GeneralListComponent extends NarikUiListForm { 18 | constructor(injector: Injector) { 19 | super(injector); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | import { browser, logging } from 'protractor'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should display welcome message', () => { 12 | page.navigateTo(); 13 | expect(page.getTitleText()).toEqual('Welcome to narik-dashboard!'); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER); 19 | expect(logs).not.toContain(jasmine.objectContaining({ 20 | level: logging.Level.SEVERE, 21 | } as logging.Entry)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /plugins/chart/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /plugins/kpi/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /plugins/link/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /plugins/todo/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /plugins/data-table/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /plugins/date-time/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /src/app/modules/narik-ngx-layout/ngx-view-header/ngx-view-header.component.html: -------------------------------------------------------------------------------- 1 |
2 | 8 | 9 |
10 | 11 | 12 |
13 | FA/EN 14 | 15 | 16 | 18 | 19 | 20 |
21 | -------------------------------------------------------------------------------- /src/assets/i18n/en/narik.json: -------------------------------------------------------------------------------- 1 | { 2 | "errors": { 3 | "invalid_form": "Please Fill Form", 4 | "required": "{0} Is Required", 5 | "STATUS_401": "Its Not Accessable By Your Role", 6 | "password_mismatch": "Your password dont mismatch", 7 | "invalid_password": "Invalid password" 8 | }, 9 | "info": { 10 | "submit-succeed": "The information was saved", 11 | "delete-confirm": "Are you sure you want to delete?", 12 | "confirm": "Confirm" 13 | }, 14 | "INVALID_LOGIN": "Invalid username or password", 15 | "dialog-buttons": { 16 | "ok": "Ok", 17 | "cancel": "Cancel", 18 | "yes": "Yes", 19 | "no": "No" 20 | }, 21 | "clear": "Clear", 22 | "refresh": "Refresh", 23 | "table": { 24 | "actions": "Action" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. 18 | -------------------------------------------------------------------------------- /plugins/todo/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | import { browser, logging } from 'protractor'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should display welcome message', async () => { 12 | await page.navigateTo(); 13 | expect(await page.getTitleText()).toEqual('todo app is running!'); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER); 19 | expect(logs).not.toContain(jasmine.objectContaining({ 20 | level: logging.Level.SEVERE, 21 | } as logging.Entry)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /src/app/modules/narik-ngx-layout/ngx-main-view/ngx-main-view.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {{title}} 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /plugins/chart/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. 18 | -------------------------------------------------------------------------------- /plugins/kpi/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. 18 | -------------------------------------------------------------------------------- /plugins/link/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. 18 | -------------------------------------------------------------------------------- /plugins/todo/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. 18 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-design/dashboard-designer/dashboard-designer.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |
5 | 7 | 8 |
9 |
10 |
11 | 12 | -------------------------------------------------------------------------------- /src/assets/i18n/fa/narik.json: -------------------------------------------------------------------------------- 1 | { 2 | "errors": { 3 | "invalid_form": "Please Fill Form", 4 | "required": "{0} Is Required", 5 | "STATUS_401": "Its Not Accessable By Your Role", 6 | "password_mismatch": "Your password dont mismatch", 7 | "invalid_password": "Invalid password" 8 | }, 9 | "info": { 10 | "submit-succeed": "اطاعات با موفقیت ذخیره شد", 11 | "delete-confirm": "آیا مطمئن به انجام عملیات حذف می باشید?", 12 | "confirm": "تاییدیه" 13 | }, 14 | "INVALID_LOGIN": "Invalid username or password", 15 | "dialog-buttons": { 16 | "ok": "تایید", 17 | "cancel": "انصراف", 18 | "yes": "بله", 19 | "no": "خیر" 20 | }, 21 | "clear": "پاک کردن", 22 | "refresh": "بروز رسانی", 23 | "table": { 24 | "actions": "عملیات" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /plugins/data-table/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. 18 | -------------------------------------------------------------------------------- /plugins/date-time/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. 18 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-share/dashboard-share.module.ts: -------------------------------------------------------------------------------- 1 | import { HttpClientModule } from '@angular/common/http'; 2 | import { NgModule } from '@angular/core'; 3 | 4 | import { PluginService } from './service/plugin.service'; 5 | import { NarikPluginService } from './service/narik-plugin.service'; 6 | import { DataSourceService } from 'dashboard-lib'; 7 | import { NarikDataSourceService } from './service/narik-dataSource.service'; 8 | 9 | @NgModule({ 10 | imports: [HttpClientModule], 11 | providers: [ 12 | { 13 | provide: PluginService, 14 | useClass: NarikPluginService, 15 | }, 16 | { 17 | provide: DataSourceService, 18 | useClass: NarikDataSourceService, 19 | }, 20 | ], 21 | }) 22 | export class DashboardShareModule { 23 | /** 24 | * 25 | */ 26 | constructor() {} 27 | } 28 | -------------------------------------------------------------------------------- /src/assets/modules/base/data-info.json: -------------------------------------------------------------------------------- 1 | { 2 | "dataInfo": { 3 | "dataUrlInfo": { 4 | "defaultRemoteDataProvider": "odata", 5 | "dataPathTemplate": "/odata/{moduleKey}/{dataKey}/Default.{dataUrlMethod}", 6 | "getPathTemplate": "/odata/{moduleKey}/{dataKey}", 7 | "listPathTemplate": "/odata/{moduleKey}/{dataKey}/{dataUrlMethod}", 8 | "postPathTemplate": "/odata/{moduleKey}/{dataKey}", 9 | "updatePathTemplate": "/odata/{moduleKey}/{dataKey}", 10 | "deletePathTemplate": "/odata/{moduleKey}/{dataKey}/Default.Delete", 11 | "completePathTemplate": "/odata/{moduleKey}/{dataKey}/Default.Complete", 12 | "parameterPrefix": "?", 13 | "defaultDataUrlMethod": "GetForSelector" 14 | }, 15 | "defaultDataProvider": "remote", 16 | "defaultOriginDataProvider": "remote" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /plugins/todo/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: { 11 | context(path: string, deep?: boolean, filter?: RegExp): { 12 | keys(): string[]; 13 | (id: string): T; 14 | }; 15 | }; 16 | 17 | // First, initialize the Angular testing environment. 18 | getTestBed().initTestEnvironment( 19 | BrowserDynamicTestingModule, 20 | platformBrowserDynamicTesting() 21 | ); 22 | // Then we find all the tests. 23 | const context = require.context('./', true, /\.spec\.ts$/); 24 | // And load the modules. 25 | context.keys().map(context); 26 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-design/dashboard-designer/dashboard-designer.component.css: -------------------------------------------------------------------------------- 1 | .dashboard-body { 2 | background-color: #edf1f7; 3 | border-radius: 5px; 4 | margin-top: 5px; 5 | } 6 | 7 | .row.selected { 8 | border: 2px solid #77797b !important; 9 | border-radius: 5px; 10 | } 11 | 12 | .cdk-drag-placeholder { 13 | opacity: 0; 14 | } 15 | 16 | .cdk-drag-animating { 17 | transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); 18 | } 19 | 20 | 21 | .row-list.cdk-drop-list-dragging .row-item:not(.cdk-drag-placeholder) { 22 | transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); 23 | } 24 | 25 | 26 | .cdk-drag-preview { 27 | box-sizing: border-box; 28 | border-width: 2px; 29 | border-radius: 1px; 30 | box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), 31 | 0 8px 10px 1px rgba(0, 0, 0, 0.14), 32 | 0 3px 14px 2px rgba(0, 0, 0, 0.12); 33 | opacity: 0.8; 34 | } 35 | -------------------------------------------------------------------------------- /plugins/data-table/src/app/designer/designer.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ 'dashboard.titles.dataTable' | translate }} 4 | 5 | 6 | 7 | 15 | 16 | 17 | 23 | 24 | 25 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/assets/modules/base/ui-default-options.json: -------------------------------------------------------------------------------- 1 | { 2 | "select": { 3 | "key": "select", 4 | "value": { 5 | "toolbarKey": "selectToolbar", 6 | "toolbarModuleKey": "narik", 7 | "showSearchBox": true, 8 | "showToolbar": true 9 | } 10 | }, 11 | "data-table-select": { 12 | "key": "data-table-select", 13 | "value": { 14 | "toolbarKey": "dataSelectToolbar", 15 | "toolbarModuleKey": "narik", 16 | "showToolbar": true 17 | } 18 | }, 19 | "data-table": { 20 | "key": "data-table", 21 | "value": { 22 | "showSearchPanel": true 23 | } 24 | }, 25 | "button": { 26 | "key": "button", 27 | "value": { 28 | "cssClass": "ui-button-info", 29 | "appendShortcutToTooltip": false 30 | } 31 | }, 32 | "toolbar": { 33 | "key": "toolbar", 34 | "value": { 35 | "appendShortcutToTooltip": true 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-view/dashboard-viewer/dashboard-viewer.component.css: -------------------------------------------------------------------------------- 1 | .dashboard-body { 2 | background-color: #edf1f7; 3 | border-radius: 5px; 4 | margin-top: 5px; 5 | } 6 | 7 | .row.selected { 8 | border: 3px solid #007bff !important; 9 | border-radius: 5px; 10 | padding: 5px !important; 11 | } 12 | 13 | .cdk-drag-placeholder { 14 | opacity: 0; 15 | } 16 | 17 | .cdk-drag-animating { 18 | transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); 19 | } 20 | 21 | 22 | .row-list.cdk-drop-list-dragging .row-item:not(.cdk-drag-placeholder) { 23 | transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); 24 | } 25 | 26 | 27 | .cdk-drag-preview { 28 | box-sizing: border-box; 29 | border-width: 2px; 30 | border-radius: 1px; 31 | box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), 32 | 0 8px 10px 1px rgba(0, 0, 0, 0.14), 33 | 0 3px 14px 2px rgba(0, 0, 0, 0.12); 34 | opacity: 0.8; 35 | 36 | } 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /src/assets/plugins 6 | /tmp 7 | /out-tsc 8 | # Only exists if Bazel was run 9 | /bazel-out 10 | 11 | # dependencies 12 | /node_modules 13 | 14 | # profiling files 15 | chrome-profiler-events.json 16 | speed-measure-plugin.json 17 | 18 | # IDEs and editors 19 | /.idea 20 | .project 21 | .classpath 22 | .c9/ 23 | *.launch 24 | .settings/ 25 | *.sublime-workspace 26 | 27 | # IDE - VSCode 28 | .vscode/* 29 | .vscode 30 | !.vscode/settings.json 31 | !.vscode/tasks.json 32 | !.vscode/launch.json 33 | !.vscode/extensions.json 34 | .history/* 35 | 36 | # misc 37 | /.sass-cache 38 | /connect.lock 39 | /coverage 40 | /libpeerconnection.log 41 | npm-debug.log 42 | yarn-error.log 43 | testem.log 44 | /typings 45 | 46 | # System Files 47 | .DS_Store 48 | Thumbs.db 49 | package-lock.json 50 | /package-lock.json 51 | /documentation 52 | -------------------------------------------------------------------------------- /e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Protractor configuration file, see link for more information 3 | // https://github.com/angular/protractor/blob/master/lib/config.ts 4 | 5 | const { SpecReporter } = require('jasmine-spec-reporter'); 6 | 7 | /** 8 | * @type { import("protractor").Config } 9 | */ 10 | exports.config = { 11 | allScriptsTimeout: 11000, 12 | specs: [ 13 | './src/**/*.e2e-spec.ts' 14 | ], 15 | capabilities: { 16 | 'browserName': 'chrome' 17 | }, 18 | directConnect: true, 19 | baseUrl: 'http://localhost:4200/', 20 | framework: 'jasmine', 21 | jasmineNodeOpts: { 22 | showColors: true, 23 | defaultTimeoutInterval: 30000, 24 | print: function() {} 25 | }, 26 | onPrepare() { 27 | require('ts-node').register({ 28 | project: require('path').join(__dirname, './tsconfig.json') 29 | }); 30 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 31 | } 32 | }; -------------------------------------------------------------------------------- /plugins/todo/src/app/viewer/viewer.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ model.title }} 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | There is no todo item! 26 | 27 |
28 |
29 | -------------------------------------------------------------------------------- /plugins/link/src/app/designer/designer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Injector } from '@angular/core'; 2 | import { WidgetDesign } from 'dashboard-lib'; 3 | 4 | 5 | @Component({ 6 | templateUrl: './designer.component.html', 7 | }) 8 | export class LinkDesignComponent extends WidgetDesign { 9 | currentLink: any = { 10 | linkTitle: '', 11 | link: '', 12 | }; 13 | 14 | constructor(injector: Injector) { 15 | super(injector); 16 | } 17 | 18 | add() { 19 | if (this.currentLink.link && this.currentLink.linkTitle) { 20 | this.model.links.push({ 21 | link: this.currentLink.link, 22 | linkTitle: this.currentLink.linkTitle, 23 | }); 24 | this.currentLink = { 25 | linkTitle: '', 26 | link: '', 27 | }; 28 | } 29 | } 30 | 31 | removeLink(link) { 32 | const pos = this.model.links.indexOf(link); 33 | if (pos >= 0) { 34 | this.model.links.splice(pos, 1); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /plugins/date-time/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { FormsModule } from '@angular/forms'; 3 | import { MatIconModule } from '@angular/material/icon'; 4 | import { BrowserModule } from '@angular/platform-browser'; 5 | import { 6 | NarikMatCheckBoxModule, 7 | NarikMatInputModule, 8 | } from '@narik/ui-material'; 9 | import { TranslateModule } from '@ngx-translate/core'; 10 | import { DateTimeDesignComponent } from './designer/designer.component'; 11 | import { DateTimeViewComponent } from './viewer/viewer.component'; 12 | import { DateFnsModule } from 'ngx-date-fns'; 13 | @NgModule({ 14 | declarations: [DateTimeDesignComponent, DateTimeViewComponent], 15 | imports: [ 16 | BrowserModule, 17 | NarikMatInputModule, 18 | FormsModule, 19 | MatIconModule, 20 | TranslateModule, 21 | NarikMatCheckBoxModule, 22 | DateFnsModule, 23 | ], 24 | providers: [], 25 | bootstrap: [], 26 | }) 27 | export class AppModule {} 28 | -------------------------------------------------------------------------------- /src/app/modules/narik-ngx-layout/ngx-main-view/ngx-main-view.component.scss: -------------------------------------------------------------------------------- 1 | @import "../../../../styles/themes"; 2 | @import "~bootstrap/scss/mixins/breakpoints"; 3 | @import "~@nebular/theme/styles/global/breakpoints"; 4 | 5 | @include nb-install-component() { 6 | nb-layout-column.small { 7 | flex: 0.15 !important; 8 | } 9 | 10 | nb-sidebar.settings-sidebar { 11 | $sidebar-width: 7.5rem; 12 | 13 | transition: width 0.3s ease; 14 | width: $sidebar-width; 15 | overflow: hidden; 16 | 17 | &.collapsed { 18 | width: 0; 19 | 20 | ::ng-deep .main-container { 21 | width: 0; 22 | 23 | .scrollable { 24 | width: $sidebar-width; 25 | padding: 1.25rem; 26 | } 27 | } 28 | } 29 | 30 | ::ng-deep .main-container { 31 | width: $sidebar-width; 32 | transition: width 0.3s ease; 33 | overflow: hidden; 34 | .scrollable { 35 | width: $sidebar-width; 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-view/dashboard-view-cell/dashboard-view-cell.component.ts: -------------------------------------------------------------------------------- 1 | import { DashboardCell } from './../../dashboard-share/base/dashboard-cell'; 2 | import { Component, OnInit, Input, HostBinding } from '@angular/core'; 3 | 4 | @Component({ 5 | selector: 'dashboard-view-cell', 6 | templateUrl: 'dashboard-view-cell.component.html', 7 | styleUrls: ['dashboard-view-cell.component.css'], 8 | }) 9 | export class DashboardViewCellComponent implements OnInit { 10 | @Input() 11 | cell: DashboardCell = new DashboardCell(); 12 | 13 | @HostBinding('class') 14 | classItems = ''; 15 | 16 | _size: number; 17 | @Input() 18 | set size(value: number) { 19 | this._size = value; 20 | this.classItems = 21 | DashboardCell.colClasses 22 | .map((x) => { 23 | return x + this.size.toString(); 24 | }) 25 | .join(' ') + ' mt-1 mt-md-0'; 26 | } 27 | get size(): number { 28 | return this._size; 29 | } 30 | 31 | constructor() {} 32 | 33 | ngOnInit() {} 34 | } 35 | -------------------------------------------------------------------------------- /plugins/kpi/src/app/viewer/viewer.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 14 | {{ model.title }} 16 | 22 | {{ 23 | kpiInfo.trade >= 0 ? 'trending_up' : 'trending_down' 24 | }}{{ kpiInfo.trade }}% 26 | 27 | 28 |
29 |

{{ kpiInfo.value | number }}

30 | {{ kpiInfo.periodTitle }} 31 |
32 |
33 | -------------------------------------------------------------------------------- /plugins/kpi/src/app/viewer/viewer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Injector } from '@angular/core'; 2 | import { WidgetView } from 'dashboard-lib'; 3 | 4 | @Component({ 5 | templateUrl: './viewer.component.html', 6 | styles: [ 7 | ` 8 | mat-chip { 9 | border-radius: 24px; 10 | position: relative; 11 | overflow: hidden; 12 | } 13 | 14 | .icon-chip { 15 | font-size: 11px !important; 16 | padding: 4px 8px !important; 17 | display: flex !important; 18 | flex-direction: row; 19 | align-items: center; 20 | justify-content: center; 21 | } 22 | `, 23 | ], 24 | }) 25 | export class KpiViewComponent extends WidgetView { 26 | displayTitle = false; 27 | kpiInfo: any = {}; 28 | constructor(injector: Injector) { 29 | super(injector); 30 | } 31 | afterModelSet() { 32 | if (this.model.dataSource) { 33 | this.dataSourceService 34 | .dataSourceData(this.model.dataSource) 35 | .subscribe((x) => (this.kpiInfo = x)); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # narik-pluggable-dashboard-sample 2 | 3 | Sample pluggable dashboard created with Narik and Webpack Module Federation. 4 | 5 | [Online Demo](http://narik.me/demo/pluggable-dashboard/) 6 | [Tutorial](./tutorial/tutorial.md) 7 | 8 | In this project , I create a dashboard system (designer and viewer) with multiple pluggable widgets. 9 | 10 | ## Widgets 11 | 12 | - [x] Link 13 | - [x] Todo List 14 | - [x] Chart 15 | - [ ] Map 16 | - [x] DataTable 17 | - [x] Gauge 18 | - [x] DateTime 19 | - [ ] .... 20 | 21 | Do you have any suggestion? Create an issue for that. 22 | 23 | ## Running the demo 24 | 25 | - Install packages: `yarn install` (do not use npm!) 26 | - Build the shared library `yarn build:shared` 27 | - Build plugins `yarn build:plugins` 28 | - Start the shell: `ng s` 29 | - Open the shell http://localhost:4200 30 | 31 | 32 | ## Serve a plugin 33 | 34 | To server a plugin use `ng s`, for example `ng s kpi`. Then change **kpi** remote mode in [**plugin definitions**](./src/assets/dashboard.json) to '**development**' . 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /plugins/link/src/app/viewer/viewer.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ model.title }} 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 16 | 17 | {{ item.linkTitle }} 18 | 19 | 24 | 25 | {{ item.linkTitle }} 26 | 27 | 28 | 29 | 30 | 31 |
32 |
33 | -------------------------------------------------------------------------------- /plugins/todo/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Protractor configuration file, see link for more information 3 | // https://github.com/angular/protractor/blob/master/lib/config.ts 4 | 5 | const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter'); 6 | 7 | /** 8 | * @type { import("protractor").Config } 9 | */ 10 | exports.config = { 11 | allScriptsTimeout: 11000, 12 | specs: [ 13 | './src/**/*.e2e-spec.ts' 14 | ], 15 | capabilities: { 16 | browserName: 'chrome' 17 | }, 18 | directConnect: true, 19 | SELENIUM_PROMISE_MANAGER: false, 20 | baseUrl: 'http://localhost:4200/', 21 | framework: 'jasmine', 22 | jasmineNodeOpts: { 23 | showColors: true, 24 | defaultTimeoutInterval: 30000, 25 | print: function() {} 26 | }, 27 | onPrepare() { 28 | require('ts-node').register({ 29 | project: require('path').join(__dirname, './tsconfig.json') 30 | }); 31 | jasmine.getEnv().addReporter(new SpecReporter({ 32 | spec: { 33 | displayStacktrace: StacktraceOption.PRETTY 34 | } 35 | })); 36 | } 37 | }; -------------------------------------------------------------------------------- /plugins/todo/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | 4 | describe('AppComponent', () => { 5 | beforeEach(async () => { 6 | await TestBed.configureTestingModule({ 7 | declarations: [ 8 | AppComponent 9 | ], 10 | }).compileComponents(); 11 | }); 12 | 13 | it('should create the app', () => { 14 | const fixture = TestBed.createComponent(AppComponent); 15 | const app = fixture.componentInstance; 16 | expect(app).toBeTruthy(); 17 | }); 18 | 19 | it(`should have as title 'todo'`, () => { 20 | const fixture = TestBed.createComponent(AppComponent); 21 | const app = fixture.componentInstance; 22 | expect(app.title).toEqual('todo'); 23 | }); 24 | 25 | it('should render title', () => { 26 | const fixture = TestBed.createComponent(AppComponent); 27 | fixture.detectChanges(); 28 | const compiled = fixture.nativeElement; 29 | expect(compiled.querySelector('.content span').textContent).toContain('todo app is running!'); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /plugins/todo/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { NgModule } from '@angular/core'; 3 | import { FormsModule } from '@angular/forms'; 4 | import { MatListModule } from '@angular/material/list'; 5 | import { BrowserModule } from '@angular/platform-browser'; 6 | import { 7 | NarikMatCheckBoxModule, 8 | NarikMatInputModule, 9 | NarikMatSelectModule, 10 | } from '@narik/ui-material'; 11 | import { AppComponent } from './app.component'; 12 | import { TodoDesignComponent } from './designer/designer.component'; 13 | import { TodoViewComponent } from './viewer/viewer.component'; 14 | import { TranslateModule } from '@ngx-translate/core'; 15 | @NgModule({ 16 | declarations: [AppComponent, TodoViewComponent, TodoDesignComponent], 17 | imports: [ 18 | BrowserModule, 19 | CommonModule, 20 | FormsModule, 21 | MatListModule, 22 | NarikMatCheckBoxModule, 23 | NarikMatSelectModule, 24 | NarikMatInputModule, 25 | TranslateModule, 26 | ], 27 | providers: [], 28 | bootstrap: [AppComponent], 29 | }) 30 | export class AppModule {} 31 | -------------------------------------------------------------------------------- /plugins/kpi/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { FormsModule } from '@angular/forms'; 3 | import { MatCardModule } from '@angular/material/card'; 4 | import { MatChipsModule } from '@angular/material/chips'; 5 | import { MatIconModule } from '@angular/material/icon'; 6 | import { BrowserModule } from '@angular/platform-browser'; 7 | import { 8 | NarikMatCheckBoxModule, 9 | NarikMatInputModule, 10 | NarikMatSelectModule, 11 | } from '@narik/ui-material'; 12 | import { TranslateModule } from '@ngx-translate/core'; 13 | import { KpiDesignComponent } from './designer/designer.component'; 14 | import { KpiViewComponent } from './viewer/viewer.component'; 15 | 16 | @NgModule({ 17 | declarations: [KpiViewComponent, KpiDesignComponent], 18 | imports: [ 19 | BrowserModule, 20 | MatIconModule, 21 | MatCardModule, 22 | MatChipsModule, 23 | NarikMatSelectModule, 24 | NarikMatCheckBoxModule, 25 | NarikMatInputModule, 26 | FormsModule, 27 | TranslateModule, 28 | ], 29 | providers: [], 30 | bootstrap: [], 31 | }) 32 | export class AppModule {} 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Narik 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /projects/dashboard-lib/README.md: -------------------------------------------------------------------------------- 1 | # DashboradLib 2 | 3 | This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 11.0.1. 4 | 5 | ## Code scaffolding 6 | 7 | Run `ng generate component component-name --project dashboard-lib` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project dashboard-lib`. 8 | > Note: Don't forget to add `--project dashboard-lib` or else it will be added to the default project in your `angular.json` file. 9 | 10 | ## Build 11 | 12 | Run `ng build dashboard-lib` to build the project. The build artifacts will be stored in the `dist/` directory. 13 | 14 | ## Publishing 15 | 16 | After building your library with `ng build dashboard-lib`, go to the dist folder `cd dist/dashboard-lib` and run `npm publish`. 17 | 18 | ## Running unit tests 19 | 20 | Run `ng test dashboard-lib` to execute the unit tests via [Karma](https://karma-runner.github.io). 21 | 22 | ## Further help 23 | 24 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. 25 | -------------------------------------------------------------------------------- /src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | 4 | describe('AppComponent', () => { 5 | beforeEach(async(() => { 6 | TestBed.configureTestingModule({ 7 | declarations: [ 8 | AppComponent 9 | ], 10 | }).compileComponents(); 11 | })); 12 | 13 | it('should create the app', () => { 14 | const fixture = TestBed.createComponent(AppComponent); 15 | const app = fixture.debugElement.componentInstance; 16 | expect(app).toBeTruthy(); 17 | }); 18 | 19 | it(`should have as title 'narik-dashboard'`, () => { 20 | const fixture = TestBed.createComponent(AppComponent); 21 | const app = fixture.debugElement.componentInstance; 22 | expect(app.title).toEqual('narik-dashboard'); 23 | }); 24 | 25 | it('should render title in a h1 tag', () => { 26 | const fixture = TestBed.createComponent(AppComponent); 27 | fixture.detectChanges(); 28 | const compiled = fixture.debugElement.nativeElement; 29 | expect(compiled.querySelector('h1').textContent).toContain('Welcome to narik-dashboard!'); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /plugins/data-table/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { FormsModule } from '@angular/forms'; 3 | import { MatIconModule } from '@angular/material/icon'; 4 | import { BrowserModule } from '@angular/platform-browser'; 5 | import { 6 | NarikMatCheckBoxModule, 7 | NarikMatDataTableModule, 8 | NarikMatInputModule, 9 | NarikMatSelectModule 10 | } from '@narik/ui-material'; 11 | import { TranslateModule } from '@ngx-translate/core'; 12 | import { AppComponent } from './app.component'; 13 | import { DataTableDesignComponent } from './designer/designer.component'; 14 | import { DataTableViewComponent } from './viewer/viewer.component'; 15 | 16 | 17 | @NgModule({ 18 | declarations: [ 19 | AppComponent, 20 | DataTableDesignComponent, 21 | DataTableViewComponent, 22 | ], 23 | imports: [ 24 | BrowserModule, 25 | FormsModule, 26 | NarikMatDataTableModule, 27 | NarikMatInputModule, 28 | NarikMatSelectModule, 29 | NarikMatCheckBoxModule, 30 | TranslateModule, 31 | MatIconModule, 32 | ], 33 | providers: [], 34 | bootstrap: [AppComponent], 35 | }) 36 | export class AppModule {} 37 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, './coverage/narik-dashboard'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /src/app/modules/narik-ngx-layout/narik-ngx-layout.module.ts: -------------------------------------------------------------------------------- 1 | import { FormsModule } from '@angular/forms'; 2 | import { CommonModule } from '@angular/common'; 3 | import { NgModule } from '@angular/core'; 4 | 5 | import { COMPONENTS } from './index'; 6 | 7 | import { MatSlideToggleModule } from '@angular/material/slide-toggle'; 8 | 9 | import { 10 | NbActionsModule, 11 | NbCardModule, 12 | NbContextMenuModule, 13 | NbLayoutModule, 14 | NbMenuModule, 15 | NbSearchModule, 16 | NbSidebarModule, 17 | NbSidebarService, 18 | NbUserModule, 19 | NbIconModule, 20 | } from '@nebular/theme'; 21 | import { RouterModule } from '@angular/router'; 22 | 23 | @NgModule({ 24 | imports: [ 25 | RouterModule, 26 | CommonModule, 27 | FormsModule, 28 | NbActionsModule, 29 | NbCardModule, 30 | NbContextMenuModule, 31 | NbLayoutModule, 32 | NbMenuModule.forRoot(), 33 | NbSearchModule, 34 | NbSidebarModule, 35 | NbIconModule, 36 | NbUserModule, 37 | MatSlideToggleModule, 38 | ], 39 | declarations: [COMPONENTS], 40 | exports: [COMPONENTS], 41 | providers: [NbSidebarService], 42 | }) 43 | export class NarikNgxLayout {} 44 | -------------------------------------------------------------------------------- /plugins/todo/src/app/viewer/viewer.component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChangeDetectionStrategy, 3 | ChangeDetectorRef, 4 | Component, 5 | Injector, 6 | NgModule, 7 | } from '@angular/core'; 8 | import { WidgetView } from 'dashboard-lib'; 9 | 10 | @Component({ 11 | templateUrl: './viewer.component.html', 12 | styleUrls: ['viewer.component.css'], 13 | changeDetection: ChangeDetectionStrategy.OnPush, 14 | }) 15 | export class TodoViewComponent extends WidgetView { 16 | todoItems: any[] = []; 17 | constructor( 18 | injector: Injector, 19 | private changeDetectorRef: ChangeDetectorRef 20 | ) { 21 | super(injector); 22 | } 23 | afterModelSet() { 24 | if (this.model.dataSource) { 25 | this.dataSourceService 26 | .dataSourceData(this.model.dataSource) 27 | .subscribe((x) => { 28 | this.todoItems = x; 29 | this.changeDetectorRef.detectChanges(); 30 | }); 31 | } 32 | } 33 | 34 | get remainCount() { 35 | return this.todoItems.filter((x) => !x.done).length; 36 | } 37 | 38 | setDone(item: any, isDone: boolean) { 39 | item.done = isDone; 40 | this.changeDetectorRef.detectChanges(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /plugins/date-time/src/app/viewer/viewer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Injector, OnDestroy, OnInit } from '@angular/core'; 2 | import { WidgetView } from 'dashboard-lib'; 3 | import { interval } from 'rxjs/internal/observable/interval'; 4 | import { takeWhile } from 'rxjs/internal/operators/takeWhile'; 5 | 6 | @Component({ 7 | templateUrl: './viewer.component.html', 8 | styles: [ 9 | ` 10 | .date-container { 11 | display: flex; 12 | } 13 | 14 | .center-item { 15 | margin: auto; 16 | } 17 | 18 | .datetime-content { 19 | font-weight: bold; 20 | } 21 | `, 22 | ], 23 | }) 24 | export class DateTimeViewComponent 25 | extends WidgetView 26 | implements OnInit, OnDestroy { 27 | today: any = new Date(); 28 | displayTitle = false; 29 | isAlive = true; 30 | constructor(injector: Injector) { 31 | super(injector); 32 | } 33 | ngOnInit(): void { 34 | interval(1000) 35 | .pipe(takeWhile(() => this.isAlive)) 36 | .subscribe(() => { 37 | this.today = new Date(); 38 | }); 39 | } 40 | afterModelSet() {} 41 | 42 | ngOnDestroy(): void { 43 | this.isAlive = false; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-view/dashboard-view.module.ts: -------------------------------------------------------------------------------- 1 | import { NarikCommonModule } from '@narik/common'; 2 | import { 3 | NarikMatBusyIndicatorModule, 4 | NarikMatToolbarModule, 5 | } from '@narik/ui-material'; 6 | 7 | import { CommonModule } from '@angular/common'; 8 | import { NgModule } from '@angular/core'; 9 | import { FormsModule } from '@angular/forms'; 10 | import { MatCardModule } from '@angular/material/card'; 11 | import { RouterModule } from '@angular/router'; 12 | 13 | import { DashboardViewCellComponent } from './dashboard-view-cell/dashboard-view-cell.component'; 14 | import { DashboardViewRowComponent } from './dashboard-view-row/dashboard-view-row.component'; 15 | import { DashboardViewerComponent } from './dashboard-viewer/dashboard-viewer.component'; 16 | 17 | @NgModule({ 18 | imports: [ 19 | CommonModule, 20 | FormsModule, 21 | MatCardModule, 22 | NarikCommonModule, 23 | NarikMatToolbarModule, 24 | NarikMatBusyIndicatorModule, 25 | RouterModule, 26 | ], 27 | declarations: [ 28 | DashboardViewRowComponent, 29 | DashboardViewCellComponent, 30 | DashboardViewerComponent, 31 | ], 32 | exports: [DashboardViewerComponent], 33 | providers: [], 34 | }) 35 | export class DashboardViewModule {} 36 | -------------------------------------------------------------------------------- /plugins/todo/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | jasmineHtmlReporter: { 19 | suppressAll: true // removes the duplicated traces 20 | }, 21 | coverageReporter: { 22 | dir: require('path').join(__dirname, '../../coverage/todo'), 23 | subdir: '.', 24 | reporters: [ 25 | { type: 'html' }, 26 | { type: 'text-summary' } 27 | ] 28 | }, 29 | reporters: ['progress', 'kjhtml'], 30 | port: 9876, 31 | colors: true, 32 | logLevel: config.LOG_INFO, 33 | autoWatch: true, 34 | browsers: ['Chrome'], 35 | singleRun: false, 36 | restartOnFileChange: true 37 | }); 38 | }; 39 | -------------------------------------------------------------------------------- /projects/dashboard-lib/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | jasmineHtmlReporter: { 19 | suppressAll: true // removes the duplicated traces 20 | }, 21 | coverageReporter: { 22 | dir: require('path').join(__dirname, '../../coverage/dashboard-lib'), 23 | subdir: '.', 24 | reporters: [ 25 | { type: 'html' }, 26 | { type: 'text-summary' } 27 | ] 28 | }, 29 | reporters: ['progress', 'kjhtml'], 30 | port: 9876, 31 | colors: true, 32 | logLevel: config.LOG_INFO, 33 | autoWatch: true, 34 | browsers: ['Chrome'], 35 | singleRun: false, 36 | restartOnFileChange: true 37 | }); 38 | }; 39 | -------------------------------------------------------------------------------- /plugins/link/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { LinkDesignComponent } from './designer/designer.component'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | import { NgModule } from '@angular/core'; 4 | 5 | import { AppComponent } from './app.component'; 6 | import { LinkViewComponent } from './viewer/viewer.component'; 7 | import { CommonModule } from '@angular/common'; 8 | import { FormsModule } from '@angular/forms'; 9 | import { MatListModule } from '@angular/material/list'; 10 | import { 11 | NarikMatButtonModule, 12 | NarikMatCheckBoxModule, 13 | NarikMatInputModule, 14 | NarikMatSelectModule, 15 | } from '@narik/ui-material'; 16 | import { TranslateModule } from '@ngx-translate/core'; 17 | import { MatCardModule } from '@angular/material/card'; 18 | import { MatIconModule } from '@angular/material/icon'; 19 | 20 | @NgModule({ 21 | declarations: [AppComponent, LinkDesignComponent, LinkViewComponent], 22 | imports: [ 23 | BrowserModule, 24 | CommonModule, 25 | FormsModule, 26 | MatListModule, 27 | NarikMatCheckBoxModule, 28 | NarikMatSelectModule, 29 | NarikMatInputModule, 30 | NarikMatButtonModule, 31 | MatCardModule, 32 | MatIconModule, 33 | TranslateModule, 34 | ], 35 | providers: [], 36 | bootstrap: [AppComponent], 37 | }) 38 | export class AppModule {} 39 | -------------------------------------------------------------------------------- /src/styles/dashboard-viewer.css: -------------------------------------------------------------------------------- 1 | .widget-view-container { 2 | position: relative; 3 | } 4 | 5 | .widget-full-screen .widget-content { 6 | padding: 20px !important; 7 | } 8 | 9 | .widget-title-container { 10 | height: 30px; 11 | } 12 | 13 | .advanced-pie-legend 14 | .legend-items-container 15 | .legend-items 16 | .legend-item 17 | .item-label { 18 | margin-top: 0 !important; 19 | } 20 | 21 | .advanced-pie-legend 22 | .legend-items-container 23 | .legend-items 24 | .legend-item 25 | .item-value { 26 | margin-top: 0 !important; 27 | } 28 | 29 | .advanced-pie-legend .total-label { 30 | margin-top: 10px; 31 | } 32 | 33 | .mat-table-container { 34 | height: 100% !important; 35 | } 36 | 37 | narik-mat-busy-indicator { 38 | height: calc(100% - 70px); 39 | } 40 | 41 | .has-paging narik-mat-busy-indicator { 42 | height: calc(100% - 100px); 43 | } 44 | 45 | .widget-view-toolbar { 46 | position: absolute; 47 | right: -10px; 48 | top: -20px; 49 | } 50 | 51 | .widget-full-screen .widget-view-toolbar { 52 | right: 0 !important; 53 | top: 0 !important; 54 | } 55 | 56 | [dir="rtl"] .widget-view-toolbar { 57 | right: initial !important; 58 | left: -10px !important; 59 | } 60 | 61 | [dir="rtl"] .widget-full-screen .widget-view-toolbar { 62 | right: initial !important; 63 | left: 0 !important; 64 | } 65 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-share/service/plugin.service.ts: -------------------------------------------------------------------------------- 1 | import { Observable } from 'rxjs/internal/Observable'; 2 | 3 | import { ComponentFactory, Type } from '@angular/core'; 4 | 5 | import { WidgetViewType } from '../base/widget-view-type'; 6 | 7 | export class WidgetType { 8 | key: string; 9 | value: string; 10 | isEnabled: boolean; 11 | defaultModel: any; 12 | designComponent?: string; 13 | viewComponent?: string; 14 | remote?: RemoteInformation; 15 | } 16 | 17 | export interface RemoteInformation { 18 | mode: 'development' | 'production'; 19 | entry: 20 | | string 21 | | { 22 | development: string; 23 | production: string; 24 | }; 25 | viewer: { 26 | module?: string; 27 | componentModule?: string; 28 | component: string; 29 | }; 30 | designer: { 31 | module?: string; 32 | componentModule?: string; 33 | component: string; 34 | }; 35 | } 36 | export class WidgetTypeGroup { 37 | key: string; 38 | value: string; 39 | isEnabled: boolean; 40 | widgetTypes: WidgetType[]; 41 | } 42 | 43 | export abstract class PluginService { 44 | abstract init(); 45 | abstract widgetGroups(): Observable; 46 | abstract widgetComponentType( 47 | widgetGroup: string, 48 | widgetKey: string, 49 | widgetType: WidgetViewType 50 | ): Promise | ComponentFactory>; 51 | } 52 | -------------------------------------------------------------------------------- /plugins/chart/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | // import { NgModule } from '@angular/core'; 2 | // import { FormsModule } from '@angular/forms'; 3 | // import { MatFormFieldModule } from '@angular/material/form-field'; 4 | // import { MatIconModule } from '@angular/material/icon'; 5 | // import { MatSelectModule } from '@angular/material/select'; 6 | // import { MatTabsModule } from '@angular/material/tabs'; 7 | // import { BrowserModule } from '@angular/platform-browser'; 8 | // import { 9 | // NarikMatCheckBoxModule, 10 | // NarikMatInputModule, 11 | // NarikMatSelectModule, 12 | // } from '@narik/ui-material'; 13 | // import { TranslateModule } from '@ngx-translate/core'; 14 | // import { NgxChartsModule, TooltipModule } from '@swimlane/ngx-charts'; 15 | 16 | // @NgModule({ 17 | // declarations: [], 18 | // imports: [ 19 | // TooltipModule, 20 | // BrowserModule, 21 | // FormsModule, 22 | // // MatTabsModule, 23 | // // MatFormFieldModule, 24 | // NarikMatSelectModule, 25 | // NarikMatInputModule, 26 | // // MatSelectModule, 27 | // NarikMatCheckBoxModule, 28 | // NgxChartsModule, 29 | // TooltipModule, 30 | // MatIconModule, 31 | // TranslateModule, 32 | // ], 33 | // providers: [], 34 | // bootstrap: [], 35 | // }) 36 | // export class AppModule { 37 | // /** 38 | // * 39 | // */ 40 | // constructor() { 41 | // console.log('AppModuleAppModuleAppModule'); 42 | // } 43 | // } 44 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-design/dashboard-cell/dashboard-cell.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 11 | 12 |
13 |
14 | 15 | 25 | 26 | 27 |
32 | horizontal_split 33 | 39 | 40 |
41 | 42 | 49 |
50 | -------------------------------------------------------------------------------- /src/assets/modules/narik.json: -------------------------------------------------------------------------------- 1 | { 2 | "metaData": { 3 | "translateItems": ["narik"], 4 | "events": [ 5 | { 6 | "key": "MODULE_LOAD_COMPLETELY", 7 | "info": { 8 | "subjectType": "ReplaySubject", 9 | "subjectParam": 10 10 | } 11 | } 12 | ], 13 | "toolbars": [ 14 | { 15 | "key": "selectToolbar", 16 | "items": [ 17 | { 18 | "key": "refresh", 19 | "busyExpr": "host.dataIsLoading" 20 | }, 21 | { 22 | "key": "new", 23 | "icon": "add" 24 | }, 25 | { 26 | "key": "edit", 27 | "disableExpr": "!host.value" 28 | } 29 | ] 30 | }, 31 | { 32 | "key": "dataSelectToolbar", 33 | "items": [ 34 | { 35 | "key": "refresh", 36 | "busyExpr": "host.dataIsLoading" 37 | }, 38 | { 39 | "key": "list" 40 | }, 41 | { 42 | "key": "new", 43 | "icon": "add" 44 | }, 45 | { 46 | "key": "edit", 47 | "disableExpr": "!host.value" 48 | } 49 | ] 50 | }, 51 | { 52 | "key": "selectRefreshToolbar", 53 | "items": [ 54 | { 55 | "key": "refresh", 56 | "busyExpr": "host.dataIsLoading" 57 | } 58 | ] 59 | } 60 | ] 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-design/select-widget-type/select-widget-type.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from "@angular/core"; 2 | import { 3 | PluginService, 4 | WidgetTypeGroup, 5 | WidgetType 6 | } from "../../dashboard-share/service/plugin.service"; 7 | 8 | @Component({ 9 | selector: "select-widget-type", 10 | templateUrl: "select-widget-type.component.html" 11 | }) 12 | export class SelectWidgetTypeComponent implements OnInit { 13 | widgetTypeGroups: WidgetTypeGroup[] = []; 14 | widgetTypes: WidgetType[] = []; 15 | 16 | widgetType: string; 17 | 18 | _widgetTypeGroup: string; 19 | set widgetTypeGroup(value: string) { 20 | if (value !== this._widgetTypeGroup) { 21 | this._widgetTypeGroup = value; 22 | if (value) { 23 | this.widgetTypes = this.widgetTypeGroups.filter( 24 | x => x.key === value 25 | )[0].widgetTypes; 26 | } else { 27 | this.widgetTypes = []; 28 | } 29 | } 30 | } 31 | get widgetTypeGroup(): string { 32 | return this._widgetTypeGroup; 33 | } 34 | 35 | get widgetTypeObject(): WidgetType { 36 | return this.widgetTypes.filter(x => x.key === this.widgetType)[0]; 37 | } 38 | selectOptions: any = { 39 | showToolbar: false 40 | }; 41 | 42 | constructor(private dashboardService: PluginService) {} 43 | 44 | ngOnInit() { 45 | this.dashboardService 46 | .widgetGroups() 47 | .subscribe(result => (this.widgetTypeGroups = result)); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /plugins/link/src/app/designer/designer.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ 'dashboard.titles.link' | translate }} 4 | 5 | 6 | 7 | 8 | 14 | 15 | 21 | 22 | 23 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | clear 43 | center_focus_weak 49 | {{ item.linkTitle }} 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/app/modules/narik-ngx-layout/ngx-view-header/ngx-view-header.component.scss: -------------------------------------------------------------------------------- 1 | @import "../../../../styles/themes"; 2 | 3 | @include nb-install-component() { 4 | display: flex; 5 | justify-content: space-between; 6 | width: 100%; 7 | 8 | .left { 9 | display: flex; 10 | width: 100%; 11 | order: 0; 12 | flex-direction: row; 13 | } 14 | .right { 15 | order: 1; 16 | flex-direction: row-reverse; 17 | } 18 | 19 | .logo-container { 20 | display: flex; 21 | align-items: center; 22 | width: calc(#{nb-theme(sidebar-width)} - #{nb-theme(header-padding)}); 23 | } 24 | 25 | nb-action { 26 | height: auto; 27 | display: flex; 28 | align-content: center; 29 | } 30 | 31 | nb-user { 32 | cursor: pointer; 33 | } 34 | 35 | ::ng-deep nb-search button { 36 | padding: 0 !important; 37 | } 38 | 39 | .header-container { 40 | display: flex; 41 | align-items: center; 42 | width: auto; 43 | 44 | .sidebar-toggle { 45 | @include nb-ltr(padding-right, 1.25rem); 46 | @include nb-rtl(padding-left, 1.25rem); 47 | text-decoration: none; 48 | color: nb-theme(text-hint-color); 49 | nb-icon { 50 | font-size: 1.75rem; 51 | } 52 | } 53 | 54 | .logo { 55 | padding: 0 1.25rem; 56 | font-size: 1.75rem; 57 | @include nb-ltr(border-left, 1px solid nb-theme(divider-color)); 58 | @include nb-rtl(border-right, 1px solid nb-theme(divider-color)); 59 | white-space: nowrap; 60 | text-decoration: none; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { DashboardDesignerComponent } from "./modules/dashboard/dashboard-design/dashboard-designer/dashboard-designer.component"; 2 | import { NgModule } from "@angular/core"; 3 | import { Routes, RouterModule } from "@angular/router"; 4 | import { MainComponent } from "./main/main.component"; 5 | import { MainViewComponent } from "./main-view/main-view.component"; 6 | import { ModuleLoadCompletelyGuard, FormViewRoute } from "@narik/app-core"; 7 | import { DashboardViewerComponent } from "./modules/dashboard/dashboard-view/dashboard-viewer/dashboard-viewer.component"; 8 | 9 | const routes: Routes = [ 10 | { 11 | path: "", 12 | canActivate: [ModuleLoadCompletelyGuard], 13 | data: { moduleKey: "main" }, 14 | component: MainComponent, 15 | children: [ 16 | { 17 | path: "", 18 | component: MainViewComponent, 19 | outlet: "dashboard", 20 | data: { 21 | showOnlyRouter: true 22 | } 23 | }, 24 | { 25 | path: "dashboard", 26 | component: DashboardViewerComponent, 27 | data: { 28 | title: "dashboard.dashboard" 29 | } 30 | }, 31 | { 32 | path: "dashboard-design", 33 | component: DashboardDesignerComponent, 34 | data: { 35 | title: "dashboard.dashboardDesign" 36 | } 37 | }, 38 | ...FormViewRoute("main") 39 | ] 40 | } 41 | ]; 42 | 43 | @NgModule({ 44 | imports: [RouterModule.forRoot(routes)], 45 | exports: [RouterModule] 46 | }) 47 | export class AppRoutingModule {} 48 | -------------------------------------------------------------------------------- /plugins/kpi/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | template: ` 6 | 7 |
8 |

9 | Welcome to {{title}}! 10 |

11 | {{ title }} app is running! 12 | Angular Logo 13 |
14 |

Here are some links to help you start:

15 | 26 | 27 | `, 28 | styles: [] 29 | }) 30 | export class AppComponent { 31 | title = 'kpi'; 32 | } 33 | -------------------------------------------------------------------------------- /plugins/link/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | template: ` 6 | 7 |
8 |

9 | Welcome to {{title}}! 10 |

11 | {{ title }} app is running! 12 | Angular Logo 13 |
14 |

Here are some links to help you start:

15 | 26 | 27 | `, 28 | styles: [] 29 | }) 30 | export class AppComponent { 31 | title = 'link'; 32 | } 33 | -------------------------------------------------------------------------------- /plugins/data-table/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | template: ` 6 | 7 |
8 |

9 | Welcome to {{title}}! 10 |

11 | {{ title }} app is running! 12 | Angular Logo 13 |
14 |

Here are some links to help you start:

15 | 26 | 27 | `, 28 | styles: [] 29 | }) 30 | export class AppComponent { 31 | title = 'data-table'; 32 | } 33 | -------------------------------------------------------------------------------- /plugins/date-time/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | template: ` 6 | 7 |
8 |

9 | Welcome to {{title}}! 10 |

11 | {{ title }} app is running! 12 | Angular Logo 13 |
14 |

Here are some links to help you start:

15 | 26 | 27 | `, 28 | styles: [] 29 | }) 30 | export class AppComponent { 31 | title = 'date-time'; 32 | } 33 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | import { loadRemoteEntry } from '@angular-architects/module-federation'; 7 | import { 8 | WidgetType, 9 | WidgetTypeGroup, 10 | } from './app/modules/dashboard/dashboard-share/service/plugin.service'; 11 | import { isString } from '@narik/common'; 12 | import 'reflect-metadata'; 13 | 14 | if (environment.production) { 15 | enableProdMode(); 16 | } 17 | 18 | fetch('assets/dashboard.json').then((res) => { 19 | res.json().then((data: { widgetTypeGroups: WidgetTypeGroup[] }) => { 20 | const plugins: WidgetType[] = Array.prototype.concat.apply( 21 | [], 22 | data.widgetTypeGroups.map((g) => g.widgetTypes.filter((d) => !!d.remote)) 23 | ); 24 | 25 | Promise.all( 26 | plugins.map((p) => 27 | loadRemoteEntry( 28 | isString(p.remote.entry) 29 | ? p.remote.entry 30 | : p.remote.mode === 'production' 31 | ? p.remote.entry.production 32 | : p.remote.entry.development, 33 | p.key 34 | ).then( 35 | (entry) => { 36 | return entry; 37 | }, 38 | (error) => { 39 | console.error('could not load entry for:' + p.key); 40 | } 41 | ) 42 | ) 43 | ).then(() => { 44 | platformBrowserDynamic() 45 | .bootstrapModule(AppModule) 46 | .catch((err) => console.error(err)); 47 | }); 48 | }); 49 | }); 50 | -------------------------------------------------------------------------------- /plugins/data-table/src/app/viewer/viewer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Injector } from '@angular/core'; 2 | import { MatLocalDataSource } from '@narik/ui-material'; 3 | import { WidgetView } from 'dashboard-lib'; 4 | 5 | @Component({ 6 | templateUrl: './viewer.component.html', 7 | styles: [ 8 | ` 9 | .full-screen-table { 10 | height: 90vh !important; 11 | } 12 | `, 13 | ], 14 | }) 15 | export class DataTableViewComponent extends WidgetView { 16 | dataSource: MatLocalDataSource = new MatLocalDataSource( 17 | undefined, 18 | undefined 19 | ); 20 | pagingInfo: any; 21 | fields: any[] = []; 22 | enabledFullScreen = true; 23 | constructor(injector: Injector) { 24 | super(injector); 25 | } 26 | afterModelSet() { 27 | if (this.model.dataSource) { 28 | if (this.model.pageSize) { 29 | this.pagingInfo = { 30 | pageSize: +this.model.pageSize, 31 | }; 32 | } else { 33 | this.pagingInfo = undefined; 34 | } 35 | this.dataSourceService 36 | .dataSourceMetadata(this.model.dataSource) 37 | .subscribe( 38 | (x: any[]) => 39 | (this.fields = x.map((field) => { 40 | return { 41 | name: field.field, 42 | model: field.field, 43 | label: field.title || field.field, 44 | type: field.type, 45 | options: {}, 46 | }; 47 | })) 48 | ); 49 | this.dataSourceService 50 | .dataSourceData(this.model.dataSource) 51 | .subscribe((x) => this.dataSource.setData(x)); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-share/service/narik-dataSource.service.ts: -------------------------------------------------------------------------------- 1 | import { map } from 'rxjs/internal/operators/map'; 2 | import { DataSourceService, DashboardDataSource } from 'dashboard-lib'; 3 | import { Observable } from 'rxjs/internal/Observable'; 4 | import { DataProviderService } from '@narik/infrastructure'; 5 | import { Injectable } from '@angular/core'; 6 | import { BehaviorSubject } from 'rxjs'; 7 | 8 | @Injectable() 9 | export class NarikDataSourceService extends DataSourceService { 10 | dataSources: DashboardDataSource[]; 11 | 12 | isReady: BehaviorSubject = new BehaviorSubject(false); 13 | isReady$ = this.isReady.asObservable().pipe((ready) => ready); 14 | constructor(private dataProvider: DataProviderService) { 15 | super(); 16 | } 17 | 18 | init() { 19 | this.dataProvider 20 | .getData({ 21 | dataKey: 'widgetData', 22 | }) 23 | .subscribe((x: any) => { 24 | this.dataSources = x.dataSources; 25 | this.isReady.next(true); 26 | }); 27 | } 28 | 29 | dataSourceList(): Observable { 30 | return this.isReady$.pipe(map(() => this.dataSources.map((x) => x.key))); 31 | } 32 | dataSourceMetadata(dataSourceKey: string): Observable { 33 | return this.isReady$.pipe( 34 | map( 35 | () => 36 | this.dataSources.filter((x) => x.key === dataSourceKey)[0].metaData 37 | ) 38 | ); 39 | } 40 | dataSourceData(dataSourceKey: string, parameters: any[]): Observable { 41 | return this.isReady$.pipe( 42 | map(() => this.dataSources.filter((x) => x.key === dataSourceKey)[0].data) 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-design/dashboard-design.module.ts: -------------------------------------------------------------------------------- 1 | import { 2 | NarikMatBusyIndicatorModule, 3 | NarikMatToolbarModule, 4 | NarikMatButtonModule, 5 | NarikMatSelectModule, 6 | } from '@narik/ui-material'; 7 | 8 | import { CommonModule } from '@angular/common'; 9 | import { NgModule } from '@angular/core'; 10 | import { DashboardCellComponent } from './dashboard-cell/dashboard-cell.component'; 11 | import { DashboardDesignerComponent } from './dashboard-designer/dashboard-designer.component'; 12 | import { DashboardRowComponent } from './dashboard-row/dashboard-row.component'; 13 | import { DragDropModule } from '@angular/cdk/drag-drop'; 14 | import { TranslateModule } from '@ngx-translate/core'; 15 | import { FormsModule } from '@angular/forms'; 16 | import { SelectWidgetTypeComponent } from './select-widget-type/select-widget-type.component'; 17 | import { NarikCommonModule } from '@narik/common'; 18 | import { MatCardModule } from '@angular/material/card'; 19 | import { MatIconModule } from '@angular/material/icon'; 20 | 21 | @NgModule({ 22 | imports: [ 23 | CommonModule, 24 | FormsModule, 25 | MatCardModule, 26 | MatIconModule, 27 | NarikCommonModule, 28 | NarikMatBusyIndicatorModule, 29 | NarikMatToolbarModule, 30 | NarikMatButtonModule, 31 | NarikMatSelectModule, 32 | TranslateModule, 33 | DragDropModule, 34 | ], 35 | declarations: [ 36 | DashboardDesignerComponent, 37 | DashboardCellComponent, 38 | DashboardRowComponent, 39 | SelectWidgetTypeComponent, 40 | ], 41 | exports: [DashboardDesignerComponent], 42 | providers: [], 43 | }) 44 | export class DashboardDesignModule {} 45 | -------------------------------------------------------------------------------- /src/app/modules/share/share.module.ts: -------------------------------------------------------------------------------- 1 | import { COMPONENTS } from './index'; 2 | import { Injectable, NgModule } from '@angular/core'; 3 | import { NarikUiMaterialModule } from '@narik/ui-material'; 4 | import { CommonModule, DatePipe } from '@angular/common'; 5 | import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 6 | import { MatCardModule } from '@angular/material/card'; 7 | import { 8 | MAT_DATE_FORMATS, 9 | NativeDateAdapter, 10 | DateAdapter, 11 | } from '@angular/material/core'; 12 | 13 | export const PICK_FORMATS = { 14 | parse: { dateInput: { month: 'short', year: 'numeric', day: 'numeric' } }, 15 | display: { 16 | dateInput: 'input', 17 | monthYearLabel: { year: 'numeric', month: 'short' }, 18 | dateA11yLabel: { year: 'numeric', month: 'long', day: 'numeric' }, 19 | monthYearA11yLabel: { year: 'numeric', month: 'long' }, 20 | }, 21 | }; 22 | 23 | @Injectable() 24 | export class PickDateAdapter extends NativeDateAdapter { 25 | format(date: Date, displayFormat: any): string { 26 | if (displayFormat === 'input') { 27 | return new DatePipe('en-US').transform(date, 'yyyy/MM/dd'); 28 | } else { 29 | return super.format(date, displayFormat); 30 | } 31 | } 32 | } 33 | 34 | @NgModule({ 35 | imports: [ 36 | CommonModule, 37 | FormsModule, 38 | ReactiveFormsModule, 39 | NarikUiMaterialModule, 40 | MatCardModule, 41 | ], 42 | declarations: [COMPONENTS], 43 | exports: [], 44 | providers: [ 45 | { provide: DateAdapter, useClass: PickDateAdapter }, 46 | { provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS }, 47 | ], 48 | entryComponents: [COMPONENTS], 49 | }) 50 | export class ShareModule {} 51 | -------------------------------------------------------------------------------- /src/assets/modules/base/tool-bars.json: -------------------------------------------------------------------------------- 1 | { 2 | "editToolBar": { 3 | "key": "editToolBar", 4 | "items": [{ 5 | "key": "new", 6 | "icon": "add", 7 | "shortcut": "control.alt.n" 8 | }, 9 | { 10 | "key": "save", 11 | "disableExpr": "host.config.readOnly", 12 | "shortcut": "control.s" 13 | }, 14 | { 15 | "key": "delete", 16 | "disableExpr": "host.config.readOnly || !host.currentEntity || !host.currentEntity.viewModelId", 17 | "shortcut": "control.d" 18 | }, 19 | { 20 | "key": "close", 21 | "hideExpr": "!host.isInDialog", 22 | "shortcut": "control.x" 23 | } 24 | ] 25 | }, 26 | "listToolBar": { 27 | "key": "listToolBar", 28 | "items": [{ 29 | "key": "new", 30 | "icon": "add", 31 | "disableExpr": "host.config.readOnly", 32 | "shortcut": "control.alt.n" 33 | }, 34 | { 35 | "key": "edit", 36 | "disableExpr": "host.config.readOnly || !host.selectedEntity ", 37 | "shortcut": "control.e" 38 | }, 39 | { 40 | "key": "delete", 41 | "disableExpr": "host.config.readOnly ", 42 | "shortcut": "control.d" 43 | 44 | }, 45 | "-", 46 | { 47 | "key": "refresh", 48 | "shortcut": "control.r" 49 | }, 50 | { 51 | "key": "close", 52 | "hideExpr": "!host.isInDialog", 53 | "shortcut": "control.x" 54 | } 55 | ] 56 | }, 57 | "addRemoveToolBar": { 58 | "key": "addRemoveToolBar", 59 | "items": [{ 60 | "key": "add", 61 | "icon": "add" 62 | }, 63 | { 64 | "key": "delete", 65 | "icon": "delete" 66 | } 67 | ] 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/app/modules/narik-ngx-layout/ngx-view-header/ngx-view-header.component.ts: -------------------------------------------------------------------------------- 1 | import { AuthenticationService } from "@narik/infrastructure"; 2 | import { Component, Input } from "@angular/core"; 3 | import { 4 | NbSidebarService, 5 | NbMenuItem, 6 | NbLayoutDirectionService, 7 | NbLayoutDirection 8 | } from "@nebular/theme"; 9 | import { TranslateService } from "@ngx-translate/core"; 10 | 11 | @Component({ 12 | selector: "ngx-view-header", 13 | styleUrls: ["ngx-view-header.component.scss"], 14 | templateUrl: "ngx-view-header.component.html" 15 | }) 16 | export class NgxHeaderComponent { 17 | @Input() position = "normal"; 18 | @Input() headerTitle = ""; 19 | user: any; 20 | 21 | _fa = false; 22 | 23 | set fa(value: boolean) { 24 | if (this.fa !== value) { 25 | this.nbLayoutDirectionService.setDirection( 26 | value ? NbLayoutDirection.RTL : NbLayoutDirection.LTR 27 | ); 28 | this.translateService.use(value ? "fa" : "en"); 29 | } 30 | this._fa = value; 31 | } 32 | get fa(): boolean { 33 | return this._fa; 34 | } 35 | 36 | userMenu: NbMenuItem[] = [ 37 | { title: "changePass", data: "changePass" }, 38 | { title: "logout", data: "logout" } 39 | ]; 40 | 41 | constructor( 42 | private sidebarService: NbSidebarService, 43 | private nbLayoutDirectionService: NbLayoutDirectionService, 44 | private translateService: TranslateService, 45 | authenticationService: AuthenticationService 46 | ) { 47 | for (const menu of this.userMenu) { 48 | menu.title = translateService.instant(menu.title); 49 | } 50 | this.user = authenticationService.currentUserValue; 51 | } 52 | 53 | toggleSidebar(): boolean { 54 | this.sidebarService.toggle(true, "menu-sidebar"); 55 | 56 | return false; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /projects/dashboard-lib/src/lib/base/widget-design.ts: -------------------------------------------------------------------------------- 1 | import { Directive, Injector, Input, OnInit } from '@angular/core'; 2 | import { isEquivalent } from '@narik/common'; 3 | import { NarikInject } from '@narik/core'; 4 | import { NarikComponent, PARAMETERS } from '@narik/infrastructure'; 5 | import { UUID } from 'angular2-uuid'; 6 | import { DataSourceService } from '../services/dataSource.service'; 7 | import { WidgetModel } from './widget-model'; 8 | 9 | @Directive() 10 | export class WidgetDesign extends NarikComponent implements OnInit { 11 | @NarikInject(DataSourceService) 12 | protected dataSourceService: DataSourceService; 13 | 14 | @NarikInject(PARAMETERS, {}) 15 | parameters: any; 16 | 17 | displayTitle = true; 18 | needDataSource = false; 19 | _model: WidgetModel = {}; 20 | dataSources: any[] = []; 21 | 22 | selectOptions: any = { 23 | showToolbar: false, 24 | }; 25 | 26 | @Input() 27 | set model(value: any) { 28 | const tempModel = this.importModel(value); 29 | if (!isEquivalent(this._model, tempModel)) { 30 | this._model = tempModel; 31 | this.afterModelSet(); 32 | } 33 | } 34 | get model(): any { 35 | if (this._model && !this._model.uniqueId) { 36 | this._model.uniqueId = UUID.UUID(); 37 | } 38 | return this.exportModel(this._model); 39 | } 40 | 41 | constructor(private injector: Injector) { 42 | super(); 43 | if (this.parameters) { 44 | this.model = this.parameters.model; 45 | } 46 | } 47 | 48 | protected importModel(model: any): any { 49 | return model; 50 | } 51 | protected exportModel(model: any): any { 52 | return model; 53 | } 54 | 55 | ngOnInit(): void { 56 | if (this.needDataSource) { 57 | this.dataSourceService.dataSourceList().subscribe( 58 | (x) => 59 | (this.dataSources = x.map((ds) => { 60 | return { 61 | id: ds, 62 | title: ds, 63 | }; 64 | })) 65 | ); 66 | } 67 | } 68 | 69 | afterModelSet() {} 70 | } 71 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-design/dashboard-row/dashboard-row.component.ts: -------------------------------------------------------------------------------- 1 | import { DashboardRow } from "./../../dashboard-share/base/dashboard-row"; 2 | import { 3 | CommandHost, 4 | CommandInfo, 5 | DialogService, 6 | DialogResult 7 | } from "@narik/infrastructure"; 8 | import { 9 | Component, 10 | Input, 11 | OnInit, 12 | HostListener, 13 | Output, 14 | EventEmitter 15 | } from "@angular/core"; 16 | 17 | import { DashboardCell } from "../../dashboard-share/base/dashboard-cell"; 18 | import { Observable } from "rxjs/internal/Observable"; 19 | 20 | @Component({ 21 | selector: "dashboard-row", 22 | templateUrl: "dashboard-row.component.html", 23 | styleUrls: ["dashboard-row.component.css"] 24 | }) 25 | export class DashboardRowComponent implements OnInit, CommandHost { 26 | change$: Observable; 27 | 28 | @Input() 29 | row: DashboardRow = new DashboardRow(); 30 | 31 | @Output() 32 | removeRequest: EventEmitter = new EventEmitter(); 33 | 34 | isMouseOver = false; 35 | 36 | constructor(private dialogService: DialogService) {} 37 | 38 | ngOnInit() {} 39 | 40 | processCommand(cmd: CommandInfo) { 41 | if (cmd.commandKey === "add") { 42 | const sumSize = this.row.cells 43 | .map(c => c.size) 44 | .reduce((a, b) => a + b, 0); 45 | if (sumSize < 12) { 46 | this.row.cells.push(new DashboardCell(12 - sumSize)); 47 | } else { 48 | this.dialogService.error("dashboard.row-size-is-full"); 49 | } 50 | } else if (cmd.commandKey === "remove") { 51 | this.dialogService 52 | .showConfirm("dashboard.confirm-remove-row", "Confirm") 53 | .closed.then((result: DialogResult) => { 54 | if (result.dialogResult === "yes") { 55 | this.removeRequest.emit(this.row); 56 | } 57 | }); 58 | } 59 | } 60 | 61 | removeCell(cell) { 62 | if (this.row.cells.length > 1) { 63 | const pos = this.row.cells.indexOf(cell); 64 | if (pos >= 0) { 65 | this.row.cells.splice(pos, 1); 66 | } 67 | } else { 68 | this.dialogService.error("dashboard.row-cell-could-not-empty"); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint:recommended", 3 | "rules": { 4 | "array-type": false, 5 | "arrow-parens": false, 6 | "deprecation": { 7 | "severity": "warn" 8 | }, 9 | "component-class-suffix": true, 10 | "contextual-lifecycle": true, 11 | "directive-class-suffix": true, 12 | "directive-selector": [ 13 | true, 14 | "attribute", 15 | "app", 16 | "camelCase" 17 | ], 18 | "component-selector": [ 19 | true, 20 | "element", 21 | "app", 22 | "kebab-case" 23 | ], 24 | "import-blacklist": [ 25 | true, 26 | "rxjs/Rx" 27 | ], 28 | "interface-name": false, 29 | "max-classes-per-file": false, 30 | "max-line-length": [ 31 | true, 32 | 140 33 | ], 34 | "member-access": false, 35 | "member-ordering": [ 36 | true, 37 | { 38 | "order": [ 39 | "static-field", 40 | "instance-field", 41 | "static-method", 42 | "instance-method" 43 | ] 44 | } 45 | ], 46 | "no-consecutive-blank-lines": false, 47 | "no-console": [ 48 | true, 49 | "debug", 50 | "info", 51 | "time", 52 | "timeEnd", 53 | "trace" 54 | ], 55 | "no-empty": false, 56 | "no-inferrable-types": [ 57 | true, 58 | "ignore-params" 59 | ], 60 | "no-non-null-assertion": true, 61 | "no-redundant-jsdoc": true, 62 | "no-switch-case-fall-through": true, 63 | "no-use-before-declare": true, 64 | "no-var-requires": false, 65 | "object-literal-key-quotes": [ 66 | true, 67 | "as-needed" 68 | ], 69 | "object-literal-sort-keys": false, 70 | "ordered-imports": false, 71 | "quotemark": [ 72 | true, 73 | "single" 74 | ], 75 | "trailing-comma": false, 76 | "no-conflicting-lifecycle": true, 77 | "no-host-metadata-property": true, 78 | "no-input-rename": true, 79 | "no-inputs-metadata-property": true, 80 | "no-output-native": true, 81 | "no-output-on-prefix": true, 82 | "no-output-rename": true, 83 | "no-outputs-metadata-property": true, 84 | "template-banana-in-box": true, 85 | "template-no-negated-async": true, 86 | "use-lifecycle-interface": true, 87 | "use-pipe-transform-interface": true 88 | }, 89 | "rulesDirectory": [ 90 | "codelyzer" 91 | ] 92 | } 93 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-view/dashboard-viewer/dashboard-viewer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, OnInit, ViewChild, ElementRef } from '@angular/core'; 2 | 3 | import { DashboardRow } from '../../dashboard-share/base/dashboard-row'; 4 | import { CommandHost, CommandInfo } from '@narik/infrastructure'; 5 | import { Observable } from 'rxjs/internal/Observable'; 6 | import { PluginService } from '../../dashboard-share/service/plugin.service'; 7 | import { WidgetViewType } from '../../dashboard-share/base/widget-view-type'; 8 | 9 | @Component({ 10 | selector: 'dashboard-viewer', 11 | templateUrl: 'dashboard-viewer.component.html', 12 | styleUrls: ['dashboard-viewer.component.css'], 13 | }) 14 | export class DashboardViewerComponent implements OnInit, CommandHost { 15 | change$: Observable; 16 | 17 | @Input() 18 | showToolbar = true; 19 | 20 | @ViewChild('importFile', { static: false }) 21 | importFile: ElementRef; 22 | 23 | _rows: DashboardRow[] = []; 24 | @Input() 25 | set rows(value: DashboardRow[]) { 26 | if (value) { 27 | this.applyComponentTypes(value); 28 | } 29 | this._rows = value; 30 | } 31 | get rows(): DashboardRow[] { 32 | return this._rows; 33 | } 34 | 35 | constructor(private dashboardService: PluginService) {} 36 | 37 | ngOnInit() {} 38 | 39 | processCommand(cmd: CommandInfo) { 40 | if (cmd.commandKey === 'import') { 41 | this.importFile.nativeElement.click(); 42 | } 43 | } 44 | 45 | import(e) { 46 | if (e.target.files[0]) { 47 | const that = this; 48 | const reader = new FileReader(); 49 | reader.readAsText(e.target.files[0], 'UTF-8'); 50 | reader.onload = (evt) => { 51 | const newModel = JSON.parse((evt.target as any).result) 52 | .rows as DashboardRow[]; 53 | 54 | this.rows = newModel; 55 | }; 56 | reader.onerror = (evt) => {}; 57 | } 58 | } 59 | applyComponentTypes(rows: DashboardRow[]) { 60 | for (const row of rows) { 61 | for (const cell of row.cells) { 62 | if (cell.widgetInfo && cell.widgetInfo.widgetTypeKey) { 63 | this.dashboardService 64 | .widgetComponentType( 65 | undefined, 66 | cell.widgetInfo.widgetTypeKey, 67 | WidgetViewType.View 68 | ) 69 | .then((type) => { 70 | cell.widgetInfo.widgetType = type; 71 | }); 72 | } 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /projects/dashboard-lib/src/lib/base/widget-view.ts: -------------------------------------------------------------------------------- 1 | import { Directive, ElementRef, Injector, Input, OnInit } from '@angular/core'; 2 | import { isEquivalent } from '@narik/common'; 3 | import { NarikInject } from '@narik/core'; 4 | import { NarikComponent } from '@narik/infrastructure'; 5 | import { fromEvent, Subject } from 'rxjs'; 6 | import { debounceTime } from 'rxjs/internal/operators/debounceTime'; 7 | import { distinctUntilChanged } from 'rxjs/internal/operators/distinctUntilChanged'; 8 | import { takeWhile } from 'rxjs/internal/operators/takeWhile'; 9 | import { DataSourceService } from '../services/dataSource.service'; 10 | import { WidgetModel } from './widget-model'; 11 | 12 | @Directive() 13 | export class WidgetView extends NarikComponent implements OnInit { 14 | isFullScreen = false; 15 | enabledFullScreen = false; 16 | displayTitle = true; 17 | _model: WidgetModel = {}; 18 | _size: number; 19 | @NarikInject(DataSourceService) 20 | protected dataSourceService: DataSourceService; 21 | 22 | @NarikInject(ElementRef) 23 | protected elementRef: ElementRef; 24 | 25 | private sizeChangedSubject = new Subject(); 26 | 27 | set size(value: number) { 28 | if (this._size && this._size !== value) { 29 | this.sizeChangedSubject.next(value); 30 | } 31 | this._size = value; 32 | } 33 | get size(): number { 34 | return this._size; 35 | } 36 | 37 | @Input() 38 | set model(value: any) { 39 | const tepModel = this.importModel(value); 40 | if (!isEquivalent(this._model, tepModel)) { 41 | this._model = tepModel; 42 | this.afterModelSet(); 43 | } 44 | } 45 | get model(): any { 46 | return this._model; 47 | } 48 | 49 | protected importModel(model: any): any { 50 | return model; 51 | } 52 | 53 | constructor(private injector: Injector) { 54 | super(); 55 | this.sizeChangedSubject 56 | .pipe( 57 | debounceTime(200), 58 | distinctUntilChanged(), 59 | takeWhile(() => this.isAlive) 60 | ) 61 | .subscribe((size) => { 62 | this.doOnResize(size); 63 | }); 64 | } 65 | 66 | ngOnInit(): void { 67 | if (this.enabledFullScreen) { 68 | fromEvent(this.elementRef.nativeElement, 'fullscreenchange') 69 | .pipe(takeWhile(() => this.isAlive)) 70 | .subscribe((x: any) => { 71 | this.isFullScreen = !!document.fullscreenElement; 72 | }); 73 | } 74 | } 75 | 76 | afterModelSet() {} 77 | 78 | toggleFullScreen() { 79 | if (this.enabledFullScreen) { 80 | if (this.isFullScreen) { 81 | document.exitFullscreen(); 82 | } else { 83 | const elem = this.elementRef.nativeElement; 84 | const methodToBeInvoked = 85 | elem.requestFullscreen || 86 | elem.webkitRequestFullScreen || 87 | elem['mozRequestFullscreen'] || 88 | elem['msRequestFullscreen']; 89 | if (methodToBeInvoked) { 90 | methodToBeInvoked.call(elem); 91 | } 92 | } 93 | } 94 | } 95 | 96 | doOnResize(newSize: number) {} 97 | } 98 | -------------------------------------------------------------------------------- /plugins/kpi/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE11 requires the following for NgClass support on SVG elements */ 22 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 23 | 24 | /** 25 | * Web Animations `@angular/platform-browser/animations` 26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 28 | */ 29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 30 | 31 | /** 32 | * By default, zone.js will patch all possible macroTask and DomEvents 33 | * user can disable parts of macroTask/DomEvents patch by setting following flags 34 | * because those flags need to be set before `zone.js` being loaded, and webpack 35 | * will put import in the top of bundle, so user need to create a separate file 36 | * in this directory (for example: zone-flags.ts), and put the following flags 37 | * into that file, and then add the following code before importing zone.js. 38 | * import './zone-flags'; 39 | * 40 | * The flags allowed in zone-flags.ts are listed here. 41 | * 42 | * The following flags will work for all browsers. 43 | * 44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 46 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 47 | * 48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 50 | * 51 | * (window as any).__Zone_enable_cross_context_check = true; 52 | * 53 | */ 54 | 55 | /*************************************************************************************************** 56 | * Zone JS is required by default for Angular itself. 57 | */ 58 | import 'zone.js/dist/zone'; // Included with Angular CLI. 59 | 60 | 61 | /*************************************************************************************************** 62 | * APPLICATION IMPORTS 63 | */ 64 | -------------------------------------------------------------------------------- /plugins/link/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE11 requires the following for NgClass support on SVG elements */ 22 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 23 | 24 | /** 25 | * Web Animations `@angular/platform-browser/animations` 26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 28 | */ 29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 30 | 31 | /** 32 | * By default, zone.js will patch all possible macroTask and DomEvents 33 | * user can disable parts of macroTask/DomEvents patch by setting following flags 34 | * because those flags need to be set before `zone.js` being loaded, and webpack 35 | * will put import in the top of bundle, so user need to create a separate file 36 | * in this directory (for example: zone-flags.ts), and put the following flags 37 | * into that file, and then add the following code before importing zone.js. 38 | * import './zone-flags'; 39 | * 40 | * The flags allowed in zone-flags.ts are listed here. 41 | * 42 | * The following flags will work for all browsers. 43 | * 44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 46 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 47 | * 48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 50 | * 51 | * (window as any).__Zone_enable_cross_context_check = true; 52 | * 53 | */ 54 | 55 | /*************************************************************************************************** 56 | * Zone JS is required by default for Angular itself. 57 | */ 58 | import 'zone.js/dist/zone'; // Included with Angular CLI. 59 | 60 | 61 | /*************************************************************************************************** 62 | * APPLICATION IMPORTS 63 | */ 64 | -------------------------------------------------------------------------------- /plugins/todo/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE11 requires the following for NgClass support on SVG elements */ 22 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 23 | 24 | /** 25 | * Web Animations `@angular/platform-browser/animations` 26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 28 | */ 29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 30 | 31 | /** 32 | * By default, zone.js will patch all possible macroTask and DomEvents 33 | * user can disable parts of macroTask/DomEvents patch by setting following flags 34 | * because those flags need to be set before `zone.js` being loaded, and webpack 35 | * will put import in the top of bundle, so user need to create a separate file 36 | * in this directory (for example: zone-flags.ts), and put the following flags 37 | * into that file, and then add the following code before importing zone.js. 38 | * import './zone-flags'; 39 | * 40 | * The flags allowed in zone-flags.ts are listed here. 41 | * 42 | * The following flags will work for all browsers. 43 | * 44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 46 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 47 | * 48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 50 | * 51 | * (window as any).__Zone_enable_cross_context_check = true; 52 | * 53 | */ 54 | 55 | /*************************************************************************************************** 56 | * Zone JS is required by default for Angular itself. 57 | */ 58 | import 'zone.js/dist/zone'; // Included with Angular CLI. 59 | 60 | 61 | /*************************************************************************************************** 62 | * APPLICATION IMPORTS 63 | */ 64 | -------------------------------------------------------------------------------- /src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 22 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 23 | 24 | /** 25 | * Web Animations `@angular/platform-browser/animations` 26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 28 | */ 29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 30 | 31 | /** 32 | * By default, zone.js will patch all possible macroTask and DomEvents 33 | * user can disable parts of macroTask/DomEvents patch by setting following flags 34 | * because those flags need to be set before `zone.js` being loaded, and webpack 35 | * will put import in the top of bundle, so user need to create a separate file 36 | * in this directory (for example: zone-flags.ts), and put the following flags 37 | * into that file, and then add the following code before importing zone.js. 38 | * import './zone-flags.ts'; 39 | * 40 | * The flags allowed in zone-flags.ts are listed here. 41 | * 42 | * The following flags will work for all browsers. 43 | * 44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 46 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 47 | * 48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 50 | * 51 | * (window as any).__Zone_enable_cross_context_check = true; 52 | * 53 | */ 54 | 55 | /*************************************************************************************************** 56 | * Zone JS is required by default for Angular itself. 57 | */ 58 | import 'zone.js/dist/zone'; // Included with Angular CLI. 59 | 60 | 61 | /*************************************************************************************************** 62 | * APPLICATION IMPORTS 63 | */ 64 | -------------------------------------------------------------------------------- /plugins/data-table/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE11 requires the following for NgClass support on SVG elements */ 22 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 23 | 24 | /** 25 | * Web Animations `@angular/platform-browser/animations` 26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 28 | */ 29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 30 | 31 | /** 32 | * By default, zone.js will patch all possible macroTask and DomEvents 33 | * user can disable parts of macroTask/DomEvents patch by setting following flags 34 | * because those flags need to be set before `zone.js` being loaded, and webpack 35 | * will put import in the top of bundle, so user need to create a separate file 36 | * in this directory (for example: zone-flags.ts), and put the following flags 37 | * into that file, and then add the following code before importing zone.js. 38 | * import './zone-flags'; 39 | * 40 | * The flags allowed in zone-flags.ts are listed here. 41 | * 42 | * The following flags will work for all browsers. 43 | * 44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 46 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 47 | * 48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 50 | * 51 | * (window as any).__Zone_enable_cross_context_check = true; 52 | * 53 | */ 54 | 55 | /*************************************************************************************************** 56 | * Zone JS is required by default for Angular itself. 57 | */ 58 | import 'zone.js/dist/zone'; // Included with Angular CLI. 59 | 60 | 61 | /*************************************************************************************************** 62 | * APPLICATION IMPORTS 63 | */ 64 | -------------------------------------------------------------------------------- /plugins/date-time/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE11 requires the following for NgClass support on SVG elements */ 22 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 23 | 24 | /** 25 | * Web Animations `@angular/platform-browser/animations` 26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 28 | */ 29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 30 | 31 | /** 32 | * By default, zone.js will patch all possible macroTask and DomEvents 33 | * user can disable parts of macroTask/DomEvents patch by setting following flags 34 | * because those flags need to be set before `zone.js` being loaded, and webpack 35 | * will put import in the top of bundle, so user need to create a separate file 36 | * in this directory (for example: zone-flags.ts), and put the following flags 37 | * into that file, and then add the following code before importing zone.js. 38 | * import './zone-flags'; 39 | * 40 | * The flags allowed in zone-flags.ts are listed here. 41 | * 42 | * The following flags will work for all browsers. 43 | * 44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 46 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 47 | * 48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 50 | * 51 | * (window as any).__Zone_enable_cross_context_check = true; 52 | * 53 | */ 54 | 55 | /*************************************************************************************************** 56 | * Zone JS is required by default for Angular itself. 57 | */ 58 | import 'zone.js/dist/zone'; // Included with Angular CLI. 59 | 60 | 61 | /*************************************************************************************************** 62 | * APPLICATION IMPORTS 63 | */ 64 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "narik-dashboard", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "test": "ng test", 9 | "lint": "ng lint", 10 | "e2e": "ng e2e", 11 | "build:shared": "ng build dashboard-lib", 12 | "build:plugins": "ng build todo && ng build kpi && ng build link && ng build chart && ng build date-time && ng build data-table " 13 | }, 14 | "private": true, 15 | "dependencies": { 16 | "@angular/animations": "^12.2.1", 17 | "@angular/cdk": "^12.2.1", 18 | "@angular/common": "^12.2.1", 19 | "@angular/compiler": "^12.2.1", 20 | "@angular/core": "^12.2.1", 21 | "@angular/flex-layout": "~12.0.0-beta.34", 22 | "@angular/forms": "^12.2.1", 23 | "@angular/material": "^12.2.1", 24 | "@angular/platform-browser": "^12.2.1", 25 | "@angular/platform-browser-dynamic": "^12.2.1", 26 | "@angular/router": "^12.2.1", 27 | "@aspnet/signalr": "^1.1.4", 28 | "@fortawesome/fontawesome-free": "^5.15.4", 29 | "@narik/app-core": "^6.0.1", 30 | "@narik/client-storage": "^6.0.1", 31 | "@narik/common": "^6.0.1", 32 | "@narik/core": "^6.0.1", 33 | "@narik/custom-validators": "^6.0.2", 34 | "@narik/infrastructure": "^6.0.1", 35 | "@narik/jwt-authentication": "^6.0.1", 36 | "@narik/ui-core": "^6.0.1", 37 | "@narik/ui-material": "^6.0.1", 38 | "@nebular/eva-icons": "8.0.0", 39 | "@nebular/theme": "8.0.0", 40 | "@ngx-translate/core": "^13.0.0", 41 | "@swimlane/ngx-charts": "^18.0.1", 42 | "angular-pipes": "^10.0.0", 43 | "angular2-text-mask": "^9.0.0", 44 | "angular2-uuid": "^1.1.1", 45 | "bootstrap": "^5.1.0", 46 | "class-validator": "^0.13.1", 47 | "data-adapter": "^0.2.3", 48 | "date-fns": "^2.23.0", 49 | "eva-icons": "^1.1.3", 50 | "file-saver": "^2.0.5", 51 | "localforage": "^1.9.0", 52 | "lodash-es": "^4.17.21", 53 | "ngforage": "^6.0.0", 54 | "ngx-custom-validators": "^11.0.1", 55 | "ngx-date-fns": "^8.2.0", 56 | "ngx-toastr": "^14.1.0", 57 | "roboto-fontface": "^0.10.0", 58 | "rxjs": "~7.3.0", 59 | "tslib": "^2.3.1", 60 | "typeface-exo": "^1.1.13", 61 | "zone.js": "~0.11.4" 62 | }, 63 | "devDependencies": { 64 | "@angular-architects/module-federation": "^12.4.0", 65 | "@angular-builders/custom-webpack": "~12.1.0", 66 | "@angular-devkit/build-angular": "~12.2.1", 67 | "@angular/cli": "~12.2.1", 68 | "@angular/compiler-cli": "^12.2.1", 69 | "@angular/language-service": "^12.2.1", 70 | "@narik/webpack-tools": "4.1.0", 71 | "@types/jasmine": "~3.8.2", 72 | "@types/jasminewd2": "~2.0.10", 73 | "@types/node": "^16.6.0", 74 | "cheerio": "^1.0.0-rc.10", 75 | "codelyzer": "^6.0.2", 76 | "jasmine-core": "~3.8.0", 77 | "jasmine-spec-reporter": "~7.0.0", 78 | "karma": "~6.3.4", 79 | "karma-chrome-launcher": "~3.1.0", 80 | "karma-coverage-istanbul-reporter": "~3.0.3", 81 | "karma-jasmine": "~4.0.1", 82 | "karma-jasmine-html-reporter": "^1.7.0", 83 | "ng-packagr": "^12.2.0", 84 | "protractor": "~7.0.0", 85 | "ts-node": "~10.2.0", 86 | "tslint": "~6.1.3", 87 | "typescript": "~4.3.5" 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/styles/styles.scss: -------------------------------------------------------------------------------- 1 | @import '~@nebular/theme/styles/prebuilt/default.css'; 2 | @import '~@angular/material/prebuilt-themes/indigo-pink.css'; 3 | @import './dashboard-designer'; 4 | @import './dashboard-viewer'; 5 | 6 | #toast-container > div { 7 | opacity: 1; 8 | } 9 | 10 | [dir='rtl'] .layout-container nb-sidebar.left { 11 | order: initial !important; 12 | } 13 | 14 | nb-layout-header.fixed { 15 | z-index: 1000 !important; 16 | } 17 | 18 | .mat-form-field-label { 19 | height: 30px; 20 | } 21 | 22 | .mat-form-field-infix { 23 | width: initial !important; 24 | } 25 | 26 | narik-button { 27 | cursor: pointer; 28 | } 29 | 30 | .cursor-pointer { 31 | cursor: pointer; 32 | } 33 | 34 | a:hover { 35 | color: #0056b3; 36 | text-decoration: none; 37 | } 38 | 39 | narik-checkbox { 40 | display: block; 41 | } 42 | 43 | .widget-full-screen { 44 | height: 100vh; 45 | background-color: #fff; 46 | } 47 | 48 | [dir='rtl'] .toolbar-btn { 49 | margin-right: 0.2rem !important; 50 | margin-left: initial !important; 51 | } 52 | 53 | [dir='rtl'] .toolbar-btn:first-child { 54 | margin-right: 0 !important; 55 | margin-left: initial !important; 56 | } 57 | 58 | [dir='rtl'] .mat-toolbar > .mat-divider-vertical { 59 | margin-right: 8px !important; 60 | margin-left: 4px !important; 61 | } 62 | 63 | [dir='rtl'] .narik-mat-table-select-arrow-wrapper { 64 | right: initial; 65 | left: 0; 66 | } 67 | 68 | [dir='rtl'] .nb-theme-default nb-layout .layout { 69 | font-family: Tahoma, Geneva, Verdana, sans-serif !important; 70 | } 71 | 72 | [dir='rtl'] .nb-theme-default nb-layout-header { 73 | font-family: Tahoma, Geneva, Verdana, sans-serif !important; 74 | } 75 | 76 | [dir='rtl'] .nb-theme-default nb-sidebar { 77 | font-family: Tahoma, Geneva, Verdana, sans-serif !important; 78 | } 79 | 80 | [dir='rtl'] .nb-theme-default nb-card { 81 | font-family: Tahoma, Geneva, Verdana, sans-serif !important; 82 | } 83 | 84 | [dir='rtl'] .nb-theme-default nb-card-header { 85 | font-family: Tahoma, Geneva, Verdana, sans-serif !important; 86 | } 87 | 88 | [dir='rtl'] .mat-card { 89 | font-family: Tahoma, Geneva, Verdana, sans-serif !important; 90 | } 91 | 92 | [dir='rtl'] .mat-form-field { 93 | font-family: Tahoma, Geneva, Verdana, sans-serif !important; 94 | } 95 | 96 | [dir='rtl'] .mat-table { 97 | font-family: Tahoma, Geneva, Verdana, sans-serif !important; 98 | } 99 | 100 | [dir='rtl'] .mat-tooltip { 101 | font-family: Tahoma, Geneva, Verdana, sans-serif !important; 102 | } 103 | 104 | [dir='rtl'] .nb-theme-default h5, 105 | .nb-theme-default .h5, 106 | .nb-theme-default h4, 107 | .nb-theme-default .h4 { 108 | font-family: Tahoma, Geneva, Verdana, sans-serif !important; 109 | } 110 | 111 | [dir='rtl'] .mat-checkbox { 112 | font-family: Tahoma, Geneva, Verdana, sans-serif !important; 113 | } 114 | 115 | [dir='rtl'] .nb-theme-default li { 116 | font-family: Tahoma, Geneva, Verdana, sans-serif !important; 117 | } 118 | 119 | [dir='rtl'] .nb-theme-default nb-menu .menu-group, 120 | .nb-theme-default nb-menu .menu-item a { 121 | font-family: Tahoma, Geneva, Verdana, sans-serif !important; 122 | } 123 | 124 | [dir='rtl'] .mat-button, 125 | .mat-raised-button, 126 | .mat-icon-button, 127 | .mat-stroked-button, 128 | .mat-flat-button, 129 | .mat-fab, 130 | .mat-mini-fab { 131 | font-family: Tahoma, Geneva, Verdana, sans-serif !important; 132 | } 133 | 134 | .designer-root { 135 | min-width: 300px; 136 | } 137 | -------------------------------------------------------------------------------- /plugins/chart/src/app/viewer/viewer.component.scss: -------------------------------------------------------------------------------- 1 | .dark { 2 | /** 3 | * Backgrounds 4 | */ 5 | $color-bg-darkest: #13141b; 6 | $color-bg-darker: #1b1e27; 7 | $color-bg-dark: #232837; 8 | $color-bg-med: #2f3646; 9 | $color-bg-light: #455066; 10 | $color-bg-lighter: #5b6882; 11 | 12 | /** 13 | * Text 14 | */ 15 | $color-text-dark: #72809b; 16 | $color-text-med-dark: #919db5; 17 | $color-text-med: #A0AABE; 18 | $color-text-med-light: #d9dce1; 19 | $color-text-light: #f0f1f6; 20 | $color-text-lighter: #fff; 21 | 22 | background: $color-bg-darker; 23 | 24 | .ngx-charts { 25 | 26 | text { 27 | fill: $color-text-med; 28 | } 29 | 30 | .tooltip-anchor { 31 | fill: rgb(255,255,255); 32 | } 33 | 34 | .gridline-path { 35 | stroke: $color-bg-med; 36 | } 37 | 38 | .refline-path { 39 | stroke: $color-bg-light; 40 | } 41 | 42 | .reference-area { 43 | fill: #fff; 44 | } 45 | 46 | .grid-panel { 47 | &.odd { 48 | rect { 49 | fill: rgba(255,255,255,0.05); 50 | } 51 | } 52 | } 53 | 54 | .force-directed-graph { 55 | .edge { 56 | stroke: $color-bg-light; 57 | } 58 | } 59 | 60 | .number-card { 61 | p { 62 | color: $color-text-light; 63 | } 64 | } 65 | 66 | .gauge { 67 | .background-arc{ 68 | path { 69 | fill: $color-bg-med; 70 | } 71 | } 72 | 73 | .gauge-tick { 74 | path { 75 | stroke: $color-text-med; 76 | } 77 | text { 78 | fill: $color-text-med; 79 | } 80 | } 81 | } 82 | 83 | .linear-gauge { 84 | .background-bar { 85 | path { 86 | fill: $color-bg-med; 87 | } 88 | } 89 | 90 | .units { 91 | fill: $color-text-dark; 92 | } 93 | } 94 | 95 | .timeline { 96 | .brush-background { 97 | fill: rgba(255,255,255,0.05); 98 | } 99 | 100 | .brush { 101 | .selection { 102 | fill: rgba(255, 255, 255, 0.1); 103 | stroke: #aaa; 104 | } 105 | } 106 | } 107 | 108 | .polar-chart .polar-chart-background { 109 | fill: rgb(30, 34, 46); 110 | } 111 | 112 | } 113 | 114 | .chart-legend { 115 | .legend-labels { 116 | background: rgba(255,255,255,0.05) !important; 117 | } 118 | 119 | .legend-item { 120 | &:hover { 121 | color: #fff; 122 | } 123 | } 124 | 125 | .legend-label { 126 | &:hover { 127 | color: #fff !important; 128 | } 129 | 130 | .active { 131 | .legend-label-text { 132 | color: #fff !important; 133 | } 134 | } 135 | } 136 | 137 | .scale-legend-label { 138 | color: $color-text-med; 139 | } 140 | } 141 | 142 | .advanced-pie-legend { 143 | color: $color-text-med; 144 | 145 | .legend-item { 146 | &:hover { 147 | color: #fff !important; 148 | } 149 | } 150 | } 151 | 152 | .number-card .number-card-label { 153 | font-size: 0.8em; 154 | color: $color-text-med; 155 | } 156 | 157 | } 158 | 159 | .full-screen-chart{ 160 | height: 90vh !important; 161 | } 162 | -------------------------------------------------------------------------------- /plugins/chart/src/app/designer/designer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Injector, NgModule, OnInit } from '@angular/core'; 2 | import { FormsModule } from '@angular/forms'; 3 | import { MatFormFieldModule } from '@angular/material/form-field'; 4 | import { MatIconModule } from '@angular/material/icon'; 5 | import { MatSelectModule } from '@angular/material/select'; 6 | import { MatTabsModule } from '@angular/material/tabs'; 7 | import { BrowserModule } from '@angular/platform-browser'; 8 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 9 | import { toDtoArray } from '@narik/common'; 10 | import { 11 | NarikMatCheckBoxModule, 12 | NarikMatInputModule, 13 | NarikMatSelectModule, 14 | } from '@narik/ui-material'; 15 | import { TranslateModule } from '@ngx-translate/core'; 16 | import { colorSets } from '@swimlane/ngx-charts'; 17 | import { WidgetDesign } from 'dashboard-lib'; 18 | import chartGroups from './chartTypes'; 19 | 20 | @Component({ 21 | templateUrl: './designer.component.html', 22 | styles: [ 23 | ` 24 | .flex-container { 25 | display: flex; 26 | flex-direction: column; 27 | } 28 | `, 29 | ], 30 | }) 31 | export class ChartDesignComponent extends WidgetDesign implements OnInit { 32 | chartGroups: any[] = []; 33 | 34 | charts: any[] = []; 35 | needDataSource = true; 36 | chart: any = { options: [] }; 37 | 38 | curves = toDtoArray([ 39 | 'Basis', 40 | 'Bundle', 41 | 'Cardinal', 42 | 'Catmull Rom', 43 | 'Linear', 44 | 'Monotone X', 45 | 'Monotone Y', 46 | 'Natural', 47 | 'Step', 48 | 'Step After', 49 | 'Step Before', 50 | ]); 51 | 52 | closedCurves = toDtoArray([ 53 | 'Basis Closed', 54 | 'Cardinal Closed', 55 | 'Catmull Rom Closed', 56 | 'Linear Closed', 57 | ]); 58 | 59 | themes: any[] = [ 60 | { 61 | id: 'dark', 62 | title: 'Dark', 63 | }, 64 | { 65 | id: 'light', 66 | title: 'Light', 67 | }, 68 | ]; 69 | legendPositions: any[] = [ 70 | { 71 | id: 'right', 72 | title: 'Right', 73 | }, 74 | { 75 | id: 'below', 76 | title: 'Below', 77 | }, 78 | ]; 79 | schemeTypes: any[] = [ 80 | { 81 | id: 'ordinal', 82 | title: 'Ordinal', 83 | }, 84 | { 85 | id: 'linear', 86 | title: 'Linear', 87 | }, 88 | ]; 89 | 90 | colorSchemes: any[] = colorSets.map((x) => { 91 | return { 92 | id: x.name, 93 | title: x.name, 94 | }; 95 | }); 96 | 97 | constructor(injector: Injector) { 98 | super(injector); 99 | this.chartGroups = chartGroups; 100 | this.charts = Array.prototype.concat.apply( 101 | [], 102 | chartGroups.map((g) => g.charts) 103 | ); 104 | } 105 | 106 | afterModelSet() { 107 | this.chartGroups = chartGroups; 108 | if (this.model && this.model.chartType) { 109 | this.selectChart(this.model.chartType); 110 | } 111 | } 112 | selectChart(chartSelector) { 113 | for (const group of this.chartGroups) { 114 | this.chart = group.charts.find((x) => x.selector === chartSelector); 115 | if (this.chart) { 116 | break; 117 | } 118 | } 119 | } 120 | } 121 | 122 | @NgModule({ 123 | declarations: [ChartDesignComponent], 124 | imports: [ 125 | BrowserModule, 126 | BrowserAnimationsModule, 127 | FormsModule, 128 | MatTabsModule, 129 | MatFormFieldModule, 130 | NarikMatSelectModule, 131 | NarikMatInputModule, 132 | MatSelectModule, 133 | NarikMatCheckBoxModule, 134 | MatIconModule, 135 | TranslateModule, 136 | ], 137 | providers: [], 138 | bootstrap: [], 139 | }) 140 | export class DesignerModule {} 141 | -------------------------------------------------------------------------------- /src/app/modules/narik-ngx-layout/ngx-main-view/ngx-main-view.component.ts: -------------------------------------------------------------------------------- 1 | import { NarikTranslateService } from "@narik/core"; 2 | import { NarikComponent } from "@narik/infrastructure"; 3 | import { filter } from "rxjs/internal/operators/filter"; 4 | import { map } from "rxjs/internal/operators/map"; 5 | 6 | import { Component, Input, OnInit } from "@angular/core"; 7 | import { Title } from "@angular/platform-browser"; 8 | import { ActivatedRoute, NavigationEnd, Router } from "@angular/router"; 9 | import { NbMenuItem } from "@nebular/theme"; 10 | import { takeWhile } from "rxjs/internal/operators/takeWhile"; 11 | 12 | @Component({ 13 | selector: "main-view", 14 | templateUrl: "ngx-main-view.component.html", 15 | styleUrls: ["ngx-main-view.component.scss"] 16 | }) 17 | export class NgxMainViewComponent extends NarikComponent implements OnInit { 18 | _menuItems: NbMenuItem[]; 19 | title: string; 20 | 21 | @Input() 22 | showOnlyRouter = false; 23 | _translateMenu = true; 24 | set translateMenu(value: boolean) { 25 | this._translateMenu = value; 26 | } 27 | get translateMenu(): boolean { 28 | return this._translateMenu; 29 | } 30 | 31 | @Input() 32 | set menuItems(value: NbMenuItem[]) { 33 | this._menuItems = value; 34 | } 35 | get menuItems(): NbMenuItem[] { 36 | return this._menuItems; 37 | } 38 | 39 | @Input() headerTitle = ""; 40 | @Input() menuHeader = ""; 41 | 42 | constructor( 43 | private translateService: NarikTranslateService, 44 | router: Router, 45 | activatedRoute: ActivatedRoute, 46 | private titleService: Title 47 | ) { 48 | super(); 49 | router.events 50 | .pipe( 51 | filter(event => event instanceof NavigationEnd), 52 | map(() => { 53 | let route = activatedRoute; 54 | while (route.firstChild) { 55 | route = route.firstChild; 56 | } 57 | return route; 58 | }), 59 | filter(route => route.outlet === "primary"), 60 | takeWhile(x => this.isAlive) 61 | ) 62 | .subscribe(ar => { 63 | const title = 64 | (ar.snapshot.data && ar.snapshot.data.title) || 65 | (ar.snapshot.url[0] && ar.snapshot.url[0].path); 66 | if (title) { 67 | this.title = this.translateService.instant(this.getFirst(title)); 68 | this.titleService.setTitle(this.title); 69 | } 70 | }); 71 | 72 | router.events 73 | .pipe( 74 | filter(event => event instanceof NavigationEnd), 75 | map(() => { 76 | let route = activatedRoute; 77 | while (route.firstChild) { 78 | route = route.firstChild; 79 | } 80 | return route; 81 | }), 82 | takeWhile(x => this.isAlive) 83 | ) 84 | .subscribe(ar => { 85 | if (ar.snapshot.data && ar.snapshot.data.showOnlyRouter === true) { 86 | this.showOnlyRouter = true; 87 | } else { 88 | this.showOnlyRouter = false; 89 | } 90 | }); 91 | } 92 | 93 | getFirst(title: string): string { 94 | return title ? title.split("-")[0] : ""; 95 | } 96 | ngOnInit() { 97 | if (this.menuItems && this.translateMenu) { 98 | this.translateMenuTitles(this.menuItems); 99 | 100 | (this.translateService as any).translateService.onLangChange.subscribe( 101 | event => this.translateMenuTitles(this.menuItems) 102 | ); 103 | } 104 | } 105 | 106 | translateMenuTitles(menuItems) { 107 | for (const item of menuItems) { 108 | if (!item.key) { 109 | item.key = item.title; 110 | } 111 | item.title = this.translateService.instant(item.key); 112 | if (item.children) { 113 | this.translateMenuTitles(item.children); 114 | } 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/assets/i18n/en/dashboard.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboard": { 3 | "dashboard": "Dashboard", 4 | "dashboardForm": "Dashboard Forms", 5 | "dashboardDesign": "Design Dashboard", 6 | "row-size-is-full": "Can not add cell to this row!", 7 | "confirm-remove-row": "Are you sure to remove the row?", 8 | "confirm-remove-cell": "Are you sure to remove the cell?", 9 | "confirm-clear-cell": "Are you sure to clear the cell?", 10 | "add_cell": "Add Cell", 11 | "add_row": "Add Row", 12 | "add_row_2": "Add Row With Two Columns", 13 | "add_row_3": "Add Row With Three Columns", 14 | "add_row_4": "Add Row With Four Columns", 15 | "remove_row": "Remove Row", 16 | "config": "Config Widget", 17 | "select-widget-type": "Select Widget Type", 18 | "widgetTypeGroup": "Widget Type Group", 19 | "widgetType": "Widget Type ", 20 | "increase_cell": "Increase Cell Size", 21 | "decrease_cell": "Decrease Cell Size", 22 | "remove_cell": "Remove", 23 | "clear_cell": "Clear", 24 | "import_cell": "Import", 25 | "import_sample": "Import sample dashboard", 26 | "export_cell": "Export", 27 | "design": "Design Widget", 28 | "title": "Title", 29 | "titles": { 30 | "link": "Link", 31 | "chart": "Chart", 32 | "todo": "To Do List", 33 | "datetime": "Date/Time", 34 | "dataTable": "Data Table", 35 | "kpi": "kpi" 36 | }, 37 | "dataSource": "Data Source", 38 | "theme": "Theme", 39 | "colorScheme": "Color Scheme", 40 | "schemeType": "Scheme Type", 41 | "animations": "Animations", 42 | "showXAxis": "Show X Axis", 43 | "showYAxis": "Show Y Axis", 44 | "gradient": "Use Gradients", 45 | "barPadding": "Padding between bars", 46 | "noBarWhenZero": "Hide bar if value is 0", 47 | "showLegend": "Show Legend", 48 | "showLabels": "Show Labels", 49 | "doughnut": "Doughnut", 50 | "legendTitle": "Legend Title", 51 | "legendPosition": "Legend Position", 52 | "showXAxisLabel": "Show X Axis Label", 53 | "xAxisLabel": "X Axis Label", 54 | "showYAxisLabel": "Show Y Axis Label", 55 | "yAxisLabel": "Y Axis Label", 56 | "showGridLines": "Show Grid Lines", 57 | "roundDomains": " Round Domains", 58 | "tooltipDisabled": "Disable tooltip", 59 | "roundEdges": "Round Bar Edges", 60 | "yScaleMax": "Maximum Y-Scale value", 61 | "showDataLabel": " Show Data Label", 62 | "trimXAxisTicks": "Trim X Axis Ticks", 63 | "trimYAxisTicks": "Trim Y Axis Ticks", 64 | "rotateXAxisTicks": "Rotate X Axis Ticks", 65 | "maxXAxisTickLength": "Max X Axis Tick Length", 66 | "maxYAxisTickLength": "Max Y Axis Tick Length", 67 | "width": "width", 68 | "height": "Height", 69 | "arcWidth": "Arc Width", 70 | "explodeSlices": "Explode Slices", 71 | "autoScale": "Auto Scale", 72 | "timeline": "Timeline", 73 | "showText": "Show Text", 74 | "gaugeMin": "Min Value", 75 | "gaugeMax": "Max value", 76 | "innerPadding": "Inner padding value", 77 | "groupPadding": "Padding between groups", 78 | "value": "Value", 79 | "previousValue": "Previous value", 80 | "largeSegments": "Number of large segments", 81 | "smallSegments": "Number of small segments", 82 | "units": "Units", 83 | "margin": "Show Margin", 84 | "marginTop": "Top", 85 | "marginRight": "Right", 86 | "marginBottom": "Bottom", 87 | "marginLeft": "Left", 88 | "minRadius": "Minimum Radius", 89 | "maxRadius": "Maximum Radius", 90 | "angleSpan": "Angle Span", 91 | "startAngle": "Start Angle", 92 | "showAxis": "Show Axis", 93 | "format": "Format", 94 | "containerHeight": "Container Height", 95 | "closedCurve": "Line Interpolation", 96 | "curve": "Line Interpolation", 97 | "pageSize": "Page Size" 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/assets/i18n/fa/dashboard.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboard": { 3 | "dashboard": "داشبورد", 4 | "dashboardForm": "مدیریت داشبورد", 5 | "dashboardDesign": "طراحی داشبورد", 6 | "row-size-is-full": "امکان اضافه کردن سلول بیشتر به این سطر نمی باشد!", 7 | "confirm-remove-row": "آیا مطمئن به حذف این سطر هستید?", 8 | "confirm-remove-cell": "آیا مطمئن به حذف این سلول هستید?", 9 | "confirm-clear-cell": "آیا مطمئن به خالی کردن این سلول هستید?", 10 | "add_cell": "اضافه کردن سلول", 11 | "add_row": "اضافه کردن سطر", 12 | "add_row_2": "اضافه کردن سطر دو ستونه", 13 | "add_row_3": "اضافه کردن سطر سه ستونه", 14 | "add_row_4": "اضافه کردن سطر چهار ستونه", 15 | "remove_row": "حذف سطر", 16 | "config": "تنظیمات ویجت", 17 | "select-widget-type": "انتخاب نوع ویجت", 18 | "widgetTypeGroup": "گروه نوع ویجت", 19 | "widgetType": "نوع ویجت", 20 | "increase_cell": "افزایش اندازه سلول", 21 | "decrease_cell": "کاهش اندازه سلول", 22 | "remove_cell": "حذف سلول", 23 | "clear_cell": "خالی کردن سلول", 24 | "import_cell": "دریافت", 25 | "import_sample":"لود داشبورد مثال", 26 | "export_cell": "ارسال", 27 | "design": "طراحی ویجت", 28 | "title": "عنوان", 29 | "titles": { 30 | "link": "لینک", 31 | "chart": "چارت", 32 | "todo": "لیست کارها", 33 | "datetime": "تاریخ/زمان", 34 | "dataTable": "جدول اطلاعات", 35 | "kpi": "kpi" 36 | }, 37 | "dataSource": "منبع داده", 38 | "theme": "Theme", 39 | "colorScheme": "Color Scheme", 40 | "schemeType": "Scheme Type", 41 | "animations": "Animations", 42 | "showXAxis": "Show X Axis", 43 | "showYAxis": "Show Y Axis", 44 | "gradient": "Use Gradients", 45 | "barPadding": "Padding between bars", 46 | "noBarWhenZero": "Hide bar if value is 0", 47 | "showLegend": "Show Legend", 48 | "showLabels": "Show Labels", 49 | "doughnut": "Doughnut", 50 | "legendTitle": "Legend Title", 51 | "legendPosition": "Legend Position", 52 | "showXAxisLabel": "Show X Axis Label", 53 | "xAxisLabel": "X Axis Label", 54 | "showYAxisLabel": "Show Y Axis Label", 55 | "yAxisLabel": "Y Axis Label", 56 | "showGridLines": "Show Grid Lines", 57 | "roundDomains": " Round Domains", 58 | "tooltipDisabled": "Disable tooltip", 59 | "roundEdges": "Round Bar Edges", 60 | "yScaleMax": "Maximum Y-Scale value", 61 | "showDataLabel": " Show Data Label", 62 | "trimXAxisTicks": "Trim X Axis Ticks", 63 | "trimYAxisTicks": "Trim Y Axis Ticks", 64 | "rotateXAxisTicks": "Rotate X Axis Ticks", 65 | "maxXAxisTickLength": "Max X Axis Tick Length", 66 | "maxYAxisTickLength": "Max Y Axis Tick Length", 67 | "width": "width", 68 | "height": "Height", 69 | "arcWidth": "Arc Width", 70 | "explodeSlices": "Explode Slices", 71 | "autoScale": "Auto Scale", 72 | "timeline": "Timeline", 73 | "showText": "Show Text", 74 | "gaugeMin": "Min Value", 75 | "gaugeMax": "Max value", 76 | "innerPadding": "Inner padding value", 77 | "groupPadding": "Padding between groups", 78 | "value": "Value", 79 | "previousValue": "Previous value", 80 | "largeSegments": "Number of large segments", 81 | "smallSegments": "Number of small segments", 82 | "units": "Units", 83 | "margin": "Show Margin", 84 | "marginTop": "Top", 85 | "marginRight": "Right", 86 | "marginBottom": "Bottom", 87 | "marginLeft": "Left", 88 | "minRadius": "Minimum Radius", 89 | "maxRadius": "Maximum Radius", 90 | "angleSpan": "Angle Span", 91 | "startAngle": "Start Angle", 92 | "showAxis": "Show Axis", 93 | "format": "Format", 94 | "containerHeight": "Container Height", 95 | "closedCurve": "Line Interpolation", 96 | "curve": "Line Interpolation", 97 | "pageSize": "تعداد رکورد در صفحه" 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/app/modules/dashboard/dashboard-design/dashboard-designer/dashboard-designer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, OnInit, ViewChild, ElementRef } from '@angular/core'; 2 | 3 | import { DashboardRow } from '../../dashboard-share/base/dashboard-row'; 4 | import { CommandHost, CommandInfo } from '@narik/infrastructure'; 5 | import { Observable } from 'rxjs/internal/Observable'; 6 | import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; 7 | import { saveAs } from 'file-saver'; 8 | import { PluginService } from '../../dashboard-share/service/plugin.service'; 9 | import { WidgetViewType } from '../../dashboard-share/base/widget-view-type'; 10 | import { HttpClient } from '@angular/common/http'; 11 | 12 | @Component({ 13 | selector: 'dashboard-designer', 14 | templateUrl: 'dashboard-designer.component.html', 15 | styleUrls: ['dashboard-designer.component.css'], 16 | }) 17 | export class DashboardDesignerComponent implements OnInit, CommandHost { 18 | change$: Observable; 19 | 20 | selectedRow: DashboardRow; 21 | _rows: DashboardRow[] = []; 22 | @Input() 23 | set rows(value: DashboardRow[]) { 24 | if (value) { 25 | this.applyComponentTypes(value); 26 | } 27 | this._rows = value; 28 | } 29 | get rows(): DashboardRow[] { 30 | return this._rows; 31 | } 32 | 33 | @ViewChild('importFile', { static: false }) 34 | importFile: ElementRef; 35 | 36 | constructor( 37 | private dashboardService: PluginService, 38 | private httpClient: HttpClient 39 | ) {} 40 | 41 | ngOnInit() {} 42 | 43 | processCommand(cmd: CommandInfo) { 44 | if (cmd.commandKey === 'add') { 45 | const newRow = new DashboardRow(cmd.commandData || 1); 46 | if (this.selectedRow) { 47 | const pos = this.rows.indexOf(this.selectedRow); 48 | this.rows.splice(pos + 1, 0, newRow); 49 | } else { 50 | this.rows.push(newRow); 51 | } 52 | } else if (cmd.commandKey === 'import') { 53 | this.importFile.nativeElement.click(); 54 | } else if (cmd.commandKey === 'export') { 55 | this.export(); 56 | } else if (cmd.commandKey === 'importSample') { 57 | this.httpClient.get(`assets/samples/1.json`).subscribe((result: any) => { 58 | this.rows = result.rows; 59 | }); 60 | } 61 | } 62 | 63 | drop(event: CdkDragDrop) { 64 | moveItemInArray(this.rows, event.previousIndex, event.currentIndex); 65 | } 66 | 67 | removeRow(row: DashboardRow) { 68 | const pos = this.rows.indexOf(row); 69 | if (pos >= 0) { 70 | this.rows.splice(pos, 1); 71 | } 72 | } 73 | 74 | export() { 75 | const data = { 76 | rows: this.rows, 77 | }; 78 | const blob = new Blob([JSON.stringify(data)], { 79 | type: 'application/octet-stream', 80 | }); 81 | saveAs(blob, `${'data'}.json`); 82 | } 83 | 84 | import(e) { 85 | if (e.target.files[0]) { 86 | const that = this; 87 | const reader = new FileReader(); 88 | reader.readAsText(e.target.files[0], 'UTF-8'); 89 | reader.onload = (evt) => { 90 | const newModel = JSON.parse((evt.target as any).result) 91 | .rows as DashboardRow[]; 92 | this.rows = newModel; 93 | }; 94 | reader.onerror = (evt) => {}; 95 | } 96 | } 97 | applyComponentTypes(rows: DashboardRow[]) { 98 | for (const row of rows) { 99 | for (const cell of row.cells) { 100 | if (cell.widgetInfo && cell.widgetInfo.widgetTypeKey) { 101 | this.dashboardService 102 | .widgetComponentType( 103 | undefined, 104 | cell.widgetInfo.widgetTypeKey, 105 | WidgetViewType.View 106 | ) 107 | .then((type) => { 108 | cell.widgetInfo.widgetType = type; 109 | }); 110 | } 111 | } 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /plugins/chart/src/app/viewer/viewer.component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AfterViewInit, 3 | Component, 4 | Injector, 5 | NgModule, 6 | ViewContainerRef, 7 | } from '@angular/core'; 8 | import { 9 | colorSets, 10 | NgxChartsModule, 11 | TooltipService, 12 | } from '@swimlane/ngx-charts'; 13 | import * as shape from 'd3-shape'; 14 | import { WidgetView } from 'dashboard-lib'; 15 | 16 | import { FormsModule } from '@angular/forms'; 17 | import { MatIconModule } from '@angular/material/icon'; 18 | import { BrowserModule } from '@angular/platform-browser'; 19 | import { 20 | NarikMatCheckBoxModule, 21 | NarikMatInputModule, 22 | NarikMatSelectModule, 23 | } from '@narik/ui-material'; 24 | import { TranslateModule } from '@ngx-translate/core'; 25 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 26 | 27 | @Component({ 28 | templateUrl: './viewer.component.html', 29 | styleUrls: ['viewer.component.scss'], 30 | }) 31 | export class ChartViewComponent extends WidgetView implements AfterViewInit { 32 | chartData: any[]; 33 | enabledFullScreen = true; 34 | view: any[]; 35 | 36 | colorScheme: any; 37 | 38 | // heatmap 39 | heatmapMin = 0; 40 | heatmapMax = 50000; 41 | 42 | curves = { 43 | Basis: shape.curveBasis, 44 | 'Basis Closed': shape.curveBasisClosed, 45 | Bundle: shape.curveBundle.beta(1), 46 | Cardinal: shape.curveCardinal, 47 | 'Cardinal Closed': shape.curveCardinalClosed, 48 | 'Catmull Rom': shape.curveCatmullRom, 49 | 'Catmull Rom Closed': shape.curveCatmullRomClosed, 50 | Linear: shape.curveLinear, 51 | 'Linear Closed': shape.curveLinearClosed, 52 | 'Monotone X': shape.curveMonotoneX, 53 | 'Monotone Y': shape.curveMonotoneY, 54 | Natural: shape.curveNatural, 55 | Step: shape.curveStep, 56 | 'Step After': shape.curveStepAfter, 57 | 'Step Before': shape.curveStepBefore, 58 | default: shape.curveLinear, 59 | }; 60 | curve: any = this.curves['Linear']; 61 | closedCurve: any = this.curves['Linear Closed']; 62 | 63 | constructor( 64 | injector: Injector, 65 | tooltipService: TooltipService, 66 | viewContainerRef: ViewContainerRef 67 | ) { 68 | super(injector); 69 | tooltipService.injectionService.setRootViewContainer(viewContainerRef); 70 | this.setColorScheme('cool'); 71 | } 72 | setColorScheme(name) { 73 | this.colorScheme = colorSets.find((s) => s.name === name); 74 | } 75 | 76 | select() {} 77 | onLegendLabelClick() {} 78 | 79 | activate() {} 80 | 81 | deactivate() {} 82 | 83 | applyDimensions() { 84 | this.view = [+this.model.width, +this.model.height]; 85 | } 86 | 87 | getInterpolationType() { 88 | return; 89 | } 90 | 91 | afterModelSet() { 92 | this.model.schemeType = this.model.schemeType || 'ordinal'; 93 | 94 | if (this.model.dataSource) { 95 | this.dataSourceService 96 | .dataSourceData(this.model.dataSource) 97 | .subscribe((x) => (this.chartData = x)); 98 | } 99 | 100 | if (this.model.width || this.model.height) { 101 | this.applyDimensions(); 102 | } else { 103 | this.view = undefined; 104 | } 105 | 106 | this.setColorScheme(this.model.colorScheme || 'cool'); 107 | 108 | if (this.model.curve) { 109 | this.curve = this.curves[this.model.curve] || this.curves['default']; 110 | } 111 | if (this.model.closedCurve) { 112 | this.closedCurve = 113 | this.curves[this.model.closedCurve] || this.curves['default']; 114 | } 115 | this.doOnResize(0); 116 | } 117 | 118 | ngAfterViewInit(): void {} 119 | 120 | doOnResize(newSize: number) { 121 | this.view = [0, 0]; 122 | setTimeout(() => { 123 | if (this.model && (this.model.width || this.model.height)) { 124 | this.applyDimensions(); 125 | } else { 126 | this.view = undefined; 127 | } 128 | }, 0); 129 | } 130 | } 131 | 132 | @NgModule({ 133 | declarations: [ChartViewComponent], 134 | imports: [ 135 | BrowserModule, 136 | BrowserAnimationsModule, 137 | FormsModule, 138 | NarikMatSelectModule, 139 | NarikMatInputModule, 140 | NarikMatCheckBoxModule, 141 | NgxChartsModule, 142 | MatIconModule, 143 | TranslateModule, 144 | ], 145 | providers: [], 146 | bootstrap: [], 147 | }) 148 | export class ViewModule { 149 | constructor() {} 150 | } 151 | -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NarikAppCoreModule } from '@narik/app-core'; 2 | import { NarikClientStorageModule } from '@narik/client-storage'; 3 | import { 4 | MEMORY_STORAGE_VALIDITY_LEN, 5 | NarikCoreModule, 6 | NarikModule, 7 | NarikTranslateLoader, 8 | } from '@narik/core'; 9 | import { 10 | ConfigService, 11 | MODULE_DATA_KEY, 12 | MODULE_UI_KEY, 13 | ModuleInfo, 14 | ModuleManager, 15 | ModuleEventArg, 16 | } from '@narik/infrastructure'; 17 | import { NarikJwtAuthenticationModule } from '@narik/jwt-authentication'; 18 | import { NarikUiCoreModule } from '@narik/ui-core'; 19 | import { FORM_ITEM_DEFAULT_CLASS } from '@narik/ui-material'; 20 | import { Observable } from 'rxjs/internal/Observable'; 21 | 22 | import { HttpClient, HttpClientModule } from '@angular/common/http'; 23 | import { Injector, NgModule } from '@angular/core'; 24 | import { BrowserModule } from '@angular/platform-browser'; 25 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 26 | import { NbEvaIconsModule } from '@nebular/eva-icons'; 27 | import { NbIconModule, NbLayoutDirection, NbThemeModule } from '@nebular/theme'; 28 | import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; 29 | 30 | import { AppRoutingModule } from './app-routing.module'; 31 | import { AppComponent } from './app.component'; 32 | import { MainViewComponent } from './main-view/main-view.component'; 33 | import { MainComponent } from './main/main.component'; 34 | 35 | import { NarikNgxLayout } from './modules/narik-ngx-layout/narik-ngx-layout.module'; 36 | import { ShareModule } from './modules/share/share.module'; 37 | import { DemoCommandProcessor } from './services/command-processor.service'; 38 | import { DashboardDesignModule } from './modules/dashboard/dashboard-design/dashboard-design.module'; 39 | import { DashboardViewModule } from './modules/dashboard/dashboard-view/dashboard-view.module'; 40 | import { DashboardShareModule } from './modules/dashboard/dashboard-share/dashboard-share.module'; 41 | import { PluginService } from './modules/dashboard/dashboard-share/service/plugin.service'; 42 | import { DataSourceService } from 'dashboard-lib'; 43 | 44 | const moduleKey = 'main'; 45 | 46 | @NgModule({ 47 | declarations: [AppComponent, MainComponent, MainViewComponent], 48 | imports: [ 49 | BrowserModule, 50 | AppRoutingModule, 51 | HttpClientModule, 52 | TranslateModule.forRoot({ 53 | loader: { 54 | provide: TranslateLoader, 55 | useFactory: HttpLoaderFactory, 56 | deps: [HttpClient, ConfigService], 57 | }, 58 | }), 59 | NarikCoreModule.forRoot({ 60 | configFilePath: 'assets/app-config.json', 61 | defaultLang: 'en', 62 | useDefaultLang: true, 63 | commandProcessor: DemoCommandProcessor, 64 | }), 65 | NarikUiCoreModule, 66 | NarikAppCoreModule.forRoot({}), 67 | NarikJwtAuthenticationModule.forRoot({ 68 | loginEndPoint: 'api/account/Authenticate', 69 | logoutEndPoint: 'api/account/Logout', 70 | refreshEndPoint: 'api/account/Authenticate', 71 | tokenStorage: 'localStorage', 72 | loginPageUrl: '/', 73 | }), 74 | 75 | NbEvaIconsModule, 76 | NbIconModule, 77 | NbThemeModule.forRoot( 78 | { name: 'default' }, 79 | undefined, 80 | undefined, 81 | NbLayoutDirection.LTR 82 | ), 83 | 84 | BrowserAnimationsModule, 85 | NarikClientStorageModule.forRoot(), 86 | NarikNgxLayout, 87 | ShareModule, 88 | DashboardDesignModule, 89 | DashboardViewModule, 90 | DashboardShareModule, 91 | ], 92 | providers: [ 93 | { 94 | provide: MODULE_DATA_KEY, 95 | useValue: moduleKey, 96 | }, 97 | { 98 | provide: MODULE_UI_KEY, 99 | useValue: moduleKey, 100 | }, 101 | { 102 | provide: MEMORY_STORAGE_VALIDITY_LEN, 103 | useValue: 1, 104 | }, 105 | { 106 | provide: FORM_ITEM_DEFAULT_CLASS, 107 | useValue: 'item-full-width', 108 | }, 109 | ], 110 | bootstrap: [AppComponent], 111 | }) 112 | export class AppModule extends NarikModule { 113 | constructor( 114 | injector: Injector, 115 | moduleManager: ModuleManager, 116 | dashboardService: PluginService, 117 | dataSourceService: DataSourceService 118 | ) { 119 | super(injector); 120 | moduleManager.modulesChanged.subscribe((x: ModuleEventArg) => { 121 | if (x.moduleKey === 'main') { 122 | dashboardService.init(); 123 | dataSourceService.init(); 124 | } 125 | }); 126 | } 127 | 128 | get key() { 129 | return moduleKey; 130 | } 131 | get moduleInfo(): Observable { 132 | return this.loadInfoFromJson(); 133 | } 134 | } 135 | 136 | export function HttpLoaderFactory( 137 | http: HttpClient, 138 | configService: ConfigService 139 | ) { 140 | return new NarikTranslateLoader(http, configService, ['app']); 141 | } 142 | --------------------------------------------------------------------------------