Skip to content
Next
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Switch to GitLab Next
Sign in / Register
Toggle navigation
Minds Frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Insights
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Locked Files
Issues
839
Issues
839
List
Boards
Labels
Service Desk
Milestones
Merge Requests
45
Merge Requests
45
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Security & Compliance
Security & Compliance
Dependency List
Packages
Packages
List
Container Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Minds
Minds Frontend
Commits
161369a1
Commit
161369a1
authored
1 hour ago
by
Emiliano Balbuena
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
(feat): Allow admins to edit Pro settings; custom <head> support
Closes
#1894
Closes
#1896
parent
ae9cbe2a
epic/minds-pro
1 merge request
!528
WIP: (feat): Minds Pro
Pipeline
#81678765
failed with stages
in 5 minutes and 11 seconds
Changes
11
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
155 additions
and
41 deletions
+155
-41
navigation.component.scss
src/app/common/layout/topbar/navigation.component.scss
+1
-0
channel-container.component.html
...odules/channel-container/channel-container.component.html
+1
-1
channel-container.component.ts
.../modules/channel-container/channel-container.component.ts
+10
-1
sidebar.html
src/app/modules/channels/sidebar/sidebar.html
+17
-18
sidebar.ts
src/app/modules/channels/sidebar/sidebar.ts
+27
-0
pro.service.ts
src/app/modules/pro/pro.service.ts
+16
-4
settings.component.html
src/app/modules/pro/settings/settings.component.html
+24
-7
settings.component.scss
src/app/modules/pro/settings/settings.component.scss
+11
-0
settings.component.ts
src/app/modules/pro/settings/settings.component.ts
+35
-8
site.service.ts
src/app/services/site.service.ts
+6
-2
index.php
src/index.php
+7
-0
No files found.
src/app/common/layout/topbar/navigation.component.scss
View file @
161369a1
...
...
@@ -8,6 +8,7 @@
@media
screen
and
(
max-width
:
$min-tablet
)
{
padding-left
:
0
;
flex-wrap
:
wrap
;
}
&
:not
(
.m-topbar--navigation--text-only
)
.m-topbar--navigation--item
span
{
...
...
This diff is collapsed.
Click to expand it.
src/app/modules/channel-container/channel-container.component.html
View file @
161369a1
<ng-container
*ngIf=
"channel; else loader"
>
<ng-container
*ngIf=
"!channel.pro || isOwner; else isProChannel"
>
<ng-container
*ngIf=
"!channel.pro || isOwner
|| isAdmin
; else isProChannel"
>
<m-channel
#channelComponent
></m-channel>
</ng-container>
<ng-template
#isProChannel
>
...
...
This diff is collapsed.
Click to expand it.
src/app/modules/channel-container/channel-container.component.ts
View file @
161369a1
...
...
@@ -84,7 +84,12 @@ export class ChannelContainerComponent implements OnInit, OnDestroy {
this
.
channel
=
response
.
channel
;
// NOTE: Temporary workaround until channel component supports children routes
if
(
!
this
.
site
.
isProDomain
&&
this
.
channel
.
pro
&&
!
this
.
isOwner
)
{
if
(
!
this
.
site
.
isProDomain
&&
this
.
channel
.
pro
&&
!
this
.
isOwner
&&
!
this
.
isAdmin
)
{
this
.
router
.
navigate
([
'
/pro
'
,
this
.
channel
.
username
],
{
replaceUrl
:
true
,
});
...
...
@@ -100,4 +105,8 @@ export class ChannelContainerComponent implements OnInit, OnDestroy {
const
currentUser
=
this
.
session
.
getLoggedInUser
();
return
this
.
channel
&&
currentUser
&&
this
.
channel
.
guid
==
currentUser
.
guid
;
}
get
isAdmin
()
{
return
this
.
site
.
isAdmin
;
}
}
This diff is collapsed.
Click to expand it.
src/app/modules/channels/sidebar/sidebar.html
View file @
161369a1
...
...
@@ -262,25 +262,24 @@
<span
[hidden]=
"!editing"
i18n=
"@@M__ACTION__SAVE"
>
Save
</span>
</button>
</div>
<ng-container
*ngIf=
"session.getLoggedInUser()?.guid == user.guid"
>
<a
*ngIf=
"!user.pro"
class=
"m-btn m-link-btn m-btn--with-icon m-btn--slim m-btn--action"
routerLink=
"/pro"
>
<i
class=
"material-icons"
>
business_center
</i>
<span
i18n
>
Become Pro
</span>
</a>
<a
*ngIf=
"user.pro"
class=
"m-btn m-link-btn m-btn--with-icon m-btn--slim"
routerLink=
"/pro/settings"
>
<i
class=
"material-icons"
>
business_center
</i>
<span
i18n
>
Pro
</span>
</a>
</ng-container>
<a
*ngIf=
"showBecomeProButton"
class=
"m-btn m-link-btn m-btn--with-icon m-btn--slim m-btn--action"
routerLink=
"/pro"
>
<i
class=
"material-icons"
>
business_center
</i>
<span
i18n
>
Become Pro
</span>
</a>
<a
*ngIf=
"showProSettings"
class=
"m-btn m-link-btn m-btn--with-icon m-btn--slim"
[routerLink]=
"proSettingsRouterLink"
>
<i
class=
"material-icons"
>
business_center
</i>
<span
i18n
>
Pro
</span>
</a>
<minds-button-boost
*ngIf=
"session.getLoggedInUser().guid == user.guid"
...
...
This diff is collapsed.
Click to expand it.
src/app/modules/channels/sidebar/sidebar.ts
View file @
161369a1
...
...
@@ -159,4 +159,31 @@ export class ChannelSidebar {
)
.
present
();
}
get
showBecomeProButton
()
{
const
isOwner
=
this
.
session
.
isLoggedIn
()
&&
this
.
session
.
getLoggedInUser
().
guid
==
this
.
user
.
guid
;
return
isOwner
&&
!
this
.
user
.
pro
;
}
get
showProSettings
()
{
const
isOwner
=
this
.
session
.
isLoggedIn
()
&&
this
.
session
.
getLoggedInUser
().
guid
==
this
.
user
.
guid
;
const
isAdmin
=
window
.
Minds
.
Admin
;
return
(
isOwner
||
isAdmin
)
&&
this
.
user
.
pro
;
}
get
proSettingsRouterLink
()
{
const
isAdmin
=
window
.
Minds
.
Admin
;
const
route
:
any
[]
=
[
'
/pro/settings
'
];
if
(
isAdmin
)
{
route
.
push
({
user
:
this
.
user
.
username
});
}
return
route
;
}
}
This diff is collapsed.
Click to expand it.
src/app/modules/pro/pro.service.ts
View file @
161369a1
...
...
@@ -28,9 +28,15 @@ export class ProService {
return
true
;
}
async
get
():
Promise
<
{
isActive
;
settings
}
>
{
async
get
(
remoteUser
:
string
|
null
=
null
):
Promise
<
{
isActive
;
settings
}
>
{
const
endpoint
=
[
'
api/v2/pro/settings
'
];
if
(
remoteUser
)
{
endpoint
.
push
(
remoteUser
);
}
const
{
isActive
,
settings
}
=
(
await
this
.
client
.
get
(
'
api/v2/pro/settings
'
,
endpoint
.
join
(
'
/
'
)
,
{},
{
cache
:
false
}
))
as
any
;
...
...
@@ -56,8 +62,14 @@ export class ProService {
return
{
isActive
,
settings
};
}
async
set
(
settings
):
Promise
<
boolean
>
{
await
this
.
client
.
post
(
'
api/v2/pro/settings
'
,
settings
);
async
set
(
settings
,
remoteUser
:
string
|
null
=
null
):
Promise
<
boolean
>
{
const
endpoint
=
[
'
api/v2/pro/settings
'
];
if
(
remoteUser
)
{
endpoint
.
push
(
remoteUser
);
}
await
this
.
client
.
post
(
endpoint
.
join
(
'
/
'
),
settings
);
return
true
;
}
}
This diff is collapsed.
Click to expand it.
src/app/modules/pro/settings/settings.component.html
View file @
161369a1
...
...
@@ -9,7 +9,7 @@
>
<span
i18n
>
General
</span>
<m-tooltip
icon=
"help"
i18n
>
TBD
Customize your title and headline.
</m-tooltip>
</a>
...
...
@@ -20,7 +20,7 @@
>
<span
i18n
>
Theme
</span>
<m-tooltip
icon=
"help"
i18n
>
TBD
Set up your color scheme.
</m-tooltip>
</a>
...
...
@@ -31,7 +31,7 @@
>
<span
i18n
>
Hashtags
</span>
<m-tooltip
icon=
"help"
i18n
>
TBD
Set up category filters using hashtags.
</m-tooltip>
</a>
...
...
@@ -42,7 +42,7 @@
>
<span
i18n
>
Footer
</span>
<m-tooltip
icon=
"help"
i18n
>
TBD
Set up site footer items.
</m-tooltip>
</a>
...
...
@@ -53,18 +53,19 @@
>
<span
i18n
>
Domain
</span>
<m-tooltip
icon=
"help"
i18n
>
TBD
Configure your custom domain.
</m-tooltip>
</a>
<a
*ngIf=
"!isRemote"
class=
"m-topbar--navigation--item"
[class.m-topbar--navigation--item-active]=
"currentTab === 'cancel'"
(click)=
"currentTab = 'cancel'"
>
<span
i18n
>
Cancel
</span>
<m-tooltip
icon=
"help"
i18n
>
TBD
Cancel your Pro subscription.
</m-tooltip>
</a>
</div>
...
...
@@ -316,7 +317,7 @@
</div>
</ng-template>
<!--
Cancel
-->
<!--
Domain
-->
<ng-template
ngSwitchCase=
"domain"
>
<p
class=
"m-pro--settings--note"
i18n
>
...
...
@@ -332,6 +333,22 @@
[(ngModel)]=
"settings.domain"
/>
</div>
<div
class=
"m-pro--settings--field"
>
<label
for=
"custom_head"
i18n
>
Custom
<
head
>
Code
</label>
<textarea
class=
"m-pro--settings--code-textarea"
id=
"custom_head"
name=
"custom_head"
[(ngModel)]=
"settings.custom_head"
[readOnly]=
"!isAdmin"
></textarea>
<p
*ngIf=
"!isAdmin"
class=
"m-pro--settings--note"
i18n
>
In order to customize this field, please contact a Minds admin
or email info@minds.com.
</p>
</div>
</ng-template>
<!-- Cancel -->
...
...
This diff is collapsed.
Click to expand it.
src/app/modules/pro/settings/settings.component.scss
View file @
161369a1
...
...
@@ -71,6 +71,17 @@
textarea
{
height
:
6em
;
resize
:
none
;
&
.m-pro--settings--code-textarea
{
font-family
:
monospace
;
font-size
:
13px
;
max-width
:
49em
;
height
:
12em
;
@media
screen
and
(
max-width
:
768px
)
{
max-width
:
100%
;
}
}
}
&
.m-pro--settings--field-actions
{
...
...
This diff is collapsed.
Click to expand it.
src/app/modules/pro/settings/settings.component.ts
View file @
161369a1
...
...
@@ -2,19 +2,22 @@ import {
ChangeDetectionStrategy
,
ChangeDetectorRef
,
Component
,
OnDestroy
,
OnInit
,
}
from
'
@angular/core
'
;
import
{
ProService
}
from
'
../pro.service
'
;
import
{
Session
}
from
'
../../../services/session
'
;
import
{
Router
}
from
'
@angular/router
'
;
import
{
ActivatedRoute
,
Router
}
from
'
@angular/router
'
;
import
{
MindsTitle
}
from
'
../../../services/ux/title
'
;
import
{
Subscription
}
from
'
rxjs
'
;
import
{
SiteService
}
from
'
../../../services/site.service
'
;
@
Component
({
selector
:
'
m-pro--settings
'
,
changeDetection
:
ChangeDetectionStrategy
.
OnPush
,
templateUrl
:
'
settings.component.html
'
,
})
export
class
ProSettingsComponent
implements
OnInit
{
export
class
ProSettingsComponent
implements
OnInit
,
OnDestroy
{
settings
:
any
;
inProgress
:
boolean
;
...
...
@@ -29,25 +32,41 @@ export class ProSettingsComponent implements OnInit {
|
'
domain
'
|
'
cancel
'
=
'
general
'
;
user
:
string
|
null
=
null
;
protected
param$
:
Subscription
;
constructor
(
protected
service
:
ProService
,
protected
session
:
Session
,
protected
router
:
Router
,
protected
route
:
ActivatedRoute
,
protected
cd
:
ChangeDetectorRef
,
protected
title
:
MindsTitle
protected
title
:
MindsTitle
,
protected
site
:
SiteService
)
{}
ngOnInit
()
{
this
.
load
();
this
.
param$
=
this
.
route
.
params
.
subscribe
(
params
=>
{
if
(
this
.
site
.
isAdmin
)
{
this
.
user
=
params
[
'
user
'
]
||
null
;
}
this
.
load
();
});
}
ngOnDestroy
()
{
this
.
param$
.
unsubscribe
();
}
async
load
()
{
this
.
inProgress
=
true
;
this
.
detectChanges
();
const
{
isActive
,
settings
}
=
await
this
.
service
.
get
();
const
{
isActive
,
settings
}
=
await
this
.
service
.
get
(
this
.
user
);
if
(
!
isActive
)
{
if
(
!
isActive
&&
!
this
.
user
)
{
this
.
router
.
navigate
([
'
/pro
'
],
{
replaceUrl
:
true
});
return
;
}
...
...
@@ -64,7 +83,7 @@ export class ProSettingsComponent implements OnInit {
this
.
inProgress
=
true
;
this
.
detectChanges
();
await
this
.
service
.
set
(
this
.
settings
);
await
this
.
service
.
set
(
this
.
settings
,
this
.
user
);
this
.
saved
=
true
;
this
.
inProgress
=
false
;
...
...
@@ -101,10 +120,18 @@ export class ProSettingsComponent implements OnInit {
}
get
previewRoute
()
{
return
[
'
/pro
'
,
this
.
session
.
getLoggedInUser
().
username
];
return
[
'
/pro
'
,
this
.
user
||
this
.
session
.
getLoggedInUser
().
username
];
}
get
ratios
()
{
return
this
.
service
.
ratios
;
}
get
isRemote
()
{
return
Boolean
(
this
.
user
);
}
get
isAdmin
()
{
return
this
.
site
.
isAdmin
;
}
}
This diff is collapsed.
Click to expand it.
src/app/services/site.service.ts
View file @
161369a1
...
...
@@ -6,11 +6,15 @@ export class SiteService {
return
window
.
Minds
.
pro
;
}
get
isProDomain
()
{
get
isProDomain
()
:
boolean
{
return
Boolean
(
this
.
pro
);
}
get
title
()
{
get
title
()
:
string
{
return
this
.
isProDomain
?
this
.
pro
.
title
||
''
:
'
Minds
'
;
}
get
isAdmin
():
boolean
{
return
window
.
Minds
.
Admin
;
}
}
This diff is collapsed.
Click to expand it.
src/index.php
View file @
161369a1
...
...
@@ -57,6 +57,13 @@
}
</script>
<?php
if
(
$pro
&&
$pro
->
getCustomHead
())
:
/* Blank line below IS IMPORTANT! Do not remove. */
?>
<!-- Minds Pro:
<?php
echo
$pro
->
getUserGuid
();
?>
-->
<?php
echo
"
\n
"
.
$pro
->
getCustomHead
()
.
"
\n
"
;
?>
<!-- End -->
<?php
endif
;
?>
</head>
<body>
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment