...
 
Commits (3)
......@@ -13,7 +13,7 @@
dndDropzone
[dndHorizontal]="false"
[dndEffectAllowed]="dndEffectAllowed"
(dndStart)="onDragStart($event)"
(dndStart)="dragging = true"
(dndDrop)="onDrop($event)"
class="m-draggableList__list"
[ngClass]="{ dragging: dragging }"
......
......@@ -23,7 +23,7 @@ export class DraggableListComponent {
@Input() headers: string[];
@ContentChild(TemplateRef, { static: false }) template: TemplateRef<any>;
@Output() emptyListHeaderRowClicked: EventEmitter<any> = new EventEmitter();
@Output() itemRemoved: EventEmitter<number> = new EventEmitter();
@Output() arrayChanged: EventEmitter<any> = new EventEmitter();
dragging: boolean = false;
......@@ -33,7 +33,7 @@ export class DraggableListComponent {
onDrop(event: DndDropEvent) {
this.dragging = false;
console.log(event);
if (
this.data &&
(event.dropEffect === 'copy' || event.dropEffect === 'move')
......@@ -41,7 +41,7 @@ export class DraggableListComponent {
let dragIndex = this.data.findIndex(
item => event.data[this.id] === item[this.id]
);
let dropIndex = event.index || this.data.length;
let dropIndex = event.index;
// remove element
this.data.splice(dragIndex, 1);
......@@ -51,14 +51,15 @@ export class DraggableListComponent {
}
this.data.splice(dropIndex, 0, event.data);
this.arrayChanged.emit(this.data);
}
}
onDragStart(event: DragEvent) {
this.dragging = true;
}
removeItem(index) {
this.itemRemoved.next(index);
console.log('***databefore removal', this.data, index);
this.data.splice(index, 1);
this.arrayChanged.emit(this.data);
console.log('***dataafter removal', this.data);
}
clickedHeaderRow($event) {
......
<m-sidebarMenu [menuId]="menuId"></m-sidebarMenu>
<m-sidebarMenu [menuId]="menuId" [menuObj]="menuObj"></m-sidebarMenu>
<section class="m-pageLayout__main">
<ng-content select="[m-pageLayout__main]"></ng-content>
</section>
......@@ -5,7 +5,8 @@ import { Component, OnInit, Input, HostBinding } from '@angular/core';
templateUrl: './page-layout.component.html',
})
export class PageLayoutComponent implements OnInit {
@Input() menuId: string;
@Input() menuId: string; // TODO remove this and use menuObj in analytics
@Input() menuObj: any;
@HostBinding('class.isForm') @Input() isForm: boolean = false;
constructor() {}
......
<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>
<ng-content></ng-content>
</button>
</div>
<!-- [ngClass]="{ transparent: saveStatus !== 'saving' }" -->
.m-shadowboxSubmitButton {
// display: grid;
min-width: 220px;
position: relative;
cursor: pointer;
......@@ -47,12 +46,8 @@ button {
outline: 0;
}
[class*='m-shadowboxSubmitButton__status'] {
// visibility: visible;
font-size: 17px;
font-weight: 300;
// &.transparent {
// visibility: hidden;
// }
}
@keyframes blink {
......
......@@ -43,7 +43,7 @@ export class SidebarMenuComponent implements OnInit {
? this.menuObj
: sidebarMenus.find(menu => menu.header.id === this.menuId);
this.getUserRoles();
this.grantPermissionsAndFindActiveMenu();
this.grantPermissions();
}
getUserRoles() {
......@@ -55,7 +55,7 @@ export class SidebarMenuComponent implements OnInit {
}
}
grantPermissionsAndFindActiveMenu() {
grantPermissions() {
this.menu.header['permissionGranted'] = this.menu.header.permissions
? this.checkForRoleMatch(this.menu.header.permissions)
: true;
......
......@@ -26,7 +26,7 @@ const sidebarMenus = [
id: 'engagement',
label: 'Engagement',
permissions: ['admin', 'user'],
// path: '/some/path/outside/header/path',
// path: '/some/path/outside/analytics/dashboard',
},
{
id: 'trending',
......@@ -59,51 +59,6 @@ const sidebarMenus = [
// },
],
},
{
header: {
id: 'pro_settings',
label: 'Pro Settings',
path: '/pro/settings/',
permissions: ['pro'],
},
links: [
{
id: 'general',
label: 'General',
},
{
id: 'theme',
label: 'Theme',
},
{
id: 'assets',
label: 'Assets',
},
{
id: 'hashtags',
label: 'Hashtags',
},
{
id: 'footer',
label: 'Footer',
},
{
id: 'domain',
label: 'Domain',
},
{
id: 'subscription',
label: 'Pro Subscription',
path: 'pro',
},
{
id: ':user',
label: 'View Pro Channel',
path: ':user',
newWindow: true,
},
],
},
];
export default sidebarMenus;
<m-pageLayout menuId="pro_settings" [isForm]="true">
<m-pageLayout [menuObj]="menuObj" [isForm]="true">
<ng-container m-pageLayout__main *ngIf="settings">
<m-shadowboxLayout
[scrollableHeader]="false"
......@@ -11,7 +11,7 @@
<div class="mdl-spinner mdl-js-spinner is-active" [mdl]></div>
</div>
<ng-container *ngIf="settings && activeTab">
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<form [formGroup]="form" (ngSubmit)="onSubmit()" #f="ngForm">
<ng-container [ngSwitch]="activeTab.id">
<!-- General -->
<ng-template ngSwitchCase="general">
......@@ -206,7 +206,7 @@
Plain Background Color </label
><m-tooltip icon="help">
<ng-container i18n
>The colour of your background</ng-container
>The color of your background</ng-container
>
</m-tooltip>
</div>
......@@ -455,7 +455,7 @@
[data]="form.value.hashtags"
[id]="'tag'"
(emptyListHeaderRowClicked)="addBlankTag()"
(itemRemoved)="removeTag($event)"
(arrayChanged)="resetArray('hashtags', $event)"
>
<ng-template let-tag="item" let-i="i">
<ng-container [formGroupName]="i">
......@@ -463,8 +463,9 @@
class="m-draggableList__cell form-control"
type="text"
[id]="'tag-label-' + i"
[name]="'tag[' + i + ' ][label]'"
[name]="'tag[' + i + '][label]'"
formControlName="label"
autofocus
/>
<input
class="m-draggableList__cell form-control"
......@@ -533,7 +534,7 @@
[data]="form.value.footer.links"
[id]="'title'"
(emptyListHeaderRowClicked)="addBlankFooterLink()"
(removeItem)="removeFooterLink($event)"
(arrayChanged)="resetArray('footer.links', $event)"
>
<ng-template let-link="item" let-i="i">
<ng-container [formGroupName]="i">
......@@ -543,6 +544,7 @@
[id]="'footer_link-title-' + i"
[name]="'footer_link[' + i + '][title]'"
formControlName="title"
autofocus
/>
<input
......@@ -655,17 +657,30 @@
</m-pageLayout>
<ng-template #submitButton>
<m-shadowboxSubmitButton
[saveStatus]="activeTab.saveStatus"
[disabled]="!form.valid"
>
<!-- [disabled]="!activeForm.valid" -->
<ng-container m-shadowboxSubmitButton__status--unsaved>
Save
{{ activeTab.id === 'general' ? 'Personal Details' : activeTab.title }}
</ng-container>
<ng-container m-shadowboxSubmitButton__status--saved>
Saved
<m-shadowboxSubmitButton [disabled]="!form.valid">
<ng-container *ngIf="saveStatus !== 'saving'">
<div
*ngIf="form.dirty || form.touched"
class="m-shadowboxSubmitButton__status--unsaved"
>
Save
{{ activeTab.id === 'general' ? 'Personal Details' : activeTab.title }}
</div>
<div
*ngIf="!form.dirty && !form.touched && saveStatus !== 'unsaved'"
class="m-shadowboxSubmitButton__status--saved"
>
Saved
</div>
</ng-container>
<div
*ngIf="saveStatus === 'saving'"
class="m-shadowboxSubmitButton__status--saving"
>
<span></span>
<span></span>
<span></span>
</div>
</m-shadowboxSubmitButton>
</ng-template>
......@@ -163,7 +163,7 @@ m-proSettings {
&:not(.m-draggableList__cell) {
&.ng-invalid.form-control {
@include m-theme() {
border-color: themed($m-red-dark);
border-color: themed($m-red-dark) !important;
}
}
}
......
......@@ -5,7 +5,6 @@ import {
ElementRef,
OnDestroy,
OnInit,
AfterViewInit,
ViewChild,
} from '@angular/core';
import { Subject, Subscription, from } from 'rxjs';
......@@ -17,6 +16,8 @@ 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 sidebarMenu from './sidebar-menu.default';
import { Menu } from '../../../common/components/sidebar-menu/sidebar-menu.component';
import {
NgForm,
FormBuilder,
......@@ -31,7 +32,8 @@ import {
changeDetection: ChangeDetectionStrategy.OnPush,
templateUrl: 'settings.component.html',
})
export class ProSettingsComponent implements OnInit, AfterViewInit, OnDestroy {
export class ProSettingsComponent implements OnInit, OnDestroy {
menuObj: Menu = sidebarMenu;
activeForm: NgForm;
activeTab: any;
tabs = [
......@@ -69,19 +71,19 @@ export class ProSettingsComponent implements OnInit, AfterViewInit, OnDestroy {
settings: any;
init: boolean = false;
inProgress: boolean;
saved: boolean = false;
saveStatus: string = 'unsaved';
user: string | null = null;
isDomainValid: boolean | null = null;
error: string;
hexPattern = '^#?([0-9A-Fa-f]{3}){1,2}$'; // accepts both 3- and 6-digit codes, hash is optional
hexPattern = '^#([0-9A-Fa-f]{3}){1,2}$'; // accepts both 3- and 6-digit codes, hash required
domainValidationSubject: Subject<any> = new Subject<any>();
......@@ -91,12 +93,16 @@ export class ProSettingsComponent implements OnInit, AfterViewInit, OnDestroy {
protected domainValidation$: Subscription;
protected formEl$: Subscription;
@ViewChild('logoField', { static: false })
protected logoField: ElementRef<HTMLInputElement>;
@ViewChild('backgroundField', { static: false })
protected backgroundField: ElementRef<HTMLInputElement>;
// @ViewChild('f', { static: false }) formEl: any;
form = this.fb.group({
title: ['', Validators.required],
headline: [''],
......@@ -140,23 +146,37 @@ export class ProSettingsComponent implements OnInit, AfterViewInit, 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.detectChanges();
}
this.saveStatus = 'unsaved';
this.detectChanges();
});
this.param$ = this.route.params.subscribe(params => {
if (this.session.isAdmin()) {
this.user = params['user'] || null;
}
this.load();
});
this.form.valueChanges.subscribe((value: any) => {
console.log(value);
console.log(this.form);
if (this.form.dirty) {
console.log('template form dirty - yes: ', value);
} else {
console.log('template form dirty - no: ');
}
});
if (this.isRemote) {
this.updatePreviewRoute();
}
}
ngAfterViewInit() {
this.init = true;
updatePreviewRoute() {
const previewRouteLink = this.menuObj.links.find(
link => link.id === ':user'
);
previewRouteLink.path = `pro/${this.user}`;
this.detectChanges();
}
......@@ -287,7 +307,7 @@ export class ProSettingsComponent implements OnInit, AfterViewInit, OnDestroy {
console.log(this.form);
console.log(this.form.value);
this.error = null;
this.activeTab.saveStatus = 'saving';
this.saveStatus = 'saving';
this.detectChanges();
await this.save();
......@@ -338,11 +358,11 @@ export class ProSettingsComponent implements OnInit, AfterViewInit, OnDestroy {
this.formToastService.success(
'Pro settings have been successfully updated'
);
this.activeTab.saveStatus = 'saved';
this.saveStatus = 'saved';
} catch (e) {
this.error = e.message;
this.formToastService.error('Error: ' + this.error);
this.activeTab.saveStatus = 'unsaved';
this.saveStatus = 'unsaved';
}
this.saved = true;
......@@ -364,12 +384,35 @@ export class ProSettingsComponent implements OnInit, AfterViewInit, OnDestroy {
);
}
removeTag(index: number) {
console.log('removing tag', index);
const hashtags = <FormArray>this.form.controls.hashtags;
hashtags.removeAt(index);
// removeTag(index: number) {
// const hashtags = <FormArray>this.form.controls.hashtags;
// }
resetArray(formArrayName: string, arrayAfterChange: any) {
console.log('***changedArray', arrayAfterChange, arrayAfterChange[0]);
const arrayBeforeChange = <FormArray>this.form.controls[formArrayName];
console.log(
'***FormArraybeforereset',
arrayBeforeChange.value,
arrayBeforeChange.value[0]
);
arrayBeforeChange.reset(arrayAfterChange);
console.log(
'***FormArrayafterereset',
arrayBeforeChange.value,
arrayBeforeChange.value[0]
);
this.detectChanges();
}
// removeFooterLink(index: number) {
// const links = <FormArray>this.form.controls.footer_links;
// links.removeAt(index);
// }
addBlankFooterLink() {
this.addFooterLink('', '');
}
......@@ -385,19 +428,11 @@ export class ProSettingsComponent implements OnInit, AfterViewInit, OnDestroy {
);
}
// removeFooterLink(index: number) {
// this.settings.footer_links.splice(index, 1);
// }
detectChanges() {
this.cd.markForCheck();
this.cd.detectChanges();
}
get previewRoute() {
return ['/pro', this.user || this.session.getLoggedInUser().username];
}
get ratios() {
return this.service.ratios;
}
......
const sidebarMenu = {
header: {
id: 'pro_settings',
label: 'Pro Settings',
path: '/pro/settings/',
permissions: ['pro'],
},
links: [
{
id: 'general',
label: 'General',
},
{
id: 'theme',
label: 'Theme',
},
{
id: 'assets',
label: 'Assets',
},
{
id: 'hashtags',
label: 'Hashtags',
},
{
id: 'footer',
label: 'Footer',
},
{
id: 'domain',
label: 'Domain',
},
{
id: 'subscription',
label: 'Pro Subscription',
path: 'pro',
},
{
id: ':user',
label: 'View Pro Channel',
path: 'pro/:user',
newWindow: true,
},
],
};
export default sidebarMenu;