diff --git a/Documentation/pg-plugin-dev.txt b/Documentation/pg-plugin-dev.txt index dc6b2b3d94..fc704a1b21 100644 --- a/Documentation/pg-plugin-dev.txt +++ b/Documentation/pg-plugin-dev.txt @@ -311,6 +311,21 @@ screen. .Returns: - Absolute URL for the screen, e.g. `http://localhost/base/x/pluginname/screenname` +[[plugin-settings]] +=== settings +`plugin.settings()` + +.Params: +- none + +.Returns: +- Instance of link:pg-plugin-settings-api.html[GrSettingsApi]. + +=== settingsScreen +`plugin.settingsScreen(path, menu, callback)` + +Deprecated. Use link:#plugin-settings[`plugin.settings()`] instead. + === theme `plugin.theme()` @@ -374,6 +389,19 @@ Support is limited: See link:js-api.html#self_panel[self.panel] for more info. +=== settingsScreen +`plugin.deprecated.settingsScreent(path, menu, callback)` + +.Params: +- `*string* path` URL path fragment of the screen for direct link. +- `*string* menu` Menu item title. +- `*function(settingsScreenContext)* callback` + +Adds a settings menu item and a section in the settings screen that is provided +to plugin for setup. + +See link:js-api.html#self_settingsScreen[self.settingsScreen] for more info. + [[deprecated-action-context]] === Action Context (deprecated) Instance of Action Context is passed to `onAction()` callback. diff --git a/Documentation/pg-plugin-settings-api.txt b/Documentation/pg-plugin-settings-api.txt new file mode 100644 index 0000000000..985809da50 --- /dev/null +++ b/Documentation/pg-plugin-settings-api.txt @@ -0,0 +1,40 @@ += Gerrit Code Review - Settings admin customization API + +This API is provided by link:pg-plugin-dev.html#plugin-settings[plugin.settings()] +and provides customization to settings page. + +== title +`settingsApi.title(title)` + +.Params +- `*string* title` Menu item and settings section title + +.Returns +- `GrSettingsApi` for chaining. + +== token +`settingsApi.token(token)` + +.Params +- `*string* token` URL path fragment of the screen for direct link, e.g. +`settings/#x/some-plugin/*token*` + +.Returns +- `GrSettingsApi` for chaining. + +== module +`settingsApi.module(token)` + +.Params +- `*string* module` Custom element name for instantiating in the settings plugin +area. + +.Returns +- `GrSettingsApi` for chaining. + +== build + +.Params +- none + +Apply all other configuration parameters and create required UI elements. diff --git a/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api.html b/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api.html new file mode 100644 index 0000000000..4c57daf0fc --- /dev/null +++ b/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api.html @@ -0,0 +1,26 @@ + + + + + + + + + + + + diff --git a/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api.js b/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api.js new file mode 100644 index 0000000000..f33b683fed --- /dev/null +++ b/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api.js @@ -0,0 +1,62 @@ +// Copyright (C) 2017 The Android Open Source Settings +// +// 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(window) { + 'use strict'; + + function GrSettingsApi(plugin) { + this._title = '(no title)'; + // Generate default screen URL token, specific to plugin, and unique(ish). + this._token = + plugin.getPluginName() + Math.random().toString(36).substr(5); + this.plugin = plugin; + } + + GrSettingsApi.prototype.title = function(title) { + this._title = title; + return this; + }; + + GrSettingsApi.prototype.token = function(token) { + this._token = token; + return this; + }; + + GrSettingsApi.prototype.module = function(moduleName) { + this._moduleName = moduleName; + return this; + }; + + GrSettingsApi.prototype.build = function() { + if (!this._moduleName) { + throw new Error('Settings screen custom element not defined!'); + } + const token = `x/${this.plugin.getPluginName()}/${this._token}`; + this.plugin.hook('settings-menu-item').onAttached(el => { + const menuItem = document.createElement('gr-settings-menu-item'); + menuItem.title = this._title; + menuItem.href = `#${token}`; + el.appendChild(menuItem); + }); + + return this.plugin.hook('settings-screen').onAttached(el => { + const item = document.createElement('gr-settings-item'); + item.title = this._title; + item.anchor = token; + item.appendChild(document.createElement(this._moduleName)); + el.appendChild(item); + }); + }; + + window.GrSettingsApi = GrSettingsApi; +})(window); diff --git a/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api_test.html b/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api_test.html new file mode 100644 index 0000000000..cbe71fec4a --- /dev/null +++ b/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api_test.html @@ -0,0 +1,82 @@ + + + + +gr-settings-api + + + + + + + + + + + + + + diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-item.html b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-item.html new file mode 100644 index 0000000000..97fbf0a322 --- /dev/null +++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-item.html @@ -0,0 +1,31 @@ + + + + + + + + + diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-item.js b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-item.js new file mode 100644 index 0000000000..e4f5d24723 --- /dev/null +++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-item.js @@ -0,0 +1,24 @@ +// 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. +(function() { + 'use strict'; + + Polymer({ + is: 'gr-settings-item', + properties: { + anchor: String, + title: String, + }, + }); +})(); diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-menu-item.html b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-menu-item.html new file mode 100644 index 0000000000..ff71d3f573 --- /dev/null +++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-menu-item.html @@ -0,0 +1,29 @@ + + + + + + + + + + + diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-menu-item.js b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-menu-item.js new file mode 100644 index 0000000000..797990daca --- /dev/null +++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-menu-item.js @@ -0,0 +1,24 @@ +// 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. +(function() { + 'use strict'; + + Polymer({ + is: 'gr-settings-menu-item', + properties: { + href: String, + title: String, + }, + }); +})(); diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html index ea1f03f1c7..8aae460415 100644 --- a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html +++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html @@ -15,12 +15,12 @@ limitations under the License. --> - - + - + + @@ -79,6 +79,8 @@ limitations under the License.
  • Mail Filters
  • + +
    @@ -480,6 +482,8 @@ limitations under the License. + +
    diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.html index 60b291ae24..a489e2cc53 100644 --- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.html +++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.html @@ -22,6 +22,7 @@ limitations under the License. + diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html index 6147e682f1..5f91be786f 100644 --- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html +++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html @@ -518,5 +518,49 @@ limitations under the License. }); }); }); + + suite('settingsScreen', () => { + test('plugin.settingsScreen is deprecated', () => { + plugin.settingsScreen('rubbish'); + assert.isTrue(console.error.called); + }); + + test('plugin.settings() returns GrSettingsApi', () => { + assert.isOk(plugin.settings()); + assert.isTrue(plugin.settings() instanceof GrSettingsApi); + }); + + test('plugin.deprecated.settingsScreen() works', () => { + const hookStub = {onAttached: sandbox.stub()}; + sandbox.stub(plugin, 'hook').returns(hookStub); + const fakeSettings = {}; + fakeSettings.title = sandbox.stub().returns(fakeSettings); + fakeSettings.token = sandbox.stub().returns(fakeSettings); + fakeSettings.module = sandbox.stub().returns(fakeSettings); + fakeSettings.build = sandbox.stub().returns(hookStub); + sandbox.stub(plugin, 'settings').returns(fakeSettings); + const callback = sandbox.stub(); + + plugin.deprecated.settingsScreen('path', 'menu', callback); + assert.isTrue(fakeSettings.title.calledWith('menu')); + assert.isTrue(fakeSettings.token.calledWith('path')); + assert.isTrue(fakeSettings.module.calledWith('div')); + assert.equal(fakeSettings.build.callCount, 1); + + const fakeBody = {}; + const fakeEl = { + style: { + display: '', + }, + querySelector: sandbox.stub().returns(fakeBody), + }; + // Emulate settings screen attached + hookStub.onAttached.callArgWith(0, fakeEl); + assert.isTrue(callback.called); + const args = callback.args[0][0]; + assert.strictEqual(args.body, fakeBody); + assert.equal(fakeEl.style.display, 'none'); + }); + }); }); diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-public-js-api.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-public-js-api.js index a36b898d90..3958cec8db 100644 --- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-public-js-api.js +++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-public-js-api.js @@ -23,7 +23,7 @@ */ const plugins = {}; - const stubbedMethods = ['_loadedGwt', 'settingsScreen']; + const stubbedMethods = ['_loadedGwt']; const GWT_PLUGIN_STUB = {}; for (const name of stubbedMethods) { GWT_PLUGIN_STUB[name] = warnNotSupported.bind(null, name); @@ -118,6 +118,7 @@ panel: deprecatedAPI.panel.bind(this), popup: deprecatedAPI.popup.bind(this), screen: deprecatedAPI.screen.bind(this), + settingsScreen: deprecatedAPI.settingsScreen.bind(this), }; this._url = new URL(opt_url); @@ -228,6 +229,10 @@ return new GrRepoApi(this); }; + Plugin.prototype.settings = function() { + return new GrSettingsApi(this); + }; + /** * To make REST requests for plugin-provided endpoints, use * @example @@ -260,6 +265,11 @@ 'Use registerCustomComponent() instead.'); }; + Plugin.prototype.settingsScreen = function() { + console.error('.settingsScreen() is deprecated! ' + + 'Use .settings() instead.'); + }; + Plugin.prototype.screen = function(screenName, opt_moduleName) { if (opt_moduleName && typeof opt_moduleName !== 'string') { throw new Error('deprecated, use deprecated.screen'); @@ -333,6 +343,28 @@ }); }, + settingsScreen(path, menu, callback) { + console.warn('.settingsScreen() is deprecated! Use .settings() instead.'); + const hook = this.settings() + .title(menu) + .token(path) + .module('div') + .build(); + hook.onAttached(el => { + el.style.display = 'none'; + const body = el.querySelector('div'); + callback({ + body, + onUnload: () => {}, + setTitle: () => {}, + setWindowTitle: () => {}, + show: () => { + el.style.display = 'initial'; + }, + }); + }); + }, + panel(extensionpoint, callback) { console.warn('.panel() is deprecated! ' + 'Use registerCustomComponent() instead.'); diff --git a/polygerrit-ui/app/test/index.html b/polygerrit-ui/app/test/index.html index ca662ddcd5..ecbd86afb6 100644 --- a/polygerrit-ui/app/test/index.html +++ b/polygerrit-ui/app/test/index.html @@ -116,6 +116,7 @@ limitations under the License. 'plugins/gr-popup-interface/gr-plugin-popup_test.html', 'plugins/gr-popup-interface/gr-popup-interface_test.html', 'plugins/gr-repo-api/gr-repo-api_test.html', + 'plugins/gr-settings-api/gr-settings-api_test.html', 'settings/gr-account-info/gr-account-info_test.html', 'settings/gr-change-table-editor/gr-change-table-editor_test.html', 'settings/gr-email-editor/gr-email-editor_test.html',