Merge "Mail footer discoverability helper"
This commit is contained in:
@@ -142,6 +142,108 @@ When sending email to an internal group, the internal group's read
|
|||||||
access is automatically checked by Gerrit and therefore does not
|
access is automatically checked by Gerrit and therefore does not
|
||||||
need to use the `visibleto:` operator in the filter.
|
need to use the `visibleto:` operator in the filter.
|
||||||
|
|
||||||
|
[[footers]]
|
||||||
|
== Email Footers
|
||||||
|
|
||||||
|
Notification emails related to changes include metadata about the change
|
||||||
|
to support writing mail filters. This metadata is included in the form
|
||||||
|
of footers in the message content. For HTML emails, these footers are
|
||||||
|
hidden, but they can be examined by viewing the HTML source of messages.
|
||||||
|
|
||||||
|
In this way users may apply filters and rules to their incoming Gerrit
|
||||||
|
notifications using the values of these footers. For example a Gmail
|
||||||
|
filter to find emails regarding reviews that you are a reviewer of might
|
||||||
|
take the following form.
|
||||||
|
|
||||||
|
----
|
||||||
|
"Gerrit-Reviewer: Your Name <your.email@example.com>"
|
||||||
|
----
|
||||||
|
|
||||||
|
[[Gerrit-MessageType]]Gerrit-MessageType::
|
||||||
|
|
||||||
|
The message type footer states the type of the message and will take one
|
||||||
|
of the following values.
|
||||||
|
|
||||||
|
* abandon
|
||||||
|
* comment
|
||||||
|
* deleteReviewer
|
||||||
|
* deleteVote
|
||||||
|
* merged
|
||||||
|
* newchange
|
||||||
|
* newpatchset
|
||||||
|
* restore
|
||||||
|
* revert
|
||||||
|
* setassignee
|
||||||
|
|
||||||
|
[[Gerrit-Change-Id]]Gerrit-Change-Id::
|
||||||
|
|
||||||
|
The change ID footer states the ID of the change, such as
|
||||||
|
`I3443af49fcdc16ca941ee7cf2b5e33c1106f3b1d`.
|
||||||
|
|
||||||
|
[[Gerrit-Change-Number]]Gerrit-Change-Number::
|
||||||
|
|
||||||
|
The change number footer states the numeric ID of the change, for
|
||||||
|
example `92191`.
|
||||||
|
|
||||||
|
[[Gerrit-PatchSet]]Gerrit-PatchSet::
|
||||||
|
|
||||||
|
The patch set footer states the number of the patch set that the email
|
||||||
|
relates to. For example, a notification email for a vote being set on
|
||||||
|
the seventh patch set will take a value of `7`.
|
||||||
|
|
||||||
|
[[Gerrit-Owner]]Gerrit-Owner::
|
||||||
|
|
||||||
|
The owner footer states the name and email address of the change's
|
||||||
|
owner. For example, `Owner Name <owner@example.com>`.
|
||||||
|
|
||||||
|
[[Gerrit-Reviewer]]Gerrit-Reviewer::
|
||||||
|
|
||||||
|
The reviewer footers list the names and email addresses of the change's
|
||||||
|
reviewrs. One footer is included for each reviewer. For example, if a
|
||||||
|
change has two reviewers, the footers might include:
|
||||||
|
|
||||||
|
----
|
||||||
|
Gerrit-Reviewer: Reviewer One <one@example.com>
|
||||||
|
Gerrit-Reviewer: Reviewer Two <two@example.com>
|
||||||
|
----
|
||||||
|
|
||||||
|
[[Gerrit-CC]]Gerrit-CC::
|
||||||
|
|
||||||
|
The CC footers list the names and email addresses of those who have been
|
||||||
|
CC'd on the change. One footer is included for each reviewer. For
|
||||||
|
example, if a change CCs two users, the footers might include:
|
||||||
|
|
||||||
|
----
|
||||||
|
Gerrit-CC: User One <one@example.com>
|
||||||
|
Gerrit-CC: User Two <two@example.com>
|
||||||
|
----
|
||||||
|
|
||||||
|
[[Gerrit-Project]]Gerrit-Project::
|
||||||
|
|
||||||
|
The project footer states the project to which the change belongs.
|
||||||
|
|
||||||
|
[[Gerrit-Branch]]Gerrit-Branch::
|
||||||
|
|
||||||
|
The branch footer states the abbreviated name of the branch that the
|
||||||
|
change targets.
|
||||||
|
|
||||||
|
[[Gerrit-Comment-Date]]Gerrit-Comment-Date::
|
||||||
|
|
||||||
|
In comment emails, the comment date footer states the date that the
|
||||||
|
comment was posted.
|
||||||
|
|
||||||
|
[[Gerrit-HasComments]]Gerrit-HasComments::
|
||||||
|
|
||||||
|
In comment emails, the has-comments footer states whether inline
|
||||||
|
comments had been posted in that notification using "Yes" or "No", for
|
||||||
|
example `Gerrit-HasComments: Yes`.
|
||||||
|
|
||||||
|
[[Gerrit-HasLabels]]Gerrit-HasLabels::
|
||||||
|
|
||||||
|
In comment emails, the has-labels footer states whether label votes had
|
||||||
|
been posted in that notification using "Yes" or "No", for
|
||||||
|
example `Gerrit-HasLabels: No`.
|
||||||
|
|
||||||
GERRIT
|
GERRIT
|
||||||
------
|
------
|
||||||
Part of link:index.html[Gerrit Code Review]
|
Part of link:index.html[Gerrit Code Review]
|
||||||
|
|||||||
@@ -239,6 +239,10 @@ public interface AccountConstants extends Constants {
|
|||||||
|
|
||||||
String errorDialogTitleRegisterNewEmail();
|
String errorDialogTitleRegisterNewEmail();
|
||||||
|
|
||||||
|
String emailFilterHelpTitle();
|
||||||
|
|
||||||
|
String emailFilterHelp();
|
||||||
|
|
||||||
String newAgreement();
|
String newAgreement();
|
||||||
|
|
||||||
String agreementName();
|
String agreementName();
|
||||||
|
|||||||
@@ -158,7 +158,74 @@ descRegisterNewEmail = \
|
|||||||
<p>A confirmation link will be sent by email to this address.</p>\
|
<p>A confirmation link will be sent by email to this address.</p>\
|
||||||
<p>You must click on the link to complete the registration and make the address available for selection.</p>
|
<p>You must click on the link to complete the registration and make the address available for selection.</p>
|
||||||
errorDialogTitleRegisterNewEmail = Email Registration Failed
|
errorDialogTitleRegisterNewEmail = Email Registration Failed
|
||||||
|
emailFilterHelpTitle = Mail Filters
|
||||||
|
emailFilterHelp = \
|
||||||
|
<p>\
|
||||||
|
Gerrit emails include metadata about the change to support \
|
||||||
|
writing mail filters.\
|
||||||
|
</p>\
|
||||||
|
<p>\
|
||||||
|
Here are some example Gmail queries that can be used for filters or \
|
||||||
|
for searching through archived messages. View the \
|
||||||
|
<a href="https://gerrit-review.googlesource.com/Documentation/user-notify.html"\
|
||||||
|
target="_blank" rel="nofollow">Gerrit documentation</a> for \
|
||||||
|
the complete set of footers.\
|
||||||
|
</p>\
|
||||||
|
<table>\
|
||||||
|
<tbody>\
|
||||||
|
<tr><th>Name</th><th>Query</th></tr>\
|
||||||
|
<tr>\
|
||||||
|
<td>Changes requesting my review</td>\
|
||||||
|
<td>\
|
||||||
|
<code>\
|
||||||
|
"Gerrit-Reviewer: <em>Your Name</em>\
|
||||||
|
<<em>your.email@example.com</em>>"\
|
||||||
|
</code>\
|
||||||
|
</td>\
|
||||||
|
</tr>\
|
||||||
|
<tr>\
|
||||||
|
<td>Changes from a specific owner</td>\
|
||||||
|
<td>\
|
||||||
|
<code>\
|
||||||
|
"Gerrit-Owner: <em>Owner name</em>\
|
||||||
|
<<em>owner.email@example.com</em>>"\
|
||||||
|
</code>\
|
||||||
|
</td>\
|
||||||
|
</tr>\
|
||||||
|
<tr>\
|
||||||
|
<td>Changes targeting a specific branch</td>\
|
||||||
|
<td>\
|
||||||
|
<code>\
|
||||||
|
"Gerrit-Branch: <em>branch-name</em>"\
|
||||||
|
</code>\
|
||||||
|
</td>\
|
||||||
|
</tr>\
|
||||||
|
<tr>\
|
||||||
|
<td>Changes in a specific project</td>\
|
||||||
|
<td>\
|
||||||
|
<code>\
|
||||||
|
"Gerrit-Project: <em>project-name</em>"\
|
||||||
|
</code>\
|
||||||
|
</td>\
|
||||||
|
</tr>\
|
||||||
|
<tr>\
|
||||||
|
<td>Messages related to a specific Change ID</td>\
|
||||||
|
<td>\
|
||||||
|
<code>\
|
||||||
|
"Gerrit-Change-Id: <em>Change ID</em>"\
|
||||||
|
</code>\
|
||||||
|
</td>\
|
||||||
|
</tr>\
|
||||||
|
<tr>\
|
||||||
|
<td>Messages related to a specific change number</td>\
|
||||||
|
<td>\
|
||||||
|
<code>\
|
||||||
|
"Gerrit-Change-Number: <em>change number</em>"\
|
||||||
|
</code>\
|
||||||
|
</td>\
|
||||||
|
</tr>\
|
||||||
|
</tbody>\
|
||||||
|
</table>
|
||||||
|
|
||||||
newAgreement = New Contributor Agreement
|
newAgreement = New Contributor Agreement
|
||||||
agreementName = Name
|
agreementName = Name
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import com.google.gerrit.client.rpc.CallbackGroup;
|
|||||||
import com.google.gerrit.client.rpc.GerritCallback;
|
import com.google.gerrit.client.rpc.GerritCallback;
|
||||||
import com.google.gerrit.client.rpc.NativeString;
|
import com.google.gerrit.client.rpc.NativeString;
|
||||||
import com.google.gerrit.client.rpc.Natives;
|
import com.google.gerrit.client.rpc.Natives;
|
||||||
|
import com.google.gerrit.client.ui.ComplexDisclosurePanel;
|
||||||
import com.google.gerrit.client.ui.OnEditEnabler;
|
import com.google.gerrit.client.ui.OnEditEnabler;
|
||||||
import com.google.gerrit.common.PageLinks;
|
import com.google.gerrit.common.PageLinks;
|
||||||
import com.google.gerrit.common.errors.EmailException;
|
import com.google.gerrit.common.errors.EmailException;
|
||||||
@@ -153,6 +154,11 @@ class ContactPanelShort extends Composite {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
final ComplexDisclosurePanel mailFilterHelp =
|
||||||
|
new ComplexDisclosurePanel(Util.C.emailFilterHelpTitle(), false);
|
||||||
|
mailFilterHelp.setContent(new HTML(Util.C.emailFilterHelp()));
|
||||||
|
body.add(mailFilterHelp);
|
||||||
|
|
||||||
emailPick.addChangeHandler(
|
emailPick.addChangeHandler(
|
||||||
new ChangeHandler() {
|
new ChangeHandler() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -30,7 +30,8 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{if $email.settingsUrl}
|
{if $email.settingsUrl}
|
||||||
To unsubscribe, visit {$email.settingsUrl}{\n}
|
To unsubscribe, or for help writing mail filters,{sp}
|
||||||
|
visit {$email.settingsUrl}{\n}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{if $email.changeUrl or $email.settingsUrl}
|
{if $email.changeUrl or $email.settingsUrl}
|
||||||
|
|||||||
@@ -29,7 +29,8 @@
|
|||||||
{/if}
|
{/if}
|
||||||
{if $email.changeUrl and $email.settingsUrl}{sp}{/if}
|
{if $email.changeUrl and $email.settingsUrl}{sp}{/if}
|
||||||
{if $email.settingsUrl}
|
{if $email.settingsUrl}
|
||||||
To unsubscribe, visit <a href="{$email.settingsUrl}">settings</a>.
|
To unsubscribe, or for help writing mail filters,{sp}
|
||||||
|
visit <a href="{$email.settingsUrl}">settings</a>.
|
||||||
{/if}
|
{/if}
|
||||||
</p>
|
</p>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2017 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="../base-url-behavior/base-url-behavior.html">
|
||||||
|
<script>
|
||||||
|
(function(window) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const PROBE_PATH = '/Documentation/index.html';
|
||||||
|
const DOCS_BASE_PATH = '/Documentation';
|
||||||
|
|
||||||
|
let cachedPromise;
|
||||||
|
|
||||||
|
/** @polymerBehavior Gerrit.DocsUrlBehavior */
|
||||||
|
const DocsUrlBehavior = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the docs base URL from either the server config or by probing.
|
||||||
|
* @param {Object} config The server config.
|
||||||
|
* @param {!Object} restApi A REST API instance
|
||||||
|
* @return {!Promise<String>} A promise that resolves with the docs base
|
||||||
|
* URL.
|
||||||
|
*/
|
||||||
|
getDocsBaseUrl(config, restApi) {
|
||||||
|
if (!cachedPromise) {
|
||||||
|
cachedPromise = new Promise(resolve => {
|
||||||
|
if (config && config.gerrit && config.gerrit.doc_url) {
|
||||||
|
resolve(config.gerrit.doc_url);
|
||||||
|
} else {
|
||||||
|
restApi.probePath(this.getBaseUrl() + PROBE_PATH).then(ok => {
|
||||||
|
resolve(ok ? (this.getBaseUrl() + DOCS_BASE_PATH) : null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return cachedPromise;
|
||||||
|
},
|
||||||
|
|
||||||
|
/** For testing only. */
|
||||||
|
_clearDocsBaseUrlCache() {
|
||||||
|
cachedPromise = undefined;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
window.Gerrit = window.Gerrit || {};
|
||||||
|
window.Gerrit.DocsUrlBehavior = [
|
||||||
|
window.Gerrit.BaseUrlBehavior,
|
||||||
|
DocsUrlBehavior,
|
||||||
|
];
|
||||||
|
})(window);
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2017 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.
|
||||||
|
-->
|
||||||
|
<!-- Polymer included for the html import polyfill. -->
|
||||||
|
<script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
|
||||||
|
<script src="../../bower_components/web-component-tester/browser.js"></script>
|
||||||
|
<link rel="import" href="../../test/common-test-setup.html"/>
|
||||||
|
<title>docs-url-behavior</title>
|
||||||
|
|
||||||
|
<link rel="import" href="docs-url-behavior.html">
|
||||||
|
|
||||||
|
<script>void(0);</script>
|
||||||
|
|
||||||
|
<test-fixture id="basic">
|
||||||
|
<template>
|
||||||
|
<docs-url-behavior-element></docs-url-behavior-element>
|
||||||
|
</template>
|
||||||
|
</test-fixture>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
suite('docs-url-behavior tests', () => {
|
||||||
|
let element;
|
||||||
|
|
||||||
|
suiteSetup(() => {
|
||||||
|
// Define a Polymer element that uses this behavior.
|
||||||
|
Polymer({
|
||||||
|
is: 'docs-url-behavior-element',
|
||||||
|
behaviors: [Gerrit.DocsUrlBehavior],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
setup(() => {
|
||||||
|
element = fixture('basic');
|
||||||
|
element._clearDocsBaseUrlCache();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('null config', () => {
|
||||||
|
const mockRestApi = {
|
||||||
|
probePath: sinon.stub().returns(Promise.resolve(true)),
|
||||||
|
};
|
||||||
|
return element.getDocsBaseUrl(null, mockRestApi)
|
||||||
|
.then(docsBaseUrl => {
|
||||||
|
assert.isTrue(
|
||||||
|
mockRestApi.probePath.calledWith('/Documentation/index.html'));
|
||||||
|
assert.equal(docsBaseUrl, '/Documentation');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('no doc config', () => {
|
||||||
|
const mockRestApi = {
|
||||||
|
probePath: sinon.stub().returns(Promise.resolve(true)),
|
||||||
|
};
|
||||||
|
const config = {gerrit: {}};
|
||||||
|
return element.getDocsBaseUrl(config, mockRestApi)
|
||||||
|
.then(docsBaseUrl => {
|
||||||
|
assert.isTrue(
|
||||||
|
mockRestApi.probePath.calledWith('/Documentation/index.html'));
|
||||||
|
assert.equal(docsBaseUrl, '/Documentation');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('has doc config', () => {
|
||||||
|
const mockRestApi = {
|
||||||
|
probePath: sinon.stub().returns(Promise.resolve(true)),
|
||||||
|
};
|
||||||
|
const config = {gerrit: {doc_url: 'foobar'}};
|
||||||
|
return element.getDocsBaseUrl(config, mockRestApi)
|
||||||
|
.then(docsBaseUrl => {
|
||||||
|
assert.isFalse(mockRestApi.probePath.called);
|
||||||
|
assert.equal(docsBaseUrl, 'foobar');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('no probe', () => {
|
||||||
|
const mockRestApi = {
|
||||||
|
probePath: sinon.stub().returns(Promise.resolve(false)),
|
||||||
|
};
|
||||||
|
return element.getDocsBaseUrl(null, mockRestApi)
|
||||||
|
.then(docsBaseUrl => {
|
||||||
|
assert.isTrue(
|
||||||
|
mockRestApi.probePath.calledWith('/Documentation/index.html'));
|
||||||
|
assert.isNotOk(docsBaseUrl);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -15,6 +15,7 @@ limitations under the License.
|
|||||||
-->
|
-->
|
||||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||||
|
|
||||||
|
<link rel="import" href="../../../behaviors/docs-url-behavior/docs-url-behavior.html">
|
||||||
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
|
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
|
||||||
<link rel="import" href="../../shared/gr-dropdown/gr-dropdown.html">
|
<link rel="import" href="../../shared/gr-dropdown/gr-dropdown.html">
|
||||||
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
|
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
|
||||||
|
|||||||
@@ -103,6 +103,7 @@
|
|||||||
|
|
||||||
behaviors: [
|
behaviors: [
|
||||||
Gerrit.BaseUrlBehavior,
|
Gerrit.BaseUrlBehavior,
|
||||||
|
Gerrit.DocsUrlBehavior,
|
||||||
],
|
],
|
||||||
|
|
||||||
observers: [
|
observers: [
|
||||||
@@ -188,24 +189,9 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
_loadConfig() {
|
_loadConfig() {
|
||||||
this.$.restAPI.getConfig().then(config => {
|
this.$.restAPI.getConfig()
|
||||||
if (config && config.gerrit && config.gerrit.doc_url) {
|
.then(config => this.getDocsBaseUrl(config, this.$.restAPI))
|
||||||
this._docBaseUrl = config.gerrit.doc_url;
|
.then(docBaseUrl => { this._docBaseUrl = docBaseUrl; });
|
||||||
}
|
|
||||||
if (!this._docBaseUrl) {
|
|
||||||
return this._probeDocLink('/Documentation/index.html');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
_probeDocLink(path) {
|
|
||||||
return this.$.restAPI.probePath(this.getBaseUrl() + path).then(ok => {
|
|
||||||
if (ok) {
|
|
||||||
this._docBaseUrl = this.getBaseUrl() + '/Documentation';
|
|
||||||
} else {
|
|
||||||
this._docBaseUrl = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_accountLoaded(account) {
|
_accountLoaded(account) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ limitations under the License.
|
|||||||
|
|
||||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||||
|
|
||||||
|
<link rel="import" href="../../../behaviors/docs-url-behavior/docs-url-behavior.html">
|
||||||
<link rel="import" href="../../../styles/shared-styles.html">
|
<link rel="import" href="../../../styles/shared-styles.html">
|
||||||
<link rel="import" href="../../../styles/gr-menu-page-styles.html">
|
<link rel="import" href="../../../styles/gr-menu-page-styles.html">
|
||||||
<link rel="import" href="../../../styles/gr-page-nav-styles.html">
|
<link rel="import" href="../../../styles/gr-page-nav-styles.html">
|
||||||
@@ -44,6 +45,12 @@ limitations under the License.
|
|||||||
#email {
|
#email {
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
|
.filters p {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
.queryExample em {
|
||||||
|
color: violet;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<style include="gr-form-styles"></style>
|
<style include="gr-form-styles"></style>
|
||||||
<style include="gr-menu-page-styles"></style>
|
<style include="gr-menu-page-styles"></style>
|
||||||
@@ -69,6 +76,7 @@ limitations under the License.
|
|||||||
<a href="#Agreements">Agreements</a>
|
<a href="#Agreements">Agreements</a>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
|
<li><a href="#MailFilters">Mail Filters</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</gr-page-nav>
|
</gr-page-nav>
|
||||||
<main class="gr-form-styles">
|
<main class="gr-form-styles">
|
||||||
@@ -383,6 +391,76 @@ limitations under the License.
|
|||||||
<gr-agreements-list id="agreementsList"></gr-agreements-list>
|
<gr-agreements-list id="agreementsList"></gr-agreements-list>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</template>
|
</template>
|
||||||
|
<h2 id="MailFilters">Mail Filters</h2>
|
||||||
|
<fieldset class="filters">
|
||||||
|
<p>
|
||||||
|
Gerrit emails include metadata about the change to support
|
||||||
|
writing mail filters.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Here are some example Gmail queries that can be used for filters or
|
||||||
|
for searching through archived messages. View the
|
||||||
|
<a href$="[[_getFilterDocsLink(_docsBaseUrl)]]"
|
||||||
|
target="_blank"
|
||||||
|
rel="nofollow">Gerrit documentation</a>
|
||||||
|
for the complete set of footers.
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr><th>Name</th><th>Query</th></tr>
|
||||||
|
<tr>
|
||||||
|
<td>Changes requesting my review</td>
|
||||||
|
<td>
|
||||||
|
<code class="queryExample">
|
||||||
|
"Gerrit-Reviewer: <em>Your Name</em>
|
||||||
|
<<em>your.email@example.com</em>>"
|
||||||
|
</code>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Changes from a specific owner</td>
|
||||||
|
<td>
|
||||||
|
<code class="queryExample">
|
||||||
|
"Gerrit-Owner: <em>Owner name</em>
|
||||||
|
<<em>owner.email@example.com</em>>"
|
||||||
|
</code>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Changes targeting a specific branch</td>
|
||||||
|
<td>
|
||||||
|
<code class="queryExample">
|
||||||
|
"Gerrit-Branch: <em>branch-name</em>"
|
||||||
|
</code>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Changes in a specific project</td>
|
||||||
|
<td>
|
||||||
|
<code class="queryExample">
|
||||||
|
"Gerrit-Project: <em>project-name</em>"
|
||||||
|
</code>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Messages related to a specific Change ID</td>
|
||||||
|
<td>
|
||||||
|
<code class="queryExample">
|
||||||
|
"Gerrit-Change-Id: <em>Change ID</em>"
|
||||||
|
</code>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Messages related to a specific change number</td>
|
||||||
|
<td>
|
||||||
|
<code class="queryExample">
|
||||||
|
"Gerrit-Change-Number: <em>change number</em>"
|
||||||
|
</code>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</fieldset>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
|
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
|
||||||
|
|||||||
@@ -25,6 +25,10 @@
|
|||||||
'email_format',
|
'email_format',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const GERRIT_DOCS_BASE_URL = 'https://gerrit-review.googlesource.com/' +
|
||||||
|
'Documentation';
|
||||||
|
const GERRIT_DOCS_FILTER_PATH = '/user-notify.html';
|
||||||
|
|
||||||
Polymer({
|
Polymer({
|
||||||
is: 'gr-settings-view',
|
is: 'gr-settings-view',
|
||||||
|
|
||||||
@@ -103,6 +107,7 @@
|
|||||||
value: null,
|
value: null,
|
||||||
},
|
},
|
||||||
_serverConfig: Object,
|
_serverConfig: Object,
|
||||||
|
_docsBaseUrl: String,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For testing purposes.
|
* For testing purposes.
|
||||||
@@ -111,6 +116,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
behaviors: [
|
behaviors: [
|
||||||
|
Gerrit.DocsUrlBehavior,
|
||||||
Gerrit.ChangeTableBehavior,
|
Gerrit.ChangeTableBehavior,
|
||||||
],
|
],
|
||||||
|
|
||||||
@@ -144,9 +150,17 @@
|
|||||||
|
|
||||||
promises.push(this.$.restAPI.getConfig().then(config => {
|
promises.push(this.$.restAPI.getConfig().then(config => {
|
||||||
this._serverConfig = config;
|
this._serverConfig = config;
|
||||||
|
const configPromises = [];
|
||||||
|
|
||||||
if (this._serverConfig.sshd) {
|
if (this._serverConfig.sshd) {
|
||||||
return this.$.sshEditor.loadData();
|
configPromises.push(this.$.sshEditor.loadData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configPromises.push(
|
||||||
|
this.getDocsBaseUrl(config, this.$.restAPI)
|
||||||
|
.then(baseUrl => { this._docsBaseUrl = baseUrl; }));
|
||||||
|
|
||||||
|
return Promise.all(configPromises);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (this.params.emailToken) {
|
if (this.params.emailToken) {
|
||||||
@@ -339,5 +353,13 @@
|
|||||||
this._newEmail = '';
|
this._newEmail = '';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_getFilterDocsLink(docsBaseUrl) {
|
||||||
|
let base = docsBaseUrl;
|
||||||
|
if (!base || !base.startsWith('http')) {
|
||||||
|
base = GERRIT_DOCS_BASE_URL;
|
||||||
|
}
|
||||||
|
return base + GERRIT_DOCS_FILTER_PATH;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ limitations under the License.
|
|||||||
// Behaviors tests.
|
// Behaviors tests.
|
||||||
const behaviors = [
|
const behaviors = [
|
||||||
'base-url-behavior/base-url-behavior_test.html',
|
'base-url-behavior/base-url-behavior_test.html',
|
||||||
|
'docs-url-behavior/docs-url-behavior_test.html',
|
||||||
'keyboard-shortcut-behavior/keyboard-shortcut-behavior_test.html',
|
'keyboard-shortcut-behavior/keyboard-shortcut-behavior_test.html',
|
||||||
'rest-client-behavior/rest-client-behavior_test.html',
|
'rest-client-behavior/rest-client-behavior_test.html',
|
||||||
'gr-change-table-behavior/gr-change-table-behavior_test.html',
|
'gr-change-table-behavior/gr-change-table-behavior_test.html',
|
||||||
|
|||||||
Reference in New Issue
Block a user