fix(ui): fix layout of list & pane (#66)
* fix(ui): refine pane layout * fix(test): add pane_admin component
This commit is contained in:
parent
df46915147
commit
916ec7c2dc
10 changed files with 294 additions and 46 deletions
|
@ -73,17 +73,6 @@ img {
|
|||
max-width: 100%;
|
||||
}
|
||||
|
||||
p,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
text-align: left;
|
||||
padding: 1rem 0;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
.container-center {
|
||||
margin: 2rem auto auto auto;
|
||||
width: 96%;
|
||||
max-width: 800px;
|
||||
max-width: 80rem;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@
|
|||
}
|
||||
|
||||
#panes .container {
|
||||
max-width: 960px;
|
||||
max-width: 80rem;
|
||||
width: 96%;
|
||||
background-color: white;
|
||||
z-index: 101;
|
||||
|
@ -629,4 +629,8 @@ div.hr {
|
|||
|
||||
.breadcrumb {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.txt-cap {
|
||||
text-transform: capitalize;
|
||||
}
|
|
@ -2,6 +2,13 @@ import axios, { AxiosRequestConfig } from "axios";
|
|||
|
||||
export const defaultTimeout = 10000;
|
||||
|
||||
export interface User {
|
||||
ID: string;
|
||||
Name: string;
|
||||
Pwd: string;
|
||||
Role: string;
|
||||
}
|
||||
|
||||
export interface MetadataResp {
|
||||
name: string;
|
||||
size: number;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { List, Set } from "immutable";
|
||||
import { List, Set, Map } from "immutable";
|
||||
|
||||
import BgWorker from "../worker/upload.bg.worker";
|
||||
import { FgWorker } from "../worker/upload.fgworker";
|
||||
|
||||
import { Props as PanelProps } from "./root_frame";
|
||||
import { Item } from "./browser";
|
||||
import { UploadInfo } from "../client";
|
||||
import { UploadInfo, User } from "../client";
|
||||
import { Up, initUploadMgr, IWorker } from "../worker/upload_mgr";
|
||||
|
||||
export class BaseUpdater {
|
||||
|
@ -66,6 +66,10 @@ export function initState(): ICoreState {
|
|||
authed: false,
|
||||
},
|
||||
},
|
||||
admin: {
|
||||
users: Map<string, User>(),
|
||||
roles: Set<string>()
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -94,6 +98,10 @@ export function mockState(): ICoreState {
|
|||
authed: false,
|
||||
},
|
||||
},
|
||||
admin: {
|
||||
users: Map<string, User>(),
|
||||
roles: Set<string>()
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
178
src/client/web/src/components/pane_admin.tsx
Normal file
178
src/client/web/src/components/pane_admin.tsx
Normal file
|
@ -0,0 +1,178 @@
|
|||
import * as React from "react";
|
||||
import { Map, Set } from "immutable";
|
||||
|
||||
import { ICoreState } from "./core_state";
|
||||
import { IUsersClient, User} from "../client";
|
||||
import { UsersClient } from "../client/users";
|
||||
import { Updater as PanesUpdater } from "./panes";
|
||||
import { updater as BrowserUpdater } from "./browser.updater";
|
||||
import { Layouter } from "./layouter";
|
||||
|
||||
export interface Props {
|
||||
users: Map<string, User>;
|
||||
roles: Set<string>;
|
||||
update?: (updater: (prevState: ICoreState) => ICoreState) => void;
|
||||
}
|
||||
|
||||
export class Updater {
|
||||
private static props: Props;
|
||||
private static client: IUsersClient;
|
||||
|
||||
static init = (props: Props) => (Updater.props = { ...props });
|
||||
|
||||
static setClient = (client: IUsersClient): void => {
|
||||
Updater.client = client;
|
||||
};
|
||||
|
||||
// static adduser = async (user: User): Promise<boolean> => {
|
||||
// const resp = await Updater.client.add
|
||||
// }
|
||||
|
||||
// static login = async (user: string, pwd: string): Promise<boolean> => {
|
||||
// const resp = await Updater.client.login(user, pwd);
|
||||
// Updater.setAuthed(resp.status === 200);
|
||||
// return resp.status === 200;
|
||||
// };
|
||||
|
||||
// static logout = async (): Promise<boolean> => {
|
||||
// const resp = await Updater.client.logout();
|
||||
// Updater.setAuthed(false);
|
||||
// return resp.status === 200;
|
||||
// };
|
||||
|
||||
// static isAuthed = async (): Promise<boolean> => {
|
||||
// const resp = await Updater.client.isAuthed();
|
||||
// return resp.status === 200;
|
||||
// };
|
||||
|
||||
// static initIsAuthed = async (): Promise<void> => {
|
||||
// return Updater.isAuthed().then((isAuthed) => {
|
||||
// Updater.setAuthed(isAuthed);
|
||||
// });
|
||||
// };
|
||||
|
||||
static setState = (preState: ICoreState): ICoreState => {
|
||||
preState.panel.authPane = {
|
||||
...preState.panel.authPane,
|
||||
...Updater.props,
|
||||
};
|
||||
return preState;
|
||||
};
|
||||
}
|
||||
|
||||
// export interface State {
|
||||
// user: string;
|
||||
// pwd: string;
|
||||
// }
|
||||
|
||||
// export class AuthPane extends React.Component<Props, State, {}> {
|
||||
// private update: (updater: (prevState: ICoreState) => ICoreState) => void;
|
||||
// constructor(p: Props) {
|
||||
// super(p);
|
||||
// Updater.init(p);
|
||||
// Updater.setClient(new UsersClient(""));
|
||||
// this.update = p.update;
|
||||
// this.state = {
|
||||
// user: "",
|
||||
// pwd: "",
|
||||
// };
|
||||
|
||||
// this.initIsAuthed();
|
||||
// }
|
||||
|
||||
// changeUser = (ev: React.ChangeEvent<HTMLInputElement>) => {
|
||||
// this.setState({ user: ev.target.value });
|
||||
// };
|
||||
|
||||
// changePwd = (ev: React.ChangeEvent<HTMLInputElement>) => {
|
||||
// this.setState({ pwd: ev.target.value });
|
||||
// };
|
||||
|
||||
// initIsAuthed = () => {
|
||||
// Updater.initIsAuthed().then(() => {
|
||||
// this.update(Updater.setAuthPane);
|
||||
// });
|
||||
// };
|
||||
|
||||
// login = () => {
|
||||
// Updater.login(this.state.user, this.state.pwd)
|
||||
// .then((ok: boolean) => {
|
||||
// if (ok) {
|
||||
// this.update(Updater.setAuthPane);
|
||||
// this.setState({ user: "", pwd: "" });
|
||||
// // close all the panes
|
||||
// PanesUpdater.displayPane("");
|
||||
// this.update(PanesUpdater.updateState);
|
||||
|
||||
// // refresh
|
||||
// return BrowserUpdater().setHomeItems();
|
||||
// } else {
|
||||
// this.setState({ user: "", pwd: "" });
|
||||
// alert("Failed to login.");
|
||||
// }
|
||||
// })
|
||||
// .then(() => {
|
||||
// return BrowserUpdater().refreshUploadings();
|
||||
// })
|
||||
// .then((_: boolean) => {
|
||||
// this.update(BrowserUpdater().setBrowser);
|
||||
// });
|
||||
// };
|
||||
|
||||
// logout = () => {
|
||||
// Updater.logout().then((ok: boolean) => {
|
||||
// if (ok) {
|
||||
// this.update(Updater.setAuthPane);
|
||||
// } else {
|
||||
// alert("Failed to logout.");
|
||||
// }
|
||||
// });
|
||||
// };
|
||||
|
||||
// render() {
|
||||
// const elements: Array<JSX.Element> = [
|
||||
// <input
|
||||
// name="user"
|
||||
// type="text"
|
||||
// onChange={this.changeUser}
|
||||
// value={this.state.user}
|
||||
// className="black0-font margin-t-m margin-b-m"
|
||||
// // style={{ width: "80%" }}
|
||||
// placeholder="user name"
|
||||
// />,
|
||||
// <input
|
||||
// name="pwd"
|
||||
// type="password"
|
||||
// onChange={this.changePwd}
|
||||
// value={this.state.pwd}
|
||||
// className="black0-font margin-t-m margin-b-m"
|
||||
// // style={{ width: "80%" }}
|
||||
// placeholder="password"
|
||||
// />,
|
||||
// <button
|
||||
// onClick={this.login}
|
||||
// className="green0-bg white-font margin-t-m margin-b-m"
|
||||
// >
|
||||
// Log in
|
||||
// </button>,
|
||||
// ];
|
||||
|
||||
// return (
|
||||
// <span>
|
||||
// <div
|
||||
// className="margin-l-l"
|
||||
// style={{ display: this.props.authed ? "none" : "block" }}
|
||||
// >
|
||||
// {/* <h5 className="black-font">Login</h5> */}
|
||||
// <Layouter isHorizontal={false} elements={elements} />
|
||||
// </div>
|
||||
|
||||
// <span style={{ display: this.props.authed ? "inherit" : "none" }}>
|
||||
// <button onClick={this.logout} className="grey1-bg white-font">
|
||||
// Log out
|
||||
// </button>
|
||||
// </span>
|
||||
// </span>
|
||||
// );
|
||||
// }
|
||||
// }
|
|
@ -158,15 +158,16 @@ export class AuthPane extends React.Component<Props, State, {}> {
|
|||
|
||||
return (
|
||||
<span>
|
||||
<span style={{ display: this.props.authed ? "none" : "inherit" }}>
|
||||
<h5 className="grey0-font">Login</h5>
|
||||
<div
|
||||
className="margin-l-l"
|
||||
style={{ display: this.props.authed ? "none" : "block" }}
|
||||
>
|
||||
{/* <h5 className="black-font">Login</h5> */}
|
||||
<Layouter isHorizontal={false} elements={elements} />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<span style={{ display: this.props.authed ? "inherit" : "none" }}>
|
||||
<button
|
||||
onClick={this.logout}
|
||||
className="grey1-bg white-font margin-r-m"
|
||||
>
|
||||
<button onClick={this.logout} className="grey1-bg white-font">
|
||||
Log out
|
||||
</button>
|
||||
</span>
|
||||
|
|
|
@ -76,7 +76,7 @@ export class PaneSettings extends React.Component<Props, State, {}> {
|
|||
if (ok) {
|
||||
alert("Password is updated");
|
||||
} else {
|
||||
alert("fail to update password");
|
||||
alert("Failed to update password");
|
||||
}
|
||||
this.setState({
|
||||
oldPwd: "",
|
||||
|
@ -120,12 +120,61 @@ export class PaneSettings extends React.Component<Props, State, {}> {
|
|||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h5 className="grey0-font">Update Password</h5>
|
||||
<Layouter isHorizontal={false} elements={inputs}></Layouter>
|
||||
<div className="hr"></div>
|
||||
<div className="padding-l">
|
||||
<div>
|
||||
<div className="flex-list-container">
|
||||
<div className="flex-list-item-l">
|
||||
<h5 className="black-font">Update Password</h5>
|
||||
</div>
|
||||
<div className="flex-list-item-r">
|
||||
<button onClick={this.setPwd} className="grey1-bg white-font">
|
||||
Update
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<AuthPane authed={this.props.login.authed} update={this.update} />
|
||||
<div>
|
||||
<input
|
||||
name="old_pwd"
|
||||
type="password"
|
||||
onChange={this.changeOldPwd}
|
||||
value={this.state.oldPwd}
|
||||
className="black0-font margin-t-m margin-b-m"
|
||||
placeholder="old password"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
name="new_pwd1"
|
||||
type="password"
|
||||
onChange={this.changeNewPwd1}
|
||||
value={this.state.newPwd1}
|
||||
className="black0-font margin-t-m margin-b-m margin-r-m"
|
||||
placeholder="new password"
|
||||
/>
|
||||
<input
|
||||
name="new_pwd2"
|
||||
type="password"
|
||||
onChange={this.changeNewPwd2}
|
||||
value={this.state.newPwd2}
|
||||
className="black0-font margin-t-m margin-b-m"
|
||||
placeholder="new password again"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="hr white0-bg margin-t-m margin-b-m"></div>
|
||||
|
||||
<div>
|
||||
<div className="flex-list-container">
|
||||
<div className="flex-list-item-l">
|
||||
<h5 className="black-font">Logout</h5>
|
||||
</div>
|
||||
<div className="flex-list-item-r">
|
||||
<AuthPane authed={this.props.login.authed} update={this.update} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -64,34 +64,43 @@ export class Panes extends React.Component<Props, State, {}> {
|
|||
}
|
||||
|
||||
const panesMap: Map<string, JSX.Element> = Map({
|
||||
settings: <PaneSettings login={this.props.login} update={this.props.update} />,
|
||||
login: <AuthPane authed={this.props.login.authed} update={this.props.update} />,
|
||||
settings: (
|
||||
<PaneSettings login={this.props.login} update={this.props.update} />
|
||||
),
|
||||
login: (
|
||||
<AuthPane authed={this.props.login.authed} update={this.props.update} />
|
||||
),
|
||||
});
|
||||
|
||||
const panes = panesMap.keySeq().map(
|
||||
(paneName: string): JSX.Element => {
|
||||
const isDisplay = displaying === paneName ? "" : "hidden";
|
||||
return (
|
||||
<div key={paneName} className={`${isDisplay}`}>
|
||||
{panesMap.get(paneName)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
const panes = panesMap.keySeq().map((paneName: string): JSX.Element => {
|
||||
const isDisplay = displaying === paneName ? "" : "hidden";
|
||||
return (
|
||||
<div key={paneName} className={`${isDisplay}`}>
|
||||
{panesMap.get(paneName)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
const btnClass = displaying === "login" ? "hidden" : "";
|
||||
return (
|
||||
<div id="panes" className={displaying === "" ? "hidden" : ""}>
|
||||
<div className="container">
|
||||
<div className="padding-l">
|
||||
<div className={btnClass}>
|
||||
<button onClick={this.closePane} className="black0-bg white-font">
|
||||
Return
|
||||
<div className="flex-list-container padding-l">
|
||||
<h3 className="flex-list-item-l txt-cap">{displaying}</h3>
|
||||
<div className="flex-list-item-r">
|
||||
<button
|
||||
onClick={this.closePane}
|
||||
className={`black0-bg white-font ${btnClass}`}
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
<div className="hr"></div>
|
||||
</div>
|
||||
{panes}
|
||||
</div>
|
||||
|
||||
<div className="hr white0-bg margin-b-m margin-l-m margin-r-m"></div>
|
||||
{panes}
|
||||
|
||||
<div className="padding-l"></div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -3,6 +3,7 @@ import * as React from "react";
|
|||
import { ICoreState, BaseUpdater } from "./core_state";
|
||||
import { Browser, Props as BrowserProps } from "./browser";
|
||||
import { Props as PaneLoginProps } from "./pane_login";
|
||||
import { Props as PaneAdminProps } from "./pane_admin";
|
||||
import { Panes, Props as PanesProps, Updater as PanesUpdater } from "./panes";
|
||||
|
||||
export interface Props {
|
||||
|
@ -10,6 +11,7 @@ export interface Props {
|
|||
browser: BrowserProps;
|
||||
authPane: PaneLoginProps;
|
||||
panes: PanesProps;
|
||||
admin: PaneAdminProps;
|
||||
update?: (updater: (prevState: ICoreState) => ICoreState) => void;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ export class StateMgr extends React.Component<Props, State, {}> {
|
|||
update={this.update}
|
||||
browser={this.state.panel.browser}
|
||||
panes={this.state.panel.panes}
|
||||
admin={this.state.panel.admin}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue