Merge pull request #2631 from overleaf/bg-maintenance-messages-in-editor

display maintenance messages in editor

GitOrigin-RevId: 7d4fda60c5e2bd12d2cead2a9bff326b75e9c4e7
This commit is contained in:
Brian Gough 2020-02-26 11:55:28 +00:00 committed by Copybot
parent ac5d688d8c
commit 509c23def7
10 changed files with 85 additions and 53 deletions

View file

@ -36,7 +36,6 @@ const BrandVariationsHandler = require('../BrandVariations/BrandVariationsHandle
const { getUserAffiliations } = require('../Institutions/InstitutionsAPI')
const V1Handler = require('../V1/V1Handler')
const UserController = require('../User/UserController')
const SystemMessageManager = require('../SystemMessages/SystemMessageManager')
const _ssoAvailable = (affiliation, session, linkedInstitutionIds) => {
if (!affiliation.institution) return false
@ -357,9 +356,6 @@ const ProjectController = {
let noV1Connection = false
async.parallel(
{
systemMessages(cb) {
SystemMessageManager.getMessages(cb)
},
tags(cb) {
TagsHandler.getAllTags(userId, cb)
},
@ -547,7 +543,6 @@ const ProjectController = {
const viewModel = {
title: 'your_projects',
priority_title: true,
systemMessages: results.systemMessages,
projects,
tags,
notifications: notifications || [],

View file

@ -0,0 +1,26 @@
const Settings = require('settings-sharelatex')
const SystemMessageManager = require('./SystemMessageManager')
const ProjectController = {
getMessages(req, res, next) {
SystemMessageManager.getMessages((err, messages) => {
if (err) {
next(err)
} else {
if (!Settings.siteIsOpen) {
// Override all messages with notice for admins when site is closed.
messages = [
{
content:
'SITE IS CLOSED TO PUBLIC. OPEN ONLY FOR SITE ADMINS. DO NOT EDIT PROJECTS.',
_id: 'protected' // prevents hiding message in frontend
}
]
}
res.json(messages || [])
}
})
}
}
module.exports = ProjectController

View file

@ -49,6 +49,7 @@ const LinkedFilesRouter = require('./Features/LinkedFiles/LinkedFilesRouter')
const TemplatesRouter = require('./Features/Templates/TemplatesRouter')
const InstitutionsController = require('./Features/Institutions/InstitutionsController')
const UserMembershipRouter = require('./Features/UserMembership/UserMembershipRouter')
const SystemMessageController = require('./Features/SystemMessages/SystemMessageController')
const logger = require('logger-sharelatex')
const _ = require('underscore')
@ -108,6 +109,12 @@ function initialize(webRouter, privateApiRouter, publicApiRouter) {
webRouter.get('/user/activate', UserPagesController.activateAccountPage)
AuthenticationController.addEndpointToLoginWhitelist('/user/activate')
webRouter.get(
'/system/messages',
AuthenticationController.requireLogin(),
SystemMessageController.getMessages
)
webRouter.get(
'/user/settings',
AuthenticationController.requireLogin(),

View file

@ -3,7 +3,6 @@ extends ../layout
block vars
- var suppressNavbar = true
- var suppressFooter = true
- var suppressSystemMessages = true
- metadata.robotsNoindexNofollow = true
block content
@ -49,6 +48,17 @@ block content
.div(ng-controller="SavingNotificationController")
.alert.alert-warning.small(ng-repeat="(doc_id, state) in docSavingStatus" ng-if="state.unsavedSeconds > 8") #{translate("saving_notification_with_seconds", {docname:"{{ state.doc.name }}", seconds:"{{ state.unsavedSeconds }}"})}
.div(ng-controller="SystemMessagesController")
.alert.alert-warning.system-message(
ng-repeat="message in messages"
ng-controller="SystemMessageController"
ng-hide="hidden"
)
button(ng-hide="protected",ng-click="hide()").close.pull-right
span(aria-hidden="true") ×
span.sr-only #{translate("close")}
.system-message-content(ng-bind-html="htmlContent")
include ./editor/left-menu
#chat-wrapper.full-size(

View file

@ -3,7 +3,6 @@ extends ../layout
block vars
- var suppressNavbar = true
- var suppressFooter = true
- var suppressSystemMessages = true
- metadata.robotsNoindexNofollow = true
block content

View file

@ -20,26 +20,19 @@ block content
ng-controller="ProjectPageController"
role="main"
)
- if(typeof(suppressSystemMessages) == "undefined")
script.
window.systemMessages = !{StringHelper.stringifyJsonForScript(systemMessages)};
- if(settings.siteIsOpen == false && getSessionUser() && getSessionUser().isAdmin)
script.
window.systemMessages.push({content: "SITE IS CLOSED TO PUBLIC. OPEN ONLY FOR SITE ADMINS", _id:"siteclosed"})
.system-messages(
ng-cloak
ng-controller="SystemMessagesController"
.system-messages(
ng-cloak
ng-controller="SystemMessagesController"
)
.system-message(
ng-repeat="message in messages"
ng-controller="SystemMessageController"
ng-hide="hidden"
)
.system-message(
ng-repeat="message in messages"
ng-controller="SystemMessageController"
ng-hide="hidden"
)
button(ng-click="hide()").close.pull-right
span(aria-hidden="true") ×
span.sr-only #{translate("close")}
.system-message-content(ng-bind-html="htmlContent")
button(ng-hide="protected",ng-click="hide()").close.pull-right
span(aria-hidden="true") ×
span.sr-only #{translate("close")}
.system-message-content(ng-bind-html="htmlContent")
include ../translations/translation_message

View file

@ -59,6 +59,7 @@ define([
'main/event',
'main/account-upgrade',
'main/exposed-settings',
'main/system-messages',
'../../modules/modules-ide.js'
], function(
App,

View file

@ -11,18 +11,36 @@
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
define(['base'], function(App) {
App.controller(
'SystemMessagesController',
$scope => ($scope.messages = window.systemMessages)
)
const MESSAGE_POLL_INTERVAL = 15 * 60 * 1000
// Controller for messages (array)
App.controller('SystemMessagesController', ($http, $scope) => {
$scope.messages = window.systemMessages
var pollSystemMessages = function() {
$http
.get('/system/messages')
.then(response => {
$scope.messages = response.data
})
.catch(() => {
// ignore errors
})
}
pollSystemMessages()
setInterval(pollSystemMessages, MESSAGE_POLL_INTERVAL)
})
// Controller for individual message (show/hide)
return App.controller('SystemMessageController', function($scope, $sce) {
$scope.hidden = $.localStorage(`systemMessage.hide.${$scope.message._id}`)
$scope.protected = $scope.message._id === 'protected'
$scope.htmlContent = $scope.message.content
return ($scope.hide = function() {
$scope.hidden = true
return $.localStorage(`systemMessage.hide.${$scope.message._id}`, true)
if (!$scope.protected) {
// do not allow protected messages to be hidden
$scope.hidden = true
return $.localStorage(`systemMessage.hide.${$scope.message._id}`, true)
}
})
})
})

View file

@ -3,6 +3,10 @@
background-color: @sys-msg-background;
color: @sys-msg-color;
border-bottom: @sys-msg-border;
a {
color: @sidebar-link-color;
text-decoration: underline;
}
}
.system-message .close when (@is-overleaf = true) {

View file

@ -130,10 +130,6 @@ describe('ProjectController', function() {
}
])
this.SystemMessageManager = {
getMessages: sinon.stub().callsArgWith(0, null, [])
}
this.ProjectController = SandboxedModule.require(MODULE_PATH, {
globals: {
console: console
@ -151,7 +147,6 @@ describe('ProjectController', function() {
inc() {}
},
'@overleaf/o-error/http': HttpErrors,
'../SystemMessages/SystemMessageManager': this.SystemMessageManager,
'./ProjectDeleter': this.ProjectDeleter,
'./ProjectDuplicator': this.ProjectDuplicator,
'./ProjectCreationHandler': this.ProjectCreationHandler,
@ -377,14 +372,6 @@ describe('ProjectController', function() {
describe('projectListPage', function() {
beforeEach(function() {
this.systemMessages = [
{ _id: '42', content: 'Hello from the other side!' },
{ _id: '1337', content: 'Can you read this?' }
]
this.SystemMessageManager.getMessages = sinon
.stub()
.callsArgWith(0, null, this.systemMessages)
this.tags = [
{ name: 1, project_ids: ['1', '2', '3'] },
{ name: 2, project_ids: ['a', '1'] },
@ -456,14 +443,6 @@ describe('ProjectController', function() {
this.ProjectController.projectListPage(this.req, this.res)
})
it('should send the systemMessages', function(done) {
this.res.render = (pageName, opts) => {
opts.systemMessages.should.deep.equal(this.systemMessages)
done()
}
this.ProjectController.projectListPage(this.req, this.res)
})
it('should create trigger ip matcher notifications', function(done) {
this.settings.overleaf = true
this.res.render = (pageName, opts) => {