Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

user can edit keys and values #233

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/js/components/DataTypes/Object.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import {polyfill} from 'react-lifecycles-compat';
import { toType } from './../../helpers/util';
import dispatcher from './../../helpers/dispatcher';

//data type components
import { JsonObject } from './DataTypes';
Expand All @@ -15,6 +16,7 @@ import AttributeStore from './../../stores/ObjectAttributes';

//icons
import { CollapsedIcon, ExpandedIcon } from './../ToggleIcons';
import { Edit } from './../icons';

//theme
import Theme from './../../themes/getStyle';
Expand Down Expand Up @@ -130,6 +132,32 @@ class RjvObject extends React.PureComponent {
return <VariableMeta size={size} {...this.props} />;
}

getEditIcon = () => {
const { theme, name, namespace, src, rjvId } = this.props;
return (
<div class="click-to-edit" style={{ verticalAlign: 'top' }} title={"Edit Key"}>
<Edit
class="click-to-edit-icon"
{...Theme(theme, 'editVarIcon')}
onClick={(e) => {
e.stopPropagation();
dispatcher.dispatch({
name: 'UPDATE_VARIABLE_KEY_REQUEST',
rjvId: rjvId,
data: {
name,
namespace: namespace.splice(0, namespace.length -1),
existing_value: src,
_removed: false,
key_name: name
}
});
}}
/>
</div>
);
}

getBraceStart(object_type, expanded) {
const { src, theme, iconStyle, parent_type } = this.props;

Expand All @@ -154,6 +182,7 @@ class RjvObject extends React.PureComponent {
}}
{...Theme(theme, 'brace-row')}
>
{this.getEditIcon()}
<div
class="icon-container"
{...Theme(theme, 'icon-container')}
Expand Down
1 change: 0 additions & 1 deletion src/js/components/ObjectKeyModal/AddKeyRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ export default class extends React.PureComponent {
);
return (
input != ''
&& Object.keys(request.existing_value).indexOf(input) === -1
);
}

Expand Down
52 changes: 52 additions & 0 deletions src/js/components/ObjectKeyModal/EditKeyRequest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React from 'react';
import dispatcher from './../../helpers/dispatcher';
import ObjectAttributes from './../../stores/ObjectAttributes';
import ObjectKeyModal from './ObjectKeyModal';

//global theme
import Theme from './../../themes/getStyle';


//this input appears when adding a new value to an object
export default class extends React.PureComponent {

render() {
const {active, theme, rjvId } = this.props;
const { name } = ObjectAttributes.get(rjvId, 'action', 'edit-key-request') || {};

return active ? (
<ObjectKeyModal
rjvId={rjvId}
theme={theme}
input={name}
isValid={this.isValid}
submit={this.submit}
/>
) : null;
}

isValid = (input) => {
const {rjvId} = this.props;
const request = ObjectAttributes.get(
rjvId, 'action', 'edit-key-request'
);
return (
input != ''
);
}

submit = (input) => {
const { rjvId } = this.props;
let request = ObjectAttributes.get(
rjvId, 'action', 'edit-key-request'
);
request.key_name = input;
request.new_value = request.existing_value;
request.variable_key_updated = true;
dispatcher.dispatch({
name: 'VARIABLE_KEY_UPDATED',
rjvId: rjvId,
data: request
});
}
}
6 changes: 5 additions & 1 deletion src/js/components/ObjectKeyModal/ObjectKeyModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@ export default class extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
input: props.input ? props.input : ''
input: ''
};
}

componentDidMount() {
this.setState({ input: this.props.input });
}

render() {
const {theme, rjvId, isValid} = this.props;
const {input} = this.state;
Expand Down
31 changes: 30 additions & 1 deletion src/js/components/VariableEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ class VariableEditor extends React.PureComponent {
class="variable-row"
key={variable.name}
>
{isNaN(Number(variable.name)) && onEdit !== false && editMode == false
? this.getEditKeyIcon()
: null}
{type == 'array' ? (
<span
{...Theme(theme, 'array-key')}
Expand Down Expand Up @@ -136,7 +139,7 @@ class VariableEditor extends React.PureComponent {
const { variable, theme } = this.props;

return (
<div class="click-to-edit" style={{ verticalAlign: 'top' }}>
<div class="click-to-edit" style={{ verticalAlign: 'top' }} title={"Edit Value"}>
<Edit
class="click-to-edit-icon"
{...Theme(theme, 'editVarIcon')}
Expand All @@ -148,6 +151,32 @@ class VariableEditor extends React.PureComponent {
);
}

getEditKeyIcon = () => {
const { variable: { name, value }, theme, namespace, rjvId } = this.props;
return (
<div class="click-to-edit" style={{ verticalAlign: 'top' }} title={"Edit Key"}>
<Edit
class="click-to-edit-icon"
{...Theme(theme, 'editVarIcon')}
onClick={(e) => {
e.stopPropagation();
dispatcher.dispatch({
name: 'UPDATE_VARIABLE_KEY_REQUEST',
rjvId: rjvId,
data: {
name,
namespace: namespace,
existing_value: value,
variable_removed: false,
key_name: name
}
});
}}
/>
</div>
);
}

prepopInput = variable => {
if (this.props.onEdit !== false) {
const stringifiedValue = stringifyVariable(variable.value);
Expand Down
32 changes: 25 additions & 7 deletions src/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import {polyfill} from 'react-lifecycles-compat';
import JsonViewer from './components/JsonViewer';
import AddKeyRequest from './components/ObjectKeyModal/AddKeyRequest';
import EditKeyRequest from './components/ObjectKeyModal/EditKeyRequest';
import ValidationFailure from './components/ValidationFailure';
import {toType, isTheme} from './helpers/util';
import ObjectAttributes from './stores/ObjectAttributes';
Expand Down Expand Up @@ -139,7 +140,8 @@ class ReactJsonView extends React.PureComponent {
return {
'reset': this.resetState,
'variable-update': this.updateSrc,
'add-key-request': this.addKeyRequest
'add-key-request': this.addKeyRequest,
'edit-key-request': this.editKeyRequest
};
}
//make sure props are passed in as expected
Expand Down Expand Up @@ -182,6 +184,7 @@ class ReactJsonView extends React.PureComponent {
validationFailure,
validationMessage,
addKeyRequest,
editKeyRequest,
theme,
src,
name
Expand Down Expand Up @@ -211,6 +214,11 @@ class ReactJsonView extends React.PureComponent {
theme={theme}
rjvId={this.rjvId}
defaultValue={defaultValue} />
<EditKeyRequest
active={editKeyRequest}
theme={theme}
rjvId={this.rjvId}
defaultValue={defaultValue} />
</div>
);
}
Expand All @@ -230,17 +238,20 @@ class ReactJsonView extends React.PureComponent {

const on_edit_payload = {
existing_src: src,
new_value: new_value,
updated_src: updated_src,
name: name,
namespace: namespace,
existing_value: existing_value,
new_value,
updated_src,
name,
namespace,
existing_value,
};

switch (type) {
case 'variable-added':
result = onAdd(on_edit_payload);
break;
case 'variable-update-key':
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a mismatch with this.set(rjvId, 'action', 'variable-update',{...data, type:'variable-key-added'}); in Object attributes line 70. Is this intended?

result = onEdit(on_edit_payload);
break;
case 'variable-edited':
result = onEdit(on_edit_payload);
break;
Expand All @@ -267,10 +278,17 @@ class ReactJsonView extends React.PureComponent {
});
}

editKeyRequest = () => {
this.setState({
editKeyRequest: true
});
}

resetState = () => {
this.setState({
validationFailure: false,
addKeyRequest: false
addKeyRequest: false,
editKeyRequest: false
});
}
}
Expand Down
26 changes: 22 additions & 4 deletions src/js/stores/ObjectAttributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,27 @@ class ObjectAttributes extends EventEmitter {
);
this.emit('variable-update-' + rjvId);
break;
case 'VARIABLE_KEY_UPDATED':
action.data.updated_src = this.updateSrc(
rjvId, data
);
this.set(rjvId, 'action', 'variable-update',{...data, type:'variable-key-added'});
this.emit('variable-update-' + rjvId);
break;
case 'ADD_VARIABLE_KEY_REQUEST':
this.set(rjvId, 'action', 'new-key-request', data);
this.emit('add-key-request-' + rjvId);
break;
case 'UPDATE_VARIABLE_KEY_REQUEST':
this.set(rjvId, 'action', 'edit-key-request', data);
this.emit('edit-key-request-' + rjvId);
break;
}
}

updateSrc = (rjvId, request) => {
let {
name, namespace, new_value, existing_value, variable_removed
name, namespace, new_value, existing_value, variable_key_updated, variable_removed, key_name
} = request;

namespace.shift();
Expand All @@ -88,19 +99,26 @@ class ObjectAttributes extends EventEmitter {
walk = walk[idx];
}


if (variable_removed) {
if(variable_key_updated) {
if (toType(walk) == 'array') {
walk.splice(name, 1);
} else {
walk[key_name] = existing_value;
delete walk[name];
}
} else if (variable_removed) {
if (toType(walk) == 'array') {
walk.splice(name, 1);
} else {
if(walk) delete walk[name];
}
} else {
//update copied variable at specified namespace
if (name !== null) {
walk[name] = new_value;
} else {
updated_src = new_value;
walk[new_value] = existing_value;
//updated_src = new_value;
}
}

Expand Down
5 changes: 4 additions & 1 deletion src/style/scss/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
}

.object-key-val {
&:hover > span > .object-meta-data {
&:hover > span > .object-meta-data, &:hover > span > span {
& > .copy-to-clipboard-container {
display: inline-block;
}
Expand All @@ -24,6 +24,9 @@
& > .click-to-remove {
display: inline-block;
}
& > .click-to-edit {
display: inline-block;
}
}
}

Expand Down
38 changes: 38 additions & 0 deletions test/tests/js/components/ObjectKeyModal/EditKeyRequest-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from "react"
import { shallow, render, mount } from "enzyme"
import { expect } from "chai"

import EditKeyRequest from "./../../../../../src/js/components/ObjectKeyModal/EditKeyRequest"
import ObjectAttributes from "./../../../../../src/js/stores/ObjectAttributes"

describe("<EditKeyRequest />", function() {
const rjvId = 1

it("EditKeyRequest should not render input when inactive", function() {
ObjectAttributes.set(rjvId, "action", "new-key-request", {
existing_value: { test: true },
namespace: [],
new_value: { test: null }
})
ObjectAttributes.set(rjvId, "global", "src", { test: true })
const wrapper = mount(
<EditKeyRequest active={false} theme="rjv-default" rjvId={rjvId} />
)

expect(wrapper.find(".key-modal-input").length).to.equal(0)
})

it("EditKeyRequest should render input when active", function() {
ObjectAttributes.set(rjvId, "action", "new-key-request", {
existing_value: { test: true },
namespace: [],
new_value: { test: null }
})
ObjectAttributes.set(rjvId, "global", "src", { test: true })
const wrapper = mount(
<EditKeyRequest active={true} theme="rjv-default" rjvId={rjvId} />
)

expect(wrapper.find(".key-modal-input").length).to.equal(1)
})
})