commit 32b0aa748b3b5980c72bab2712c62ed35da5395d Author: Dmitrii Filippov Date: Wed Oct 14 10:37:58 2020 +0200 Rename files to preserve history Test\Eslint fail - this is expected. Change-Id: I3a947f259f6316582735d6489aaf3471c4fe21a6 diff --git a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js deleted file mode 100644 index 88c4cef..0000000 --- a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js +++ /dev/null @@ -1,363 +0,0 @@ -/** - * @license - * Copyright (C) 2016 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 '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator.js'; -import '../../shared/gr-dropdown/gr-dropdown.js'; -import '../../shared/gr-icons/gr-icons.js'; -import '../../shared/gr-js-api-interface/gr-js-api-interface.js'; -import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js'; -import '../gr-account-dropdown/gr-account-dropdown.js'; -import '../gr-smart-search/gr-smart-search.js'; -import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js'; -import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js'; -import {PolymerElement} from '@polymer/polymer/polymer-element.js'; -import {htmlTemplate} from './gr-main-header_html.js'; -import {getBaseUrl, getDocsBaseUrl} from '../../../utils/url-util.js'; -import {getPluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.js'; -import {getAdminLinks} from '../../../utils/admin-nav-util.js'; - -const DEFAULT_LINKS = [{ - title: 'Changes', - links: [ - { - url: '/q/status:open+-is:wip', - name: 'Open', - }, - { - url: '/q/status:merged', - name: 'Merged', - }, - { - url: '/q/status:abandoned', - name: 'Abandoned', - }, - ], -}]; - -const DOCUMENTATION_LINKS = [ - { - url: '/index.html', - name: 'Table of Contents', - }, - { - url: '/user-search.html', - name: 'Searching', - }, - { - url: '/user-upload.html', - name: 'Uploading', - }, - { - url: '/access-control.html', - name: 'Access Control', - }, - { - url: '/rest-api.html', - name: 'REST API', - }, - { - url: '/intro-project-owner.html', - name: 'Project Owner Guide', - }, -]; - -// Set of authentication methods that can provide custom registration page. -const AUTH_TYPES_WITH_REGISTER_URL = new Set([ - 'LDAP', - 'LDAP_BIND', - 'CUSTOM_EXTENSION', -]); - -/** - * @extends PolymerElement - */ -class GrMainHeader extends GestureEventListeners( - LegacyElementMixin( - PolymerElement)) { - static get template() { return htmlTemplate; } - - static get is() { return 'gr-main-header'; } - - static get properties() { - return { - searchQuery: { - type: String, - notify: true, - }, - loggedIn: { - type: Boolean, - reflectToAttribute: true, - }, - loading: { - type: Boolean, - reflectToAttribute: true, - }, - - /** @type {?Object} */ - _account: Object, - _adminLinks: { - type: Array, - value() { return []; }, - }, - _defaultLinks: { - type: Array, - value() { - return DEFAULT_LINKS; - }, - }, - _docBaseUrl: { - type: String, - value: null, - }, - _links: { - type: Array, - computed: '_computeLinks(_defaultLinks, _userLinks, _adminLinks, ' + - '_topMenus, _docBaseUrl)', - }, - loginUrl: { - type: String, - value: '/login', - }, - _userLinks: { - type: Array, - value() { return []; }, - }, - _topMenus: { - type: Array, - value() { return []; }, - }, - _registerText: { - type: String, - value: 'Sign up', - }, - _registerURL: { - type: String, - value: null, - }, - mobileSearchHidden: { - type: Boolean, - value: false, - }, - }; - } - - static get observers() { - return [ - '_accountLoaded(_account)', - ]; - } - - /** @override */ - ready() { - super.ready(); - this._ensureAttribute('role', 'banner'); - } - - /** @override */ - attached() { - super.attached(); - this._loadAccount(); - this._loadConfig(); - } - - /** @override */ - detached() { - super.detached(); - } - - reload() { - this._loadAccount(); - } - - _computeRelativeURL(path) { - return '//' + window.location.host + getBaseUrl() + path; - } - - _computeLinks(defaultLinks, userLinks, adminLinks, topMenus, docBaseUrl) { - // Polymer 2: check for undefined - if ([ - defaultLinks, - userLinks, - adminLinks, - topMenus, - docBaseUrl, - ].includes(undefined)) { - return undefined; - } - - const links = defaultLinks.map(menu => { - return { - title: menu.title, - links: menu.links.slice(), - }; - }); - if (userLinks && userLinks.length > 0) { - links.push({ - title: 'Your', - links: userLinks.slice(), - }); - } - const docLinks = this._getDocLinks(docBaseUrl, DOCUMENTATION_LINKS); - if (docLinks.length) { - links.push({ - title: 'Documentation', - links: docLinks, - class: 'hideOnMobile', - }); - } - links.push({ - title: 'Browse', - links: adminLinks.slice(), - }); - const topMenuLinks = []; - links.forEach(link => { topMenuLinks[link.title] = link.links; }); - for (const m of topMenus) { - const items = m.items.map(this._fixCustomMenuItem).filter(link => - // Ignore GWT project links - !link.url.includes('${projectName}') - ); - if (m.name in topMenuLinks) { - items.forEach(link => { topMenuLinks[m.name].push(link); }); - } else { - links.push({ - title: m.name, - links: topMenuLinks[m.name] = items, - }); - } - } - return links; - } - - _getDocLinks(docBaseUrl, docLinks) { - if (!docBaseUrl || !docLinks) { - return []; - } - return docLinks.map(link => { - let url = docBaseUrl; - if (url && url[url.length - 1] === '/') { - url = url.substring(0, url.length - 1); - } - return { - url: url + link.url, - name: link.name, - target: '_blank', - }; - }); - } - - _loadAccount() { - this.loading = true; - const promises = [ - this.$.restAPI.getAccount(), - this.$.restAPI.getTopMenus(), - getPluginLoader().awaitPluginsLoaded(), - ]; - - return Promise.all(promises).then(result => { - const account = result[0]; - this._account = account; - this.loggedIn = !!account; - this.loading = false; - this._topMenus = result[1]; - - return getAdminLinks(account, - params => this.$.restAPI.getAccountCapabilities(params), - () => this.$.jsAPI.getAdminMenuLinks()) - .then(res => { - this._adminLinks = res.links; - }); - }); - } - - _loadConfig() { - this.$.restAPI.getConfig() - .then(config => { - this._retrieveRegisterURL(config); - return getDocsBaseUrl(config, this.$.restAPI); - }) - .then(docBaseUrl => { this._docBaseUrl = docBaseUrl; }); - } - - _accountLoaded(account) { - if (!account) { return; } - - this.$.restAPI.getPreferences().then(prefs => { - this._userLinks = prefs && prefs.my ? - prefs.my.map(this._fixCustomMenuItem) : []; - }); - } - - _retrieveRegisterURL(config) { - if (AUTH_TYPES_WITH_REGISTER_URL.has(config.auth.auth_type)) { - this._registerURL = config.auth.register_url; - if (config.auth.register_text) { - this._registerText = config.auth.register_text; - } - } - } - - _computeIsInvisible(registerURL) { - return registerURL ? '' : 'invisible'; - } - - _fixCustomMenuItem(linkObj) { - // Normalize all urls to PolyGerrit style. - if (linkObj.url.startsWith('#')) { - linkObj.url = linkObj.url.slice(1); - } - - // Delete target property due to complications of - // https://bugs.chromium.org/p/gerrit/issues/detail?id=5888 - // - // The server tries to guess whether URL is a view within the UI. - // If not, it sets target='_blank' on the menu item. The server - // makes assumptions that work for the GWT UI, but not PolyGerrit, - // so we'll just disable it altogether for now. - delete linkObj.target; - - return linkObj; - } - - _generateSettingsLink() { - return getBaseUrl() + '/settings/'; - } - - _onMobileSearchTap(e) { - e.preventDefault(); - e.stopPropagation(); - this.dispatchEvent(new CustomEvent('mobile-search', { - composed: true, bubbles: false, - })); - } - - _computeLinkGroupClass(linkGroup) { - if (linkGroup && linkGroup.class) { - return linkGroup.class; - } - - return ''; - } - - _computeShowHideAriaLabel(mobileSearchHidden) { - if (mobileSearchHidden) { - return 'Show Searchbar'; - } else { - return 'Hide Searchbar'; - } - } -} - -customElements.define(GrMainHeader.is, GrMainHeader); diff --git a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.ts b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.ts new file mode 100644 index 0000000..88c4cef --- /dev/null +++ b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.ts @@ -0,0 +1,363 @@ +/** + * @license + * Copyright (C) 2016 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 '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator.js'; +import '../../shared/gr-dropdown/gr-dropdown.js'; +import '../../shared/gr-icons/gr-icons.js'; +import '../../shared/gr-js-api-interface/gr-js-api-interface.js'; +import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js'; +import '../gr-account-dropdown/gr-account-dropdown.js'; +import '../gr-smart-search/gr-smart-search.js'; +import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js'; +import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js'; +import {PolymerElement} from '@polymer/polymer/polymer-element.js'; +import {htmlTemplate} from './gr-main-header_html.js'; +import {getBaseUrl, getDocsBaseUrl} from '../../../utils/url-util.js'; +import {getPluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.js'; +import {getAdminLinks} from '../../../utils/admin-nav-util.js'; + +const DEFAULT_LINKS = [{ + title: 'Changes', + links: [ + { + url: '/q/status:open+-is:wip', + name: 'Open', + }, + { + url: '/q/status:merged', + name: 'Merged', + }, + { + url: '/q/status:abandoned', + name: 'Abandoned', + }, + ], +}]; + +const DOCUMENTATION_LINKS = [ + { + url: '/index.html', + name: 'Table of Contents', + }, + { + url: '/user-search.html', + name: 'Searching', + }, + { + url: '/user-upload.html', + name: 'Uploading', + }, + { + url: '/access-control.html', + name: 'Access Control', + }, + { + url: '/rest-api.html', + name: 'REST API', + }, + { + url: '/intro-project-owner.html', + name: 'Project Owner Guide', + }, +]; + +// Set of authentication methods that can provide custom registration page. +const AUTH_TYPES_WITH_REGISTER_URL = new Set([ + 'LDAP', + 'LDAP_BIND', + 'CUSTOM_EXTENSION', +]); + +/** + * @extends PolymerElement + */ +class GrMainHeader extends GestureEventListeners( + LegacyElementMixin( + PolymerElement)) { + static get template() { return htmlTemplate; } + + static get is() { return 'gr-main-header'; } + + static get properties() { + return { + searchQuery: { + type: String, + notify: true, + }, + loggedIn: { + type: Boolean, + reflectToAttribute: true, + }, + loading: { + type: Boolean, + reflectToAttribute: true, + }, + + /** @type {?Object} */ + _account: Object, + _adminLinks: { + type: Array, + value() { return []; }, + }, + _defaultLinks: { + type: Array, + value() { + return DEFAULT_LINKS; + }, + }, + _docBaseUrl: { + type: String, + value: null, + }, + _links: { + type: Array, + computed: '_computeLinks(_defaultLinks, _userLinks, _adminLinks, ' + + '_topMenus, _docBaseUrl)', + }, + loginUrl: { + type: String, + value: '/login', + }, + _userLinks: { + type: Array, + value() { return []; }, + }, + _topMenus: { + type: Array, + value() { return []; }, + }, + _registerText: { + type: String, + value: 'Sign up', + }, + _registerURL: { + type: String, + value: null, + }, + mobileSearchHidden: { + type: Boolean, + value: false, + }, + }; + } + + static get observers() { + return [ + '_accountLoaded(_account)', + ]; + } + + /** @override */ + ready() { + super.ready(); + this._ensureAttribute('role', 'banner'); + } + + /** @override */ + attached() { + super.attached(); + this._loadAccount(); + this._loadConfig(); + } + + /** @override */ + detached() { + super.detached(); + } + + reload() { + this._loadAccount(); + } + + _computeRelativeURL(path) { + return '//' + window.location.host + getBaseUrl() + path; + } + + _computeLinks(defaultLinks, userLinks, adminLinks, topMenus, docBaseUrl) { + // Polymer 2: check for undefined + if ([ + defaultLinks, + userLinks, + adminLinks, + topMenus, + docBaseUrl, + ].includes(undefined)) { + return undefined; + } + + const links = defaultLinks.map(menu => { + return { + title: menu.title, + links: menu.links.slice(), + }; + }); + if (userLinks && userLinks.length > 0) { + links.push({ + title: 'Your', + links: userLinks.slice(), + }); + } + const docLinks = this._getDocLinks(docBaseUrl, DOCUMENTATION_LINKS); + if (docLinks.length) { + links.push({ + title: 'Documentation', + links: docLinks, + class: 'hideOnMobile', + }); + } + links.push({ + title: 'Browse', + links: adminLinks.slice(), + }); + const topMenuLinks = []; + links.forEach(link => { topMenuLinks[link.title] = link.links; }); + for (const m of topMenus) { + const items = m.items.map(this._fixCustomMenuItem).filter(link => + // Ignore GWT project links + !link.url.includes('${projectName}') + ); + if (m.name in topMenuLinks) { + items.forEach(link => { topMenuLinks[m.name].push(link); }); + } else { + links.push({ + title: m.name, + links: topMenuLinks[m.name] = items, + }); + } + } + return links; + } + + _getDocLinks(docBaseUrl, docLinks) { + if (!docBaseUrl || !docLinks) { + return []; + } + return docLinks.map(link => { + let url = docBaseUrl; + if (url && url[url.length - 1] === '/') { + url = url.substring(0, url.length - 1); + } + return { + url: url + link.url, + name: link.name, + target: '_blank', + }; + }); + } + + _loadAccount() { + this.loading = true; + const promises = [ + this.$.restAPI.getAccount(), + this.$.restAPI.getTopMenus(), + getPluginLoader().awaitPluginsLoaded(), + ]; + + return Promise.all(promises).then(result => { + const account = result[0]; + this._account = account; + this.loggedIn = !!account; + this.loading = false; + this._topMenus = result[1]; + + return getAdminLinks(account, + params => this.$.restAPI.getAccountCapabilities(params), + () => this.$.jsAPI.getAdminMenuLinks()) + .then(res => { + this._adminLinks = res.links; + }); + }); + } + + _loadConfig() { + this.$.restAPI.getConfig() + .then(config => { + this._retrieveRegisterURL(config); + return getDocsBaseUrl(config, this.$.restAPI); + }) + .then(docBaseUrl => { this._docBaseUrl = docBaseUrl; }); + } + + _accountLoaded(account) { + if (!account) { return; } + + this.$.restAPI.getPreferences().then(prefs => { + this._userLinks = prefs && prefs.my ? + prefs.my.map(this._fixCustomMenuItem) : []; + }); + } + + _retrieveRegisterURL(config) { + if (AUTH_TYPES_WITH_REGISTER_URL.has(config.auth.auth_type)) { + this._registerURL = config.auth.register_url; + if (config.auth.register_text) { + this._registerText = config.auth.register_text; + } + } + } + + _computeIsInvisible(registerURL) { + return registerURL ? '' : 'invisible'; + } + + _fixCustomMenuItem(linkObj) { + // Normalize all urls to PolyGerrit style. + if (linkObj.url.startsWith('#')) { + linkObj.url = linkObj.url.slice(1); + } + + // Delete target property due to complications of + // https://bugs.chromium.org/p/gerrit/issues/detail?id=5888 + // + // The server tries to guess whether URL is a view within the UI. + // If not, it sets target='_blank' on the menu item. The server + // makes assumptions that work for the GWT UI, but not PolyGerrit, + // so we'll just disable it altogether for now. + delete linkObj.target; + + return linkObj; + } + + _generateSettingsLink() { + return getBaseUrl() + '/settings/'; + } + + _onMobileSearchTap(e) { + e.preventDefault(); + e.stopPropagation(); + this.dispatchEvent(new CustomEvent('mobile-search', { + composed: true, bubbles: false, + })); + } + + _computeLinkGroupClass(linkGroup) { + if (linkGroup && linkGroup.class) { + return linkGroup.class; + } + + return ''; + } + + _computeShowHideAriaLabel(mobileSearchHidden) { + if (mobileSearchHidden) { + return 'Show Searchbar'; + } else { + return 'Hide Searchbar'; + } + } +} + +customElements.define(GrMainHeader.is, GrMainHeader);