summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaša Živkov <zivkov@gmail.com>2020-02-03 14:15:54 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2020-02-03 14:15:54 +0000
commitd4ba7fb691edf0a5ff4944be339dfe4941bcf5e3 (patch)
treea8bcf53712b2933575020cfb5ab4cb624acf58b6
parent15753c282e9fcb44fa049788136505071a339ad5 (diff)
parentcfff720610374fe538649f272a762569bb785998 (diff)
Merge changes from topic "motd" into stable-2.16
* changes: Document MessageOfTheDay extension Add UI element to display messages of the day Add MessageOfTheDay-entries to ServerInfo
-rw-r--r--Documentation/dev-plugins.txt34
-rw-r--r--Documentation/rest-api-config.txt21
-rw-r--r--java/com/google/gerrit/extensions/common/MessageOfTheDayInfo.java27
-rw-r--r--java/com/google/gerrit/extensions/common/ServerInfo.java2
-rw-r--r--java/com/google/gerrit/server/restapi/config/GetServerInfo.java24
-rw-r--r--polygerrit-ui/app/elements/core/gr-message-header/gr-message-header.html41
-rw-r--r--polygerrit-ui/app/elements/core/gr-message-header/gr-message-header.js52
-rw-r--r--polygerrit-ui/app/elements/core/gr-message-header/gr-message-header_test.html60
-rw-r--r--polygerrit-ui/app/elements/gr-app.html7
-rw-r--r--polygerrit-ui/app/elements/gr-app.js4
10 files changed, 271 insertions, 1 deletions
diff --git a/Documentation/dev-plugins.txt b/Documentation/dev-plugins.txt
index 974e3706ca..64cae2d5a6 100644
--- a/Documentation/dev-plugins.txt
+++ b/Documentation/dev-plugins.txt
@@ -2954,6 +2954,40 @@ to change in order to be compliant. These requirements should be kept once they
are met, but marked as `OK`. If the requirements were not displayed, reviewers
would need to use their precious time to manually check that they were met.
+[[message-of-the-day]]
+== Posting Messages (Of The Day) to the UI
+Gerrit provides an extension point that enables plugins to implement a method to
+collect messages that will then be shown below the main header in the Gerrit UI.
+
+[source, java]
+----
+import com.google.gerrit.extensions.systemstatus.MessageOfTheDay;
+
+@Singleton
+class MessageOfTheDayImpl extends MessageOfTheDay {
+
+ private final String id;
+ private final String msg;
+
+ public MessageOfTheDayImpl() {
+ id = "hello";
+ msg = "I just wanted to say <b>hello</b>.";
+ }
+
+ @Override
+ public String getHtmlMessage() {
+ return msg;
+ }
+
+ @Override
+ public String getMessageId() {
+ return id;
+ }
+}
+----
+
+Note, that the message will be added as HTML and parsed into the DOM. Thus,
+plugins using this extension should ensure that the message content is safe.
== SEE ALSO
diff --git a/Documentation/rest-api-config.txt b/Documentation/rest-api-config.txt
index 7be8c324b4..905c3ef830 100644
--- a/Documentation/rest-api-config.txt
+++ b/Documentation/rest-api-config.txt
@@ -1905,6 +1905,22 @@ The maximal memory size. The value is returned with a unit abbreviation
The number of open files.
|============================
+[[message-of-the-day-info]]
+=== MessageOfTheDayInfo
+The `MessageOfTheDayInfo` entity contains information about a message
+that was registered with the
+link:dev-plugins.html#message-of-the-day[MessageOfTheDay]-extension by plugins.
+
+[options="header",cols="1,^1,5"]
+|===========================
+|Field Name ||Description
+|`id` ||ID of the message.
+|`redisplay` ||
+Date and Time, when the message should be displayed again after it was dismissed
+by the user.
+|`html` ||Message in HTML-format.
+|===========================
+
[[plugin-config-info]]
=== PluginConfigInfo
The `PluginConfigInfo` entity contains information about Gerrit
@@ -1958,6 +1974,11 @@ information about Gerrit
Information about the configuration from the
link:config-gerrit.html#gerrit[gerrit] section as link:#gerrit-info[
GerritInfo] entity.
+|`messages` ||
+List of messages registered with the
+link:dev-plugins.html#message-of-the-day[MessageOfTheDay]-extension
+containing link:#message-of-the-day-info[
+MessageOfTheDayInfo] entities.
|`note_db_enabled` |not set if `false`|
Whether the NoteDb storage backend is fully enabled.
|`plugin` ||
diff --git a/java/com/google/gerrit/extensions/common/MessageOfTheDayInfo.java b/java/com/google/gerrit/extensions/common/MessageOfTheDayInfo.java
new file mode 100644
index 0000000000..f752f86a64
--- /dev/null
+++ b/java/com/google/gerrit/extensions/common/MessageOfTheDayInfo.java
@@ -0,0 +1,27 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.extensions.common;
+
+import java.util.Date;
+
+/** REST API representation of a "message of the day". */
+public class MessageOfTheDayInfo {
+ /** The ID of the message. */
+ public String id;
+ /** The date and time the message will be displayed again after being dismissed by the user. */
+ public Date redisplay;
+ /** The message in HTML-format. */
+ public String html;
+}
diff --git a/java/com/google/gerrit/extensions/common/ServerInfo.java b/java/com/google/gerrit/extensions/common/ServerInfo.java
index 8904f0a03b..27cf529a24 100644
--- a/java/com/google/gerrit/extensions/common/ServerInfo.java
+++ b/java/com/google/gerrit/extensions/common/ServerInfo.java
@@ -14,6 +14,7 @@
package com.google.gerrit.extensions.common;
+import java.util.List;
import java.util.Map;
public class ServerInfo {
@@ -22,6 +23,7 @@ public class ServerInfo {
public ChangeConfigInfo change;
public DownloadInfo download;
public GerritInfo gerrit;
+ public List<MessageOfTheDayInfo> messages;
public Boolean noteDbEnabled;
public PluginConfigInfo plugin;
public SshdInfo sshd;
diff --git a/java/com/google/gerrit/server/restapi/config/GetServerInfo.java b/java/com/google/gerrit/server/restapi/config/GetServerInfo.java
index eca26c34a5..04f4f8a824 100644
--- a/java/com/google/gerrit/server/restapi/config/GetServerInfo.java
+++ b/java/com/google/gerrit/server/restapi/config/GetServerInfo.java
@@ -27,6 +27,7 @@ import com.google.gerrit.extensions.common.ChangeConfigInfo;
import com.google.gerrit.extensions.common.DownloadInfo;
import com.google.gerrit.extensions.common.DownloadSchemeInfo;
import com.google.gerrit.extensions.common.GerritInfo;
+import com.google.gerrit.extensions.common.MessageOfTheDayInfo;
import com.google.gerrit.extensions.common.PluginConfigInfo;
import com.google.gerrit.extensions.common.ReceiveInfo;
import com.google.gerrit.extensions.common.ServerInfo;
@@ -36,7 +37,9 @@ import com.google.gerrit.extensions.common.UserConfigInfo;
import com.google.gerrit.extensions.config.CloneCommand;
import com.google.gerrit.extensions.config.DownloadCommand;
import com.google.gerrit.extensions.config.DownloadScheme;
+import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.extensions.systemstatus.MessageOfTheDay;
import com.google.gerrit.extensions.webui.WebUiPlugin;
import com.google.gerrit.server.EnableSignedPush;
import com.google.gerrit.server.account.AccountVisibilityProvider;
@@ -69,6 +72,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
@@ -100,6 +104,7 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
private final GerritOptions gerritOptions;
private final ChangeIndexCollection indexes;
private final SitePaths sitePaths;
+ private final DynamicSet<MessageOfTheDay> messages;
@Inject
public GetServerInfo(
@@ -123,7 +128,8 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
AgreementJson agreementJson,
GerritOptions gerritOptions,
ChangeIndexCollection indexes,
- SitePaths sitePaths) {
+ SitePaths sitePaths,
+ DynamicSet<MessageOfTheDay> motd) {
this.config = config;
this.accountVisibilityProvider = accountVisibilityProvider;
this.authConfig = authConfig;
@@ -145,6 +151,7 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
this.gerritOptions = gerritOptions;
this.indexes = indexes;
this.sitePaths = sitePaths;
+ this.messages = motd;
}
@Override
@@ -155,6 +162,7 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
info.change = getChangeInfo();
info.download = getDownloadInfo();
info.gerrit = getGerritInfo();
+ info.messages = getMessages();
info.noteDbEnabled = toBoolean(isNoteDbEnabled());
info.plugin = getPluginInfo();
info.defaultTheme = getDefaultTheme();
@@ -325,6 +333,20 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
return CharMatcher.is('/').trimTrailingFrom(docUrl) + '/';
}
+ private List<MessageOfTheDayInfo> getMessages() {
+ return this.messages.stream()
+ .filter(motd -> !Strings.isNullOrEmpty(motd.getHtmlMessage()))
+ .map(
+ motd -> {
+ MessageOfTheDayInfo m = new MessageOfTheDayInfo();
+ m.id = motd.getMessageId();
+ m.redisplay = motd.getRedisplay();
+ m.html = motd.getHtmlMessage();
+ return m;
+ })
+ .collect(toList());
+ }
+
private boolean isNoteDbEnabled() {
return migration.readChanges();
}
diff --git a/polygerrit-ui/app/elements/core/gr-message-header/gr-message-header.html b/polygerrit-ui/app/elements/core/gr-message-header/gr-message-header.html
new file mode 100644
index 0000000000..b2b382ca50
--- /dev/null
+++ b/polygerrit-ui/app/elements/core/gr-message-header/gr-message-header.html
@@ -0,0 +1,41 @@
+<!--
+@license
+Copyright (C) 2020 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="../../shared/gr-button/gr-button.html">
+
+<dom-module id="gr-message-header">
+ <template>
+ <style include="shared-styles">
+ #container {
+ background-color: lightyellow;
+ display: flex;
+ height: fit-content;
+ justify-content: space-between;
+ padding: 1em;
+ }
+ </style>
+ <div id="container" hidden$="[[_hidden]]">
+ <div id="message"></div>
+ <gr-button id="dismissMessageBtn"
+ link
+ on-tap="_handleDismissMessage">Dismiss</gr-button>
+ </div>
+ <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
+ </template>
+ <script src="../../../scripts/util.js"></script>
+ <script src="gr-message-header.js"></script>
+</dom-module>
diff --git a/polygerrit-ui/app/elements/core/gr-message-header/gr-message-header.js b/polygerrit-ui/app/elements/core/gr-message-header/gr-message-header.js
new file mode 100644
index 0000000000..fac4a6a399
--- /dev/null
+++ b/polygerrit-ui/app/elements/core/gr-message-header/gr-message-header.js
@@ -0,0 +1,52 @@
+/**
+ * @license
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+(function() {
+ 'use strict';
+
+ Polymer({
+ is: 'gr-message-header',
+
+ properties: {
+ message: {
+ type: Object,
+ reflectToAttribute: true,
+ },
+ _hidden: {
+ type: Boolean,
+ value: true,
+ },
+ },
+
+ attached() {
+ if (!this.message || !this.message.html) {
+ return;
+ }
+ this._isHidden();
+ this.$.message.innerHTML = this.message.html;
+ },
+
+ _handleDismissMessage() {
+ document.cookie =
+ `msg-${this.message.id}=1; expires=${this.message.redisplay}`;
+ this._hidden = true;
+ },
+
+ _isHidden() {
+ this._hidden = window.util.getCookie(`msg-${this.message.id}`) === '1';
+ },
+ });
+})();
diff --git a/polygerrit-ui/app/elements/core/gr-message-header/gr-message-header_test.html b/polygerrit-ui/app/elements/core/gr-message-header/gr-message-header_test.html
new file mode 100644
index 0000000000..c275e55345
--- /dev/null
+++ b/polygerrit-ui/app/elements/core/gr-message-header/gr-message-header_test.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<!--
+@license
+Copyright (C) 2020 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+<title>gr-message-header</title>
+
+<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
+<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<link rel="import" href="../../../test/common-test-setup.html"/>
+<link rel="import" href="gr-message-header.html">
+
+<script>void(0);</script>
+
+<test-fixture id="basic">
+ <template>
+ <gr-message-header></gr-message-header>
+ </template>
+</test-fixture>
+
+<script>
+ suite('gr-message-header tests', () => {
+ let element;
+
+ setup(() => {
+ element = fixture('basic');
+ });
+
+ test('show message', () => {
+ element.message = {html: 'This is a test message.'};
+ element.attached();
+ assert.equal(element.$.message.innerHTML, element.message.html);
+ });
+
+ test('hide message on dismiss', () => {
+ element.message = {html: 'This is a test message.', id: 'test'};
+ element.attached();
+ MockInteractions.tap(element.$.dismissMessageBtn);
+ assert.isTrue(element.$.container.hidden);
+ assert.isTrue(document.cookie.includes('msg-test=1'));
+
+ element.attached();
+ assert.isTrue(element.$.container.hidden);
+ });
+ });
+</script>
diff --git a/polygerrit-ui/app/elements/gr-app.html b/polygerrit-ui/app/elements/gr-app.html
index 3a9719d5b9..4fff9e6221 100644
--- a/polygerrit-ui/app/elements/gr-app.html
+++ b/polygerrit-ui/app/elements/gr-app.html
@@ -55,6 +55,7 @@ limitations under the License.
<link rel="import" href="./core/gr-error-manager/gr-error-manager.html">
<link rel="import" href="./core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog.html">
<link rel="import" href="./core/gr-main-header/gr-main-header.html">
+<link rel="import" href="./core/gr-message-header/gr-message-header.html">
<link rel="import" href="./core/gr-navigation/gr-navigation.html">
<link rel="import" href="./core/gr-reporting/gr-reporting.html">
<link rel="import" href="./core/gr-router/gr-router.html">
@@ -158,6 +159,12 @@ limitations under the License.
class$="[[_computeShadowClass(_isShadowDom)]]">
</gr-main-header>
</gr-fixed-panel>
+ <template
+ is="dom-repeat"
+ items="[[_getMessages(_serverConfig)]]"
+ as="message">
+ <gr-message-header message="{{message}}"></gr-message-header>
+ </template>
<main>
<template is="dom-if" if="[[_showChangeListView]]" restamp="true">
<gr-change-list-view
diff --git a/polygerrit-ui/app/elements/gr-app.js b/polygerrit-ui/app/elements/gr-app.js
index f48951bd53..ea7e86dc0b 100644
--- a/polygerrit-ui/app/elements/gr-app.js
+++ b/polygerrit-ui/app/elements/gr-app.js
@@ -339,6 +339,10 @@
config.gerrit.web_uis && config.gerrit.web_uis.includes('GWT');
},
+ _getMessages(config) {
+ return config.messages ? config.messages : [];
+ },
+
_handlePageError(e) {
const props = [
'_showChangeListView',