Support for .settingsScreen() plugin API
Change-Id: I05ef82957952893ca64c5af5ef59d2c0a54d95c1
This commit is contained in:
parent
9a0fa9f65a
commit
17c02269fc
@ -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.
|
||||
|
40
Documentation/pg-plugin-settings-api.txt
Normal file
40
Documentation/pg-plugin-settings-api.txt
Normal file
@ -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.
|
@ -0,0 +1,26 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
|
||||
<link rel="import" href="../../settings/gr-settings-view/gr-settings-item.html">
|
||||
<link rel="import" href="../../settings/gr-settings-view/gr-settings-menu-item.html">
|
||||
<link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html">
|
||||
<link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html">
|
||||
|
||||
<dom-module id="gr-settings-api">
|
||||
<script src="gr-settings-api.js"></script>
|
||||
</dom-module>
|
@ -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);
|
@ -0,0 +1,82 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
|
||||
<title>gr-settings-api</title>
|
||||
|
||||
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
|
||||
<script src="../../../bower_components/web-component-tester/browser.js"></script>
|
||||
<link rel="import" href="../../../test/common-test-setup.html"/>
|
||||
<link rel="import" href="../gr-endpoint-decorator/gr-endpoint-decorator.html">
|
||||
<link rel="import" href="gr-settings-api.html">
|
||||
|
||||
<script>void(0);</script>
|
||||
|
||||
<test-fixture id="basic">
|
||||
<template>
|
||||
<gr-endpoint-decorator name="settings-menu-item">
|
||||
</gr-endpoint-decorator>
|
||||
<gr-endpoint-decorator name="settings-screen">
|
||||
</gr-endpoint-decorator>
|
||||
</template>
|
||||
</test-fixture>
|
||||
|
||||
<script>
|
||||
suite('gr-settings-api tests', () => {
|
||||
let sandbox;
|
||||
let settingsApi;
|
||||
|
||||
setup(() => {
|
||||
sandbox = sinon.sandbox.create();
|
||||
let plugin;
|
||||
Gerrit.install(p => { plugin = p; }, '0.1',
|
||||
'http://test.com/plugins/testplugin/static/test.js');
|
||||
sandbox.stub(Gerrit, '_arePluginsLoaded').returns(true);
|
||||
settingsApi = plugin.settings();
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
settingsApi = null;
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
test('exists', () => {
|
||||
assert.isOk(settingsApi);
|
||||
});
|
||||
|
||||
test('works', done => {
|
||||
settingsApi
|
||||
.title('foo')
|
||||
.token('bar')
|
||||
.module('some-settings-screen')
|
||||
.build();
|
||||
const element = fixture('basic');
|
||||
flush(() => {
|
||||
const [menuItemEl, itemEl] = element;
|
||||
const menuItem = menuItemEl.$$('gr-settings-menu-item');
|
||||
assert.isOk(menuItem);
|
||||
assert.equal(menuItem.title, 'foo');
|
||||
assert.equal(menuItem.href, '#x/testplugin/bar');
|
||||
const item = itemEl.$$('gr-settings-item');
|
||||
assert.isOk(item);
|
||||
assert.equal(item.title, 'foo');
|
||||
assert.equal(item.anchor, 'x/testplugin/bar');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
@ -0,0 +1,31 @@
|
||||
<!--
|
||||
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="../../../bower_components/polymer/polymer.html">
|
||||
|
||||
<dom-module id="gr-settings-item">
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<h2 id="[[anchor]]">[[title]]</h2>
|
||||
<slot></slot>
|
||||
</template>
|
||||
<script src="gr-settings-item.js"></script>
|
||||
</dom-module>
|
@ -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,
|
||||
},
|
||||
});
|
||||
})();
|
@ -0,0 +1,29 @@
|
||||
<!--
|
||||
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="../../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../../../styles/gr-page-nav-styles.html">
|
||||
|
||||
<dom-module id="gr-settings-menu-item">
|
||||
<style include="shared-styles"></style>
|
||||
<style include="gr-page-nav-styles"></style>
|
||||
<template>
|
||||
<div class="navStyles">
|
||||
<li><a href$="[[href]]">[[title]]</a></li>
|
||||
</div>
|
||||
</template>
|
||||
<script src="gr-settings-menu-item.js"></script>
|
||||
</dom-module>
|
@ -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,
|
||||
},
|
||||
});
|
||||
})();
|
@ -15,12 +15,12 @@ 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-form-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-form-styles.html">
|
||||
<link rel="import" href="../../../styles/shared-styles.html">
|
||||
<link rel="import" href="../../plugins/gr-endpoint-decorator/gr-endpoint-decorator.html">
|
||||
<link rel="import" href="../../settings/gr-change-table-editor/gr-change-table-editor.html">
|
||||
<link rel="import" href="../../shared/gr-button/gr-button.html">
|
||||
<link rel="import" href="../../shared/gr-date-formatter/gr-date-formatter.html">
|
||||
@ -79,6 +79,8 @@ limitations under the License.
|
||||
</li>
|
||||
</template>
|
||||
<li><a href="#MailFilters">Mail Filters</a></li>
|
||||
<gr-endpoint-decorator name="settings-menu-item">
|
||||
</gr-endpoint-decorator>
|
||||
</ul>
|
||||
</gr-page-nav>
|
||||
<main class="gr-form-styles">
|
||||
@ -480,6 +482,8 @@ limitations under the License.
|
||||
</tbody>
|
||||
</table>
|
||||
</fieldset>
|
||||
<gr-endpoint-decorator name="settings-screen">
|
||||
</gr-endpoint-decorator>
|
||||
</main>
|
||||
</div>
|
||||
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
|
||||
|
@ -22,6 +22,7 @@ limitations under the License.
|
||||
<link rel="import" href="../../plugins/gr-event-helper/gr-event-helper.html">
|
||||
<link rel="import" href="../../plugins/gr-popup-interface/gr-popup-interface.html">
|
||||
<link rel="import" href="../../plugins/gr-repo-api/gr-repo-api.html">
|
||||
<link rel="import" href="../../plugins/gr-settings-api/gr-settings-api.html">
|
||||
<link rel="import" href="../../plugins/gr-theme-api/gr-theme-api.html">
|
||||
<link rel="import" href="../gr-rest-api-interface/gr-rest-api-interface.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');
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
@ -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.');
|
||||
|
@ -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',
|
||||
|
Loading…
Reference in New Issue
Block a user