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
|
||||
no-warn: 1
|
||||
no-debug: 1
|
||||
no-ids: 2
|
||||
no-important: 2
|
||||
hex-notation:
|
||||
- 2
|
||||
- style: uppercase
|
||||
|
@ -26,8 +24,4 @@ rules:
|
|||
- 2
|
||||
- size: 4
|
||||
property-sort-order:
|
||||
- 1
|
||||
- order:
|
||||
- display
|
||||
- margin
|
||||
ignore-custom-properties: true
|
||||
- 0
|
||||
|
|
|
@ -17,18 +17,22 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||
-->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<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="theme-color" content="#50D367">
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||
<title>Maubot Manager</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
You need to enable JavaScript to run this app.
|
||||
</noscript>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
You need to enable JavaScript to run this app.
|
||||
</noscript>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -34,28 +34,28 @@ export const PrefTable = ({ children, wrapperClass }) => {
|
|||
)
|
||||
}
|
||||
|
||||
export const PrefRow = ({ name, children }) => (
|
||||
<div className="row">
|
||||
<div className="key">{name}</div>
|
||||
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 PrefInput = ({ rowName, ...args }) => (
|
||||
<PrefRow name={rowName}>
|
||||
<input {...args}/>
|
||||
export const PrefInput = ({ rowName, fullWidth = false, ...args }) => (
|
||||
<PrefRow name={rowName} fullWidth={fullWidth} labelFor={rowName}>
|
||||
<input {...args} id={rowName}/>
|
||||
</PrefRow>
|
||||
)
|
||||
|
||||
export const PrefSwitch = ({ rowName, ...args }) => (
|
||||
<PrefRow name={rowName}>
|
||||
<Switch {...args}/>
|
||||
export const PrefSwitch = ({ rowName, fullWidth = false, ...args }) => (
|
||||
<PrefRow name={rowName} fullWidth={fullWidth} labelFor={rowName}>
|
||||
<Switch {...args} id={rowName}/>
|
||||
</PrefRow>
|
||||
)
|
||||
|
||||
export const PrefSelect = ({ rowName, ...args }) => (
|
||||
<PrefRow name={rowName}>
|
||||
<Select className="select" {...args}/>
|
||||
export const PrefSelect = ({ rowName, fullWidth = false, ...args }) => (
|
||||
<PrefRow name={rowName} fullWidth={fullWidth} labelFor={rowName}>
|
||||
<Select className="select" {...args} id={rowName}/>
|
||||
</PrefRow>
|
||||
)
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ class Switch extends Component {
|
|||
render() {
|
||||
return (
|
||||
<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">
|
||||
<span className="text">
|
||||
<span className="on">{this.props.onText || "On"}</span>
|
||||
|
|
|
@ -193,18 +193,18 @@ class Client extends Component {
|
|||
|
||||
renderPreferences = () => (
|
||||
<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}
|
||||
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"
|
||||
value={this.state.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"
|
||||
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"/>
|
||||
|
|
|
@ -63,8 +63,8 @@ class Instance extends Component {
|
|||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
this.setState(Object.assign(this.initialState, nextProps.instance), () =>
|
||||
this.updateClientOptions())
|
||||
this.setState(Object.assign(this.initialState, nextProps.instance))
|
||||
this.updateClientOptions()
|
||||
}
|
||||
|
||||
clientSelectEntry = client => client && {
|
||||
|
@ -127,7 +127,9 @@ class Instance extends Component {
|
|||
}
|
||||
|
||||
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() {
|
||||
|
@ -159,7 +161,7 @@ class Instance extends Component {
|
|||
<PrefTable>
|
||||
<PrefInput rowName="ID" type="text" name={"id"} value={this.state.id}
|
||||
placeholder="fancybotinstance" onChange={this.inputChange}
|
||||
disabled={!this.isNew}/>
|
||||
disabled={!this.isNew} fullWidth={true}/>
|
||||
<PrefSwitch rowName="Enabled" active={this.state.enabled}
|
||||
onToggle={enabled => this.setState({ enabled })}/>
|
||||
<PrefSwitch rowName="Running" active={this.state.started}
|
||||
|
|
|
@ -90,10 +90,9 @@ class Dashboard extends Component {
|
|||
<img src="/favicon.png" alt=""/>
|
||||
Maubot Manager
|
||||
</Link>
|
||||
<div className="topbar">
|
||||
<div className="user">
|
||||
{localStorage.username}
|
||||
</div>
|
||||
|
||||
<div className="user">
|
||||
<span>{localStorage.username}</span>
|
||||
</div>
|
||||
<nav className="sidebar">
|
||||
<div className="instances list">
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
=main-color-button()
|
||||
background-color: $primary
|
||||
color: $inverted-text-color
|
||||
&:hover:not(:disabled)
|
||||
background-color: $primary-dark
|
||||
|
||||
|
@ -56,16 +57,15 @@
|
|||
display: flex
|
||||
> button, > .button
|
||||
flex: 1
|
||||
border-radius: 0
|
||||
|
||||
&:first-of-type
|
||||
border-radius: .25rem 0 0 .25rem
|
||||
margin-right: .5rem
|
||||
|
||||
&:last-of-type
|
||||
border-radius: 0 .25rem .25rem 0
|
||||
margin-left: .5rem
|
||||
|
||||
&:first-of-type:last-of-type
|
||||
border-radius: .25rem
|
||||
margin: 0
|
||||
|
||||
=vertical-button-group()
|
||||
display: flex
|
||||
|
@ -106,6 +106,9 @@
|
|||
.input, .textarea
|
||||
+input
|
||||
|
||||
input
|
||||
font-family: $font-stack
|
||||
|
||||
=notification($border: $error-dark, $background: transparentize($error-light, 0.5))
|
||||
padding: 1rem
|
||||
border-radius: .25rem
|
||||
|
|
|
@ -29,4 +29,4 @@ $text-color: #212121
|
|||
$background: #FAFAFA
|
||||
$background-dark: #E7E7E7
|
||||
$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/>.
|
||||
|
||||
.preference-table
|
||||
display: table
|
||||
display: flex
|
||||
|
||||
width: 100%
|
||||
|
||||
> .row
|
||||
display: table-row
|
||||
flex-wrap: wrap
|
||||
|
||||
> .key, > .value
|
||||
display: table-cell
|
||||
padding-bottom: .5rem
|
||||
> .entry
|
||||
display: block
|
||||
width: calc(50% - 1rem)
|
||||
margin: .5rem
|
||||
|
||||
> .key
|
||||
width: 7rem
|
||||
&.full-width
|
||||
width: 100%
|
||||
|
||||
> label, > .value
|
||||
display: block
|
||||
width: 100%
|
||||
|
||||
> label
|
||||
font-size: 0.875rem
|
||||
padding-bottom: .25rem
|
||||
font-weight: lighter
|
||||
|
||||
> .value
|
||||
margin: .5rem
|
||||
|
||||
> .switch
|
||||
width: auto
|
||||
height: 2rem
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
cursor: pointer
|
||||
|
||||
border: 1px solid $primary
|
||||
border: 1px solid $error-light
|
||||
border-radius: .25rem
|
||||
background-color: $background
|
||||
|
||||
|
@ -37,9 +37,9 @@
|
|||
transition: .5s
|
||||
text-align: center
|
||||
|
||||
color: $text-color
|
||||
border-radius: .15rem 0 0 .15rem
|
||||
background-color: $primary
|
||||
background-color: $error-light
|
||||
color: $inverted-text-color
|
||||
|
||||
align-items: center
|
||||
|
||||
|
@ -50,7 +50,7 @@
|
|||
text-align: center
|
||||
vertical-align: middle
|
||||
|
||||
color: $text-color
|
||||
color: $inverted-text-color
|
||||
font-size: 1rem
|
||||
|
||||
user-select: none
|
||||
|
@ -63,7 +63,9 @@
|
|||
|
||||
|
||||
&[data-active=true]
|
||||
border: 1px solid $primary
|
||||
> .box
|
||||
background-color: $primary
|
||||
transform: translateX(100%)
|
||||
|
||||
border-radius: 0 .15rem .15rem 0
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
|
||||
> div.client
|
||||
display: flex
|
||||
margin: 2rem
|
||||
|
||||
margin: 2rem 4rem
|
||||
|
||||
> div.sidebar
|
||||
vertical-align: top
|
||||
text-align: center
|
||||
width: 8rem
|
||||
margin-right: 1rem
|
||||
|
||||
> div
|
||||
margin-bottom: 1rem
|
||||
|
@ -32,7 +32,6 @@
|
|||
|
||||
> div.info
|
||||
vertical-align: top
|
||||
margin-left: 1rem
|
||||
flex: 1
|
||||
|
||||
@import instances
|
||||
|
|
|
@ -15,15 +15,20 @@
|
|||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
> div.instances
|
||||
margin-top: 1rem
|
||||
margin: 1rem 0
|
||||
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
|
||||
> h3
|
||||
margin-bottom: .5rem
|
||||
margin: .5rem
|
||||
width: 100%
|
||||
|
||||
> a.instance
|
||||
display: block
|
||||
width: 100%
|
||||
width: calc(50% - 1rem)
|
||||
padding: .375rem .5rem
|
||||
margin: .5rem
|
||||
background-color: white
|
||||
border-radius: .25rem
|
||||
color: $text-color
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
.dashboard {
|
||||
grid-template:
|
||||
[row1-start] "title topbar" 3.5rem [row1-end]
|
||||
[row2-start] "sidebar main" auto [row2-end]
|
||||
[row1-start] "title main" 3.5rem [row1-end]
|
||||
[row2-start] "user main" 2.5rem [row2-end]
|
||||
[row3-start] "sidebar main" auto [row3-end]
|
||||
/ 15rem auto;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
> a.title
|
||||
grid-area: title
|
||||
background-color: white
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
|
@ -35,37 +36,34 @@
|
|||
color: $text-color
|
||||
text-decoration: none
|
||||
|
||||
background-color: white
|
||||
border-right: 1px solid $primary
|
||||
border-bottom: 1px solid $border-color
|
||||
|
||||
> img
|
||||
max-width: 2rem
|
||||
margin-right: .5rem
|
||||
|
||||
> div.topbar
|
||||
grid-area: topbar
|
||||
> div.user
|
||||
grid-area: user
|
||||
background-color: white
|
||||
border-bottom: 1px solid $border-color
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: right
|
||||
background-color: $primary
|
||||
box-shadow: 0 .25rem .25rem rgba(0, 0, 0, .2)
|
||||
padding: .5rem 1rem
|
||||
|
||||
> div.user
|
||||
display: inline-flex
|
||||
justify-content: center
|
||||
span
|
||||
display: flex
|
||||
align-items: center
|
||||
height: 100%
|
||||
padding: 0 1rem
|
||||
justify-content: center
|
||||
background-color: $primary
|
||||
color: $inverted-text-color
|
||||
margin: .375rem .5rem
|
||||
width: 100%
|
||||
height: calc(100% - .375rem)
|
||||
box-sizing: border-box
|
||||
background-color: $primary-dark
|
||||
border-radius: .25rem
|
||||
|
||||
|
||||
@import sidebar
|
||||
|
||||
> main.view
|
||||
grid-area: main
|
||||
border-left: 1px solid $border-color
|
||||
|
||||
@import client/index
|
||||
@import instance
|
||||
|
@ -74,6 +72,8 @@
|
|||
div.buttons
|
||||
+button-group
|
||||
display: flex
|
||||
margin: 1rem .5rem
|
||||
width: calc(100% - 1rem)
|
||||
|
||||
div.error
|
||||
+notification($error)
|
||||
|
@ -82,6 +82,12 @@
|
|||
&:empty
|
||||
display: none
|
||||
|
||||
button.delete
|
||||
background-color: $error-light !important
|
||||
|
||||
&:hover
|
||||
background-color: $error !important
|
||||
|
||||
button.save, button.delete
|
||||
+button
|
||||
+main-color-button
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
> div.instance
|
||||
margin: 2rem
|
||||
margin: 2rem 4rem
|
||||
|
||||
> div.preference-table
|
||||
.select-client
|
||||
|
@ -28,8 +28,10 @@
|
|||
margin-right: .5rem
|
||||
|
||||
> div.ace_editor
|
||||
z-index: 0
|
||||
height: 15rem !important
|
||||
width: 100% !important
|
||||
font-size: 14px
|
||||
width: calc(100% - 1rem) !important
|
||||
font-size: 12px
|
||||
font-family: "Fira Code", monospace
|
||||
|
||||
margin-bottom: 1rem
|
||||
margin: .75rem .5rem 1.5rem
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
grid-area: sidebar
|
||||
background-color: white
|
||||
|
||||
border-right: 1px solid $border-color
|
||||
padding: .5rem
|
||||
|
||||
overflow-y: auto
|
||||
|
@ -57,6 +56,7 @@
|
|||
|
||||
&.active
|
||||
background-color: $primary
|
||||
color: white
|
||||
|
||||
&.client
|
||||
img.avatar
|
||||
|
|
Loading…
Reference in a new issue