add recycle bin list

This commit is contained in:
Simba
2020-07-14 23:08:31 +08:00
parent d880fc0487
commit 0296d2f345
11 changed files with 656 additions and 264 deletions
+3 -1
View File
@@ -13,7 +13,8 @@ import {
PoweroffOutlined,
SettingOutlined,
ShareAltOutlined,
TeamOutlined
TeamOutlined,
DeleteOutlined
} from '@ant-design/icons';
import {LoginOutlined} from "@ant-design/icons/lib";
import Preference from "../model/preference/Preference";
@@ -81,6 +82,7 @@ export default class MenuManager {
} else {
menuItems.push(new MenuItem(Lang.t("layout.allFiles"), '/matter/list', <AppstoreOutlined/>))
menuItems.push(new MenuItem(Lang.t("layout.myShare"), '/share/list', <ShareAltOutlined/>))
menuItems.push(new MenuItem(Lang.t("layout.bin"), '/bin/list', <DeleteOutlined />))
if (user.role === UserRole.ADMINISTRATOR) {
menuItems.push(new MenuItem(Lang.t("layout.setting"), '/preference/index', <SettingOutlined/>))
+5 -1
View File
@@ -70,6 +70,7 @@ let LangEn = {
layout: {
allFiles: "Files",
myShare: "My Share",
bin: "Recycle bin",
setting: "Setting",
dashboard: "Dashboard",
users: "Users",
@@ -84,6 +85,7 @@ let LangEn = {
rename: "Rename",
download: "Download",
delete: "Delete",
hardDelete: "Hard delete",
more: "More",
share: "Share",
close: "Close",
@@ -130,7 +132,8 @@ let LangEn = {
newDirectory: "New directory",
notChoose: "Not choose any file",
exceed1000: "Exceed file limit 1000",
noImageCache: "No image cache"
noImageCache: "No image cache",
recycleBin: "Recycle bin"
},
router: {
allFiles: "All Files",
@@ -326,6 +329,7 @@ let LangEn = {
cancel: "Cancel",
delete: "Delete",
actionCanNotRevertConfirm: "This action cannot be reverted, confirm?",
actionDeleteConfirm: "Delete, confirm?",
prompt: "Prompt",
confirm: "Confirm",
copy: "Copy",
+6 -2
View File
@@ -69,8 +69,9 @@ let LangZh = {
finish: "完成",
},
layout: {
allFiles: "所有文件",
allFiles: "全部文件",
myShare: "我的分享",
bin: "回收站",
setting: "网站设置",
dashboard: "监控统计",
users: "用户管理",
@@ -85,6 +86,7 @@ let LangZh = {
rename: "重命名",
download: "下载",
delete: "删除",
hardDelete: "彻底删除",
more: "更多",
share: "分享",
close: "关闭",
@@ -131,7 +133,8 @@ let LangZh = {
newDirectory: "新建文件夹",
notChoose: "没有选择文件",
exceed1000: "最多只能同时选取1000个文件",
noImageCache: "暂无图片缓存数据"
noImageCache: "暂无图片缓存数据",
recycleBin: "回收站"
},
router: {
allFiles: "全部文件",
@@ -327,6 +330,7 @@ let LangZh = {
cancel: "取消",
delete: "删除",
actionCanNotRevertConfirm: "此操作不可撤回, 是否继续?",
actionDeleteConfirm: "确定删除吗?",
prompt: "提示",
confirm: "确定",
copy: "复制",
+29
View File
@@ -30,6 +30,9 @@ export default class Matter extends BaseEntity {
//上次访问时间
visitTime: Date | null = null;
parent: Matter | null = null;
// 文件是否被软删除
deleted: boolean = false;
deleteTime: Date | null = null;
/*
这部分是辅助UI的字段信息
@@ -51,6 +54,8 @@ export default class Matter extends BaseEntity {
speed: number = 0;
static URL_MATTER_CREATE_DIRECTORY = "/api/matter/create/directory";
static URL_MATTER_SOFT_DELETE = "/api/matter/soft/delete";
static URL_MATTER_SOFT_DELETE_BATCH = "/api/matter/soft/delete/batch";
static URL_MATTER_DELETE = "/api/matter/delete";
static URL_MATTER_DELETE_BATCH = "/api/matter/delete/batch";
static URL_MATTER_RENAME = "/api/matter/rename";
@@ -77,6 +82,7 @@ export default class Matter extends BaseEntity {
super.assign(obj);
this.assignEntity("parent", Matter);
this.assignEntity("visitTime", Date);
this.assignEntity("deleteTime", Date);
}
getForm(): any {
@@ -104,6 +110,7 @@ export default class Matter extends BaseEntity {
new InputFilter("关键字", "name"),
new CheckFilter("文件夹", "dir"),
new CheckFilter("应用数据", "alien"),
new CheckFilter("删除", "deleted"),
new SortFilter("文件夹", "orderDir"),
new SortFilter("下载次数", "orderTimes"),
new SortFilter("大小", "orderSize"),
@@ -210,6 +217,28 @@ export default class Matter extends BaseEntity {
);
}
httpSoftDelete(successCallback?: any, errorCallback?: any) {
this.httpPost(
Matter.URL_MATTER_SOFT_DELETE,
{uuid: this.uuid},
function (response: any) {
typeof successCallback === "function" && successCallback(response);
},
errorCallback
);
}
httpSoftDeleteBatch(uuids: string, successCallback?: any, errorCallback?: any) {
this.httpPost(
Matter.URL_MATTER_SOFT_DELETE_BATCH,
{uuids: uuids},
function (response: any) {
typeof successCallback === "function" && successCallback(response);
},
errorCallback
);
}
httpDelete(successCallback?: any, errorCallback?: any) {
this.httpPost(
Matter.URL_MATTER_DELETE,
+115 -114
View File
@@ -1,182 +1,183 @@
import React from 'react';
import {Redirect, Route, RouteComponentProps, withRouter} from 'react-router-dom';
import React from "react";
import {
Redirect,
Route,
RouteComponentProps,
withRouter,
} from "react-router-dom";
import './Frame.less';
import TankComponent from '../common/component/TankComponent';
import UserLogin from './user/Login';
import UserRegister from './user/Register';
import "./Frame.less";
import TankComponent from "../common/component/TankComponent";
import UserLogin from "./user/Login";
import UserRegister from "./user/Register";
import UserList from './user/List';
import MobileUserList from './user/MobileList';
import UserDetail from './user/Detail';
import UserEdit from './user/Edit';
import UserAuthentication from './user/Authentication';
import UserList from "./user/List";
import MobileUserList from "./user/MobileList";
import UserDetail from "./user/Detail";
import UserEdit from "./user/Edit";
import UserAuthentication from "./user/Authentication";
import PreferenceIndex from './preference/Index';
import PreferenceEdit from './preference/Edit';
import PreferenceEngineEdit from './preference/PreviewEngineEdit';
import PreferenceScanEdit from './preference/ScanEdit';
import PreferenceIndex from "./preference/Index";
import PreferenceEdit from "./preference/Edit";
import PreferenceEngineEdit from "./preference/PreviewEngineEdit";
import PreferenceScanEdit from "./preference/ScanEdit";
import DashboardIndex from './dashboard/Index';
import InstallIndex from './install/Index';
import DashboardIndex from "./dashboard/Index";
import InstallIndex from "./install/Index";
import MatterList from './matter/List';
import MatterDetail from './matter/Detail';
import MatterList from "./matter/List";
import MatterDetail from "./matter/Detail";
import BinList from './bin/List';
import ShareList from './share/List';
import ShareDetail from './share/Detail';
import User from '../common/model/user/User';
import Moon from '../common/model/global/Moon';
import Sun from '../common/model/global/Sun';
import ShareList from "./share/List";
import ShareDetail from "./share/Detail";
import User from "../common/model/user/User";
import Moon from "../common/model/global/Moon";
import Sun from "../common/model/global/Sun";
import FrameLoading from "./widget/FrameLoading";
import Preference from "../common/model/preference/Preference";
import {WebResultCode} from "../common/model/base/WebResultCode";
import { WebResultCode } from "../common/model/base/WebResultCode";
import MessageBoxUtil from "../common/util/MessageBoxUtil";
import BottomLayout from "./layout/BottomLayout";
import SideLayout from "./layout/SideLayout";
import TopLayout from "./layout/TopLayout";
import ContentLayout from "./layout/ContentLayout";
interface IProps extends RouteComponentProps<{}> {
}
interface IState {
}
interface IProps extends RouteComponentProps<{}> {}
interface IState {}
class RawFrame extends TankComponent<IProps, IState> {
user: User = Moon.getSingleton().user;
preference: Preference = Moon.getSingleton().preference;
//是否已经完成初始化
initialized: boolean = false
initialized: boolean = false;
constructor(props: IProps) {
super(props);
}
componentDidMount() {
//装载全局的路由
Sun.getSingleton().reactRouter = this.props.history;
//装在全局Frame
Sun.getSingleton().frameComponent = this
Sun.getSingleton().frameComponent = this;
this.initialize();
}
//获取当前登录者的信息
initialize() {
let that = this;
let pathname: string = that.props.location.pathname
let pathname: string = that.props.location.pathname;
this.preference.httpFetch(function () {
let whitePaths = ['/user/login', '/user/register'];
//如果当前本身是登录界面,那么不用去获取。
if (whitePaths.indexOf(pathname) == -1 && !pathname.startsWith("/user/authentication")) {
that.user.httpInfo(null, null, function () {
that.initialized = true
this.preference.httpFetch(
function () {
let whitePaths = ["/user/login", "/user/register"];
//如果当前本身是登录界面,那么不用去获取。
if (
whitePaths.indexOf(pathname) == -1 &&
!pathname.startsWith("/user/authentication")
) {
that.user.httpInfo(null, null, function () {
that.initialized = true;
that.updateUI();
});
} else {
that.initialized = true;
that.updateUI();
});
} else {
that.initialized = true
}
},
function (errMessage: string, response: any) {
that.initialized = true;
that.updateUI();
if (
response &&
response.data &&
response.data["code"] === WebResultCode.NOT_INSTALLED
) {
MessageBoxUtil.warning("网站尚未安装,即将引导进入安装页面!");
that.preference.installed = false;
Sun.navigateTo("/install/index");
}
}
}, function (errMessage: string, response: any) {
that.initialized = true
that.updateUI()
if (response && response.data && response.data["code"] === WebResultCode.NOT_INSTALLED) {
MessageBoxUtil.warning("网站尚未安装,即将引导进入安装页面!")
that.preference.installed = false
Sun.navigateTo("/install/index")
}
})
);
}
render() {
let content: React.ReactNode;
if (this.initialized) {
content = (
<div className="pages-frame-inner">
<SideLayout />
<SideLayout/>
<TopLayout/>
<TopLayout />
<ContentLayout>
{
this.preference.installed ? (
<div className="pages-content">
<Route exact path="/" render={() =>
<Redirect to="/matter/list"/>
}/>
<Route path="/user/login" component={UserLogin}/>
<Route path="/user/register" component={UserRegister}/>
<Route path="/user/detail/:uuid" component={UserDetail}/>
<Route path="/user/list" component={UserList}/>
<Route path="/mobile/user/list" component={MobileUserList}/>
<Route path="/user/create" component={UserEdit}/>
<Route path="/user/edit/:uuid" component={UserEdit}/>
<Route path="/user/authentication/:authentication" component={UserAuthentication}/>
{this.preference.installed ? (
<div className="pages-content">
<Route
exact
path="/"
render={() => <Redirect to="/matter/list" />}
/>
<Route path="/user/login" component={UserLogin} />
<Route path="/user/register" component={UserRegister} />
<Route path="/user/detail/:uuid" component={UserDetail} />
<Route path="/user/list" component={UserList} />
<Route path="/mobile/user/list" component={MobileUserList} />
<Route path="/user/create" component={UserEdit} />
<Route path="/user/edit/:uuid" component={UserEdit} />
<Route
path="/user/authentication/:authentication"
component={UserAuthentication}
/>
<Route path="/dashboard/index" component={DashboardIndex}/>
<Route path="/dashboard/index" component={DashboardIndex} />
<Route path="/preference/index" component={PreferenceIndex}/>
<Route path="/preference/edit" component={PreferenceEdit}/>
<Route path="/preference/engine/edit" component={PreferenceEngineEdit}/>
<Route path="/preference/scan/edit" component={PreferenceScanEdit}/>
<Route path="/preference/index" component={PreferenceIndex} />
<Route path="/preference/edit" component={PreferenceEdit} />
<Route
path="/preference/engine/edit"
component={PreferenceEngineEdit}
/>
<Route
path="/preference/scan/edit"
component={PreferenceScanEdit}
/>
<Route path="/matter/detail/:uuid" component={MatterDetail}/>
<Route exact path="/matter" render={() =>
<Redirect to="/matter/list"/>
}/>
<Route path="/matter/list" component={MatterList}/>
<Route path="/matter/detail/:uuid" component={MatterDetail} />
<Route
exact
path="/matter"
render={() => <Redirect to="/matter/list" />}
/>
<Route path="/matter/list" component={MatterList} />
<Route path="/share/list" component={ShareList}/>
<Route path="/share/detail/:uuid" component={ShareDetail}/>
</div>
) : (
<div className="pages-content">
<Route path="/install/index" component={InstallIndex}/>
</div>
)
}
<Route path="/share/list" component={ShareList} />
<Route path="/share/detail/:uuid" component={ShareDetail} />
<Route path="/bin/list" component={BinList} />
</div>
) : (
<div className="pages-content">
<Route path="/install/index" component={InstallIndex} />
</div>
)}
</ContentLayout>
<BottomLayout/>
<BottomLayout />
</div>
)
);
} else {
content = (
<FrameLoading/>
)
content = <FrameLoading />;
}
return (
<div className="pages-frame">
{content}
</div>
);
return <div className="pages-frame">{content}</div>;
}
}
+3
View File
@@ -0,0 +1,3 @@
.page-bin {
}
+327 -6
View File
@@ -1,22 +1,343 @@
import React from "react";
import { Link, RouteComponentProps } from "react-router-dom";
import { RouteComponentProps } from "react-router-dom";
import "./List.less";
import TankComponent from "../../common/component/TankComponent";
import Pager from "../../common/model/base/Pager";
import Matter from "../../common/model/matter/Matter";
import Moon from "../../common/model/global/Moon";
import SortDirection from "../../common/model/base/SortDirection";
import MatterPanel from "../matter/widget/MatterPanel";
import {
Button,
Col,
Empty,
Input,
Modal,
Pagination,
Row,
Space,
} from "antd";
import MessageBoxUtil from "../../common/util/MessageBoxUtil";
import {
ExclamationCircleFilled,
PlusSquareOutlined,
MinusSquareOutlined,
SyncOutlined,
DeleteOutlined,
} from "@ant-design/icons";
import ImagePreviewer from "../widget/previewer/ImagePreviewer";
import Sun from "../../common/model/global/Sun";
import { UserRole } from "../../common/model/user/UserRole";
import BreadcrumbModel from "../../common/model/base/option/BreadcrumbModel";
import BreadcrumbPanel from "../widget/BreadcrumbPanel";
import Lang from "../../common/model/global/Lang";
interface IProps extends RouteComponentProps {}
interface IState {}
export default class List extends TankComponent<IProps, IState>{
export default class List extends TankComponent<IProps, IState> {
//当前文件夹信息。
matter = new Matter();
//当前选中的文件
selectedMatters: Matter[] = [];
//搜索的文字
searchText: string | null = null;
//获取分页的一个帮助器
pager = new Pager<Matter>(this, Matter, 100);
user = Moon.getSingleton().user;
preference = Moon.getSingleton().preference;
//当前面包屑模型数组。
breadcrumbModels: BreadcrumbModel[] = [];
constructor(props: IProps) {
super(props);
}
render() {
return (
<div>
componentDidMount() {
//刷新一下列表
if (this.user.role === UserRole.ADMINISTRATOR) {
this.pager.getFilter("userUuid")!.visible = true;
} else {
this.pager.setFilterValue("userUuid", this.user.uuid);
}
this.pager.enableHistory();
this.refresh();
}
componentWillReceiveProps(nextProps: Readonly<IProps>, nextContext: any) {
if (this.props.location.search !== nextProps.location.search) {
this.pager.enableHistory();
this.refresh();
}
}
refresh = () => {
// 清空暂存区
this.selectedMatters = [];
// 刷新文件列表
this.refreshPager();
// 刷新面包屑
this.refreshBreadcrumbs();
};
refreshPager = () => {
// 初始化当前matter uuid
if (this.matter.uuid !== this.pager.getFilterValue("puuid")) {
this.matter.uuid =
this.pager.getFilterValue("puuid") || Matter.MATTER_ROOT;
}
this.pager.setFilterValue("puuid", this.matter.uuid);
//如果没有任何的排序,默认使用时间倒序和文件夹在顶部
if (!this.pager.getCurrentSortFilter()) {
this.pager.setFilterValue("orderCreateTime", SortDirection.DESC);
this.pager.setFilterValue("orderDir", SortDirection.DESC);
}
//如果没有设置用户的话,那么默认显示当前登录用户的资料
if (!this.pager.getFilterValue("userUuid")) {
this.pager.setFilterValue("userUuid", this.user.uuid);
}
// 过滤掉被软删除的文件
this.pager.setFilterValue("deleted", true);
this.pager.httpList();
};
checkMatter = (matter?: Matter) => {
if (matter) {
if (matter.check) {
this.selectedMatters.push(matter);
} else {
const index = this.selectedMatters.findIndex(
(item) => item.uuid === matter.uuid
);
this.selectedMatters.splice(index, 1);
}
} else {
//统计所有的勾选
this.selectedMatters = [];
this.pager.data.forEach((matter) => {
if (matter.check) {
this.selectedMatters.push(matter);
}
});
}
this.updateUI();
};
checkAll = () => {
this.pager.data.forEach((i) => {
i.check = true;
});
this.checkMatter();
};
checkNone = () => {
this.pager.data.forEach((i) => {
i.check = false;
});
this.checkMatter();
};
deleteBatch = () => {
Modal.confirm({
title: Lang.t("actionCanNotRevertConfirm"),
icon: <ExclamationCircleFilled twoToneColor="#FFDC00" />,
onOk: () => {
const uuids = this.selectedMatters.map((i) => i.uuid).toString();
this.matter.httpDeleteBatch(uuids, () => {
MessageBoxUtil.success(Lang.t("operationSuccess"));
this.refresh();
});
},
});
};
searchFile = (value?: string) => {
this.pager.resetFilter();
if (value) {
this.pager.setFilterValue("orderCreateTime", SortDirection.DESC);
this.pager.setFilterValue("orderDir", SortDirection.DESC);
this.pager.setFilterValue("name", value);
this.pager.setFilterValue("deleted", true);
this.pager.httpList();
} else {
this.refresh();
}
};
changeSearch = (e: any) => {
if (!e.currentTarget.value) this.searchFile();
};
changePage = (page: number) => {
this.pager.page = page - 1; // page的页数0基
this.pager.httpList();
this.updateUI();
};
previewImage = (matter: Matter) => {
let imageArray: string[] = [];
let startIndex = -1;
this.pager.data.forEach((item) => {
if (item.isImage()) {
imageArray.push(item.getPreviewUrl());
if (item.uuid === matter.uuid) {
startIndex = imageArray.length - 1;
}
}
});
ImagePreviewer.showMultiPhoto(imageArray, startIndex);
};
goToDirectory = (id: string) => {
this.searchText = null;
this.pager.setFilterValue("puuid", id);
this.pager.page = 0;
const query = this.pager.getParams();
Sun.navigateQueryTo({ path: "/matter/list", query });
this.refresh();
};
//刷新面包屑
refreshBreadcrumbs = () => {
const uuid = this.pager.getFilterValue("puuid") || Matter.MATTER_ROOT;
//根目录简单处理即可。
if (uuid === Matter.MATTER_ROOT) {
this.matter.uuid = Matter.MATTER_ROOT;
this.breadcrumbModels = [
{
name: Lang.t("matter.recycleBin"),
path: "/matter/list",
query: {},
displayDirect: true,
},
];
} else {
this.matter.uuid = uuid;
this.matter.httpDetail(() => {
const arr = [];
let cur: Matter | null = this.matter;
do {
arr.push(cur);
cur = cur.parent;
} while (cur);
this.breadcrumbModels = arr.reduceRight(
(t: any, item: Matter, i: number) => {
const query = this.pager.getParams();
query["puuid"] = item.uuid!;
t.push({
name: item.name,
path: "/matter/list",
query: query,
displayDirect: !i, // 当前目录不需要导航
});
return t;
},
[
{
name: Lang.t("matter.recycleBin"),
path: "/matter/list",
query: {},
displayDirect: false,
},
]
);
this.updateUI();
});
}
};
render() {
const {
pager,
selectedMatters,
} = this;
return (
<div className="matter-list">
<BreadcrumbPanel breadcrumbModels={this.breadcrumbModels} />
<Row className="mt10">
<Col xs={24} sm={24} md={14} lg={16}>
<Space className="buttons">
{selectedMatters.length !== pager.data.length ? (
<Button type="primary" className="mb10" onClick={this.checkAll}>
<PlusSquareOutlined />
{Lang.t("selectAll")}
</Button>
) : null}
{pager.data.length &&
selectedMatters.length === pager.data.length ? (
<Button
type="primary"
className="mb10"
onClick={this.checkNone}
>
<MinusSquareOutlined />
{Lang.t("cancel")}
</Button>
) : null}
{selectedMatters.length ? (
<Button
type="primary"
className="mb10"
onClick={this.deleteBatch}
>
<DeleteOutlined />
{Lang.t("matter.hardDelete")}
</Button>
) : null}
<Button type="primary" className="mb10" onClick={this.refresh}>
<SyncOutlined />
{Lang.t("refresh")}
</Button>
</Space>
</Col>
<Col xs={24} sm={24} md={10} lg={8}>
<Input.Search
className="mb10"
placeholder={Lang.t("matter.searchFile")}
onSearch={(value) => this.searchFile(value)}
onChange={this.changeSearch}
enterButton
/>
</Col>
</Row>
<div>
{pager.loading || pager.data.length ? (
pager.data.map((matter) => (
<MatterPanel
recycleMode
key={matter.uuid!}
matter={matter}
onGoToDirectory={this.goToDirectory}
onDeleteSuccess={this.refresh}
onCheckMatter={this.checkMatter}
onPreviewImage={this.previewImage}
/>
))
) : (
<Empty description={Lang.t("matter.noContentYet")} />
)}
</div>
<Pagination
className="mt10 pull-right"
onChange={this.changePage}
current={pager.page + 1}
total={pager.totalItems}
pageSize={pager.pageSize}
hideOnSinglePage
/>
</div>
)
);
}
}
+11 -9
View File
@@ -151,22 +151,21 @@ export default class List extends TankComponent<IProps, IState> {
}
refresh = () => {
// 初始化当前matter uuid
if(this.matter.uuid !== this.pager.getFilterValue("puuid")) {
this.matter.uuid = this.pager.getFilterValue("puuid") || Matter.MATTER_ROOT;
}
// 清空暂存区
this.selectedMatters = [];
// 刷新文件列表
this.refreshPager();
// 刷新面包屑
this.refreshBreadcrumbs();
};
refreshPager = () => {
// 初始化当前matter uuid
if (this.matter.uuid !== this.pager.getFilterValue("puuid")) {
this.matter.uuid =
this.pager.getFilterValue("puuid") || Matter.MATTER_ROOT;
}
this.pager.setFilterValue("puuid", this.matter.uuid);
//如果没有任何的排序,默认使用时间倒序和文件夹在顶部
@@ -180,6 +179,9 @@ export default class List extends TankComponent<IProps, IState> {
this.pager.setFilterValue("userUuid", this.user.uuid);
}
// 过滤掉被软删除的文件
this.pager.setFilterValue("deleted", false);
this.pager.httpList();
};
@@ -221,11 +223,11 @@ export default class List extends TankComponent<IProps, IState> {
deleteBatch = () => {
Modal.confirm({
title: Lang.t("actionCanNotRevertConfirm"),
title: Lang.t("actionDeleteConfirm"),
icon: <ExclamationCircleFilled twoToneColor="#FFDC00" />,
onOk: () => {
const uuids = this.selectedMatters.map((i) => i.uuid).toString();
this.matter.httpDeleteBatch(uuids, () => {
this.matter.httpSoftDeleteBatch(uuids, () => {
MessageBoxUtil.success(Lang.t("operationSuccess"));
this.refresh();
});
+9 -3
View File
@@ -21,9 +21,15 @@
line-height: @base-height;
margin-left: 10px;
&-hot {
margin-left: 0;
margin-right: -10px;
padding: 0 10px;
position: relative;
&:after {
position: absolute;
top: 0;
right: -10px;
bottom: 0;
left: -10px;
content: '';
}
}
}
.btn-action{
+148 -123
View File
@@ -28,7 +28,7 @@ import Lang from "../../../common/model/global/Lang";
interface IProps {
matter: Matter;
shareMode?: boolean; // 分享模式
recycleMode?: boolean; // 回收站模式,默认false
director?: Director;
onCreateDirectoryCallback?: () => any;
onDeleteSuccess?: () => any;
@@ -90,6 +90,19 @@ export default class MatterPanel extends TankComponent<IProps, IState> {
};
deleteMatter = () => {
Modal.confirm({
title: Lang.t("actionDeleteConfirm"),
icon: <ExclamationCircleFilled twoToneColor="#FFDC00" />,
onOk: () => {
this.props.matter.httpSoftDelete(() => {
MessageBoxUtil.success(Lang.t("operationSuccess"));
this.props.onDeleteSuccess!();
});
},
});
};
hardDeleteMatter = () => {
Modal.confirm({
title: Lang.t("actionCanNotRevertConfirm"),
icon: <ExclamationCircleFilled twoToneColor="#FFDC00" />,
@@ -210,96 +223,96 @@ export default class MatterPanel extends TankComponent<IProps, IState> {
};
renderPcOperation = () => {
const { matter, shareMode } = this.props;
if (shareMode)
return (
<div className="right-part">
<Tooltip title={Lang.t("download")}>
<DownloadOutlined
className="btn-action text-theme"
const { matter, recycleMode = false } = this.props;
// 文件操作在正常模式 or 回收站模式下不同,其中回收站模式只保留查看信息与彻底删除操作
const handles = recycleMode ? (
<>
<Tooltip title={Lang.t("matter.fileDetail")}>
<InfoCircleOutlined
className="btn-action"
onClick={(e) =>
SafeUtil.stopPropagationWrap(e)(
Sun.navigateTo("/matter/detail/" + matter.uuid)
)
}
/>
</Tooltip>
<Tooltip title={Lang.t("matter.hardDelete")}>
<DeleteOutlined
className="btn-action text-danger"
onClick={(e) =>
SafeUtil.stopPropagationWrap(e)(this.hardDeleteMatter())
}
/>
</Tooltip>
</>
) : (
<>
{!matter.dir && matter.privacy && (
<Tooltip title={Lang.t("matter.setPublic")}>
<UnlockOutlined
className="btn-action"
onClick={(e) =>
SafeUtil.stopPropagationWrap(e)(matter.download())
SafeUtil.stopPropagationWrap(e)(this.changePrivacy(false))
}
/>
</Tooltip>
<Tooltip title={Lang.t("matter.size")}>
<span className="matter-size">
{StringUtil.humanFileSize(matter.size)}
</span>
)}
{!matter.dir && !matter.privacy && (
<Tooltip title={Lang.t("matter.setPrivate")}>
<LockOutlined
className="btn-action"
onClick={(e) =>
SafeUtil.stopPropagationWrap(e)(this.changePrivacy(true))
}
/>
</Tooltip>
)}
<Tooltip title={Lang.t("matter.fileDetail")}>
<InfoCircleOutlined
className="btn-action"
onClick={(e) =>
SafeUtil.stopPropagationWrap(e)(
Sun.navigateTo("/matter/detail/" + matter.uuid)
)
}
/>
</Tooltip>
<Tooltip title={Lang.t("matter.rename")}>
<EditOutlined
className="btn-action"
onClick={(e) =>
SafeUtil.stopPropagationWrap(e)(this.prepareRename())
}
/>
</Tooltip>
<Tooltip title={Lang.t("matter.copyPath")}>
<LinkOutlined
className="btn-action"
onClick={(e) => SafeUtil.stopPropagationWrap(e)(this.clipboard())}
/>
</Tooltip>
<Tooltip title={Lang.t("matter.download")}>
<DownloadOutlined
className="btn-action"
onClick={(e) => SafeUtil.stopPropagationWrap(e)(matter.download())}
/>
</Tooltip>
<Tooltip title={Lang.t("matter.delete")}>
<DeleteOutlined
className="btn-action text-danger"
onClick={(e) =>
SafeUtil.stopPropagationWrap(e)(this.deleteMatter())
}
/>
</Tooltip>
</>
);
<Tooltip title={Lang.t("matter.updateTime")}>
<span className="matter-date mr10">
{DateUtil.simpleDateHourMinute(matter.updateTime)}
</span>
</Tooltip>
</div>
);
return (
<div className="right-part">
<span className="matter-operation text-theme">
{!matter.dir && matter.privacy && (
<Tooltip title={Lang.t("matter.setPublic")}>
<UnlockOutlined
className="btn-action"
onClick={(e) =>
SafeUtil.stopPropagationWrap(e)(this.changePrivacy(false))
}
/>
</Tooltip>
)}
{!matter.dir && !matter.privacy && (
<Tooltip title={Lang.t("matter.setPrivate")}>
<LockOutlined
className="btn-action"
onClick={(e) =>
SafeUtil.stopPropagationWrap(e)(this.changePrivacy(true))
}
/>
</Tooltip>
)}
<Tooltip title={Lang.t("matter.fileDetail")}>
<InfoCircleOutlined
className="btn-action"
onClick={(e) =>
SafeUtil.stopPropagationWrap(e)(
Sun.navigateTo("/matter/detail/" + matter.uuid)
)
}
/>
</Tooltip>
<Tooltip title={Lang.t("matter.rename")}>
<EditOutlined
className="btn-action"
onClick={(e) =>
SafeUtil.stopPropagationWrap(e)(this.prepareRename())
}
/>
</Tooltip>
<Tooltip title={Lang.t("matter.copyPath")}>
<LinkOutlined
className="btn-action"
onClick={(e) => SafeUtil.stopPropagationWrap(e)(this.clipboard())}
/>
</Tooltip>
<Tooltip title={Lang.t("matter.download")}>
<DownloadOutlined
className="btn-action"
onClick={(e) =>
SafeUtil.stopPropagationWrap(e)(matter.download())
}
/>
</Tooltip>
<Tooltip title={Lang.t("matter.delete")}>
<DeleteOutlined
className="btn-action text-danger"
onClick={(e) =>
SafeUtil.stopPropagationWrap(e)(this.deleteMatter())
}
/>
</Tooltip>
</span>
<span className="matter-operation text-theme">{handles}</span>
<Tooltip title={Lang.t("matter.size")}>
<span className="matter-size">
{StringUtil.humanFileSize(matter.size)}
@@ -315,34 +328,34 @@ export default class MatterPanel extends TankComponent<IProps, IState> {
};
renderMobileOperation = () => {
const { matter, shareMode } = this.props;
if (shareMode)
return (
<div className="more-panel">
<div className="cell-btn navy text">
<span>{DateUtil.simpleDateHourMinute(matter.updateTime)}</span>
<span className="matter-size">
{StringUtil.humanFileSize(matter.size)}
</span>
</div>
<div
className="cell-btn navy"
onClick={(e) => SafeUtil.stopPropagationWrap(e)(matter.download())}
>
<DownloadOutlined className="btn-action mr5" />
{Lang.t("matter.download")}
</div>
</div>
);
return (
<div className="more-panel">
<div className="cell-btn navy text">
<span>{DateUtil.simpleDateHourMinute(matter.updateTime)}</span>
<span className="matter-size">
{StringUtil.humanFileSize(matter.size)}
</span>
</div>
const { matter, recycleMode = false } = this.props;
// 文件操作在正常模式 or 回收站模式下不同,其中回收站模式只保留查看信息与彻底删除操作
const handles = recycleMode ? (
<>
<div
className="cell-btn navy"
onClick={(e) =>
SafeUtil.stopPropagationWrap(e)(
Sun.navigateTo("/matter/detail/" + matter.uuid)
)
}
>
<InfoCircleOutlined className="btn-action mr5" />
{Lang.t("matter.fileDetail")}
</div>
<div
className="cell-btn text-danger"
onClick={(e) =>
SafeUtil.stopPropagationWrap(e)(this.hardDeleteMatter())
}
>
<DeleteOutlined className="btn-action mr5" />
{Lang.t("matter.hardDelete")}
</div>
</>
) : (
<>
{!matter.dir && matter.privacy && (
<div
className="cell-btn navy"
@@ -406,12 +419,24 @@ export default class MatterPanel extends TankComponent<IProps, IState> {
<DeleteOutlined className="btn-action mr5" />
{Lang.t("matter.delete")}
</div>
</>
);
return (
<div className="more-panel">
<div className="cell-btn navy text">
<span>{DateUtil.simpleDateHourMinute(matter.updateTime)}</span>
<span className="matter-size">
{StringUtil.humanFileSize(matter.size)}
</span>
</div>
{handles}
</div>
);
};
render() {
const { matter, shareMode } = this.props;
const { matter } = this.props;
return (
<div className="widget-matter-panel">
@@ -419,17 +444,15 @@ export default class MatterPanel extends TankComponent<IProps, IState> {
<div className="media clearfix">
<div className="pull-left">
<div className="left-part">
{!shareMode && (
<span
className="cell cell-hot"
onClick={(e) => SafeUtil.stopPropagationWrap(e)}
>
<Checkbox
checked={matter.check}
onChange={this.checkToggle}
/>
</span>
)}
<span
className="cell cell-hot"
onClick={(e) => SafeUtil.stopPropagationWrap(e)}
>
<Checkbox
checked={matter.check}
onChange={this.checkToggle}
/>
</span>
<span className="cell">
<img className="matter-icon" src={matter.getIcon()} />
</span>
@@ -470,7 +493,9 @@ export default class MatterPanel extends TankComponent<IProps, IState> {
<span className="matter-name">
{matter.name}
{!matter.dir && !matter.privacy && (
<Tooltip title={Lang.t("matter.publicFileEveryoneCanVisit")}>
<Tooltip
title={Lang.t("matter.publicFileEveryoneCanVisit")}
>
<UnlockOutlined className="icon" />
</Tooltip>
)}
@@ -20,11 +20,6 @@
vertical-align: middle;
line-height: @base-height;
margin-left: 10px;
&-hot {
margin-left: 0;
margin-right: -10px;
padding: 0 10px;
}
}
.btn-action{
font-size: 15px;