...
 
Commits (3)
......@@ -123,6 +123,7 @@ import { ShadowboxLayoutComponent } from './components/shadowbox-layout/shadowbo
import { ShadowboxHeaderComponent } from './components/shadowbox-header/shadowbox-header.component';
import { FormDescriptorComponent } from './components/form-descriptor/form-descriptor.component';
import { FormToastComponent } from './components/form-toast/form-toast.component';
import { ShadowboxSubmitButtonComponent } from './components/shadowbox-submit-button/shadowbox-submit-button.component';
PlotlyModule.plotlyjs = PlotlyJS;
......@@ -236,6 +237,7 @@ PlotlyModule.plotlyjs = PlotlyJS;
ShadowboxHeaderComponent,
FormDescriptorComponent,
FormToastComponent,
ShadowboxSubmitButtonComponent,
],
exports: [
MINDS_PIPES,
......@@ -333,6 +335,7 @@ PlotlyModule.plotlyjs = PlotlyJS;
ShadowboxLayoutComponent,
FormDescriptorComponent,
FormToastComponent,
ShadowboxSubmitButtonComponent,
],
providers: [
SiteService,
......
<div class="m-formToast__toastsContainer">
<ng-container *ngFor="let toast of toasts; let i = index">
<div class="m-formToast__wrapper" *ngIf="toast.visible">
<div class="m-formToast__wrapper" [ngClass]="{ active: toast.visible }">
<i
class="material-icons m-formToast__icon--success"
*ngIf="toast.type === 'success'"
......@@ -16,9 +16,15 @@
*ngIf="toast.type === 'warning'"
>warning</i
>
<i
class="material-icons m-formToast__icon--info"
*ngIf="toast.type === 'info'"
></i>
<p i18n>{{ toast.message }}</p>
<div class="m-formToast__iconWrapper">
<i class="material-icons m-formToast__icon--close" (click)="dismiss(i)"
<i
class="material-icons m-formToast__icon--close"
(click)="toast.visible = false"
>clear</i
>
</div>
......
......@@ -2,12 +2,13 @@ m-formToast {
margin: 37px 70px 0 70px;
display: flex;
flex-flow: column nowrap;
min-width: 300px;
max-width: 522px;
position: fixed;
bottom: 24px;
bottom: 24;
}
.m-formToasts__toastsContainer {
min-width: 300px;
.m-formToast__toastsContainer {
height: auto;
transition: all 0.3s ease;
}
.m-formToast__wrapper {
......@@ -17,11 +18,16 @@ m-formToast {
padding: 13px;
margin-bottom: 16px;
display: flex;
opacity: 0;
transition: opacity 0.4s cubic-bezier(0.23, 1, 0.32, 1);
@include m-theme() {
color: themed($m-grey-600);
background-color: themed($m-white);
box-shadow: 0 0 15px 0 rgba(themed($m-black), 0.2);
}
&.active {
opacity: 1;
}
p {
flex-grow: 1;
margin: 0;
......@@ -46,37 +52,33 @@ m-formToast {
color: themed($m-amber-dark);
}
}
.m-formToast__icon--info {
margin-right: 14px;
}
.m-formToast__icon--close {
cursor: pointer;
transition: all 0.2s ease-out;
@include m-theme() {
color: themed($m-grey-400);
color: themed($m-grey-300);
}
&:hover {
transform: scale(1.2);
@include m-theme() {
color: themed($m-grey-200);
color: themed($m-grey-100);
}
}
&:active {
@include m-theme() {
color: themed($m-grey-600);
color: themed($m-grey-400);
}
}
}
@media screen and (max-width: $min-tablet) {
m-formToast {
// margin: 37px 24px 0 24px;
margin: 0px 24px;
margin: 0 auto;
max-width: 85%;
position: absolute;
bottom: 48px;
}
}
// TODOOJM
// @media screen and (max-width: $max-mobile) {
// m-formToast {
// position: fixed;
// }
// }
import { Component, OnInit, OnDestroy } from '@angular/core';
import {
Component,
OnInit,
OnDestroy,
ChangeDetectionStrategy,
ChangeDetectorRef,
} from '@angular/core';
import { FormToast, FormToastService } from '../../services/form-toast.service';
import { Subscription } from 'rxjs';
@Component({
selector: 'm-formToast',
templateUrl: './form-toast.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class FormToastComponent implements OnInit, OnDestroy {
toasts: FormToast[] = [];
timeoutIds: number[] = [];
subscription: Subscription;
constructor(private service: FormToastService) {}
constructor(
private service: FormToastService,
protected cd: ChangeDetectorRef
) {}
ngOnInit() {
this.subscription = this.service.onToast().subscribe(toast => {
// clear toasts when an empty toast is received
if (!toast.message) {
// clear toasts when an empty toast is received
this.toasts = [];
return;
}
toast['visible'] = true;
const toastIndex = this.toasts.push(toast) - 1;
console.log('***tolll', toast);
console.log(toastIndex);
this.detectChanges();
// TODOOJM something is wrong here
const toastTimeout = setTimeout(() => {
this.toasts[toastIndex].visible = false;
console.log('***to', this.toasts[toastIndex]);
}, 10000);
this.detectChanges();
}, 3000);
this.timeoutIds.push(setTimeout(() => toastTimeout));
});
}
dismiss(index) {
console.log(this.toasts[index]);
this.toasts[index].visible = false;
this.detectChanges();
}
detectChanges() {
this.cd.markForCheck();
this.cd.detectChanges();
}
ngOnDestroy() {
......
......@@ -2,6 +2,8 @@ m-pageLayout {
display: block;
position: relative;
width: 100%;
max-width: 1200px;
margin: auto;
min-height: 100%;
padding: 56px 0 48px 0;
@include m-theme() {
......@@ -9,7 +11,7 @@ m-pageLayout {
color: themed($m-grey-800);
}
&.isForm {
min-height: none;
min-height: 0px;
}
.m-tooltip {
......@@ -33,14 +35,14 @@ m-pageLayout {
m-sidebarMenu {
display: block;
box-sizing: border-box;
padding-left: 105px;
width: 245px;
padding-left: 20px;
@include m-theme() {
background-color: themed($m-white);
}
}
.m-pageLayout__main {
margin-left: 350px;
margin-left: 25%;
margin-right: 24px;
@include m-theme() {
......@@ -50,6 +52,12 @@ m-sidebarMenu {
}
@media screen and (max-width: $min-tablet) {
m-pageLayout {
&.isForm {
padding-bottom: 0px;
}
}
.m-pageLayout__main {
display: block;
margin: 0;
......
......@@ -16,8 +16,6 @@ m-shadowboxHeader {
.m-shadowboxHeader__container {
overflow-x: hidden;
overflow-y: hidden;
// display: flex;
// flex-wrap: nowrap;
transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
&.disable-scrollbars {
......
......@@ -17,7 +17,18 @@
</ng-container>
></m-shadowboxHeader
>
<div class="m-shadowboxLayout__bottom">
<div *ngIf="!isForm" class="m-shadowboxLayout__bottom">
<ng-content select=".m-shadowboxLayout__body"></ng-content>
<ng-content select=".m-shadowboxLayout__footer"></ng-content>
</div>
<ng-container *ngIf="isForm">
<ng-content
class="m-shadowboxLayout__bottom"
select=".m-shadowboxLayout__bottom"
>
<!-- <ng-content select=".m-shadowboxLayout__body"></ng-content>
<ng-content select=".m-shadowboxLayout__footer"></ng-content> -->
</ng-content>
</ng-container>
......@@ -31,10 +31,8 @@ m-shadowboxHeader.isScrollable {
.m-shadowboxLayout__button {
cursor: pointer;
padding: 10px 20px;
font-size: 17px;
font-weight: 300;
background-color: #4fc3a9;
height: 43px;
min-height: 43px;
border: 0;
transition: all 0.2s ease;
border-radius: 2px;
......@@ -44,9 +42,6 @@ m-shadowboxHeader.isScrollable {
}
&:hover {
transform: scale(1.02);
// background-color: #4cb9a0;
}
&:active {
background-color: #55ccb2;
@include m-theme() {
box-shadow: 0 3px 3px -2px rgba(themed($m-black), 0.2),
......@@ -54,17 +49,67 @@ m-shadowboxHeader.isScrollable {
0 1px 7px 0 rgba(themed($m-black), 0.12);
}
}
&:active {
transform: scale(0.999);
@include m-theme() {
box-shadow: 0 3px 2px -2px rgba(themed($m-black), 0.2),
0 2px 3px 0 rgba(themed($m-black), 0.14),
0 1px 5px 0 rgba(themed($m-black), 0.12);
}
}
&:disabled,
&[disabled] {
cursor: default;
@include m-theme() {
background-color: themed($m-grey-200);
background-color: themed($m-grey-100);
}
}
p {
margin: 0;
font-size: 17px;
font-weight: 300;
span {
font-size: 72px;
}
}
}
button {
outline: 0;
}
@keyframes blink {
0% {
opacity: 0.2;
transform: scale(2.1);
font-size: 77px;
}
20% {
opacity: 1;
transform: scale(1.2);
font-size: 90px;
}
100% {
opacity: 0.2;
transform: scale(1.3);
}
}
p.m-shadowboxLayout__buttonStatus--saving {
// line-height:70px
span {
animation-name: blink;
animation-duration: 1.4s;
animation-iteration-count: infinite;
animation-fill-mode: both;
&:nth-child(2) {
animation-delay: 0.2s;
}
&:nth-child(3) {
animation-delay: 0.4s;
}
}
}
// ---------------------------------------
m-shadowboxLayout.isForm {
margin-top: 69px;
......@@ -108,7 +153,7 @@ m-shadowboxLayout.isForm {
}
.m-shadowboxLayout__footer {
justify-content: center;
padding: 24px;
padding: 24px 24px 48px 24px;
}
}
}
......
<div class="m-shadowboxLayout__footer">
<button class="m-shadowboxSubmitButton" type="submit" [disabled]="disabled">
<div
[hidden]="saveStatus !== 'unsaved'"
class="m-shadowboxSubmitButton__status--unsaved"
>
<ng-content
select="[m-shadowboxSubmitButton__status--unsaved]"
></ng-content>
</div>
<div
[hidden]="saveStatus !== 'saving'"
class="m-shadowboxSubmitButton__status--saving"
>
<span></span>
<span></span>
<span></span>
</div>
<div
[hidden]="saveStatus !== 'saved'"
class="m-shadowboxSubmitButton__status--saved"
>
<ng-content
select="[m-shadowboxSubmitButton__status--saved]"
></ng-content>
</div>
</button>
</div>
<!-- [ngClass]="{ transparent: saveStatus !== 'saving' }" -->
.m-shadowboxSubmitButton {
// display: grid;
min-width: 220px;
position: relative;
cursor: pointer;
padding: 10px 20px;
background-color: #4fc3a9;
min-height: 43px;
border: 0;
transition: all 0.2s ease;
border-radius: 2px;
outline: 0;
@include m-theme() {
color: themed($m-white);
}
&:hover {
&:not(:disabled) {
transform: scale(1.02);
background-color: #55ccb2;
@include m-theme() {
box-shadow: 0 3px 3px -2px rgba(themed($m-black), 0.2),
0 2px 5px 0 rgba(themed($m-black), 0.14),
0 1px 7px 0 rgba(themed($m-black), 0.12);
}
}
}
&:active {
&:not(:disabled) {
transform: scale(0.999);
background-color: #4fc3a9;
@include m-theme() {
box-shadow: 0 3px 2px -2px rgba(themed($m-black), 0.2),
0 2px 3px 0 rgba(themed($m-black), 0.14),
0 1px 5px 0 rgba(themed($m-black), 0.12);
}
}
}
&:disabled,
&[disabled] {
cursor: default;
@include m-theme() {
background-color: themed($m-grey-100);
}
}
}
button {
outline: 0;
}
[class*='m-shadowboxSubmitButton__status'] {
// visibility: visible;
font-size: 17px;
font-weight: 300;
// &.transparent {
// visibility: hidden;
// }
}
@keyframes blink {
0% {
opacity: 0.2;
}
20% {
opacity: 1;
transform: scale(1.05);
}
100% {
opacity: 0.2;
transform: scale(0.9);
}
}
.m-shadowboxSubmitButton__status--saving {
span {
display: inline-block;
height: 8px;
width: 8px;
margin: 0 6px;
border-radius: 50%;
animation-name: blink;
animation-duration: 1.4s;
animation-iteration-count: infinite;
animation-fill-mode: both;
@include m-theme() {
background-color: themed($m-white);
}
&:nth-child(2) {
animation-delay: 0.2s;
}
&:nth-child(3) {
animation-delay: 0.4s;
}
}
}
@media screen and (max-width: $max-mobile) {
m-shadowboxSubmitButton {
min-width: 50%;
}
}
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ShadowboxSubmitButtonComponent } from './shadowbox-submit-button.component';
describe('ShadowboxSubmitButtonComponent', () => {
let component: ShadowboxSubmitButtonComponent;
let fixture: ComponentFixture<ShadowboxSubmitButtonComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ShadowboxSubmitButtonComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ShadowboxSubmitButtonComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'm-shadowboxSubmitButton',
templateUrl: './shadowbox-submit-button.component.html',
})
export class ShadowboxSubmitButtonComponent implements OnInit {
@Input() saveStatus: string = 'unsaved';
@Input() disabled: boolean = false;
constructor() {}
ngOnInit() {}
}
......@@ -29,43 +29,38 @@
</div> -->
</div>
</a>
<!-- <ng-container *ngFor="let menu of menus"> -->
<div
class="m-sidebarMenu__menuContainer expanded"
*ngIf="menu.header.permissionGranted"
>
<!-- [ngClass]="{ expanded: menu.header.expanded }" -->
<div class="m-sidebarMenu__header">
<h3>{{ menu.header.label }}</h3>
<!-- <i
class="material-icons"
*ngIf="menu.header.expanded && menu.links"
(click)="menu.header.expanded = false"
>keyboard_arrow_up</i
> -->
<!-- <i class="material-icons" *ngIf="!menu.header.expanded && menu.links"
>keyboard_arrow_down</i
> -->
<!-- (click)="menu.header.expanded = true" -->
</div>
<nav class="m-sidebarMenu__linksContainer" *ngIf="menu.links">
<div class="m-sidebarMenu__link" *ngFor="let link of menu.links">
<!-- OJMTODO: fix target _blank -->
<a
*ngIf="link.permissionGranted"
(click)="mobileMenuExpanded = false"
[routerLink]="link.path ? '/' + link.path : '../' + link.id"
routerLinkActive="selected"
[routerLinkActiveOptions]="{ exact: true }"
[target]="link.newWindow ? '_blank' : '_self'"
[ngClass]="{ newWindow: link.newWindow }"
><i class="material-icons" *ngIf="link.newWindow">launch</i>
<span>{{ link.label }}</span></a
<ng-container *ngIf="link.permissionGranted">
<ng-container *ngIf="!link.newWindow">
<a
(click)="mobileMenuExpanded = false"
[routerLink]="link.path ? '/' + link.path : '../' + link.id"
routerLinkActive="selected"
[routerLinkActiveOptions]="{ exact: true }"
>
<span>{{ link.label }}</span></a
>
</ng-container>
<ng-container *ngIf="link.newWindow"
><a
[routerLink]="link.path ? ['/' + link.path] : ['../' + link.id]"
target="_blank"
class="newWindow"
><i class="material-icons">launch</i>
<span>{{ link.label }}</span></a
></ng-container
></ng-container
>
</div>
</nav>
</div>
<!-- </ng-container> -->
</div>
......@@ -26,6 +26,7 @@ export { MenuLink };
})
export class SidebarMenuComponent implements OnInit {
@Input() menuId: string;
@Input() menuObj: Menu;
menu: Menu;
mobileMenuExpanded = false;
......@@ -38,7 +39,9 @@ export class SidebarMenuComponent implements OnInit {
ngOnInit() {
this.minds = window.Minds;
this.user = this.session.getLoggedInUser();
this.menu = sidebarMenus.find(menu => menu.header.id === this.menuId);
this.menu = this.menuObj
? this.menuObj
: sidebarMenus.find(menu => menu.header.id === this.menuId);
this.getUserRoles();
this.grantPermissionsAndFindActiveMenu();
}
......@@ -53,7 +56,6 @@ export class SidebarMenuComponent implements OnInit {
}
grantPermissionsAndFindActiveMenu() {
// this.menu.forEach(this.menu => {
this.menu.header['permissionGranted'] = this.menu.header.permissions
? this.checkForRoleMatch(this.menu.header.permissions)
: true;
......@@ -72,14 +74,6 @@ export class SidebarMenuComponent implements OnInit {
}
});
}
// if (location.pathname.indexOf(this.menus.header.path) !== -1) {
// this.menus.header['expanded'] = true;
// this.activeMenu = this.menu;
// } else {
// this.menu.header['expanded'] = false;
// }
// });
}
checkForRoleMatch(permissionsArray) {
......
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
// import { filter } from 'rxjs/operators';
export interface FormToast {
type?: 'success' | 'error' | 'warning' | 'info' | null;
......@@ -13,11 +12,8 @@ export class FormToastService {
private subject = new Subject<FormToast>();
constructor() {}
// enable subscribing to toasts observable
onToast(): Observable<FormToast> {
return this.subject.asObservable();
// .pipe(filter(x => x);
// .pipe(filter(x => x && x.toastId === toastId));
}
success(message: string) {
......@@ -47,14 +43,16 @@ export class FormToastService {
inform(message: string) {
const toast: FormToast = {
message: message,
type: 'error',
type: 'info',
};
this.trigger(toast);
}
trigger(toast: FormToast) {
toast['visible'] = true;
if (!toast.type) toast.type = 'info';
if (!toast.type) {
toast.type = 'info';
}
this.subject.next(toast);
}
}
m-proSettings {
display: block;
@include m-theme() {
background-color: themed($m-white);
}
form {
margin: 0;
padding: 0;
......@@ -17,23 +21,28 @@ m-proSettings {
[class*='m-proSettings__field'] {
position: relative;
margin-top: 28px;
margin-bottom: 28px;
font-size: 15px;
line-height: 20px;
font-weight: 300;
@include m-theme() {
color: themed($m-grey-800);
}
&:first-child {
margin-top: 0;
&:last-child {
margin-bottom: 42px;
}
&.hasValidationRow {
&:not(:last-child) {
margin-bottom: 6px;
}
}
&[class$='--checkbox'],
&[class$='--radio'] {
&.m-proSettings__field--checkbox,
&.m-proSettings__field--radio {
align-items: center;
flex-flow: row wrap;
}
&[class$='--radio'] {
&.m-proSettings__field--radio {
.m-proSettings__row--label {
margin-bottom: 21px;
}
......@@ -50,17 +59,30 @@ m-proSettings {
flex-flow: row nowrap;
position: relative;
}
&[class$='--validation'] {
margin-top: 3px;
min-height: 22px;
p {
font-size: 14px;
line-height: 19px;
margin: 0 8px 0 0;
font-weight: 300;
@include m-theme() {
color: themed($m-red-dark);
}
}
}
}
.stretchedField {
.m-proSettings__row--label m-tooltip {
margin-left: -12px;
.m-tooltip--bubble {
right: 12px;
}
}
.m-proSettings__row--input {
flex-flow: row nowrap;
}
.m-proSettings__row--validation {
justify-content: flex-end;
}
label,
input,
textarea {
......@@ -70,9 +92,11 @@ m-proSettings {
}
.m-proSettings__field--color {
.m-proSettings__row--input input {
width: 120px;
box-sizing: border-box;
.m-proSettings__row--input {
input {
width: 120px;
box-sizing: border-box;
}
}
}
......@@ -122,8 +146,24 @@ m-proSettings {
border: 1px solid themed($m-grey-50);
}
&:focus {
&:not(:read-only) {
@include m-theme() {
border-color: themed($m-blue);
}
}
}
}
}
input,
textarea {
&:not(:read-only):not(:-moz-read-only) {
cursor: default;
}
&:not(.m-draggableList__cell) {
&.ng-invalid.form-control {
@include m-theme() {
border-color: themed($m-blue);
border-color: themed($m-red-dark);
}
}
}
......@@ -162,17 +202,22 @@ m-proSettings {
background-color: themed($m-white);
}
&:hover {
transform: scale(1.04);
@include m-theme() {
border-color: rgba(themed($m-grey-200), 0.7);
box-shadow: 0 3px 2px -5px rgba(themed($m-black), 0.1),
0 2px 2px 0 rgba(themed($m-black), 0.04),
0 1px 4px 0 rgba(themed($m-black), 0.05);
}
}
&:active {
transform: scale(0.98);
@include m-theme() {
box-shadow: 0 1px 1px -4px rgba(themed($m-black), 0.2),
0 2px 2px 0 rgba(themed($m-black), 0.14),
0 1px 2px 0 rgba(themed($m-black), 0.12);
box-shadow: 0 3px 1px -6px rgba(themed($m-black), 0.12),
0 0px 1px 0 rgba(themed($m-black), 0.07),
0 1px 2px 0 rgba(themed($m-black), 0.08);
}
}
&:disabled,
&[disabled] {
cursor: default;
......@@ -233,7 +278,7 @@ m-proSettings {
object-fit: cover;
}
}
&[class$='__overlay'] {
&[class$='Overlay'] {
opacity: 0;
position: absolute;
top: 0;
......@@ -249,12 +294,12 @@ m-proSettings {
background: rgba(themed($m-black-always), 0.4);
}
&:hover {
.m-proSettings__filePreviewOverlay {
opacity: 1;
// display: flex;
// align-items: center;
// justify-content: center;
}
// .m-proSettings__filePreviewOverlay {
opacity: 1;
// display: flex;
// align-items: center;
// justify-content: center;
// }
}
}
......@@ -290,25 +335,11 @@ m-proSettings {
&.m-proSettingsDomain__validIcon--false i.material-icons {
@include m-theme() {
color: themed($m-red);
color: themed($m-red-dark);
}
}
}
.m-proSettings__error {
margin: 0 0 16px 0;
padding: 8px;
border-radius: 8px;
border: 1px solid;
font-size: 14px;
line-height: 1;
@include m-theme() {
color: themed($m-red);
border-color: themed($m-red);
}
}
m-formDescriptor {
box-sizing: border-box;
flex: 1 0 160px;
......@@ -331,6 +362,11 @@ m-proSettings {
-ms-user-select: none;
user-select: none;
&[class$='--radio'] {
margin: 0 24px 12px 0;
padding-left: 30px;
}
input {
position: absolute;
opacity: 0;
......@@ -338,8 +374,10 @@ m-proSettings {
height: 0;
width: 0;
&:checked ~ [class*='m-proSettings__customInput'] {
@include m-theme() {
background-color: themed($m-blue);
&[class$='--checkbox'] {
@include m-theme() {
background-color: themed($m-blue);
}
}
&:after {
display: block;
......@@ -380,12 +418,12 @@ m-proSettings {
}
&:after {
border-radius: 50%;
left: 8px;
top: 8px;
width: 7px;
height: 7px;
left: 3px;
top: 3px;
width: 0px;
height: 0px;
@include m-theme() {
border: 2px solid themed($m-blue);
border: 7px solid themed($m-blue);
}
}
}
......@@ -406,6 +444,12 @@ m-proSettings {
@media screen and (max-width: 1000px) {
m-proSettings {
.stretchedField {
// .m-proSettings__row--label m-tooltip {
// .m-tooltip--bubble {
// right: 12px;
// }
// }
[class*='m-proSettings__row'] {
flex-flow: row wrap;
label,
......@@ -427,3 +471,14 @@ m-proSettings {
}
}
}
@media screen and (max-width: $min-tablet) {
m-proSettings {
.stretchedField {
.m-proSettings__row--label m-tooltip {
.m-tooltip--bubble {
right: 12px;
}
}
}
}
}
......@@ -5,6 +5,7 @@ import {
ElementRef,
OnDestroy,
OnInit,
AfterViewInit,
ViewChild,
} from '@angular/core';
import { Subject, Subscription } from 'rxjs';
......@@ -16,17 +17,15 @@ import { SiteService } from '../../../common/services/site.service';
import { debounceTime } from 'rxjs/operators';
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
import { FormToastService } from '../../../common/services/form-toast.service';
import { NgForm } from '@angular/forms';
@Component({
selector: 'm-proSettings',
changeDetection: ChangeDetectionStrategy.OnPush,
templateUrl: 'settings.component.html',
})
export class ProSettingsComponent implements OnInit, OnDestroy {
//OJMTODO remove this
toastIndex: number = 0;
toastMessages = ['rye', 'wheat', '7-grain', 'bagel', 'pumpernickel'];
export class ProSettingsComponent implements OnInit, AfterViewInit, OnDestroy {
activeForm: NgForm;
activeTab: any;
tabs = [
{
......@@ -63,6 +62,8 @@ export class ProSettingsComponent implements OnInit, OnDestroy {
settings: any;
init: boolean = false;
inProgress: boolean;
saved: boolean = false;
......@@ -73,7 +74,7 @@ export class ProSettingsComponent implements OnInit, OnDestroy {
error: string;
saveSuccessful: boolean;
hexPattern = '^#?([0-9A-Fa-f]{3}){1,2}$'; // accepts both 3- and 6-digit codes, hash is optional
domainValidationSubject: Subject<any> = new Subject<any>();
......@@ -89,6 +90,9 @@ export class ProSettingsComponent implements OnInit, OnDestroy {
@ViewChild('backgroundField', { static: false })
protected backgroundField: ElementRef<HTMLInputElement>;
// TODO: make one of these for each form
@ViewChild('themeForm', { static: false }) themeForm: NgForm;
constructor(
protected service: ProService,
protected session: Session,
......@@ -105,6 +109,11 @@ export class ProSettingsComponent implements OnInit, OnDestroy {
this.paramMap$ = this.route.paramMap.subscribe((params: ParamMap) => {
const activeTabParam = params.get('tab');
this.activeTab = this.tabs.find(tab => tab.id === activeTabParam);
this.activeTab['saveStatus'] = 'unsaved';
if (this.init) {
this.getActiveForm();
this.detectChanges();
}
});
this.param$ = this.route.params.subscribe(params => {
......@@ -120,22 +129,23 @@ export class ProSettingsComponent implements OnInit, OnDestroy {
.subscribe(() => this.validateDomain());
}
ngAfterViewInit() {
this.init = true;
this.getActiveForm();
this.detectChanges();
}
getActiveForm() {
const tempFormStr = this.activeTab.id + 'Form';
this.activeForm = this[tempFormStr];
console.log(this.activeForm);
}
ngOnDestroy() {
this.paramMap$.unsubscribe();
this.param$.unsubscribe();
this.domainValidation$.unsubscribe();
}
// OJMTODO remove this after testing
tempToast() {
this.formToastService.warn(this.toastMessages[this.toastIndex]);
if (this.toastIndex < 6) {
this.toastIndex++;
} else {
this.toastIndex = 0;
}
}
async load() {
this.inProgress = true;
this.detectChanges();
......@@ -169,6 +179,7 @@ export class ProSettingsComponent implements OnInit, OnDestroy {
} catch (e) {
this.isDomainValid = null;
this.error = (e && e.message) || 'Error checking domain';
this.formToastService.error(this.error);
}
this.detectChanges();
......@@ -217,6 +228,16 @@ export class ProSettingsComponent implements OnInit, OnDestroy {
return this.settings[`${type}_image`];
}
onSubmit(form) {
console.log(form);
console.log(form.value);
this.error = null;
this.activeTab.saveStatus = 'saving';
this.detectChanges();
// TODO: add '#' to colors without them
}
async save() {
this.error = null;
this.inProgress = true;
......@@ -243,10 +264,14 @@ export class ProSettingsComponent implements OnInit, OnDestroy {
this.settings = settings;
await this.service.set(this.settings, this.user);
this.saveSuccessful = true;
this.formToastService.success(
'Pro settings have been successfully updated'
);
this.activeTab.saveStatus = 'saved';
} catch (e) {
this.error = e.message;
this.saveSuccessful = false;
this.formToastService.error('Error: ' + this.error);
this.activeTab.saveStatus = 'unsaved';
}
this.saved = true;
......