Skip to content
Projects
Groups
Snippets
Help
Sign in / Register
Toggle navigation
Minds Frontend
Project overview
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Locked Files
Issues
805
Merge Requests
54
CI / CD
Security & Compliance
Packages
Wiki
Snippets
Members
Collapse sidebar
Close sidebar
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Minds
Minds Frontend
Compare Revisions
ba68b78d658bbb80d6a4a2059c797766835a4ada...d50b0fb56b3f5ff13c3a920b0d174cf25c482583
Source
d50b0fb56b3f5ff13c3a920b0d174cf25c482583
...
Target
ba68b78d658bbb80d6a4a2059c797766835a4ada
Compare
Commits (3)
(chore): update hex validator pattern
· caaa844c
Olivia Madrid
authored
7 hours ago
caaa844c
Merge branch 'pro-settings-2163' of gitlab.com:minds/front into pro-settings-2163
· a8f48939
Olivia Madrid
authored
7 hours ago
a8f48939
(refactor): communication btwn draggableList and FormArray
· d50b0fb5
Olivia Madrid
authored
17 minutes ago
d50b0fb5
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
158 additions
and
135 deletions
+158
-135
src/app/common/components/draggable-list/list.component.html
View file @
d50b0fb5
...
...
@@ -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 }"
...
...
This diff is collapsed.
src/app/common/components/draggable-list/list.component.ts
View file @
d50b0fb5
...
...
@@ -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
)
{
...
...
This diff is collapsed.
src/app/common/components/page-layout/page-layout.component.html
View file @
d50b0fb5
<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>
This diff is collapsed.
src/app/common/components/page-layout/page-layout.component.ts
View file @
d50b0fb5
...
...
@@ -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
()
{}
...
...
This diff is collapsed.
src/app/common/components/shadowbox-submit-button/shadowbox-submit-button.component.html
View file @
d50b0fb5
<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' }" -->
This diff is collapsed.
src/app/common/components/shadowbox-submit-button/shadowbox-submit-button.component.scss
View file @
d50b0fb5
.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
{
...
...
This diff is collapsed.
src/app/common/components/sidebar-menu/sidebar-menu.component.ts
View file @
d50b0fb5
...
...
@@ -43,7 +43,7 @@ export class SidebarMenuComponent implements OnInit {
?
this
.
menuObj
:
sidebarMenus
.
find
(
menu
=>
menu
.
header
.
id
===
this
.
menuId
);
this
.
getUserRoles
();
this
.
grantPermissions
AndFindActiveMenu
();
this
.
grantPermissions
();
}
getUserRoles
()
{
...
...
@@ -55,7 +55,7 @@ export class SidebarMenuComponent implements OnInit {
}
}
grantPermissions
AndFindActiveMenu
()
{
grantPermissions
()
{
this
.
menu
.
header
[
'
permissionGranted
'
]
=
this
.
menu
.
header
.
permissions
?
this
.
checkForRoleMatch
(
this
.
menu
.
header
.
permissions
)
:
true
;
...
...
This diff is collapsed.
src/app/common/components/sidebar-menu/sidebar-menus.default.ts
View file @
d50b0fb5
...
...
@@ -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
;
This diff is collapsed.
src/app/modules/pro/settings/settings.component.html
View file @
d50b0fb5
<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 colo
u
r 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>
This diff is collapsed.
src/app/modules/pro/settings/settings.component.scss
View file @
d50b0fb5
...
...
@@ -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
;
}
}
}
...
...
This diff is collapsed.
src/app/modules/pro/settings/settings.component.ts
View file @
d50b0fb5
...
...
@@ -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
;
}
...
...
This diff is collapsed.
src/app/modules/pro/settings/sidebar-menu.default.ts
0 → 100644
View file @
d50b0fb5
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
;
This diff is collapsed.