Web: Files: added OFORMs gallery

This commit is contained in:
Nikita Gopienko 2022-03-31 16:10:16 +03:00
parent 83ba8fa153
commit 8c782a7903
21 changed files with 4941 additions and 9 deletions

View File

@ -456,3 +456,11 @@ export function toggleTipsSubscription() {
};
return request(options);
}
export function getOforms(url) {
const options = {
method: "get",
url,
};
return request(options);
}

View File

@ -49,6 +49,7 @@ class SettingsStore {
enabledJoin = false;
urlLicense = "https://gnu.org/licenses/gpl-3.0.html";
urlSupport = "https://helpdesk.onlyoffice.com/";
urlOforms = "https://oforms.onlyoffice.com/data/def.json";
logoUrl = combineUrl(proxyURL, "/static/images/nav.logo.opened.react.svg");
customNames = {
id: "Common",
@ -422,6 +423,10 @@ class SettingsStore {
this.theme = themes[theme];
localStorage.setItem("theme", theme);
};
getOforms = () => {
return api.settings.getOforms(this.urlOforms);
};
}
export default SettingsStore;

View File

@ -0,0 +1,15 @@
<svg width="150" height="150" viewBox="0 0 150 150" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_964_170806)">
<path d="M71.4219 20.8414C72.779 18.6071 76.0175 18.595 77.3912 20.8191L144.306 129.161C145.746 131.493 144.069 134.5 141.328 134.5H21.1846H8.6095C5.88051 134.5 4.20137 131.516 5.61805 129.183L71.4219 20.8414Z" fill="url(#paint0_linear_964_170806)" stroke="#333333"/>
<path d="M84.6797 70.3176C84.6797 74.9563 83.6221 80.7454 81.5068 87.6848C81.0244 89.2434 80.5605 90.802 80.1152 92.3606C79.6699 93.9192 79.1875 95.4963 78.668 97.092C77.5547 100.506 76.5342 102.157 75.6064 102.046C74.6045 101.898 73.4912 100.172 72.2666 96.8694C72.0439 96.3128 71.6729 95.2737 71.1533 93.7522C70.6709 92.2307 70.0215 90.2083 69.2051 87.6848C67.0898 80.968 66.0322 75.3274 66.0322 70.763C66.0322 62.8958 69.1494 58.8694 75.3838 58.6838C81.5811 58.5725 84.6797 62.4505 84.6797 70.3176ZM82.4531 111.954C82.4531 113.81 81.8408 115.443 80.6162 116.853C79.2803 118.374 77.5361 119.135 75.3838 119.135C73.1201 119.135 71.3389 118.43 70.04 117.02C68.8154 115.647 68.2031 113.995 68.2031 112.066C68.2031 110.099 68.8154 108.41 70.04 107C71.3018 105.59 73.0273 104.885 75.2168 104.885C77.5176 104.885 79.2988 105.59 80.5605 107C81.8223 108.448 82.4531 110.099 82.4531 111.954Z" fill="white"/>
</g>
<defs>
<linearGradient id="paint0_linear_964_170806" x1="-0.598706" y1="31.0226" x2="80.71" y2="121.735" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFC671"/>
<stop offset="1" stop-color="#FF6F3D"/>
</linearGradient>
<clipPath id="clip0_964_170806">
<rect width="150" height="150" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,4 @@
{
"EmptyScreenHeader": "Failed to load form templates",
"EmptyScreenDescription": "Please check your Internet connection and refresh the page or try later"
}

View File

@ -0,0 +1,4 @@
{
"EmptyScreenHeader": "Не удалось загрузить шаблоны форм",
"EmptyScreenDescription": "Проверьте подключение к Интернету и обновите страницу или повторите попытку позже"
}

View File

@ -1,7 +1,7 @@
import React from "react";
import { Provider as FilesProvider } from "mobx-react";
import { inject, observer } from "mobx-react";
import { Switch } from "react-router-dom";
import { Switch, withRouter } from "react-router-dom";
import config from "../package.json";
import PrivateRoute from "@appserver/common/components/PrivateRoute";
import AppLoader from "@appserver/common/components/AppLoader";
@ -28,6 +28,7 @@ import {
ArticleHeaderContent,
ArticleMainButtonContent,
} from "./components/Article";
import FormGallery from "./pages/FormGallery";
const { proxyURL } = AppServerConfig;
const homepage = config.homepage;
@ -40,6 +41,7 @@ const HISTORY_URL = combineUrl(PROXY_HOMEPAGE_URL, "/:fileId/history");
const PRIVATE_ROOMS_URL = combineUrl(PROXY_HOMEPAGE_URL, "/private");
const FILTER_URL = combineUrl(PROXY_HOMEPAGE_URL, "/filter");
const MEDIA_VIEW_URL = combineUrl(PROXY_HOMEPAGE_URL, "/#preview");
const FORM_GALLERY_URL = combineUrl(PROXY_HOMEPAGE_URL, "/form-gallery");
if (!window.AppServer) {
window.AppServer = {};
@ -56,8 +58,12 @@ window.AppServer.files = {
const Error404 = React.lazy(() => import("studio/Error404"));
const FilesArticle = React.memo(() => {
return (
const FilesArticle = React.memo(({ history }) => {
const isFormGallery = history.location.pathname
.split("/")
.includes("form-gallery");
return !isFormGallery ? (
<Article>
<Article.Header>
<ArticleHeaderContent />
@ -69,6 +75,8 @@ const FilesArticle = React.memo(() => {
<ArticleBodyContent />
</Article.Body>
</Article>
) : (
<></>
);
});
@ -81,6 +89,7 @@ const FilesSection = React.memo(() => {
<PrivateRoute exact path={HOME_URL} component={Home} />
<PrivateRoute path={FILTER_URL} component={Home} />
<PrivateRoute path={MEDIA_VIEW_URL} component={Home} />
<PrivateRoute path={FORM_GALLERY_URL} component={FormGallery} />
<PrivateRoute component={Error404Route} />
</Switch>
);
@ -158,7 +167,7 @@ class FilesContent extends React.Component {
return (
<>
<Panels />
<FilesArticle />
<FilesArticle history={this.props.history} />
<FilesSection />
</>
);
@ -182,7 +191,7 @@ const Files = inject(({ auth, filesStore }) => {
auth.setProductVersion(config.version);
},
};
})(withTranslation("Common")(observer(FilesContent)));
})(withTranslation("Common")(observer(withRouter(FilesContent))));
export default () => (
<FilesProvider {...stores}>

View File

@ -10,10 +10,13 @@ import {
isTablet as isTabletUtils,
} from "@appserver/components/utils/device";
import Loaders from "@appserver/common/components/Loaders";
import { FileAction } from "@appserver/common/constants";
import { AppServerConfig, FileAction } from "@appserver/common/constants";
import { encryptionUploadDialog } from "../../../helpers/desktop";
import { withRouter } from "react-router";
import MobileView from "./MobileView";
import { combineUrl } from "@appserver/common/utils";
import config from "../../../../package.json";
const ArticleMainButtonContent = (props) => {
const {
@ -33,6 +36,8 @@ const ArticleMainButtonContent = (props) => {
isRecentFolder,
isCommonFolder,
isRecycleBinFolder,
history,
hasOFORMFilesGallery,
} = props;
const inputFilesElement = React.useRef(null);
const inputFolderElement = React.useRef(null);
@ -93,6 +98,12 @@ const ArticleMainButtonContent = (props) => {
const onInputClick = React.useCallback((e) => (e.target.value = null), []);
const onShowGallery = () => {
history.push(
combineUrl(AppServerConfig.proxyURL, config.homepage, `/form-gallery`)
);
};
React.useEffect(() => {
const folderUpload = !isMobile
? [
@ -130,6 +141,13 @@ const ArticleMainButtonContent = (props) => {
disabled: isPrivacy,
key: "form-file",
},
hasOFORMFilesGallery && {
className: "main-button_drop-down_sub",
label: t("Common:OFORMsGallery"),
onClick: onShowGallery,
disabled: isPrivacy, //TODO: OFORM
key: "form-gallery",
},
],
},
]
@ -150,6 +168,14 @@ const ArticleMainButtonContent = (props) => {
disabled: isPrivacy,
key: "form-file",
},
hasOFORMFilesGallery && {
className: "main-button_drop-down_sub",
icon: "images/form.react.svg",
label: t("Common:OFORMsGallery"),
onClick: onShowGallery,
disabled: isPrivacy, //TODO: OFORM
key: "form-gallery",
},
];
const actions = [
@ -281,6 +307,7 @@ export default inject(
isLoading,
fileActionStore,
canCreate,
hasOFORMFilesGallery,
} = filesStore;
const {
isPrivacyFolder,
@ -315,6 +342,11 @@ export default inject(
isLoading,
isLoaded,
firstLoad,
hasOFORMFilesGallery,
};
}
)(withTranslation(["Article", "Common"])(observer(ArticleMainButtonContent)));
)(
withTranslation(["Article", "Common"])(
observer(withRouter(ArticleMainButtonContent))
)
);

View File

@ -0,0 +1,30 @@
import React from "react";
import { observer, inject } from "mobx-react";
import EmptyScreenContainer from "@appserver/components/empty-screen-container";
import { withTranslation } from "react-i18next";
import TileContainer from "./TilesView/sub-components/TileContainer";
import FileTile from "./TilesView/FileTile";
const SectionBodyContent = ({ oformFiles, hasOFORMFilesGallery, t }) => {
//console.log("oformFiles", oformFiles);
return !hasOFORMFilesGallery ? (
<EmptyScreenContainer
imageSrc="images/empty_screen_form-gallery.react.svg"
imageAlt="Empty Screen Filter image"
headerText={t("EmptyScreenHeader")}
descriptionText={t("EmptyScreenDescription")}
/>
) : (
<TileContainer useReactWindow={false} className="tile-container">
{oformFiles.map((item, index) => (
<FileTile key={`${item.id}_${index}`} item={item} />
))}
</TileContainer>
);
};
export default inject(({ filesStore }) => ({
oformFiles: filesStore.oformFiles,
hasOFORMFilesGallery: filesStore.hasOFORMFilesGallery,
}))(withTranslation("FormGallery")(observer(SectionBodyContent)));

View File

@ -0,0 +1,27 @@
import React from "react";
import IconButton from "@appserver/components/icon-button";
import { withTranslation } from "react-i18next";
import { withRouter } from "react-router-dom";
import { StyledHeadline, StyledContainer } from "./StyledGallery";
const SectionHeaderContent = ({ t, history }) => {
const onBackToFiles = () => history.goBack();
return (
<StyledContainer>
<IconButton
iconName="/static/images/arrow.path.react.svg"
size="17"
isFill
onClick={onBackToFiles}
className="arrow-button"
/>
<StyledHeadline type="content" truncate>
{t("Common:OFORMsGallery")}
</StyledHeadline>
</StyledContainer>
);
};
export default withTranslation("Common")(withRouter(SectionHeaderContent));

View File

@ -0,0 +1,59 @@
import styled, { css } from "styled-components";
import { isMobile, isMobileOnly } from "react-device-detect";
import { tablet, mobile } from "@appserver/components/utils/device";
import Headline from "@appserver/common/components/Headline";
const StyledHeadline = styled(Headline)`
width: calc(100% + 1px);
font-weight: 700;
font-size: ${isMobile ? "21px !important" : "18px"};
line-height: ${isMobile ? "28px !important" : "24px"};
@media ${tablet} {
font-size: 21px;
line-height: 28px;
}
`;
const StyledContainer = styled.div`
padding: ${(props) => (props.isDropBox ? "14px 0 3px" : "14px 0 0px")};
width: fit-content;
display: grid;
grid-template-columns: ${(props) =>
props.isRootFolder ? "1fr auto" : "29px 1fr auto"};
align-items: center;
.arrow-button {
width: 17px;
min-width: 17px;
}
@media ${tablet} {
width: 100%;
padding: ${(props) => (props.isDropBox ? "16px 0 5px" : "16px 0 0px")};
}
${isMobile &&
css`
width: 100% !important;
padding: ${(props) =>
props.isDropBox ? "16px 0 5px" : " 16px 0 0px"} !important;
`}
@media ${mobile} {
width: 100%;
padding: ${(props) => (props.isDropBox ? "12px 0 5px" : "12px 0 0")};
}
${isMobileOnly &&
css`
width: 100% !important;
padding: ${(props) =>
props.isDropBox ? "12px 0 5px" : "12px 0 0"} !important;
`}
`;
export { StyledHeadline, StyledContainer };

View File

@ -0,0 +1,56 @@
import React from "react";
import { observer, inject } from "mobx-react";
import Tile from "./sub-components/Tile";
import { SimpleFilesTileContent } from "./StyledTileView";
import Link from "@appserver/components/link";
import { isDesktop } from "react-device-detect";
const FileTile = (props) => {
const { item, getIcon } = props;
const { fileExst, title } = item;
const src = getIcon(32, ".docxf");
const temporaryIcon = getIcon(96, ".oform");
const { thumbnailUrl } = item;
const element = <img className="react-svg-icon" src={src} />;
return (
<div ref={props.selectableRef}>
<Tile
key={item.id}
item={item}
thumbnail={thumbnailUrl}
element={element}
temporaryIcon={temporaryIcon}
>
<SimpleFilesTileContent
//sideColor={theme.filesSection.tilesView.sideColor}
isFile={fileExst}
>
<Link
className="item-file-name"
containerWidth="100%"
type="page"
title={title}
fontWeight="600"
fontSize={isDesktop ? "13px" : "14px"}
target="_blank"
//{...linkStyles} //TODO
//color={theme.filesSection.tilesView.color}
isTextOverflow
>
{item.name}
</Link>
</SimpleFilesTileContent>
</Tile>
</div>
);
};
export default inject(({ settingsStore }) => {
const { getIcon } = settingsStore;
return {
getIcon,
};
})(observer(FileTile));

View File

@ -0,0 +1,30 @@
import React from "react";
import { inject, observer } from "mobx-react";
import TileContainer from "./sub-components/TileContainer";
import FileTile from "./FileTile";
const FilesTileContainer = ({ filesList, t }) => {
return (
<TileContainer
className="tile-container"
draggable
useReactWindow={false}
headingFolders={t("Folders")}
headingFiles={t("Files")}
>
<div className="tile-item-wrapper file">
{filesList.map((item, index) => (
<FileTile key={`${item.id}_${index}`} item={item} />
))}
</div>
</TileContainer>
);
};
export default inject(({ filesStore }) => {
const { filesList } = filesStore;
return {
filesList,
};
})(observer(FilesTileContainer));

View File

@ -0,0 +1,370 @@
import styled, { css } from "styled-components";
import { Base } from "@appserver/components/themes";
import TileContent from "./sub-components/TileContent";
import { tablet, desktop } from "@appserver/components/utils/device";
const FlexBoxStyles = css`
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: center;
align-content: center;
`;
const StyledTile = styled.div`
box-sizing: border-box;
width: 100%;
border: ${(props) => props.theme.filesSection.tilesView.tile.border};
border-radius: 6px;
${(props) => props.showHotkeyBorder && "border-color: #2DA7DB"};
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
&:before,
&:after {
${(props) => props.showHotkeyBorder && "border-color: #2DA7DB"};
}
.file-icon {
display: flex;
flex: 0 0 auto;
user-select: none;
}
.file-icon_container {
width: 32px;
height: 32px;
margin-left: 16px;
margin-right: 8px;
}
`;
const StyledFileTileTop = styled.div`
${FlexBoxStyles};
background: ${(props) =>
props.theme.filesSection.tilesView.tile.backgroundColorTop};
justify-content: space-between;
align-items: baseline;
height: 156px;
position: relative;
.thumbnail-image {
pointer-events: none;
position: absolute;
height: 100%;
width: 100%;
object-fit: cover;
border-radius: 6px 6px 0 0;
z-index: 0;
}
.temporary-icon > .injected-svg {
position: absolute;
width: 100%;
bottom: 16px;
}
`;
const StyledFileTileBottom = styled.div`
${FlexBoxStyles};
border-top: 1px solid transparent;
padding: 9px 0;
height: 62px;
box-sizing: border-box;
.tile-file-loader {
padding-top: 4px;
padding-left: 3px;
}
`;
const StyledContent = styled.div`
display: flex;
flex-basis: 100%;
a {
display: block;
display: -webkit-box;
max-width: 400px;
height: auto;
margin: 0 auto;
line-height: 19px;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
white-space: normal;
word-break: break-word;
}
@media (max-width: 1024px) {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
`;
const StyledElement = styled.div`
flex: 0 0 auto;
display: flex;
margin-right: 4px;
user-select: none;
margin-top: 3px;
height: 32px;
width: 32px;
`;
const StyledOptionButton = styled.div`
display: block;
.expandButton > div:first-child {
padding: 8px 21px 8px 12px;
}
`;
StyledOptionButton.defaultProps = { theme: Base };
const SimpleFilesTileContent = styled(TileContent)`
.row-main-container {
height: auto;
max-width: 100%;
align-self: flex-end;
}
.main-icons {
align-self: flex-end;
}
.badge {
margin-right: 8px;
cursor: pointer;
height: 16px;
width: 16px;
}
.new-items {
position: absolute;
right: 29px;
top: 19px;
}
.badges {
display: flex;
align-items: center;
}
.share-icon {
margin-top: -4px;
padding-right: 8px;
}
.favorite,
.can-convert,
.edit {
svg:not(:root) {
width: 14px;
height: 14px;
}
}
@media (max-width: 1024px) {
display: inline-flex;
height: auto;
& > div {
margin-top: 0;
}
}
`;
const paddingCss = css`
@media ${desktop} {
margin-left: 1px;
padding-right: 3px;
}
@media ${tablet} {
margin-left: -1px;
}
`;
const StyledGridWrapper = styled.div`
display: grid;
grid-template-columns: repeat(auto-fill, minmax(216px, 1fr));
width: 100%;
margin-bottom: ${(props) => (props.isFolders ? "23px" : 0)};
box-sizing: border-box;
${paddingCss};
grid-gap: 14px 16px;
@media ${tablet} {
grid-gap: 14px;
}
`;
const StyledTileContainer = styled.div`
position: relative;
.tile-item-wrapper {
position: relative;
width: 100%;
&.file {
padding: 0;
}
&.folder {
padding: 0;
}
}
.tile-items-heading {
margin: 0;
margin-bottom: 15px;
display: flex;
align-items: center;
justify-content: space-between;
div {
cursor: pointer !important;
.sort-combo-box {
margin-right: 3px;
.dropdown-container {
top: 104%;
bottom: auto;
min-width: 200px;
margin-top: 3px;
.option-item {
display: flex;
align-items: center;
justify-content: space-between;
min-width: 200px;
svg {
width: 16px;
height: 16px;
}
.option-item__icon {
display: none;
cursor: pointer;
${(props) =>
props.isDesc &&
css`
transform: rotate(180deg);
`}
path {
fill: ${(props) => props.theme.filterInput.sort.sortFill};
}
}
:hover {
.option-item__icon {
display: flex;
}
}
}
.selected-option-item {
background: ${(props) =>
props.theme.filterInput.sort.hoverBackground};
cursor: auto;
.selected-option-item__icon {
display: flex;
}
}
}
.optionalBlock {
display: flex;
flex-direction: row;
align-items: center;
font-size: 12px;
font-weight: 600;
color: ${(props) => props.theme.filterInput.sort.tileSortColor};
.sort-icon {
margin-right: 8px;
svg {
path {
fill: ${(props) => props.theme.filterInput.sort.tileSortFill};
}
}
}
}
.combo-buttons_arrow-icon {
display: none;
}
}
}
}
@media ${tablet} {
margin-right: -3px;
}
`;
StyledTileContainer.defaultProps = { theme: Base };
const truncateCss = css`
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
`;
const commonCss = css`
margin: 0;
font-family: "Open Sans";
font-size: 12px;
font-style: normal;
font-weight: 600;
`;
const StyledTileContent = styled.div`
width: 100%;
display: inline-flex;
`;
const MainContainerWrapper = styled.div`
${commonCss};
display: flex;
align-self: center;
margin-right: auto;
`;
const MainContainer = styled.div`
height: 20px;
@media (max-width: 1024px) {
${truncateCss};
}
`;
export {
StyledTile,
StyledFileTileTop,
StyledFileTileBottom,
StyledContent,
StyledElement,
StyledOptionButton,
SimpleFilesTileContent,
StyledGridWrapper,
StyledTileContainer,
StyledTileContent,
MainContainerWrapper,
MainContainer,
};

View File

@ -0,0 +1,181 @@
import ContextMenuButton from "@appserver/components/context-menu-button";
import PropTypes from "prop-types";
import React from "react";
import ContextMenu from "@appserver/components/context-menu";
import { isDesktop } from "react-device-detect";
import Link from "@appserver/components/link";
import { ReactSVG } from "react-svg";
import {
StyledTile,
StyledFileTileTop,
StyledFileTileBottom,
StyledContent,
StyledElement,
StyledOptionButton,
} from "../StyledTileView";
class Tile extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
errorLoadSrc: false,
};
this.cm = React.createRef();
this.tile = React.createRef();
}
onError = () => {
this.setState({
errorLoadSrc: true,
});
};
getIconFile = () => {
const { thumbnailClick, item, temporaryIcon } = this.props;
//const src = item.file_image;
const src = temporaryIcon;
//const svgLoader = () => <div style={{ width: "96px" }} />;
return (
<ReactSVG
className="temporary-icon"
src={src} /* loading={svgLoader} */
/>
);
return (
<Link type="page" onClick={thumbnailClick}>
<img
src={src}
//className="thumbnail-image"
className="temporary-icon"
alt="Thumbnail-img"
onError={this.onError}
/>
</Link>
);
};
onFileIconClick = () => {
if (isDesktop) return;
const { onSelect, item } = this.props;
onSelect && onSelect(true, item);
};
render() {
const {
children,
contextButtonSpacerWidth,
contextOptions,
element,
tileContextClick,
item,
isActive,
title,
getContextModel,
showHotkeyBorder,
} = this.props;
const renderElement = Object.prototype.hasOwnProperty.call(
this.props,
"element"
);
const renderContext =
Object.prototype.hasOwnProperty.call(item, "contextOptions") &&
contextOptions.length > 0;
const getOptions = () => {
tileContextClick && tileContextClick();
return contextOptions;
};
const onContextMenu = (e) => {
tileContextClick && tileContextClick();
if (!this.cm.current.menuRef.current) {
this.tile.current.click(e); //TODO: need fix context menu to global
}
this.cm.current.show(e);
};
const icon = this.getIconFile();
// const contextMenuHeader = {
// icon: children[0].props.item.icon,
// title: children[0].props.item.title,
// };
return (
<StyledTile
ref={this.tile}
{...this.props}
onContextMenu={onContextMenu}
isActive={isActive}
isDesktop={isDesktop}
showHotkeyBorder={showHotkeyBorder}
>
<StyledFileTileTop isActive={isActive}>{icon}</StyledFileTileTop>
<StyledFileTileBottom isActive={isActive}>
<div className="file-icon_container">
<div className="file-icon" onClick={this.onFileIconClick}>
{element}
</div>
</div>
<StyledContent>{children}</StyledContent>
<StyledOptionButton spacerWidth={contextButtonSpacerWidth}>
{renderContext ? (
<ContextMenuButton
className="expandButton"
directionX="right"
getData={getOptions}
isNew={true}
onClick={onContextMenu}
title={title}
/>
) : (
<div className="expandButton" />
)}
<ContextMenu
getContextModel={getContextModel}
ref={this.cm}
//header={contextMenuHeader}
withBackdrop={true}
/>
</StyledOptionButton>
</StyledFileTileBottom>
</StyledTile>
);
}
}
Tile.propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.element),
PropTypes.element,
]),
className: PropTypes.string,
contextButtonSpacerWidth: PropTypes.string,
contextOptions: PropTypes.array,
data: PropTypes.object,
element: PropTypes.element,
id: PropTypes.string,
onSelect: PropTypes.func,
tileContextClick: PropTypes.func,
};
Tile.defaultProps = {
contextButtonSpacerWidth: "32px",
item: {},
};
export default Tile;

View File

@ -0,0 +1,106 @@
import React, { memo } from "react";
import { withTranslation } from "react-i18next";
import PropTypes from "prop-types";
import { FixedSizeList as List, areEqual } from "react-window";
import AutoSizer from "react-virtualized-auto-sizer";
import CustomScrollbarsVirtualList from "@appserver/components/scrollbar";
import { StyledGridWrapper, StyledTileContainer } from "../StyledTileView";
class TileContainer extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
contextOptions: [],
};
}
onRowContextClick = (options) => {
if (Array.isArray(options)) {
this.setState({
contextOptions: options,
});
}
};
renderTile = memo(({ data, index, style }) => {
const options = data[index].props.contextOptions;
return (
<div
onContextMenu={this.onRowContextClick.bind(this, options)}
style={style}
>
{data[index]}
</div>
);
}, areEqual);
render() {
const {
itemHeight,
children,
useReactWindow,
id,
className,
style,
} = this.props;
const renderList = ({ height, width }) => (
<List
className="list"
height={height}
width={width}
itemSize={itemHeight}
itemCount={children.length}
itemData={children}
outerElementType={CustomScrollbarsVirtualList}
>
{this.renderTile}
</List>
);
return (
<StyledTileContainer
id={id}
className={className}
style={style}
useReactWindow={useReactWindow}
>
{useReactWindow ? (
<AutoSizer>{renderList}</AutoSizer>
) : (
<StyledGridWrapper>
{/* <div
className="tile-item-wrapper file"
// onContextMenu={this.onRowContextClick.bind(
// this,
// children.props.contextOptions
// )}
> */}
{children}
{/* </div> */}
</StyledGridWrapper>
)}
</StyledTileContainer>
);
}
}
TileContainer.propTypes = {
itemHeight: PropTypes.number,
manualHeight: PropTypes.string,
children: PropTypes.any.isRequired,
useReactWindow: PropTypes.bool,
className: PropTypes.string,
id: PropTypes.string,
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
};
TileContainer.defaultProps = {
itemHeight: 50,
useReactWindow: true,
id: "rowContainer",
};
export default withTranslation(["Home", "Common"])(TileContainer);

View File

@ -0,0 +1,37 @@
import React from "react";
import PropTypes from "prop-types";
import {
StyledTileContent,
MainContainerWrapper,
MainContainer,
} from "../StyledTileView";
const TileContent = (props) => {
const { children, id, className, style, onClick } = props;
return (
<StyledTileContent
id={id}
className={className}
style={style}
onClick={onClick}
>
<MainContainerWrapper
mainContainerWidth={children.props && children.props.containerWidth}
>
<MainContainer className="row-main-container">{children}</MainContainer>
</MainContainerWrapper>
</StyledTileContent>
);
};
TileContent.propTypes = {
children: PropTypes.node.isRequired,
className: PropTypes.string,
id: PropTypes.string,
onClick: PropTypes.func,
sideColor: PropTypes.string,
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
};
export default TileContent;

View File

@ -0,0 +1,23 @@
import React from "react";
import Section from "@appserver/common/components/Section";
import SectionHeaderContent from "./Header";
import SectionBodyContent from "./Body";
const FormGallery = () => {
return (
<Section
// withBodyScroll
// withBodyAutoFocus={!isMobile}
>
<Section.SectionHeader>
<SectionHeaderContent />
</Section.SectionHeader>
<Section.SectionBody>
<SectionBodyContent />
</Section.SectionBody>
</Section>
);
};
export default FormGallery;

View File

@ -21,6 +21,8 @@ import toastr from "studio/toastr";
const { FilesFilter } = api;
const storageViewAs = localStorage.getItem("viewAs");
import OFORMsGallery from "./OFORMsGallery.json";
class FilesStore {
authStore;
settingsStore;
@ -62,6 +64,7 @@ class FilesStore {
headerBorder = false;
isPrevSettingsModule = false;
oformFiles = [];
constructor(
authStore,
@ -287,10 +290,33 @@ class FilesStore {
}
}
requests.push(getFilesSettings());
//requests.push(this.getOforms());
this.getOforms();
return Promise.all(requests).then(() => (this.isInit = true));
};
getOforms = async () => {
const { getOforms, culture } = this.settingsStore;
console.log("culture", culture);
//const oformData = await getOforms();
const oformData = OFORMsGallery;
this.oformFiles = oformData.filter((f) =>
f["file_country_access"].includes("US")
); //TODO oformCulture
// const split = culture.split("-");
// const oformCulture = split[1] ? split[1] : split[0].toUpperCase();
// const oformData = jsonFile.filter(
// (f) => f["file_country_access"].includes("US") //TODO oformCulture
// );
};
get hasOFORMFilesGallery() {
return !!this.oformFiles.length;
}
setFirstLoad = (firstLoad) => {
this.firstLoad = firstLoad;
};

File diff suppressed because it is too large Load Diff

View File

@ -153,5 +153,6 @@
"Video": "Video",
"View": "View",
"ViewWeb": "View web version",
"Warning": "Warning"
"Warning": "Warning",
"OFORMsGallery": "OFORMs gallery"
}

View File

@ -153,5 +153,6 @@
"Video": "Видео",
"View": "Просмотр",
"ViewWeb": "Просмотреть веб-версию",
"Warning": "Внимание"
"Warning": "Внимание",
"OFORMsGallery": "Галерея OFORMs"
}