blob: a44e258558e3e952c02b76a6008cc6126bdae9c7 [file] [log] [blame]
/**
* @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 {CodeOwnersModelMixin} from './code-owners-model-mixin.js';
import {PluginState} from './code-owners-model.js';
// There are 2 elements in this file:
// CodeOwnersBanner - visual elements. This element is shown at the top
// of the page when pluginStatus are changed to failed.
// The CodeOwnersBanner is added to the 'banner' endpoint. The endpoint
// is placed at the top level of the gerrit and doesn't provide a current
// change, so it is impossible to get the pluginStatus directly in the
// CodeOwnersBanner.
// To solve this problem, this files provides non-visual
// CodeOwnersPluginStatusNotifier element. This element is added to the
// change-view-integration endpoint, so it can track the plugin state.
// When a plugin state is changed, the CodeOwnersPluginStatusNotifier updates
// the pluginStatus property of the banner.
// CodeOwnersBanner and CodeOwnersPluginStatusNotifier can be attached and
// detached in any order. The following piece of code ensures that these
// banner and notifier are always connected correctly. The code assumes,
// that max one banner and one notifier can be connected at any time.
let activeBanner = undefined;
let activeStatusNotifier = undefined;
function setActiveBanner(banner) {
// banner is null when CodeOwnersBanner has been disconnected
activeBanner = banner;
if (activeStatusNotifier) {
activeStatusNotifier.banner = banner;
}
}
function setActiveStatusNotifier(notifier) {
// notifier is null when CodeOwnersBanner has been disconnected
if (activeStatusNotifier) {
if (activeStatusNotifier.banner) {
activeStatusNotifier.banner.pluginStatus = undefined;
}
activeStatusNotifier.banner = undefined;
}
activeStatusNotifier = notifier;
if (activeStatusNotifier) {
activeStatusNotifier.banner = activeBanner;
}
}
export class CodeOwnersBanner extends Polymer.Element {
static get is() { return 'gr-code-owners-banner'; }
static get template() {
return Polymer.html`
<style include="shared-styles">
:host {
display: block;
overflow: hidden;
background: red;
}
.text {
color: white;
font-family: var(--header-font-family);
font-size: var(--font-size-h3);
font-weight: var(--font-weight-h3);
line-height: var(--line-height-h3);
margin-left: var(--spacing-l);
}
</style>
<span class="text">Error: Code-owners plugin has failed</span>
<gr-button link on-click="_showFailDetails">
Details
</gr-button>
`;
}
static get properties() {
return {
// @internal attributes
hidden: {
type: Boolean,
value: true,
reflectToAttribute: true,
computed: '_computeHidden(pluginStatus)',
},
pluginStatus: {
type: Object,
},
};
}
connectedCallback() {
super.connectedCallback();
setActiveBanner(this);
}
disconnectedCallback() {
super.disconnectedCallback();
setActiveBanner(undefined);
}
_computeHidden(pluginStatus) {
return !pluginStatus || pluginStatus.state !== PluginState.Failed;
}
_showFailDetails() {
showPluginFailedMessage(this, this.pluginStatus);
}
}
customElements.define(CodeOwnersBanner.is, CodeOwnersBanner);
export class CodeOwnersPluginStatusNotifier extends
CodeOwnersModelMixin(Polymer.Element) {
static get is() {
return 'owners-plugin-status-notifier';
}
static get properties() {
return {
banner: {
type: Object,
},
};
}
static get observers() {
return [
'_pluginStatusOrBannerChanged(model.pluginStatus, banner)',
];
}
connectedCallback() {
super.connectedCallback();
setActiveStatusNotifier(this);
}
disconnectedCallback() {
super.disconnectedCallback();
setActiveStatusNotifier(undefined);
}
_pluginStatusOrBannerChanged(status, banner) {
if (!banner) return;
banner.pluginStatus = status;
}
_loadDataAfterStateChanged() {
this.modelLoader.loadPluginStatus();
}
}
customElements.define(CodeOwnersPluginStatusNotifier.is,
CodeOwnersPluginStatusNotifier);
export function showPluginFailedMessage(sourceEl, pluginStatus) {
sourceEl.dispatchEvent(
new CustomEvent('show-error', {
detail: {message: pluginStatus.failedMessage},
composed: true,
bubbles: true,
})
);
}