Web:Files:VirtualRooms: add group menu for virtual room pages
This commit is contained in:
parent
1bee56d3aa
commit
9bfb54bcc3
@ -13,7 +13,37 @@ import VirtualRoomsTable from "./TableView";
|
|||||||
|
|
||||||
import withLoader from "../../../../HOCs/withLoader";
|
import withLoader from "../../../../HOCs/withLoader";
|
||||||
|
|
||||||
const SectionBodyContent = ({ isEmpty, viewAs }) => {
|
const SectionBodyContent = ({
|
||||||
|
isEmpty,
|
||||||
|
viewAs,
|
||||||
|
|
||||||
|
setSelection,
|
||||||
|
setBufferSelection,
|
||||||
|
}) => {
|
||||||
|
React.useEffect(() => {
|
||||||
|
window.addEventListener("mousedown", onMouseDown);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener("mousedown", onMouseDown);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onMouseDown = React.useCallback((e) => {
|
||||||
|
if (
|
||||||
|
(e.target.closest(".scroll-body") &&
|
||||||
|
!e.target.closest(".rooms-item") &&
|
||||||
|
!e.target.closest(".not-selectable") &&
|
||||||
|
!e.target.closest(".info-panel") &&
|
||||||
|
!e.target.closest(".table-container_group-menu")) ||
|
||||||
|
e.target.closest(".files-main-button") ||
|
||||||
|
e.target.closest(".add-button") ||
|
||||||
|
e.target.closest(".search-input-block")
|
||||||
|
) {
|
||||||
|
setSelection([]);
|
||||||
|
setBufferSelection(null);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Consumer>
|
<Consumer>
|
||||||
{(context) =>
|
{(context) =>
|
||||||
@ -34,9 +64,9 @@ const SectionBodyContent = ({ isEmpty, viewAs }) => {
|
|||||||
export default inject(({ filesStore, roomsStore }) => {
|
export default inject(({ filesStore, roomsStore }) => {
|
||||||
const { viewAs } = filesStore;
|
const { viewAs } = filesStore;
|
||||||
|
|
||||||
const { rooms } = roomsStore;
|
const { rooms, setSelection, setBufferSelection } = roomsStore;
|
||||||
|
|
||||||
const isEmpty = rooms.length < 1;
|
const isEmpty = rooms.length === 0;
|
||||||
|
|
||||||
return { viewAs, isEmpty };
|
return { viewAs, isEmpty, setSelection, setBufferSelection };
|
||||||
})(withTranslation([])(withLoader(observer(SectionBodyContent))()));
|
})(withTranslation([])(withLoader(observer(SectionBodyContent))()));
|
||||||
|
@ -1,60 +1,213 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import styled from "styled-components";
|
import styled, { css } from "styled-components";
|
||||||
import { inject, observer } from "mobx-react";
|
import { inject, observer } from "mobx-react";
|
||||||
import { withTranslation } from "react-i18next";
|
import { withTranslation } from "react-i18next";
|
||||||
|
|
||||||
import { isMobile } from "react-device-detect";
|
import { isMobile } from "react-device-detect";
|
||||||
|
|
||||||
import { tablet } from "@appserver/components/utils/device";
|
import { tablet } from "@appserver/components/utils/device";
|
||||||
|
|
||||||
import Headline from "@appserver/common/components/Headline";
|
import Navigation from "@appserver/common/components/Navigation";
|
||||||
|
|
||||||
import IconButton from "@appserver/components/icon-button";
|
|
||||||
import withLoader from "../../../../HOCs/withLoader";
|
|
||||||
import Loaders from "@appserver/common/components/Loaders";
|
import Loaders from "@appserver/common/components/Loaders";
|
||||||
|
|
||||||
|
import TableGroupMenu from "@appserver/components/table-container/TableGroupMenu";
|
||||||
|
|
||||||
|
import withLoader from "../../../../HOCs/withLoader";
|
||||||
|
import { Consumer } from "@appserver/components/utils/context";
|
||||||
|
import { FolderType } from "@appserver/common/constants";
|
||||||
|
import DropDownItem from "@appserver/components/drop-down-item";
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
width: 100%;
|
.table-container_group-menu {
|
||||||
height: 53px;
|
${(props) =>
|
||||||
display: flex;
|
props.viewAs === "table"
|
||||||
align-items: center;
|
? css`
|
||||||
`;
|
margin: 0px -20px;
|
||||||
|
width: calc(100% + 40px);
|
||||||
|
`
|
||||||
|
: css`
|
||||||
|
margin: 0px -20px;
|
||||||
|
width: calc(100% + 40px);
|
||||||
|
`}
|
||||||
|
|
||||||
const StyledHeadline = styled(Headline)`
|
@media ${tablet} {
|
||||||
font-weight: 700;
|
margin: 0 -16px;
|
||||||
font-size: ${isMobile ? "21px !important" : "18px"};
|
width: calc(100% + 32px);
|
||||||
line-height: ${isMobile ? "28px !important" : "24px"};
|
}
|
||||||
|
|
||||||
margin-right: 16px;
|
${isMobile &&
|
||||||
|
css`
|
||||||
@media ${tablet} {
|
margin: 0 -16px;
|
||||||
font-size: 21px;
|
width: calc(100% + 32px);
|
||||||
line-height: 28px;
|
`}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const SectionHeaderContent = ({ createRoom, title }) => {
|
const SectionHeaderContent = ({
|
||||||
return (
|
t,
|
||||||
<StyledContainer>
|
|
||||||
<StyledHeadline>{title}</StyledHeadline>
|
createRoom,
|
||||||
<IconButton
|
viewAs,
|
||||||
zIndex={402}
|
title,
|
||||||
className="create-button"
|
showText,
|
||||||
directionX="right"
|
isArchive,
|
||||||
iconName="images/plus.svg"
|
isDesktop,
|
||||||
size={15}
|
isTabletView,
|
||||||
isFill
|
tReady,
|
||||||
onClick={createRoom}
|
navigationPath,
|
||||||
isDisabled={false}
|
|
||||||
|
isHeaderVisible,
|
||||||
|
isHeaderChecked,
|
||||||
|
isHeaderIndeterminate,
|
||||||
|
checkboxMenuItems,
|
||||||
|
getRoomCheckboxTitle,
|
||||||
|
setSelected,
|
||||||
|
|
||||||
|
getHeaderMenu,
|
||||||
|
|
||||||
|
toggleInfoPanel,
|
||||||
|
isInfoPanelVisible,
|
||||||
|
}) => {
|
||||||
|
const getContextOptionsPlus = () => {
|
||||||
|
return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
const getContextOptionsFolder = () => {
|
||||||
|
return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderGroupMenu = React.useCallback(() => {
|
||||||
|
const onSelected = (e) => {
|
||||||
|
setSelected && setSelected(e.target.dataset.key);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onChange = (checked) => {
|
||||||
|
setSelected && setSelected(checked ? "all" : "none");
|
||||||
|
};
|
||||||
|
|
||||||
|
const menuItems = (
|
||||||
|
<>
|
||||||
|
{checkboxMenuItems.map((key) => {
|
||||||
|
const label = getRoomCheckboxTitle(t, key);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DropDownItem
|
||||||
|
key={key}
|
||||||
|
label={label}
|
||||||
|
data-key={key}
|
||||||
|
onClick={onSelected}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
const headerMenu = getHeaderMenu(t);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableGroupMenu
|
||||||
|
checkboxOptions={menuItems}
|
||||||
|
onChange={onChange}
|
||||||
|
isChecked={isHeaderChecked}
|
||||||
|
isIndeterminate={isHeaderIndeterminate}
|
||||||
|
headerMenu={headerMenu}
|
||||||
|
isInfoPanelVisible={isInfoPanelVisible}
|
||||||
|
toggleInfoPanel={toggleInfoPanel}
|
||||||
/>
|
/>
|
||||||
</StyledContainer>
|
);
|
||||||
|
}, [
|
||||||
|
t,
|
||||||
|
isHeaderChecked,
|
||||||
|
isHeaderIndeterminate,
|
||||||
|
checkboxMenuItems,
|
||||||
|
getRoomCheckboxTitle,
|
||||||
|
getHeaderMenu,
|
||||||
|
setSelected,
|
||||||
|
toggleInfoPanel,
|
||||||
|
isInfoPanelVisible,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Consumer>
|
||||||
|
{(context) => (
|
||||||
|
<StyledContainer width={context.sectionWidth} viewAs={viewAs}>
|
||||||
|
{isHeaderVisible ? (
|
||||||
|
renderGroupMenu()
|
||||||
|
) : (
|
||||||
|
<div className="header-container">
|
||||||
|
<Navigation
|
||||||
|
sectionWidth={context.sectionWidth}
|
||||||
|
showText={showText}
|
||||||
|
isRootFolder={true}
|
||||||
|
canCreate={!isArchive}
|
||||||
|
title={title}
|
||||||
|
isDesktop={isDesktop}
|
||||||
|
isTabletView={isTabletView}
|
||||||
|
personal={false}
|
||||||
|
tReady={tReady}
|
||||||
|
navigationItems={navigationPath}
|
||||||
|
getContextOptionsPlus={getContextOptionsPlus}
|
||||||
|
getContextOptionsFolder={getContextOptionsFolder}
|
||||||
|
// toggleInfoPanel={toggleInfoPanel} TODO: return after adding info-panel for rooms
|
||||||
|
isInfoPanelVisible={isInfoPanelVisible}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</StyledContainer>
|
||||||
|
)}
|
||||||
|
</Consumer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default inject(({ roomsStore, selectedFolderStore }) => {
|
export default inject(
|
||||||
const { createRoom } = roomsStore;
|
({
|
||||||
|
auth,
|
||||||
|
roomsStore,
|
||||||
|
roomsActionsStore,
|
||||||
|
filesStore,
|
||||||
|
selectedFolderStore,
|
||||||
|
}) => {
|
||||||
|
const {
|
||||||
|
isHeaderVisible,
|
||||||
|
isHeaderChecked,
|
||||||
|
isHeaderIndeterminate,
|
||||||
|
checkboxMenuItems,
|
||||||
|
getRoomCheckboxTitle,
|
||||||
|
setSelected,
|
||||||
|
} = roomsStore;
|
||||||
|
|
||||||
return { createRoom, title: selectedFolderStore.title };
|
const { getHeaderMenu } = roomsActionsStore;
|
||||||
})(
|
|
||||||
|
const { viewAs } = filesStore;
|
||||||
|
|
||||||
|
const { toggleIsVisible, isVisible } = auth.infoPanelStore;
|
||||||
|
|
||||||
|
const { title, rootFolderType, navigationPath } = selectedFolderStore;
|
||||||
|
|
||||||
|
const isArchive = rootFolderType === FolderType.Archive;
|
||||||
|
|
||||||
|
return {
|
||||||
|
showText: auth.settingsStore.showText,
|
||||||
|
isDesktop: auth.settingsStore.isDesktopClient,
|
||||||
|
isTabletView: auth.settingsStore.isTabletView,
|
||||||
|
viewAs,
|
||||||
|
title,
|
||||||
|
isArchive,
|
||||||
|
navigationPath,
|
||||||
|
|
||||||
|
isHeaderVisible,
|
||||||
|
isHeaderChecked,
|
||||||
|
isHeaderIndeterminate,
|
||||||
|
checkboxMenuItems,
|
||||||
|
getRoomCheckboxTitle,
|
||||||
|
setSelected,
|
||||||
|
|
||||||
|
getHeaderMenu,
|
||||||
|
|
||||||
|
toggleInfoPanel: toggleIsVisible,
|
||||||
|
isInfoPanelVisible: isVisible,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)(
|
||||||
withTranslation([])(
|
withTranslation([])(
|
||||||
withLoader(observer(SectionHeaderContent))(<Loaders.SectionHeader />)
|
withLoader(observer(SectionHeaderContent))(<Loaders.SectionHeader />)
|
||||||
)
|
)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { makeAutoObservable, runInAction } from "mobx";
|
import { makeAutoObservable, runInAction } from "mobx";
|
||||||
import { AppServerConfig } from "@appserver/common/constants";
|
import { AppServerConfig, FolderType } from "@appserver/common/constants";
|
||||||
|
|
||||||
import toastr from "studio/toastr";
|
import toastr from "studio/toastr";
|
||||||
|
|
||||||
@ -62,8 +62,60 @@ class RoomsActionsStore {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onSelectRoom = (id) => {
|
getHeaderMenu = (t) => {
|
||||||
console.log(id);
|
const { selection } = this.roomsStore;
|
||||||
|
|
||||||
|
if (selection.length === 0) return;
|
||||||
|
|
||||||
|
const pinOption =
|
||||||
|
selection.findIndex((room) => !room.pinned) > -1
|
||||||
|
? this.getOption("pin", t)
|
||||||
|
: this.getOption("unpin", t);
|
||||||
|
|
||||||
|
const archiveOption =
|
||||||
|
selection.findIndex((room) => room.rootFolderType === FolderType.Rooms) >
|
||||||
|
-1
|
||||||
|
? this.getOption("archive", t)
|
||||||
|
: this.getOption("unarchive", t);
|
||||||
|
|
||||||
|
return [pinOption, archiveOption];
|
||||||
|
};
|
||||||
|
|
||||||
|
getOption = (option, t) => {
|
||||||
|
switch (option) {
|
||||||
|
case "pin":
|
||||||
|
return {
|
||||||
|
key: "pin",
|
||||||
|
label: "Pin to top",
|
||||||
|
iconUrl: "/static/images/pin.react.svg",
|
||||||
|
onClick: () => console.log("pin"),
|
||||||
|
disabled: false,
|
||||||
|
};
|
||||||
|
case "unpin":
|
||||||
|
return {
|
||||||
|
key: "unpin",
|
||||||
|
label: "Unpin",
|
||||||
|
iconUrl: "/static/images/unpin.react.svg",
|
||||||
|
onClick: () => console.log("unpin"),
|
||||||
|
disabled: false,
|
||||||
|
};
|
||||||
|
case "archive":
|
||||||
|
return {
|
||||||
|
key: "archive",
|
||||||
|
label: "Move to archive",
|
||||||
|
iconUrl: "/static/images/room.archive.svg",
|
||||||
|
onClick: () => console.log("to archive"),
|
||||||
|
disabled: false,
|
||||||
|
};
|
||||||
|
case "unarchive":
|
||||||
|
return {
|
||||||
|
key: "unarchive",
|
||||||
|
label: "Move from archive",
|
||||||
|
iconUrl: "/static/images/room.archive.svg",
|
||||||
|
onClick: () => console.log("from archive"),
|
||||||
|
disabled: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onSelectTag = (tag) => {
|
onSelectTag = (tag) => {
|
||||||
|
@ -87,6 +87,10 @@ class RoomsStore {
|
|||||||
this.bufferSelection = item;
|
this.bufferSelection = item;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
setHeaderVisible = (isHeaderVisible) => {
|
||||||
|
this.isHeaderVisible = isHeaderVisible;
|
||||||
|
};
|
||||||
|
|
||||||
sortRooms = (sortBy, sortOrder) => {
|
sortRooms = (sortBy, sortOrder) => {
|
||||||
const newFilter = this.filter.clone();
|
const newFilter = this.filter.clone();
|
||||||
|
|
||||||
@ -181,6 +185,22 @@ class RoomsStore {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
setSelected = (selected) => {
|
||||||
|
if (selected === "none") {
|
||||||
|
this.setBufferSelection(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
const newSelection = [];
|
||||||
|
|
||||||
|
this.rooms.forEach((room) => {
|
||||||
|
const checked = this.getRoomChecked(room, selected);
|
||||||
|
|
||||||
|
if (checked) newSelection.push(room);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.selection = newSelection;
|
||||||
|
};
|
||||||
|
|
||||||
openContextMenu = (item) => {
|
openContextMenu = (item) => {
|
||||||
if (this.selection.length > 0) return;
|
if (this.selection.length > 0) return;
|
||||||
|
|
||||||
@ -256,6 +276,88 @@ class RoomsStore {
|
|||||||
|
|
||||||
return request();
|
return request();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
getRoomCheckboxTitle = (t, key) => {
|
||||||
|
switch (key) {
|
||||||
|
case "all":
|
||||||
|
return t("All");
|
||||||
|
case RoomsType.FillingFormsRoom:
|
||||||
|
return "Filling form rooms";
|
||||||
|
case RoomsType.CustomRoom:
|
||||||
|
return "Custom rooms";
|
||||||
|
case RoomsType.EditingRoom:
|
||||||
|
return "Editing rooms";
|
||||||
|
case RoomsType.ReviewRoom:
|
||||||
|
return "Review rooms";
|
||||||
|
case RoomsType.ReadOnlyRoom:
|
||||||
|
return "Read-only rooms";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
getRoomChecked = (room, selected) => {
|
||||||
|
const type = room.roomType;
|
||||||
|
|
||||||
|
switch (selected) {
|
||||||
|
case "all":
|
||||||
|
return true;
|
||||||
|
case RoomsType.FillingFormsRoom:
|
||||||
|
return type === RoomsType.FillingFormsRoom;
|
||||||
|
case RoomsType.CustomRoom:
|
||||||
|
return type === RoomsType.CustomRoom;
|
||||||
|
case RoomsType.EditingRoom:
|
||||||
|
return type === RoomsType.EditingRoom;
|
||||||
|
case RoomsType.ReviewRoom:
|
||||||
|
return type === RoomsType.ReviewRoom;
|
||||||
|
case RoomsType.ReadOnlyRoom:
|
||||||
|
return type === RoomsType.ReadOnlyRoom;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
get isHeaderVisible() {
|
||||||
|
return this.selection.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isHeaderIndeterminate() {
|
||||||
|
return this.isHeaderVisible && this.selection.length
|
||||||
|
? this.selection.length < this.rooms.length
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isHeaderChecked() {
|
||||||
|
return this.isHeaderVisible && this.selection.length === this.rooms.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
get checkboxMenuItems() {
|
||||||
|
let cbMenu = ["all"];
|
||||||
|
|
||||||
|
for (const item of this.rooms) {
|
||||||
|
switch (item.roomType) {
|
||||||
|
case RoomsType.FillingFormsRoom:
|
||||||
|
cbMenu.push(RoomsType.FillingFormsRoom);
|
||||||
|
break;
|
||||||
|
case RoomsType.CustomRoom:
|
||||||
|
cbMenu.push(RoomsType.CustomRoom);
|
||||||
|
break;
|
||||||
|
case RoomsType.EditingRoom:
|
||||||
|
cbMenu.push(RoomsType.EditingRoom);
|
||||||
|
break;
|
||||||
|
case RoomsType.ReviewRoom:
|
||||||
|
cbMenu.push(RoomsType.ReviewRoom);
|
||||||
|
break;
|
||||||
|
case RoomsType.ReadOnlyRoom:
|
||||||
|
cbMenu.push(RoomsType.ReadOnlyRoom);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cbMenu = cbMenu.filter((item, index) => cbMenu.indexOf(item) === index);
|
||||||
|
|
||||||
|
return cbMenu;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default RoomsStore;
|
export default RoomsStore;
|
||||||
|
Loading…
Reference in New Issue
Block a user