Migrate reviewers plugin to polymer 3
Change-Id: I925d0ed0cff1b6f40d2f1311309c48856ff8eca7
diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.eslintignore
diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000..da33ea2
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,165 @@
+{
+ "extends": ["eslint:recommended", "google"],
+ "parserOptions": {
+ "ecmaVersion": 8,
+ "sourceType": "module"
+ },
+ "env": {
+ "browser": true,
+ "es6": true
+ },
+ "globals": {
+ "__dirname": false,
+ "app": false,
+ "page": false,
+ "Polymer": false,
+ "process": false,
+ "require": false,
+ "Gerrit": false,
+ "Promise": false,
+ "assert": false,
+ "test": false,
+ "flushAsynchronousOperations": false
+ },
+ "rules": {
+ "arrow-parens": ["error", "as-needed"],
+ "block-spacing": ["error", "always"],
+ "brace-style": ["error", "1tbs", { "allowSingleLine": true }],
+ "camelcase": "off",
+ "comma-dangle": ["error", {
+ "arrays": "always-multiline",
+ "objects": "always-multiline",
+ "imports": "always-multiline",
+ "exports": "always-multiline",
+ "functions": "never"
+ }],
+ "eol-last": "off",
+ "indent": ["error", 2, {
+ "MemberExpression": 2,
+ "FunctionDeclaration": {"body": 1, "parameters": 2},
+ "FunctionExpression": {"body": 1, "parameters": 2},
+ "CallExpression": {"arguments": 2 },
+ "ArrayExpression": 1,
+ "ObjectExpression": 1,
+ "SwitchCase": 1
+ }],
+ "keyword-spacing": ["error", { "after": true, "before": true }],
+ "lines-between-class-members": ["error", "always"],
+ "max-len": [
+ "error",
+ 80,
+ 2,
+ {
+ "ignoreComments": true,
+ "ignorePattern": "^import .*;$"
+ }
+ ],
+ "new-cap": ["error", { "capIsNewExceptions": ["Polymer", "LegacyElementMixin", "GestureEventListeners", "LegacyDataMixin"] }],
+ "no-console": "off",
+ "no-multiple-empty-lines": [ "error", { "max": 1 } ],
+ "no-prototype-builtins": "off",
+ "no-redeclare": "off",
+ "no-restricted-syntax": [
+ "error",
+ {
+ "selector": "ExpressionStatement > CallExpression > MemberExpression[object.name='test'][property.name='only']",
+ "message": "Remove test.only."
+ },
+ {
+ "selector": "ExpressionStatement > CallExpression > MemberExpression[object.name='suite'][property.name='only']",
+ "message": "Remove suite.only."
+ }
+ ],
+ "no-undef": "off",
+ "no-useless-escape": "off",
+ "no-var": "error",
+ "object-shorthand": ["error", "always"],
+ "padding-line-between-statements": [
+ "error",
+ {
+ "blankLine": "always",
+ "prev": "class",
+ "next": "*"
+ },
+ {
+ "blankLine": "always",
+ "prev": "*",
+ "next": "class"
+ }
+ ],
+ "prefer-arrow-callback": "error",
+ "prefer-const": "error",
+ "prefer-spread": "error",
+ "quote-props": ["error", "consistent-as-needed"],
+ "semi": [2, "always"],
+ "template-curly-spacing": "error",
+ "valid-jsdoc": "off",
+ "require-jsdoc": 0,
+ "valid-jsdoc": 0,
+ "jsdoc/check-alignment": 2,
+ "jsdoc/check-examples": 0,
+ "jsdoc/check-indentation": 0,
+ "jsdoc/check-param-names": 0,
+ "jsdoc/check-syntax": 0,
+ "jsdoc/check-tag-names": 0,
+ "jsdoc/check-types": 0,
+ "jsdoc/implements-on-classes": 2,
+ "jsdoc/match-description": 0,
+ "jsdoc/newline-after-description": 2,
+ "jsdoc/no-types": 0,
+ "jsdoc/no-undefined-types": 0,
+ "jsdoc/require-description": 0,
+ "jsdoc/require-description-complete-sentence": 0,
+ "jsdoc/require-example": 0,
+ "jsdoc/require-hyphen-before-param-description": 0,
+ "jsdoc/require-jsdoc": 0,
+ "jsdoc/require-param": 0,
+ "jsdoc/require-param-description": 0,
+ "jsdoc/require-param-name": 2,
+ "jsdoc/require-param-type": 2,
+ "jsdoc/require-returns": 0,
+ "jsdoc/require-returns-check": 0,
+ "jsdoc/require-returns-description": 0,
+ "jsdoc/require-returns-type": 2,
+ "jsdoc/valid-types": 2,
+ "jsdoc/require-file-overview": ["error", {
+ "tags": {
+ "license": {
+ "mustExist": true,
+ "preventDuplicates": true
+ }
+ }
+ }],
+ "import/named": 2,
+ "import/no-unresolved": 2,
+ "import/no-self-import": 2,
+ // The no-cycle rule is slow, because it doesn't cache dependencies.
+ // Disable it.
+ "import/no-cycle": 0,
+ "import/no-useless-path-segments": 2,
+ "import/no-unused-modules": 2,
+ "import/no-default-export": 2
+ },
+ "plugins": [
+ "html",
+ "jsdoc",
+ "import"
+ ],
+ "settings": {
+ "html/report-bad-indent": "error"
+ },
+ "overrides": [
+ {
+ "files": ["*_html.js", "*-styles.js", "externs.js"],
+ "rules": {
+ "max-len": "off"
+ }
+ },
+ {
+ "files": ["*.html"],
+ "rules": {
+ "jsdoc/require-file-overview": "off"
+ }
+ }
+ ]
+}
diff --git a/.gitignore b/.gitignore
index adb2912..1c805b7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@
/.settings
/local.properties
*.pyc
+/package-lock.json
diff --git a/BUILD b/BUILD
index 8fd0a8e..6379a0d 100644
--- a/BUILD
+++ b/BUILD
@@ -1,5 +1,7 @@
load("@rules_java//java:defs.bzl", "java_library")
+load("@npm_bazel_rollup//:index.bzl", "rollup_bundle")
load("//tools/bzl:junit.bzl", "junit_tests")
+load("//tools/js:eslint.bzl", "eslint")
load(
"//tools/bzl:plugin.bzl",
"PLUGIN_DEPS",
@@ -34,11 +36,20 @@
polygerrit_plugin(
name = "rv-reviewers",
- srcs = glob([
- "rv-reviewers/*.html",
- "rv-reviewers/*.js",
- ]),
- app = "plugin.html",
+ app = "reviewers-bundle.js",
+ plugin_name = "rv-reviewers",
+)
+
+rollup_bundle(
+ name = "reviewers-bundle",
+ srcs = glob(["rv-reviewers/*.js"]),
+ entry_point = "rv-reviewers/plugin.js",
+ format = "iife",
+ rollup_bin = "//tools/node_tools:rollup-bin",
+ sourcemap = "hidden",
+ deps = [
+ "@tools_npm//rollup-plugin-node-resolve",
+ ],
)
junit_tests(
@@ -50,3 +61,24 @@
":reviewers__plugin",
],
)
+
+# Define the eslinter for the plugin
+# The eslint macro creates 2 rules: lint_test and lint_bin
+eslint(
+ name = "lint",
+ srcs = glob([
+ "rv-reviewers/*.js",
+ ]),
+ config = ".eslintrc.json",
+ data = [],
+ extensions = [
+ ".js",
+ ],
+ ignore = ".eslintignore",
+ plugins = [
+ "@npm//eslint-config-google",
+ "@npm//eslint-plugin-html",
+ "@npm//eslint-plugin-import",
+ "@npm//eslint-plugin-jsdoc",
+ ],
+)
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..2064647
--- /dev/null
+++ b/package.json
@@ -0,0 +1,13 @@
+{
+ "name": "reviewers",
+ "description": "Reviewers plugin",
+ "browser": true,
+ "scripts": {
+ "safe_bazelisk": "if which bazelisk >/dev/null; then bazel_bin=bazelisk; else bazel_bin=bazel; fi && $bazel_bin",
+ "eslint": "npm run safe_bazelisk test :lint_test",
+ "eslintfix": "npm run safe_bazelisk run :lint_bin -- -- --fix $(pwd)"
+ },
+ "devDependencies": {},
+ "license": "Apache-2.0",
+ "private": true
+}
diff --git a/plugin.html b/plugin.html
deleted file mode 100644
index 29c10cb..0000000
--- a/plugin.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-@license
-Copyright (C) 2019 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="./rv-reviewers/rv-reviewers.html">
-
-<dom-module id="reviewers">
- <script>
- if (window.Polymer) {
- Gerrit.install(plugin => {
- plugin.registerCustomComponent('repo-command', 'rv-reviewers');
- });
- }
- </script>
-</dom-module>
diff --git a/rv-reviewers/plugin.js b/rv-reviewers/plugin.js
new file mode 100644
index 0000000..ba7e1d2
--- /dev/null
+++ b/rv-reviewers/plugin.js
@@ -0,0 +1,22 @@
+/**
+ * @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.
+ */
+import './rv-reviewers.js';
+
+Gerrit.install(plugin => {
+ plugin.registerCustomComponent(
+ 'repo-command', 'rv-reviewers');
+});
diff --git a/rv-reviewers/rv-edit-screen.js b/rv-reviewers/rv-edit-screen.js
index be302a8..36ff185 100644
--- a/rv-reviewers/rv-edit-screen.js
+++ b/rv-reviewers/rv-edit-screen.js
@@ -1,72 +1,84 @@
-// Copyright (C) 2019 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() {
- class RvEditScreen extends Polymer.Element {
- static get is() { return 'rv-edit-screen'; }
+/**
+ * @license
+ * Copyright (C) 2019 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.
+ */
+import {htmlTemplate} from './rv-edit-screen_html.js';
- static get properties() {
- return {
- pluginRestApi: {
- type: Object,
- observer: '_loadFilterSections',
- },
- repoName: String,
- loading: Boolean,
- canModifyConfig: Boolean,
- _editingFilter: {
- type: Boolean,
- value: false,
- },
- _filterSections: Array,
- };
- }
+class RvEditScreen extends Polymer.Element {
+ /** @returns {string} name of the component */
+ static get is() { return 'rv-edit-screen'; }
- _loadFilterSections() {
- this.pluginRestApi.get(this._getReviewersUrl(this.repoName))
- .then(filterSections => {
- this._filterSections = filterSections;
- });
- }
+ /** @returns {?} template for this component */
+ static get template() { return htmlTemplate; }
- _computeAddFilterBtnHidden(canModifyConfig, editingFilter) {
- return !canModifyConfig || editingFilter;
- }
-
- _computeLoadingClass(loading) {
- return loading ? 'loading' : '';
- }
-
- _getReviewersUrl(repoName) {
- return `/projects/${encodeURIComponent(repoName)}/reviewers`;
- }
-
- _handleCreateSection() {
- const section = {filter: '', reviewers: [], editing: true};
- this._editingFilter = true;
- this.push('_filterSections', section);
- }
-
- _handleCloseTap(e) {
- e.preventDefault();
- this.fire('close', null, {bubbles: false});
- }
-
- _handleReviewerChanged(e) {
- this._filterSections = e.detail.result;
- this._editingFilter = false;
- }
+ /**
+ * Defines properties of the component
+ *
+ * @returns {?}
+ */
+ static get properties() {
+ return {
+ pluginRestApi: {
+ type: Object,
+ observer: '_loadFilterSections',
+ },
+ repoName: String,
+ loading: Boolean,
+ canModifyConfig: Boolean,
+ _editingFilter: {
+ type: Boolean,
+ value: false,
+ },
+ _filterSections: Array,
+ };
}
- customElements.define(RvEditScreen.is, RvEditScreen);
-})();
+ _loadFilterSections() {
+ this.pluginRestApi.get(this._getReviewersUrl(this.repoName))
+ .then(filterSections => {
+ this._filterSections = filterSections;
+ });
+ }
+
+ _computeAddFilterBtnHidden(canModifyConfig, editingFilter) {
+ return !canModifyConfig || editingFilter;
+ }
+
+ _computeLoadingClass(loading) {
+ return loading ? 'loading' : '';
+ }
+
+ _getReviewersUrl(repoName) {
+ return `/projects/${encodeURIComponent(repoName)}/reviewers`;
+ }
+
+ _handleCreateSection() {
+ const section = {filter: '', reviewers: [], editing: true};
+ this._editingFilter = true;
+ this.push('_filterSections', section);
+ }
+
+ _handleCloseTap(e) {
+ e.preventDefault();
+ this.fire('close', null, {bubbles: false});
+ }
+
+ _handleReviewerChanged(e) {
+ this._filterSections = e.detail.result;
+ this._editingFilter = false;
+ }
+}
+
+customElements.define(RvEditScreen.is, RvEditScreen);
diff --git a/rv-reviewers/rv-edit-screen.html b/rv-reviewers/rv-edit-screen_html.js
similarity index 70%
rename from rv-reviewers/rv-edit-screen.html
rename to rv-reviewers/rv-edit-screen_html.js
index 3291e3c..c6e46a5 100644
--- a/rv-reviewers/rv-edit-screen.html
+++ b/rv-reviewers/rv-edit-screen_html.js
@@ -1,23 +1,22 @@
-<!--
-@license
-Copyright (C) 2019 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2019 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.
+ */
+import './rv-filter-section.js';
-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="./rv-filter-section.html">
-
-<dom-module id="rv-edit-screen">
- <template>
+export const htmlTemplate = Polymer.html`
<style include="shared-styles"></style>
<style include="gr-menu-page-styles"></style>
<style include="gr-subpage-styles">
@@ -72,6 +71,4 @@
hidden="[[_computeAddFilterBtnHidden(canModifyConfig, _editingFilter)]]">Add New Filter</gr-button>
</div>
</div>
- </template>
- <script src="./rv-edit-screen.js"></script>
-</dom-module>
+`;
diff --git a/rv-reviewers/rv-filter-section.js b/rv-reviewers/rv-filter-section.js
index 962a54f..568ba6d 100644
--- a/rv-reviewers/rv-filter-section.js
+++ b/rv-reviewers/rv-filter-section.js
@@ -1,104 +1,116 @@
-// Copyright (C) 2019 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() {
- class RvFilterSection extends Polymer.Element {
- static get is() { return 'rv-filter-section'; }
+/**
+ * @license
+ * Copyright (C) 2019 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.
+ */
+import {htmlTemplate} from './rv-filter-section_html.js';
- static get properties() {
- return {
- pluginRestApi: Object,
- repoName: String,
- reviewers: Array,
- filter: String,
- canModifyConfig: Boolean,
- _originalFilter: String,
- _editingReviewer: {
- type: Boolean,
- value: false,
- },
- reviewersUrl: String,
- };
+class RvFilterSection extends Polymer.Element {
+ /** @returns {string} name of the component */
+ static get is() { return 'rv-filter-section'; }
+
+ /** @returns {?} template for this component */
+ static get template() { return htmlTemplate; }
+
+ /**
+ * Defines properties of the component
+ *
+ * @returns {?}
+ */
+ static get properties() {
+ return {
+ pluginRestApi: Object,
+ repoName: String,
+ reviewers: Array,
+ filter: String,
+ canModifyConfig: Boolean,
+ _originalFilter: String,
+ _editingReviewer: {
+ type: Boolean,
+ value: false,
+ },
+ reviewersUrl: String,
+ };
+ }
+
+ connectedCallback() {
+ super.connectedCallback();
+ this._updateSection();
+ }
+
+ _updateSection() {
+ this._originalFilter = this.filter;
+ }
+
+ _computeEditing(filter, _originalFilter) {
+ if (_originalFilter === '') {
+ return true;
}
+ return filter === '';
+ }
- connectedCallback() {
- super.connectedCallback();
- this._updateSection();
- }
+ _computeCancelHidden(filter, _originalFilter) {
+ return !this._computeEditing(filter, _originalFilter);
+ }
- _updateSection() {
- this._originalFilter = this.filter;
- }
+ _computeAddBtnHidden(canModifyConfig, editingReviewer) {
+ return !(canModifyConfig && !editingReviewer);
+ }
- _computeEditing(filter, _originalFilter) {
- if (_originalFilter === '') {
- return true;
- }
- return filter === '';
- }
+ _computeFilterInputDisabled(canModifyConfig, originalFilter) {
+ return !canModifyConfig || originalFilter !== '';
+ }
- _computeCancelHidden(filter, _originalFilter) {
- return !this._computeEditing(filter, _originalFilter);
- }
+ _handleCancel() {
+ this.remove();
+ }
- _computeAddBtnHidden(canModifyConfig, editingReviewer) {
- return !(canModifyConfig && !editingReviewer);
- }
-
- _computeFilterInputDisabled(canModifyConfig, originalFilter) {
- return !canModifyConfig || originalFilter !== '';
- }
-
- _handleCancel() {
- this.remove();
- }
-
- _handleReviewerDeleted(e) {
- if (e.detail.editing) {
- this.reviewers.pop();
- this._editingReviewer = false;
- } else {
- const index = e.model.index;
- const deleted = this.reviewers[index];
- this._putReviewer(deleted, 'DELETE');
- }
- }
-
- _handleReviewerAdded(e) {
+ _handleReviewerDeleted(e) {
+ if (e.detail.editing) {
+ this.reviewers.pop();
this._editingReviewer = false;
- this._putReviewer(e.detail.reviewer, 'ADD').catch(err => {
- this.fire('show-alert', {message: err});
- throw err;
- });
- }
-
- _putReviewer(reviewer, action) {
- return this.pluginRestApi.put(this.reviewersUrl, {
- action,
- reviewer,
- filter: this.filter,
- }).then(result => {
- const detail = {result};
- this.dispatchEvent(
- new CustomEvent('reviewer-changed', {detail, bubbles: true}));
- });
- }
-
- _handleAddReviewer() {
- this.push('reviewers', '');
- this._editingReviewer = true;
+ } else {
+ const index = e.model.index;
+ const deleted = this.reviewers[index];
+ this._putReviewer(deleted, 'DELETE');
}
}
- customElements.define(RvFilterSection.is, RvFilterSection);
-})();
+ _handleReviewerAdded(e) {
+ this._editingReviewer = false;
+ this._putReviewer(e.detail.reviewer, 'ADD').catch(err => {
+ this.fire('show-alert', {message: err});
+ throw err;
+ });
+ }
+
+ _putReviewer(reviewer, action) {
+ return this.pluginRestApi.put(this.reviewersUrl, {
+ action,
+ reviewer,
+ filter: this.filter,
+ }).then(result => {
+ const detail = {result};
+ this.dispatchEvent(
+ new CustomEvent('reviewer-changed', {detail, bubbles: true}));
+ });
+ }
+
+ _handleAddReviewer() {
+ this.push('reviewers', '');
+ this._editingReviewer = true;
+ }
+}
+
+customElements.define(RvFilterSection.is, RvFilterSection);
diff --git a/rv-reviewers/rv-filter-section.html b/rv-reviewers/rv-filter-section_html.js
similarity index 77%
rename from rv-reviewers/rv-filter-section.html
rename to rv-reviewers/rv-filter-section_html.js
index 7513675..e850b39 100644
--- a/rv-reviewers/rv-filter-section.html
+++ b/rv-reviewers/rv-filter-section_html.js
@@ -1,23 +1,22 @@
-<!--
-@license
-Copyright (C) 2019 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2019 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.
+ */
+import './rv-reviewer.js';
-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="./rv-reviewer.html">
-
-<dom-module id="rv-filter-section">
- <template>
+export const htmlTemplate = Polymer.html`
<style include="shared-styles">
:host {
display: block;
@@ -99,6 +98,4 @@
</div><!-- reviewers -->
</div>
</fieldset>
- </template>
- <script src="./rv-filter-section.js"></script>
-</dom-module>
+`;
diff --git a/rv-reviewers/rv-reviewer.js b/rv-reviewers/rv-reviewer.js
index bb0b792..dd516c4 100644
--- a/rv-reviewers/rv-reviewer.js
+++ b/rv-reviewers/rv-reviewer.js
@@ -1,141 +1,153 @@
-// Copyright (C) 2019 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() {
- class RvReviewer extends Polymer.Element {
- static get is() { return 'rv-reviewer'; }
+/**
+ * @license
+ * Copyright (C) 2019 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.
+ */
+import {htmlTemplate} from './rv-reviewer_html.js';
- static get properties() {
- return {
- canModifyConfig: Boolean,
- pluginRestAPi: Object,
- repoName: String,
- reviewer: String,
- _reviewerSearchId: String,
- _queryReviewers: {
- type: Function,
- value() {
- return this._getReviewerSuggestions.bind(this);
- },
+class RvReviewer extends Polymer.Element {
+ /** @returns {string} name of the component */
+ static get is() { return 'rv-reviewer'; }
+
+ /** @returns {?} template for this component */
+ static get template() { return htmlTemplate; }
+
+ /**
+ * Defines properties of the component
+ *
+ * @returns {?}
+ */
+ static get properties() {
+ return {
+ canModifyConfig: Boolean,
+ pluginRestAPi: Object,
+ repoName: String,
+ reviewer: String,
+ _reviewerSearchId: String,
+ _queryReviewers: {
+ type: Function,
+ value() {
+ return this._getReviewerSuggestions.bind(this);
},
- _originalReviewer: String,
- _deleted: Boolean,
- _editing: {
- type: Boolean,
- computed: '_computeEditing(reviewer, _originalReviewer)',
- },
- };
- }
-
- connectedCallback() {
- super.connectedCallback();
- this._originalReviewer = this.reviewer;
- }
-
- _computeEditing(reviewer, _originalReviewer) {
- if (_originalReviewer === '') {
- return true;
- }
- return reviewer === '';
- }
-
- _computeDeleteCancel(reviewer, _originalReviewer) {
- return this._computeEditing(reviewer, _originalReviewer) ?
- 'Cancel' : 'Delete';
- }
-
- _computeHideAddButton(reviewer, _originalReviewer) {
- return !(this._computeEditing(reviewer, _originalReviewer)
- && this._reviewerSearchId);
- }
-
- _computeHideDeleteButton(canModifyConfig) {
- return !canModifyConfig;
- }
-
- _getReviewerSuggestions(input) {
- if (input.length === 0) { return Promise.resolve([]); }
- const promises = [];
- promises.push(this._getSuggestedGroups(input));
- promises.push(this._getSuggestedAccounts(input));
- return Promise.all(promises).then(result => {
- return result.flat();
- });
- }
-
- _getSuggestedGroups(input) {
- const suggestUrl = `/groups/?suggest=${input}&p=${this.repoName}`;
- return this.pluginRestApi.get(suggestUrl).then(groups => {
- if (!groups) { return []; }
- const groupSuggestions = [];
- for (const key in groups) {
- if (!groups.hasOwnProperty(key)) { continue; }
- groupSuggestions.push({
- name: key,
- value: key,
- });
- }
- return groupSuggestions;
- });
- }
-
- _getSuggestedAccounts(input) {
- const suggestUrl = `/accounts/?suggest&q=${input}`;
- return this.pluginRestApi.get(suggestUrl).then(accounts => {
- const accountSuggestions = [];
- let nameAndEmail;
- let value;
- if (!accounts) { return []; }
- for (const key in accounts) {
- if (!accounts.hasOwnProperty(key)) { continue; }
- if (accounts[key].email) {
- nameAndEmail = accounts[key].name +
- ' <' + accounts[key].email + '>';
- } else {
- nameAndEmail = accounts[key].name;
- }
- if (accounts[key].username) {
- value = accounts[key].username;
- } else if (accounts[key].email) {
- value = accounts[key].email;
- } else {
- value = accounts[key]._account_id;
- }
- accountSuggestions.push({
- name: nameAndEmail,
- value,
- });
- }
- return accountSuggestions;
- });
- }
-
- _handleDeleteCancel() {
- const detail = {editing: this._editing};
- if (this._editing) {
- this.remove();
- }
- this.dispatchEvent(
- new CustomEvent('reviewer-deleted', {detail, bubbles: true}));
- }
-
- _handleAddReviewer() {
- const detail = {reviewer: this._reviewerSearchId};
- this._originalReviewer = this.reviewer;
- this.dispatchEvent(
- new CustomEvent('reviewer-added', {detail, bubbles: true}));
- }
+ },
+ _originalReviewer: String,
+ _deleted: Boolean,
+ _editing: {
+ type: Boolean,
+ computed: '_computeEditing(reviewer, _originalReviewer)',
+ },
+ };
}
- customElements.define(RvReviewer.is, RvReviewer);
-})();
+ connectedCallback() {
+ super.connectedCallback();
+ this._originalReviewer = this.reviewer;
+ }
+
+ _computeEditing(reviewer, _originalReviewer) {
+ if (_originalReviewer === '') {
+ return true;
+ }
+ return reviewer === '';
+ }
+
+ _computeDeleteCancel(reviewer, _originalReviewer) {
+ return this._computeEditing(reviewer, _originalReviewer) ?
+ 'Cancel' : 'Delete';
+ }
+
+ _computeHideAddButton(reviewer, _originalReviewer) {
+ return !(this._computeEditing(reviewer, _originalReviewer)
+ && this._reviewerSearchId);
+ }
+
+ _computeHideDeleteButton(canModifyConfig) {
+ return !canModifyConfig;
+ }
+
+ _getReviewerSuggestions(input) {
+ if (input.length === 0) { return Promise.resolve([]); }
+ const promises = [];
+ promises.push(this._getSuggestedGroups(input));
+ promises.push(this._getSuggestedAccounts(input));
+ return Promise.all(promises).then(result => {
+ return result.flat();
+ });
+ }
+
+ _getSuggestedGroups(input) {
+ const suggestUrl = `/groups/?suggest=${input}&p=${this.repoName}`;
+ return this.pluginRestApi.get(suggestUrl).then(groups => {
+ if (!groups) { return []; }
+ const groupSuggestions = [];
+ for (const key in groups) {
+ if (!groups.hasOwnProperty(key)) { continue; }
+ groupSuggestions.push({
+ name: key,
+ value: key,
+ });
+ }
+ return groupSuggestions;
+ });
+ }
+
+ _getSuggestedAccounts(input) {
+ const suggestUrl = `/accounts/?suggest&q=${input}`;
+ return this.pluginRestApi.get(suggestUrl).then(accounts => {
+ const accountSuggestions = [];
+ let nameAndEmail;
+ let value;
+ if (!accounts) { return []; }
+ for (const key in accounts) {
+ if (!accounts.hasOwnProperty(key)) { continue; }
+ if (accounts[key].email) {
+ nameAndEmail = accounts[key].name +
+ ' <' + accounts[key].email + '>';
+ } else {
+ nameAndEmail = accounts[key].name;
+ }
+ if (accounts[key].username) {
+ value = accounts[key].username;
+ } else if (accounts[key].email) {
+ value = accounts[key].email;
+ } else {
+ value = accounts[key]._account_id;
+ }
+ accountSuggestions.push({
+ name: nameAndEmail,
+ value,
+ });
+ }
+ return accountSuggestions;
+ });
+ }
+
+ _handleDeleteCancel() {
+ const detail = {editing: this._editing};
+ if (this._editing) {
+ this.remove();
+ }
+ this.dispatchEvent(
+ new CustomEvent('reviewer-deleted', {detail, bubbles: true}));
+ }
+
+ _handleAddReviewer() {
+ const detail = {reviewer: this._reviewerSearchId};
+ this._originalReviewer = this.reviewer;
+ this.dispatchEvent(
+ new CustomEvent('reviewer-added', {detail, bubbles: true}));
+ }
+}
+
+customElements.define(RvReviewer.is, RvReviewer);
\ No newline at end of file
diff --git a/rv-reviewers/rv-reviewer.html b/rv-reviewers/rv-reviewer_html.js
similarity index 69%
rename from rv-reviewers/rv-reviewer.html
rename to rv-reviewers/rv-reviewer_html.js
index 10ab166..a4eee47 100644
--- a/rv-reviewers/rv-reviewer.html
+++ b/rv-reviewers/rv-reviewer_html.js
@@ -1,21 +1,20 @@
-<!--
-@license
-Copyright (C) 2019 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.
--->
-<dom-module id="rv-reviewer">
- <template>
+/**
+ * @license
+ * Copyright (C) 2019 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.
+ */
+export const htmlTemplate = Polymer.html`
<style include="shared-styles">
#editReviewerInput {
display: block;
@@ -45,11 +44,11 @@
<span class="value">
<!--
TODO:
- Investigate wether we could reuse gr-account-list.
+ Investigate whether we could reuse gr-account-list.
If the REST API returns AccountInfo instead of an account
identifier String we should be able to use gr-account-list(size=1)
for all reviewers, including those who are non-editable
- (#reviewerField below) and allign the plugin with how accounts
+ (#reviewerField below) and align the plugin with how accounts
are displayed in core Gerrit's UI.
-->
<gr-autocomplete
@@ -74,6 +73,4 @@
on-tap="_handleAddReviewer"
hidden$="[[_computeHideAddButton(reviewer, _originalReviewer)]]">Add</gr-button>
</div> <!-- reviewerRow -->
- </template>
- <script src="./rv-reviewer.js"></script>
-</dom-module>
+`;
\ No newline at end of file
diff --git a/rv-reviewers/rv-reviewers.html b/rv-reviewers/rv-reviewers.html
deleted file mode 100644
index f44aa6f..0000000
--- a/rv-reviewers/rv-reviewers.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!--
-@license
-Copyright (C) 2019 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="./rv-edit-screen.html">
-
-<dom-module id="rv-reviewers">
- <template>
- <style include="shared-styles">
- #rvScreenOverlay {
- width: 50em;
- overflow: auto;
- }
- </style>
- <gr-repo-command
- title="Reviewers Config"
- on-command-tap="_handleCommandTap">
- </gr-repo-command>
- <gr-overlay id="rvScreenOverlay" with-backdrop>
- <rv-edit-screen
- plugin-rest-api="[[pluginRestApi]]"
- repo-name="[[repoName]]"
- loading="[[_loading]]"
- can-modify-config="[[_canModifyConfig]]"
- on-close="_handleRvEditScreenClose"></rv-edit-screen>
- </gr-overlay>
- </template>
- <script src="./rv-reviewers.js"></script>
-</dom-module>
diff --git a/rv-reviewers/rv-reviewers.js b/rv-reviewers/rv-reviewers.js
index 8c10ea4..9782b8c 100644
--- a/rv-reviewers/rv-reviewers.js
+++ b/rv-reviewers/rv-reviewers.js
@@ -1,87 +1,100 @@
-// Copyright (C) 2019 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() {
- class RvReviewers extends Polymer.Element {
- static get is() { return 'rv-reviewers'; }
+/**
+ * @license
+ * Copyright (C) 2019 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.
+ */
+import {htmlTemplate} from './rv-reviewers_html.js';
- static get properties() {
- return {
- pluginRestApi: Object,
- repoName: String,
- _canModifyConfig: {
- type: Boolean,
- computed: '_computeCanModifyConfig(_isOwner, _hasModifyCapability)',
- },
- _loading: {
- type: Boolean,
- value: true,
- },
- _isOwner: {
- type: Boolean,
- value: false,
- },
- _hasModifyCapability: {
- type: Boolean,
- value: false,
- },
- };
- }
+class RvReviewers extends Polymer.Element {
+ /** @returns {string} name of the component */
+ static get is() { return 'rv-reviewers'; }
- connectedCallback() {
- super.connectedCallback();
- this.pluginRestApi = this.plugin.restApi();
- this._setCanModifyConfig();
- }
+ /** @returns {?} template for this component */
+ static get template() { return htmlTemplate; }
- _handleCommandTap() {
- this.$.rvScreenOverlay.open();
- }
-
- _handleRvEditScreenClose() {
- this.$.rvScreenOverlay.close();
- }
-
- _setCanModifyConfig() {
- const promises = [];
- promises.push(this._getRepoAccess(this.repoName).then( access => {
- if (access && access[this.repoName] && access[this.repoName].is_owner) {
- this._isOwner = true;
- }
- }));
- promises.push(this._getCapabilities().then(capabilities => {
- if (capabilities['reviewers-modifyReviewersConfig']) {
- this._hasModifyCapability = true;
- }
- }));
- Promise.all(promises).then(() => {
- this._loading = false;
- });
- }
-
- _computeCanModifyConfig(isOwner, hasModifyCapability) {
- return isOwner || hasModifyCapability;
- }
-
- _getRepoAccess(repoName) {
- return this.pluginRestApi.get(
- '/access/?project=' + encodeURIComponent(repoName));
- }
-
- _getCapabilities() {
- return this.pluginRestApi.get('/accounts/self/capabilities');
- }
+ /**
+ * Defines properties of the component
+ *
+ * @returns {?}
+ */
+ static get properties() {
+ return {
+ pluginRestApi: Object,
+ repoName: String,
+ _canModifyConfig: {
+ type: Boolean,
+ computed: '_computeCanModifyConfig(_isOwner, _hasModifyCapability)',
+ },
+ _loading: {
+ type: Boolean,
+ value: true,
+ },
+ _isOwner: {
+ type: Boolean,
+ value: false,
+ },
+ _hasModifyCapability: {
+ type: Boolean,
+ value: false,
+ },
+ };
}
- customElements.define(RvReviewers.is, RvReviewers);
-})();
+ connectedCallback() {
+ super.connectedCallback();
+ this.pluginRestApi = this.plugin.restApi();
+ this._setCanModifyConfig();
+ }
+
+ _handleCommandTap() {
+ this.$.rvScreenOverlay.open();
+ }
+
+ _handleRvEditScreenClose() {
+ this.$.rvScreenOverlay.close();
+ }
+
+ _setCanModifyConfig() {
+ const promises = [];
+ promises.push(this._getRepoAccess(this.repoName).then( access => {
+ if (access && access[this.repoName] && access[this.repoName].is_owner) {
+ this._isOwner = true;
+ }
+ }));
+ promises.push(this._getCapabilities().then(capabilities => {
+ if (capabilities['reviewers-modifyReviewersConfig']) {
+ this._hasModifyCapability = true;
+ }
+ }));
+ Promise.all(promises).then(() => {
+ this._loading = false;
+ });
+ }
+
+ _computeCanModifyConfig(isOwner, hasModifyCapability) {
+ return isOwner || hasModifyCapability;
+ }
+
+ _getRepoAccess(repoName) {
+ return this.pluginRestApi.get(
+ '/access/?project=' + encodeURIComponent(repoName));
+ }
+
+ _getCapabilities() {
+ return this.pluginRestApi.get('/accounts/self/capabilities');
+ }
+}
+
+customElements.define(RvReviewers.is, RvReviewers);
+
diff --git a/rv-reviewers/rv-reviewers_html.js b/rv-reviewers/rv-reviewers_html.js
new file mode 100644
index 0000000..358e5e5
--- /dev/null
+++ b/rv-reviewers/rv-reviewers_html.js
@@ -0,0 +1,38 @@
+/**
+ * @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.
+ */
+import './rv-edit-screen.js';
+
+export const htmlTemplate = Polymer.html`
+ <style include="shared-styles">
+ #rvScreenOverlay {
+ width: 50em;
+ overflow: auto;
+ }
+ </style>
+ <gr-repo-command
+ title="Reviewers Config"
+ on-command-tap="_handleCommandTap">
+ </gr-repo-command>
+ <gr-overlay id="rvScreenOverlay" with-backdrop>
+ <rv-edit-screen
+ plugin-rest-api="[[pluginRestApi]]"
+ repo-name="[[repoName]]"
+ loading="[[_loading]]"
+ can-modify-config="[[_canModifyConfig]]"
+ on-close="_handleRvEditScreenClose"></rv-edit-screen>
+ </gr-overlay>
+`;