├── 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 |
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 |
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 |
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 |
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 |
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 |
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 |
10 |
11 |
12 |
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 |
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 |
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 |
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 |
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 |
13 |
14 | Here are some links to help you start:
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
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 |
13 |
14 | Here are some links to help you start:
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
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 |
13 |
14 | Here are some links to help you start:
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
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 |
13 |
14 | Here are some links to help you start:
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
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 |
--------------------------------------------------------------------------------