Highlight edited fields

This commit is contained in:
Tulir Asokan 2018-12-08 13:29:53 +02:00
parent 4f7eef6029
commit d09dd8ddc6
6 changed files with 56 additions and 36 deletions

View File

@ -34,28 +34,32 @@ export const PrefTable = ({ children, wrapperClass }) => {
)
}
export const PrefRow = ({ name, fullWidth = false, labelFor = undefined, children }) => (
<div className={`entry ${fullWidth ? "full-width" : ""}`}>
<label htmlFor={labelFor}>{name}</label>
<div className="value">{children}</div>
</div>
)
export const PrefRow =
({ name, fullWidth = false, labelFor = undefined, changed = false, children }) => (
<div className={`entry ${fullWidth ? "full-width" : ""} ${changed ? "changed" : ""}`}>
<label htmlFor={labelFor}>{name}</label>
<div className="value">{children}</div>
</div>
)
export const PrefInput = ({ rowName, fullWidth = false, ...args }) => (
<PrefRow name={rowName} fullWidth={fullWidth} labelFor={rowName}>
<input {...args} id={rowName}/>
export const PrefInput = ({ rowName, value, origValue, fullWidth = false, ...args }) => (
<PrefRow name={rowName} fullWidth={fullWidth} labelFor={rowName}
changed={origValue !== undefined && value !== origValue}>
<input {...args} value={value} id={rowName}/>
</PrefRow>
)
export const PrefSwitch = ({ rowName, fullWidth = false, ...args }) => (
<PrefRow name={rowName} fullWidth={fullWidth} labelFor={rowName}>
<Switch {...args} id={rowName}/>
export const PrefSwitch = ({ rowName, active, origActive, fullWidth = false, ...args }) => (
<PrefRow name={rowName} fullWidth={fullWidth} labelFor={rowName}
changed={origActive !== undefined && active !== origActive}>
<Switch {...args} active={active} id={rowName}/>
</PrefRow>
)
export const PrefSelect = ({ rowName, fullWidth = false, ...args }) => (
<PrefRow name={rowName} fullWidth={fullWidth} labelFor={rowName}>
<Select className="select" {...args} id={rowName}/>
export const PrefSelect = ({ rowName, value, origValue, fullWidth = false, ...args }) => (
<PrefRow name={rowName} fullWidth={fullWidth} labelFor={rowName}
changed={origValue !== undefined && value.id !== origValue}>
<Select className="select" {...args} id={rowName} value={value}/>
</PrefRow>
)

View File

@ -34,7 +34,7 @@ class BaseMainView extends Component {
}
get isNew() {
return !this.props.entry
return !this.props.entry.id
}
inputChange = event => {

View File

@ -157,25 +157,31 @@ class Client extends BaseMainView {
renderPreferences = () => (
<PrefTable>
<PrefInput rowName="User ID" type="text" disabled={!this.isNew} fullWidth={true}
name={this.isNew ? "id" : ""} value={this.state.id} className="id"
name={this.isNew ? "id" : ""} className="id"
value={this.state.id} origValue={this.props.entry.id}
placeholder="@fancybot:example.com" onChange={this.inputChange}/>
<PrefInput rowName="Homeserver" type="text" name="homeserver"
value={this.state.homeserver} placeholder="https://example.com"
onChange={this.inputChange}/>
value={this.state.homeserver} origValue={this.props.entry.homeserver}
placeholder="https://example.com" onChange={this.inputChange}/>
<PrefInput rowName="Access token" type="text" name="access_token"
value={this.state.access_token} onChange={this.inputChange}
placeholder="MDAxYWxvY2F0aW9uIG1hdHJpeC5sb2NhbAowMDEzaWRlbnRpZmllc"/>
<PrefInput rowName="Display name" type="text" name="displayname"
value={this.state.displayname} placeholder="My fancy bot"
value={this.state.access_token} origValue={this.props.entry.access_token}
placeholder="MDAxYWxvY2F0aW9uIG1hdHJpeC5sb2NhbAowMDEzaWRlbnRpZmllc"
onChange={this.inputChange}/>
<PrefInput rowName="Display name" type="text" name="displayname"
value={this.state.displayname} origValue={this.props.entry.displayname}
placeholder="My fancy bot" onChange={this.inputChange}/>
<PrefInput rowName="Avatar URL" type="text" name="avatar_url"
value={this.state.avatar_url} onChange={this.inputChange}
placeholder="mxc://example.com/mbmwyoTvPhEQPiCskcUsppko"/>
<PrefSwitch rowName="Sync" active={this.state.sync}
value={this.state.avatar_url} origValue={this.props.entry.avatar_url}
placeholder="mxc://example.com/mbmwyoTvPhEQPiCskcUsppko"
onChange={this.inputChange}/>
<PrefSwitch rowName="Sync"
active={this.state.sync} origActive={this.props.entry.sync}
onToggle={sync => this.setState({ sync })}/>
<PrefSwitch rowName="Autojoin" active={this.state.autojoin}
<PrefSwitch rowName="Autojoin"
active={this.state.autojoin} origActive={this.props.entry.autojoin}
onToggle={autojoin => this.setState({ autojoin })}/>
<PrefSwitch rowName="Enabled" active={this.state.enabled}
<PrefSwitch rowName="Enabled"
active={this.state.enabled} origActive={this.props.entry.enabled}
onToggle={enabled => this.setState({
enabled,
started: enabled && this.state.started,

View File

@ -138,15 +138,18 @@ class Instance extends BaseMainView {
<PrefInput rowName="ID" type="text" name="id" value={this.state.id}
placeholder="fancybotinstance" onChange={this.inputChange}
disabled={!this.isNew} fullWidth={true} className="id"/>
<PrefSwitch rowName="Enabled" active={this.state.enabled}
<PrefSwitch rowName="Enabled"
active={this.state.enabled} origActive={this.props.entry.enabled}
onToggle={enabled => this.setState({ enabled })}/>
<PrefSwitch rowName="Running" active={this.state.started}
<PrefSwitch rowName="Running"
active={this.state.started} origActive={this.props.entry.started}
onToggle={started => this.setState({ started })}/>
<PrefSelect rowName="Primary user" options={this.clientOptions}
isSearchable={false} value={this.selectedClientEntry}
origValue={this.props.entry.primary_user}
onChange={({ id }) => this.setState({ primary_user: id })}/>
<PrefSelect rowName="Type" options={this.typeOptions} isSearchable={false}
value={this.selectedPluginEntry}
value={this.selectedPluginEntry} origValue={this.props.entry.type}
onChange={({ id }) => this.setState({ type: id })}/>
</PrefTable>
{!this.isNew &&

View File

@ -191,11 +191,13 @@ class Dashboard extends Component {
<Route path="/" exact render={() => <Home openLog={this.openLog}/>}/>
<Route path="/new/instance" render={() =>
<Instance onChange={newEntry => this.add("instances", newEntry)}
ctx={this.state}/>}/>
<Route path="/new/client" render={() => <Client
onChange={newEntry => this.add("clients", newEntry)}/>}/>
<Route path="/new/plugin" render={() => <Plugin
onChange={newEntry => this.add("plugins", newEntry)}/>}/>
entry={{}} ctx={this.state}/>}/>
<Route path="/new/client" render={() =>
<Client entry={{}} onChange={newEntry =>
this.add("clients", newEntry)}/>}/>
<Route path="/new/plugin" render={() =>
<Plugin entry={{}} onChange={newEntry =>
this.add("plugins", newEntry)}/>}/>
<Route path="/instance/:id" render={({ match }) =>
this.renderView("instances", Instance, match.params.id)}/>
<Route path="/client/:id" render={({ match }) =>

View File

@ -32,6 +32,11 @@
&.full-width
width: 100%
&.changed > label
font-weight: bold
&:after
content: "*"
> label, > .value
display: block
width: 100%