More metadata editor, tab/untab with selection

This commit is contained in:
Vincent Fiduccia 2017-10-02 18:25:04 -07:00
parent 46dd00a382
commit a535c3ba3d
No known key found for this signature in database
GPG Key ID: 2B29AD6BB2BB2582
5 changed files with 114 additions and 55 deletions

View File

@ -96,18 +96,20 @@ export default Ember.Component.extend(NewOrEdit, {
this.set('launchConfig.secrets', []);
}
if ( !this.get('launchConfig.metadata') ) {
this.set('launchConfig.metadata', {});
};
if ( this.get('isService') && !this.get('isSidekick') ) {
this.setProperties({
name: this.get('service.name'),
description: this.get('service.description'),
scale: this.get('service.scale'),
metadata: this.get('service.metadata') || {},
});
} else {
this.setProperties({
name: this.get('launchConfig.name'),
description: this.get('launchConfig.description'),
metadata: {},
});
}
@ -264,7 +266,6 @@ export default Ember.Component.extend(NewOrEdit, {
pr = this.get('service').clone();
nameResource = pr;
pr.set('launchConfig', lc);
pr.set('metadata', this.get('metadata'))
pr.set('scale', this.get('scale'));
} else {
// Convert the launch config to a container

View File

@ -152,16 +152,16 @@
expandFn=expandFn
}}
{{form-metadata
classNames="accordion-wrapper"
instance=launchConfig
errors=metadataErrors
expandAll=al.expandAll
expandFn=expandFn
}}
{{#if isService}}
{{#unless isSidekick}}
{{form-metadata
classNames="accordion-wrapper"
instance=metadata
errors=metadataErrors
expandAll=al.expandAll
expandFn=expandFn
}}
{{container/form-service-links
service=service
expandAll=al.expandAll

View File

@ -4,13 +4,12 @@ import { STATUS, STATUS_INTL_KEY, classForStatus } from 'ui/components/accordion
export default Ember.Component.extend({
intl: Ember.inject.service(),
classNames: ['accordion-wrapper'],
detailKey: 'formMetadata.detail',
instance: null,
detailKey: 'formMetadata.detail',
errors: null,
invalid: false,
valid: true,
classNames: ['accordion-wrapper'],
didReceiveAttrs() {
if (!this.get('expandFn')) {
@ -22,26 +21,28 @@ export default Ember.Component.extend({
validate: function () {
let intl = this.get('intl');
if (this.get('invalid')) {
this.set('errors', [intl.t('formMetadata.errors.invalidJSON')])
} else if (['object', 'null'].indexOf(Ember.typeOf(this.get('instance'))) === -1) {
this.set('errors', [intl.t('formMetadata.errors.topLevelValueInvalid')]);
if ( this.get('valid') ) {
if ( ['object', 'null'].indexOf(Ember.typeOf(this.get('instance.metadata'))) === -1 ) {
this.set('errors', [intl.t('formMetadata.errors.topLevelValueInvalid')]);
} else {
this.set('errors', []);
}
} else {
this.set('errors', []);
this.set('errors', [intl.t('formMetadata.errors.invalidJSON')]);
}
}.observes('invalid', 'instance'),
}.observes('valid', 'instance.metadata'),
statusClass: null,
status: function () {
let k;
if (this.get('invalid') || ['object', 'null'].indexOf(Ember.typeOf(this.get('instance'))) === -1) {
if (this.get('errors.length') ) {
k = STATUS.ERROR;
} else if (!Ember.isNone(this.get('instance')) && Object.keys(this.get('instance')).length > 0) {
} else if (!Ember.isNone(this.get('instance.metadata')) && Object.keys(this.get('instance.metadata')).length > 0) {
k = STATUS.CONFIGURED;
} else {
k = STATUS.NOTCONFIGURED;
}
this.set('statusClass', classForStatus(k));
return this.get('intl').t(`${STATUS_INTL_KEY}.${k}`);
}.property('invalid'),
}.property('errors.length'),
});

View File

@ -6,5 +6,5 @@
expandAll=expandAll
expand=(action expandFn)
}}
{{json-editor json=instance isInvalid=invalid}}
{{json-editor json=instance.metadata isValid=valid}}
{{/accordion-list-item}}

View File

@ -2,51 +2,108 @@ import Ember from 'ember';
import sanitize from 'json-sanitizer';
import C from 'ui/utils/constants';
const TAB_SIZE = 2;
const TAB_STR = (new Array(TAB_SIZE+1)).join(' ');
export default Ember.Component.extend({
json: {},
isInvalid: false,
jsonString: null,
tagName: 'div',
classNames: ['jsoneditor-component'],
jsonString: function () {
return JSON.stringify(this.get('json'), undefined, 4);
}.property('json'),
json: {},
isValid: true,
onChange: function () {
try {
const json = this.parseJSON(this.jsonString)
this.set('json', json);
this.set('isInvalid', false)
} catch (err) {
this.set('isInvalid', true)
}
}.observes('jsonString'),
parseJSON: function (jsonString) {
try {
return JSON.parse(jsonString);
} catch (err) {
return JSON.parse(sanitize(jsonString));
}
init() {
this._super();
this.focusOut();
},
focusOut() {
if (!this.get('isInvalid')) {
this.set('jsonString', JSON.stringify(this.get('json'), undefined, 4));
if ( this.get('isValid') ) {
this.set('jsonString', JSON.stringify(this.get('json'), undefined, TAB_SIZE));
}
},
keyDown: function (event) {
keyDown(event) {
const keyCode = event.which;
if (keyCode === C.KEY.TAB) {
event.preventDefault();
const el = $(this).get(0).childViews.get(0).element;
const start = el.selectionStart;
const end = el.selectionEnd;
$(el).val($(el).val().substring(0, start) + " " + $(el).val().substring(end));
el.selectionStart = start + 4;
el.selectionEnd = start + 4;
const val = $(el).val();
let start = el.selectionStart;
let end = el.selectionEnd;
const origStart = start;
const origEnd = end;
// Move start to the beginning of the line
while ( start > 0 && val.charAt(start-1) !== '\n' ) {
start--;
}
// And end to the end of the line
while ( end < val.length && val.charAt(end) !== '\n') {
end++;
}
let lines = val.substring(start,end).split(/\n/);
let sub;
let direction;
if ( event.shiftKey ) {
const re = new RegExp("^(\\s{"+ TAB_SIZE + "}|\\t)");
let found = false;
sub = lines.map((x) => {
let out = x.replace(re,'');
if ( out !== x ) {
found = true;
}
return out;
});
if ( found ) {
direction = -1;
} else {
// If no lines moved, this will prevent the cursor from moving back
direction = 0;
}
} else {
sub = lines.map(x => TAB_STR+x);
direction = 1;
}
let replaceStr = sub.join("\n");
$(el).val(val.substring(0, start) + replaceStr + val.substring(end));
if ( origStart === origEnd ) {
el.selectionStart = el.selectionEnd = origStart + direction*TAB_SIZE*sub.length;
} else {
el.selectionStart = start;
el.selectionEnd = start + replaceStr.length;
}
}
},
onChange: function() {
const [json, isValid] = this.parse(this.get('jsonString'));
this.setProperties({
json,
isValid,
});
}.observes('jsonString'),
parse(jsonString) {
try {
const json = JSON.parse(jsonString);
return [json,true];
} catch (err) {
try {
const json = JSON.parse(sanitize(jsonString));
return [json,true];
} catch (err) {
return [null,false];
}
}
},
});