fix(fe): show different panes according to user role

This commit is contained in:
hexxa 2021-09-25 11:53:34 +08:00 committed by Hexxa
parent 9501bed740
commit 08ed7f175b
8 changed files with 94 additions and 92 deletions

View file

@ -19,7 +19,6 @@ export interface MsgProps {
} }
export interface UIProps { export interface UIProps {
// background: url("/static/img/textured_paper.png") repeat fixed center;
wallpaper: string; wallpaper: string;
repeat: string; repeat: string;
position: string; position: string;
@ -63,7 +62,7 @@ export function initState(): ICoreState {
}, },
panes: { panes: {
displaying: "browser", displaying: "browser",
paneNames: Set<string>(["settings", "login", "admin"]), paneNames: Set<string>([]), // "settings", "login", "admin"
}, },
login: { login: {
userID: "", userID: "",

View file

@ -97,21 +97,6 @@ export class AuthPane extends React.Component<Props, State, {}> {
}); });
}; };
logout = async () => {
return updater()
.logout()
.then((ok: boolean) => {
if (ok) {
this.update(updater().updateLogin);
} else {
alertMsg(this.props.msg.pkg.get("login.logout.fail"));
}
})
.then(() => {
return this.refreshCaptcha();
});
};
refreshCaptcha = async () => { refreshCaptcha = async () => {
return updater() return updater()
.getCaptchaID() .getCaptchaID()
@ -177,12 +162,6 @@ export class AuthPane extends React.Component<Props, State, {}> {
</div> </div>
</div> </div>
</div> </div>
<span style={{ display: this.props.login.authed ? "inherit" : "none" }}>
<button onClick={this.logout}>
{this.props.msg.pkg.get("login.logout")}
</button>
</span>
</span> </span>
); );
} }

View file

@ -35,55 +35,11 @@ export class Panes extends React.Component<Props, State, {}> {
render() { render() {
let displaying = this.props.panes.displaying; let displaying = this.props.panes.displaying;
let panesMap: Map<string, JSX.Element> = Map({});
const settingsPane = (
<PaneSettings
login={this.props.login}
msg={this.props.msg}
update={this.props.update}
/>
);
const loginPane = (
<AuthPane
login={this.props.login}
update={this.props.update}
msg={this.props.msg}
/>
);
const adminPane = (
<AdminPane
admin={this.props.admin}
msg={this.props.msg}
update={this.props.update}
/>
);
switch(this.props.login.userRole) {
case roleAdmin:
panesMap = panesMap.set("settings", settingsPane);
panesMap = panesMap.set("admin", adminPane);
panesMap = panesMap.set("login", loginPane);
break;
case roleUser:
panesMap = panesMap.set("settings", settingsPane);
panesMap = panesMap.set("login", loginPane);
break;
default:
panesMap = panesMap.set("login", loginPane);
break;
}
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" : ""; const btnClass = displaying === "login" ? "hidden" : "";
const showSettings = this.props.panes.paneNames.get("settings") && displaying === "settings" ? "" : "hidden";
const showLogin = this.props.panes.paneNames.get("login") && displaying === "login" ? "" : "hidden";
const showAdmin = this.props.panes.paneNames.get("admin") && displaying === "admin" ? "" : "hidden";
return ( return (
<div id="panes" className={displaying === "" ? "hidden" : ""}> <div id="panes" className={displaying === "" ? "hidden" : ""}>
<div className="root-container"> <div className="root-container">
@ -102,7 +58,30 @@ export class Panes extends React.Component<Props, State, {}> {
</div> </div>
</div> </div>
{panes} <div className={`${showSettings}`}>
<PaneSettings
login={this.props.login}
msg={this.props.msg}
update={this.props.update}
/>
</div>
<div className={`${showLogin}`}>
<AuthPane
login={this.props.login}
update={this.props.update}
msg={this.props.msg}
/>
</div>
<div className={`${showAdmin}`}>
<AdminPane
admin={this.props.admin}
msg={this.props.msg}
update={this.props.update}
/>
</div>
</div> </div>
</div> </div>
); );

View file

@ -44,6 +44,7 @@ export class RootFrame extends React.Component<Props, State, {}> {
<TopBar <TopBar
login={this.props.login} login={this.props.login}
panes={this.props.panes}
msg={this.props.msg} msg={this.props.msg}
update={this.props.update} update={this.props.update}
/> />

View file

@ -1,5 +1,5 @@
import * as React from "react"; import * as React from "react";
import { List } from "immutable"; import { List, Set } from "immutable";
import { updater } from "./state_updater"; import { updater } from "./state_updater";
import { ICoreState, newState } from "./core_state"; import { ICoreState, newState } from "./core_state";
@ -62,16 +62,24 @@ export class StateMgr extends React.Component<Props, State, {}> {
if (updater().props.login.userRole === roleVisitor) { if (updater().props.login.userRole === roleVisitor) {
if (updater().props.browser.isSharing) { if (updater().props.browser.isSharing) {
// sharing with visitor // sharing with visitor
updater().setPanes(Set<string>(["login"]));
updater().displayPane(""); updater().displayPane("");
return Promise.all([]); return Promise.all([]);
} }
// redirect to login // redirect to login
updater().setPanes(Set<string>(["login"]));
updater().displayPane("login"); updater().displayPane("login");
return Promise.all([updater().getCaptchaID()]); return Promise.all([updater().getCaptchaID()]);
} }
if (updater().props.login.userRole === roleAdmin) {
updater().setPanes(Set<string>(["login", "settings", "admin"]));
} else {
updater().setPanes(Set<string>(["login", "settings"]));
}
updater().displayPane(""); updater().displayPane("");
return Promise.all([ return Promise.all([
updater().refreshUploadings(), updater().refreshUploadings(),
updater().initUploads(), updater().initUploads(),

View file

@ -12,6 +12,7 @@ import {
UploadInfo, UploadInfo,
Quota, Quota,
Response, Response,
roleVisitor,
} from "../client"; } from "../client";
import { FilesClient } from "../client/files"; import { FilesClient } from "../client/files";
import { UsersClient } from "../client/users"; import { UsersClient } from "../client/users";
@ -279,11 +280,15 @@ export class Updater {
if (pane != null) { if (pane != null) {
this.props.panes.displaying = paneName; this.props.panes.displaying = paneName;
} else { } else {
alertMsg(`dialgos: pane (${paneName}) not found`); alertMsg(`pane (${paneName}) not found`);
} }
} }
}; };
setPanes = (paneNames: Set<string>) => {
this.props.panes.paneNames = paneNames;
};
self = async (): Promise<boolean> => { self = async (): Promise<boolean> => {
const resp = await this.usersClient.self(); const resp = await this.usersClient.self();
if (resp.status === 200) { if (resp.status === 200) {
@ -294,6 +299,7 @@ export class Updater {
this.props.login.quota = resp.data.quota; this.props.login.quota = resp.data.quota;
return true; return true;
} }
this.props.login.userRole = roleVisitor;
return false; return false;
}; };

View file

@ -1,15 +1,17 @@
import * as React from "react"; import * as React from "react";
import { List } from "immutable"; import { List } from "immutable";
import { RiGithubFill } from "@react-icons/all-files/ri/RiGithubFill"; import { alertMsg } from "../common/env";
import { ICoreState, MsgProps } from "./core_state"; import { ICoreState, MsgProps } from "./core_state";
import { LoginProps } from "./pane_login"; import { LoginProps } from "./pane_login";
import { PanesProps } from "./panes";
import { updater } from "./state_updater"; import { updater } from "./state_updater";
import { Flexbox } from "./layout/flexbox"; import { Flexbox } from "./layout/flexbox";
export interface State { } export interface State { }
export interface Props { export interface Props {
login: LoginProps; login: LoginProps;
panes: PanesProps;
msg: MsgProps; msg: MsgProps;
update?: (updater: (prevState: ICoreState) => ICoreState) => void; update?: (updater: (prevState: ICoreState) => ICoreState) => void;
} }
@ -40,17 +42,34 @@ export class TopBar extends React.Component<Props, State, {}> {
}); });
}; };
logout = async () => {
return updater()
.logout()
.then((ok: boolean) => {
if (ok) {
this.props.update(updater().updateLogin);
} else {
alertMsg(this.props.msg.pkg.get("login.logout.fail"));
}
})
.then(() => {
return this.refreshCaptcha();
});
};
refreshCaptcha = async () => {
return updater()
.getCaptchaID()
.then(() => {
this.props.update(updater().updateLogin);
});
};
render() { render() {
const adminBtn = const showUserInfo = this.props.login.authed ? "" : "hidden";
this.props.login.userRole === "admin" ? ( const showLogin = this.props.login.authed ? "" : "hidden";
<button const showSettings = this.props.panes.paneNames.get("settings") ? "" : "hidden";
onClick={this.showAdmin} const showAdmin = this.props.panes.paneNames.get("admin") ? "" : "hidden";
className="grey3-bg grey4-font margin-r-m"
style={{ minWidth: "7rem" }}
>
{this.props.msg.pkg.get("admin")}
</button>
) : null;
return ( return (
<div <div
@ -69,7 +88,7 @@ export class TopBar extends React.Component<Props, State, {}> {
<Flexbox <Flexbox
children={List([ children={List([
<span> <span className={`${showUserInfo}`}>
<span className="grey3-font font-s"> <span className="grey3-font font-s">
{this.props.login.userName} {this.props.login.userName}
</span> </span>
@ -81,13 +100,23 @@ export class TopBar extends React.Component<Props, State, {}> {
<button <button
onClick={this.showSettings} onClick={this.showSettings}
className="grey3-bg grey4-font margin-r-m" className={`grey3-bg grey4-font margin-r-m ${showSettings}`}
style={{ minWidth: "7rem" }} style={{ minWidth: "7rem" }}
> >
{this.props.msg.pkg.get("settings")} {this.props.msg.pkg.get("settings")}
</button>, </button>,
adminBtn, <button
onClick={this.showAdmin}
className={`grey3-bg grey4-font margin-r-m ${showAdmin}`}
style={{ minWidth: "7rem" }}
>
{this.props.msg.pkg.get("admin")}
</button>,
<button onClick={this.logout} className={`${showLogin}`}>
{this.props.msg.pkg.get("login.logout")}
</button>,
])} ])}
childrenStyles={List([{}, {}, {}, {}])} childrenStyles={List([{}, {}, {}, {}])}
/>, />,

View file

@ -111,6 +111,7 @@ func NewMultiUsersSvc(cfg gocfg.ICfg, deps *depidx.Deps) (*MultiUsersSvc, error)
apiRuleCname(userstore.VisitorRole, "OPTIONS", "/v1/settings/health"): true, apiRuleCname(userstore.VisitorRole, "OPTIONS", "/v1/settings/health"): true,
apiRuleCname(userstore.VisitorRole, "GET", "/v1/captchas/"): true, apiRuleCname(userstore.VisitorRole, "GET", "/v1/captchas/"): true,
apiRuleCname(userstore.VisitorRole, "GET", "/v1/captchas/imgs"): true, apiRuleCname(userstore.VisitorRole, "GET", "/v1/captchas/imgs"): true,
apiRuleCname(userstore.VisitorRole, "GET", "/v1/fs/sharings/exist"): true,
} }
return &MultiUsersSvc{ return &MultiUsersSvc{