diff --git a/package-lock.json b/package-lock.json index aea0e3b15f..8b35517c45 100644 --- a/package-lock.json +++ b/package-lock.json @@ -690,19 +690,19 @@ } }, "@nebular/auth": { - "version": "2.0.0-rc.7", - "resolved": "https://registry.npmjs.org/@nebular/auth/-/auth-2.0.0-rc.7.tgz", - "integrity": "sha512-0REoqU771vKuF02bnBZVqDAzC5WfWfB79dl6Wk51Oau6tOJDpL3Kw3FPbPeHHDr3tzFj9UNDXGmtJ0DyUAaibQ==" + "version": "2.0.0-rc.8", + "resolved": "https://registry.npmjs.org/@nebular/auth/-/auth-2.0.0-rc.8.tgz", + "integrity": "sha512-uImudGbG2qcaTpimjJFyqRdxhjE62sQfqqzZcH//NsokXbC5+8YMfUMcX4SpPTYOpWsx4p9T4vEIUDJOoYIBnw==" }, "@nebular/security": { - "version": "2.0.0-rc.7", - "resolved": "https://registry.npmjs.org/@nebular/security/-/security-2.0.0-rc.7.tgz", - "integrity": "sha512-K2VOvgUUzd54v7VSs6pFfzdq0UhRlYhCP4EPCi3INcM7mY/dh6F6yIDZMlz0AybS5et1G4PMWUHqvUi1AnrSsQ==" + "version": "2.0.0-rc.8", + "resolved": "https://registry.npmjs.org/@nebular/security/-/security-2.0.0-rc.8.tgz", + "integrity": "sha512-aC3q1AR7jmF3Cm/TNT4Rut/ZQcmBrna0zNPxwg5cBSvWAPk3vRXVTYSFPQCNHDs2tyXJz4Xf50Sl2YJQhCiMnw==" }, "@nebular/theme": { - "version": "2.0.0-rc.7", - "resolved": "https://registry.npmjs.org/@nebular/theme/-/theme-2.0.0-rc.7.tgz", - "integrity": "sha512-I8hB+ik/1086HSx8tbJcHuZfXdfpq5lg8cDcUMW0h8Y3Gp0Na5sqpdq850SoTlcqc4HiE6CFS/fkx6ro+8HtTQ==" + "version": "2.0.0-rc.8", + "resolved": "https://registry.npmjs.org/@nebular/theme/-/theme-2.0.0-rc.8.tgz", + "integrity": "sha512-1BLG4J0ElUOHMjIJQ6lSSzMK+8iaPX1brDVPI3Ol0O0FTiyCPVXugyK09/GNX2Of4xUIZqX7VvNYGywiJ7dUTw==" }, "@ng-bootstrap/ng-bootstrap": { "version": "1.0.0", @@ -3106,16 +3106,6 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, - "cors": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", - "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", - "dev": true, - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, "cosmiconfig": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz", @@ -3584,7 +3574,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -3747,8 +3736,7 @@ "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" }, "des.js": { "version": "1.0.0", @@ -3763,8 +3751,7 @@ "destroy": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, "detect-indent": { "version": "4.0.0", @@ -4186,8 +4173,7 @@ "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "ejs": { "version": "2.6.1", @@ -4225,8 +4211,7 @@ "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, "end-of-stream": { "version": "1.4.1", @@ -4429,8 +4414,7 @@ "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, "escape-string-regexp": { "version": "1.0.5", @@ -4525,8 +4509,7 @@ "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, "event-stream": { "version": "3.3.4", @@ -5099,8 +5082,7 @@ "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, "from": { "version": "0.1.7", @@ -7122,7 +7104,6 @@ "version": "1.6.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", - "dev": true, "requires": { "depd": "1.1.1", "inherits": "2.0.3", @@ -7133,14 +7114,12 @@ "depd": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", - "dev": true + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" }, "setprototypeof": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", - "dev": true + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" } } }, @@ -7639,8 +7618,7 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ini": { "version": "1.3.5", @@ -8039,8 +8017,7 @@ "is-wsl": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" }, "isarray": { "version": "1.0.0", @@ -8996,17 +8973,10 @@ "integrity": "sha1-pp8ObKWB4DkapXlBlw4XwwjdSGk=", "dev": true, "requires": { - "colors": "latest", "connect": "3.4.x", - "cors": "latest", - "event-stream": "latest", "faye-websocket": "0.11.x", "http-auth": "2.4.x", "morgan": "^1.6.1", - "object-assign": "latest", - "opn": "latest", - "proxy-middleware": "latest", - "send": "latest", "serve-index": "^1.7.2", "watchr": "2.6.x" }, @@ -9014,8 +8984,7 @@ "colors": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", - "dev": true + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=" }, "faye-websocket": { "version": "0.11.1", @@ -9029,20 +8998,17 @@ "mime": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", - "dev": true + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "opn": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.2.0.tgz", "integrity": "sha512-Jd/GpzPyHF4P2/aNOVmS3lfMSWV9J7cOhCG1s08XCEAsPkB7lp6ddiU0J7XzyQRDUh8BqJ7PchfINjR8jyofRQ==", - "dev": true, "requires": { "is-wsl": "^1.1.0" } @@ -9051,7 +9017,6 @@ "version": "0.16.2", "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", - "dev": true, "requires": { "debug": "2.6.9", "depd": "~1.1.2", @@ -9071,8 +9036,7 @@ "statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", - "dev": true + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" } } }, @@ -9758,8 +9722,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "multicast-dns": { "version": "6.2.3", @@ -10444,7 +10407,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, "requires": { "ee-first": "1.1.1" } @@ -11440,12 +11402,6 @@ "ipaddr.js": "1.6.0" } }, - "proxy-middleware": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz", - "integrity": "sha1-o/3xvvtzD5UZZYcqwvYHTGFHelY=", - "dev": true - }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -11612,8 +11568,7 @@ "range-parser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", - "dev": true + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" }, "raw-body": { "version": "2.3.2", @@ -12965,8 +12920,7 @@ "statuses": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", - "dev": true + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" }, "stdout-stream": { "version": "1.4.0", diff --git a/package.json b/package.json index 4b2cfd0d1d..4db7adce78 100644 --- a/package.json +++ b/package.json @@ -40,9 +40,9 @@ "@angular/platform-browser-dynamic": "6.0.0", "@angular/router": "6.0.0", "@asymmetrik/ngx-leaflet": "3.0.1", - "@nebular/auth": "^2.0.0-rc.7", - "@nebular/security": "^2.0.0-rc.7", - "@nebular/theme": "^2.0.0-rc.7", + "@nebular/auth": "^2.0.0-rc.8", + "@nebular/security": "^2.0.0-rc.8", + "@nebular/theme": "^2.0.0-rc.8", "@ng-bootstrap/ng-bootstrap": "1.0.0", "@swimlane/ngx-charts": "7.0.1", "angular2-chartjs": "0.4.1", diff --git a/src/app/@core/data/state.service.ts b/src/app/@core/data/state.service.ts index 6f1328fbf0..3f0847d5b7 100644 --- a/src/app/@core/data/state.service.ts +++ b/src/app/@core/data/state.service.ts @@ -1,10 +1,11 @@ +import { Injectable, OnDestroy } from '@angular/core'; +import { of as observableOf, Observable, BehaviorSubject } from 'rxjs'; +import { takeWhile } from 'rxjs/operators'; -import { of as observableOf, Observable , BehaviorSubject } from 'rxjs'; -import { Injectable } from '@angular/core'; - +import { NbLayoutDirectionService, NbLayoutDirection } from '@nebular/theme'; @Injectable() -export class StateService { +export class StateService implements OnDestroy { protected layouts: any = [ { @@ -27,21 +28,44 @@ export class StateService { protected sidebars: any = [ { - name: 'Left Sidebar', + name: 'Sidebar at layout start', icon: 'nb-layout-sidebar-left', - id: 'left', + id: 'start', selected: true, }, { - name: 'Right Sidebar', + name: 'Sidebar at layout end', icon: 'nb-layout-sidebar-right', - id: 'right', + id: 'end', }, ]; protected layoutState$ = new BehaviorSubject(this.layouts[0]); protected sidebarState$ = new BehaviorSubject(this.sidebars[0]); + alive = true; + + constructor(directionService: NbLayoutDirectionService) { + directionService.onDirectionChange() + .pipe(takeWhile(() => this.alive)) + .subscribe(direction => this.updateSidebarIcons(direction)); + + this.updateSidebarIcons(directionService.getDirection()); + } + + ngOnDestroy() { + this.alive = false; + } + + private updateSidebarIcons(direction: NbLayoutDirection) { + const [ startSidebar, endSidebar ] = this.sidebars; + const isLtr = direction === NbLayoutDirection.LTR; + const startIconClass = isLtr ? 'nb-layout-sidebar-left' : 'nb-layout-sidebar-right'; + const endIconClass = isLtr ? 'nb-layout-sidebar-right' : 'nb-layout-sidebar-left'; + startSidebar.icon = startIconClass; + endSidebar.icon = endIconClass; + } + setLayoutState(state: any): any { this.layoutState$.next(state); } diff --git a/src/app/@theme/components/header/header.component.html b/src/app/@theme/components/header/header.component.html index 72ee690cfa..d1e747c10f 100644 --- a/src/app/@theme/components/header/header.component.html +++ b/src/app/@theme/components/header/header.component.html @@ -6,6 +6,7 @@ + - + diff --git a/src/app/@theme/components/header/header.component.scss b/src/app/@theme/components/header/header.component.scss index 647311b5a4..b5de674da1 100644 --- a/src/app/@theme/components/header/header.component.scss +++ b/src/app/@theme/components/header/header.component.scss @@ -33,7 +33,8 @@ width: 100%; .navigation { - padding-right: nb-theme(padding); + @include nb-ltr(padding-right, nb-theme(padding)); + @include nb-rtl(padding-left, nb-theme(padding)); font-size: 2.5rem; text-decoration: none; @@ -47,7 +48,8 @@ padding: 0 nb-theme(padding); font-size: 1.75rem; font-weight: nb-theme(font-weight-bolder); - border-left: 1px solid nb-theme(separator); + @include nb-ltr(border-left, 1px solid nb-theme(separator)); + @include nb-rtl(border-right, 1px solid nb-theme(separator)); white-space: nowrap; span { @@ -56,6 +58,17 @@ } } + ngx-layout-direction-switcher, + ngx-theme-switcher { + margin: 0 1em; + } + + @include media-breakpoint-down(xl) { + ngx-layout-direction-switcher { + display: none; + } + } + .toggle-layout /deep/ a { display: block; text-decoration: none; @@ -64,6 +77,54 @@ i { color: nb-theme(color-fg-highlight); font-size: 2.25rem; + border-radius: 50%; + position: relative; + animation-name: pulse-light; + + &::after { + content: ' '; + // hack to be able to set border-radius + background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'); + border-radius: 50%; + pointer-events: none; + + position: absolute; + top: 52.3%; + left: 50%; + transform: translate(-50%, -50%); + width: 13%; + height: 13%; + + animation: 3s linear infinite pulse; + + @include nb-for-theme(default) { + animation-name: pulse-light; + } + } + } + } + + @include keyframes(pulse) { + 0% { + box-shadow: 0 0 1px 0 rgba(nb-theme(color-fg-highlight), 0); + } + 20% { + box-shadow: 0 0 3px 10px rgba(nb-theme(color-fg-highlight), 0.4); + } + 100% { + box-shadow: 0 0 5px 20px rgba(nb-theme(color-fg-highlight), 0); + } + } + + @include keyframes(pulse-light) { + 0% { + box-shadow: 0 0 1px 0 rgba(115, 255, 208, 0); + } + 20% { + box-shadow: 0 0 3px 10px rgba(115, 255, 208, 0.4); + } + 100% { + box-shadow: 0 0 5px 20px rgba(115, 255, 208, 0); } } @@ -80,6 +141,11 @@ .toggle-layout { padding: 0; } + + ngx-layout-direction-switcher, + ngx-theme-switcher { + display: none; + } } @include media-breakpoint-down(sm) { @@ -112,4 +178,3 @@ } } } - diff --git a/src/app/@theme/components/index.ts b/src/app/@theme/components/index.ts index 8da51e3d78..efcf5eda81 100644 --- a/src/app/@theme/components/index.ts +++ b/src/app/@theme/components/index.ts @@ -4,3 +4,5 @@ export * from './search-input/search-input.component'; export * from './tiny-mce/tiny-mce.component'; export * from './theme-settings/theme-settings.component'; export * from './theme-switcher/theme-switcher.component'; +export * from './switcher/switcher.component'; +export * from './layout-direction-switcher/layout-direction-switcher.component' diff --git a/src/app/@theme/components/layout-direction-switcher/layout-direction-switcher.component.ts b/src/app/@theme/components/layout-direction-switcher/layout-direction-switcher.component.ts new file mode 100644 index 0000000000..515385d6c6 --- /dev/null +++ b/src/app/@theme/components/layout-direction-switcher/layout-direction-switcher.component.ts @@ -0,0 +1,42 @@ +import { Component, OnDestroy, Input } from '@angular/core'; +import { NbLayoutDirectionService, NbLayoutDirection } from '@nebular/theme'; +import { takeWhile } from 'rxjs/operators/takeWhile'; + +@Component({ + selector: 'ngx-layout-direction-switcher', + template: ` + + + `, +}) +export class LayoutDirectionSwitcherComponent implements OnDestroy { + directions = NbLayoutDirection; + currentDirection: NbLayoutDirection; + alive = true; + + @Input() vertical: boolean = false; + + constructor(private directionService: NbLayoutDirectionService) { + this.currentDirection = this.directionService.getDirection(); + + this.directionService.onDirectionChange() + .pipe(takeWhile(() => this.alive)) + .subscribe(newDirection => this.currentDirection = newDirection); + } + + toggleDirection(newDirection) { + this.directionService.setDirection(newDirection); + } + + ngOnDestroy() { + this.alive = false; + } +} diff --git a/src/app/@theme/components/theme-switcher/theme-switcher.component.scss b/src/app/@theme/components/switcher/switcher.component.scss similarity index 70% rename from src/app/@theme/components/theme-switcher/theme-switcher.component.scss rename to src/app/@theme/components/switcher/switcher.component.scss index 210add829d..7406d42448 100644 --- a/src/app/@theme/components/theme-switcher/theme-switcher.component.scss +++ b/src/app/@theme/components/switcher/switcher.component.scss @@ -4,39 +4,51 @@ @import '~@nebular/theme/styles/global/bootstrap/breakpoints'; @include nb-install-component() { - display: flex; - flex-direction: column; - align-items: center; - width: 50%; - - .theme-switch { + .switch-label { display: flex; justify-content: space-between; align-items: center; cursor: pointer; margin: 0; + &.vertical { + flex-direction: column; + align-items: flex-start; + + .first, + .second { + padding: 0; + } + + .switch { + margin-top: 0.5em; + } + } + & > span { font-size: 1.125rem; font-weight: nb-theme(font-weight-bold); transition: opacity 0.3s ease; + color: nb-theme(color-fg); - &.light { - color: nb-theme(color-fg-text); - padding-right: 10px; + &.first { + @include nb-ltr(padding-right, 10px); + @include nb-rtl(padding-left, 10px); } - &.cosmic { - color: nb-theme(color-fg); - padding-left: 10px; + &.second { + @include nb-ltr(padding-left, 10px); + @include nb-rtl(padding-right, 10px); + } + + &.active { + color: nb-theme(color-fg-text); } @include nb-for-theme(cosmic) { - &.light { - color: nb-theme(color-fg); - } + color: nb-theme(color-fg); - &.cosmic { + &.active { color: nb-theme(color-white); } } @@ -58,7 +70,8 @@ display: none; &:checked + .slider::before { - transform: translateX(2.25rem); + @include nb-ltr(transform, translateX(2.25rem)); + @include nb-rtl(transform, translateX(-2.25rem)); } } @@ -89,13 +102,7 @@ } } - @include media-breakpoint-down(is) { - .light, .cosmic { - display: none; - } - } - @include media-breakpoint-down(xs) { - align-items: flex-end; + align-items: flex-end; } } diff --git a/src/app/@theme/components/switcher/switcher.component.ts b/src/app/@theme/components/switcher/switcher.component.ts new file mode 100644 index 0000000000..a7875f147c --- /dev/null +++ b/src/app/@theme/components/switcher/switcher.component.ts @@ -0,0 +1,60 @@ +import { Component, Input, Output, EventEmitter } from '@angular/core'; + +@Component({ + selector: 'ngx-switcher', + styleUrls: ['./switcher.component.scss'], + template: ` + + `, +}) +export class SwitcherComponent { + @Input() firstValue: any; + @Input() secondValue: any; + + @Input() firstValueLabel: string; + @Input() secondValueLabel: string; + + @Input() vertical: boolean; + + @Input() value: any; + @Output() valueChange = new EventEmitter(); + + isFirstValue() { + return this.value === this.firstValue; + } + + isSecondValue() { + return this.value === this.secondValue; + } + + currentValueLabel() { + return this.isFirstValue() + ? this.firstValueLabel + : this.secondValueLabel; + } + + changeValue() { + this.value = this.isFirstValue() + ? this.secondValue + : this.firstValue; + + this.valueChange.emit(this.value); + } +} diff --git a/src/app/@theme/components/theme-settings/theme-settings.component.scss b/src/app/@theme/components/theme-settings/theme-settings.component.scss index 4a0a93e4a8..b23be934b9 100644 --- a/src/app/@theme/components/theme-settings/theme-settings.component.scss +++ b/src/app/@theme/components/theme-settings/theme-settings.component.scss @@ -32,5 +32,40 @@ } } } -} + .settings { + margin-bottom: 1em; + } + + .switcher { + margin-bottom: 1rem; + + /deep/ ngx-switcher { + .switch-label span { + font-size: 1em; + font-weight: normal; + } + + .switch { + height: 1.5em; + width: 3em; + + .slider::before { + height: 1.5em; + width: 1.5em; + } + + input:checked + .slider::before { + @include nb-ltr(transform, translateX(1.5rem)!important); + @include nb-rtl(transform, translateX(-1.5rem)!important); + } + } + + @include nb-for-theme(cosmic) { + .switch .slider { + background-color: nb-theme(color-bg); + } + } + } + } +} diff --git a/src/app/@theme/components/theme-settings/theme-settings.component.ts b/src/app/@theme/components/theme-settings/theme-settings.component.ts index 38a50ad59f..a2531a8c33 100644 --- a/src/app/@theme/components/theme-settings/theme-settings.component.ts +++ b/src/app/@theme/components/theme-settings/theme-settings.component.ts @@ -26,6 +26,13 @@ import { StateService } from '../../../@core/data/state.service'; +
SETTINGS
+
+ +
+
+ +
`, }) export class ThemeSettingsComponent { diff --git a/src/app/@theme/components/theme-switcher/theme-switcher.component.ts b/src/app/@theme/components/theme-switcher/theme-switcher.component.ts index e84b942691..bb362e61e1 100644 --- a/src/app/@theme/components/theme-switcher/theme-switcher.component.ts +++ b/src/app/@theme/components/theme-switcher/theme-switcher.component.ts @@ -1,27 +1,35 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, Input } from '@angular/core'; import { NbThemeService } from '@nebular/theme'; import { NbJSThemeOptions } from '@nebular/theme/services/js-themes/theme.options'; import { AnalyticsService } from '../../../@core/utils/analytics.service'; @Component({ selector: 'ngx-theme-switcher', - styleUrls: ['./theme-switcher.component.scss'], template: ` - + + `, }) export class ThemeSwitcherComponent implements OnInit { theme: NbJSThemeOptions; - constructor(private themeService: NbThemeService, private analyticsService: AnalyticsService) { - } + firstTheme = 'default'; + secondTheme = 'cosmic'; + + @Input() vertical: boolean = false; + + constructor( + private themeService: NbThemeService, + private analyticsService: AnalyticsService, + ) {} ngOnInit() { this.themeService.getJsTheme() @@ -29,8 +37,9 @@ export class ThemeSwitcherComponent implements OnInit { } toggleTheme(theme: boolean) { - const boolTheme = this.boolToTheme(theme); - this.themeService.changeTheme(boolTheme); + const themeName = this.boolToTheme(theme); + this.themeService.changeTheme(themeName); + this.analyticsService.trackEvent('switchTheme'); } @@ -39,10 +48,10 @@ export class ThemeSwitcherComponent implements OnInit { } private themeToBool(theme: NbJSThemeOptions) { - return theme.name === 'cosmic'; + return theme.name === this.secondTheme; } private boolToTheme(theme: boolean) { - return theme ? 'cosmic' : 'default'; + return theme ? this.secondTheme : this.firstTheme; } } diff --git a/src/app/@theme/layouts/one-column/one-column.layout.scss b/src/app/@theme/layouts/one-column/one-column.layout.scss index 7ccf7b7700..498bb4bb6c 100644 --- a/src/app/@theme/layouts/one-column/one-column.layout.scss +++ b/src/app/@theme/layouts/one-column/one-column.layout.scss @@ -50,7 +50,8 @@ /deep/ .main-container { height: calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)} - #{nb-theme(sidebar-header-gap)}) !important; - border-top-right-radius: nb-theme(radius); + @include nb-ltr(border-top-right-radius, nb-theme(radius)); + @include nb-rtl(border-top-left-radius, nb-theme(radius)); } /deep/ nb-sidebar-header { @@ -71,7 +72,8 @@ text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); } span { - padding-left: 0.25rem; + @include nb-ltr(padding-left, 0.25rem); + @include nb-rtl(padding-right, 0.25rem); } i, span { @@ -115,7 +117,8 @@ /deep/ .main-container { height: calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)}) !important; - border-top-right-radius: 0; + @include nb-ltr(border-top-right-radius, 0); + @include nb-rtl(border-top-left-radius, 0); .scrollable { padding-top: 0; diff --git a/src/app/@theme/layouts/sample/sample.layout.scss b/src/app/@theme/layouts/sample/sample.layout.scss index 7ccf7b7700..498bb4bb6c 100644 --- a/src/app/@theme/layouts/sample/sample.layout.scss +++ b/src/app/@theme/layouts/sample/sample.layout.scss @@ -50,7 +50,8 @@ /deep/ .main-container { height: calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)} - #{nb-theme(sidebar-header-gap)}) !important; - border-top-right-radius: nb-theme(radius); + @include nb-ltr(border-top-right-radius, nb-theme(radius)); + @include nb-rtl(border-top-left-radius, nb-theme(radius)); } /deep/ nb-sidebar-header { @@ -71,7 +72,8 @@ text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); } span { - padding-left: 0.25rem; + @include nb-ltr(padding-left, 0.25rem); + @include nb-rtl(padding-right, 0.25rem); } i, span { @@ -115,7 +117,8 @@ /deep/ .main-container { height: calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)}) !important; - border-top-right-radius: 0; + @include nb-ltr(border-top-right-radius, 0); + @include nb-rtl(border-top-left-radius, 0); .scrollable { padding-top: 0; diff --git a/src/app/@theme/layouts/sample/sample.layout.ts b/src/app/@theme/layouts/sample/sample.layout.ts index 4696007ca7..c79a0b4e14 100644 --- a/src/app/@theme/layouts/sample/sample.layout.ts +++ b/src/app/@theme/layouts/sample/sample.layout.ts @@ -19,13 +19,13 @@ import { StateService } from '../../../@core/data/state.service'; template: ` - + + tag="menu-sidebar" + responsive + [end]="sidebar.id === 'end'"> Support Us @@ -38,11 +38,11 @@ import { StateService } from '../../../@core/data/state.service'; - + - + @@ -51,10 +51,10 @@ import { StateService } from '../../../@core/data/state.service'; + tag="settings-sidebar" + state="collapsed" + fixed + [end]="sidebar.id !== 'end'"> diff --git a/src/app/@theme/layouts/three-columns/three-columns.layout.scss b/src/app/@theme/layouts/three-columns/three-columns.layout.scss index 7ccf7b7700..498bb4bb6c 100644 --- a/src/app/@theme/layouts/three-columns/three-columns.layout.scss +++ b/src/app/@theme/layouts/three-columns/three-columns.layout.scss @@ -50,7 +50,8 @@ /deep/ .main-container { height: calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)} - #{nb-theme(sidebar-header-gap)}) !important; - border-top-right-radius: nb-theme(radius); + @include nb-ltr(border-top-right-radius, nb-theme(radius)); + @include nb-rtl(border-top-left-radius, nb-theme(radius)); } /deep/ nb-sidebar-header { @@ -71,7 +72,8 @@ text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); } span { - padding-left: 0.25rem; + @include nb-ltr(padding-left, 0.25rem); + @include nb-rtl(padding-right, 0.25rem); } i, span { @@ -115,7 +117,8 @@ /deep/ .main-container { height: calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)}) !important; - border-top-right-radius: 0; + @include nb-ltr(border-top-right-radius, 0); + @include nb-rtl(border-top-left-radius, 0); .scrollable { padding-top: 0; diff --git a/src/app/@theme/layouts/three-columns/three-columns.layout.ts b/src/app/@theme/layouts/three-columns/three-columns.layout.ts index 447b23e5ad..bc02f98283 100644 --- a/src/app/@theme/layouts/three-columns/three-columns.layout.ts +++ b/src/app/@theme/layouts/three-columns/three-columns.layout.ts @@ -22,7 +22,7 @@ import { Component } from '@angular/core'; - + diff --git a/src/app/@theme/layouts/two-columns/two-columns.layout.scss b/src/app/@theme/layouts/two-columns/two-columns.layout.scss index 7ccf7b7700..498bb4bb6c 100644 --- a/src/app/@theme/layouts/two-columns/two-columns.layout.scss +++ b/src/app/@theme/layouts/two-columns/two-columns.layout.scss @@ -50,7 +50,8 @@ /deep/ .main-container { height: calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)} - #{nb-theme(sidebar-header-gap)}) !important; - border-top-right-radius: nb-theme(radius); + @include nb-ltr(border-top-right-radius, nb-theme(radius)); + @include nb-rtl(border-top-left-radius, nb-theme(radius)); } /deep/ nb-sidebar-header { @@ -71,7 +72,8 @@ text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); } span { - padding-left: 0.25rem; + @include nb-ltr(padding-left, 0.25rem); + @include nb-rtl(padding-right, 0.25rem); } i, span { @@ -115,7 +117,8 @@ /deep/ .main-container { height: calc(#{nb-theme(sidebar-height)} - #{nb-theme(header-height)}) !important; - border-top-right-radius: 0; + @include nb-ltr(border-top-right-radius, 0); + @include nb-rtl(border-top-left-radius, 0); .scrollable { padding-top: 0; diff --git a/src/app/@theme/layouts/two-columns/two-columns.layout.ts b/src/app/@theme/layouts/two-columns/two-columns.layout.ts index b7f3a67448..7b37d2623b 100644 --- a/src/app/@theme/layouts/two-columns/two-columns.layout.ts +++ b/src/app/@theme/layouts/two-columns/two-columns.layout.ts @@ -22,7 +22,7 @@ import { Component } from '@angular/core'; - + diff --git a/src/app/@theme/styles/bootstrap-rtl.scss b/src/app/@theme/styles/bootstrap-rtl.scss new file mode 100644 index 0000000000..3d8bd7bf58 --- /dev/null +++ b/src/app/@theme/styles/bootstrap-rtl.scss @@ -0,0 +1,193 @@ +@import './themes'; + +@mixin bootstrap-rtl() { + .btn-group:not(.btn-divided-group) > .btn:not(.dropdown-toggle) { + &:first-child { + @include nb-ltr() { + border-top-left-radius: nb-theme(btn-border-radius); + border-bottom-left-radius: nb-theme(btn-border-radius); + border-top-right-radius: 0; + border-bottom-right-radius: 0; + }; + @include nb-rtl() { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-top-right-radius: nb-theme(btn-border-radius); + border-bottom-right-radius: nb-theme(btn-border-radius); + }; + } + &:last-child { + @include nb-ltr() { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-top-right-radius: nb-theme(btn-border-radius); + border-bottom-right-radius: nb-theme(btn-border-radius); + }; + @include nb-rtl() { + border-top-left-radius: nb-theme(btn-border-radius); + border-bottom-left-radius: nb-theme(btn-border-radius); + border-top-right-radius: 0; + border-bottom-right-radius: 0; + }; + } + } + + .btn-group.dropdown { + & > .btn:first-of-type.dropdown-toggle { + @include nb-ltr() { + border-top-left-radius: nb-theme(btn-border-radius); + border-top-right-radius: 0; + }; + @include nb-rtl() { + border-top-left-radius: 0; + border-top-right-radius: nb-theme(btn-border-radius); + }; + } + & > .btn:last-of-type.dropdown-toggle { + @include nb-ltr() { + border-top-left-radius: 0; + border-top-right-radius: nb-theme(btn-border-radius); + }; + @include nb-rtl() { + border-top-left-radius: nb-theme(btn-border-radius); + border-top-right-radius: 0; + }; + } + + &:not(.show) { + & > .btn:first-of-type.dropdown-toggle { + @include nb-ltr() { + border-bottom-left-radius: nb-theme(btn-border-radius); + border-bottom-right-radius: 0; + }; + @include nb-rtl() { + border-bottom-left-radius: 0; + border-bottom-right-radius: nb-theme(btn-border-radius); + }; + } + & > .btn:last-of-type.dropdown-toggle { + @include nb-ltr() { + border-bottom-left-radius: 0; + border-bottom-right-radius: nb-theme(btn-border-radius); + }; + @include nb-rtl() { + border-bottom-left-radius: nb-theme(btn-border-radius); + border-bottom-right-radius: 0; + }; + } + } + } + + .btn-group.dropup { + & > .btn:first-of-type.dropdown-toggle { + @include nb-ltr() { + border-bottom-left-radius: nb-theme(btn-border-radius); + border-bottom-right-radius: 0; + }; + @include nb-rtl() { + border-bottom-left-radius: 0; + border-bottom-right-radius: nb-theme(btn-border-radius); + }; + } + & > .btn:last-of-type.dropdown-toggle { + @include nb-ltr() { + border-bottom-left-radius: 0; + border-bottom-right-radius: nb-theme(btn-border-radius); + }; + @include nb-rtl() { + border-bottom-left-radius: nb-theme(btn-border-radius); + border-bottom-right-radius: 0; + }; + } + + &:not(.show) { + & > .btn:first-of-type.dropdown-toggle { + @include nb-ltr() { + border-top-left-radius: nb-theme(btn-border-radius); + border-top-right-radius: 0; + }; + @include nb-rtl() { + border-top-left-radius: 0; + border-top-right-radius: nb-theme(btn-border-radius); + }; + } + & > .btn:last-of-type.dropdown-toggle { + @include nb-ltr() { + border-top-left-radius: 0; + border-top-right-radius: nb-theme(btn-border-radius); + }; + @include nb-rtl() { + border-top-left-radius: nb-theme(btn-border-radius); + border-top-right-radius: 0; + }; + } + } + } + + .btn-divided-group { + .btn:not(:first-child) { + @include nb-ltr(margin-left, 0.5rem); + @include nb-rtl(margin-right, 0.5rem); + border-radius: nb-theme(btn-border-radius); + } + } + + .input-group-addon, + .input-group-icon { + @include nb-ltr() { + border-left: nb-theme(form-control-border); + border-right: none; + }; + @include nb-rtl() { + border-left: none; + border-right: nb-theme(form-control-border); + }; + } + + .input-group { + .form-control:first-child:not(:only-child), + .input-group-addon:first-child, + .input-group-prepend .btn:first-child, + .input-group-btn .btn:first-child { + @include nb-ltr() { + border-top-left-radius: nb-theme(form-control-border-radius); + border-bottom-left-radius: nb-theme(form-control-border-radius); + border-top-right-radius: 0; + border-bottom-right-radius: 0; + }; + @include nb-rtl() { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-top-right-radius: nb-theme(form-control-border-radius); + border-bottom-right-radius: nb-theme(form-control-border-radius); + }; + } + .form-control:last-child:not(:only-child), + .input-group-addon:last-child, + .input-group-append .btn:last-child, + .input-group-btn .btn:last-child { + @include nb-ltr() { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-top-right-radius: nb-theme(form-control-border-radius); + border-bottom-right-radius: nb-theme(form-control-border-radius); + }; + @include nb-rtl() { + border-top-left-radius: nb-theme(form-control-border-radius); + border-bottom-left-radius: nb-theme(form-control-border-radius); + border-top-right-radius: 0; + border-bottom-right-radius: 0; + }; + } + + .dropdown.show .btn.dropdown-toggle { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + + .dropup.show .btn.dropdown-toggle { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + } +} diff --git a/src/app/@theme/styles/styles.scss b/src/app/@theme/styles/styles.scss index c827f39175..e8868b318c 100644 --- a/src/app/@theme/styles/styles.scss +++ b/src/app/@theme/styles/styles.scss @@ -8,6 +8,8 @@ // loading progress bar theme @import './pace.theme'; +@import './bootstrap-rtl'; + // install the framework and custom global styles @include nb-install() { @@ -18,7 +20,9 @@ // loading progress bar @include ngx-pace-theme(); + // fixed in rc.9 and can be removed after upgrade .custom-control .custom-control-indicator { border-radius: 50%; // TODO: quickfix for https://github.com/akveo/nebular/issues/275 } + @include bootstrap-rtl(); }; diff --git a/src/app/@theme/theme.module.ts b/src/app/@theme/theme.module.ts index e7a9600e10..a00fb500eb 100644 --- a/src/app/@theme/theme.module.ts +++ b/src/app/@theme/theme.module.ts @@ -26,6 +26,8 @@ import { HeaderComponent, SearchInputComponent, ThemeSettingsComponent, + SwitcherComponent, + LayoutDirectionSwitcherComponent, ThemeSwitcherComponent, TinyMCEComponent, } from './components'; @@ -59,6 +61,8 @@ const NB_MODULES = [ ]; const COMPONENTS = [ + SwitcherComponent, + LayoutDirectionSwitcherComponent, ThemeSwitcherComponent, HeaderComponent, FooterComponent, diff --git a/src/app/pages/components/notifications/notifications.component.scss b/src/app/pages/components/notifications/notifications.component.scss index c5550bedd4..dcab501678 100644 --- a/src/app/pages/components/notifications/notifications.component.scss +++ b/src/app/pages/components/notifications/notifications.component.scss @@ -8,13 +8,14 @@ padding-bottom: 0.25rem; button { - margin: 0 1rem 1rem 0; + @include nb-ltr(margin, 0 1rem 1rem 0); + @include nb-rtl(margin, 0 0 1rem 1rem); } } /* stylelint-disable */ toaster-container /deep/ { - #toast-container .toast-close-button { + #toast-container .toast-close-button { right: 0; } } diff --git a/src/app/pages/dashboard/contacts/contacts.component.scss b/src/app/pages/dashboard/contacts/contacts.component.scss index 5c2b407062..d582d231e5 100644 --- a/src/app/pages/dashboard/contacts/contacts.component.scss +++ b/src/app/pages/dashboard/contacts/contacts.component.scss @@ -39,7 +39,8 @@ nb-user /deep/ { .info-container { - margin-left: 0.875rem; + @include nb-ltr(margin-left, 0.875rem); + @include nb-rtl(margin-right, 0.875rem); } .user-name { @@ -60,5 +61,3 @@ } } } - - diff --git a/src/app/pages/dashboard/rooms/player/player.component.html b/src/app/pages/dashboard/rooms/player/player.component.html index ecf18a5004..020f015181 100644 --- a/src/app/pages/dashboard/rooms/player/player.component.html +++ b/src/app/pages/dashboard/rooms/player/player.component.html @@ -11,7 +11,7 @@

{{ track.name }}

-
diff --git a/src/app/pages/dashboard/rooms/player/player.component.scss b/src/app/pages/dashboard/rooms/player/player.component.scss index 12ba71a3f1..fdeaa3c50b 100644 --- a/src/app/pages/dashboard/rooms/player/player.component.scss +++ b/src/app/pages/dashboard/rooms/player/player.component.scss @@ -60,6 +60,7 @@ background-color: nb-theme(color-success); height: 2px; position: absolute; + left: 0; margin-top: calc(0.75rem - 1px); width: 100px; @@ -107,12 +108,22 @@ display: flex; justify-content: space-between; color: nb-theme(color-fg); + + .current { + @include nb-ltr(order, 0); + @include nb-rtl(order, 1); + } + .remaining { + @include nb-ltr(order, 1); + @include nb-rtl(order, 0); + } } .controls { display: flex; justify-content: space-between; align-items: center; + @include nb-rtl(flex-direction, row-reverse); padding: 0.25rem 2rem 1rem; max-width: 400px; width: 100%; @@ -171,6 +182,7 @@ width: 80%; .progress-foreground { + left: auto; margin-top: calc(1rem + 1px); z-index: 0; } diff --git a/src/app/pages/dashboard/security-cameras/security-cameras.component.scss b/src/app/pages/dashboard/security-cameras/security-cameras.component.scss index 5bc1abeca2..8e9ab67f91 100644 --- a/src/app/pages/dashboard/security-cameras/security-cameras.component.scss +++ b/src/app/pages/dashboard/security-cameras/security-cameras.component.scss @@ -40,11 +40,13 @@ } a:first-child { - border-left: 1px solid nb-theme(separator); + @include nb-ltr(border-left, 1px solid nb-theme(separator)); + @include nb-rtl(border-right, 1px solid nb-theme(separator)); } a:last-child { - border-top-right-radius: nb-theme(card-border-radius); + @include nb-ltr(border-top-right-radius, nb-theme(card-border-radius)); + @include nb-rtl(border-top-left-radius, nb-theme(card-border-radius)); } a.active { diff --git a/src/app/pages/dashboard/solar/solar.component.scss b/src/app/pages/dashboard/solar/solar.component.scss index c9480638e0..375b93c0ae 100644 --- a/src/app/pages/dashboard/solar/solar.component.scss +++ b/src/app/pages/dashboard/solar/solar.component.scss @@ -13,6 +13,7 @@ .echart { position: absolute; + left: 1em; height: calc(100% - 2 * #{$padding}); width: 40%; } diff --git a/src/app/pages/dashboard/status-card/status-card.component.scss b/src/app/pages/dashboard/status-card/status-card.component.scss index 08abc6113b..40175fb0b2 100644 --- a/src/app/pages/dashboard/status-card/status-card.component.scss +++ b/src/app/pages/dashboard/status-card/status-card.component.scss @@ -90,7 +90,8 @@ flex-direction: column; justify-content: center; height: 100%; - padding: 0 0.5rem 0 0.75rem; + @include nb-ltr(padding, 0 0.5rem 0 0.75rem); + @include nb-rtl(padding, 0 0.75rem 0 0.5rem); border-left: 1px solid transparent; } @@ -112,7 +113,8 @@ @include nb-for-theme(cosmic) { nb-card { &.off .icon-container { - border-right: 1px solid nb-theme(separator); + @include nb-ltr(border-right, 1px solid nb-theme(separator)); + @include nb-rtl(border-left, 1px solid nb-theme(separator)); } .icon-container { @@ -120,14 +122,16 @@ } .details { - padding-left: 1.25rem; + @include nb-ltr(padding-left, 1.25rem); + @include nb-rtl(padding-right, 1.25rem); } .icon { width: 7rem; height: 100%; font-size: 4.5rem; - border-radius: nb-theme(card-border-radius) 0 0 nb-theme(card-border-radius); + @include nb-ltr(border-radius, nb-theme(card-border-radius) 0 0 nb-theme(card-border-radius)); + @include nb-rtl(border-radius, 0 nb-theme(card-border-radius) nb-theme(card-border-radius) 0); } .title { diff --git a/src/app/pages/forms/form-inputs/form-inputs.component.html b/src/app/pages/forms/form-inputs/form-inputs.component.html index 3a8277fb60..6331c2b7c5 100644 --- a/src/app/pages/forms/form-inputs/form-inputs.component.html +++ b/src/app/pages/forms/form-inputs/form-inputs.component.html @@ -73,7 +73,7 @@
-