feat(fe/loading): introduce loading layer
This commit is contained in:
parent
f06c5f5a7d
commit
2904d03bdb
7 changed files with 82 additions and 44 deletions
|
@ -70,6 +70,7 @@
|
||||||
|
|
||||||
.theme-default #layers {
|
.theme-default #layers {
|
||||||
height: 0;
|
height: 0;
|
||||||
|
z-index: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-default #panes .container {
|
.theme-default #panes .container {
|
||||||
|
@ -499,12 +500,28 @@
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-default #login-layer {
|
.theme-default #login-layer {
|
||||||
z-index: 200;
|
z-index: 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.theme-default #loading-layer {
|
||||||
|
z-index: 201;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-default #loading-container {
|
||||||
|
background-color: rgba(255, 255, 255, 1);
|
||||||
|
border-radius: 0.6rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
position: fixed;
|
||||||
|
right: 2rem;
|
||||||
|
bottom: 2rem;
|
||||||
|
height: 3rem;
|
||||||
|
z-index: 201;
|
||||||
|
}
|
||||||
|
|
||||||
.theme-default #settings-layer {
|
.theme-default #settings-layer {
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,3 +5,4 @@ export const filesViewCtrl = "filesView";
|
||||||
export const ctrlHidden = "hidden";
|
export const ctrlHidden = "hidden";
|
||||||
export const ctrlOn = "on";
|
export const ctrlOn = "on";
|
||||||
export const ctrlOff = "off";
|
export const ctrlOff = "off";
|
||||||
|
export const loadingCtrl = "loading";
|
|
@ -17,6 +17,7 @@ import {
|
||||||
import { NewMockSettingsClient } from "../../client/settings_mock";
|
import { NewMockSettingsClient } from "../../client/settings_mock";
|
||||||
import { controlName as panelTabs } from "../root_frame";
|
import { controlName as panelTabs } from "../root_frame";
|
||||||
import {
|
import {
|
||||||
|
loadingCtrl,
|
||||||
sharingCtrl,
|
sharingCtrl,
|
||||||
ctrlOn,
|
ctrlOn,
|
||||||
ctrlOff,
|
ctrlOff,
|
||||||
|
@ -131,6 +132,7 @@ describe("Login", () => {
|
||||||
[settingsTabsCtrl]: "preferencePane",
|
[settingsTabsCtrl]: "preferencePane",
|
||||||
[sharingCtrl]: ctrlOff,
|
[sharingCtrl]: ctrlOff,
|
||||||
[filesViewCtrl]: "rows",
|
[filesViewCtrl]: "rows",
|
||||||
|
[loadingCtrl]: ctrlOff,
|
||||||
}),
|
}),
|
||||||
options: Map<string, Set<string>>({
|
options: Map<string, Set<string>>({
|
||||||
[panelTabs]: Set<string>([
|
[panelTabs]: Set<string>([
|
||||||
|
@ -142,6 +144,7 @@ describe("Login", () => {
|
||||||
[settingsTabsCtrl]: Set<string>(["preferencePane", "managementPane"]),
|
[settingsTabsCtrl]: Set<string>(["preferencePane", "managementPane"]),
|
||||||
[sharingCtrl]: Set<string>([ctrlOn, ctrlOff]),
|
[sharingCtrl]: Set<string>([ctrlOn, ctrlOff]),
|
||||||
[filesViewCtrl]: Set<string>(["rows", "table"]),
|
[filesViewCtrl]: Set<string>(["rows", "table"]),
|
||||||
|
[loadingCtrl]: Set<string>([ctrlOn, ctrlOff]),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
sharingCtrl,
|
sharingCtrl,
|
||||||
ctrlOn,
|
ctrlOn,
|
||||||
ctrlOff,
|
ctrlOff,
|
||||||
|
loadingCtrl,
|
||||||
} from "../common/controls";
|
} from "../common/controls";
|
||||||
import { LoginProps } from "./pane_login";
|
import { LoginProps } from "./pane_login";
|
||||||
import { AdminProps } from "./pane_admin";
|
import { AdminProps } from "./pane_admin";
|
||||||
|
@ -117,6 +118,7 @@ export function initState(): ICoreState {
|
||||||
[settingsTabsCtrl]: "preferencePane",
|
[settingsTabsCtrl]: "preferencePane",
|
||||||
[sharingCtrl]: ctrlOff,
|
[sharingCtrl]: ctrlOff,
|
||||||
[filesViewCtrl]: "rows",
|
[filesViewCtrl]: "rows",
|
||||||
|
[loadingCtrl]: ctrlOff,
|
||||||
}),
|
}),
|
||||||
options: Map<string, Set<string>>({
|
options: Map<string, Set<string>>({
|
||||||
[panelTabs]: Set<string>([
|
[panelTabs]: Set<string>([
|
||||||
|
@ -128,6 +130,7 @@ export function initState(): ICoreState {
|
||||||
[settingsTabsCtrl]: Set<string>(["preferencePane", "managementPane"]),
|
[settingsTabsCtrl]: Set<string>(["preferencePane", "managementPane"]),
|
||||||
[sharingCtrl]: Set<string>([ctrlOn, ctrlOff]),
|
[sharingCtrl]: Set<string>([ctrlOn, ctrlOff]),
|
||||||
[filesViewCtrl]: Set<string>(["rows", "table"]),
|
[filesViewCtrl]: Set<string>(["rows", "table"]),
|
||||||
|
[loadingCtrl]: Set<string>([ctrlOn, ctrlOff]),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { List } from "immutable";
|
import { List } from "immutable";
|
||||||
|
|
||||||
|
import { RiTimer2Line } from "@react-icons/all-files/ri/RiTimer2Line";
|
||||||
|
|
||||||
import { updater } from "./state_updater";
|
import { updater } from "./state_updater";
|
||||||
import { ICoreState, MsgProps, UIProps } from "./core_state";
|
import { ICoreState, MsgProps, UIProps } from "./core_state";
|
||||||
import { AdminProps } from "./pane_admin";
|
import { AdminProps } from "./pane_admin";
|
||||||
|
@ -10,7 +12,7 @@ import { AuthPane, LoginProps } from "./pane_login";
|
||||||
import { FilesProps } from "./panel_files";
|
import { FilesProps } from "./panel_files";
|
||||||
import { Flexbox } from "./layout/flexbox";
|
import { Flexbox } from "./layout/flexbox";
|
||||||
import { Container } from "./layout/container";
|
import { Container } from "./layout/container";
|
||||||
import { sharingCtrl, ctrlOn } from "../common/controls";
|
import { sharingCtrl, loadingCtrl, ctrlOn } from "../common/controls";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
filesInfo: FilesProps;
|
filesInfo: FilesProps;
|
||||||
|
@ -40,9 +42,11 @@ export class Layers extends React.Component<Props, State, {}> {
|
||||||
? "hidden"
|
? "hidden"
|
||||||
: "";
|
: "";
|
||||||
const showSettings =
|
const showSettings =
|
||||||
this.props.ui.control.controls.get("settingsDialog") === "on"
|
this.props.ui.control.controls.get("settingsDialog") === ctrlOn
|
||||||
? ""
|
? ""
|
||||||
: "hidden";
|
: "hidden";
|
||||||
|
const showLoading =
|
||||||
|
this.props.ui.control.controls.get(loadingCtrl) == ctrlOn ? "" : "hidden";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="layers">
|
<div id="layers">
|
||||||
|
@ -56,6 +60,12 @@ export class Layers extends React.Component<Props, State, {}> {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="loading-layer" className={showLoading}>
|
||||||
|
<div id="loading-container">
|
||||||
|
<RiTimer2Line size="3rem" className="cyan1-font anm-rotate" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="settings-layer" className={`layer ${showSettings}`}>
|
<div id="settings-layer" className={`layer ${showSettings}`}>
|
||||||
<div id="root-container">
|
<div id="root-container">
|
||||||
<Container>
|
<Container>
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { updater } from "./state_updater";
|
||||||
import { alertMsg } from "../common/env";
|
import { alertMsg } from "../common/env";
|
||||||
import { Quota, Preferences } from "../client";
|
import { Quota, Preferences } from "../client";
|
||||||
import { getErrMsg } from "../common/utils";
|
import { getErrMsg } from "../common/utils";
|
||||||
|
import { ctrlOn, ctrlOff, loadingCtrl } from "../common/controls";
|
||||||
|
|
||||||
export interface ExtInfo {
|
export interface ExtInfo {
|
||||||
usedSpace: string;
|
usedSpace: string;
|
||||||
|
@ -59,46 +60,47 @@ export class AuthPane extends React.Component<Props, State, {}> {
|
||||||
};
|
};
|
||||||
|
|
||||||
login = async () => {
|
login = async () => {
|
||||||
return updater()
|
updater().setControlOption(loadingCtrl, ctrlOn);
|
||||||
.login(
|
this.props.update(updater().updateUI);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const loginStatus = await updater().login(
|
||||||
this.state.user,
|
this.state.user,
|
||||||
this.state.pwd,
|
this.state.pwd,
|
||||||
this.props.login.captchaID,
|
this.props.login.captchaID,
|
||||||
this.state.captchaInput
|
this.state.captchaInput
|
||||||
)
|
|
||||||
.then((status: string): Promise<any> => {
|
|
||||||
this.setState({ captchaInput: "" });
|
|
||||||
if (status === "") {
|
|
||||||
const params = new URLSearchParams(
|
|
||||||
document.location.search.substring(1)
|
|
||||||
);
|
);
|
||||||
return updater().initAll(params);
|
if (loginStatus !== "") {
|
||||||
} else {
|
alertMsg(
|
||||||
throw status;
|
getErrMsg(this.props.msg.pkg, "op.fail", loginStatus.toString())
|
||||||
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.then((status: string) => {
|
const params = new URLSearchParams(document.location.search.substring(1));
|
||||||
if (status !== "") {
|
const initStatus = await updater().initAll(params);
|
||||||
throw status;
|
if (initStatus !== "") {
|
||||||
|
alertMsg(
|
||||||
|
getErrMsg(this.props.msg.pkg, "op.fail", initStatus.toString())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ user: "", pwd: "" });
|
||||||
|
} finally {
|
||||||
|
this.setState({ pwd: "", captchaInput: "" });
|
||||||
|
updater().setControlOption(loadingCtrl, ctrlOff);
|
||||||
|
await this.refreshCaptcha();
|
||||||
|
this.props.update(updater().updateAll);
|
||||||
}
|
}
|
||||||
this.update(updater().updateAll);
|
|
||||||
})
|
|
||||||
.catch((status: Error) => {
|
|
||||||
alertMsg(getErrMsg(this.props.msg.pkg, "op.fail", status.toString()));
|
|
||||||
return updater().getCaptchaID();
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
refreshCaptcha = async () => {
|
refreshCaptcha = async () => {
|
||||||
return updater()
|
const status = await updater().getCaptchaID();
|
||||||
.getCaptchaID()
|
|
||||||
.then((status: string) => {
|
|
||||||
if (status !== "") {
|
if (status !== "") {
|
||||||
alertMsg(getErrMsg(this.props.msg.pkg, "op.fail", status));
|
alertMsg(getErrMsg(this.props.msg.pkg, "op.fail", status));
|
||||||
} else {
|
} else {
|
||||||
this.props.update(updater().updateLogin);
|
this.props.update(updater().updateLogin);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import { FilesClient } from "../client/files";
|
||||||
import { UsersClient } from "../client/users";
|
import { UsersClient } from "../client/users";
|
||||||
import { SettingsClient } from "../client/settings";
|
import { SettingsClient } from "../client/settings";
|
||||||
import { IUsersClient, IFilesClient, ISettingsClient } from "../client";
|
import { IUsersClient, IFilesClient, ISettingsClient } from "../client";
|
||||||
|
import { loadingCtrl, ctrlOn, ctrlOff } from "../common/controls";
|
||||||
|
|
||||||
export interface Props {}
|
export interface Props {}
|
||||||
export interface State extends ICoreState {}
|
export interface State extends ICoreState {}
|
||||||
|
@ -49,6 +50,9 @@ export class StateMgr extends React.Component<Props, State, {}> {
|
||||||
query: URLSearchParams
|
query: URLSearchParams
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
updater().init(state);
|
updater().init(state);
|
||||||
|
updater().setControlOption(loadingCtrl, ctrlOn);
|
||||||
|
this.update(updater().updateUI);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this.usersClient == null ||
|
this.usersClient == null ||
|
||||||
this.filesClient == null ||
|
this.filesClient == null ||
|
||||||
|
@ -63,14 +67,12 @@ export class StateMgr extends React.Component<Props, State, {}> {
|
||||||
this.settingsClient
|
this.settingsClient
|
||||||
);
|
);
|
||||||
|
|
||||||
return updater()
|
const status = await updater().initAll(query);
|
||||||
.initAll(query)
|
|
||||||
.then((status: string) => {
|
|
||||||
if (status !== "") {
|
if (status !== "") {
|
||||||
alertMsg(getErrMsg(state.msg.pkg, "op.fail", status));
|
alertMsg(getErrMsg(state.msg.pkg, "op.fail", status));
|
||||||
}
|
}
|
||||||
|
updater().setControlOption(loadingCtrl, ctrlOff);
|
||||||
this.update(updater().updateAll);
|
this.update(updater().updateAll);
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
update = (update: (prevState: ICoreState) => ICoreState): void => {
|
update = (update: (prevState: ICoreState) => ICoreState): void => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue