Revision 32da02c5
Added by Oleh Fedorenko over 2 years ago
.eslintrc | ||
---|---|---|
"xpi",
|
||
"xyz",
|
||
"yaml",
|
||
"cpu",
|
||
"Autocompletion"
|
||
"cpu"
|
||
],
|
||
"minLength": 3
|
||
}
|
app/controllers/templates_controller.rb | ||
---|---|---|
|
||
def new
|
||
@template = resource_class.new
|
||
@dsl_cache = ApipieDSL.docs
|
||
end
|
||
|
||
# we can't use `clone` here, ActionController disables public method that are inherited and present in Base
|
||
... | ... | |
@template.locked = false
|
||
load_vars_from_template
|
||
@template.valid?
|
||
@dsl_cache = ApipieDSL.docs
|
||
render :action => :new
|
||
end
|
||
|
||
... | ... | |
|
||
def edit
|
||
load_vars_from_template
|
||
@dsl_cache = ApipieDSL.docs
|
||
end
|
||
|
||
def update
|
app/services/foreman/renderer/scope/macros/base.rb | ||
---|---|---|
|
||
apipie :method, desc: 'Takes a block of code, runs it and prefixes the resulting text by given number of spaces' do
|
||
desc "This is useful when rendering output is a whitespace sensitive format, such as YAML."
|
||
required :count, Integer, desc: 'the number of spaces'
|
||
keyword :skip1, [true, false], desc: 'skips the first line prefixing, defaults to false', default: false
|
||
block 'Optional. Does nothing if no block is given.', schema: '{ code }'
|
||
required :count, String, desc: 'the number of spaces'
|
||
keyword :skip1, String, desc: 'skips the first line prefixing, defaults to false', default: false
|
||
returns String, desc: 'The indented text, that was the result of block of code'
|
||
example "indent(2) { snippet('epel') } # => ' echo Installing yum repo\n yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm'"
|
||
example "indent(2) { snippet('epel', skip1: true) } # => 'echo Installing yum repo\n yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm'"
|
app/views/templates/_form.html.erb | ||
---|---|---|
</span>
|
||
<% end %>
|
||
<%= react_component('Editor', { data: {
|
||
dslCache: @dsl_cache.to_json,
|
||
template: @template.template,
|
||
locked: @template.locked,
|
||
id: @template.id,
|
webpack/assets/javascripts/react_app/components/Editor/Editor.fixtures.js | ||
---|---|---|
previewResult: 'previewResult',
|
||
mode: 'Ruby',
|
||
theme: 'Monokai',
|
||
autocompletion: true,
|
||
liveAutocompletion: false,
|
||
keyBinding: 'Default',
|
||
selectedView: 'input',
|
||
editorName: 'editor',
|
webpack/assets/javascripts/react_app/components/Editor/Editor.js | ||
---|---|---|
class Editor extends React.Component {
|
||
componentDidMount() {
|
||
const {
|
||
data: { hosts, templateClass, locked, template, type, dslCache },
|
||
data: { hosts, templateClass, locked, template, type },
|
||
initializeEditor,
|
||
isMasked,
|
||
isRendering,
|
||
... | ... | |
showError,
|
||
template,
|
||
type,
|
||
dslCache,
|
||
};
|
||
initializeEditor(initializeData);
|
||
}
|
||
... | ... | |
selectedView,
|
||
showError,
|
||
theme,
|
||
autocompletion,
|
||
liveAutocompletion,
|
||
toggleMaskValue,
|
||
toggleModal,
|
||
toggleRenderView,
|
||
... | ... | |
value: isRendering ? previewResult : value,
|
||
mode: isRendering ? 'Text' : mode,
|
||
theme,
|
||
autocompletion,
|
||
liveAutocompletion,
|
||
keyBinding,
|
||
onChange: isRendering ? noop : changeEditorValue,
|
||
readOnly: readOnly || isRendering,
|
||
... | ... | |
mode={isRendering ? 'Text' : mode}
|
||
theme={theme}
|
||
keyBinding={keyBinding}
|
||
autocompletion={autocompletion}
|
||
liveAutocompletion={liveAutocompletion}
|
||
value={value}
|
||
renderedEditorValue={renderedEditorValue}
|
||
diffViewType={diffViewType}
|
||
... | ... | |
diffViewType={diffViewType}
|
||
mode={mode}
|
||
theme={theme}
|
||
autocompletion={autocompletion}
|
||
liveAutocompletion={liveAutocompletion}
|
||
keyBinding={keyBinding}
|
||
readOnly={readOnly}
|
||
isMaximized={isMaximized}
|
||
... | ... | |
hosts: PropTypes.array,
|
||
locked: PropTypes.bool,
|
||
type: PropTypes.string,
|
||
dslCache: PropTypes.string,
|
||
}).isRequired,
|
||
selectedHost: PropTypes.shape({
|
||
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||
... | ... | |
selectedView: PropTypes.string.isRequired,
|
||
showError: PropTypes.bool.isRequired,
|
||
theme: PropTypes.string.isRequired,
|
||
autocompletion: PropTypes.bool.isRequired,
|
||
liveAutocompletion: PropTypes.bool.isRequired,
|
||
toggleMaskValue: PropTypes.func.isRequired,
|
||
toggleModal: PropTypes.func.isRequired,
|
||
toggleRenderView: PropTypes.func.isRequired,
|
webpack/assets/javascripts/react_app/components/Editor/EditorActions.js | ||
---|---|---|
selectHosts,
|
||
} from './EditorSelectors';
|
||
|
||
import { parseDocs } from './EditorHelpers';
|
||
|
||
export const initializeEditor = initializeData => dispatch => {
|
||
const {
|
||
template,
|
||
... | ... | |
isRendering,
|
||
previewResult,
|
||
showError,
|
||
dslCache,
|
||
} = initializeData;
|
||
|
||
const initialState = {};
|
||
... | ... | |
if (isRendering) initialState.isRendering = false;
|
||
if (previewResult !== '') initialState.previewResult = '';
|
||
if (showError) initialState.showError = false;
|
||
parseDocs(dslCache);
|
||
dispatch({
|
||
type: EDITOR_INITIALIZE,
|
||
payload: initialState,
|
webpack/assets/javascripts/react_app/components/Editor/EditorHelpers.js | ||
---|---|---|
import {
|
||
isEmpty,
|
||
filter,
|
||
find,
|
||
replace,
|
||
capitalize,
|
||
forEach,
|
||
concat,
|
||
sortBy,
|
||
} from 'lodash';
|
||
|
||
import ace from 'brace';
|
||
import 'brace/ext/language_tools';
|
||
|
||
const resolveDefault = ({ default: defValue }) => {
|
||
switch (typeof defValue) {
|
||
case 'object':
|
||
if (defValue === null) return 'nil';
|
||
|
||
return '{}';
|
||
case 'string':
|
||
if (defValue === '') return '""';
|
||
|
||
return `"${defValue}"`;
|
||
default:
|
||
return defValue;
|
||
}
|
||
};
|
||
|
||
const methodReturns = ({ returns: { object: retObject } }) => {
|
||
// TODO: add support for Hash return object with nested description
|
||
// can be skipped for now since we don't use it yet and it wasn't tested properly
|
||
if (retObject.class === 'Hash' && retObject.data.constructor === Array)
|
||
return 'Object';
|
||
const retMeta = capitalize(replace(retObject.meta, '_', ' '));
|
||
const retData = replace(JSON.stringify(retObject.data), 'null', 'nil');
|
||
const returns = retObject.data === null ? retObject.class : retData;
|
||
return `${retMeta}: ${returns}`;
|
||
};
|
||
|
||
const methodTooltip = (method, isMacro) => {
|
||
const usagePrefix = isMacro ? '' : 'obj.';
|
||
const usage = `Usage:\n\t${usagePrefix}${methodSignature(method)}`;
|
||
const returns = `Returns:\n\t${methodReturns(method)}`;
|
||
if (isEmpty(method.examples))
|
||
return [method.short_description, usage, returns].join('\n\n');
|
||
|
||
let examples = method.examples
|
||
.map(e => {
|
||
const desc = e.desc ? `${e.desc}\n\n` : '';
|
||
return `${desc}${e.example}`;
|
||
})
|
||
.join('\n\n');
|
||
examples = `Examples:\n\n${examples}`;
|
||
return [method.short_description, usage, returns, examples].join('\n\n');
|
||
};
|
||
|
||
const methodSignature = (method, isSnippet) => {
|
||
if (isEmpty(method.params)) return method.name;
|
||
|
||
let currParam = 1;
|
||
const params = method.params.map(p => {
|
||
switch (p.type) {
|
||
case 'required':
|
||
return isSnippet ? `\${${currParam++}:${p.name}}` : p.name;
|
||
case 'optional': {
|
||
if (p.expected_type === 'list') {
|
||
return isSnippet
|
||
? `\${${currParam++}:first},\${${currParam++}:second}`
|
||
: `*${p.name}`;
|
||
}
|
||
const defaultVal = resolveDefault(p);
|
||
return isSnippet
|
||
? `\${${currParam++}:${defaultVal}}`
|
||
: `${p.name} = ${defaultVal}`;
|
||
}
|
||
case 'keyword':
|
||
return isSnippet
|
||
? `${p.name}: \${${currParam++}:${resolveDefault(p)}}`
|
||
: `${p.name}: ${resolveDefault(p)}`;
|
||
default:
|
||
return null;
|
||
}
|
||
});
|
||
const filtered = filter(params, p => p !== null).join(', ');
|
||
const blockParam = find(method.params, p => p.type === 'block');
|
||
const parts = [method.name];
|
||
if (!isEmpty(method.params)) parts.push(`(${filtered})`);
|
||
if (blockParam) parts.push(` ${blockParam.schema}`);
|
||
return parts.join('');
|
||
};
|
||
|
||
export const parseDocs = cache => {
|
||
// Do nothing if the editor is not being used for templates
|
||
if (!cache) return;
|
||
|
||
const langTools = ace.acequire('ace/ext/language_tools');
|
||
// Custom basic snippets
|
||
/* eslint-disable */
|
||
let completions = [
|
||
{
|
||
caption: '<%',
|
||
snippet: '<% ${1:code} %>',
|
||
tooltip: 'Executes code, but does not insert a value\n\n<% code %>',
|
||
meta: 'erb',
|
||
},
|
||
{
|
||
caption: '<%=',
|
||
snippet: '<%= ${1:expression} %>',
|
||
tooltip: 'Inserts the value of an expression\n\n<%= expression %>',
|
||
meta: 'erb',
|
||
},
|
||
{
|
||
caption: '<%-',
|
||
snippet: '<% ${1:code} -%>',
|
||
tooltip:
|
||
'Executes code, but does not insert a value, trims the following line break\n\n<% code -%>',
|
||
meta: 'erb',
|
||
},
|
||
{
|
||
caption: '<%=-',
|
||
snippet: '<%= ${1:expression} -%>',
|
||
tooltip:
|
||
'Inserts the value of an expression, trims the following line break\n\n<%= expression -%>',
|
||
meta: 'erb',
|
||
},
|
||
{
|
||
caption: '<%#',
|
||
snippet: '<%# ${1:comment} -%>',
|
||
tooltip:
|
||
'Comment, removed from the final output, trims the following line break\n\n<%# comment -%>',
|
||
meta: 'erb',
|
||
},
|
||
];
|
||
/* eslint-enable */
|
||
// Parse JSON with DSL documentation
|
||
forEach(JSON.parse(cache).docs.classes, cls => {
|
||
const macros = cls.methods.map(method => ({
|
||
caption: method.name,
|
||
snippet: methodSignature(method, true),
|
||
tooltip: methodTooltip(method, true),
|
||
meta: 'macro',
|
||
}));
|
||
const props = cls.properties.map(prop => ({
|
||
caption: `${cls.name}#${prop.name}`,
|
||
snippet: methodSignature(prop, true),
|
||
tooltip: methodTooltip(prop),
|
||
meta: 'property',
|
||
}));
|
||
completions = concat(completions, macros, props);
|
||
});
|
||
const completer = {
|
||
getDocTooltip: selected => selected.tooltip,
|
||
getCompletions: (editor, session, pos, prefix, callback) =>
|
||
callback(null, sortBy(completions, ['meta', 'caption'])),
|
||
};
|
||
|
||
langTools.setCompleters([completer]);
|
||
};
|
webpack/assets/javascripts/react_app/components/Editor/EditorReducer.js | ||
---|---|---|
showError: false,
|
||
templateClass: '',
|
||
theme: 'Monokai',
|
||
autocompletion: true,
|
||
liveAutocompletion: false,
|
||
value: '',
|
||
});
|
||
|
webpack/assets/javascripts/react_app/components/Editor/EditorSelectors.js | ||
---|---|---|
export const selectEditorName = state => selectEditor(state).editorName;
|
||
export const selectChosenView = state => selectEditor(state).selectedView;
|
||
export const selectTheme = state => selectEditor(state).theme;
|
||
export const selectAutocompletion = state => selectEditor(state).autocompletion;
|
||
export const selectLiveAutocompletion = state =>
|
||
selectEditor(state).liveAutocompletion;
|
||
export const selectDiffType = state => selectEditor(state).diffViewType;
|
||
export const selectIsMaximized = state => selectEditor(state).isMaximized;
|
||
export const selectIsMasked = state => selectEditor(state).isMasked;
|
webpack/assets/javascripts/react_app/components/Editor/__tests__/__snapshots__/Editor.test.js.snap | ||
---|---|---|
type="error"
|
||
/>
|
||
<EditorNavbar
|
||
autocompletion={true}
|
||
changeDiffViewType={[Function]}
|
||
changeSetting={[Function]}
|
||
changeTab={[Function]}
|
||
... | ... | |
"Vim",
|
||
]
|
||
}
|
||
liveAutocompletion={false}
|
||
mode="Ruby"
|
||
modes={
|
||
Array [
|
||
... | ... | |
value="value"
|
||
/>
|
||
<EditorView
|
||
autocompletion={true}
|
||
className="ace_editor_form ace_preview"
|
||
isMasked={false}
|
||
isSelected={false}
|
||
key="editorPreview"
|
||
keyBinding="Default"
|
||
liveAutocompletion={false}
|
||
mode="Ruby"
|
||
name="editorPreview"
|
||
onChange={[Function]}
|
||
... | ... | |
value="value"
|
||
/>
|
||
<EditorView
|
||
autocompletion={true}
|
||
className="ace_editor_form ace_input"
|
||
isMasked={false}
|
||
isSelected={true}
|
||
key="editorCode"
|
||
keyBinding="Default"
|
||
liveAutocompletion={false}
|
||
mode="Ruby"
|
||
name="editorCode"
|
||
onChange={[Function]}
|
||
... | ... | |
/>
|
||
</div>
|
||
<EditorModal
|
||
autocompletion={true}
|
||
changeDiffViewType={[Function]}
|
||
changeEditorValue={[Function]}
|
||
diffViewType="split"
|
||
... | ... | |
isRendering={false}
|
||
key="editorModal"
|
||
keyBinding="Default"
|
||
liveAutocompletion={false}
|
||
mode="Ruby"
|
||
name="editor"
|
||
previewValue="previewResult"
|
webpack/assets/javascripts/react_app/components/Editor/__tests__/__snapshots__/EditorReducer.test.js.snap | ||
---|---|---|
|
||
exports[`Editor reducer should handle EDITOR_CHANGE_DIFF_VIEW 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "unified",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should handle EDITOR_CHANGE_SETTING 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "html",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should handle EDITOR_CHANGE_STATE 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should handle EDITOR_CHANGE_TAB 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should handle EDITOR_DISMISS_ERROR 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should handle EDITOR_EXEC_PREVIEW 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "</>",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should handle EDITOR_FETCH_HOST_PENDING 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": true,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should handle EDITOR_FETCH_HOST_RESOLVED 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should handle EDITOR_HIDE_LOADING 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should handle EDITOR_HOST_INITIAL_FETCH 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should handle EDITOR_HOST_SELECT_CLEAR 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should handle EDITOR_HOST_SELECT_RESET 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should handle EDITOR_HOST_SELECT_TOGGLE 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": true,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should handle EDITOR_IMPORT_FILE 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should handle EDITOR_INITIALIZE 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should handle EDITOR_MODAL_TOGGLE 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should handle EDITOR_REVERT_CHANGES 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should handle EDITOR_SHOW_ERROR 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "error",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "error",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should handle EDITOR_SHOW_LOADING 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should handle EDITOR_TOGGLE_MASK 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should handle EDITOR_TOGGLE_RENDER_VIEW 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
|
||
exports[`Editor reducer should return the initial state 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
webpack/assets/javascripts/react_app/components/Editor/__tests__/__snapshots__/EditorSelectors.test.js.snap | ||
---|---|---|
|
||
exports[`Editor selectors should return editor 1`] = `
|
||
Object {
|
||
"autocompletion": true,
|
||
"changeDiffViewType": [Function],
|
||
"changeEditorValue": [Function],
|
||
"changeSetting": [Function],
|
||
... | ... | |
"Emacs",
|
||
"Vim",
|
||
],
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"modes": Array [
|
||
"Text",
|
webpack/assets/javascripts/react_app/components/Editor/__tests__/__snapshots__/integration.test.js.snap | ||
---|---|---|
],
|
||
"state": Object {
|
||
"editor": Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
exports[`Editor integration test should flow: initial state 1`] = `
|
||
Object {
|
||
"editor": Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
||
... | ... | |
],
|
||
"state": Object {
|
||
"editor": Object {
|
||
"autocompletion": true,
|
||
"diffViewType": "split",
|
||
"editorName": "editor",
|
||
"errorText": "",
|
||
... | ... | |
"isSearchingHosts": false,
|
||
"isSelectOpen": false,
|
||
"keyBinding": "Default",
|
||
"liveAutocompletion": false,
|
||
"mode": "Ruby",
|
||
"previewResult": "",
|
||
"readOnly": false,
|
webpack/assets/javascripts/react_app/components/Editor/components/EditorModal.js | ||
---|---|---|
selectedView,
|
||
template,
|
||
theme,
|
||
autocompletion,
|
||
liveAutocompletion,
|
||
title,
|
||
toggleModal,
|
||
}) => (
|
||
... | ... | |
readOnly={readOnly || selectedView === 'preview'}
|
||
className="editor ace_editor_modal"
|
||
isMasked={isMasked}
|
||
autocompletion={autocompletion}
|
||
liveAutocompletion={liveAutocompletion}
|
||
/>
|
||
)}
|
||
</Modal.Body>
|
||
... | ... | |
selectedView: PropTypes.string.isRequired,
|
||
template: PropTypes.string.isRequired,
|
||
theme: PropTypes.string.isRequired,
|
||
autocompletion: PropTypes.bool.isRequired,
|
||
liveAutocompletion: PropTypes.bool.isRequired,
|
||
title: PropTypes.string,
|
||
toggleModal: PropTypes.func.isRequired,
|
||
};
|
webpack/assets/javascripts/react_app/components/Editor/components/EditorNavbar.js | ||
---|---|---|
template,
|
||
theme,
|
||
themes,
|
||
autocompletion,
|
||
liveAutocompletion,
|
||
toggleMaskValue,
|
||
toggleModal,
|
||
toggleRenderView,
|
||
... | ... | |
keyBindings={keyBindings}
|
||
theme={theme}
|
||
themes={themes}
|
||
autocompletion={autocompletion}
|
||
liveAutocompletion={liveAutocompletion}
|
||
/>
|
||
</div>
|
||
);
|
||
... | ... | |
isSelectOpen: PropTypes.bool.isRequired,
|
||
keyBinding: PropTypes.string.isRequired,
|
||
keyBindings: PropTypes.array.isRequired,
|
||
autocompletion: PropTypes.bool.isRequired,
|
||
liveAutocompletion: PropTypes.bool.isRequired,
|
||
mode: PropTypes.string.isRequired,
|
||
modes: PropTypes.array.isRequired,
|
||
onHostSearch: PropTypes.func.isRequired,
|
webpack/assets/javascripts/react_app/components/Editor/components/EditorOptions.js | ||
---|---|---|
template,
|
||
theme,
|
||
themes,
|
||
autocompletion,
|
||
liveAutocompletion,
|
||
toggleMaskValue,
|
||
toggleModal,
|
||
} = this.props;
|
||
... | ... | |
keyBinding={keyBinding}
|
||
theme={theme}
|
||
themes={themes}
|
||
autocompletion={autocompletion}
|
||
liveAutocompletion={liveAutocompletion}
|
||
/>
|
||
<OverlayTrigger
|
||
delayShow={500}
|
||
... | ... | |
template: PropTypes.string,
|
||
theme: PropTypes.string.isRequired,
|
||
themes: PropTypes.array.isRequired,
|
||
autocompletion: PropTypes.bool.isRequired,
|
||
liveAutocompletion: PropTypes.bool.isRequired,
|
||
toggleMaskValue: PropTypes.func.isRequired,
|
||
toggleModal: PropTypes.func.isRequired,
|
||
};
|
webpack/assets/javascripts/react_app/components/Editor/components/EditorSettings.js | ||
---|---|---|
modes,
|
||
theme,
|
||
themes,
|
||
autocompletion,
|
||
liveAutocompletion,
|
||
}) => (
|
||
<OverlayTrigger
|
||
overlay={
|
||
... | ... | |
</Dropdown.Menu>
|
||
</Dropdown>
|
||
</div>
|
||
<div className="cog-popover-dropdown">
|
||
<div className="cog-popover-dropdown-title">
|
||
{__('Autocompletion')}
|
||
</div>
|
||
<div className="dropdown btn-group">
|
||
<input
|
||
id="autocompletion-checkbox"
|
||
name="autocompletion"
|
||
type="checkbox"
|
||
checked={autocompletion}
|
||
onChange={e => changeSetting({ autocompletion: !autocompletion })}
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div className="cog-popover-dropdown">
|
||
<div className="cog-popover-dropdown-title">
|
||
{__('Live Autocompletion')}
|
||
</div>
|
||
<div className="dropdown btn-group">
|
||
<input
|
||
id="live-autocompletion-checkbox"
|
||
name="liveAutocompletion"
|
||
type="checkbox"
|
||
checked={liveAutocompletion}
|
||
onChange={e =>
|
||
changeSetting({ liveAutocompletion: !liveAutocompletion })
|
||
}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Popover>
|
||
}
|
||
placement="bottom"
|
||
... | ... | |
modes: PropTypes.array.isRequired,
|
||
theme: PropTypes.string.isRequired,
|
||
themes: PropTypes.array.isRequired,
|
||
autocompletion: PropTypes.bool.isRequired,
|
||
liveAutocompletion: PropTypes.bool.isRequired,
|
||
};
|
||
|
||
export default EditorSettings;
|
webpack/assets/javascripts/react_app/components/Editor/components/EditorView.js | ||
---|---|---|
onChange,
|
||
readOnly,
|
||
theme,
|
||
autocompletion,
|
||
liveAutocompletion,
|
||
value,
|
||
isSelected,
|
||
}) => (
|
||
... | ... | |
editorProps={{ $blockScrolling: Infinity }}
|
||
showPrintMargin={false}
|
||
debounceChangePeriod={250}
|
||
enableBasicAutocompletion={autocompletion}
|
||
enableLiveAutocompletion={autocompletion && liveAutocompletion}
|
||
/>
|
||
);
|
||
EditorView.propTypes = {
|
||
mode: PropTypes.string.isRequired,
|
||
theme: PropTypes.string.isRequired,
|
||
autocompletion: PropTypes.bool.isRequired,
|
||
liveAutocompletion: PropTypes.bool.isRequired,
|
||
keyBinding: PropTypes.string.isRequired,
|
||
onChange: PropTypes.func,
|
||
readOnly: PropTypes.bool.isRequired,
|
webpack/assets/javascripts/react_app/components/Editor/components/__tests__/EditorSettings.test.js | ||
---|---|---|
mode: 'Ruby',
|
||
selectedView: 'input',
|
||
theme: 'Github',
|
||
autocompletion: true,
|
||
liveAutocompletion: false,
|
||
keyBinding: 'vim',
|
||
changeSetting: noop,
|
||
},
|
||
... | ... | |
mode: 'Ruby',
|
||
selectedView: 'preview',
|
||
theme: 'Github',
|
||
autocompletion: true,
|
||
liveAutocompletion: false,
|
||
keyBinding: 'vim',
|
||
changeSetting: noop,
|
||
},
|
webpack/assets/javascripts/react_app/components/Editor/components/__tests__/__snapshots__/EditorModal.test.js.snap | ||
---|---|---|
componentClass="div"
|
||
>
|
||
<EditorView
|
||
autocompletion={true}
|
||
className="editor ace_editor_modal"
|
||
isMasked={false}
|
||
isSelected={true}
|
||
keyBinding="Default"
|
||
liveAutocompletion={false}
|
||
mode="Ruby"
|
||
name="editor"
|
||
onChange={[Function]}
|
webpack/assets/javascripts/react_app/components/Editor/components/__tests__/__snapshots__/EditorNavbar.test.js.snap | ||
---|---|---|
/>
|
||
</Nav>
|
||
<EditorOptions
|
||
autocompletion={true}
|
||
changeDiffViewType={[Function]}
|
||
changeSetting={[Function]}
|
||
changeTab={[Function]}
|
||
... | ... | |
"Vim",
|
||
]
|
||
}
|
||
liveAutocompletion={false}
|
||
mode="Ruby"
|
||
modes={
|
||
Array [
|
webpack/assets/javascripts/react_app/components/Editor/components/__tests__/__snapshots__/EditorOptions.test.js.snap | ||
---|---|---|
</Button>
|
||
</OverlayTrigger>
|
||
<EditorSettings
|
||
autocompletion={true}
|
||
changeSetting={[Function]}
|
||
keyBinding="Default"
|
||
keyBindings={
|
||
... | ... | |
"Vim",
|
||
]
|
||
}
|
||
liveAutocompletion={false}
|
||
mode="Ruby"
|
||
modes={
|
||
Array [
|
webpack/assets/javascripts/react_app/components/Editor/components/__tests__/__snapshots__/EditorSettings.test.js.snap | ||
---|---|---|
</DropdownMenu>
|
||
</ForwardRef>
|
||
</div>
|
||
<div
|
||
className="cog-popover-dropdown"
|
||
>
|
||
<div
|
||
className="cog-popover-dropdown-title"
|
||
>
|
||
Autocompletion
|
||
</div>
|
||
<div
|
||
className="dropdown btn-group"
|
||
>
|
||
<input
|
||
checked={true}
|
||
id="autocompletion-checkbox"
|
||
name="autocompletion"
|
||
onChange={[Function]}
|
||
type="checkbox"
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div
|
||
className="cog-popover-dropdown"
|
||
>
|
||
<div
|
||
className="cog-popover-dropdown-title"
|
||
>
|
||
Live Autocompletion
|
||
</div>
|
||
<div
|
||
className="dropdown btn-group"
|
||
>
|
||
<input
|
||
checked={false}
|
||
id="live-autocompletion-checkbox"
|
||
name="liveAutocompletion"
|
||
onChange={[Function]}
|
||
type="checkbox"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Popover>
|
||
}
|
||
placement="bottom"
|
||
... | ... | |
</DropdownMenu>
|
||
</ForwardRef>
|
||
</div>
|
||
<div
|
||
className="cog-popover-dropdown"
|
||
>
|
||
<div
|
||
className="cog-popover-dropdown-title"
|
||
>
|
||
Autocompletion
|
||
</div>
|
||
<div
|
||
className="dropdown btn-group"
|
||
>
|
||
<input
|
||
checked={true}
|
||
id="autocompletion-checkbox"
|
||
name="autocompletion"
|
||
onChange={[Function]}
|
||
type="checkbox"
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div
|
||
className="cog-popover-dropdown"
|
||
>
|
||
<div
|
||
className="cog-popover-dropdown-title"
|
||
>
|
||
Live Autocompletion
|
||
</div>
|
||
<div
|
||
className="dropdown btn-group"
|
||
>
|
||
<input
|
||
checked={false}
|
||
id="live-autocompletion-checkbox"
|
||
name="liveAutocompletion"
|
||
onChange={[Function]}
|
||
type="checkbox"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</Popover>
|
||
}
|
||
placement="bottom"
|
webpack/assets/javascripts/react_app/components/Editor/components/__tests__/__snapshots__/EditorView.test.js.snap | ||
---|---|---|
"$blockScrolling": Infinity,
|
||
}
|
||
}
|
||
enableBasicAutocompletion={true}
|
||
enableBasicAutocompletion={false}
|
||
enableLiveAutocompletion={false}
|
||
focus={false}
|
||
fontSize={12}
|
||
... | ... | |
"$blockScrolling": Infinity,
|
||
}
|
||
}
|
||
enableBasicAutocompletion={true}
|
||
enableBasicAutocompletion={false}
|
||
enableLiveAutocompletion={false}
|
||
focus={false}
|
||
fontSize={12}
|
webpack/assets/javascripts/react_app/components/Editor/editor.scss | ||
---|---|---|
}
|
||
}
|
||
}
|
||
|
||
.ace_tooltip.ace_doc-tooltip {
|
||
position: absolute;
|
||
}
|
webpack/assets/javascripts/react_app/components/Editor/index.js | ||
---|---|---|
selectSearchQuery,
|
||
selectShowError,
|
||
selectTheme,
|
||
selectAutocompletion,
|
||
selectLiveAutocompletion,
|
||
selectValue,
|
||
} from './EditorSelectors';
|
||
|
||
... | ... | |
selectedView: selectChosenView(state),
|
||
showError: selectShowError(state),
|
||
theme: selectTheme(state),
|
||
autocompletion: selectAutocompletion(state),
|
||
liveAutocompletion: selectLiveAutocompletion(state),
|
||
value: selectValue(state),
|
||
});
|
||
|
Also available in: Unified diff
Revert "Fixes #32035 - Add DSL autocompletion in templates"
This reverts commit bde7047acb8a68a899f60585f751093c9713bb92.