mirror of https://github.com/rancher/ui.git
284 lines
8.5 KiB
JavaScript
284 lines
8.5 KiB
JavaScript
import { computed } from '@ember/object';
|
|
import { scheduleOnce } from '@ember/runloop';
|
|
import { alias, notEmpty } from '@ember/object/computed';
|
|
import { inject as service } from '@ember/service';
|
|
import Component from '@ember/component';
|
|
import NewOrEdit from 'shared/mixins/new-or-edit';
|
|
import C from 'ui/utils/constants';
|
|
import Util from 'ui/utils/util';
|
|
import { compare as compareVersion } from 'ui/utils/parse-version';
|
|
import { task } from 'ember-concurrency';
|
|
import YAML from 'npm:yamljs';
|
|
import layout from './template';
|
|
|
|
|
|
export default Component.extend(NewOrEdit, {
|
|
layout,
|
|
catalog: service(),
|
|
intl: service(),
|
|
scope: service(),
|
|
router: service(),
|
|
settings: service(),
|
|
|
|
allTemplates: null,
|
|
templateResource: null,
|
|
stackResource: null,
|
|
versionsArray: null,
|
|
versionsLinks: null,
|
|
actuallySave: true,
|
|
showHeader: true,
|
|
showPreview: true,
|
|
showName: true,
|
|
titleAdd: 'newCatalog.titleAdd',
|
|
titleUpgrade: 'newCatalog.titleUpgrade',
|
|
selectVersionAdd: 'newCatalog.selectVersionAdd',
|
|
selectVersionUpgrade: 'newCatalog.selectVersionUpgrade',
|
|
saveUpgrade: 'newCatalog.saveUpgrade',
|
|
saveNew: 'newCatalog.saveNew',
|
|
sectionClass: 'box mb-20',
|
|
showDefaultVersionOption: false,
|
|
|
|
classNames: ['launch-catalog'],
|
|
|
|
primaryResource: alias('stackResource'),
|
|
templateBase: alias('templateResource.templateBase'),
|
|
editing: notEmpty('stackResource.id'),
|
|
|
|
previewOpen: false,
|
|
previewTab: null,
|
|
questionsArray: null,
|
|
selectedTemplateUrl: null,
|
|
selectedTemplateModel: null,
|
|
readmeContent: null,
|
|
pastedAnswers: null,
|
|
|
|
actions: {
|
|
cancel: function() {
|
|
this.sendAction('cancel');
|
|
},
|
|
|
|
togglePreview: function() {
|
|
this.toggleProperty('previewOpen');
|
|
},
|
|
|
|
selectPreviewTab: function(tab) {
|
|
this.set('previewTab', tab);
|
|
},
|
|
|
|
changeTemplate: function(tpl) {
|
|
this.get('router').transitionTo('catalog-tab.launch', tpl.id);
|
|
},
|
|
|
|
saveTemplate() {
|
|
this.sendAction('templateEdited', this.get('stackResource'));
|
|
}
|
|
},
|
|
|
|
didReceiveAttrs: function() {
|
|
this._super(...arguments);
|
|
this.set('selectedTemplateModel', null);
|
|
|
|
scheduleOnce('afterRender', () => {
|
|
if ( this.get('selectedTemplateUrl') ) {
|
|
this.templateChanged();
|
|
} else {
|
|
var def = this.get('templateResource.defaultVersion');
|
|
var links = this.get('versionLinks');
|
|
if (links[def]) {
|
|
this.set('selectedTemplateUrl', links[def]);
|
|
} else {
|
|
this.set('selectedTemplateUrl', null);
|
|
}
|
|
}
|
|
});
|
|
},
|
|
|
|
updateReadme: function() {
|
|
let model = this.get('selectedTemplateModel');
|
|
this.set('readmeContent', null);
|
|
if ( model && model.hasLink('readme') ) {
|
|
model.followLink('readme').then((response) => {
|
|
this.set('readmeContent', response);
|
|
});
|
|
}
|
|
},
|
|
|
|
sortedVersions: function() {
|
|
let out = this.get('versionsArray').sort((a,b) => {
|
|
if ( a.sortVersion && b.sortVersion ) {
|
|
return compareVersion(a.sortVersion, b.sortVersion);
|
|
} else {
|
|
return compareVersion(a.version, b.version);
|
|
}
|
|
});
|
|
|
|
let def = this.get('templateResource.defaultVersion');
|
|
if ( this.get('showDefaultVersionOption') && this.get('defaultUrl') ) {
|
|
out.unshift({version: this.get('intl').t('newCatalog.version.default', {version: def}), link: 'default'});
|
|
}
|
|
|
|
return out;
|
|
}.property('versionsArray','templateResource.defaultVersion'),
|
|
|
|
defaultUrl: function() {
|
|
var defaultVersion = this.get('templateResource.defaultVersion');
|
|
var versionLinks = this.get('versionLinks');
|
|
|
|
if ( defaultVersion && versionLinks && versionLinks[defaultVersion] ) {
|
|
return versionLinks[defaultVersion];
|
|
}
|
|
|
|
return null;
|
|
}.property('templateResource.defaultVersion','versionLinks'),
|
|
|
|
getTemplate: task(function * () {
|
|
var url = this.get('selectedTemplateUrl');
|
|
|
|
if ( url === 'default' ) {
|
|
let defaultUrl = this.get('defaultUrl');
|
|
if ( defaultUrl ) {
|
|
url = defaultUrl;
|
|
} else {
|
|
url = null;
|
|
}
|
|
}
|
|
|
|
if (url) {
|
|
var version = this.get('settings.rancherVersion');
|
|
|
|
if ( version ) {
|
|
url = Util.addQueryParam(url, 'rancherVersion', version);
|
|
}
|
|
|
|
var current = this.get('stackResource.answers');
|
|
|
|
if ( !current ) {
|
|
current = {};
|
|
this.set('stackResource.answers', current);
|
|
}
|
|
|
|
var selectedTemplateModel = yield this.get('catalog').fetchByUrl(url).then((response) => {
|
|
if (response.questions) {
|
|
response.questions.forEach((item) => {
|
|
// This will be the component that is rendered to edit this answer
|
|
item.inputComponent = 'schema/input-'+item.type;
|
|
|
|
// Only types marked supported will show the component, Ember will explode if the component doesn't exist
|
|
item.supported = C.SUPPORTED_SCHEMA_INPUTS.indexOf(item.type) >= 0;
|
|
|
|
if (typeof current[item.variable] !== 'undefined') {
|
|
// If there's an existing value, use it (for upgrade)
|
|
item.answer = current[item.variable];
|
|
} else if (item.type === 'service' || item.type === 'certificate') {
|
|
// Loaded async and then the component picks the default
|
|
} else if ( item.type === 'boolean' ) {
|
|
// Coerce booleans
|
|
item.answer = (item.default === 'true' || item.default === true);
|
|
} else {
|
|
// Everything else
|
|
item.answer = item.default;
|
|
}
|
|
});
|
|
}
|
|
return response;
|
|
});
|
|
|
|
this.set('selectedTemplateModel', selectedTemplateModel);
|
|
this.set('previewTab', Object.keys(selectedTemplateModel.get('files')||[])[0]);
|
|
} else {
|
|
this.set('selectedTemplateModel', null);
|
|
this.set('readmeContent', null);
|
|
}
|
|
|
|
this.updateReadme();
|
|
}),
|
|
|
|
templateChanged: function() {
|
|
this.get('getTemplate').perform();
|
|
}.observes('selectedTemplateUrl','templateResource.defaultVersion'),
|
|
|
|
answers: function() {
|
|
var out = {};
|
|
(this.get('selectedTemplateModel.questions') || []).forEach((item) => {
|
|
out[item.variable] = item.answer;
|
|
});
|
|
|
|
return out;
|
|
}.property('selectedTemplateModel.questions.@each.{variable,answer}'),
|
|
|
|
answersArray: alias('selectedTemplateModel.questions'),
|
|
|
|
answersString: computed('answersArray.@each.{variable,answer}', function() {
|
|
let neu = {};
|
|
this.get('answersArray').forEach((a) => {
|
|
neu[a.variable] = a.answer || a.default;
|
|
});
|
|
return YAML.stringify(neu);
|
|
}),
|
|
|
|
validate() {
|
|
var errors = [];
|
|
|
|
if (!this.get('editing') && !this.get('stackResource.name')) {
|
|
errors.push('Name is required');
|
|
}
|
|
|
|
if (this.get('selectedTemplateModel.questions')) {
|
|
this.get('selectedTemplateModel.questions').forEach((item) => {
|
|
if (item.required && item.type !== 'boolean' && !item.answer) {
|
|
errors.push(`${item.label} is required`);
|
|
}
|
|
});
|
|
}
|
|
|
|
if (errors.length) {
|
|
this.set('errors', errors.uniq());
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
},
|
|
|
|
newExternalId: function() {
|
|
return C.EXTERNAL_ID.KIND_CATALOG + C.EXTERNAL_ID.KIND_SEPARATOR + this.get('selectedTemplateModel.id');
|
|
}.property('selectedTemplateModel.id'),
|
|
|
|
willSave() {
|
|
this.set('errors', null);
|
|
var ok = this.validate();
|
|
if (!ok) {
|
|
// Validation failed
|
|
return false;
|
|
}
|
|
|
|
let stack = this.get('stackResource');
|
|
|
|
if ( this.get('actuallySave') ) {
|
|
stack.setProperties({
|
|
answers: this.get('answers'),
|
|
externalId: this.get('newExternalId'),
|
|
});
|
|
|
|
return true;
|
|
} else {
|
|
let versionId = null;
|
|
if ( this.get('selectedTemplateUrl') !== 'default' && this.get('selectedTemplateModel') ) {
|
|
versionId = this.get('selectedTemplateModel.id');
|
|
}
|
|
|
|
this.sendAction('doSave', {
|
|
answers: this.get('answers'),
|
|
externalId: this.get('newExternalId'),
|
|
templateId: this.get('templateResource.id'),
|
|
templateVersionId: versionId,
|
|
});
|
|
return false;
|
|
}
|
|
},
|
|
|
|
doneSaving() {
|
|
var projectId = this.get('scope.current.id');
|
|
return this.get('router').transitionTo('apps-tab.index', projectId);
|
|
}
|
|
});
|