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
 | 
			
		||||
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
 | 
			
		||||
------
 | 
			
		||||
Part of link:index.html[Gerrit Code Review]
 | 
			
		||||
 
 | 
			
		||||
@@ -239,6 +239,10 @@ public interface AccountConstants extends Constants {
 | 
			
		||||
 | 
			
		||||
  String errorDialogTitleRegisterNewEmail();
 | 
			
		||||
 | 
			
		||||
  String emailFilterHelpTitle();
 | 
			
		||||
 | 
			
		||||
  String emailFilterHelp();
 | 
			
		||||
 | 
			
		||||
  String newAgreement();
 | 
			
		||||
 | 
			
		||||
  String agreementName();
 | 
			
		||||
 
 | 
			
		||||
@@ -158,7 +158,74 @@ descRegisterNewEmail = \
 | 
			
		||||
  <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>
 | 
			
		||||
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
 | 
			
		||||
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.NativeString;
 | 
			
		||||
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.common.PageLinks;
 | 
			
		||||
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(
 | 
			
		||||
        new ChangeHandler() {
 | 
			
		||||
          @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,8 @@
 | 
			
		||||
  {/if}
 | 
			
		||||
 | 
			
		||||
  {if $email.settingsUrl}
 | 
			
		||||
    To unsubscribe, visit {$email.settingsUrl}{\n}
 | 
			
		||||
    To unsubscribe, or for help writing mail filters,{sp}
 | 
			
		||||
    visit {$email.settingsUrl}{\n}
 | 
			
		||||
  {/if}
 | 
			
		||||
 | 
			
		||||
  {if $email.changeUrl or $email.settingsUrl}
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,8 @@
 | 
			
		||||
      {/if}
 | 
			
		||||
      {if $email.changeUrl and $email.settingsUrl}{sp}{/if}
 | 
			
		||||
      {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}
 | 
			
		||||
    </p>
 | 
			
		||||
  {/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="../../../behaviors/docs-url-behavior/docs-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-rest-api-interface/gr-rest-api-interface.html">
 | 
			
		||||
 
 | 
			
		||||
@@ -103,6 +103,7 @@
 | 
			
		||||
 | 
			
		||||
    behaviors: [
 | 
			
		||||
      Gerrit.BaseUrlBehavior,
 | 
			
		||||
      Gerrit.DocsUrlBehavior,
 | 
			
		||||
    ],
 | 
			
		||||
 | 
			
		||||
    observers: [
 | 
			
		||||
@@ -188,24 +189,9 @@
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _loadConfig() {
 | 
			
		||||
      this.$.restAPI.getConfig().then(config => {
 | 
			
		||||
        if (config && config.gerrit && config.gerrit.doc_url) {
 | 
			
		||||
          this._docBaseUrl = config.gerrit.doc_url;
 | 
			
		||||
        }
 | 
			
		||||
        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;
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
      this.$.restAPI.getConfig()
 | 
			
		||||
          .then(config => this.getDocsBaseUrl(config, this.$.restAPI))
 | 
			
		||||
          .then(docBaseUrl => { this._docBaseUrl = docBaseUrl; });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _accountLoaded(account) {
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@ limitations under the License.
 | 
			
		||||
 | 
			
		||||
<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/gr-menu-page-styles.html">
 | 
			
		||||
<link rel="import" href="../../../styles/gr-page-nav-styles.html">
 | 
			
		||||
@@ -44,6 +45,12 @@ limitations under the License.
 | 
			
		||||
      #email {
 | 
			
		||||
        margin-bottom: 1em;
 | 
			
		||||
      }
 | 
			
		||||
      .filters p {
 | 
			
		||||
        margin-bottom: 1em;
 | 
			
		||||
      }
 | 
			
		||||
      .queryExample em {
 | 
			
		||||
        color: violet;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
    <style include="gr-form-styles"></style>
 | 
			
		||||
    <style include="gr-menu-page-styles"></style>
 | 
			
		||||
@@ -69,6 +76,7 @@ limitations under the License.
 | 
			
		||||
              <a href="#Agreements">Agreements</a>
 | 
			
		||||
            </li>
 | 
			
		||||
          </template>
 | 
			
		||||
          <li><a href="#MailFilters">Mail Filters</a></li>
 | 
			
		||||
        </ul>
 | 
			
		||||
      </gr-page-nav>
 | 
			
		||||
      <main class="gr-form-styles">
 | 
			
		||||
@@ -383,6 +391,76 @@ limitations under the License.
 | 
			
		||||
            <gr-agreements-list id="agreementsList"></gr-agreements-list>
 | 
			
		||||
          </fieldset>
 | 
			
		||||
        </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>
 | 
			
		||||
    </div>
 | 
			
		||||
    <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,10 @@
 | 
			
		||||
    'email_format',
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  const GERRIT_DOCS_BASE_URL = 'https://gerrit-review.googlesource.com/' +
 | 
			
		||||
      'Documentation';
 | 
			
		||||
  const GERRIT_DOCS_FILTER_PATH = '/user-notify.html';
 | 
			
		||||
 | 
			
		||||
  Polymer({
 | 
			
		||||
    is: 'gr-settings-view',
 | 
			
		||||
 | 
			
		||||
@@ -103,6 +107,7 @@
 | 
			
		||||
        value: null,
 | 
			
		||||
      },
 | 
			
		||||
      _serverConfig: Object,
 | 
			
		||||
      _docsBaseUrl: String,
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * For testing purposes.
 | 
			
		||||
@@ -111,6 +116,7 @@
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    behaviors: [
 | 
			
		||||
      Gerrit.DocsUrlBehavior,
 | 
			
		||||
      Gerrit.ChangeTableBehavior,
 | 
			
		||||
    ],
 | 
			
		||||
 | 
			
		||||
@@ -144,9 +150,17 @@
 | 
			
		||||
 | 
			
		||||
      promises.push(this.$.restAPI.getConfig().then(config => {
 | 
			
		||||
        this._serverConfig = config;
 | 
			
		||||
        const configPromises = [];
 | 
			
		||||
 | 
			
		||||
        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) {
 | 
			
		||||
@@ -339,5 +353,13 @@
 | 
			
		||||
        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.
 | 
			
		||||
  const behaviors = [
 | 
			
		||||
    'base-url-behavior/base-url-behavior_test.html',
 | 
			
		||||
    'docs-url-behavior/docs-url-behavior_test.html',
 | 
			
		||||
    'keyboard-shortcut-behavior/keyboard-shortcut-behavior_test.html',
 | 
			
		||||
    'rest-client-behavior/rest-client-behavior_test.html',
 | 
			
		||||
    'gr-change-table-behavior/gr-change-table-behavior_test.html',
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user