user admin features

master
rob 1 year ago
parent b529e12a77
commit c296aad5c3

@ -74,9 +74,11 @@ class AdminController extends SiteController {
async getHomeView (req, res) {
const {
chat: chatService,
coreNode: coreNodeService,
dashboard: dashboardService,
logan: loganService,
user: userService,
} = this.dtp.services;
res.locals.stats = {
@ -87,6 +89,12 @@ class AdminController extends SiteController {
res.locals.pageTitle = `Admin Dashbord for ${this.dtp.config.site.name}`;
res.locals.recentMembers = await userService.getRecent(10);
res.locals.admins = await userService.getAdmins();
res.locals.moderators = await userService.getModerators();
res.locals.recentChat = await chatService.getRecent(10);
loganService.sendRequestEvent(module.exports, req, {
level: 'info',
event: 'getHomeView',

@ -366,16 +366,21 @@ class ChatController extends SiteController {
async getRoomEditor (req, res) {
const { logan: loganService } = this.dtp.services;
const logData = { };
if (res.locals.room) {
logData.room = {
_id: res.locals.room._id,
name: res.locals.room.name,
};
}
loganService.sendRequestEvent(module.exports, req, {
level: 'info',
event: 'getRoomEditor',
data: {
room: {
_id: res.locals.room._id,
name: res.locals.room.name,
},
},
data: logData,
});
res.render('chat/room/editor');
}

@ -785,6 +785,16 @@ class ChatService extends SiteService {
return reaction.toObject();
}
async getRecent (limit = 10) {
const messages = await ChatMessage
.find({ })
.sort({ created: -1 })
.limit(limit)
.populate(this.populateChatMessage)
.lean();
return messages;
}
async removeForUser (user) {
const { logan: loganService } = this.dtp.services;

@ -508,6 +508,24 @@ class UserService extends SiteService {
return users;
}
async getAdmins ( ) {
const admins = await User
.find({ 'flags.isAdmin': true })
.select(UserService.USER_SELECT)
.sort({ username: 1 })
.lean();
return admins;
}
async getModerators ( ) {
const moderators = await User
.find({ 'flags.isModerator': true })
.select(UserService.USER_SELECT)
.sort({ username: 1 })
.lean();
return moderators;
}
async setUserSettings (user, settings) {
const {
crypto: cryptoService,

@ -1,6 +1,9 @@
extends layouts/main
block content
include user/components/list-item
include ../chat/components/message
div(uk-grid)
div(class="uk-width-1-1 uk-width-auto@m")
h3= site.name
@ -25,6 +28,53 @@ block content
h3 Hourly Sign-Ups
canvas(id="hourly-signups")
.uk-margin
div(uk-grid)
div(class="uk-width-1-1 uk-width-1-3@l")
h3 Admins
if Array.isArray(admins) && (admins.length > 0)
ul.uk-list.uk-list-divider
each member in admins
li
+renderUserListItem(member)
else
div There are no system admins.
h3 Moderators
if Array.isArray(moderators) && (moderators.length > 0)
ul.uk-list.uk-list-divider
each member in moderators
li
+renderUserListItem(member)
else
div There are no system-level moderators.
div(class="uk-width-1-1 uk-width-1-3@l")
h3 Recent Chat
if Array.isArray(recentChat) && (recentChat.length > 0)
ul.uk-list.uk-list-divider
each message in recentChat
li
div(uk-grid).uk-grid-small
.uk-width-expand
+renderChatMessage(message, { fullWidth: true })
.uk-width-auto
a(href=`/admin/user/local/${message.author._id}`, uk-tooltip={ title: 'Manage user account' }).uk-button.uk-button-default.uk-button-small.uk-border-rounded
span
i.fas.fa-wrench
else
div There is no recent chat.
div(class="uk-width-1-1 uk-width-1-3@l")
h3 Recent Members
if Array.isArray(recentMembers) && (recentMembers.length > 0)
ul.uk-list.uk-list-divider
each member in recentMembers
li
+renderUserListItem(member)
else
div There are no recent members.
block viewjs
script(src="/chart.js/chart.min.js")
script(src="/chartjs-adapter-moment/chartjs-adapter-moment.min.js")

@ -0,0 +1,14 @@
mixin renderUserListItem (user)
div(uk-grid).uk-grid-small
.uk-width-auto
+renderProfileIcon(user)
.uk-width-expand
.uk-text-bold(style="line-height: 1;").uk-text-truncate= user.displayName || user.username
.uk-text-small.uk-text-muted
a(href= getUserProfileUrl(user))= user.username
.uk-text-small.uk-text-truncate= user.bio
.uk-text-small.uk-text-muted created #{moment(user.created).fromNow()}
.uk-width-auto
a(href=`/admin/user/local/${user._id}`, uk-tooltip={ title: 'Manage user account' }).uk-button.uk-button-default.uk-button-small.uk-border-rounded
span
i.fas.fa-wrench

@ -2,8 +2,10 @@ include ../../sticker/components/sticker
mixin renderChatMessage (message, options = { })
- var authorName = message.author.displayName || message.author.username;
div(
data-message-id= message._id, data-author-id= message.author._id
).chat-message
data-message-id= message._id,
data-author-id= message.author._id,
class={ 'full-width': options.fullWidth },
).site-chat-message
.uk-margin-small
div(uk-grid).uk-grid-small
.uk-width-auto
@ -34,7 +36,7 @@ mixin renderChatMessage (message, options = { })
//- "time" is filled in by the JavaScript client using the browser's locale
//- information so that "time" is always in the user's display timezone.
.chat-timestamp(data-dtp-timestamp= message.created).uk-text-small
.chat-timestamp(data-dtp-timestamp= message.created).uk-text-small.uk-text-muted
if Array.isArray(message.stickers) && (message.stickers.length > 0)
each sticker in message.stickers

@ -35,7 +35,6 @@ export default class SiteChat {
if (this.ui.messageList) {
this.ui.messageList.addEventListener('scroll', this.onChatMessageListScroll.bind(this));
this.updateTimestamps();
setTimeout(( ) => {
this.log.info('constructor', 'scrolling chat', { top: this.ui.messageList.scrollHeight });
this.ui.messageList.scrollTo({ top: this.ui.messageList.scrollHeight, behavior: 'instant' });
@ -62,6 +61,8 @@ export default class SiteChat {
this.mutedUsers = window.localStorage.mutedUsers ? JSON.parse(window.localStorage.mutedUsers) : [ ];
this.filterChatView();
}
this.updateTimestamps();
}
async filterChatView ( ) {

@ -13,6 +13,97 @@
background-color: @content-background-color;
}
.site-chat-message {
padding: @grid-small-gutter-vertical @grid-small-gutter-horizontal;
margin: (@grid-small-gutter-vertical / 2) @grid-small-gutter-horizontal;
border: solid 1px @content-border-color;
border-radius: 8px;
background: @content-background-color;
color: inherit;
font-size: var(--dtp-chat-font-size);
&.full-width {
margin-left: 0;
margin-right: 0;
&:first-of-type { margin-top: 0; }
&:last-of-type { margin-bottom: 0; }
}
&.system-message {
background: #e8e8e8;
color: #1a1a1a;
&[data-message-type="info"] {
background: #068be4;
color: white;
}
&[data-message-type="warning"] {
background: #e4c306;
color: white;
}
&[data-message-type="error"] {
background: #ff00131a;
color: white;
}
}
.chat-username {
font-weight: bold;
font-size: var(--dtp-chat-font-size);
line-height: 1;
color: var(--dtp-chat-username-color);
}
img.chat-author-image {
width: auto;
height: 40px;
border-radius: 4px;
}
.chat-content {
line-height: 1.2em;
font-size: var(--dtp-chat-font-size);
color: inherit;
overflow-wrap: break-word;
p:last-child {
margin-bottom: 0;
}
}
.chat-timestamp {
color: var(--dtp-chat-timestamp-color);
}
.chat-sticker {
display: inline-block;
margin-top: 4px;
margin-right: 8px;
color: inherit;
video {
width: auto;
height: 100px;
}
}
.chat-user-menu {
button.chat-menu-button {
padding: 0;
margin: 0;
background: transparent;
outline: none;
border: none;
line-height: 1;
}
}
}
#site-chat-container {
overflow: auto;
background-color: @content-container-color;
@ -145,88 +236,6 @@
background-color: @scrollbar-thumb-color;
}
.chat-message {
padding: @grid-small-gutter-vertical @grid-small-gutter-horizontal;
margin: (@grid-small-gutter-vertical / 2) @grid-small-gutter-horizontal;
border: solid 1px @content-border-color;
border-radius: 8px;
background: @content-background-color;
color: inherit;
font-size: var(--dtp-chat-font-size);
&.system-message {
background: #e8e8e8;
color: #1a1a1a;
&[data-message-type="info"] {
background: #068be4;
color: white;
}
&[data-message-type="warning"] {
background: #e4c306;
color: white;
}
&[data-message-type="error"] {
background: #ff00131a;
color: white;
}
}
.chat-username {
font-weight: bold;
font-size: var(--dtp-chat-font-size);
line-height: 1;
color: var(--dtp-chat-username-color);
}
img.chat-author-image {
width: auto;
height: 40px;
border-radius: 4px;
}
.chat-content {
line-height: 1.2em;
font-size: var(--dtp-chat-font-size);
color: inherit;
overflow-wrap: break-word;
p:last-child {
margin-bottom: 0;
}
}
.chat-timestamp {
color: var(--dtp-chat-timestamp-color);
}
.chat-sticker {
display: inline-block;
margin-top: 4px;
margin-right: 8px;
color: inherit;
video {
width: auto;
height: 100px;
}
}
.chat-user-menu {
button.chat-menu-button {
padding: 0;
margin: 0;
background: transparent;
outline: none;
border: none;
line-height: 1;
}
}
}
}
.chat-message-menu {

Loading…
Cancel
Save