feat(layers): replaces panes with layers and dialogs

This commit is contained in:
hexxa 2021-11-28 12:06:42 +08:00 committed by Hexxa
parent 7df3cd0981
commit dc6babcc17
7 changed files with 227 additions and 48 deletions

View file

@ -2,10 +2,12 @@ import { List, Set, Map } from "immutable";
import { UploadEntry } from "../worker/interface";
import { loginDialogCtrl, settingsDialogCtrl } from "./layers";
import { FilesProps } from "./panel_files";
import { UploadingsProps } from "./panel_uploadings";
import { SharingsProps } from "./panel_sharings";
import { controlName as panelTabs } from "./root_frame";
import { settingsTabsCtrl } from "./dialog_settings";
import { PanesProps } from "./panes";
import { LoginProps } from "./pane_login";
import { AdminProps } from "./pane_admin";
@ -112,6 +114,9 @@ export function initState(): ICoreState {
control: {
controls: Map<string, string>({
[panelTabs]: "filesPanel",
[loginDialogCtrl]: "on",
[settingsDialogCtrl]: "off",
[settingsTabsCtrl]: "settingsPane",
}),
options: Map<string, Set<string>>({
[panelTabs]: Set<string>([
@ -119,6 +124,9 @@ export function initState(): ICoreState {
"uploadingsPanel",
"sharingsPanel",
]),
[loginDialogCtrl]: Set<string>(["on", "off"]),
[settingsDialogCtrl]: Set<string>(["on", "off"]),
[settingsTabsCtrl]: Set<string>(["settingsPane", "managementPane"]),
}),
},
},

View file

@ -0,0 +1,86 @@
import * as React from "react";
import { Map } from "immutable";
import { ICoreState, MsgProps, UIProps } from "./core_state";
import { FilesPanel, FilesProps } from "./panel_files";
import { UploadingsPanel, UploadingsProps } from "./panel_uploadings";
import { SharingsPanel, SharingsProps } from "./panel_sharings";
import { IconProps } from "./visual/icons";
import { PaneSettings } from "./pane_settings";
import { AdminPane, AdminProps } from "./pane_admin";
import { Tabs } from "./control/tabs";
import { LoginProps } from "./pane_login";
import { RiShareBoxLine } from "@react-icons/all-files/ri/RiShareBoxLine";
import { roleAdmin } from "../client";
export const settingsTabsCtrl = "settingsTabs";
export interface Props {
admin: AdminProps;
login: LoginProps;
msg: MsgProps;
ui: UIProps;
update?: (updater: (prevState: ICoreState) => ICoreState) => void;
}
export interface State {}
export class SettingsDialog extends React.Component<Props, State, {}> {
constructor(p: Props) {
super(p);
}
render() {
const displaying = this.props.ui.control.controls.get(settingsTabsCtrl);
const showSettings = displaying === "settingsPane" ? "" : "hidden";
const showManagement =
this.props.login.userRole === roleAdmin && displaying === "managementPane"
? ""
: "hidden";
return (
<div id="settings-dialog">
<div className="container">
<Tabs
targetControl={settingsTabsCtrl}
tabIcons={Map<string, IconProps>({
settingsPane: {
name: "RiSettings3Fill",
size: "1.6rem",
color: "cyan0",
},
managementPane: {
name: "RiWindowFill",
size: "1.6rem",
color: "cyan0",
},
})}
login={this.props.login}
admin={this.props.admin}
ui={this.props.ui}
msg={this.props.msg}
update={this.props.update}
/>
</div>
<div className={`${showSettings}`}>
<PaneSettings
login={this.props.login}
msg={this.props.msg}
update={this.props.update}
/>
</div>
<div className={`${showManagement}`}>
<AdminPane
admin={this.props.admin}
ui={this.props.ui}
msg={this.props.msg}
update={this.props.update}
/>
</div>
</div>
);
}
}

View file

@ -0,0 +1,88 @@
import * as React from "react";
import { Set, List } from "immutable";
import { updater } from "./state_updater";
import { ICoreState, MsgProps, UIProps } from "./core_state";
// import { PaneSettings } from "./pane_settings";
import { AdminProps } from "./pane_admin";
import { SettingsDialog } from "./dialog_settings";
import { AuthPane, LoginProps } from "./pane_login";
import { Flexbox } from "./layout/flexbox";
export const loginDialogCtrl = "loginDialog";
export const settingsDialogCtrl = "settingsDialog";
export interface Props {
login: LoginProps;
admin: AdminProps;
ui: UIProps;
msg: MsgProps;
update?: (updater: (prevState: ICoreState) => ICoreState) => void;
}
export interface State {}
export class Layers extends React.Component<Props, State, {}> {
constructor(p: Props) {
super(p);
}
setControlOption = (targetControl: string, option: string) => {
updater().setControlOption(targetControl, option);
this.props.update(updater().updateUI);
};
render() {
const showLogin = this.props.login.authed ? "hidden" : "";
const showSettings =
this.props.ui.control.controls.get("settingsDialog") == "on"
? ""
: "hidden";
return (
<div id="layers">
<div id="login-layer" className={`layer ${showLogin}`}>
<div id="root-container">
<AuthPane
login={this.props.login}
update={this.props.update}
msg={this.props.msg}
/>
</div>
</div>
<div id="settings-layer" className={`layer ${showSettings}`}>
<div id="root-container">
<div className="container">
<div className="padding-m">
<Flexbox
children={List([
<h4 id="title">
{this.props.msg.pkg.get("pane.settings")}
</h4>,
<button
onClick={() => {
this.setControlOption("settingsDialog", "off");
}}
>
{this.props.msg.pkg.get("panes.close")}
</button>,
])}
childrenStyles={List([{}, { justifyContent: "flex-end" }])}
/>
</div>
</div>
<SettingsDialog
admin={this.props.admin}
login={this.props.login}
msg={this.props.msg}
ui={this.props.ui}
update={this.props.update}
/>
</div>
</div>
</div>
);
}
}

View file

@ -10,6 +10,7 @@ import { IconProps } from "./visual/icons";
import { Tabs } from "./control/tabs";
import { LoginProps } from "./pane_login";
import { Panes, PanesProps } from "./panes";
import { Layers } from "./layers";
import { AdminProps } from "./pane_admin";
import { TopBar } from "./topbar";
import { roleVisitor } from "../client";
@ -67,8 +68,7 @@ export class RootFrame extends React.Component<Props, State, {}> {
return (
<div id="root-frame" className={`${theme} ${fontSizeClass}`}>
<div id="bg" style={bgStyle}>
<Panes
panes={this.props.panes}
<Layers
login={this.props.login}
admin={this.props.admin}
ui={this.props.ui}

View file

@ -7,6 +7,7 @@ import { LoginProps } from "./pane_login";
import { PanesProps } from "./panes";
import { updater } from "./state_updater";
import { Flexbox } from "./layout/flexbox";
import { getIcon } from "./visual/icons";
export interface State {}
export interface Props {
@ -22,24 +23,8 @@ export class TopBar extends React.Component<Props, State, {}> {
}
showSettings = () => {
updater().displayPane("settings");
this.props.update(updater().updatePanes);
};
showAdmin = async () => {
return updater()
.self()
.then(() => {
// TODO: remove hardcode role
if (this.props.login.authed && this.props.login.userRole === "admin") {
return Promise.all([updater().listRoles(), updater().listUsers()]);
}
})
.then(() => {
updater().displayPane("admin");
this.props.update(updater().updateAdmin);
this.props.update(updater().updatePanes);
});
updater().setControlOption("settingsDialog", "on");
this.props.update(updater().updateUI);
};
logout = async (): Promise<void> => {
@ -83,12 +68,7 @@ export class TopBar extends React.Component<Props, State, {}> {
};
render() {
const showUserInfo = this.props.login.authed ? "" : "hidden";
const showLogin = this.props.login.authed ? "" : "hidden";
const showSettings = this.props.panes.paneNames.get("settings")
? ""
: "hidden";
const showAdmin = this.props.panes.paneNames.get("admin") ? "" : "hidden";
return (
<div id="top-bar">
@ -105,30 +85,23 @@ export class TopBar extends React.Component<Props, State, {}> {
<Flexbox
children={List([
<span className={`${showUserInfo}`}>
<span id="topbar-user-info">
{this.props.login.userName}
</span>
</span>,
// <span className={`${showUserInfo}`}>
// <span id="topbar-user-info">{this.props.login.userName}</span>
// </span>,
<button
onClick={this.showSettings}
className={`margin-r-m ${showSettings}`}
>
<button onClick={this.showSettings} className={`margin-r-m`}>
{this.props.msg.pkg.get("settings")}
{/* {getIcon("RiSettings4Line", "1.8rem", "cyan0")} */}
</button>,
<button
onClick={this.showAdmin}
className={`margin-r-m ${showAdmin}`}
>
{this.props.msg.pkg.get("admin")}
</button>,
// <button
// onClick={this.showAdmin}
// className={`margin-r-m ${showAdmin}`}
// >
// {this.props.msg.pkg.get("admin")}
// </button>,
<button
onClick={this.logout}
className={`${showLogin}`}
>
<button onClick={this.logout} className={`${showLogin}`}>
{this.props.msg.pkg.get("login.logout")}
</button>,
])}

View file

@ -5,6 +5,8 @@ import { IconType, IconBaseProps } from "@react-icons/all-files";
import { RiFolder2Fill } from "@react-icons/all-files/ri/RiFolder2Fill";
import { RiShareBoxLine } from "@react-icons/all-files/ri/RiShareBoxLine";
import { RiUploadCloudFill } from "@react-icons/all-files/ri/RiUploadCloudFill";
import { RiSettings3Fill } from "@react-icons/all-files/ri/RiSettings3Fill";
import { RiWindowFill } from "@react-icons/all-files/ri/RiWindowFill";
import { colorClass } from "./colors";
@ -18,6 +20,8 @@ const icons = Map<string, IconType>({
RiFolder2Fill: RiFolder2Fill,
RiShareBoxLine: RiShareBoxLine,
RiUploadCloudFill: RiUploadCloudFill,
RiSettings3Fill: RiSettings3Fill,
RiWindowFill: RiWindowFill,
});
export function getIconWithProps(