Updated code mirror component for consistency (#11500)
* Updated code mirror component for consistency - Hide gutters, line number and selection while read only - Show toolbar with copy functionality for all instances * Moved toolbar and actions to json editor component * Updated form-field-from-model template * Added test for toolbar
This commit is contained in:
parent
0926e302c5
commit
1d26f056bc
|
@ -0,0 +1,3 @@
|
|||
```release-note:improvement
|
||||
ui: Updated ivy code mirror component for consistency
|
||||
```
|
|
@ -1,5 +1,5 @@
|
|||
import { assign } from '@ember/polyfills';
|
||||
import IvyCodemirrorComponent from './ivy-codemirror';
|
||||
import Component from '@ember/component';
|
||||
|
||||
const JSON_EDITOR_DEFAULTS = {
|
||||
// IMPORTANT: `gutters` must come before `lint` since the presence of
|
||||
// `gutters` is cached internally when `lint` is toggled
|
||||
|
@ -13,19 +13,41 @@ const JSON_EDITOR_DEFAULTS = {
|
|||
showCursorWhenSelecting: true,
|
||||
};
|
||||
|
||||
export default IvyCodemirrorComponent.extend({
|
||||
'data-test-component': 'json-editor',
|
||||
updateCodeMirrorOptions() {
|
||||
const options = assign({}, JSON_EDITOR_DEFAULTS, this.options);
|
||||
if (options.autoHeight) {
|
||||
options.viewportMargin = Infinity;
|
||||
delete options.autoHeight;
|
||||
}
|
||||
export default Component.extend({
|
||||
showToolbar: true,
|
||||
title: null,
|
||||
subTitle: null,
|
||||
helpText: null,
|
||||
value: null,
|
||||
options: null,
|
||||
valueUpdated: null,
|
||||
onFocusOut: null,
|
||||
readOnly: false,
|
||||
|
||||
if (options) {
|
||||
Object.keys(options).forEach(function(option) {
|
||||
this.updateCodeMirrorOption(option, options[option]);
|
||||
}, this);
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.options = { ...JSON_EDITOR_DEFAULTS, ...this.options };
|
||||
if (this.options.autoHeight) {
|
||||
this.options.viewportMargin = Infinity;
|
||||
delete this.options.autoHeight;
|
||||
}
|
||||
if (this.options.readOnly) {
|
||||
this.options.readOnly = 'nocursor';
|
||||
this.options.lineNumbers = false;
|
||||
delete this.options.gutters;
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
updateValue(...args) {
|
||||
if (this.valueUpdated) {
|
||||
this.valueUpdated(...args);
|
||||
}
|
||||
},
|
||||
onFocus(...args) {
|
||||
if (this.onFocusOut) {
|
||||
this.onFocusOut(...args);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -49,6 +49,8 @@ export default Model.extend({
|
|||
}),
|
||||
policyDocument: attr('string', {
|
||||
editType: 'json',
|
||||
helpText:
|
||||
'A policy is an object in AWS that, when associated with an identity or resource, defines their permissions.',
|
||||
}),
|
||||
fields: computed('credentialType', function() {
|
||||
let credentialType = this.credentialType;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="console-ui-output has-copy-button">
|
||||
<JsonEditor @value={{stringify content}} @options={{hash
|
||||
<JsonEditor @showToolbar={{false}} @value={{stringify content}} @options={{hash
|
||||
readOnly=true
|
||||
lineNumbers=false
|
||||
autoHeight=true
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
<div class="has-copy-button">
|
||||
<JsonEditor
|
||||
data-test-json-viewer
|
||||
@showToolbar={{false}}
|
||||
@value={{ stringify unwrapData }}
|
||||
@options={{hash
|
||||
readOnly=true
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
{{#if showToolbar }}
|
||||
<div data-test-component="json-editor-toolbar">
|
||||
<Toolbar>
|
||||
<label class="is-label" data-test-component="json-editor-title">
|
||||
{{title}}
|
||||
{{#if subTitle }}
|
||||
<span class="is-size-9 is-lowercase has-text-grey">({{ subTitle }})</span>
|
||||
{{/if}}
|
||||
</label>
|
||||
<ToolbarActions>
|
||||
{{yield}}
|
||||
<div class="toolbar-separator"></div>
|
||||
<CopyButton class="button is-transparent" @clipboardText={{value}}
|
||||
@buttonType="button" @success={{action (set-flash-message 'Data copied!')}}>
|
||||
<Icon @glyph="copy-action" aria-label="Copy" />
|
||||
</CopyButton>
|
||||
</ToolbarActions>
|
||||
</Toolbar>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{ivy-codemirror
|
||||
data-test-component="json-editor"
|
||||
value=value
|
||||
options=options
|
||||
valueUpdated=(action "updateValue")
|
||||
onFocusOut=(action "onFocus")
|
||||
}}
|
||||
{{#if helpText }}
|
||||
<div class="box is-shadowless is-fullwidth has-short-padding">
|
||||
<p class="sub-text">{{ helpText }}</p>
|
||||
</div>
|
||||
{{/if}}
|
|
@ -36,18 +36,12 @@
|
|||
|
||||
{{#if @showAdvancedMode}}
|
||||
<div class="form-section">
|
||||
<label class="title is-5">
|
||||
{{#if isV2}}
|
||||
Version data
|
||||
{{else}}
|
||||
Secret data
|
||||
{{/if}}
|
||||
</label>
|
||||
<JsonEditor
|
||||
<JsonEditor
|
||||
@title={{if isV2 "Version Data" "Secret Data"}}
|
||||
@value={{@codemirrorString}}
|
||||
@valueUpdated={{@editActions.codemirrorUpdated}}
|
||||
@onFocusOut={{@editActions.formatJSON}}
|
||||
/>
|
||||
@valueUpdated={{action @editActions.codemirrorUpdated}}
|
||||
@onFocusOut={{action @editActions.formatJSON}}>
|
||||
</JsonEditor>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="form-section">
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
<p>You can decrypt ciphertext using <code>{{key.name}}</code> as the encryption key.</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="ciphertext" class="is-label">Ciphertext</label>
|
||||
<div id="ciphertext-control" class="control">
|
||||
<IvyCodemirror @valueUpdated={{action (mut ciphertext)}} @options={{hash
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
}} @data-test-transit-input="ciphertext" />
|
||||
<JsonEditor
|
||||
@title="Ciphertext"
|
||||
@valueUpdated={{action (mut ciphertext)}}
|
||||
@options={{hash
|
||||
mode='ruby'
|
||||
}}
|
||||
@data-test-transit-input="ciphertext" />
|
||||
</div>
|
||||
</div>
|
||||
{{#if key.derived}}
|
||||
|
|
|
@ -6,16 +6,14 @@
|
|||
</div>
|
||||
<KeyVersionSelect @key={{key}} @onVersionChange={{action (mut key_version)}} @key_version={{key_version}} />
|
||||
<div class="field">
|
||||
<label for="plaintext" class="is-label">
|
||||
Plaintext
|
||||
</label>
|
||||
<div id="plaintext-control" class="control is-relative">
|
||||
<IvyCodemirror @value={{plaintext}} @valueUpdated={{action (mut plaintext)}} @options={{hash
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
}} @data-test-transit-input="plaintext" />
|
||||
<JsonEditor
|
||||
@title="Plaintext"
|
||||
@value={{plaintext}} @valueUpdated={{action (mut plaintext)}}
|
||||
@options={{hash
|
||||
mode='ruby'
|
||||
}}
|
||||
@data-test-transit-input="plaintext" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
|
|
|
@ -6,16 +6,14 @@
|
|||
</div>
|
||||
<KeyVersionSelect @key={{key}} @onVersionChange={{action (mut key_version)}} @key_version={{key_version}} />
|
||||
<div class="field">
|
||||
<label for="input" class="is-label">
|
||||
Input
|
||||
</label>
|
||||
<div id="input-control" class="control is-relative">
|
||||
<IvyCodemirror @valueUpdated={{action (mut input)}} @options={{hash
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
}} @data-test-transit-input="input" />
|
||||
<JsonEditor
|
||||
@title="Input"
|
||||
@valueUpdated={{action (mut input)}}
|
||||
@options={{hash
|
||||
mode='ruby'
|
||||
}}
|
||||
@data-test-transit-input="input" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
</div>
|
||||
<KeyVersionSelect @key={{key}} @onVersionChange={{action (mut key_version)}} @key_version={{key_version}} />
|
||||
<div class="field">
|
||||
<label for="ciphertext" class="is-label">Ciphertext</label>
|
||||
<div class="control is-expanded">
|
||||
<IvyCodemirror @valueUpdated={{action (mut ciphertext)}} @options={{hash
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
}} />
|
||||
<JsonEditor
|
||||
@title="Ciphertext"
|
||||
@valueUpdated={{action (mut ciphertext)}}
|
||||
@options={{hash
|
||||
mode='ruby'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{{#if key.derived}}
|
||||
|
|
|
@ -6,16 +6,15 @@
|
|||
</div>
|
||||
<KeyVersionSelect @key={{key}} @onVersionChange={{action (mut key_version)}} @key_version={{key_version}} />
|
||||
<div class="field">
|
||||
<label for="input" class="is-label">
|
||||
Input
|
||||
</label>
|
||||
<div class="control is-relative">
|
||||
<IvyCodemirror @value={{input}} @valueUpdated={{action (mut input)}} @options={{hash
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
<JsonEditor
|
||||
@title="Input"
|
||||
@value={{input}}
|
||||
@valueUpdated={{action (mut input)}}
|
||||
@options={{hash
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
}} @data-test-transit-input="input" />
|
||||
}}
|
||||
@data-test-transit-input="input" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
|
|
|
@ -4,16 +4,14 @@
|
|||
<p>Check whether the provided signature is valid for the given data.</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="input" class="is-label">
|
||||
Input
|
||||
</label>
|
||||
<div class="control is-relative">
|
||||
<IvyCodemirror @id="input" @value={{input}} @valueUpdated={{action (mut input)}} @options={{hash
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
}} @data-test-transit-input="input" />
|
||||
<JsonEditor
|
||||
@title="Input"
|
||||
@value={{input}} @valueUpdated={{action (mut input)}}
|
||||
@options={{hash
|
||||
mode='ruby'
|
||||
}}
|
||||
@data-test-transit-input="input" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
|
@ -115,25 +113,26 @@
|
|||
<div class="column is-two-thirds is-flex-column">
|
||||
{{#if (or (and verification (eq verification 'HMAC')) hmac)}}
|
||||
<div class="field is-flex-column is-flex-1">
|
||||
<label for="hmac" class="is-label">HMAC</label>
|
||||
<div class="control is-flex-column is-flex-1">
|
||||
<IvyCodemirror @id="hmac" @value={{hmac}} @valueUpdated={{action (mut hmac)}} @options={{hash
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
}} />
|
||||
<JsonEditor
|
||||
@title="HMAC"
|
||||
@value={{hmac}}
|
||||
@valueUpdated={{action (mut hmac)}}
|
||||
@options={{hash
|
||||
mode='ruby'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="field is-flex-column is-flex-1">
|
||||
<label for="signature" class="is-label">Signature</label>
|
||||
<div class="control is-flex-column is-flex-1">
|
||||
<IvyCodemirror @id="signature" @value={{signature}} @valueUpdated={{action (mut signature)}} @options={{hash
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
<JsonEditor
|
||||
@title="Signature"
|
||||
@value={{signature}}
|
||||
@valueUpdated={{action (mut signature)}}
|
||||
@options={{hash
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
}} />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -142,14 +141,15 @@
|
|||
</div>
|
||||
{{else}}
|
||||
<div class="field">
|
||||
<label for="hmac" class="is-label">HMAC</label>
|
||||
<div class="control">
|
||||
<IvyCodemirror @id="hmac" @value={{hmac}} @valueUpdated={{action (mut hmac)}} @options={{hash
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
}} />
|
||||
<JsonEditor
|
||||
@title="HMAC"
|
||||
@value={{hmac}}
|
||||
@valueUpdated={{action (mut hmac)}}
|
||||
@options={{hash
|
||||
mode='ruby'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
(eq attr.type "boolean")
|
||||
)
|
||||
}}
|
||||
{{#unless (eq attr.type "object")}}
|
||||
<label for="{{attr.name}}" class="is-label">
|
||||
{{capitalize (or attr.options.label (humanize (dasherize attr.name)))}}
|
||||
{{#if attr.options.helpText}}
|
||||
|
@ -24,6 +25,7 @@
|
|||
{{/if}}
|
||||
</label>
|
||||
{{/unless}}
|
||||
{{/unless}}
|
||||
{{#if attr.options.possibleValues}}
|
||||
<div class="control is-expanded">
|
||||
<div class="select is-fullwidth">
|
||||
|
@ -73,6 +75,10 @@
|
|||
</label>
|
||||
</div>
|
||||
{{else if (eq attr.type "object")}}
|
||||
<JsonEditor @value={{if (get model attr.name) (stringify (get model attr.name)) emptyData}} @valueUpdated={{action "codemirrorUpdated" attr.name}} />
|
||||
<JsonEditor
|
||||
@title={{capitalize (or attr.options.label (humanize (dasherize attr.name)))}}
|
||||
@helpText={{attr.options.helpText}}
|
||||
@value={{if (get model attr.name) (stringify (get model attr.name)) emptyData}}
|
||||
@valueUpdated={{action "codemirrorUpdated" attr.name}} />
|
||||
{{/if}}
|
||||
</div>
|
|
@ -29,9 +29,15 @@
|
|||
</EmptyState>
|
||||
{{else}}
|
||||
{{#if showAdvancedMode}}
|
||||
<JsonEditor @value={{modelForData.dataAsJSONString}} @options={{hash
|
||||
readOnly=true
|
||||
}} />
|
||||
<div class="has-top-margin-s">
|
||||
<JsonEditor
|
||||
@title={{if isV2 "Version Data" "Secret Data"}}
|
||||
@value={{modelForData.dataAsJSONString}}
|
||||
@options={{hash
|
||||
readOnly=true
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="table info-table-row-header">
|
||||
<div class="info-table-row thead">
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
{{#if (eq unwrapActiveTab "data")}}
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<JsonEditor @value={{stringify unwrap_data}} @options={{hash
|
||||
<JsonEditor @title="Unwrapped Data" @value={{stringify unwrap_data}} @options={{hash
|
||||
readOnly=true
|
||||
}} />
|
||||
</div>
|
||||
|
|
|
@ -32,9 +32,11 @@
|
|||
<NamespaceReminder @mode="perform" @noun={{selectedAction}} />
|
||||
<MessageError @errors={{errors}} />
|
||||
<div class="field">
|
||||
<label for="data" class="is-label">Data to wrap <span class="is-size-9 is-lowercase has-text-grey">(json-formatted)</span></label>
|
||||
<div class="control">
|
||||
<JsonEditor @value={{data}} @valueUpdated={{action "codemirrorUpdated"}} />
|
||||
<JsonEditor @title="Data to wrap"
|
||||
@subTitle="json-formatted"
|
||||
@value={{data}}
|
||||
@valueUpdated={{action "codemirrorUpdated"}} />
|
||||
</div>
|
||||
</div>
|
||||
<TtlPicker2
|
||||
|
|
|
@ -32,36 +32,32 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="level is-mobile">
|
||||
<div class="level-left">
|
||||
<label for="policy" class="is-label">Policy</label>
|
||||
</div>
|
||||
<div class="level-right">
|
||||
<div class="field is-horizontal is-flex-end is-single-line">
|
||||
<Toolbar>
|
||||
<label class="is-label">Policy</label>
|
||||
<ToolbarActions>
|
||||
<div class="toolbar-separator"></div>
|
||||
<div class="control is-flex">
|
||||
<Input @id="fileUploadToggle" @type="checkbox" @name="fileUploadToggle" class="switch is-rounded is-success is-small" @checked={{showFileUpload}} @change={{toggle-action "showFileUpload" this}} data-test-policy-edit-toggle={{true}} />
|
||||
<label for="fileUploadToggle">Upload file</label>
|
||||
<Input @id="fileUploadToggle" @type="checkbox" @name="fileUploadToggle" class="switch is-rounded is-success is-small" @checked={{showFileUpload}} @change={{toggle-action "showFileUpload" this}} data-test-policy-edit-toggle={{true}} />
|
||||
<label for="fileUploadToggle">Upload file</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ToolbarActions>
|
||||
</Toolbar>
|
||||
{{#if showFileUpload}}
|
||||
<TextFile @inputOnly={{true}} @file={{file}} @onChange={{action "setPolicyFromFile"}} />
|
||||
{{else}}
|
||||
<IvyCodemirror @value={{model.policy}} @id="policy" @valueUpdated={{action (mut model.policy)}} @options={{hash
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
<JsonEditor
|
||||
@title="Policy"
|
||||
@helpText="You can use Alt+Tab (Option+Tab on MacOS) in the code editor to skip to the next field"
|
||||
@showToolbar={{false}}
|
||||
@value={{model.policy}}
|
||||
@valueUpdated={{action (mut model.policy)}}
|
||||
@options={{hash
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
extraKeys=(hash
|
||||
Shift-Enter=(action "savePolicy" model)
|
||||
)
|
||||
}} />
|
||||
<div class="box is-shadowless is-fullwidth has-short-padding">
|
||||
<p class="help-text has-text-grey-dark is-size-7">
|
||||
You can use Alt+Tab (Option+Tab on MacOS) in the code editor to skip to the next field
|
||||
</p>
|
||||
</div>
|
||||
}}>
|
||||
</JsonEditor>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{#each model.additionalAttrs as |attr|}}
|
||||
|
|
|
@ -47,13 +47,13 @@
|
|||
<div class="box is-bottomless is-fullwidth is-marginless">
|
||||
<MessageError @model={{model}} />
|
||||
<NamespaceReminder @mode="edit" @noun="policy" />
|
||||
<label for="policy" class="is-label">Policy</label>
|
||||
<div class="field">
|
||||
<IvyCodemirror @value={{model.policy}} @valueUpdated={{action (mut model.policy)}} @options={{hash
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
<JsonEditor
|
||||
@title="Policy"
|
||||
@value={{model.policy}}
|
||||
@valueUpdated={{action (mut model.policy)}}
|
||||
@options={{hash
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
extraKeys=(hash
|
||||
Shift-Enter=(action "savePolicy" model)
|
||||
)
|
||||
|
|
|
@ -40,20 +40,13 @@
|
|||
</Toolbar>
|
||||
<div class="box is-bottomless is-fullwidth is-marginless">
|
||||
<div class="field">
|
||||
<label for="policy" class="is-label">
|
||||
Policy
|
||||
{{#if (eq policyType "acl")}}
|
||||
<span class="tag is-white is-size-9 has-text-grey" data-test-acl-format>
|
||||
({{uppercase model.format}} format)
|
||||
</span>
|
||||
{{/if}}
|
||||
</label>
|
||||
<IvyCodemirror @value={{model.policy}} @options={{hash
|
||||
<JsonEditor
|
||||
@title="Policy"
|
||||
@subTitle={{if (eq policyType "acl") (concat uppercase model.format " format")}}
|
||||
@value={{model.policy}}
|
||||
@options={{hash
|
||||
readOnly=true
|
||||
lineNumbers=true
|
||||
tabSize=2
|
||||
mode='ruby'
|
||||
theme='hashi'
|
||||
}} />
|
||||
</div>
|
||||
{{#if model.paths}}
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
)
|
||||
)
|
||||
}}
|
||||
<label for="{{attr.name}}" class="is-label">
|
||||
{{#unless (eq attr.type "object")}}
|
||||
<label for="{{attr.name}}" class="is-label">
|
||||
{{labelString}}
|
||||
{{#if attr.options.helpText}}
|
||||
{{#info-tooltip}}
|
||||
|
@ -27,9 +28,10 @@
|
|||
{{/info-tooltip}}
|
||||
{{/if}}
|
||||
</label>
|
||||
{{#if attr.options.subText}}
|
||||
<p class="sub-text">{{attr.options.subText}} {{#if attr.options.docLink}}<a href="{{attr.options.docLink}}" target="_blank" rel="noopener noreferrer">See our documentation</a> for help.{{/if}}</p>
|
||||
{{/if}}
|
||||
{{#if attr.options.subText}}
|
||||
<p class="sub-text">{{attr.options.subText}} {{#if attr.options.docLink}}<a href="{{attr.options.docLink}}" target="_blank" rel="noopener noreferrer">See our documentation</a> for help.{{/if}}</p>
|
||||
{{/if}}
|
||||
{{/unless}}
|
||||
{{/unless}}
|
||||
{{#if attr.options.possibleValues}}
|
||||
<div class="control is-expanded">
|
||||
|
@ -198,21 +200,12 @@
|
|||
@spellcheck="false" />
|
||||
{{else if (eq attr.options.editType "json")}}
|
||||
{{!-- JSON Editor --}}
|
||||
<label for="{{attr.name}}" class="is-label">
|
||||
{{labelString}}
|
||||
{{#if attr.options.helpText}}
|
||||
{{#info-tooltip}}
|
||||
<span data-test-help-text>
|
||||
{{attr.options.helpText}}
|
||||
</span>
|
||||
{{/info-tooltip}}
|
||||
{{/if}}
|
||||
</label>
|
||||
{{#if attr.options.subText}}
|
||||
<p class="sub-text">{{attr.options.subText}} {{#if attr.options.docLink}}<a href="{{attr.options.docLink}}" target="_blank" rel="noopener noreferrer">See our documentation</a> for help.{{/if}}</p>
|
||||
{{/if}}
|
||||
<JsonEditor
|
||||
data-test-input={{attr.name}}
|
||||
@title={{labelString}}
|
||||
@value={{if
|
||||
(get model valuePath)
|
||||
(stringify (jsonify (get model valuePath)))
|
||||
|
@ -222,6 +215,7 @@
|
|||
@options={{hash
|
||||
theme=(or attr.options.theme 'hashi')
|
||||
}}
|
||||
@helpText={{attr.options.helpText}}
|
||||
/>
|
||||
{{else}}
|
||||
{{!-- Regular Text Input --}}
|
||||
|
@ -259,7 +253,9 @@
|
|||
</div>
|
||||
{{else if (eq attr.type "object")}}
|
||||
{{json-editor
|
||||
title=labelString
|
||||
value=(if (get model valuePath) (stringify (get model valuePath)) emptyData)
|
||||
valueUpdated=(action "codemirrorUpdated" attr.name false)
|
||||
helpText=attr.options.helpText
|
||||
}}
|
||||
{{/if}}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { create } from 'ember-cli-page-object';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import jsonEditor from '../../pages/components/json-editor';
|
||||
|
||||
const component = create(jsonEditor);
|
||||
|
||||
module('Integration | Component | json-editor', function(hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
const setup = async function(context, title, value, options, showToolbar = true) {
|
||||
context.set('value', JSON.stringify(value));
|
||||
context.set('options', options);
|
||||
context.set('title', title);
|
||||
context.set('showToolbar', showToolbar);
|
||||
await render(hbs`{{json-editor title=title value=value options=options showToolbar=showToolbar}}`);
|
||||
};
|
||||
|
||||
test('it renders', async function(assert) {
|
||||
let value = '';
|
||||
await setup(this, 'Test title', value, null);
|
||||
assert.equal(component.title, 'Test title', 'renders the provided title');
|
||||
assert.equal(component.hasToolbar, true, 'renders the toolbar');
|
||||
assert.equal(component.hasJSONEditor, true, 'renders the ivy code mirror component');
|
||||
assert.equal(component.canEdit, true, 'json editor is in read only mode');
|
||||
});
|
||||
|
||||
test('it renders in read only mode', async function(assert) {
|
||||
let value = '';
|
||||
let options = {
|
||||
readOnly: true,
|
||||
};
|
||||
await setup(this, 'Test title', value, options);
|
||||
assert.equal(component.canEdit, false, 'editor is in read only mode');
|
||||
});
|
||||
|
||||
test('it renders the editor without toolbar', async function(assert) {
|
||||
let value = '';
|
||||
await setup(this, 'Test title', value, null, false);
|
||||
assert.equal(component.hasToolbar, false, 'toolbar is not rendered');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,8 @@
|
|||
import { isPresent, isVisible, text } from 'ember-cli-page-object';
|
||||
|
||||
export default {
|
||||
title: text('[data-test-component=json-editor-title]'),
|
||||
hasToolbar: isPresent('[data-test-component=json-editor-toolbar]'),
|
||||
hasJSONEditor: isPresent('[data-test-component=json-editor]'),
|
||||
canEdit: isVisible('div.CodeMirror-gutters'),
|
||||
};
|
Loading…
Reference in New Issue