/** * @license * 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'; const STATES = { active: {value: 'ACTIVE', label: 'Active'}, readOnly: {value: 'READ_ONLY', label: 'Read Only'}, hidden: {value: 'HIDDEN', label: 'Hidden'}, }; const SUBMIT_TYPES = { // Exclude INHERIT, which is handled specially. mergeIfNecessary: { value: 'MERGE_IF_NECESSARY', label: 'Merge if necessary', }, fastForwardOnly: { value: 'FAST_FORWARD_ONLY', label: 'Fast forward only', }, rebaseAlways: { value: 'REBASE_ALWAYS', label: 'Rebase Always', }, rebaseIfNecessary: { value: 'REBASE_IF_NECESSARY', label: 'Rebase if necessary', }, mergeAlways: { value: 'MERGE_ALWAYS', label: 'Merge always', }, cherryPick: { value: 'CHERRY_PICK', label: 'Cherry pick', }, }; /** * @appliesMixin Gerrit.FireMixin */ class GrRepo extends Polymer.mixinBehaviors( [ Gerrit.FireBehavior, ], Polymer.GestureEventListeners( Polymer.LegacyElementMixin( Polymer.Element))) { static get is() { return 'gr-repo'; } static get properties() { return { params: Object, repo: String, _configChanged: { type: Boolean, value: false, }, _loading: { type: Boolean, value: true, }, _loggedIn: { type: Boolean, value: false, observer: '_loggedInChanged', }, /** @type {?} */ _repoConfig: Object, /** @type {?} */ _pluginData: { type: Array, computed: '_computePluginData(_repoConfig.plugin_config.*)', }, _readOnly: { type: Boolean, value: true, }, _states: { type: Array, value() { return Object.values(STATES); }, }, _submitTypes: { type: Array, value() { return Object.values(SUBMIT_TYPES); }, }, _schemes: { type: Array, value() { return []; }, computed: '_computeSchemes(_schemesObj)', observer: '_schemesChanged', }, _selectedCommand: { type: String, value: 'Clone', }, _selectedScheme: String, _schemesObj: Object, }; } static get observers() { return [ '_handleConfigChanged(_repoConfig.*)', ]; } attached() { super.attached(); this._loadRepo(); this.fire('title-change', {title: this.repo}); } _computePluginData(configRecord) { if (!configRecord || !configRecord.base) { return []; } const pluginConfig = configRecord.base; return Object.keys(pluginConfig) .map(name => ({name, config: pluginConfig[name]})); } _loadRepo() { if (!this.repo) { return Promise.resolve(); } const promises = []; const errFn = response => { this.fire('page-error', {response}); }; promises.push(this._getLoggedIn().then(loggedIn => { this._loggedIn = loggedIn; if (loggedIn) { this.$.restAPI.getRepoAccess(this.repo).then(access => { if (!access) { return Promise.resolve(); } // If the user is not an owner, is_owner is not a property. this._readOnly = !access[this.repo].is_owner; }); } })); promises.push(this.$.restAPI.getProjectConfig(this.repo, errFn) .then(config => { if (!config) { return Promise.resolve(); } if (config.default_submit_type) { // The gr-select is bound to submit_type, which needs to be the // *configured* submit type. When default_submit_type is // present, the server reports the *effective* submit type in // submit_type, so we need to overwrite it before storing the // config in this. config.submit_type = config.default_submit_type.configured_value; } if (!config.state) { config.state = STATES.active.value; } this._repoConfig = config; this._loading = false; })); promises.push(this.$.restAPI.getConfig().then(config => { if (!config) { return Promise.resolve(); } this._schemesObj = config.download.schemes; })); return Promise.all(promises); } _computeLoadingClass(loading) { return loading ? 'loading' : ''; } _computeHideClass(arr) { return !arr || !arr.length ? 'hide' : ''; } _loggedInChanged(_loggedIn) { if (!_loggedIn) { return; } this.$.restAPI.getPreferences().then(prefs => { if (prefs.download_scheme) { // Note (issue 5180): normalize the download scheme with lower-case. this._selectedScheme = prefs.download_scheme.toLowerCase(); } }); } _formatBooleanSelect(item) { if (!item) { return; } let inheritLabel = 'Inherit'; if (!(item.inherited_value === undefined)) { inheritLabel = `Inherit (${item.inherited_value})`; } return [ { label: inheritLabel, value: 'INHERIT', }, { label: 'True', value: 'TRUE', }, { label: 'False', value: 'FALSE', }, ]; } _formatSubmitTypeSelect(projectConfig) { if (!projectConfig) { return; } const allValues = Object.values(SUBMIT_TYPES); const type = projectConfig.default_submit_type; if (!type) { // Server is too old to report default_submit_type, so assume INHERIT // is not a valid value. return allValues; } let inheritLabel = 'Inherit'; if (type.inherited_value) { let inherited = type.inherited_value; for (const val of allValues) { if (val.value === type.inherited_value) { inherited = val.label; break; } } inheritLabel = `Inherit (${inherited})`; } return [ { label: inheritLabel, value: 'INHERIT', }, ...allValues, ]; } _isLoading() { return this._loading || this._loading === undefined; } _getLoggedIn() { return this.$.restAPI.getLoggedIn(); } _formatRepoConfigForSave(repoConfig) { const configInputObj = {}; for (const key in repoConfig) { if (repoConfig.hasOwnProperty(key)) { if (key === 'default_submit_type') { // default_submit_type is not in the input type, and the // configured value was already copied to submit_type by // _loadProject. Omit this property when saving. continue; } if (key === 'plugin_config') { configInputObj.plugin_config_values = repoConfig[key]; } else if (typeof repoConfig[key] === 'object') { configInputObj[key] = repoConfig[key].configured_value; } else { configInputObj[key] = repoConfig[key]; } } } return configInputObj; } _handleSaveRepoConfig() { return this.$.restAPI.saveRepoConfig(this.repo, this._formatRepoConfigForSave(this._repoConfig)).then(() => { this._configChanged = false; }); } _handleConfigChanged() { if (this._isLoading()) { return; } this._configChanged = true; } _computeButtonDisabled(readOnly, configChanged) { return readOnly || !configChanged; } _computeHeaderClass(configChanged) { return configChanged ? 'edited' : ''; } _computeSchemes(schemesObj) { return Object.keys(schemesObj); } _schemesChanged(schemes) { if (schemes.length === 0) { return; } if (!schemes.includes(this._selectedScheme)) { this._selectedScheme = schemes.sort()[0]; } } _computeCommands(repo, schemesObj, _selectedScheme) { if (!schemesObj || !repo || !_selectedScheme) { return []; } const commands = []; let commandObj; if (schemesObj.hasOwnProperty(_selectedScheme)) { commandObj = schemesObj[_selectedScheme].clone_commands; } for (const title in commandObj) { if (!commandObj.hasOwnProperty(title)) { continue; } commands.push({ title, command: commandObj[title] .replace(/\$\{project\}/gi, encodeURI(repo)) .replace(/\$\{project-base-name\}/gi, encodeURI(repo.substring(repo.lastIndexOf('/') + 1))), }); } return commands; } _computeRepositoriesClass(config) { return config ? 'showConfig': ''; } _computeChangesUrl(name) { return Gerrit.Nav.getUrlForProjectChanges(name); } _handlePluginConfigChanged({detail: {name, config, notifyPath}}) { this._repoConfig.plugin_config[name] = config; this.notifyPath('_repoConfig.plugin_config.' + notifyPath); } } customElements.define(GrRepo.is, GrRepo); })();