fix(fe): enable loading icon

This commit is contained in:
hexxa 2022-01-23 14:59:17 +08:00 committed by Hexxa
parent 5a11463386
commit dd6e229fce
4 changed files with 226 additions and 122 deletions

View file

@ -10,6 +10,7 @@ import { User, Quota } from "../client";
import { updater } from "./state_updater"; import { updater } from "./state_updater";
import { Flexbox } from "./layout/flexbox"; import { Flexbox } from "./layout/flexbox";
import { Container } from "./layout/container"; import { Container } from "./layout/container";
import { loadingCtrl, ctrlOn, ctrlOff } from "../common/controls";
export interface AdminProps { export interface AdminProps {
users: Map<string, User>; users: Map<string, User>;
@ -103,41 +104,57 @@ export class UserForm extends React.Component<
}); });
}; };
setLoading = (state: boolean) => {
updater().setControlOption(loadingCtrl, state ? ctrlOn : ctrlOff);
this.props.update(updater().updateUI);
};
setPwd = async () => { setPwd = async () => {
if (this.state.newPwd1 !== this.state.newPwd2) { if (this.state.newPwd1 !== this.state.newPwd2) {
alertMsg(this.props.msg.pkg.get("settings.pwd.notSame")); alertMsg(this.props.msg.pkg.get("settings.pwd.notSame"));
return; return;
} }
return updater() this.setLoading(true);
.forceSetPwd(this.state.id, this.state.newPwd1) try {
.then((status: string) => { const status = await updater().forceSetPwd(
if (status === "") { this.state.id,
alertMsg(this.props.msg.pkg.get("update.ok")); this.state.newPwd1
} else { );
alertMsg(this.props.msg.pkg.get("update.fail")); if (status !== "") {
} alertMsg(this.props.msg.pkg.get("update.fail"));
this.setState({ return;
newPwd1: "", }
newPwd2: "", alertMsg(this.props.msg.pkg.get("update.ok"));
}); } finally {
}); this.setLoading(false);
}
}; };
setUser = async () => { setUser = async () => {
return updater() this.setLoading(true);
.setUser(this.props.id, this.state.role, this.state.quota) try {
.then((status: string) => { const status = await updater().setUser(
if (status === "") { this.props.id,
alertMsg(this.props.msg.pkg.get("update.ok")); this.state.role,
} else { this.state.quota
alertMsg(this.props.msg.pkg.get("update.fail")); );
} if (status !== "") {
return updater().listUsers(); alertMsg(this.props.msg.pkg.get("update.fail"));
}) return;
.then(() => { }
this.props.update(updater().updateAdmin);
}); const listStatus = await updater().listUsers();
if (listStatus !== "") {
alertMsg(this.props.msg.pkg.get("update.fail"));
return;
}
alertMsg(this.props.msg.pkg.get("update.ok"));
} finally {
this.props.update(updater().updateAdmin);
this.setLoading(false);
}
}; };
delUser = async () => { delUser = async () => {
@ -145,17 +162,25 @@ export class UserForm extends React.Component<
return; return;
} }
return updater() this.setLoading(true);
.delUser(this.state.id) try {
.then((status: string) => { const status = await updater().delUser(this.state.id);
if (status !== "") { if (status !== "") {
alertMsg(this.props.msg.pkg.get("delete.fail")); alertMsg(this.props.msg.pkg.get("delete.fail"));
} return;
return updater().listUsers(); }
})
.then((_: string) => { const listStatus = await updater().listUsers();
this.props.update(updater().updateAdmin); if (listStatus !== "") {
}); alertMsg(this.props.msg.pkg.get("op.fail"));
return;
}
alertMsg(this.props.msg.pkg.get("delete.ok"));
} finally {
this.props.update(updater().updateAdmin);
this.setLoading(false);
}
}; };
toggle = () => { toggle = () => {
@ -369,14 +394,30 @@ export class AdminPane extends React.Component<Props, State, {}> {
this.setState({ newRole: ev.target.value }); this.setState({ newRole: ev.target.value });
}; };
setLoading = (state: boolean) => {
updater().setControlOption(loadingCtrl, state ? ctrlOn : ctrlOff);
this.props.update(updater().updateUI);
};
addRole = async () => { addRole = async () => {
const status = await updater().addRole(this.state.newRole); this.setLoading(true);
if (status !== "") { try {
alertMsg(this.props.msg.pkg.get("add.fail")); const status = await updater().addRole(this.state.newRole);
} else { if (status !== "") {
alertMsg(this.props.msg.pkg.get("add.fail"));
return;
}
const listStatus = await updater().listRoles();
if (listStatus !== "") {
alertMsg(this.props.msg.pkg.get("add.fail"));
return;
}
alertMsg(this.props.msg.pkg.get("add.ok")); alertMsg(this.props.msg.pkg.get("add.ok"));
await updater().listRoles(); } finally {
this.props.update(updater().updateAdmin); this.props.update(updater().updateAdmin);
this.setLoading(false);
} }
}; };
@ -385,12 +426,24 @@ export class AdminPane extends React.Component<Props, State, {}> {
return; return;
} }
const status = await updater().delRole(role); this.setLoading(true);
if (status !== "") {
this.props.msg.pkg.get("delete.fail"); try {
} else { const status = await updater().delRole(role);
if (status !== "") {
this.props.msg.pkg.get("delete.fail");
return;
}
const listStatus = await updater().listRoles();
if (listStatus !== "") {
alertMsg(this.props.msg.pkg.get("add.fail"));
return;
}
this.props.msg.pkg.get("delete.ok"); this.props.msg.pkg.get("delete.ok");
await updater().listRoles(); } finally {
this.setLoading(false);
this.props.update(updater().updateAdmin); this.props.update(updater().updateAdmin);
} }
}; };
@ -401,27 +454,38 @@ export class AdminPane extends React.Component<Props, State, {}> {
return; return;
} }
const status = await updater().addUser({ this.setLoading(true);
id: "", // backend will fill it
name: this.state.newUserName, try {
pwd: this.state.newUserPwd1, const status = await updater().addUser({
role: this.state.newUserRole, id: "", // backend will fill it
quota: undefined, name: this.state.newUserName,
usedSpace: "0", pwd: this.state.newUserPwd1,
preferences: undefined, role: this.state.newUserRole,
}); quota: undefined,
usedSpace: "0",
preferences: undefined,
});
if (status !== "") {
alertMsg(this.props.msg.pkg.get("add.fail"));
return;
}
const listStatus = await updater().listUsers();
if (listStatus !== "") {
alertMsg(this.props.msg.pkg.get("op.fail"));
return;
}
if (status !== "") {
alertMsg(this.props.msg.pkg.get("add.fail"));
} else {
alertMsg(this.props.msg.pkg.get("add.ok")); alertMsg(this.props.msg.pkg.get("add.ok"));
} finally {
this.setState({ this.setState({
newUserName: "", newUserName: "",
newUserPwd1: "", newUserPwd1: "",
newUserPwd2: "", newUserPwd2: "",
newUserRole: "", newUserRole: "",
}); });
await updater().listUsers(); this.setLoading(false);
this.props.update(updater().updateAdmin); this.props.update(updater().updateAdmin);
} }
}; };
@ -652,6 +716,11 @@ export class BgCfg extends React.Component<BgProps, BgState, {}> {
super(p); super(p);
} }
setLoading = (state: boolean) => {
updater().setControlOption(loadingCtrl, state ? ctrlOn : ctrlOff);
this.props.update(updater().updateUI);
};
setClientCfg = async () => { setClientCfg = async () => {
const bgURL = this.props.ui.bg.url; const bgURL = this.props.ui.bg.url;
if (bgURL.length === 0 || bgURL.length >= 4096) { if (bgURL.length === 0 || bgURL.length >= 4096) {
@ -690,19 +759,23 @@ export class BgCfg extends React.Component<BgProps, BgState, {}> {
return; return;
} }
return updater() this.setLoading(true);
.setClientCfgRemote({
try {
const status = await updater().setClientCfgRemote({
siteName: this.props.ui.siteName, siteName: this.props.ui.siteName,
siteDesc: this.props.ui.siteDesc, siteDesc: this.props.ui.siteDesc,
bg: this.props.ui.bg, bg: this.props.ui.bg,
})
.then((status: string) => {
if (status === "") {
alertMsg(this.props.msg.pkg.get("update.ok"));
} else {
alertMsg(this.props.msg.pkg.get("update.fail"));
}
}); });
if (status !== "") {
alertMsg(this.props.msg.pkg.get("update.fail"));
return;
}
alertMsg(this.props.msg.pkg.get("update.ok"));
} finally {
this.setLoading(false);
}
}; };
resetClientCfg = () => { resetClientCfg = () => {

View file

@ -11,6 +11,7 @@ import { Container } from "./layout/container";
import { Card } from "./layout/card"; import { Card } from "./layout/card";
import { Rows, Row } from "./layout/rows"; import { Rows, Row } from "./layout/rows";
import { ClientErrorV001, ErrorLogger } from "../common/log_error"; import { ClientErrorV001, ErrorLogger } from "../common/log_error";
import { loadingCtrl, ctrlOn, ctrlOff } from "../common/controls";
export interface Props { export interface Props {
login: LoginProps; login: LoginProps;
msg: MsgProps; msg: MsgProps;
@ -85,59 +86,74 @@ export class PaneSettings extends React.Component<Props, State, {}> {
}; };
} }
setLoading = (state: boolean) => {
updater().setControlOption(loadingCtrl, state ? ctrlOn : ctrlOff);
this.props.update(updater().updateUI);
};
syncPreferences = async () => { syncPreferences = async () => {
updater() this.setLoading(true);
.syncPreferences() try {
.then((status: string) => { const status = await updater().syncPreferences();
if (status === "") { if (status !== "") {
alertMsg(this.props.msg.pkg.get("update.ok")); alertMsg(this.props.msg.pkg.get("update.fail"));
} else { return;
alertMsg(this.props.msg.pkg.get("update.fail")); }
} alertMsg(this.props.msg.pkg.get("update.ok"));
}); } finally {
this.setLoading(false);
}
}; };
setPwd = async (): Promise<any> => { setPwd = async (): Promise<any> => {
if (this.state.newPwd1 !== this.state.newPwd2) { if (this.state.newPwd1 !== this.state.newPwd2) {
alertMsg(this.props.msg.pkg.get("settings.pwd.notSame")); alertMsg(this.props.msg.pkg.get("settings.pwd.notSame"));
return;
} else if ( } else if (
this.state.oldPwd == "" || this.state.oldPwd == "" ||
this.state.newPwd1 == "" || this.state.newPwd1 == "" ||
this.state.newPwd2 == "" this.state.newPwd2 == ""
) { ) {
alertMsg(this.props.msg.pkg.get("settings.pwd.empty")); alertMsg(this.props.msg.pkg.get("settings.pwd.empty"));
return;
} else if (this.state.oldPwd == this.state.newPwd1) { } else if (this.state.oldPwd == this.state.newPwd1) {
alertMsg(this.props.msg.pkg.get("settings.pwd.notChanged")); alertMsg(this.props.msg.pkg.get("settings.pwd.notChanged"));
} else { return;
return updater() }
.setPwd(this.state.oldPwd, this.state.newPwd1)
.then((status: string) => { this.setLoading(true);
if (status === "") { try {
alertMsg(this.props.msg.pkg.get("update.ok")); const status = await updater().setPwd(
} else { this.state.oldPwd,
alertMsg(this.props.msg.pkg.get("update.fail")); this.state.newPwd1
} );
this.setState({ if (status !== "") {
oldPwd: "", alertMsg(this.props.msg.pkg.get("update.fail"));
newPwd1: "", return;
newPwd2: "", }
});
}); alertMsg(this.props.msg.pkg.get("update.ok"));
} finally {
this.setState({
oldPwd: "",
newPwd1: "",
newPwd2: "",
});
this.setLoading(false);
} }
}; };
setLan = (lan: string) => { setLan = async (lan: string) => {
updater().setLan(lan); updater().setLan(lan);
updater() try {
.syncPreferences() const status = await updater().syncPreferences();
.then((status: string) => { if (status !== "") {
if (status === "") { alertMsg(this.props.msg.pkg.get("update.fail"));
alertMsg(this.props.msg.pkg.get("update.ok")); }
this.props.update(updater().updateMsg); } finally {
} else { alertMsg(this.props.msg.pkg.get("update.ok"));
alertMsg(this.props.msg.pkg.get("update.fail")); this.props.update(updater().updateMsg);
} }
});
}; };
truncateErrors = () => { truncateErrors = () => {

View file

@ -1,6 +1,5 @@
import * as React from "react"; import * as React from "react";
import { List, Map } from "immutable"; import { List, Map } from "immutable";
import QRCode from "react-qr-code";
import { RiShareBoxLine } from "@react-icons/all-files/ri/RiShareBoxLine"; import { RiShareBoxLine } from "@react-icons/all-files/ri/RiShareBoxLine";
import { RiCloudOffFill } from "@react-icons/all-files/ri/RiCloudOffFill"; import { RiCloudOffFill } from "@react-icons/all-files/ri/RiCloudOffFill";
@ -15,6 +14,7 @@ import { Flexbox } from "./layout/flexbox";
import { Container } from "./layout/container"; import { Container } from "./layout/container";
import { Rows, Row } from "./layout/rows"; import { Rows, Row } from "./layout/rows";
import { shareIDQuery } from "../client/files"; import { shareIDQuery } from "../client/files";
import { loadingCtrl, ctrlOn, ctrlOff } from "../common/controls";
export interface SharingsProps { export interface SharingsProps {
sharings: Map<string, string>; sharings: Map<string, string>;
@ -36,7 +36,14 @@ export class SharingsPanel extends React.Component<Props, State, {}> {
this.state = {}; this.state = {};
} }
setLoading = (state: boolean) => {
updater().setControlOption(loadingCtrl, state ? ctrlOn : ctrlOff);
this.props.update(updater().updateUI);
};
deleteSharing = async (dirPath: string) => { deleteSharing = async (dirPath: string) => {
this.setLoading(true);
try { try {
const deleteStatus = await updater().deleteSharing(dirPath); const deleteStatus = await updater().deleteSharing(dirPath);
if (deleteStatus !== "") { if (deleteStatus !== "") {
@ -47,16 +54,23 @@ export class SharingsPanel extends React.Component<Props, State, {}> {
await this.listSharings(); await this.listSharings();
} catch (e: any) { } catch (e: any) {
alertMsg(getErrMsg(this.props.msg.pkg, "op.fail", status)); alertMsg(getErrMsg(this.props.msg.pkg, "op.fail", status));
} finally {
this.setLoading(false);
} }
}; };
listSharings = async () => { listSharings = async () => {
const status = await updater().listSharings(); this.setLoading(true);
if (status !== "") { try {
alertMsg(getErrMsg(this.props.msg.pkg, "op.fail", status)); const status = await updater().listSharings();
if (status !== "") {
alertMsg(getErrMsg(this.props.msg.pkg, "op.fail", status));
}
this.props.update(updater().updateFilesInfo);
this.props.update(updater().updateSharingsInfo);
} finally {
this.setLoading(false);
} }
this.props.update(updater().updateFilesInfo);
this.props.update(updater().updateSharingsInfo);
}; };
makeRows = (sharings: Map<string, string>): List<Row> => { makeRows = (sharings: Map<string, string>): List<Row> => {

View file

@ -3,7 +3,6 @@ import { List } from "immutable";
import FileSize from "filesize"; import FileSize from "filesize";
import { RiUploadCloudFill } from "@react-icons/all-files/ri/RiUploadCloudFill"; import { RiUploadCloudFill } from "@react-icons/all-files/ri/RiUploadCloudFill";
import { RiUploadCloudLine } from "@react-icons/all-files/ri/RiUploadCloudLine";
import { RiCloudOffFill } from "@react-icons/all-files/ri/RiCloudOffFill"; import { RiCloudOffFill } from "@react-icons/all-files/ri/RiCloudOffFill";
import { alertMsg } from "../common/env"; import { alertMsg } from "../common/env";
@ -15,6 +14,7 @@ import { UploadEntry, UploadState } from "../worker/interface";
import { Flexbox } from "./layout/flexbox"; import { Flexbox } from "./layout/flexbox";
import { Container } from "./layout/container"; import { Container } from "./layout/container";
import { Rows, Row } from "./layout/rows"; import { Rows, Row } from "./layout/rows";
import { loadingCtrl, ctrlOn, ctrlOff } from "../common/controls";
export interface UploadingsProps { export interface UploadingsProps {
uploadings: List<UploadEntry>; uploadings: List<UploadEntry>;
@ -36,7 +36,14 @@ export class UploadingsPanel extends React.Component<Props, State, {}> {
this.state = {}; this.state = {};
} }
setLoading = (state: boolean) => {
updater().setControlOption(loadingCtrl, state ? ctrlOn : ctrlOff);
this.props.update(updater().updateUI);
};
deleteUpload = async (filePath: string): Promise<void> => { deleteUpload = async (filePath: string): Promise<void> => {
this.setLoading(true);
try { try {
const deleteStatus = await updater().deleteUpload(filePath); const deleteStatus = await updater().deleteUpload(filePath);
if (deleteStatus !== "") { if (deleteStatus !== "") {
@ -55,6 +62,8 @@ export class UploadingsPanel extends React.Component<Props, State, {}> {
this.props.update(updater().updateUploadingsInfo); this.props.update(updater().updateUploadingsInfo);
} catch (status: any) { } catch (status: any) {
alertMsg(getErrMsg(this.props.msg.pkg, "op.fail", status.toString())); alertMsg(getErrMsg(this.props.msg.pkg, "op.fail", status.toString()));
} finally {
this.setLoading(false);
} }
}; };
@ -122,12 +131,8 @@ export class UploadingsPanel extends React.Component<Props, State, {}> {
</div> </div>
); );
// file path, size, progress // file path
const sortVals = List<string>([ const sortVals = List<string>([uploading.filePath]);
uploading.filePath,
`${uploading.size}`,
`${progress}`,
]);
return { return {
elem, elem,
sortVals, sortVals,
@ -148,11 +153,7 @@ export class UploadingsPanel extends React.Component<Props, State, {}> {
const uploadingRows = this.makeRowsInputs( const uploadingRows = this.makeRowsInputs(
this.props.uploadingsInfo.uploadings this.props.uploadingsInfo.uploadings
); );
const sortKeys = List([ const sortKeys = List([this.props.msg.pkg.get("item.path")]);
this.props.msg.pkg.get("item.path"),
this.props.msg.pkg.get("item.size"),
this.props.msg.pkg.get("item.progress"),
]);
const view = ( const view = (
<Rows <Rows
sortKeys={sortKeys} sortKeys={sortKeys}