Improve design of management UI
This commit is contained in:
parent
15db7b95c3
commit
5220d2e5c9
17 changed files with 113 additions and 89 deletions
|
@ -17,8 +17,6 @@ rules:
|
||||||
- mq
|
- mq
|
||||||
no-warn: 1
|
no-warn: 1
|
||||||
no-debug: 1
|
no-debug: 1
|
||||||
no-ids: 2
|
|
||||||
no-important: 2
|
|
||||||
hex-notation:
|
hex-notation:
|
||||||
- 2
|
- 2
|
||||||
- style: uppercase
|
- style: uppercase
|
||||||
|
@ -26,8 +24,4 @@ rules:
|
||||||
- 2
|
- 2
|
||||||
- size: 4
|
- size: 4
|
||||||
property-sort-order:
|
property-sort-order:
|
||||||
- 1
|
- 0
|
||||||
- order:
|
|
||||||
- display
|
|
||||||
- margin
|
|
||||||
ignore-custom-properties: true
|
|
||||||
|
|
|
@ -17,18 +17,22 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.png">
|
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.png">
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="https://fonts.googleapis.com/css?family=Raleway:300,400,700">
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="https://cdn.jsdelivr.net/gh/tonsky/FiraCode@1.206/distr/fira_code.css">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<meta name="theme-color" content="#50D367">
|
<meta name="theme-color" content="#50D367">
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||||
<title>Maubot Manager</title>
|
<title>Maubot Manager</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>
|
<noscript>
|
||||||
You need to enable JavaScript to run this app.
|
You need to enable JavaScript to run this app.
|
||||||
</noscript>
|
</noscript>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -34,28 +34,28 @@ export const PrefTable = ({ children, wrapperClass }) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PrefRow = ({ name, children }) => (
|
export const PrefRow = ({ name, fullWidth = false, labelFor = undefined, children }) => (
|
||||||
<div className="row">
|
<div className={`entry ${fullWidth ? "full-width" : ""}`}>
|
||||||
<div className="key">{name}</div>
|
<label htmlFor={labelFor}>{name}</label>
|
||||||
<div className="value">{children}</div>
|
<div className="value">{children}</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
export const PrefInput = ({ rowName, ...args }) => (
|
export const PrefInput = ({ rowName, fullWidth = false, ...args }) => (
|
||||||
<PrefRow name={rowName}>
|
<PrefRow name={rowName} fullWidth={fullWidth} labelFor={rowName}>
|
||||||
<input {...args}/>
|
<input {...args} id={rowName}/>
|
||||||
</PrefRow>
|
</PrefRow>
|
||||||
)
|
)
|
||||||
|
|
||||||
export const PrefSwitch = ({ rowName, ...args }) => (
|
export const PrefSwitch = ({ rowName, fullWidth = false, ...args }) => (
|
||||||
<PrefRow name={rowName}>
|
<PrefRow name={rowName} fullWidth={fullWidth} labelFor={rowName}>
|
||||||
<Switch {...args}/>
|
<Switch {...args} id={rowName}/>
|
||||||
</PrefRow>
|
</PrefRow>
|
||||||
)
|
)
|
||||||
|
|
||||||
export const PrefSelect = ({ rowName, ...args }) => (
|
export const PrefSelect = ({ rowName, fullWidth = false, ...args }) => (
|
||||||
<PrefRow name={rowName}>
|
<PrefRow name={rowName} fullWidth={fullWidth} labelFor={rowName}>
|
||||||
<Select className="select" {...args}/>
|
<Select className="select" {...args} id={rowName}/>
|
||||||
</PrefRow>
|
</PrefRow>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ class Switch extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="switch" data-active={this.state.active} onClick={this.toggle}
|
<div className="switch" data-active={this.state.active} onClick={this.toggle}
|
||||||
tabIndex="0" onKeyPress={this.toggleKeyboard}>
|
tabIndex="0" onKeyPress={this.toggleKeyboard} id={this.props.id}>
|
||||||
<div className="box">
|
<div className="box">
|
||||||
<span className="text">
|
<span className="text">
|
||||||
<span className="on">{this.props.onText || "On"}</span>
|
<span className="on">{this.props.onText || "On"}</span>
|
||||||
|
|
|
@ -193,18 +193,18 @@ class Client extends Component {
|
||||||
|
|
||||||
renderPreferences = () => (
|
renderPreferences = () => (
|
||||||
<PrefTable>
|
<PrefTable>
|
||||||
<PrefInput rowName="User ID" type="text" disabled={!this.isNew}
|
<PrefInput rowName="User ID" type="text" disabled={!this.isNew} fullWidth={true}
|
||||||
name={!this.isNew ? "id" : ""} value={this.state.id}
|
name={!this.isNew ? "id" : ""} value={this.state.id}
|
||||||
placeholder="@fancybot:example.com" onChange={this.inputChange}/>
|
placeholder="@fancybot:example.com" onChange={this.inputChange}/>
|
||||||
<PrefInput rowName="Display name" type="text" name="displayname"
|
|
||||||
value={this.state.displayname} placeholder="My fancy bot"
|
|
||||||
onChange={this.inputChange}/>
|
|
||||||
<PrefInput rowName="Homeserver" type="text" name="homeserver"
|
<PrefInput rowName="Homeserver" type="text" name="homeserver"
|
||||||
value={this.state.homeserver} placeholder="https://example.com"
|
value={this.state.homeserver} placeholder="https://example.com"
|
||||||
onChange={this.inputChange}/>
|
onChange={this.inputChange}/>
|
||||||
<PrefInput rowName="Access token" type="text" name="access_token"
|
<PrefInput rowName="Access token" type="text" name="access_token"
|
||||||
value={this.state.access_token} onChange={this.inputChange}
|
value={this.state.access_token} onChange={this.inputChange}
|
||||||
placeholder="MDAxYWxvY2F0aW9uIG1hdHJpeC5sb2NhbAowMDEzaWRlbnRpZmllc"/>
|
placeholder="MDAxYWxvY2F0aW9uIG1hdHJpeC5sb2NhbAowMDEzaWRlbnRpZmllc"/>
|
||||||
|
<PrefInput rowName="Display name" type="text" name="displayname"
|
||||||
|
value={this.state.displayname} placeholder="My fancy bot"
|
||||||
|
onChange={this.inputChange}/>
|
||||||
<PrefInput rowName="Avatar URL" type="text" name="avatar_url"
|
<PrefInput rowName="Avatar URL" type="text" name="avatar_url"
|
||||||
value={this.state.avatar_url} onChange={this.inputChange}
|
value={this.state.avatar_url} onChange={this.inputChange}
|
||||||
placeholder="mxc://example.com/mbmwyoTvPhEQPiCskcUsppko"/>
|
placeholder="mxc://example.com/mbmwyoTvPhEQPiCskcUsppko"/>
|
||||||
|
|
|
@ -63,8 +63,8 @@ class Instance extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
this.setState(Object.assign(this.initialState, nextProps.instance), () =>
|
this.setState(Object.assign(this.initialState, nextProps.instance))
|
||||||
this.updateClientOptions())
|
this.updateClientOptions()
|
||||||
}
|
}
|
||||||
|
|
||||||
clientSelectEntry = client => client && {
|
clientSelectEntry = client => client && {
|
||||||
|
@ -127,7 +127,9 @@ class Instance extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
get selectedClientEntry() {
|
get selectedClientEntry() {
|
||||||
return this.clientSelectEntry(this.props.ctx.clients[this.state.primary_user])
|
return this.state.primary_user
|
||||||
|
? this.clientSelectEntry(this.props.ctx.clients[this.state.primary_user])
|
||||||
|
: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
get selectedPluginEntry() {
|
get selectedPluginEntry() {
|
||||||
|
@ -159,7 +161,7 @@ class Instance extends Component {
|
||||||
<PrefTable>
|
<PrefTable>
|
||||||
<PrefInput rowName="ID" type="text" name={"id"} value={this.state.id}
|
<PrefInput rowName="ID" type="text" name={"id"} value={this.state.id}
|
||||||
placeholder="fancybotinstance" onChange={this.inputChange}
|
placeholder="fancybotinstance" onChange={this.inputChange}
|
||||||
disabled={!this.isNew}/>
|
disabled={!this.isNew} fullWidth={true}/>
|
||||||
<PrefSwitch rowName="Enabled" active={this.state.enabled}
|
<PrefSwitch rowName="Enabled" active={this.state.enabled}
|
||||||
onToggle={enabled => this.setState({ enabled })}/>
|
onToggle={enabled => this.setState({ enabled })}/>
|
||||||
<PrefSwitch rowName="Running" active={this.state.started}
|
<PrefSwitch rowName="Running" active={this.state.started}
|
||||||
|
|
|
@ -90,10 +90,9 @@ class Dashboard extends Component {
|
||||||
<img src="/favicon.png" alt=""/>
|
<img src="/favicon.png" alt=""/>
|
||||||
Maubot Manager
|
Maubot Manager
|
||||||
</Link>
|
</Link>
|
||||||
<div className="topbar">
|
|
||||||
<div className="user">
|
<div className="user">
|
||||||
{localStorage.username}
|
<span>{localStorage.username}</span>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<nav className="sidebar">
|
<nav className="sidebar">
|
||||||
<div className="instances list">
|
<div className="instances list">
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
|
|
||||||
=main-color-button()
|
=main-color-button()
|
||||||
background-color: $primary
|
background-color: $primary
|
||||||
|
color: $inverted-text-color
|
||||||
&:hover:not(:disabled)
|
&:hover:not(:disabled)
|
||||||
background-color: $primary-dark
|
background-color: $primary-dark
|
||||||
|
|
||||||
|
@ -56,16 +57,15 @@
|
||||||
display: flex
|
display: flex
|
||||||
> button, > .button
|
> button, > .button
|
||||||
flex: 1
|
flex: 1
|
||||||
border-radius: 0
|
|
||||||
|
|
||||||
&:first-of-type
|
&:first-of-type
|
||||||
border-radius: .25rem 0 0 .25rem
|
margin-right: .5rem
|
||||||
|
|
||||||
&:last-of-type
|
&:last-of-type
|
||||||
border-radius: 0 .25rem .25rem 0
|
margin-left: .5rem
|
||||||
|
|
||||||
&:first-of-type:last-of-type
|
&:first-of-type:last-of-type
|
||||||
border-radius: .25rem
|
margin: 0
|
||||||
|
|
||||||
=vertical-button-group()
|
=vertical-button-group()
|
||||||
display: flex
|
display: flex
|
||||||
|
@ -106,6 +106,9 @@
|
||||||
.input, .textarea
|
.input, .textarea
|
||||||
+input
|
+input
|
||||||
|
|
||||||
|
input
|
||||||
|
font-family: $font-stack
|
||||||
|
|
||||||
=notification($border: $error-dark, $background: transparentize($error-light, 0.5))
|
=notification($border: $error-dark, $background: transparentize($error-light, 0.5))
|
||||||
padding: 1rem
|
padding: 1rem
|
||||||
border-radius: .25rem
|
border-radius: .25rem
|
||||||
|
|
|
@ -29,4 +29,4 @@ $text-color: #212121
|
||||||
$background: #FAFAFA
|
$background: #FAFAFA
|
||||||
$background-dark: #E7E7E7
|
$background-dark: #E7E7E7
|
||||||
$inverted-text-color: $background
|
$inverted-text-color: $background
|
||||||
$font-stack: sans-serif
|
$font-stack: Raleway, sans-serif
|
||||||
|
|
|
@ -15,23 +15,30 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
.preference-table
|
.preference-table
|
||||||
display: table
|
display: flex
|
||||||
|
|
||||||
width: 100%
|
width: 100%
|
||||||
|
|
||||||
> .row
|
flex-wrap: wrap
|
||||||
display: table-row
|
|
||||||
|
|
||||||
> .key, > .value
|
> .entry
|
||||||
display: table-cell
|
display: block
|
||||||
padding-bottom: .5rem
|
width: calc(50% - 1rem)
|
||||||
|
margin: .5rem
|
||||||
|
|
||||||
> .key
|
&.full-width
|
||||||
width: 7rem
|
width: 100%
|
||||||
|
|
||||||
|
> label, > .value
|
||||||
|
display: block
|
||||||
|
width: 100%
|
||||||
|
|
||||||
|
> label
|
||||||
|
font-size: 0.875rem
|
||||||
|
padding-bottom: .25rem
|
||||||
|
font-weight: lighter
|
||||||
|
|
||||||
> .value
|
> .value
|
||||||
margin: .5rem
|
|
||||||
|
|
||||||
> .switch
|
> .switch
|
||||||
width: auto
|
width: auto
|
||||||
height: 2rem
|
height: 2rem
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
cursor: pointer
|
cursor: pointer
|
||||||
|
|
||||||
border: 1px solid $primary
|
border: 1px solid $error-light
|
||||||
border-radius: .25rem
|
border-radius: .25rem
|
||||||
background-color: $background
|
background-color: $background
|
||||||
|
|
||||||
|
@ -37,9 +37,9 @@
|
||||||
transition: .5s
|
transition: .5s
|
||||||
text-align: center
|
text-align: center
|
||||||
|
|
||||||
color: $text-color
|
|
||||||
border-radius: .15rem 0 0 .15rem
|
border-radius: .15rem 0 0 .15rem
|
||||||
background-color: $primary
|
background-color: $error-light
|
||||||
|
color: $inverted-text-color
|
||||||
|
|
||||||
align-items: center
|
align-items: center
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
text-align: center
|
text-align: center
|
||||||
vertical-align: middle
|
vertical-align: middle
|
||||||
|
|
||||||
color: $text-color
|
color: $inverted-text-color
|
||||||
font-size: 1rem
|
font-size: 1rem
|
||||||
|
|
||||||
user-select: none
|
user-select: none
|
||||||
|
@ -63,7 +63,9 @@
|
||||||
|
|
||||||
|
|
||||||
&[data-active=true]
|
&[data-active=true]
|
||||||
|
border: 1px solid $primary
|
||||||
> .box
|
> .box
|
||||||
|
background-color: $primary
|
||||||
transform: translateX(100%)
|
transform: translateX(100%)
|
||||||
|
|
||||||
border-radius: 0 .15rem .15rem 0
|
border-radius: 0 .15rem .15rem 0
|
||||||
|
|
|
@ -16,13 +16,13 @@
|
||||||
|
|
||||||
> div.client
|
> div.client
|
||||||
display: flex
|
display: flex
|
||||||
margin: 2rem
|
margin: 2rem 4rem
|
||||||
|
|
||||||
|
|
||||||
> div.sidebar
|
> div.sidebar
|
||||||
vertical-align: top
|
vertical-align: top
|
||||||
text-align: center
|
text-align: center
|
||||||
width: 8rem
|
width: 8rem
|
||||||
|
margin-right: 1rem
|
||||||
|
|
||||||
> div
|
> div
|
||||||
margin-bottom: 1rem
|
margin-bottom: 1rem
|
||||||
|
@ -32,7 +32,6 @@
|
||||||
|
|
||||||
> div.info
|
> div.info
|
||||||
vertical-align: top
|
vertical-align: top
|
||||||
margin-left: 1rem
|
|
||||||
flex: 1
|
flex: 1
|
||||||
|
|
||||||
@import instances
|
@import instances
|
||||||
|
|
|
@ -15,15 +15,20 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
> div.instances
|
> div.instances
|
||||||
margin-top: 1rem
|
margin: 1rem 0
|
||||||
|
|
||||||
|
display: flex
|
||||||
|
flex-wrap: wrap
|
||||||
|
|
||||||
> h3
|
> h3
|
||||||
margin-bottom: .5rem
|
margin: .5rem
|
||||||
|
width: 100%
|
||||||
|
|
||||||
> a.instance
|
> a.instance
|
||||||
display: block
|
display: block
|
||||||
width: 100%
|
width: calc(50% - 1rem)
|
||||||
padding: .375rem .5rem
|
padding: .375rem .5rem
|
||||||
|
margin: .5rem
|
||||||
background-color: white
|
background-color: white
|
||||||
border-radius: .25rem
|
border-radius: .25rem
|
||||||
color: $text-color
|
color: $text-color
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
.dashboard {
|
.dashboard {
|
||||||
grid-template:
|
grid-template:
|
||||||
[row1-start] "title topbar" 3.5rem [row1-end]
|
[row1-start] "title main" 3.5rem [row1-end]
|
||||||
[row2-start] "sidebar main" auto [row2-end]
|
[row2-start] "user main" 2.5rem [row2-end]
|
||||||
|
[row3-start] "sidebar main" auto [row3-end]
|
||||||
/ 15rem auto;
|
/ 15rem auto;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
> a.title
|
> a.title
|
||||||
grid-area: title
|
grid-area: title
|
||||||
|
background-color: white
|
||||||
display: flex
|
display: flex
|
||||||
align-items: center
|
align-items: center
|
||||||
justify-content: center
|
justify-content: center
|
||||||
|
@ -35,37 +36,34 @@
|
||||||
color: $text-color
|
color: $text-color
|
||||||
text-decoration: none
|
text-decoration: none
|
||||||
|
|
||||||
background-color: white
|
|
||||||
border-right: 1px solid $primary
|
|
||||||
border-bottom: 1px solid $border-color
|
|
||||||
|
|
||||||
> img
|
> img
|
||||||
max-width: 2rem
|
max-width: 2rem
|
||||||
margin-right: .5rem
|
margin-right: .5rem
|
||||||
|
|
||||||
> div.topbar
|
> div.user
|
||||||
grid-area: topbar
|
grid-area: user
|
||||||
|
background-color: white
|
||||||
|
border-bottom: 1px solid $border-color
|
||||||
display: flex
|
display: flex
|
||||||
align-items: center
|
align-items: center
|
||||||
justify-content: right
|
justify-content: center
|
||||||
background-color: $primary
|
span
|
||||||
box-shadow: 0 .25rem .25rem rgba(0, 0, 0, .2)
|
display: flex
|
||||||
padding: .5rem 1rem
|
|
||||||
|
|
||||||
> div.user
|
|
||||||
display: inline-flex
|
|
||||||
align-items: center
|
align-items: center
|
||||||
height: 100%
|
justify-content: center
|
||||||
padding: 0 1rem
|
background-color: $primary
|
||||||
|
color: $inverted-text-color
|
||||||
|
margin: .375rem .5rem
|
||||||
|
width: 100%
|
||||||
|
height: calc(100% - .375rem)
|
||||||
box-sizing: border-box
|
box-sizing: border-box
|
||||||
background-color: $primary-dark
|
|
||||||
border-radius: .25rem
|
border-radius: .25rem
|
||||||
|
|
||||||
|
|
||||||
@import sidebar
|
@import sidebar
|
||||||
|
|
||||||
> main.view
|
> main.view
|
||||||
grid-area: main
|
grid-area: main
|
||||||
|
border-left: 1px solid $border-color
|
||||||
|
|
||||||
@import client/index
|
@import client/index
|
||||||
@import instance
|
@import instance
|
||||||
|
@ -74,6 +72,8 @@
|
||||||
div.buttons
|
div.buttons
|
||||||
+button-group
|
+button-group
|
||||||
display: flex
|
display: flex
|
||||||
|
margin: 1rem .5rem
|
||||||
|
width: calc(100% - 1rem)
|
||||||
|
|
||||||
div.error
|
div.error
|
||||||
+notification($error)
|
+notification($error)
|
||||||
|
@ -82,6 +82,12 @@
|
||||||
&:empty
|
&:empty
|
||||||
display: none
|
display: none
|
||||||
|
|
||||||
|
button.delete
|
||||||
|
background-color: $error-light !important
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color: $error !important
|
||||||
|
|
||||||
button.save, button.delete
|
button.save, button.delete
|
||||||
+button
|
+button
|
||||||
+main-color-button
|
+main-color-button
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
> div.instance
|
> div.instance
|
||||||
margin: 2rem
|
margin: 2rem 4rem
|
||||||
|
|
||||||
> div.preference-table
|
> div.preference-table
|
||||||
.select-client
|
.select-client
|
||||||
|
@ -28,8 +28,10 @@
|
||||||
margin-right: .5rem
|
margin-right: .5rem
|
||||||
|
|
||||||
> div.ace_editor
|
> div.ace_editor
|
||||||
|
z-index: 0
|
||||||
height: 15rem !important
|
height: 15rem !important
|
||||||
width: 100% !important
|
width: calc(100% - 1rem) !important
|
||||||
font-size: 14px
|
font-size: 12px
|
||||||
|
font-family: "Fira Code", monospace
|
||||||
|
|
||||||
margin-bottom: 1rem
|
margin: .75rem .5rem 1.5rem
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
grid-area: sidebar
|
grid-area: sidebar
|
||||||
background-color: white
|
background-color: white
|
||||||
|
|
||||||
border-right: 1px solid $border-color
|
|
||||||
padding: .5rem
|
padding: .5rem
|
||||||
|
|
||||||
overflow-y: auto
|
overflow-y: auto
|
||||||
|
@ -57,6 +56,7 @@
|
||||||
|
|
||||||
&.active
|
&.active
|
||||||
background-color: $primary
|
background-color: $primary
|
||||||
|
color: white
|
||||||
|
|
||||||
&.client
|
&.client
|
||||||
img.avatar
|
img.avatar
|
||||||
|
|
Loading…
Reference in a new issue