From c148a8f55ae08bbc672e70ae8ee1b22ce2e8977b Mon Sep 17 00:00:00 2001 From: Mushka Nikita Date: Tue, 22 Aug 2023 00:30:34 +0300 Subject: [PATCH 001/334] finised client-side, provided functionality for sort, locale and category filters. ip for category and search filters --- .../client/public/locales/en/FormGallery.json | 11 +- .../client/public/locales/ru/FormGallery.json | 11 +- .../components/Article/MainButton/index.js | 2 +- .../Filter/CategoryFilter/SubListByBranch.js | 80 ++++++++++ .../Filter/CategoryFilter/SubListByType.js | 79 ++++++++++ .../Filter/CategoryFilter/SubListPopular.js | 57 +++++++ .../Filter/CategoryFilter/index.js | 105 +++++++++++++ .../Filter/CategoryFilter/index.styled.js | 148 ++++++++++++++++++ .../Filter/LanguageFilter/index.js | 90 +++++++++++ .../Filter/LanguageFilter/index.styled.js | 97 ++++++++++++ .../FormGallery/Filter/SearchFilter/index.js | 54 +++++++ .../FormGallery/Filter/SortFilter/index.js | 119 ++++++++++++++ .../Filter/SortFilter/index.styled.js | 87 ++++++++++ .../src/pages/FormGallery/Filter/index.js | 63 ++++++++ .../TilesView/sub-components/Tile.js | 14 ++ .../client/src/pages/FormGallery/index.js | 23 ++- .../Home/InfoPanel/Body/styles/common.js | 42 ++++- .../ItemTitle/GalleryItemTitle.js | 28 +++- .../ItemTitle/ItemContextOptions.js | 31 +++- .../InfoPanel/Body/views/Gallery/index.js | 35 ++++- .../src/pages/Home/Section/Header/index.js | 5 +- packages/client/src/routes/client.js | 12 +- .../client/src/store/ContextOptionsStore.js | 4 +- packages/common/api/oformClient.js | 15 ++ packages/common/api/oforms/filter.js | 108 +++++++++---- packages/common/api/oforms/index.js | 37 +++++ .../FilterInput/sub-components/SortButton.js | 17 ++ packages/common/store/AuthStore.js | 19 +-- packages/common/store/FormGalleryStore.js | 9 ++ packages/common/utils/axiosOformClient.js | 30 ++++ packages/common/utils/index.ts | 33 ++++ public/scripts/api.js | 1 + public/scripts/config.json | 5 + 33 files changed, 1410 insertions(+), 61 deletions(-) create mode 100644 packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByBranch.js create mode 100644 packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByType.js create mode 100644 packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListPopular.js create mode 100644 packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js create mode 100644 packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.styled.js create mode 100644 packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js create mode 100644 packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js create mode 100644 packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js create mode 100644 packages/client/src/pages/FormGallery/Filter/SortFilter/index.js create mode 100644 packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js create mode 100644 packages/client/src/pages/FormGallery/Filter/index.js create mode 100644 packages/common/api/oformClient.js create mode 100644 packages/common/api/oforms/index.js create mode 100644 packages/common/store/FormGalleryStore.js create mode 100644 packages/common/utils/axiosOformClient.js diff --git a/packages/client/public/locales/en/FormGallery.json b/packages/client/public/locales/en/FormGallery.json index d71b8dd92c..e0be0b33d3 100644 --- a/packages/client/public/locales/en/FormGallery.json +++ b/packages/client/public/locales/en/FormGallery.json @@ -2,5 +2,14 @@ "EmptyScreenDescription": "Please check your Internet connection and refresh the page or try later.", "GalleryEmptyScreenDescription": "Select any form template to see the details", "GalleryEmptyScreenHeader": "Failed to load form templates", - "TemplateInfo": "Template info" + "TemplateInfo": "Template info", + + "Categories": "Categories", + "ViewAllTemplates": "View all templates", + "FormsByBranch": "Forms by branch", + "FormsByType": "Forms by type", + "PopularCompilations": "Popular Compilations", + + "Free": "Free", + "SuggestChanges": "Suggest changes" } diff --git a/packages/client/public/locales/ru/FormGallery.json b/packages/client/public/locales/ru/FormGallery.json index 4f733d5b30..db8b7ead95 100644 --- a/packages/client/public/locales/ru/FormGallery.json +++ b/packages/client/public/locales/ru/FormGallery.json @@ -2,5 +2,14 @@ "EmptyScreenDescription": "Проверьте подключение к Интернету и обновите страницу или повторите попытку позже.", "GalleryEmptyScreenDescription": "Выберите шаблон формы, чтобы просмотреть подробности", "GalleryEmptyScreenHeader": "Не удалось загрузить шаблоны форм", - "TemplateInfo": "Информация шаблона" + "TemplateInfo": "Информация шаблона", + + "Categories": "Категории", + "ViewAllTemplates": "Все шаблоны", + "FormsByBranch": "Формы по ветке", + "FormsByType": "Формы по типу", + "PopularCompilations": "Популярные подборки", + + "Free": "Бесплатно", + "SuggestChanges": "Предложить изменения" } diff --git a/packages/client/src/components/Article/MainButton/index.js b/packages/client/src/components/Article/MainButton/index.js index 3081d3a415..7fb987d80c 100644 --- a/packages/client/src/components/Article/MainButton/index.js +++ b/packages/client/src/components/Article/MainButton/index.js @@ -197,7 +197,7 @@ const ArticleMainButtonContent = (props) => { const onInputClick = React.useCallback((e) => (e.target.value = null), []); const onShowGallery = () => { - navigate(`/form-gallery/${currentFolderId}/`); + navigate(`/form-gallery`); }; const onInvite = React.useCallback((e) => { diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByBranch.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByBranch.js new file mode 100644 index 0000000000..ecd8dc5b9a --- /dev/null +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByBranch.js @@ -0,0 +1,80 @@ +import DropDownItem from "@docspace/components/drop-down-item"; +import { isMobileOnly } from "react-device-detect"; +import { isMobile, isSmallTablet } from "@docspace/components/utils/device"; +import { StyledSubList, StyledSubItemMobile } from "./index.styled"; +import { getCategoriesByBranch } from "@docspace/common/api/oforms"; +import { useState, useEffect } from "react"; +import { + useLocation, + useNavigate, + useParams, + useSearchParams, +} from "react-router-dom"; +import OformsFilter from "@docspace/common/api/oforms/filter"; +import { inject } from "mobx-react"; +import { withTranslation } from "react-i18next"; + +const SubListByBranch = ({ isOpen, getOforms }) => { + const [formsByBranch, setFormsByBranch] = useState([]); + + const location = useLocation(); + const navigate = useNavigate(); + const { category } = useParams(); + + const onOpenCategory = (newCategory) => { + console.log(location); + console.log(newCategory); + console.log(category); + + const newFilter = OformsFilter.getFilter(location); + newFilter.categorizeBy = "categorie"; + newFilter.categoryId = newCategory.id; + getOforms(newFilter); + navigate(`${location.pathname}?${newFilter.toUrlParams()}`); + }; + + useEffect(() => { + (async () => { + const data = await getCategoriesByBranch(); + setFormsByBranch(data); + })(); + }, []); + + if (isSmallTablet() || isMobile() || isMobileOnly) { + if (isOpen) + return formsByBranch.map((category) => ( + onOpenCategory(category)} + /> + )); + } else + return ( + {}} + withBackdrop={false} + marginTop={"43px"} + > + {formsByBranch.map((category) => ( + onOpenCategory(category)} + /> + ))} + + ); +}; + +export default inject(({ oformsStore }) => ({ + getOforms: oformsStore.getOforms, +}))(withTranslation(["FormGallery", "Common"])(SubListByBranch)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByType.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByType.js new file mode 100644 index 0000000000..7d0b2564d0 --- /dev/null +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByType.js @@ -0,0 +1,79 @@ +import DropDownItem from "@docspace/components/drop-down-item"; +import { isMobileOnly } from "react-device-detect"; +import { isMobile, isSmallTablet } from "@docspace/components/utils/device"; +import { StyledSubList, StyledSubItemMobile } from "./index.styled"; +import { getCategoriesByType } from "@docspace/common/api/oforms"; +import { useState, useEffect } from "react"; +import { + useLocation, + useNavigate, + useParams, + useSearchParams, +} from "react-router-dom"; +import OformsFilter from "@docspace/common/api/oforms/filter"; +import { inject } from "mobx-react"; +import { withTranslation } from "react-i18next"; +import Scrollbar from "@docspace/components/scrollbar"; +import styled from "styled-components"; + +const SubListByType = ({ getOforms, isOpen }) => { + const [formsByType, setFormsByType] = useState([]); + + const location = useLocation(); + const navigate = useNavigate(); + + const onOpenCategory = (category) => { + console.log(category); + + const newFilter = OformsFilter.getFilter(location); + newFilter.categorizeBy = "type"; + newFilter.categoryName = category.attributes.urlReq; + getOforms(newFilter); + navigate(`${location.pathname}?${newFilter.toUrlParams()}`); + }; + + useEffect(() => { + (async () => { + const data = await getCategoriesByType(); + setFormsByType(data); + })(); + }, []); + + if (isSmallTablet() || isMobile() || isMobileOnly) { + if (isOpen) + return formsByType.map((category) => ( + onOpenCategory(category)} + /> + )); + } else + return ( + {}} + withBackdrop={false} + marginTop={"79px"} + > + {formsByType.map((category) => ( + onOpenCategory(category)} + /> + ))} + + ); +}; + +export default inject(({ oformsStore }) => ({ + getOforms: oformsStore.getOforms, +}))(withTranslation(["FormGallery", "Common"])(SubListByType)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListPopular.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListPopular.js new file mode 100644 index 0000000000..72b9839cf6 --- /dev/null +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListPopular.js @@ -0,0 +1,57 @@ +import DropDownItem from "@docspace/components/drop-down-item"; +import { isMobileOnly } from "react-device-detect"; +import { isMobile, isSmallTablet } from "@docspace/components/utils/device"; +import { StyledSubList, StyledSubItemMobile } from "./index.styled"; +import { getPopularCategories } from "@docspace/common/api/oforms"; +import { useState, useEffect } from "react"; + +const SubListPopular = ({ isOpen }) => { + const [popularForms, setPopularForms] = useState([]); + + const onOpenCategory = (category) => { + openCategory(); + }; + + useEffect(() => { + (async () => { + const data = await getPopularCategories(); + setPopularForms(data); + })(); + }, []); + + if (isSmallTablet() || isMobile() || isMobileOnly) { + if (isOpen) + return popularForms.map((category) => ( + onOpenCategory(category)} + /> + )); + } else + return ( + {}} + withBackdrop={false} + marginTop={"111px"} + > + {popularForms.map((category) => ( + onOpenCategory(category)} + /> + ))} + + ); +}; + +export default SubListPopular; diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js new file mode 100644 index 0000000000..1f859daf69 --- /dev/null +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js @@ -0,0 +1,105 @@ +import * as Styled from "./index.styled"; + +import DropDown from "@docspace/components/drop-down"; +import DropDownItem from "@docspace/components/drop-down-item"; +import ExpanderDownReactSvgUrl from "PUBLIC_DIR/images/expander-down.react.svg?url"; +import { ReactSVG } from "react-svg"; +import Text from "@docspace/components/text"; +import { useRef, useState } from "react"; +import { inject } from "mobx-react"; +import { withTranslation } from "react-i18next"; +import SubListByBranch from "./SubListByBranch"; +import SubListByType from "./SubListByType"; +import SubListPopular from "./SubListPopular"; + +const CategoryFilter = ({ t }) => { + const dropdownRef = useRef(null); + + const [isOpen, setIsOpen] = useState(false); + const toggleDropdownIsOpen = () => setIsOpen(!isOpen); + const onCloseDropdown = () => setIsOpen(false); + + const [mobileSubByBranchIsOpen, setMobileSubByBranchIsOpen] = useState(false); + const onToggleMobileSubByBranchIsOpen = () => { + setMobileSubByBranchIsOpen(!mobileSubByBranchIsOpen); + setMobileSubByTypeIsOpen(false); + setMobileSubPopularIsOpen(false); + }; + + const [mobileSubByTypeIsOpen, setMobileSubByTypeIsOpen] = useState(false); + const onToggleMobileSubByTypeIsOpen = () => { + setMobileSubByTypeIsOpen(!mobileSubByTypeIsOpen); + setMobileSubByBranchIsOpen(false); + setMobileSubPopularIsOpen(false); + }; + + const [mobileSubPopularIsOpen, setMobileSubPopularIsOpen] = useState(false); + const onToggleMobileSubPopularIsOpen = () => { + setMobileSubPopularIsOpen(!mobileSubPopularIsOpen); + setMobileSubByBranchIsOpen(false); + setMobileSubByTypeIsOpen(false); + }; + + return ( + +
+ + {t("FormGallery:Categories")} + + +
+
+ + {}} + /> + + + + + + + + + + + +
+
+ ); +}; +export default inject(({}) => ({}))( + withTranslation(["FormGallery"])(CategoryFilter) +); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.styled.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.styled.js new file mode 100644 index 0000000000..f39495dfe7 --- /dev/null +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.styled.js @@ -0,0 +1,148 @@ +import { smallTablet } from "@docspace/components/utils/device"; +import styled from "styled-components"; + +import DropDown from "@docspace/components/drop-down"; +import DropDownItem from "@docspace/components/drop-down-item"; + +export const CategoryFilter = styled.div` + width: 220px; + box-sizing: border-box; + + @media ${smallTablet} { + width: 100%; + } + + .combobox { + cursor: pointer; + width: 100%; + height: 32px; + box-sizing: border-box; + display: flex; + flex-direction: row; + justify-content: space-between; + padding: 5px 7px; + background: ${(props) => + props.theme.createEditRoomDialog.thirdpartyStorage.combobox.background}; + border-radius: 3px; + max-height: 32px; + + border: ${(props) => + `1px solid ${ + props.isOpen + ? props.theme.createEditRoomDialog.thirdpartyStorage.combobox + .isOpenDropdownBorderColor + : props.theme.createEditRoomDialog.thirdpartyStorage.combobox + .dropdownBorderColor + }`}; + + transition: all 0.2s ease; + &:hover { + border: ${(props) => + `1px solid ${ + props.isOpen + ? props.theme.createEditRoomDialog.thirdpartyStorage.combobox + .isOpenDropdownBorderColor + : props.theme.createEditRoomDialog.thirdpartyStorage.combobox + .hoverDropdownBorderColor + }`}; + } + + &-text { + font-weight: 400; + font-size: 13px; + line-height: 20px; + } + + &-expander { + display: flex; + align-items: center; + justify-content: center; + width: 6.35px; + svg { + transform: ${(props) => + props.isOpen ? "rotate(180deg)" : "rotate(0)"}; + width: 6.35px; + height: auto; + path { + fill: ${(props) => + props.theme.createEditRoomDialog.thirdpartyStorage.combobox + .arrowFill}; + } + } + } + } + + .dropdown-wrapper { + width: 100%; + box-sizing: border-box; + position: relative; + + .dropdown-container { + width: 100%; + box-sizing: border-box; + margin-top: 4px; + + .dropdown-item { + width: 100%; + height: 32px; + box-sizing: border-box; + font-size: 12px; + font-weight: 600; + line-height: 16px; + padding-top: 8px; + padding-bottom: 8px; + + .submenu-arrow { + margin-right: 0; + svg { + height: 12px; + width: 12px; + } + } + } + + .mobile-sub-open { + .submenu-arrow { + transform: rotate(270deg); + } + } + + .item-by-branch:hover + .sub-by-branch { + visibility: visible; + } + + .item-by-type:hover + .sub-by-type { + visibility: visible; + } + + .item-popular:hover + .sub-popular { + visibility: visible; + } + } + } +`; + +export const StyledSubList = styled(DropDown)` + position: absolute; + top: 0; + margin-top: ${({ marginTop }) => marginTop}; + left: calc(100% + 4px); + + visibility: hidden; + &:hover { + visibility: visible; + } + + &:before { + content: ""; + position: absolute; + left: -4px; + top: 0; + width: 4px; + height: 100%; + } +`; + +export const StyledSubItemMobile = styled(DropDownItem)` + margin-left: 16px; +`; diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js new file mode 100644 index 0000000000..7f1bad8b88 --- /dev/null +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js @@ -0,0 +1,90 @@ +import * as Styled from "./index.styled"; + +import { useEffect } from "react"; +import { useLocation, useNavigate, useSearchParams } from "react-router-dom"; +import DropDown from "@docspace/components/drop-down"; +import DropDownItem from "@docspace/components/drop-down-item"; +import ExpanderDownReactSvgUrl from "PUBLIC_DIR/images/expander-down.react.svg?url"; +import { ReactSVG } from "react-svg"; +import { useRef, useState } from "react"; +import { inject } from "mobx-react"; +import { withTranslation } from "react-i18next"; +import OformsFilter from "@docspace/common/api/oforms/filter"; +import { flagsIcons } from "@docspace/common/utils/image-helpers"; +import { + convertToCulture, + getDefaultOformLocale, +} from "@docspace/common/utils"; + +const avialableLocales = ["en", "zh", "it", "fr", "es", "de", "ja"]; +const defaultOformLocale = getDefaultOformLocale(); + +const LanguageFilter = ({ getOforms }) => { + const dropdownRef = useRef(null); + + const location = useLocation(); + const navigate = useNavigate(); + const [searchParams, setSearchParams] = useSearchParams(); + + const [isOpen, setIsOpen] = useState(false); + const toggleDropdownIsOpen = () => setIsOpen(!isOpen); + + const [locale, setLocale] = useState(defaultOformLocale); + + const onSelectLanguage = (newLocale) => { + return () => { + const newFilter = OformsFilter.getFilter(location); + newFilter.locale = newLocale; + getOforms(newFilter); + navigate(`${location.pathname}?${newFilter.toUrlParams()}`); + + setLocale(newLocale); + setIsOpen(false); + }; + }; + + useEffect(() => { + let firstLoadLocale = searchParams.get("locale"); + if (!firstLoadLocale) firstLoadLocale = defaultOformLocale; + setLocale(firstLoadLocale); + }, []); + + return ( + +
+ {locale} + +
+
+ + {avialableLocales.map((locale, i) => ( + + ))} + +
+
+ ); +}; + +export default inject(({ oformsStore }) => ({ + getOforms: oformsStore.getOforms, +}))(withTranslation(["FormGallery", "Common"])(LanguageFilter)); diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js new file mode 100644 index 0000000000..9cf63417e3 --- /dev/null +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js @@ -0,0 +1,97 @@ +import styled from "styled-components"; + +export const LanguageFilter = styled.div` + width: 41px; + box-sizing: border-box; + + .combobox { + cursor: pointer; + width: 100%; + height: 32px; + box-sizing: border-box; + display: flex; + flex-direction: row; + justify-content: space-between; + gap: 4px; + padding: 8px; + background: ${(props) => + props.theme.createEditRoomDialog.thirdpartyStorage.combobox.background}; + border-radius: 3px; + max-height: 32px; + + border: ${(props) => + `1px solid ${ + props.isOpen + ? props.theme.createEditRoomDialog.thirdpartyStorage.combobox + .isOpenDropdownBorderColor + : props.theme.createEditRoomDialog.thirdpartyStorage.combobox + .dropdownBorderColor + }`}; + + transition: all 0.2s ease; + &:hover { + border: ${(props) => + `1px solid ${ + props.isOpen + ? props.theme.createEditRoomDialog.thirdpartyStorage.combobox + .isOpenDropdownBorderColor + : props.theme.createEditRoomDialog.thirdpartyStorage.combobox + .hoverDropdownBorderColor + }`}; + } + + &-icon { + width: 16px; + height: 16px; + } + + &-expander { + display: flex; + align-items: center; + justify-content: center; + width: 6.35px; + svg { + transform: ${(props) => + props.isOpen ? "rotate(180deg)" : "rotate(0)"}; + width: 6.35px; + height: auto; + path { + fill: ${(props) => + props.theme.createEditRoomDialog.thirdpartyStorage.combobox + .arrowFill}; + } + } + } + } + + .dropdown-wrapper { + width: 100%; + box-sizing: border-box; + position: relative; + + .dropdown-container { + width: 100%; + box-sizing: border-box; + margin-top: 4px; + } + + .dropdown-item { + width: 100%; + height: 32px; + width: 41px; + box-sizing: border-box; + padding: 8px; + + display: flex; + align-items: center; + justify-content: center; + + .drop-down-icon { + margin-right: 0; + width: 16px; + height: 16px; + line-height: 0 !important; + } + } + } +`; diff --git a/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js b/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js new file mode 100644 index 0000000000..b3ec5a535f --- /dev/null +++ b/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js @@ -0,0 +1,54 @@ +import InputBlock from "@docspace/components/input-block"; +import SearchInput from "@docspace/components/search-input"; +import TextInput from "@docspace/components/text-input"; +import FieldContainer from "@docspace/components/field-container"; + +import { useState, useRef } from "react"; +import CopyReactSvgUrl from "PUBLIC_DIR/images/copy.react.svg?url"; + +import styled from "styled-components"; + +export const StyledTextInput = styled(TextInput)` + width: 100%; + max-width: 653px; +`; + +const SearchFilter = ({}) => { + const [value, setValue] = useState("asd"); + + const onChangeValue = (e) => { + setValue(e.target.value); + }; + + const onClearSearch = () => { + setValue(""); + }; + + const ref = useRef(null); + const handleClick = () => { + if (!ref?.current) return; + console.log(ref.current); + }; + + return ( +
+ {}} + onBlur={() => console.log("blur")} + onFocus={() => console.log("onFocus")} + onClick={handleClick} + // tabIndex={1} + // isAutoFocussed={true} + // isDisabled={false} + // onKeyDown={onKeyDown} + /> +
+ ); +}; + +export default SearchFilter; diff --git a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js new file mode 100644 index 0000000000..ac59035790 --- /dev/null +++ b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js @@ -0,0 +1,119 @@ +import * as Styled from "./index.styled"; + +import DropDown from "@docspace/components/drop-down"; +import DropDownItem from "@docspace/components/drop-down-item"; +import { useRef, useState } from "react"; +import { inject } from "mobx-react"; +import { withTranslation } from "react-i18next"; +import SortReactSvgUrl from "PUBLIC_DIR/images/sort.react.svg?url"; +import { ReactSVG } from "react-svg"; +import IconButton from "@docspace/components/icon-button"; +import ComboBox from "@docspace/components/combobox"; +import SortDesc from "PUBLIC_DIR/images/sort.desc.react.svg"; +import Backdrop from "@docspace/components/backdrop"; +import Text from "@docspace/components/text"; +import OformsFilter from "@docspace/common/api/oforms/filter"; + +import { useLocation, useNavigate, useSearchParams } from "react-router-dom"; + +const sortData = [ + { + id: "sort-by_name", + key: "name_form", + label: "Name", + default: true, + isSelected: true, + }, +]; + +const SortFilter = ({ t, getOforms }) => { + const location = useLocation(); + const navigate = useNavigate(); + + const [searchParams, setSearchParams] = useSearchParams(); + const sortBy = searchParams.get("sortby"); + const sortOrder = searchParams.get("sortorder"); + + const [isOpen, setIsOpen] = useState(false); + const onToggleCombobox = () => setIsOpen(!isOpen); + const onCloseCombobox = () => setIsOpen(false); + + const onSetSortBy = (sortBy) => { + const newFilter = OformsFilter.getFilter(location); + newFilter.sortBy = sortBy; + getOforms(newFilter); + navigate(`${location.pathname}?${newFilter.toUrlParams()}`); + + onCloseCombobox(); + }; + + const onToggleSortOrder = (e) => { + e.stopPropagation(); + + const newFilter = OformsFilter.getFilter(location); + newFilter.sortOrder = sortOrder === "desc" ? "asc" : "desc"; + getOforms(newFilter); + navigate(`${location.pathname}?${newFilter.toUrlParams()}`); + + onCloseCombobox(); + }; + + return ( + <> + + + + {sortData?.map((item) => ( + onSetSortBy(item.key)} + key={item.key} + data-value={item.key} + isSelected={sortBy === item.key} + isDescending={sortOrder === "desc"} + > + {t(`Common:${item.label}`)} + + + ))} + + } + advancedOptionsCount={sortData.length} + disableIconClick={false} + disableItemClick={true} + isDefaultMode={false} + manualY={"102%"} + > + + + + + ); +}; + +export default inject(({ oformsStore }) => ({ + getOforms: oformsStore.getOforms, +}))(withTranslation(["FormGallery", "Common"])(SortFilter)); diff --git a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js new file mode 100644 index 0000000000..196842758c --- /dev/null +++ b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js @@ -0,0 +1,87 @@ +import DropDownItem from "@docspace/components/drop-down-item"; +import styled, { css } from "styled-components"; + +export const SortButton = styled.div` + .combo-button { + background: ${(props) => + props.theme.filterInput.sort.background} !important; + + .icon-button_svg { + cursor: pointer; + } + } + + .sort-combo-box { + width: 32px; + height: 32px; + padding: 0; + margin: 0; + + .dropdown-container { + top: 102%; + bottom: auto; + min-width: 200px; + margin-top: 3px; + } + + .optionalBlock { + display: flex; + align-items: center; + justify-content: center; + margin-right: 0; + } + + .combo-buttons_arrow-icon { + display: none; + } + + .backdrop-active { + display: none; + } + } +`; + +export const SortDropdownItem = styled(DropDownItem)` + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + min-width: 200px; + line-height: 30px; + + .sortorder-arrow { + width: 16px; + height: 16px; + display: flex; + visibility: hidden; + cursor: pointer; + + path { + fill: ${(props) => props.theme.filterInput.sort.sortFill}; + } + } + + &:hover { + .sortorder-arrow { + visibility: visible; + } + } + + ${({ isSelected, theme }) => + isSelected && + css` + background: ${theme.filterInput.sort.hoverBackground}; + cursor: auto; + .sortorder-arrow { + visibility: visible; + } + `} + + ${({ isDescending }) => + isDescending && + css` + .sortorder-arrow { + transform: rotate(180deg); + } + `} +`; diff --git a/packages/client/src/pages/FormGallery/Filter/index.js b/packages/client/src/pages/FormGallery/Filter/index.js new file mode 100644 index 0000000000..d216216648 --- /dev/null +++ b/packages/client/src/pages/FormGallery/Filter/index.js @@ -0,0 +1,63 @@ +import styled from "styled-components"; +import { inject, observer } from "mobx-react"; + +import { useEffect } from "react"; +import { useLocation, useNavigate } from "react-router-dom"; +import CategoryFilter from "./CategoryFilter"; +import LanguageFilter from "./LanguageFilter"; +import SearchFilter from "./SearchFilter"; +import SortFilter from "./SortFilter"; +import { smallTablet } from "@docspace/components/utils/device"; +import OformsFilter from "@docspace/common/api/oforms/filter"; + +export const StyledFilter = styled.div` + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + gap: 8px; + height: 32px; + padding: 8px 0; + + .form-only-filters { + display: flex; + flex-direction: row; + align-items: center; + gap: 8px; + } + + .general-filters { + width: 100%; + display: flex; + flex-direction: row; + align-items: center; + justify-content: end; + gap: 8px; + } + + @media ${smallTablet} { + height: 72px; + flex-direction: column-reverse; + + .form-only-filters { + width: 100%; + } + } +`; + +const SectionFilterContent = ({}) => { + return ( + +
+ + +
+
+ + +
+
+ ); +}; + +export default inject(({}) => ({}))(observer(SectionFilterContent)); diff --git a/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js b/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js index eb95e0942a..e15ea31368 100644 --- a/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js +++ b/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js @@ -83,11 +83,25 @@ const Tile = (props) => { label: t("Common:Create"), onClick: onCreateForm, }, + { + key: "preview", + label: t("Common:Preview"), + onClick: () => {}, + }, { key: "template-info", label: t("TemplateInfo"), onClick: onShowTemplateInfo, }, + { + key: "separator", + isSeparator: true, + }, + { + key: "suggest-changes", + label: t("FormGallery:SuggestChanges"), + onClick: () => {}, + }, ]; }; diff --git a/packages/client/src/pages/FormGallery/index.js b/packages/client/src/pages/FormGallery/index.js index 3e05137ed0..e817d42d73 100644 --- a/packages/client/src/pages/FormGallery/index.js +++ b/packages/client/src/pages/FormGallery/index.js @@ -1,30 +1,49 @@ import React, { useEffect } from "react"; import Section from "@docspace/common/components/Section"; import { observer, inject } from "mobx-react"; +import { useLocation, useNavigate } from "react-router-dom"; import SectionHeaderContent from "./Header"; import SectionBodyContent from "./Body"; import { InfoPanelBodyContent } from "../Home/InfoPanel"; import InfoPanelHeaderContent from "../Home/InfoPanel/Header"; +import SectionFilterContent from "./Filter"; +import OformsFilter from "@docspace/common/api/oforms/filter"; const FormGallery = ({ getOforms, setOformFiles }) => { - useEffect(() => { - getOforms(); + const location = useLocation(); + const navigate = useNavigate(); + useEffect(() => { + if (!window.location.search) { + const defaultFilter = OformsFilter.getDefault(); + navigate(`${location.pathname}/filter?${defaultFilter.toUrlParams()}`); + getOforms(defaultFilter); + } else { + const firstLoadFilter = OformsFilter.getFilter(window.location); + getOforms(firstLoadFilter); + } return () => { setOformFiles(null); }; }, [getOforms, setOformFiles]); + const [value, setValue] = React.useState(""); + const onChange = (e) => setValue(e.target.value); + return (
+ + + + diff --git a/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js b/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js index 90e9ff1a84..44ce7f18c7 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js @@ -68,6 +68,15 @@ const StyledTitle = styled.div` -webkit-line-clamp: 2; } + .free-label { + margin-left: auto; + margin-right: 8px; + font-size: 14px; + font-weight: 600; + line-height: 16px; + color: #4781d1; + } + ${(props) => props.withBottomBorder && css` @@ -97,6 +106,22 @@ const StyledTitle = styled.div` } `; +const StyledLink = styled.div` + display: flex; + padding: 8px 0; + flex-direction: column; + align-items: flex-start; + gap: 10px; + + a, + .link { + font-size: 13px; + font-weight: 600; + line-height: 15px; + color: #4781d1; + } +`; + const StyledSubtitle = styled.div` display: flex; flex-direction: row; @@ -105,6 +130,13 @@ const StyledSubtitle = styled.div` padding: 24px 0; `; +const StyledDescription = styled.div` + font-size: 13px; + font-weight: 400; + line-height: 20px; + color: #657077; +`; + const StyledProperties = styled.div` display: flex; flex-direction: column; @@ -205,5 +237,13 @@ const StyledProperties = styled.div` StyledInfoPanelBody.defaultProps = { theme: Base }; StyledTitle.defaultProps = { theme: Base }; +StyledTitle.StyledLink = { theme: Base }; -export { StyledInfoPanelBody, StyledTitle, StyledSubtitle, StyledProperties }; +export { + StyledInfoPanelBody, + StyledTitle, + StyledSubtitle, + StyledProperties, + StyledLink, + StyledDescription, +}; diff --git a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js index 1c7843dad8..be0b1a7e92 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js @@ -1,17 +1,37 @@ -import React from "react"; +import { useRef } from "react"; import { withTranslation } from "react-i18next"; import { ReactSVG } from "react-svg"; +import ItemContextOptions from "./ItemContextOptions"; import { Text } from "@docspace/components"; import { StyledTitle } from "../../styles/common"; -const GalleryItemTitle = ({ gallerySelected, getIcon }) => { +const GalleryItemTitle = ({ t, gallerySelected, getIcon }) => { + const itemTitleRef = useRef(); + return ( - + {gallerySelected?.attributes?.name_form} + + {t("FormGallery:Free")} + {gallerySelected && ( + + )} ); }; -export default withTranslation([])(GalleryItemTitle); +export default withTranslation([ + "FormGallery", + "Files", + "Common", + "Translations", + "InfoPanel", +])(GalleryItemTitle); diff --git a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/ItemContextOptions.js b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/ItemContextOptions.js index 1ca0d037ee..43e1cf8c9a 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/ItemContextOptions.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/ItemContextOptions.js @@ -7,18 +7,44 @@ import { ContextMenu, ContextMenuButton } from "@docspace/components"; import ContextHelper from "../../helpers/ContextHelper"; const StyledItemContextOptions = styled.div` - margin-left: auto; + height: 16px; + ${({ withLabel }) => !withLabel && "margin-left: auto;"} `; +const getFormContextOptions = (t) => [ + { + key: "create", + label: t("Common:Create"), + onClick: () => {}, + }, + { + key: "preview", + label: t("Common:Preview"), + onClick: () => {}, + }, + { + key: "separator", + isSeparator: true, + }, + { + key: "suggest-changes", + label: t("FormGallery:SuggestChanges"), + onClick: () => {}, + }, +]; + const ItemContextOptions = ({ t, selection, + isForm = false, getContextOptions, getContextOptionActions, getUserContextOptions, isUser = false, itemTitleRef, + + withLabel = false, }) => { if (!selection) return null; @@ -59,11 +85,12 @@ const ItemContextOptions = ({ const options = contextHelper?.getItemContextOptions(); const getData = () => { + if (isForm) return getFormContextOptions(t); return options; }; return ( - + { const thumbnailBlank = getIcon(96, ".docxf"); @@ -30,9 +36,34 @@ const Gallery = ({ t, gallerySelected, getIcon, culture, personal }) => { )} + + + {t("FormGallery:SuggestChanges")} + + + - {t("InfoPanel:SystemProperties")} + {t("Description")} + + + + + Fill out the form online and get a recipe page ready, or just download + the template in the desirable format: DOCXF, OFORM, or PDF. Designing + custom recipe cards or pages helps create useful complimentary content + for cooking blogs, culinary websites, or restaurants. + + + + + {t("Properties")} diff --git a/packages/client/src/pages/Home/Section/Header/index.js b/packages/client/src/pages/Home/Section/Header/index.js index 2260abb493..0428f869cc 100644 --- a/packages/client/src/pages/Home/Section/Header/index.js +++ b/packages/client/src/pages/Home/Section/Header/index.js @@ -244,7 +244,7 @@ const SectionHeaderContent = (props) => { }; const onShowGallery = () => { - navigate(`/form-gallery/${currentFolderId}/`); + navigate(`/form-gallery/`); }; const createFolder = () => onCreate(); @@ -1126,7 +1126,8 @@ export default inject( const selectedFolder = { ...selectedFolderStore }; - const { enablePlugins, theme, whiteLabelLogoUrls, isFrame } = auth.settingsStore; + const { enablePlugins, theme, whiteLabelLogoUrls, isFrame } = + auth.settingsStore; const { isGracePeriod } = auth.currentTariffStatusStore; const isRoom = !!roomType; diff --git a/packages/client/src/routes/client.js b/packages/client/src/routes/client.js index 4dfbb8758a..292828851a 100644 --- a/packages/client/src/routes/client.js +++ b/packages/client/src/routes/client.js @@ -236,7 +236,17 @@ const ClientRoutes = [ element: , }, { - path: "/form-gallery/:folderId", + path: "/form-gallery", + element: ( + + + + + + ), + }, + { + path: "/form-gallery/filter", element: ( diff --git a/packages/client/src/store/ContextOptionsStore.js b/packages/client/src/store/ContextOptionsStore.js index d1462b18d7..40c9adaa1f 100644 --- a/packages/client/src/store/ContextOptionsStore.js +++ b/packages/client/src/store/ContextOptionsStore.js @@ -1159,7 +1159,7 @@ class ContextOptionsStore { label: t("Common:Download"), icon: DownloadReactSvgUrl, onClick: () => this.onClickDownload(item, t), - disabled: !item.security.Download, + disabled: !item.security?.Download, }, { id: "option_download-as", @@ -1167,7 +1167,7 @@ class ContextOptionsStore { label: t("Translations:DownloadAs"), icon: DownloadAsReactSvgUrl, onClick: this.onClickDownloadAs, - disabled: !item.security.Download || this.publicRoomStore.isPublicRoom, + disabled: !item.security?.Download || this.publicRoomStore.isPublicRoom, }, ...moveActions, { diff --git a/packages/common/api/oformClient.js b/packages/common/api/oformClient.js new file mode 100644 index 0000000000..4bff1abbbb --- /dev/null +++ b/packages/common/api/oformClient.js @@ -0,0 +1,15 @@ +import AxiosOformClient from "../utils/axiosOformClient"; + +const oformClient = new AxiosOformClient(); + +// export const initSSR = (headers) => { +// oformClient.initSSR(headers); +// }; + +export const request = (options) => { + return oformClient.request(options); +}; + +// export const setWithCredentialsStatus = (state) => { +// return oformClient.setWithCredentialsStatus(state); +// }; diff --git a/packages/common/api/oforms/filter.js b/packages/common/api/oforms/filter.js index 2e0a226b4a..e5f4cb2ea8 100644 --- a/packages/common/api/oforms/filter.js +++ b/packages/common/api/oforms/filter.js @@ -1,32 +1,70 @@ -import { getObjectByLocation, toUrlParams } from "../../utils"; +import { getDefaultOformLocale, toUrlParams } from "../../utils"; + +const PAGE = "pagination[page]"; +const PAGE_SIZE = "pagination[pageSize]"; +const CATEGORIZE_BY = "categorizeby"; +const CATEGORY_NAME = "categoryName"; +const LOCALE = "locale"; +const SORT = "sort"; +const SORT_BY = "sortby"; +const SORT_ORDER = "sortorder"; const DEFAULT_PAGE = 1; const DEFAULT_PAGE_SIZE = 150; const DEFAULT_TOTAL = 0; - -const PAGE = "pagination[page]"; -const PAGE_SIZE = "pagination[pageSize]"; +const DEFAULT_LOCALE = getDefaultOformLocale(); +const DEFAULT_SORT_BY = ""; +const DEFAULT_SORT_ORDER = ""; +const DEFAULT_CATEGORIZE_BY = ""; +const DEFAULT_CATEGORY_NAME = ""; class OformsFilter { static getDefault(total = DEFAULT_TOTAL) { - return new OformsFilter(DEFAULT_PAGE, DEFAULT_PAGE_SIZE, total); + return new OformsFilter( + DEFAULT_PAGE, + DEFAULT_PAGE_SIZE, + DEFAULT_CATEGORIZE_BY, + DEFAULT_CATEGORY_NAME, + DEFAULT_LOCALE, + DEFAULT_SORT_BY, + DEFAULT_SORT_ORDER, + total + ); } static getFilter(location) { if (!location) return this.getDefault(); - const urlFilter = getObjectByLocation(location); + const urlFilter = new URLSearchParams(location.search); if (!urlFilter) return null; const defaultFilter = OformsFilter.getDefault(); const page = - (urlFilter[PAGE] && +urlFilter[PAGE] - 1) || defaultFilter.page; + (urlFilter.get(PAGE) && +urlFilter.get(PAGE) - 1) || defaultFilter.page; const pageSize = - (urlFilter[PAGE_SIZE] && +urlFilter[PAGE_SIZE]) || defaultFilter.pageSize; + (urlFilter.get(PAGE_SIZE) && +urlFilter.get(PAGE_SIZE)) || + defaultFilter.pageSize; - const newFilter = new OformsFilter(page, pageSize, defaultFilter.total); + const categorizeBy = + urlFilter.get(CATEGORIZE_BY) || defaultFilter.categorizeBy; + const categoryName = + urlFilter.get(CATEGORY_NAME) || defaultFilter.categoryName; + const locale = urlFilter.get(LOCALE) || defaultFilter.locale; + const sortBy = urlFilter.get(SORT_BY) || defaultFilter.sortBy; + const sortOrder = urlFilter.get(SORT_ORDER) || defaultFilter.sortOrder; + + const newFilter = new OformsFilter( + page, + pageSize, + categorizeBy, + categoryName, + locale, + sortBy, + sortOrder, + defaultFilter.total + ); return newFilter; } @@ -34,10 +72,20 @@ class OformsFilter { constructor( page = DEFAULT_PAGE, pageSize = DEFAULT_PAGE_SIZE, + categorizeBy = DEFAULT_CATEGORIZE_BY, + categoryName = DEFAULT_CATEGORY_NAME, + locale = DEFAULT_LOCALE, + sortBy = DEFAULT_SORT_BY, + sortOrder = DEFAULT_SORT_ORDER, total = DEFAULT_TOTAL ) { this.page = page; this.pageSize = pageSize; + this.categorizeBy = categorizeBy; + this.categoryName = categoryName; + this.locale = locale; + this.sortBy = sortBy; + this.sortOrder = sortOrder; this.total = total; } @@ -46,35 +94,41 @@ class OformsFilter { }; toUrlParams = () => { - const { pageSize, page } = this; + const { categorizeBy, categoryName, sortBy, sortOrder, locale } = this; const dtoFilter = {}; + dtoFilter[CATEGORIZE_BY] = categorizeBy; + dtoFilter[CATEGORY_NAME] = categoryName; + dtoFilter[LOCALE] = locale; + dtoFilter[SORT_BY] = sortBy; + dtoFilter[SORT_ORDER] = sortOrder; - if (pageSize !== PAGE_SIZE) { - dtoFilter[PAGE_SIZE] = pageSize; - } - - dtoFilter[PAGE] = page; - - const str = toUrlParams(dtoFilter, true); - - return str; + return toUrlParams(dtoFilter, true); }; toApiUrlParams = () => { - const { pageSize } = this; + const { categorizeBy, categoryName, sortBy, sortOrder, locale } = this; - let dtoFilter = { - StartIndex: this.getStartIndex(), - Count: pageSize, - }; + const dtoFilter = {}; + dtoFilter[categorizeBy] = categoryName; + dtoFilter[LOCALE] = locale; + if (sortBy && sortOrder) dtoFilter[SORT] = `${sortBy}:${sortOrder}`; - const str = toUrlParams(dtoFilter, true); - return str; + console.log(toUrlParams(dtoFilter, true)); + return toUrlParams(dtoFilter, true); }; clone() { - return new OformsFilter(this.page, this.pageSize, this.total); + return new OformsFilter( + this.page, + this.pageSize, + this.categorizeBy, + this.categoryName, + this.locale, + this.sortBy, + this.sortOrder, + this.total + ); } } diff --git a/packages/common/api/oforms/index.js b/packages/common/api/oforms/index.js new file mode 100644 index 0000000000..f61760ee89 --- /dev/null +++ b/packages/common/api/oforms/index.js @@ -0,0 +1,37 @@ +import { request } from "../oformClient"; + +export const getCategoriesByBranch = async () => { + const options = { + method: "get", + url: `/categories`, + }; + + return request(options).then((res) => { + console.log(res); + return res; + }); +}; + +export const getCategoriesByType = async () => { + const options = { + method: "get", + url: `/types`, + }; + + return request(options).then((res) => { + console.log(res); + return res; + }); +}; + +export const getPopularCategories = async () => { + const options = { + method: "get", + url: `/compilations`, + }; + + return request(options).then((res) => { + console.log(res); + return res; + }); +}; diff --git a/packages/common/components/FilterInput/sub-components/SortButton.js b/packages/common/components/FilterInput/sub-components/SortButton.js index 087c899ef8..915f0e1afb 100644 --- a/packages/common/components/FilterInput/sub-components/SortButton.js +++ b/packages/common/components/FilterInput/sub-components/SortButton.js @@ -174,6 +174,23 @@ const SortButton = ({ onSortButtonClick, title, }) => { + console.log( + id, + getSortData(), + getSelectedSortData(), + + onChangeViewAs(), + view, + viewAs, + viewSettings, + + onSort, + viewSelectorVisible, + + onSortButtonClick(), + title + ); + const [isOpen, setIsOpen] = React.useState(false); const [sortData, setSortData] = React.useState([]); diff --git a/packages/common/store/AuthStore.js b/packages/common/store/AuthStore.js index 3b5e4a47c4..8ef4cfbdee 100644 --- a/packages/common/store/AuthStore.js +++ b/packages/common/store/AuthStore.js @@ -420,9 +420,6 @@ class AuthStore { }; getOforms = (filter) => { - const culture = - this.userStore.user.cultureName || this.settingsStore.culture; - const formName = "&fields[0]=name_form"; const updatedAt = "&fields[1]=updatedAt"; const size = "&fields[2]=file_size"; @@ -431,20 +428,12 @@ class AuthStore { const templateImage = "&populate[template_image][fields][5]=formats"; const fields = `${formName}${updatedAt}${size}${filePages}${cardPrewiew}${templateImage}`; - - const params = `?${filter.toUrlParams()}${fields}`; + const params = `?${filter.toApiUrlParams()}${fields}`; const promise = new Promise(async (resolve, reject) => { - let oforms = await api.settings.getOforms( - `${this.settingsStore.urlOforms}${params}&locale=${culture}` - ); - - if (!oforms?.data?.data.length) { - oforms = await api.settings.getOforms( - `${this.settingsStore.urlOforms}${params}&locale=en` - ); - } - + const apiUrl = `${this.settingsStore.urlOforms}${params}`; + let oforms = await api.settings.getOforms(apiUrl); + console.log(oforms); resolve(oforms); }); diff --git a/packages/common/store/FormGalleryStore.js b/packages/common/store/FormGalleryStore.js new file mode 100644 index 0000000000..4bdb077ef8 --- /dev/null +++ b/packages/common/store/FormGalleryStore.js @@ -0,0 +1,9 @@ +import { makeAutoObservable, runInAction } from "mobx"; + +class AuthStore { + constructor() { + makeAutoObservable(this); + } +} + +export default new AuthStore(); diff --git a/packages/common/utils/axiosOformClient.js b/packages/common/utils/axiosOformClient.js new file mode 100644 index 0000000000..5c882775b1 --- /dev/null +++ b/packages/common/utils/axiosOformClient.js @@ -0,0 +1,30 @@ +import axios from "axios"; +import defaultConfig from "PUBLIC_DIR/scripts/config.json"; +import combineUrl from "./combineUrl"; + +let { oformsApi: apiConf } = defaultConfig; +let { origin, prefix, timeout } = apiConf; + +class AxiosOformClient { + constructor() { + this.client = axios.create({ + baseURL: combineUrl(origin, prefix), + responseType: "json", + timeout: timeout, + withCredentials: true, + }); + } + + request = async (options) => + this.client(options) + .then((res) => { + if (res.data && res.data.error) throw new Error(res.data.error.message); + if (res.isAxiosError && res.message) throw new Error(res.message); + + if (!res || !res.data || res.isAxiosError) return null; + return res.data.data; + }) + .catch((err) => Promise.reject(err)); +} + +export default AxiosOformClient; diff --git a/packages/common/utils/index.ts b/packages/common/utils/index.ts index 6efc14b98e..d9408dcb48 100644 --- a/packages/common/utils/index.ts +++ b/packages/common/utils/index.ts @@ -66,6 +66,7 @@ export function getObjectByLocation(location) { if (!location.search || !location.search.length) return null; const searchUrl = location.search.substring(1); + console.log(searchUrl); const decodedString = decodeURIComponent(searchUrl) .replace(/\["/g, '["') .replace(/"\]/g, '"]') @@ -79,6 +80,7 @@ export function getObjectByLocation(location) { .replace(/\]"/g, "]") .replace(/\\\\",\\\\"/g, '","'); + console.log(`{"${decodedString}"}`); const object = JSON.parse(`{"${decodedString}"}`); return object; @@ -303,6 +305,12 @@ export function getLanguage(lng) { return lng; } +export const getDefaultOformLocale = () => { + const avialableLocales = ["en", "zh", "it", "fr", "es", "de", "ja"]; + const userLocale = getCookie(LANGUAGE) || "en"; + return avialableLocales.includes(userLocale) ? userLocale : "en"; +}; + export function loadScript(url, id, onLoad, onError) { try { const script = document.createElement("script"); @@ -352,6 +360,31 @@ export function convertLanguage(key) { return key; } +export function convertToCulture(key: string) { + switch (key) { + case "en": + return "en-US"; + case "el": + return "el-GR"; + case "hy": + return "hy-AM"; + case "ko": + return "ko-KR"; + case "lo": + return "lo-LA"; + case "pt": + return "pt-BR"; + case "uk": + return "uk-UA"; + case "ja": + return "ja-JP"; + case "zh": + return "zh-CN"; + } + + return key; +} + export function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } diff --git a/public/scripts/api.js b/public/scripts/api.js index 19057a4af7..e3bbdcbd91 100644 --- a/public/scripts/api.js +++ b/public/scripts/api.js @@ -28,6 +28,7 @@ search: "", roomId: null, withSubfolders: true, + locale: "en", }, keysForReload: [ "src", diff --git a/public/scripts/config.json b/public/scripts/config.json index 22577ef25f..534b4d78f2 100644 --- a/public/scripts/config.json +++ b/public/scripts/config.json @@ -4,6 +4,11 @@ "prefix": "/api/2.0", "timeout": 30000 }, + "oformsApi": { + "origin": "https://cmsoforms.onlyoffice.com/", + "prefix": "/api", + "timeout": 30000 + }, "proxy": { "url": "" }, From d943935b2c6e536517fe7ecbcd66398a5c66e405 Mon Sep 17 00:00:00 2001 From: Mushka Nikita Date: Fri, 25 Aug 2023 23:40:23 +0300 Subject: [PATCH 002/334] update on category filter + bugfixes --- packages/client/src/helpers/constants.js | 6 ++++ .../Filter/CategoryFilter/SubListByBranch.js | 24 +++++-------- .../Filter/CategoryFilter/SubListByType.js | 22 ++++-------- .../Filter/CategoryFilter/SubListPopular.js | 22 ++++++++++-- .../Filter/CategoryFilter/index.js | 23 ++++++++++--- .../Filter/LanguageFilter/index.js | 5 +-- .../FormGallery/Filter/SortFilter/index.js | 16 ++++----- packages/client/src/store/OformsStore.js | 5 +++ packages/common/api/oforms/filter.js | 34 ++++++++----------- 9 files changed, 89 insertions(+), 68 deletions(-) diff --git a/packages/client/src/helpers/constants.js b/packages/client/src/helpers/constants.js index 648320b665..8c27c5b1ac 100644 --- a/packages/client/src/helpers/constants.js +++ b/packages/client/src/helpers/constants.js @@ -126,4 +126,10 @@ export const LinkType = Object.freeze({ External: 1, }); +export const OformCategory = Object.freeze({ + Branch: "categories", + Type: "types", + Compilation: "compilations", +}); + export const SSO_LABEL = "SSO"; diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByBranch.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByBranch.js index ecd8dc5b9a..aec5c2d326 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByBranch.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByBranch.js @@ -4,31 +4,22 @@ import { isMobile, isSmallTablet } from "@docspace/components/utils/device"; import { StyledSubList, StyledSubItemMobile } from "./index.styled"; import { getCategoriesByBranch } from "@docspace/common/api/oforms"; import { useState, useEffect } from "react"; -import { - useLocation, - useNavigate, - useParams, - useSearchParams, -} from "react-router-dom"; +import { useLocation, useNavigate, useSearchParams } from "react-router-dom"; import OformsFilter from "@docspace/common/api/oforms/filter"; import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; +import { OformCategory } from "@docspace/client/src/helpers/constants"; -const SubListByBranch = ({ isOpen, getOforms }) => { +const SubListByBranch = ({ isOpen, oformsFilter, getOforms }) => { const [formsByBranch, setFormsByBranch] = useState([]); const location = useLocation(); const navigate = useNavigate(); - const { category } = useParams(); - const onOpenCategory = (newCategory) => { - console.log(location); - console.log(newCategory); - console.log(category); - - const newFilter = OformsFilter.getFilter(location); - newFilter.categorizeBy = "categorie"; - newFilter.categoryId = newCategory.id; + const onOpenCategory = (category) => { + const newFilter = oformsFilter.clone(); + newFilter.categorizeBy = OformCategory.Branch; + newFilter.categoryUrl = category.attributes.urlReq; getOforms(newFilter); navigate(`${location.pathname}?${newFilter.toUrlParams()}`); }; @@ -76,5 +67,6 @@ const SubListByBranch = ({ isOpen, getOforms }) => { }; export default inject(({ oformsStore }) => ({ + oformsFilter: oformsStore.oformsFilter, getOforms: oformsStore.getOforms, }))(withTranslation(["FormGallery", "Common"])(SubListByBranch)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByType.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByType.js index 7d0b2564d0..995c20e7f5 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByType.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByType.js @@ -4,30 +4,21 @@ import { isMobile, isSmallTablet } from "@docspace/components/utils/device"; import { StyledSubList, StyledSubItemMobile } from "./index.styled"; import { getCategoriesByType } from "@docspace/common/api/oforms"; import { useState, useEffect } from "react"; -import { - useLocation, - useNavigate, - useParams, - useSearchParams, -} from "react-router-dom"; -import OformsFilter from "@docspace/common/api/oforms/filter"; +import { useLocation, useNavigate, useSearchParams } from "react-router-dom"; import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; -import Scrollbar from "@docspace/components/scrollbar"; -import styled from "styled-components"; +import { OformCategory } from "@docspace/client/src/helpers/constants"; -const SubListByType = ({ getOforms, isOpen }) => { +const SubListByType = ({ isOpen, getOforms, oformsFilter }) => { const [formsByType, setFormsByType] = useState([]); const location = useLocation(); const navigate = useNavigate(); const onOpenCategory = (category) => { - console.log(category); - - const newFilter = OformsFilter.getFilter(location); - newFilter.categorizeBy = "type"; - newFilter.categoryName = category.attributes.urlReq; + const newFilter = oformsFilter.clone(); + newFilter.categorizeBy = OformCategory.Type; + newFilter.categoryUrl = category.attributes.urlReq; getOforms(newFilter); navigate(`${location.pathname}?${newFilter.toUrlParams()}`); }; @@ -75,5 +66,6 @@ const SubListByType = ({ getOforms, isOpen }) => { }; export default inject(({ oformsStore }) => ({ + oformsFilter: oformsStore.oformsFilter, getOforms: oformsStore.getOforms, }))(withTranslation(["FormGallery", "Common"])(SubListByType)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListPopular.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListPopular.js index 72b9839cf6..d8404c0a3b 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListPopular.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListPopular.js @@ -5,11 +5,24 @@ import { StyledSubList, StyledSubItemMobile } from "./index.styled"; import { getPopularCategories } from "@docspace/common/api/oforms"; import { useState, useEffect } from "react"; -const SubListPopular = ({ isOpen }) => { +import { useLocation, useNavigate, useSearchParams } from "react-router-dom"; +import OformsFilter from "@docspace/common/api/oforms/filter"; +import { inject } from "mobx-react"; +import { withTranslation } from "react-i18next"; +import { OformCategory } from "@docspace/client/src/helpers/constants"; + +const SubListPopular = ({ isOpen, oformsFilter, getOforms }) => { const [popularForms, setPopularForms] = useState([]); + const location = useLocation(); + const navigate = useNavigate(); + const onOpenCategory = (category) => { - openCategory(); + const newFilter = oformsFilter.clone(); + newFilter.categorizeBy = OformCategory.Compilation; + newFilter.categoryUrl = category.attributes.urlReq; + getOforms(newFilter); + navigate(`${location.pathname}?${newFilter.toUrlParams()}`); }; useEffect(() => { @@ -54,4 +67,7 @@ const SubListPopular = ({ isOpen }) => { ); }; -export default SubListPopular; +export default inject(({ oformsStore }) => ({ + oformsFilter: oformsStore.oformsFilter, + getOforms: oformsStore.getOforms, +}))(withTranslation(["FormGallery", "Common"])(SubListPopular)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js index 1f859daf69..f06f3fc757 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js @@ -11,10 +11,15 @@ import { withTranslation } from "react-i18next"; import SubListByBranch from "./SubListByBranch"; import SubListByType from "./SubListByType"; import SubListPopular from "./SubListPopular"; +import { useLocation, useNavigate, useSearchParams } from "react-router-dom"; +import OformsFilter from "@docspace/common/api/oforms/filter"; -const CategoryFilter = ({ t }) => { +const CategoryFilter = ({ t, getOforms }) => { const dropdownRef = useRef(null); + const location = useLocation(); + const navigate = useNavigate(); + const [isOpen, setIsOpen] = useState(false); const toggleDropdownIsOpen = () => setIsOpen(!isOpen); const onCloseDropdown = () => setIsOpen(false); @@ -40,6 +45,14 @@ const CategoryFilter = ({ t }) => { setMobileSubByTypeIsOpen(false); }; + const onViewAllTemplates = () => { + const newFilter = OformsFilter.getFilter(location); + newFilter.categorizeBy = ""; + newFilter.categoryUrl = ""; + getOforms(newFilter); + navigate(`${location.pathname}?${newFilter.toUrlParams()}`); + }; + return (
@@ -62,7 +75,7 @@ const CategoryFilter = ({ t }) => { {}} + onClick={onViewAllTemplates} /> @@ -100,6 +113,6 @@ const CategoryFilter = ({ t }) => { ); }; -export default inject(({}) => ({}))( - withTranslation(["FormGallery"])(CategoryFilter) -); +export default inject(({ oformsStore }) => ({ + getOforms: oformsStore.getOforms, +}))(withTranslation(["FormGallery"])(CategoryFilter)); diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js index 7f1bad8b88..9cf296688e 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js @@ -19,7 +19,7 @@ import { const avialableLocales = ["en", "zh", "it", "fr", "es", "de", "ja"]; const defaultOformLocale = getDefaultOformLocale(); -const LanguageFilter = ({ getOforms }) => { +const LanguageFilter = ({ oformsFilter, getOforms }) => { const dropdownRef = useRef(null); const location = useLocation(); @@ -33,7 +33,7 @@ const LanguageFilter = ({ getOforms }) => { const onSelectLanguage = (newLocale) => { return () => { - const newFilter = OformsFilter.getFilter(location); + const newFilter = oformsFilter.clone(); newFilter.locale = newLocale; getOforms(newFilter); navigate(`${location.pathname}?${newFilter.toUrlParams()}`); @@ -86,5 +86,6 @@ const LanguageFilter = ({ getOforms }) => { }; export default inject(({ oformsStore }) => ({ + oformsFilter: oformsStore.oformsFilter, getOforms: oformsStore.getOforms, }))(withTranslation(["FormGallery", "Common"])(LanguageFilter)); diff --git a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js index ac59035790..34fb085cce 100644 --- a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js @@ -1,12 +1,9 @@ import * as Styled from "./index.styled"; -import DropDown from "@docspace/components/drop-down"; -import DropDownItem from "@docspace/components/drop-down-item"; import { useRef, useState } from "react"; import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; import SortReactSvgUrl from "PUBLIC_DIR/images/sort.react.svg?url"; -import { ReactSVG } from "react-svg"; import IconButton from "@docspace/components/icon-button"; import ComboBox from "@docspace/components/combobox"; import SortDesc from "PUBLIC_DIR/images/sort.desc.react.svg"; @@ -26,7 +23,7 @@ const sortData = [ }, ]; -const SortFilter = ({ t, getOforms }) => { +const SortFilter = ({ t, oformsFilter, getOforms }) => { const location = useLocation(); const navigate = useNavigate(); @@ -39,18 +36,20 @@ const SortFilter = ({ t, getOforms }) => { const onCloseCombobox = () => setIsOpen(false); const onSetSortBy = (sortBy) => { - const newFilter = OformsFilter.getFilter(location); + const newFilter = oformsFilter.clone(); newFilter.sortBy = sortBy; + if (!sortOrder) newFilter.sortOrder = "asc"; getOforms(newFilter); navigate(`${location.pathname}?${newFilter.toUrlParams()}`); onCloseCombobox(); }; - const onToggleSortOrder = (e) => { + const onToggleSortOrder = (e, sortBy) => { e.stopPropagation(); - const newFilter = OformsFilter.getFilter(location); + const newFilter = oformsFilter.clone(); + newFilter.sortBy = sortBy; newFilter.sortOrder = sortOrder === "desc" ? "asc" : "desc"; getOforms(newFilter); navigate(`${location.pathname}?${newFilter.toUrlParams()}`); @@ -94,7 +93,7 @@ const SortFilter = ({ t, getOforms }) => { > {t(`Common:${item.label}`)} onToggleSortOrder(e, item.key)} className="sortorder-arrow" /> @@ -115,5 +114,6 @@ const SortFilter = ({ t, getOforms }) => { }; export default inject(({ oformsStore }) => ({ + oformsFilter: oformsStore.oformsFilter, getOforms: oformsStore.getOforms, }))(withTranslation(["FormGallery", "Common"])(SortFilter)); diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index b7a880f670..4f5cee45df 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -25,6 +25,11 @@ class OformsStore { if (oformsFilter) { newOformsFilter.page = oformsFilter.page; newOformsFilter.total = oformsFilter.total; + newOformsFilter.categorizeBy = filter.categorizeBy; + newOformsFilter.categoryUrl = filter.categoryUrl; + newOformsFilter.locale = filter.locale; + newOformsFilter.sortBy = filter.sortBy; + newOformsFilter.sortOrder = filter.sortOrder; } runInAction(() => { diff --git a/packages/common/api/oforms/filter.js b/packages/common/api/oforms/filter.js index e5f4cb2ea8..62fe9175ea 100644 --- a/packages/common/api/oforms/filter.js +++ b/packages/common/api/oforms/filter.js @@ -3,7 +3,7 @@ import { getDefaultOformLocale, toUrlParams } from "../../utils"; const PAGE = "pagination[page]"; const PAGE_SIZE = "pagination[pageSize]"; const CATEGORIZE_BY = "categorizeby"; -const CATEGORY_NAME = "categoryName"; +const CATEGORY_URL = "categoryUrl"; const LOCALE = "locale"; const SORT = "sort"; const SORT_BY = "sortby"; @@ -16,7 +16,7 @@ const DEFAULT_LOCALE = getDefaultOformLocale(); const DEFAULT_SORT_BY = ""; const DEFAULT_SORT_ORDER = ""; const DEFAULT_CATEGORIZE_BY = ""; -const DEFAULT_CATEGORY_NAME = ""; +const DEFAULT_CATEGORY_URL = ""; class OformsFilter { static getDefault(total = DEFAULT_TOTAL) { @@ -24,7 +24,7 @@ class OformsFilter { DEFAULT_PAGE, DEFAULT_PAGE_SIZE, DEFAULT_CATEGORIZE_BY, - DEFAULT_CATEGORY_NAME, + DEFAULT_CATEGORY_URL, DEFAULT_LOCALE, DEFAULT_SORT_BY, DEFAULT_SORT_ORDER, @@ -36,21 +36,18 @@ class OformsFilter { if (!location) return this.getDefault(); const urlFilter = new URLSearchParams(location.search); - if (!urlFilter) return null; const defaultFilter = OformsFilter.getDefault(); - const page = (urlFilter.get(PAGE) && +urlFilter.get(PAGE) - 1) || defaultFilter.page; const pageSize = (urlFilter.get(PAGE_SIZE) && +urlFilter.get(PAGE_SIZE)) || defaultFilter.pageSize; - const categorizeBy = urlFilter.get(CATEGORIZE_BY) || defaultFilter.categorizeBy; - const categoryName = - urlFilter.get(CATEGORY_NAME) || defaultFilter.categoryName; + const categoryUrl = + urlFilter.get(CATEGORY_URL) || defaultFilter.categoryUrl; const locale = urlFilter.get(LOCALE) || defaultFilter.locale; const sortBy = urlFilter.get(SORT_BY) || defaultFilter.sortBy; const sortOrder = urlFilter.get(SORT_ORDER) || defaultFilter.sortOrder; @@ -59,7 +56,7 @@ class OformsFilter { page, pageSize, categorizeBy, - categoryName, + categoryUrl, locale, sortBy, sortOrder, @@ -73,7 +70,7 @@ class OformsFilter { page = DEFAULT_PAGE, pageSize = DEFAULT_PAGE_SIZE, categorizeBy = DEFAULT_CATEGORIZE_BY, - categoryName = DEFAULT_CATEGORY_NAME, + categoryUrl = DEFAULT_CATEGORY_URL, locale = DEFAULT_LOCALE, sortBy = DEFAULT_SORT_BY, sortOrder = DEFAULT_SORT_ORDER, @@ -82,7 +79,7 @@ class OformsFilter { this.page = page; this.pageSize = pageSize; this.categorizeBy = categorizeBy; - this.categoryName = categoryName; + this.categoryUrl = categoryUrl; this.locale = locale; this.sortBy = sortBy; this.sortOrder = sortOrder; @@ -94,11 +91,10 @@ class OformsFilter { }; toUrlParams = () => { - const { categorizeBy, categoryName, sortBy, sortOrder, locale } = this; + const { categorizeBy, categoryUrl, sortBy, sortOrder, locale } = this; const dtoFilter = {}; - dtoFilter[CATEGORIZE_BY] = categorizeBy; - dtoFilter[CATEGORY_NAME] = categoryName; + dtoFilter[categorizeBy] = categoryUrl; dtoFilter[LOCALE] = locale; dtoFilter[SORT_BY] = sortBy; dtoFilter[SORT_ORDER] = sortOrder; @@ -107,14 +103,14 @@ class OformsFilter { }; toApiUrlParams = () => { - const { categorizeBy, categoryName, sortBy, sortOrder, locale } = this; + const { categorizeBy, categoryUrl, sortBy, sortOrder, locale } = this; const dtoFilter = {}; - dtoFilter[categorizeBy] = categoryName; - dtoFilter[LOCALE] = locale; + if (categorizeBy && categoryUrl) + dtoFilter[`filters[${categorizeBy}][urlReq][$eq]`] = categoryUrl; if (sortBy && sortOrder) dtoFilter[SORT] = `${sortBy}:${sortOrder}`; + dtoFilter[LOCALE] = locale; - console.log(toUrlParams(dtoFilter, true)); return toUrlParams(dtoFilter, true); }; @@ -123,7 +119,7 @@ class OformsFilter { this.page, this.pageSize, this.categorizeBy, - this.categoryName, + this.categoryUrl, this.locale, this.sortBy, this.sortOrder, From 79dea3bcd3baebf310a2bab3ce4ef72ffa32d008 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Mon, 28 Aug 2023 01:57:38 +0300 Subject: [PATCH 003/334] fix pagination --- packages/common/api/oforms/filter.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/common/api/oforms/filter.js b/packages/common/api/oforms/filter.js index 62fe9175ea..0e07601f52 100644 --- a/packages/common/api/oforms/filter.js +++ b/packages/common/api/oforms/filter.js @@ -86,10 +86,6 @@ class OformsFilter { this.total = total; } - getStartIndex = () => { - return this.page * this.pageSize; - }; - toUrlParams = () => { const { categorizeBy, categoryUrl, sortBy, sortOrder, locale } = this; @@ -103,9 +99,19 @@ class OformsFilter { }; toApiUrlParams = () => { - const { categorizeBy, categoryUrl, sortBy, sortOrder, locale } = this; + const { + page, + pageSize, + categorizeBy, + categoryUrl, + sortBy, + sortOrder, + locale, + } = this; const dtoFilter = {}; + dtoFilter[PAGE] = page; + dtoFilter[PAGE_SIZE] = pageSize; if (categorizeBy && categoryUrl) dtoFilter[`filters[${categorizeBy}][urlReq][$eq]`] = categoryUrl; if (sortBy && sortOrder) dtoFilter[SORT] = `${sortBy}:${sortOrder}`; From 60448436be064a7abcdd39ba1c5f92cfec7d260b Mon Sep 17 00:00:00 2001 From: mushka-n Date: Mon, 28 Aug 2023 03:01:47 +0300 Subject: [PATCH 004/334] sort optimization + initial rendering --- .../FormGallery/Filter/SortFilter/index.js | 39 +++------- .../src/pages/FormGallery/Filter/index.js | 31 +++++++- packages/client/src/store/OformsStore.js | 73 ++++++++----------- 3 files changed, 66 insertions(+), 77 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js index 34fb085cce..7ebe916b63 100644 --- a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js @@ -1,6 +1,6 @@ import * as Styled from "./index.styled"; -import { useRef, useState } from "react"; +import { useState } from "react"; import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; import SortReactSvgUrl from "PUBLIC_DIR/images/sort.react.svg?url"; @@ -9,9 +9,6 @@ import ComboBox from "@docspace/components/combobox"; import SortDesc from "PUBLIC_DIR/images/sort.desc.react.svg"; import Backdrop from "@docspace/components/backdrop"; import Text from "@docspace/components/text"; -import OformsFilter from "@docspace/common/api/oforms/filter"; - -import { useLocation, useNavigate, useSearchParams } from "react-router-dom"; const sortData = [ { @@ -23,38 +20,22 @@ const sortData = [ }, ]; -const SortFilter = ({ t, oformsFilter, getOforms }) => { - const location = useLocation(); - const navigate = useNavigate(); - - const [searchParams, setSearchParams] = useSearchParams(); - const sortBy = searchParams.get("sortby"); - const sortOrder = searchParams.get("sortorder"); +const SortFilter = ({ t, oformsFilter, sortOforms }) => { + const sortBy = oformsFilter.sortBy; + const sortOrder = oformsFilter.sortOrder; const [isOpen, setIsOpen] = useState(false); const onToggleCombobox = () => setIsOpen(!isOpen); const onCloseCombobox = () => setIsOpen(false); - const onSetSortBy = (sortBy) => { - const newFilter = oformsFilter.clone(); - newFilter.sortBy = sortBy; - if (!sortOrder) newFilter.sortOrder = "asc"; - getOforms(newFilter); - navigate(`${location.pathname}?${newFilter.toUrlParams()}`); - + const onSort = async (newSortBy, newSortOrder = "asc") => { + await sortOforms(newSortBy, newSortOrder); onCloseCombobox(); }; - const onToggleSortOrder = (e, sortBy) => { + const onToggleSortOrder = (e, newSortBy) => { e.stopPropagation(); - - const newFilter = oformsFilter.clone(); - newFilter.sortBy = sortBy; - newFilter.sortOrder = sortOrder === "desc" ? "asc" : "desc"; - getOforms(newFilter); - navigate(`${location.pathname}?${newFilter.toUrlParams()}`); - - onCloseCombobox(); + onSort(newSortBy, sortOrder === "desc" ? "asc" : "desc"); }; return ( @@ -85,7 +66,7 @@ const SortFilter = ({ t, oformsFilter, getOforms }) => { {sortData?.map((item) => ( onSetSortBy(item.key)} + onClick={() => onSort(item.key)} key={item.key} data-value={item.key} isSelected={sortBy === item.key} @@ -115,5 +96,5 @@ const SortFilter = ({ t, oformsFilter, getOforms }) => { export default inject(({ oformsStore }) => ({ oformsFilter: oformsStore.oformsFilter, - getOforms: oformsStore.getOforms, + sortOforms: oformsStore.sortOforms, }))(withTranslation(["FormGallery", "Common"])(SortFilter)); diff --git a/packages/client/src/pages/FormGallery/Filter/index.js b/packages/client/src/pages/FormGallery/Filter/index.js index d216216648..38677f9c6b 100644 --- a/packages/client/src/pages/FormGallery/Filter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/index.js @@ -1,13 +1,14 @@ import styled from "styled-components"; import { inject, observer } from "mobx-react"; -import { useEffect } from "react"; -import { useLocation, useNavigate } from "react-router-dom"; +import { useState, useEffect } from "react"; +import { useLocation, useNavigate, useSearchParams } from "react-router-dom"; import CategoryFilter from "./CategoryFilter"; import LanguageFilter from "./LanguageFilter"; import SearchFilter from "./SearchFilter"; import SortFilter from "./SortFilter"; import { smallTablet } from "@docspace/components/utils/device"; +import { getDefaultOformLocale } from "@docspace/common/utils"; import OformsFilter from "@docspace/common/api/oforms/filter"; export const StyledFilter = styled.div` @@ -45,7 +46,26 @@ export const StyledFilter = styled.div` } `; -const SectionFilterContent = ({}) => { +const SectionFilterContent = ({ oformsFilter, setOformsFilter }) => { + const location = useLocation(); + const navigate = useNavigate(); + + const [isInitLoading, setIsInitLoading] = useState(true); + + useEffect(() => { + const firstLoadFilter = OformsFilter.getFilter(location); + if (!firstLoadFilter.locale) + firstLoadFilter.locale = getDefaultOformLocale(); + + setOformsFilter(firstLoadFilter); + setIsInitLoading(false); + }, []); + + useEffect(() => { + if (isInitLoading) return; + navigate(`${location.pathname}?${oformsFilter.toUrlParams()}`); + }, [oformsFilter.sortBy, oformsFilter.sortOrder]); + return (
@@ -60,4 +80,7 @@ const SectionFilterContent = ({}) => { ); }; -export default inject(({}) => ({}))(observer(SectionFilterContent)); +export default inject(({ oformsStore }) => ({ + oformsFilter: oformsStore.oformsFilter, + setOformsFilter: oformsStore.setOformsFilter, +}))(SectionFilterContent); diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index 4f5cee45df..c44b4be904 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -8,82 +8,67 @@ class OformsStore { oformFiles = null; oformsFilter = OformsFilter.getDefault(); - gallerySelected = null; oformsIsLoading = false; + gallerySelected = null; constructor(authStore) { - makeAutoObservable(this); - this.authStore = authStore; + makeAutoObservable(this); } - getOforms = async (filter = OformsFilter.getDefault()) => { - const oformData = await this.authStore.getOforms(filter); - const oformsFilter = oformData?.data?.meta?.pagination; - const newOformsFilter = this.oformsFilter.clone(); - - if (oformsFilter) { - newOformsFilter.page = oformsFilter.page; - newOformsFilter.total = oformsFilter.total; - newOformsFilter.categorizeBy = filter.categorizeBy; - newOformsFilter.categoryUrl = filter.categoryUrl; - newOformsFilter.locale = filter.locale; - newOformsFilter.sortBy = filter.sortBy; - newOformsFilter.sortOrder = filter.sortOrder; - } - - runInAction(() => { - this.setOformsFilter(newOformsFilter); - this.setOformFiles(oformData?.data?.data ?? []); - }); - }; - - setOformFiles = (oformFiles) => { - this.oformFiles = oformFiles; - }; - - setOformsFilter = (oformsFilter) => { - this.oformsFilter = oformsFilter; - }; - + setOformFiles = (oformFiles) => (this.oformFiles = oformFiles); + setOformsFilter = (oformsFilter) => (this.oformsFilter = oformsFilter); + setOformsIsLoading = (oformsIsLoading) => + (this.oformsIsLoading = oformsIsLoading); setGallerySelected = (gallerySelected) => { this.gallerySelected = gallerySelected; this.authStore.infoPanelStore.setSelection(gallerySelected); }; - setOformsIsLoading = (oformsIsLoading) => { - this.oformsIsLoading = oformsIsLoading; + getOforms = async (filter = OformsFilter.getDefault()) => { + const oformData = await this.authStore.getOforms(filter); + const forms = oformData?.data?.data ?? []; + + runInAction(() => { + this.setOformsFilter(filter); + this.setOformFiles(forms); + }); }; loadMoreForms = async () => { if (!this.hasMoreForms || this.oformsIsLoading) return; - - // console.log("loadMoreForms"); - this.setOformsIsLoading(true); const newOformsFilter = this.oformsFilter.clone(); - newOformsFilter.page += 1; - this.setOformsFilter(newOformsFilter); - const oformData = await this.authStore.getOforms(newOformsFilter); + const oformData = await this.authStore.getOforms(newOformsFilter, true); const newForms = oformData?.data?.data ?? []; runInAction(() => { + this.setOformsFilter(newOformsFilter); this.setOformFiles([...this.oformFiles, ...newForms]); this.setOformsIsLoading(false); }); }; + sortOforms = (sortBy, sortOrder) => { + if (!sortBy) return; + + const newOformsFilter = this.oformsFilter.clone(); + newOformsFilter.page = 1; + newOformsFilter.sortBy = sortBy; + newOformsFilter.sortOrder = sortOrder; + + this.getOforms(newOformsFilter); + }; + + filterByCategory = async () => {}; + get hasGalleryFiles() { return this.oformFiles && !!this.oformFiles.length; } - // get oformFilesLength() { - // return this.oformFiles.length; - // } - get oformsFilterTotal() { return this.oformsFilter.total; } From de77b417574eb9f53a0140eec3b176292bed4a41 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Mon, 28 Aug 2023 03:09:47 +0300 Subject: [PATCH 005/334] fixed pagination --- .../TilesView/sub-components/InfiniteGrid.js | 8 ++------ packages/client/src/store/OformsStore.js | 10 ++++++++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/client/src/pages/FormGallery/TilesView/sub-components/InfiniteGrid.js b/packages/client/src/pages/FormGallery/TilesView/sub-components/InfiniteGrid.js index ed94791990..86de474eff 100644 --- a/packages/client/src/pages/FormGallery/TilesView/sub-components/InfiniteGrid.js +++ b/packages/client/src/pages/FormGallery/TilesView/sub-components/InfiniteGrid.js @@ -129,12 +129,8 @@ const InfiniteGrid = (props) => { }; export default inject(({ auth, filesStore, oformsStore }) => { - const { - oformFiles, - hasMoreForms, - oformsFilterTotal, - loadMoreForms, - } = oformsStore; + const { oformFiles, hasMoreForms, oformsFilterTotal, loadMoreForms } = + oformsStore; const { getCountTilesInRow } = filesStore; diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index c44b4be904..82af35c52c 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -27,15 +27,21 @@ class OformsStore { getOforms = async (filter = OformsFilter.getDefault()) => { const oformData = await this.authStore.getOforms(filter); - const forms = oformData?.data?.data ?? []; + + const paginationData = oformData?.data?.meta?.pagination; + if (paginationData) { + filter.page = paginationData.page; + filter.total = paginationData.total; + } runInAction(() => { this.setOformsFilter(filter); - this.setOformFiles(forms); + this.setOformFiles(oformData?.data?.data ?? []); }); }; loadMoreForms = async () => { + console.log("loadmore!!"); if (!this.hasMoreForms || this.oformsIsLoading) return; this.setOformsIsLoading(true); From 82af5734ceaa33dc8adf7ab1dc21a915feff3059 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Mon, 28 Aug 2023 15:12:00 +0300 Subject: [PATCH 006/334] fix navigation issues --- .../components/Article/MainButton/index.js | 12 ++++++++++- .../client/src/pages/FormGallery/Header.js | 10 +++------- .../client/src/pages/FormGallery/index.js | 15 ++++---------- .../src/pages/Home/Section/Header/index.js | 10 +++++++++- packages/client/src/routes/client.js | 20 +++++++++++++++++++ 5 files changed, 47 insertions(+), 20 deletions(-) diff --git a/packages/client/src/components/Article/MainButton/index.js b/packages/client/src/components/Article/MainButton/index.js index 7fb987d80c..789382d939 100644 --- a/packages/client/src/components/Article/MainButton/index.js +++ b/packages/client/src/components/Article/MainButton/index.js @@ -105,6 +105,8 @@ const ArticleMainButtonContent = (props) => { isRoomsFolder, isArchiveFolder, + oformsFilter, + enablePlugins, currentColorScheme, @@ -197,7 +199,10 @@ const ArticleMainButtonContent = (props) => { const onInputClick = React.useCallback((e) => (e.target.value = null), []); const onShowGallery = () => { - navigate(`/form-gallery`); + const initOformFilter = ( + oformsFilter || oformsFilter.getDefault() + ).toUrlParams(); + navigate(`/form-gallery/${currentFolderId}/filter?${initOformFilter}`); }; const onInvite = React.useCallback((e) => { @@ -540,6 +545,7 @@ export default inject( treeFoldersStore, selectedFolderStore, clientLoadingStore, + oformsStore, }) => { const { showArticleLoader } = clientLoadingStore; const { mainButtonMobileVisible } = filesStore; @@ -568,6 +574,8 @@ export default inject( const { isAdmin, isOwner } = auth.userStore.user; const { isGracePeriod } = auth.currentTariffStatusStore; + const { oformsFilter } = oformsStore; + return { isGracePeriod, setInviteUsersWarningDialogVisible, @@ -591,6 +599,8 @@ export default inject( currentFolderId, + oformsFilter, + enablePlugins, currentColorScheme, diff --git a/packages/client/src/pages/FormGallery/Header.js b/packages/client/src/pages/FormGallery/Header.js index 38f6698616..1fc5d5537f 100644 --- a/packages/client/src/pages/FormGallery/Header.js +++ b/packages/client/src/pages/FormGallery/Header.js @@ -26,19 +26,15 @@ const SectionHeaderContent = (props) => { } = props; const navigate = useNavigate(); - const params = useParams(); + const { fromFolderId } = useParams(); const onBackToFiles = () => { setGallerySelected(null); const filter = FilesFilter.getDefault(); - - filter.folder = params.folderId; - + filter.folder = fromFolderId; const filterParamsStr = filter.toUrlParams(); - - const url = getCategoryUrl(categoryType, filter.folder); - + const url = getCategoryUrl(categoryType, fromFolderId); const pathname = `${url}?${filterParamsStr}`; navigate( diff --git a/packages/client/src/pages/FormGallery/index.js b/packages/client/src/pages/FormGallery/index.js index e817d42d73..0b74a33d0c 100644 --- a/packages/client/src/pages/FormGallery/index.js +++ b/packages/client/src/pages/FormGallery/index.js @@ -15,17 +15,10 @@ const FormGallery = ({ getOforms, setOformFiles }) => { const navigate = useNavigate(); useEffect(() => { - if (!window.location.search) { - const defaultFilter = OformsFilter.getDefault(); - navigate(`${location.pathname}/filter?${defaultFilter.toUrlParams()}`); - getOforms(defaultFilter); - } else { - const firstLoadFilter = OformsFilter.getFilter(window.location); - getOforms(firstLoadFilter); - } - return () => { - setOformFiles(null); - }; + const firstLoadFilter = OformsFilter.getFilter(location); + getOforms(firstLoadFilter); + + return () => setOformFiles(null); }, [getOforms, setOformFiles]); const [value, setValue] = React.useState(""); diff --git a/packages/client/src/pages/Home/Section/Header/index.js b/packages/client/src/pages/Home/Section/Header/index.js index 248ea36c00..d2fb38e61a 100644 --- a/packages/client/src/pages/Home/Section/Header/index.js +++ b/packages/client/src/pages/Home/Section/Header/index.js @@ -136,6 +136,7 @@ const SectionHeaderContent = (props) => { isHeaderChecked, isHeaderIndeterminate, showText, + oformsFilter, isEmptyArchive, @@ -244,7 +245,10 @@ const SectionHeaderContent = (props) => { }; const onShowGallery = () => { - navigate(`/form-gallery/`); + const initOformFilter = ( + oformsFilter || oformsFilter.getDefault() + ).toUrlParams(); + navigate(`/form-gallery/${currentFolderId}/filter?${initOformFilter}`); }; const createFolder = () => onCreate(); @@ -1046,6 +1050,7 @@ export default inject( clientLoadingStore, publicRoomStore, contextOptionsStore, + oformsStore, }) => { const isOwner = auth.userStore.user?.isOwner; const isAdmin = auth.userStore.user?.isAdmin; @@ -1119,6 +1124,8 @@ export default inject( moveToPublicRoom, } = filesActionsStore; + const { oformsFilter } = oformsStore; + const { setIsVisible, isVisible } = auth.infoPanelStore; const { title, id, roomType, pathParts, navigationPath, security } = @@ -1193,6 +1200,7 @@ export default inject( currentFolderId: id, pathParts: pathParts, navigationPath: folderPath, + oformsFilter, setIsInfoPanelVisible: setIsVisible, isInfoPanelVisible: isVisible, diff --git a/packages/client/src/routes/client.js b/packages/client/src/routes/client.js index 98a31ba3c6..854de8e113 100644 --- a/packages/client/src/routes/client.js +++ b/packages/client/src/routes/client.js @@ -245,6 +245,16 @@ const ClientRoutes = [ ), }, + { + path: "/form-gallery/:fromFolderId", + element: ( + + + + + + ), + }, { path: "/form-gallery/filter", element: ( @@ -255,6 +265,16 @@ const ClientRoutes = [ ), }, + { + path: "/form-gallery/:fromFolderId/filter", + element: ( + + + + + + ), + }, { path: "/rooms/share", element: ( From 716e08f1bddd1ab8835a85373de81ffbb4d4b19e Mon Sep 17 00:00:00 2001 From: mushka-n Date: Tue, 29 Aug 2023 04:51:39 +0300 Subject: [PATCH 007/334] dropdown and sortFilter update --- .../FormGallery/Filter/SearchFilter/index.js | 2 +- .../FormGallery/Filter/SortFilter/index.js | 9 +- .../Filter/SortFilter/index.styled.js | 21 ++-- .../client/src/pages/FormGallery/Header.js | 117 ++++++++++++++---- .../src/pages/FormGallery/StyledGallery.js | 43 +++++-- packages/client/src/store/OformsStore.js | 4 +- 6 files changed, 140 insertions(+), 56 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js b/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js index b3ec5a535f..e6b7317529 100644 --- a/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js @@ -14,7 +14,7 @@ export const StyledTextInput = styled(TextInput)` `; const SearchFilter = ({}) => { - const [value, setValue] = useState("asd"); + const [value, setValue] = useState(""); const onChangeValue = (e) => { setValue(e.target.value); diff --git a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js index 7ebe916b63..6ce9c09370 100644 --- a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js @@ -20,17 +20,13 @@ const sortData = [ }, ]; -const SortFilter = ({ t, oformsFilter, sortOforms }) => { - const sortBy = oformsFilter.sortBy; - const sortOrder = oformsFilter.sortOrder; - +const SortFilter = ({ t, sortBy, sortOrder, sortOforms }) => { const [isOpen, setIsOpen] = useState(false); const onToggleCombobox = () => setIsOpen(!isOpen); const onCloseCombobox = () => setIsOpen(false); const onSort = async (newSortBy, newSortOrder = "asc") => { await sortOforms(newSortBy, newSortOrder); - onCloseCombobox(); }; const onToggleSortOrder = (e, newSortBy) => { @@ -95,6 +91,7 @@ const SortFilter = ({ t, oformsFilter, sortOforms }) => { }; export default inject(({ oformsStore }) => ({ - oformsFilter: oformsStore.oformsFilter, + sortBy: oformsStore.oformsFilter.sortBy, + sortOrder: oformsStore.oformsFilter.sortOrder, sortOforms: oformsStore.sortOforms, }))(withTranslation(["FormGallery", "Common"])(SortFilter)); diff --git a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js index 196842758c..03ca0f90da 100644 --- a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js @@ -68,14 +68,19 @@ export const SortDropdownItem = styled(DropDownItem)` } ${({ isSelected, theme }) => - isSelected && - css` - background: ${theme.filterInput.sort.hoverBackground}; - cursor: auto; - .sortorder-arrow { - visibility: visible; - } - `} + isSelected + ? css` + background: ${theme.filterInput.sort.hoverBackground}; + cursor: auto; + .sortorder-arrow { + visibility: visible; + } + ` + : css` + .sortorder-arrow { + pointer-events: none; + } + `} ${({ isDescending }) => isDescending && diff --git a/packages/client/src/pages/FormGallery/Header.js b/packages/client/src/pages/FormGallery/Header.js index 1fc5d5537f..b5c89082cc 100644 --- a/packages/client/src/pages/FormGallery/Header.js +++ b/packages/client/src/pages/FormGallery/Header.js @@ -1,64 +1,125 @@ import PanelReactSvgUrl from "PUBLIC_DIR/images/panel.react.svg?url"; import ArrowPathReactSvgUrl from "PUBLIC_DIR/images/arrow.path.react.svg?url"; -import React from "react"; +import React, { useState, useEffect } from "react"; import { inject, observer } from "mobx-react"; import IconButton from "@docspace/components/icon-button"; import { withTranslation } from "react-i18next"; import { useNavigate, useParams } from "react-router-dom"; import { - StyledHeadline, StyledContainer, + StyledHeadline, + StyledNavigationDrodown, StyledInfoPanelToggleWrapper, } from "./StyledGallery"; import config from "PACKAGE_FILE"; import FilesFilter from "@docspace/common/api/files/filter"; import { combineUrl } from "@docspace/common/utils"; import { getCategoryUrl } from "SRC_DIR/helpers/utils"; +import TriangleNavigationDownReactSvgUrl from "PUBLIC_DIR/images/triangle.navigation.down.react.svg?url"; +import api from "@docspace/common/api"; +import { isMobileOnly } from "react-device-detect"; +import DropDownItem from "@docspace/components/drop-down-item"; -const SectionHeaderContent = (props) => { - const { - t, +const SectionHeaderContent = ({ + t, - isInfoPanelVisible, - setIsInfoPanelVisible, - setGallerySelected, - categoryType, - } = props; + categorizeBy, + categoryUrl, + isInfoPanelVisible, + setIsInfoPanelVisible, + setGallerySelected, + categoryType, +}) => { const navigate = useNavigate(); const { fromFolderId } = useParams(); - const onBackToFiles = () => { + const [checkboxOptions, setCheckboxOptions] = useState(<>{[]}); + + const onNavigateBack = () => { setGallerySelected(null); const filter = FilesFilter.getDefault(); filter.folder = fromFolderId; - const filterParamsStr = filter.toUrlParams(); const url = getCategoryUrl(categoryType, fromFolderId); - const pathname = `${url}?${filterParamsStr}`; + const filterParamsStr = filter.toUrlParams(); navigate( - combineUrl(window.DocSpaceConfig?.proxy?.url, config.homepage, pathname) + combineUrl( + window.DocSpaceConfig?.proxy?.url, + config.homepage, + `${url}?${filterParamsStr}` + ) ); }; - const toggleInfoPanel = () => { - setIsInfoPanelVisible(!isInfoPanelVisible); - }; + const onToggleInfoPanel = () => setIsInfoPanelVisible(!isInfoPanelVisible); + + useEffect(() => { + (async () => { + const newCheckboxOptions = []; + + if (categorizeBy && categoryUrl) { + newCheckboxOptions.push( + {}} + /> + ); + } + + if (fromFolderId) { + const fromFolder = await api.files.getFolderInfo(fromFolderId); + newCheckboxOptions.push( + + ); + } + + setCheckboxOptions(<>{newCheckboxOptions}); + })(); + }, [fromFolderId, categoryUrl]); return ( - + {t("Common:OFORMsGallery")} + + {((categorizeBy && categoryUrl) || fromFolderId) && ( + + )} +
{ iconName={PanelReactSvgUrl} size="16" isFill={true} - onClick={toggleInfoPanel} + onClick={onToggleInfoPanel} title={t("Common:InfoPanel")} />
@@ -76,13 +137,15 @@ const SectionHeaderContent = (props) => { }; export default inject(({ auth, filesStore, oformsStore }) => { - const { isVisible, setIsVisible } = auth.infoPanelStore; - const { categoryType } = filesStore; - const { setGallerySelected } = oformsStore; return { - isInfoPanelVisible: isVisible, - setIsInfoPanelVisible: setIsVisible, - setGallerySelected, - categoryType, + categoryType: filesStore.categoryType, + + categorizeBy: oformsStore.oformsFilter.categorizeBy, + categoryUrl: oformsStore.oformsFilter.categoryUrl, + + setGallerySelected: oformsStore.setGallerySelected, + + isInfoPanelVisible: auth.infoPanelStore.isVisible, + setIsInfoPanelVisible: auth.infoPanelStore.setIsVisible, }; })(withTranslation("Common")(observer(SectionHeaderContent))); diff --git a/packages/client/src/pages/FormGallery/StyledGallery.js b/packages/client/src/pages/FormGallery/StyledGallery.js index 06ae844849..ac821f5ab2 100644 --- a/packages/client/src/pages/FormGallery/StyledGallery.js +++ b/packages/client/src/pages/FormGallery/StyledGallery.js @@ -2,26 +2,22 @@ import styled, { css } from "styled-components"; import { isMobile, isMobileOnly } from "react-device-detect"; import { tablet, mobile } from "@docspace/components/utils/device"; import Headline from "@docspace/common/components/Headline"; +import ComboBox from "@docspace/components/combobox"; import { Base } from "@docspace/components/themes"; -const StyledHeadline = styled(Headline)` - width: 100%; - 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` width: 100%; height: 32px; display: grid; grid-template-columns: ${(props) => - props.isRootFolder ? "1fr auto" : "29px 1fr auto"}; + props.isRootFolder + ? props.withDropdown + ? "min-content 12px auto" + : "min-content auto" + : props.withDropdown + ? "29px min-content 12px auto" + : "29px min-content auto"}; align-items: center; @@ -53,6 +49,22 @@ const StyledContainer = styled.div` `} `; +const StyledHeadline = styled(Headline)` + width: fit-content; + font-weight: 700; + font-size: ${isMobile ? "21px !important" : "18px"}; + line-height: ${isMobile ? "28px !important" : "24px"}; + @media ${tablet} { + font-size: 21px; + line-height: 28px; + } +`; + +const StyledNavigationDrodown = styled(ComboBox)` + width: 12px; + margin-left: 4px; +`; + const StyledInfoPanelToggleWrapper = styled.div` margin-left: auto; @@ -88,4 +100,9 @@ const StyledInfoPanelToggleWrapper = styled.div` `; StyledInfoPanelToggleWrapper.defaultProps = { theme: Base }; -export { StyledHeadline, StyledContainer, StyledInfoPanelToggleWrapper }; +export { + StyledHeadline, + StyledContainer, + StyledNavigationDrodown, + StyledInfoPanelToggleWrapper, +}; diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index 82af35c52c..024c73a2e7 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -66,7 +66,9 @@ class OformsStore { newOformsFilter.sortBy = sortBy; newOformsFilter.sortOrder = sortOrder; - this.getOforms(newOformsFilter); + runInAction(() => { + this.getOforms(newOformsFilter); + }); }; filterByCategory = async () => {}; From bd4b4549793b6ecbce792b825ecfe245cee8e549 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Tue, 29 Aug 2023 05:05:57 +0300 Subject: [PATCH 008/334] dropdown update - now works without fromFolderId --- .../client/src/pages/FormGallery/Header.js | 58 +++++++++---------- .../src/pages/FormGallery/StyledGallery.js | 8 +-- .../src/pages/Home/InfoPanel/Body/index.js | 8 +-- 3 files changed, 33 insertions(+), 41 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Header.js b/packages/client/src/pages/FormGallery/Header.js index b5c89082cc..4c296d7d18 100644 --- a/packages/client/src/pages/FormGallery/Header.js +++ b/packages/client/src/pages/FormGallery/Header.js @@ -19,6 +19,7 @@ import TriangleNavigationDownReactSvgUrl from "PUBLIC_DIR/images/triangle.naviga import api from "@docspace/common/api"; import { isMobileOnly } from "react-device-detect"; import DropDownItem from "@docspace/components/drop-down-item"; +import { CategoryType } from "@docspace/client/src/helpers/constants"; const SectionHeaderContent = ({ t, @@ -64,34 +65,31 @@ const SectionHeaderContent = ({ {}} /> ); } - if (fromFolderId) { - const fromFolder = await api.files.getFolderInfo(fromFolderId); - newCheckboxOptions.push( - - ); - } + const prevFolderId = fromFolderId || CategoryType.SharedRoom; + const prevFolder = await api.files.getFolderInfo(prevFolderId); + newCheckboxOptions.push( + + ); setCheckboxOptions(<>{newCheckboxOptions}); })(); }, [fromFolderId, categoryUrl]); return ( - + - {((categorizeBy && categoryUrl) || fromFolderId) && ( - - )} +
diff --git a/packages/client/src/pages/FormGallery/StyledGallery.js b/packages/client/src/pages/FormGallery/StyledGallery.js index ac821f5ab2..104283472f 100644 --- a/packages/client/src/pages/FormGallery/StyledGallery.js +++ b/packages/client/src/pages/FormGallery/StyledGallery.js @@ -12,12 +12,8 @@ const StyledContainer = styled.div` grid-template-columns: ${(props) => props.isRootFolder - ? props.withDropdown - ? "min-content 12px auto" - : "min-content auto" - : props.withDropdown - ? "29px min-content 12px auto" - : "29px min-content auto"}; + ? "min-content 12px auto" + : "29px min-content 12px auto"}; align-items: center; diff --git a/packages/client/src/pages/Home/InfoPanel/Body/index.js b/packages/client/src/pages/Home/InfoPanel/Body/index.js index 72f71becb1..4e69166b88 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/index.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/index.js @@ -140,10 +140,10 @@ const InfoPanelBodyContent = ({ ////////////////////////////////////////////////////////// - // useEffect(() => { - // console.log("\nfor-dev Selected items: ", selectedItems); - // console.log("\nfor-dev Selected folder: ", selectedFolder); - // }, [selectedItems, selectedFolder]); + useEffect(() => { + console.log("\nfor-dev Selected items: ", selectedItems); + console.log("\nfor-dev Selected folder: ", selectedFolder); + }, [selectedItems, selectedFolder]); ////////////////////////////////////////////////////////// From da2b50d74b065f173832d4fe78b8daec33a85e53 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Tue, 29 Aug 2023 14:49:35 +0300 Subject: [PATCH 009/334] search filter --- .../Filter/CategoryFilter/SubList.js | 58 +++++++++++++ .../Filter/CategoryFilter/SubListByBranch.js | 43 ++-------- .../FormGallery/Filter/SearchFilter/index.js | 82 ++++++++++++------- packages/common/api/oforms/filter.js | 80 ++++++++++-------- packages/components/input-block/index.js | 4 + packages/components/search-input/index.js | 8 +- .../text-input/styled-text-input.js | 1 + packages/components/text-input/text-input.js | 2 + 8 files changed, 178 insertions(+), 100 deletions(-) create mode 100644 packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubList.js diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubList.js new file mode 100644 index 0000000000..62d69ad468 --- /dev/null +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubList.js @@ -0,0 +1,58 @@ +import DropDownItem from "@docspace/components/drop-down-item"; +import { isMobileOnly } from "react-device-detect"; +import { isMobile, isSmallTablet } from "@docspace/components/utils/device"; +import { StyledSubList, StyledSubItemMobile } from "./index.styled"; +import { inject } from "mobx-react"; +import { withTranslation } from "react-i18next"; +import { useLocation, useNavigate } from "react-router-dom"; + +const SubListByBranch = ({ isOpen, categories, marginTop, categoryType }) => { + const location = useLocation(); + const navigate = useNavigate(); + + const onOpenCategory = (category) => { + const newFilter = oformsFilter.clone(); + newFilter.categorizeBy = OformCategory.Branch; + newFilter.categoryUrl = category.attributes.urlReq; + getOforms(newFilter); + navigate(`${location.pathname}?${newFilter.toUrlParams()}`); + }; + + if (isSmallTablet() || isMobile() || isMobileOnly) + if (isOpen) + return categories.map((category) => ( + onOpenCategory(category)} + /> + )); + + return ( + {}} + withBackdrop={false} + marginTop={marginTop} + > + {categories.map((category) => ( + onOpenCategory(category)} + /> + ))} + + ); +}; + +export default inject(({}) => ({}))( + withTranslation(["FormGallery", "Common"])(SubListByBranch) +); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByBranch.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByBranch.js index aec5c2d326..bd510536e1 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByBranch.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByBranch.js @@ -9,6 +9,7 @@ import OformsFilter from "@docspace/common/api/oforms/filter"; import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; import { OformCategory } from "@docspace/client/src/helpers/constants"; +import SubList from "./SubList"; const SubListByBranch = ({ isOpen, oformsFilter, getOforms }) => { const [formsByBranch, setFormsByBranch] = useState([]); @@ -31,41 +32,15 @@ const SubListByBranch = ({ isOpen, oformsFilter, getOforms }) => { })(); }, []); - if (isSmallTablet() || isMobile() || isMobileOnly) { - if (isOpen) - return formsByBranch.map((category) => ( - onOpenCategory(category)} - /> - )); - } else - return ( - {}} - withBackdrop={false} - marginTop={"43px"} - > - {formsByBranch.map((category) => ( - onOpenCategory(category)} - /> - ))} - - ); + return ( + + ); }; - export default inject(({ oformsStore }) => ({ oformsFilter: oformsStore.oformsFilter, getOforms: oformsStore.getOforms, diff --git a/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js b/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js index e6b7317529..8164f2025c 100644 --- a/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js @@ -2,53 +2,75 @@ import InputBlock from "@docspace/components/input-block"; import SearchInput from "@docspace/components/search-input"; import TextInput from "@docspace/components/text-input"; import FieldContainer from "@docspace/components/field-container"; - -import { useState, useRef } from "react"; +import { inject } from "mobx-react"; +import { useState, useRef, useEffect, useCallback, useMemo } from "react"; import CopyReactSvgUrl from "PUBLIC_DIR/images/copy.react.svg?url"; - import styled from "styled-components"; +import { useLocation, useNavigate, useSearchParams } from "react-router-dom"; +import { withTranslation } from "react-i18next"; +import debounce from "lodash/debounce"; export const StyledTextInput = styled(TextInput)` width: 100%; max-width: 653px; `; -const SearchFilter = ({}) => { +const SearchFilter = ({ oformsFilter, getOforms }) => { + const location = useLocation(); + const navigate = useNavigate(); + const [value, setValue] = useState(""); - const onChangeValue = (e) => { - setValue(e.target.value); + // const onFilter = useCallback((val) => { + // const newFilter = oformsFilter.clone(); + // newFilter.search = val; + // getOforms(newFilter); + // navigate(`${location.pathname}?${newFilter.toUrlParams()}`); + // }, []); + + const onFilter = (val) => { + const newFilter = oformsFilter.clone(); + newFilter.search = val; + console.log(newFilter); + getOforms(newFilter); + navigate(`${location.pathname}?${newFilter.toUrlParams()}`); }; - const onClearSearch = () => { - setValue(""); + const debouncedOnFilter = useMemo(() => { + return debounce(onFilter, 300); + }, [onFilter]); + + const onChangeValue = (val) => { + setValue(val); + // debouncedOnFilter(value); + onFilter(val); }; + const onClearValue = () => onChangeValue(""); const ref = useRef(null); - const handleClick = () => { - if (!ref?.current) return; - console.log(ref.current); - }; + const onInputClick = () => ref?.current?.focus(); + const onInputOutsideClick = (e) => + !ref?.current?.contains(e.target) && ref.current.blur(); + useEffect(() => { + document.addEventListener("mousedown", onInputOutsideClick); + return () => document.removeEventListener("mousedown", onInputOutsideClick); + }, [ref]); return ( -
- {}} - onBlur={() => console.log("blur")} - onFocus={() => console.log("onFocus")} - onClick={handleClick} - // tabIndex={1} - // isAutoFocussed={true} - // isDisabled={false} - // onKeyDown={onKeyDown} - /> -
+ ); }; -export default SearchFilter; +export default inject(({ oformsStore }) => ({ + oformsFilter: oformsStore.oformsFilter, + getOforms: oformsStore.getOforms, +}))(withTranslation(["FormGallery", "Common"])(SearchFilter)); diff --git a/packages/common/api/oforms/filter.js b/packages/common/api/oforms/filter.js index 0e07601f52..592fec3e91 100644 --- a/packages/common/api/oforms/filter.js +++ b/packages/common/api/oforms/filter.js @@ -5,6 +5,7 @@ const PAGE_SIZE = "pagination[pageSize]"; const CATEGORIZE_BY = "categorizeby"; const CATEGORY_URL = "categoryUrl"; const LOCALE = "locale"; +const SEARCH = "filterValue"; const SORT = "sort"; const SORT_BY = "sortby"; const SORT_ORDER = "sortorder"; @@ -13,12 +14,35 @@ const DEFAULT_PAGE = 1; const DEFAULT_PAGE_SIZE = 150; const DEFAULT_TOTAL = 0; const DEFAULT_LOCALE = getDefaultOformLocale(); +const DEFAULT_SEARCH = ""; const DEFAULT_SORT_BY = ""; const DEFAULT_SORT_ORDER = ""; const DEFAULT_CATEGORIZE_BY = ""; const DEFAULT_CATEGORY_URL = ""; class OformsFilter { + constructor( + page = DEFAULT_PAGE, + pageSize = DEFAULT_PAGE_SIZE, + categorizeBy = DEFAULT_CATEGORIZE_BY, + categoryUrl = DEFAULT_CATEGORY_URL, + locale = DEFAULT_LOCALE, + search = DEFAULT_SEARCH, + sortBy = DEFAULT_SORT_BY, + sortOrder = DEFAULT_SORT_ORDER, + total = DEFAULT_TOTAL + ) { + this.page = page; + this.pageSize = pageSize; + this.categorizeBy = categorizeBy; + this.categoryUrl = categoryUrl; + this.locale = locale; + this.search = search; + this.sortBy = sortBy; + this.sortOrder = sortOrder; + this.total = total; + } + static getDefault(total = DEFAULT_TOTAL) { return new OformsFilter( DEFAULT_PAGE, @@ -26,6 +50,7 @@ class OformsFilter { DEFAULT_CATEGORIZE_BY, DEFAULT_CATEGORY_URL, DEFAULT_LOCALE, + DEFAULT_SEARCH, DEFAULT_SORT_BY, DEFAULT_SORT_ORDER, total @@ -49,6 +74,7 @@ class OformsFilter { const categoryUrl = urlFilter.get(CATEGORY_URL) || defaultFilter.categoryUrl; const locale = urlFilter.get(LOCALE) || defaultFilter.locale; + const search = urlFilter.get(SEARCH) || defaultFilter.search; const sortBy = urlFilter.get(SORT_BY) || defaultFilter.sortBy; const sortOrder = urlFilter.get(SORT_ORDER) || defaultFilter.sortOrder; @@ -58,6 +84,7 @@ class OformsFilter { categorizeBy, categoryUrl, locale, + search, sortBy, sortOrder, defaultFilter.total @@ -66,32 +93,28 @@ class OformsFilter { return newFilter; } - constructor( - page = DEFAULT_PAGE, - pageSize = DEFAULT_PAGE_SIZE, - categorizeBy = DEFAULT_CATEGORIZE_BY, - categoryUrl = DEFAULT_CATEGORY_URL, - locale = DEFAULT_LOCALE, - sortBy = DEFAULT_SORT_BY, - sortOrder = DEFAULT_SORT_ORDER, - total = DEFAULT_TOTAL - ) { - this.page = page; - this.pageSize = pageSize; - this.categorizeBy = categorizeBy; - this.categoryUrl = categoryUrl; - this.locale = locale; - this.sortBy = sortBy; - this.sortOrder = sortOrder; - this.total = total; + clone() { + return new OformsFilter( + this.page, + this.pageSize, + this.categorizeBy, + this.categoryUrl, + this.locale, + this.search, + this.sortBy, + this.sortOrder, + this.total + ); } toUrlParams = () => { - const { categorizeBy, categoryUrl, sortBy, sortOrder, locale } = this; + const { categorizeBy, categoryUrl, locale, search, sortBy, sortOrder } = + this; const dtoFilter = {}; dtoFilter[categorizeBy] = categoryUrl; dtoFilter[LOCALE] = locale; + dtoFilter[SEARCH] = search; dtoFilter[SORT_BY] = sortBy; dtoFilter[SORT_ORDER] = sortOrder; @@ -104,9 +127,10 @@ class OformsFilter { pageSize, categorizeBy, categoryUrl, + locale, + search, sortBy, sortOrder, - locale, } = this; const dtoFilter = {}; @@ -114,24 +138,12 @@ class OformsFilter { dtoFilter[PAGE_SIZE] = pageSize; if (categorizeBy && categoryUrl) dtoFilter[`filters[${categorizeBy}][urlReq][$eq]`] = categoryUrl; - if (sortBy && sortOrder) dtoFilter[SORT] = `${sortBy}:${sortOrder}`; dtoFilter[LOCALE] = locale; + dtoFilter[`filters[name_form][$containsi]`] = search; + if (sortBy && sortOrder) dtoFilter[SORT] = `${sortBy}:${sortOrder}`; return toUrlParams(dtoFilter, true); }; - - clone() { - return new OformsFilter( - this.page, - this.pageSize, - this.categorizeBy, - this.categoryUrl, - this.locale, - this.sortBy, - this.sortOrder, - this.total - ); - } } export default OformsFilter; diff --git a/packages/components/input-block/index.js b/packages/components/input-block/index.js index f5f05b37ff..9402618d2a 100644 --- a/packages/components/input-block/index.js +++ b/packages/components/input-block/index.js @@ -60,6 +60,7 @@ class InputBlock extends React.Component { iconSize, theme, forwardedRef, + onClick, iconButtonClassName, iconNode, } = this.props; @@ -105,6 +106,7 @@ class InputBlock extends React.Component { name={name} type={type} value={value} + onClick={onClick} isDisabled={isDisabled} hasError={hasError} hasWarning={hasWarning} @@ -155,6 +157,8 @@ class InputBlock extends React.Component { InputBlock.propTypes = { /** Used as HTML `id` property */ id: PropTypes.string, + /** Forwarded ref */ + forwardedRef: PropTypes.object, /** Used as HTML `name` property */ name: PropTypes.string, /** Supported type of the input fields. */ diff --git a/packages/components/search-input/index.js b/packages/components/search-input/index.js index f27af0c908..78ae82bcce 100644 --- a/packages/components/search-input/index.js +++ b/packages/components/search-input/index.js @@ -10,7 +10,8 @@ class SearchInput extends React.Component { constructor(props) { super(props); - this.input = React.createRef(); + this.forwardedRef = props.forwardedRef || React.createRef(); + console.log(this.input); this.timerId = null; this.state = { @@ -99,7 +100,8 @@ class SearchInput extends React.Component { ({ id: props.id, + forwardedRef: props.forwardedRef, name: props.name, type: props.type, value: props.value, diff --git a/packages/components/text-input/text-input.js b/packages/components/text-input/text-input.js index 5c6274ca3b..242c06d319 100644 --- a/packages/components/text-input/text-input.js +++ b/packages/components/text-input/text-input.js @@ -18,6 +18,8 @@ class TextInput extends React.Component { TextInput.propTypes = { /** Used as HTML `id` property */ id: PropTypes.string, + /** Forwarded ref */ + forwardedRef: PropTypes.object, /** Used as HTML `name` property */ name: PropTypes.string, /** Supported type of the input fields. */ From 1c0b5034b63a65a8161a179b8a84b2454cb5077b Mon Sep 17 00:00:00 2001 From: mushka-n Date: Thu, 31 Aug 2023 17:20:43 +0300 Subject: [PATCH 010/334] refactored SubList to single component, moved all logic to CategoryFilter --- .../Filter/CategoryFilter/SubList.js | 32 ++++-- .../Filter/CategoryFilter/SubListByBranch.js | 47 -------- .../Filter/CategoryFilter/SubListByType.js | 71 ------------ .../Filter/CategoryFilter/SubListPopular.js | 73 ------------- .../Filter/CategoryFilter/index.js | 102 ++++++++++++------ .../Filter/CategoryFilter/index.styled.js | 6 +- .../FormGallery/Filter/SearchFilter/index.js | 38 ++----- 7 files changed, 105 insertions(+), 264 deletions(-) delete mode 100644 packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByBranch.js delete mode 100644 packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByType.js delete mode 100644 packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListPopular.js diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubList.js index 62d69ad468..b8ced770fb 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubList.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubList.js @@ -5,14 +5,30 @@ import { StyledSubList, StyledSubItemMobile } from "./index.styled"; import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; import { useLocation, useNavigate } from "react-router-dom"; +import { OformCategory } from "@docspace/client/src/helpers/constants"; -const SubListByBranch = ({ isOpen, categories, marginTop, categoryType }) => { +const SubListByBranch = ({ + isOpen, + categoryType, + categories, + marginTop, + + getOforms, + oformsFilter, +}) => { const location = useLocation(); const navigate = useNavigate(); + const getCategoryLabel = (category) => + categoryType === OformCategory.Branch + ? category.attributes.categorie + : categoryType === OformCategory.Type + ? category.attributes.type + : category.attributes.compilation; + const onOpenCategory = (category) => { const newFilter = oformsFilter.clone(); - newFilter.categorizeBy = OformCategory.Branch; + newFilter.categorizeBy = categoryType; newFilter.categoryUrl = category.attributes.urlReq; getOforms(newFilter); navigate(`${location.pathname}?${newFilter.toUrlParams()}`); @@ -24,10 +40,11 @@ const SubListByBranch = ({ isOpen, categories, marginTop, categoryType }) => { onOpenCategory(category)} /> )); + else return null; return ( { onOpenCategory(category)} /> ))} @@ -53,6 +70,7 @@ const SubListByBranch = ({ isOpen, categories, marginTop, categoryType }) => { ); }; -export default inject(({}) => ({}))( - withTranslation(["FormGallery", "Common"])(SubListByBranch) -); +export default inject(({ oformsStore }) => ({ + getOforms: oformsStore.getOforms, + oformsFilter: oformsStore.oformsFilter, +}))(withTranslation(["FormGallery", "Common"])(SubListByBranch)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByBranch.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByBranch.js deleted file mode 100644 index bd510536e1..0000000000 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByBranch.js +++ /dev/null @@ -1,47 +0,0 @@ -import DropDownItem from "@docspace/components/drop-down-item"; -import { isMobileOnly } from "react-device-detect"; -import { isMobile, isSmallTablet } from "@docspace/components/utils/device"; -import { StyledSubList, StyledSubItemMobile } from "./index.styled"; -import { getCategoriesByBranch } from "@docspace/common/api/oforms"; -import { useState, useEffect } from "react"; -import { useLocation, useNavigate, useSearchParams } from "react-router-dom"; -import OformsFilter from "@docspace/common/api/oforms/filter"; -import { inject } from "mobx-react"; -import { withTranslation } from "react-i18next"; -import { OformCategory } from "@docspace/client/src/helpers/constants"; -import SubList from "./SubList"; - -const SubListByBranch = ({ isOpen, oformsFilter, getOforms }) => { - const [formsByBranch, setFormsByBranch] = useState([]); - - const location = useLocation(); - const navigate = useNavigate(); - - const onOpenCategory = (category) => { - const newFilter = oformsFilter.clone(); - newFilter.categorizeBy = OformCategory.Branch; - newFilter.categoryUrl = category.attributes.urlReq; - getOforms(newFilter); - navigate(`${location.pathname}?${newFilter.toUrlParams()}`); - }; - - useEffect(() => { - (async () => { - const data = await getCategoriesByBranch(); - setFormsByBranch(data); - })(); - }, []); - - return ( - - ); -}; -export default inject(({ oformsStore }) => ({ - oformsFilter: oformsStore.oformsFilter, - getOforms: oformsStore.getOforms, -}))(withTranslation(["FormGallery", "Common"])(SubListByBranch)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByType.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByType.js deleted file mode 100644 index 995c20e7f5..0000000000 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListByType.js +++ /dev/null @@ -1,71 +0,0 @@ -import DropDownItem from "@docspace/components/drop-down-item"; -import { isMobileOnly } from "react-device-detect"; -import { isMobile, isSmallTablet } from "@docspace/components/utils/device"; -import { StyledSubList, StyledSubItemMobile } from "./index.styled"; -import { getCategoriesByType } from "@docspace/common/api/oforms"; -import { useState, useEffect } from "react"; -import { useLocation, useNavigate, useSearchParams } from "react-router-dom"; -import { inject } from "mobx-react"; -import { withTranslation } from "react-i18next"; -import { OformCategory } from "@docspace/client/src/helpers/constants"; - -const SubListByType = ({ isOpen, getOforms, oformsFilter }) => { - const [formsByType, setFormsByType] = useState([]); - - const location = useLocation(); - const navigate = useNavigate(); - - const onOpenCategory = (category) => { - const newFilter = oformsFilter.clone(); - newFilter.categorizeBy = OformCategory.Type; - newFilter.categoryUrl = category.attributes.urlReq; - getOforms(newFilter); - navigate(`${location.pathname}?${newFilter.toUrlParams()}`); - }; - - useEffect(() => { - (async () => { - const data = await getCategoriesByType(); - setFormsByType(data); - })(); - }, []); - - if (isSmallTablet() || isMobile() || isMobileOnly) { - if (isOpen) - return formsByType.map((category) => ( - onOpenCategory(category)} - /> - )); - } else - return ( - {}} - withBackdrop={false} - marginTop={"79px"} - > - {formsByType.map((category) => ( - onOpenCategory(category)} - /> - ))} - - ); -}; - -export default inject(({ oformsStore }) => ({ - oformsFilter: oformsStore.oformsFilter, - getOforms: oformsStore.getOforms, -}))(withTranslation(["FormGallery", "Common"])(SubListByType)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListPopular.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListPopular.js deleted file mode 100644 index d8404c0a3b..0000000000 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubListPopular.js +++ /dev/null @@ -1,73 +0,0 @@ -import DropDownItem from "@docspace/components/drop-down-item"; -import { isMobileOnly } from "react-device-detect"; -import { isMobile, isSmallTablet } from "@docspace/components/utils/device"; -import { StyledSubList, StyledSubItemMobile } from "./index.styled"; -import { getPopularCategories } from "@docspace/common/api/oforms"; -import { useState, useEffect } from "react"; - -import { useLocation, useNavigate, useSearchParams } from "react-router-dom"; -import OformsFilter from "@docspace/common/api/oforms/filter"; -import { inject } from "mobx-react"; -import { withTranslation } from "react-i18next"; -import { OformCategory } from "@docspace/client/src/helpers/constants"; - -const SubListPopular = ({ isOpen, oformsFilter, getOforms }) => { - const [popularForms, setPopularForms] = useState([]); - - const location = useLocation(); - const navigate = useNavigate(); - - const onOpenCategory = (category) => { - const newFilter = oformsFilter.clone(); - newFilter.categorizeBy = OformCategory.Compilation; - newFilter.categoryUrl = category.attributes.urlReq; - getOforms(newFilter); - navigate(`${location.pathname}?${newFilter.toUrlParams()}`); - }; - - useEffect(() => { - (async () => { - const data = await getPopularCategories(); - setPopularForms(data); - })(); - }, []); - - if (isSmallTablet() || isMobile() || isMobileOnly) { - if (isOpen) - return popularForms.map((category) => ( - onOpenCategory(category)} - /> - )); - } else - return ( - {}} - withBackdrop={false} - marginTop={"111px"} - > - {popularForms.map((category) => ( - onOpenCategory(category)} - /> - ))} - - ); -}; - -export default inject(({ oformsStore }) => ({ - oformsFilter: oformsStore.oformsFilter, - getOforms: oformsStore.getOforms, -}))(withTranslation(["FormGallery", "Common"])(SubListPopular)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js index f06f3fc757..ac5d7d852a 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js @@ -5,14 +5,18 @@ import DropDownItem from "@docspace/components/drop-down-item"; import ExpanderDownReactSvgUrl from "PUBLIC_DIR/images/expander-down.react.svg?url"; import { ReactSVG } from "react-svg"; import Text from "@docspace/components/text"; -import { useRef, useState } from "react"; +import { useRef, useState, useEffect } from "react"; import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; -import SubListByBranch from "./SubListByBranch"; -import SubListByType from "./SubListByType"; -import SubListPopular from "./SubListPopular"; -import { useLocation, useNavigate, useSearchParams } from "react-router-dom"; +import { useLocation, useNavigate } from "react-router-dom"; import OformsFilter from "@docspace/common/api/oforms/filter"; +import SubList from "./SubList"; +import { OformCategory } from "@docspace/client/src/helpers/constants"; +import { + getCategoriesByBranch, + getCategoriesByType, + getPopularCategories, +} from "@docspace/common/api/oforms"; const CategoryFilter = ({ t, getOforms }) => { const dropdownRef = useRef(null); @@ -24,26 +28,38 @@ const CategoryFilter = ({ t, getOforms }) => { const toggleDropdownIsOpen = () => setIsOpen(!isOpen); const onCloseDropdown = () => setIsOpen(false); - const [mobileSubByBranchIsOpen, setMobileSubByBranchIsOpen] = useState(false); - const onToggleMobileSubByBranchIsOpen = () => { - setMobileSubByBranchIsOpen(!mobileSubByBranchIsOpen); - setMobileSubByTypeIsOpen(false); - setMobileSubPopularIsOpen(false); - }; + const [openedCategory, setOpenedCategory] = useState(null); + const isBranchCategoryOpen = openedCategory === OformCategory.Branch; + const isTypeCategoryOpen = openedCategory === OformCategory.Type; + const isCompilationCategoryOpen = + openedCategory === OformCategory.Compilation; - const [mobileSubByTypeIsOpen, setMobileSubByTypeIsOpen] = useState(false); - const onToggleMobileSubByTypeIsOpen = () => { - setMobileSubByTypeIsOpen(!mobileSubByTypeIsOpen); - setMobileSubByBranchIsOpen(false); - setMobileSubPopularIsOpen(false); - }; + const onToggleBranchCategory = () => + setOpenedCategory(isBranchCategoryOpen ? null : OformCategory.Branch); + const onToggleTypeCategory = () => + setOpenedCategory(isTypeCategoryOpen ? null : OformCategory.Type); + const onToggleCompilationCategory = () => + setOpenedCategory( + isCompilationCategoryOpen ? null : OformCategory.Compilation + ); - const [mobileSubPopularIsOpen, setMobileSubPopularIsOpen] = useState(false); - const onToggleMobileSubPopularIsOpen = () => { - setMobileSubPopularIsOpen(!mobileSubPopularIsOpen); - setMobileSubByBranchIsOpen(false); - setMobileSubByTypeIsOpen(false); - }; + const [formsByBranch, setFormsByBranch] = useState([]); + const [formsByType, setFormsByType] = useState([]); + const [formsByCompilation, setFormsByCompilation] = useState([]); + useEffect(() => { + (async () => { + const branchData = await getCategoriesByBranch(); + setFormsByBranch(branchData); + const typeData = await getCategoriesByType(); + setFormsByType(typeData); + const compilationData = await getPopularCategories(); + setFormsByCompilation(compilationData); + })(); + }, []); + + console.log(formsByBranch); + console.log(formsByType); + console.log(formsByCompilation); const onViewAllTemplates = () => { const newFilter = OformsFilter.getFilter(location); @@ -77,37 +93,53 @@ const CategoryFilter = ({ t, getOforms }) => { label={t("FormGallery:ViewAllTemplates")} onClick={onViewAllTemplates} /> + - + - + - +
diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.styled.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.styled.js index f39495dfe7..c1332b5e18 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.styled.js @@ -107,15 +107,15 @@ export const CategoryFilter = styled.div` } } - .item-by-branch:hover + .sub-by-branch { + .item-by-categories:hover + .sub-by-categories { visibility: visible; } - .item-by-type:hover + .sub-by-type { + .item-by-types:hover + .sub-by-types { visibility: visible; } - .item-popular:hover + .sub-popular { + .item-by-compilations:hover + .sub-by-compilations { visibility: visible; } } diff --git a/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js b/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js index 8164f2025c..ba07d950b6 100644 --- a/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js @@ -1,16 +1,11 @@ -import InputBlock from "@docspace/components/input-block"; import SearchInput from "@docspace/components/search-input"; -import TextInput from "@docspace/components/text-input"; -import FieldContainer from "@docspace/components/field-container"; import { inject } from "mobx-react"; -import { useState, useRef, useEffect, useCallback, useMemo } from "react"; -import CopyReactSvgUrl from "PUBLIC_DIR/images/copy.react.svg?url"; +import { useState, useRef, useEffect } from "react"; import styled from "styled-components"; -import { useLocation, useNavigate, useSearchParams } from "react-router-dom"; +import { useLocation, useNavigate } from "react-router-dom"; import { withTranslation } from "react-i18next"; -import debounce from "lodash/debounce"; -export const StyledTextInput = styled(TextInput)` +export const StyledSearchInput = styled(SearchInput)` width: 100%; max-width: 653px; `; @@ -20,15 +15,13 @@ const SearchFilter = ({ oformsFilter, getOforms }) => { const navigate = useNavigate(); const [value, setValue] = useState(""); + const onChangeValue = (val) => { + setValue(val); + onSearch(val); + }; + const onClearValue = () => onChangeValue(""); - // const onFilter = useCallback((val) => { - // const newFilter = oformsFilter.clone(); - // newFilter.search = val; - // getOforms(newFilter); - // navigate(`${location.pathname}?${newFilter.toUrlParams()}`); - // }, []); - - const onFilter = (val) => { + const onSearch = (val) => { const newFilter = oformsFilter.clone(); newFilter.search = val; console.log(newFilter); @@ -36,17 +29,6 @@ const SearchFilter = ({ oformsFilter, getOforms }) => { navigate(`${location.pathname}?${newFilter.toUrlParams()}`); }; - const debouncedOnFilter = useMemo(() => { - return debounce(onFilter, 300); - }, [onFilter]); - - const onChangeValue = (val) => { - setValue(val); - // debouncedOnFilter(value); - onFilter(val); - }; - const onClearValue = () => onChangeValue(""); - const ref = useRef(null); const onInputClick = () => ref?.current?.focus(); const onInputOutsideClick = (e) => @@ -57,7 +39,7 @@ const SearchFilter = ({ oformsFilter, getOforms }) => { }, [ref]); return ( - Date: Thu, 31 Aug 2023 18:24:19 +0300 Subject: [PATCH 011/334] fixed optimized filtering --- .../Filter/CategoryFilter/SubList.js | 12 +++------ .../Filter/CategoryFilter/index.js | 4 --- .../FormGallery/Filter/SortFilter/index.js | 4 +-- .../src/pages/FormGallery/Filter/index.js | 18 ++++++++++--- packages/client/src/store/OformsStore.js | 14 ++++++++++ packages/common/api/oforms/filter.js | 27 +++++++++---------- 6 files changed, 47 insertions(+), 32 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubList.js index b8ced770fb..04794183eb 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubList.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubList.js @@ -13,8 +13,7 @@ const SubListByBranch = ({ categories, marginTop, - getOforms, - oformsFilter, + filterOformsByCategory, }) => { const location = useLocation(); const navigate = useNavigate(); @@ -26,12 +25,8 @@ const SubListByBranch = ({ ? category.attributes.type : category.attributes.compilation; - const onOpenCategory = (category) => { - const newFilter = oformsFilter.clone(); - newFilter.categorizeBy = categoryType; - newFilter.categoryUrl = category.attributes.urlReq; - getOforms(newFilter); - navigate(`${location.pathname}?${newFilter.toUrlParams()}`); + const onOpenCategory = async (category) => { + await filterOformsByCategory(categoryType, category.id); }; if (isSmallTablet() || isMobile() || isMobileOnly) @@ -73,4 +68,5 @@ const SubListByBranch = ({ export default inject(({ oformsStore }) => ({ getOforms: oformsStore.getOforms, oformsFilter: oformsStore.oformsFilter, + filterOformsByCategory: oformsStore.filterOformsByCategory, }))(withTranslation(["FormGallery", "Common"])(SubListByBranch)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js index ac5d7d852a..3528d43681 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js @@ -57,10 +57,6 @@ const CategoryFilter = ({ t, getOforms }) => { })(); }, []); - console.log(formsByBranch); - console.log(formsByType); - console.log(formsByCompilation); - const onViewAllTemplates = () => { const newFilter = OformsFilter.getFilter(location); newFilter.categorizeBy = ""; diff --git a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js index 6ce9c09370..605f75524e 100644 --- a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js @@ -15,8 +15,8 @@ const sortData = [ id: "sort-by_name", key: "name_form", label: "Name", - default: true, - isSelected: true, + default: false, + isSelected: false, }, ]; diff --git a/packages/client/src/pages/FormGallery/Filter/index.js b/packages/client/src/pages/FormGallery/Filter/index.js index 38677f9c6b..e7bcbd9038 100644 --- a/packages/client/src/pages/FormGallery/Filter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/index.js @@ -54,17 +54,27 @@ const SectionFilterContent = ({ oformsFilter, setOformsFilter }) => { useEffect(() => { const firstLoadFilter = OformsFilter.getFilter(location); - if (!firstLoadFilter.locale) - firstLoadFilter.locale = getDefaultOformLocale(); - setOformsFilter(firstLoadFilter); + if (!firstLoadFilter.locale) { + firstLoadFilter.locale = getDefaultOformLocale(); + setOformsFilter(firstLoadFilter); + navigate(`${location.pathname}?${oformsFilter.toUrlParams()}`); + } else setOformsFilter(firstLoadFilter); + setIsInitLoading(false); }, []); useEffect(() => { if (isInitLoading) return; navigate(`${location.pathname}?${oformsFilter.toUrlParams()}`); - }, [oformsFilter.sortBy, oformsFilter.sortOrder]); + }, [ + oformsFilter.categorizeBy, + oformsFilter.categoryId, + // oformsFilter.locale, + // oformsFilter.search, + oformsFilter.sortBy, + oformsFilter.sortOrder, + ]); return ( diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index 024c73a2e7..37f7ee62c1 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -58,6 +58,20 @@ class OformsStore { }); }; + filterOformsByCategory = (categorizeBy, categoryId) => { + console.log(categorizeBy, categoryId); + if (!categorizeBy || !categoryId) return; + + const newOformsFilter = this.oformsFilter.clone(); + newOformsFilter.page = 1; + newOformsFilter.categorizeBy = categorizeBy; + newOformsFilter.categoryId = categoryId; + + runInAction(() => { + this.getOforms(newOformsFilter); + }); + }; + sortOforms = (sortBy, sortOrder) => { if (!sortBy) return; diff --git a/packages/common/api/oforms/filter.js b/packages/common/api/oforms/filter.js index 592fec3e91..17ca8a14b0 100644 --- a/packages/common/api/oforms/filter.js +++ b/packages/common/api/oforms/filter.js @@ -3,7 +3,7 @@ import { getDefaultOformLocale, toUrlParams } from "../../utils"; const PAGE = "pagination[page]"; const PAGE_SIZE = "pagination[pageSize]"; const CATEGORIZE_BY = "categorizeby"; -const CATEGORY_URL = "categoryUrl"; +const CATEGORY_ID = "categoryId"; const LOCALE = "locale"; const SEARCH = "filterValue"; const SORT = "sort"; @@ -18,14 +18,14 @@ const DEFAULT_SEARCH = ""; const DEFAULT_SORT_BY = ""; const DEFAULT_SORT_ORDER = ""; const DEFAULT_CATEGORIZE_BY = ""; -const DEFAULT_CATEGORY_URL = ""; +const DEFAULT_CATEGORY_ID = ""; class OformsFilter { constructor( page = DEFAULT_PAGE, pageSize = DEFAULT_PAGE_SIZE, categorizeBy = DEFAULT_CATEGORIZE_BY, - categoryUrl = DEFAULT_CATEGORY_URL, + categoryId = DEFAULT_CATEGORY_ID, locale = DEFAULT_LOCALE, search = DEFAULT_SEARCH, sortBy = DEFAULT_SORT_BY, @@ -35,7 +35,7 @@ class OformsFilter { this.page = page; this.pageSize = pageSize; this.categorizeBy = categorizeBy; - this.categoryUrl = categoryUrl; + this.categoryId = categoryId; this.locale = locale; this.search = search; this.sortBy = sortBy; @@ -48,7 +48,7 @@ class OformsFilter { DEFAULT_PAGE, DEFAULT_PAGE_SIZE, DEFAULT_CATEGORIZE_BY, - DEFAULT_CATEGORY_URL, + DEFAULT_CATEGORY_ID, DEFAULT_LOCALE, DEFAULT_SEARCH, DEFAULT_SORT_BY, @@ -71,8 +71,7 @@ class OformsFilter { defaultFilter.pageSize; const categorizeBy = urlFilter.get(CATEGORIZE_BY) || defaultFilter.categorizeBy; - const categoryUrl = - urlFilter.get(CATEGORY_URL) || defaultFilter.categoryUrl; + const categoryId = urlFilter.get(CATEGORY_ID) || defaultFilter.categoryId; const locale = urlFilter.get(LOCALE) || defaultFilter.locale; const search = urlFilter.get(SEARCH) || defaultFilter.search; const sortBy = urlFilter.get(SORT_BY) || defaultFilter.sortBy; @@ -82,7 +81,7 @@ class OformsFilter { page, pageSize, categorizeBy, - categoryUrl, + categoryId, locale, search, sortBy, @@ -98,7 +97,7 @@ class OformsFilter { this.page, this.pageSize, this.categorizeBy, - this.categoryUrl, + this.categoryId, this.locale, this.search, this.sortBy, @@ -108,11 +107,11 @@ class OformsFilter { } toUrlParams = () => { - const { categorizeBy, categoryUrl, locale, search, sortBy, sortOrder } = + const { categorizeBy, categoryId, locale, search, sortBy, sortOrder } = this; const dtoFilter = {}; - dtoFilter[categorizeBy] = categoryUrl; + dtoFilter[categorizeBy] = categoryId; dtoFilter[LOCALE] = locale; dtoFilter[SEARCH] = search; dtoFilter[SORT_BY] = sortBy; @@ -126,7 +125,7 @@ class OformsFilter { page, pageSize, categorizeBy, - categoryUrl, + categoryId, locale, search, sortBy, @@ -136,8 +135,8 @@ class OformsFilter { const dtoFilter = {}; dtoFilter[PAGE] = page; dtoFilter[PAGE_SIZE] = pageSize; - if (categorizeBy && categoryUrl) - dtoFilter[`filters[${categorizeBy}][urlReq][$eq]`] = categoryUrl; + if (categorizeBy && categoryId) + dtoFilter[`filters[${categorizeBy}][id][$eq]`] = categoryId; dtoFilter[LOCALE] = locale; dtoFilter[`filters[name_form][$containsi]`] = search; if (sortBy && sortOrder) dtoFilter[SORT] = `${sortBy}:${sortOrder}`; From e34b5b72b50a033b690ce5440723e05bca48c3bf Mon Sep 17 00:00:00 2001 From: mushka-n Date: Thu, 31 Aug 2023 18:39:13 +0300 Subject: [PATCH 012/334] refactored everything to store --- .../Filter/LanguageFilter/index.js | 45 +++++-------------- .../FormGallery/Filter/SearchFilter/index.js | 22 +++------ .../src/pages/FormGallery/Filter/index.js | 4 +- packages/client/src/store/OformsStore.js | 33 +++++++++----- 4 files changed, 40 insertions(+), 64 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js index 9cf296688e..1292d026c8 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js @@ -1,7 +1,5 @@ import * as Styled from "./index.styled"; -import { useEffect } from "react"; -import { useLocation, useNavigate, useSearchParams } from "react-router-dom"; import DropDown from "@docspace/components/drop-down"; import DropDownItem from "@docspace/components/drop-down-item"; import ExpanderDownReactSvgUrl from "PUBLIC_DIR/images/expander-down.react.svg?url"; @@ -9,53 +7,30 @@ import { ReactSVG } from "react-svg"; import { useRef, useState } from "react"; import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; -import OformsFilter from "@docspace/common/api/oforms/filter"; import { flagsIcons } from "@docspace/common/utils/image-helpers"; -import { - convertToCulture, - getDefaultOformLocale, -} from "@docspace/common/utils"; +import { convertToCulture } from "@docspace/common/utils"; const avialableLocales = ["en", "zh", "it", "fr", "es", "de", "ja"]; -const defaultOformLocale = getDefaultOformLocale(); -const LanguageFilter = ({ oformsFilter, getOforms }) => { +const LanguageFilter = ({ oformsFilter, filterOformsByLocale }) => { const dropdownRef = useRef(null); - const location = useLocation(); - const navigate = useNavigate(); - const [searchParams, setSearchParams] = useSearchParams(); - const [isOpen, setIsOpen] = useState(false); const toggleDropdownIsOpen = () => setIsOpen(!isOpen); - const [locale, setLocale] = useState(defaultOformLocale); - - const onSelectLanguage = (newLocale) => { - return () => { - const newFilter = oformsFilter.clone(); - newFilter.locale = newLocale; - getOforms(newFilter); - navigate(`${location.pathname}?${newFilter.toUrlParams()}`); - - setLocale(newLocale); - setIsOpen(false); - }; + const onFilterByLocale = (newLocale) => { + filterOformsByLocale(newLocale); }; - useEffect(() => { - let firstLoadLocale = searchParams.get("locale"); - if (!firstLoadLocale) firstLoadLocale = defaultOformLocale; - setLocale(firstLoadLocale); - }, []); - return (
{locale}
@@ -75,7 +50,7 @@ const LanguageFilter = ({ oformsFilter, getOforms }) => { key={i} className="dropdown-item" icon={flagsIcons?.get(`${convertToCulture(locale)}.react.svg`)} - onClick={onSelectLanguage(locale)} + onClick={() => onFilterByLocale(locale)} fillIcon={false} /> ))} @@ -87,5 +62,5 @@ const LanguageFilter = ({ oformsFilter, getOforms }) => { export default inject(({ oformsStore }) => ({ oformsFilter: oformsStore.oformsFilter, - getOforms: oformsStore.getOforms, + filterOformsByLocale: oformsStore.filterOformsByLocale, }))(withTranslation(["FormGallery", "Common"])(LanguageFilter)); diff --git a/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js b/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js index ba07d950b6..ae768a0fe0 100644 --- a/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js @@ -2,7 +2,6 @@ import SearchInput from "@docspace/components/search-input"; import { inject } from "mobx-react"; import { useState, useRef, useEffect } from "react"; import styled from "styled-components"; -import { useLocation, useNavigate } from "react-router-dom"; import { withTranslation } from "react-i18next"; export const StyledSearchInput = styled(SearchInput)` @@ -10,24 +9,14 @@ export const StyledSearchInput = styled(SearchInput)` max-width: 653px; `; -const SearchFilter = ({ oformsFilter, getOforms }) => { - const location = useLocation(); - const navigate = useNavigate(); - +const SearchFilter = ({ filterOformsBySearch }) => { const [value, setValue] = useState(""); + const onSearch = (val) => filterOformsBySearch(val); + const onClear = () => onChangeValue(""); const onChangeValue = (val) => { setValue(val); onSearch(val); }; - const onClearValue = () => onChangeValue(""); - - const onSearch = (val) => { - const newFilter = oformsFilter.clone(); - newFilter.search = val; - console.log(newFilter); - getOforms(newFilter); - navigate(`${location.pathname}?${newFilter.toUrlParams()}`); - }; const ref = useRef(null); const onInputClick = () => ref?.current?.focus(); @@ -47,12 +36,11 @@ const SearchFilter = ({ oformsFilter, getOforms }) => { value={value} onChange={onChangeValue} onClick={onInputClick} - onClearSearch={onClearValue} + onClearSearch={onClear} /> ); }; export default inject(({ oformsStore }) => ({ - oformsFilter: oformsStore.oformsFilter, - getOforms: oformsStore.getOforms, + filterOformsBySearch: oformsStore.filterOformsBySearch, }))(withTranslation(["FormGallery", "Common"])(SearchFilter)); diff --git a/packages/client/src/pages/FormGallery/Filter/index.js b/packages/client/src/pages/FormGallery/Filter/index.js index e7bcbd9038..d77b76e6ea 100644 --- a/packages/client/src/pages/FormGallery/Filter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/index.js @@ -70,8 +70,8 @@ const SectionFilterContent = ({ oformsFilter, setOformsFilter }) => { }, [ oformsFilter.categorizeBy, oformsFilter.categoryId, - // oformsFilter.locale, - // oformsFilter.search, + oformsFilter.locale, + oformsFilter.search, oformsFilter.sortBy, oformsFilter.sortOrder, ]); diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index 37f7ee62c1..1916aff7c3 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -59,7 +59,6 @@ class OformsStore { }; filterOformsByCategory = (categorizeBy, categoryId) => { - console.log(categorizeBy, categoryId); if (!categorizeBy || !categoryId) return; const newOformsFilter = this.oformsFilter.clone(); @@ -67,26 +66,40 @@ class OformsStore { newOformsFilter.categorizeBy = categorizeBy; newOformsFilter.categoryId = categoryId; - runInAction(() => { - this.getOforms(newOformsFilter); - }); + runInAction(() => this.getOforms(newOformsFilter)); + }; + + filterOformsByLocale = (locale) => { + if (!locale) return; + + const newOformsFilter = this.oformsFilter.clone(); + newOformsFilter.page = 1; + newOformsFilter.locale = locale; + newOformsFilter.categorizeBy = ""; + newOformsFilter.categoryId = ""; + + runInAction(() => this.getOforms(newOformsFilter)); + }; + + filterOformsBySearch = (search) => { + const newOformsFilter = this.oformsFilter.clone(); + newOformsFilter.page = 1; + newOformsFilter.search = search; + + runInAction(() => this.getOforms(newOformsFilter)); }; sortOforms = (sortBy, sortOrder) => { - if (!sortBy) return; + if (!sortBy || !sortOrder) return; const newOformsFilter = this.oformsFilter.clone(); newOformsFilter.page = 1; newOformsFilter.sortBy = sortBy; newOformsFilter.sortOrder = sortOrder; - runInAction(() => { - this.getOforms(newOformsFilter); - }); + runInAction(() => this.getOforms(newOformsFilter)); }; - filterByCategory = async () => {}; - get hasGalleryFiles() { return this.oformFiles && !!this.oformFiles.length; } From 3b591bdc891b8e01238e5084e1ab5aa8736e5f8c Mon Sep 17 00:00:00 2001 From: mushka-n Date: Thu, 31 Aug 2023 18:51:33 +0300 Subject: [PATCH 013/334] improved language filter styling --- .../FormGallery/Filter/LanguageFilter/index.js | 7 ++++--- .../Filter/LanguageFilter/index.styled.js | 13 ++++++++++++- .../client/src/pages/FormGallery/Filter/index.js | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js index 1292d026c8..af9c79bb2c 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js @@ -45,9 +45,10 @@ const LanguageFilter = ({ oformsFilter, filterOformsByLocale }) => { isDefaultMode={false} fixedDirection={true} > - {avialableLocales.map((locale, i) => ( - ( + onFilterByLocale(locale)} diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js index 9cf63417e3..d4a0a59325 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js @@ -1,4 +1,6 @@ -import styled from "styled-components"; +import DropDownItem from "@docspace/components/drop-down-item"; +import styled, { css } from "styled-components"; +import Base from "@docspace/components/themes/base"; export const LanguageFilter = styled.div` width: 41px; @@ -95,3 +97,12 @@ export const LanguageFilter = styled.div` } } `; + +export const LanguageFilterItem = styled(DropDownItem)` + ${({ isSelected, theme }) => + isSelected && + css` + background-color: ${theme.dropDownItem.hoverBackgroundColor}; + `} +`; +LanguageFilterItem.defaultProps = { theme: Base }; diff --git a/packages/client/src/pages/FormGallery/Filter/index.js b/packages/client/src/pages/FormGallery/Filter/index.js index d77b76e6ea..2a870c8a31 100644 --- a/packages/client/src/pages/FormGallery/Filter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/index.js @@ -2,7 +2,7 @@ import styled from "styled-components"; import { inject, observer } from "mobx-react"; import { useState, useEffect } from "react"; -import { useLocation, useNavigate, useSearchParams } from "react-router-dom"; +import { useLocation, useNavigate } from "react-router-dom"; import CategoryFilter from "./CategoryFilter"; import LanguageFilter from "./LanguageFilter"; import SearchFilter from "./SearchFilter"; From 5e9e2fdb7f704b93a60a99cf8f199c55b26e5b69 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Thu, 31 Aug 2023 20:57:12 +0300 Subject: [PATCH 014/334] category list renames --- .../{SubList.js => CategorySubList.js} | 13 ++++--------- .../FormGallery/Filter/CategoryFilter/index.js | 8 ++++---- .../pages/FormGallery/Filter/SortFilter/index.js | 10 +++++----- 3 files changed, 13 insertions(+), 18 deletions(-) rename packages/client/src/pages/FormGallery/Filter/CategoryFilter/{SubList.js => CategorySubList.js} (84%) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/CategorySubList.js similarity index 84% rename from packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubList.js rename to packages/client/src/pages/FormGallery/Filter/CategoryFilter/CategorySubList.js index 04794183eb..f9cfdcf0d9 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/SubList.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/CategorySubList.js @@ -4,10 +4,9 @@ import { isMobile, isSmallTablet } from "@docspace/components/utils/device"; import { StyledSubList, StyledSubItemMobile } from "./index.styled"; import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; -import { useLocation, useNavigate } from "react-router-dom"; import { OformCategory } from "@docspace/client/src/helpers/constants"; -const SubListByBranch = ({ +const CategorySubList = ({ isOpen, categoryType, categories, @@ -15,9 +14,6 @@ const SubListByBranch = ({ filterOformsByCategory, }) => { - const location = useLocation(); - const navigate = useNavigate(); - const getCategoryLabel = (category) => categoryType === OformCategory.Branch ? category.attributes.categorie @@ -25,9 +21,8 @@ const SubListByBranch = ({ ? category.attributes.type : category.attributes.compilation; - const onOpenCategory = async (category) => { - await filterOformsByCategory(categoryType, category.id); - }; + const onOpenCategory = (category) => + filterOformsByCategory(categoryType, category.id); if (isSmallTablet() || isMobile() || isMobileOnly) if (isOpen) @@ -69,4 +64,4 @@ export default inject(({ oformsStore }) => ({ getOforms: oformsStore.getOforms, oformsFilter: oformsStore.oformsFilter, filterOformsByCategory: oformsStore.filterOformsByCategory, -}))(withTranslation(["FormGallery", "Common"])(SubListByBranch)); +}))(withTranslation(["FormGallery", "Common"])(CategorySubList)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js index 3528d43681..8b52ceac36 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js @@ -10,7 +10,7 @@ import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; import { useLocation, useNavigate } from "react-router-dom"; import OformsFilter from "@docspace/common/api/oforms/filter"; -import SubList from "./SubList"; +import CategorySubList from "./CategorySubList"; import { OformCategory } from "@docspace/client/src/helpers/constants"; import { getCategoriesByBranch, @@ -100,7 +100,7 @@ const CategoryFilter = ({ t, getOforms }) => { onClick={onToggleBranchCategory} isSubMenu /> - { onClick={onToggleTypeCategory} isSubMenu /> - { onClick={onToggleCompilationCategory} isSubMenu /> - { directionY={"both"} scaled={true} size={"content"} + advancedOptionsCount={sortData.length} + disableIconClick={false} + disableItemClick={true} + isDefaultMode={false} + manualY={"102%"} advancedOptions={ <> {sortData?.map((item) => ( @@ -77,11 +82,6 @@ const SortFilter = ({ t, sortBy, sortOrder, sortOforms }) => { ))} } - advancedOptionsCount={sortData.length} - disableIconClick={false} - disableItemClick={true} - isDefaultMode={false} - manualY={"102%"} > From c2fae9ed4f131870b5f856e444134e0deb57cb26 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Thu, 31 Aug 2023 22:56:26 +0300 Subject: [PATCH 015/334] dynamic header + responsiveness tweaks --- packages/client/src/helpers/constants.js | 2 +- packages/client/src/helpers/utils.js | 11 +++- .../Filter/CategoryFilter/CategorySubList.js | 24 ++++--- .../Filter/CategoryFilter/index.js | 61 +++++++++-------- .../FormGallery/Filter/SearchFilter/index.js | 18 ++--- .../Filter/SearchFilter/index.styled.js | 7 ++ .../client/src/pages/FormGallery/Header.js | 66 ++++++++++++------- packages/client/src/store/OformsStore.js | 51 +++++++++----- packages/common/api/oforms/filter.js | 5 +- packages/common/api/oforms/index.js | 27 ++++---- 10 files changed, 161 insertions(+), 111 deletions(-) create mode 100644 packages/client/src/pages/FormGallery/Filter/SearchFilter/index.styled.js diff --git a/packages/client/src/helpers/constants.js b/packages/client/src/helpers/constants.js index 8c27c5b1ac..8817861caf 100644 --- a/packages/client/src/helpers/constants.js +++ b/packages/client/src/helpers/constants.js @@ -126,7 +126,7 @@ export const LinkType = Object.freeze({ External: 1, }); -export const OformCategory = Object.freeze({ +export const OformCategoryType = Object.freeze({ Branch: "categories", Type: "types", Compilation: "compilations", diff --git a/packages/client/src/helpers/utils.js b/packages/client/src/helpers/utils.js index 5c4b2331bc..1cca55d61a 100644 --- a/packages/client/src/helpers/utils.js +++ b/packages/client/src/helpers/utils.js @@ -1,7 +1,7 @@ import authStore from "@docspace/common/store/AuthStore"; import { toCommunityHostname, getLanguage } from "@docspace/common/utils"; -import { CategoryType } from "./constants"; +import { CategoryType, OformCategoryType } from "./constants"; import { FolderType, ShareAccessRights } from "@docspace/common/constants"; import { translations } from "./autoGeneratedTranslations"; // import router from "SRC_DIR/router"; @@ -224,3 +224,12 @@ export const filterUserRoleOptions = ( return newOptions; }; + +export const getOformCategoryTitle = (categorizeBy, category) => { + if (!categorizeBy || !category) return; + return categorizeBy === OformCategoryType.Branch + ? category.attributes.categorie + : categorizeBy === OformCategoryType.Type + ? category.attributes.type + : category.attributes.compilation; +}; diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/CategorySubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/CategorySubList.js index f9cfdcf0d9..9d1ed5b422 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/CategorySubList.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/CategorySubList.js @@ -4,7 +4,8 @@ import { isMobile, isSmallTablet } from "@docspace/components/utils/device"; import { StyledSubList, StyledSubItemMobile } from "./index.styled"; import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; -import { OformCategory } from "@docspace/client/src/helpers/constants"; +import { OformCategoryType } from "@docspace/client/src/helpers/constants"; +import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; const CategorySubList = ({ isOpen, @@ -13,16 +14,12 @@ const CategorySubList = ({ marginTop, filterOformsByCategory, + setOformsCurrentCategory, }) => { - const getCategoryLabel = (category) => - categoryType === OformCategory.Branch - ? category.attributes.categorie - : categoryType === OformCategory.Type - ? category.attributes.type - : category.attributes.compilation; - - const onOpenCategory = (category) => + const onFilterByCategory = (category) => { + setOformsCurrentCategory(category); filterOformsByCategory(categoryType, category.id); + }; if (isSmallTablet() || isMobile() || isMobileOnly) if (isOpen) @@ -30,8 +27,8 @@ const CategorySubList = ({ onOpenCategory(category)} + label={getOformCategoryTitle(categoryType, category)} + onClick={() => onFilterByCategory(category)} /> )); else return null; @@ -52,8 +49,8 @@ const CategorySubList = ({ onOpenCategory(category)} + label={getOformCategoryTitle(categoryType, category)} + onClick={() => onFilterByCategory(category)} /> ))} @@ -64,4 +61,5 @@ export default inject(({ oformsStore }) => ({ getOforms: oformsStore.getOforms, oformsFilter: oformsStore.oformsFilter, filterOformsByCategory: oformsStore.filterOformsByCategory, + setOformsCurrentCategory: oformsStore.setOformsCurrentCategory, }))(withTranslation(["FormGallery", "Common"])(CategorySubList)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js index 8b52ceac36..f2a26400ae 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js @@ -8,39 +8,42 @@ import Text from "@docspace/components/text"; import { useRef, useState, useEffect } from "react"; import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; -import { useLocation, useNavigate } from "react-router-dom"; -import OformsFilter from "@docspace/common/api/oforms/filter"; import CategorySubList from "./CategorySubList"; -import { OformCategory } from "@docspace/client/src/helpers/constants"; +import { OformCategoryType } from "@docspace/client/src/helpers/constants"; import { getCategoriesByBranch, getCategoriesByType, getPopularCategories, } from "@docspace/common/api/oforms"; +import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; -const CategoryFilter = ({ t, getOforms }) => { +const CategoryFilter = ({ + t, + currentCategory, + oformsFilter, + filterOformsByCategory, +}) => { const dropdownRef = useRef(null); - const location = useLocation(); - const navigate = useNavigate(); - const [isOpen, setIsOpen] = useState(false); const toggleDropdownIsOpen = () => setIsOpen(!isOpen); const onCloseDropdown = () => setIsOpen(false); const [openedCategory, setOpenedCategory] = useState(null); - const isBranchCategoryOpen = openedCategory === OformCategory.Branch; - const isTypeCategoryOpen = openedCategory === OformCategory.Type; + const isBranchCategoryOpen = openedCategory === OformCategoryType.Branch; + const isTypeCategoryOpen = openedCategory === OformCategoryType.Type; const isCompilationCategoryOpen = - openedCategory === OformCategory.Compilation; + openedCategory === OformCategoryType.Compilation; + + const onViewAllTemplates = () => filterOformsByCategory("", ""); const onToggleBranchCategory = () => - setOpenedCategory(isBranchCategoryOpen ? null : OformCategory.Branch); + setOpenedCategory(isBranchCategoryOpen ? null : OformCategoryType.Branch); const onToggleTypeCategory = () => - setOpenedCategory(isTypeCategoryOpen ? null : OformCategory.Type); + setOpenedCategory(isTypeCategoryOpen ? null : OformCategoryType.Type); const onToggleCompilationCategory = () => setOpenedCategory( - isCompilationCategoryOpen ? null : OformCategory.Compilation + isCompilationCategoryOpen ? null : OformCategoryType.Compilation ); const [formsByBranch, setFormsByBranch] = useState([]); @@ -57,19 +60,12 @@ const CategoryFilter = ({ t, getOforms }) => { })(); }, []); - const onViewAllTemplates = () => { - const newFilter = OformsFilter.getFilter(location); - newFilter.categorizeBy = ""; - newFilter.categoryUrl = ""; - getOforms(newFilter); - navigate(`${location.pathname}?${newFilter.toUrlParams()}`); - }; - return (
- {t("FormGallery:Categories")} + {getOformCategoryTitle(oformsFilter.categorizeBy, currentCategory) || + t("FormGallery:Categories")}
@@ -93,7 +89,7 @@ const CategoryFilter = ({ t, getOforms }) => { { /> { /> @@ -142,5 +138,8 @@ const CategoryFilter = ({ t, getOforms }) => { ); }; export default inject(({ oformsStore }) => ({ - getOforms: oformsStore.getOforms, + currentCategory: oformsStore.currentCategory, + + oformsFilter: oformsStore.oformsFilter, + filterOformsByCategory: oformsStore.filterOformsByCategory, }))(withTranslation(["FormGallery"])(CategoryFilter)); diff --git a/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js b/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js index ae768a0fe0..31ba74d4c6 100644 --- a/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js @@ -1,16 +1,11 @@ -import SearchInput from "@docspace/components/search-input"; import { inject } from "mobx-react"; import { useState, useRef, useEffect } from "react"; -import styled from "styled-components"; import { withTranslation } from "react-i18next"; -export const StyledSearchInput = styled(SearchInput)` - width: 100%; - max-width: 653px; -`; +import * as Styled from "./index.styled"; -const SearchFilter = ({ filterOformsBySearch }) => { - const [value, setValue] = useState(""); +const SearchFilter = ({ oformsFilter, filterOformsBySearch }) => { + const [value, setValue] = useState(oformsFilter.search); const onSearch = (val) => filterOformsBySearch(val); const onClear = () => onChangeValue(""); const onChangeValue = (val) => { @@ -18,6 +13,10 @@ const SearchFilter = ({ filterOformsBySearch }) => { onSearch(val); }; + useEffect(() => { + if (value !== oformsFilter.search) setValue(oformsFilter.search); + }, [oformsFilter.search]); + const ref = useRef(null); const onInputClick = () => ref?.current?.focus(); const onInputOutsideClick = (e) => @@ -28,7 +27,7 @@ const SearchFilter = ({ filterOformsBySearch }) => { }, [ref]); return ( - { }; export default inject(({ oformsStore }) => ({ + oformsFilter: oformsStore.oformsFilter, filterOformsBySearch: oformsStore.filterOformsBySearch, }))(withTranslation(["FormGallery", "Common"])(SearchFilter)); diff --git a/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.styled.js b/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.styled.js new file mode 100644 index 0000000000..703839f8ef --- /dev/null +++ b/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.styled.js @@ -0,0 +1,7 @@ +import styled from "styled-components"; +import SearchInput from "@docspace/components/search-input"; + +export const SearchFilter = styled(SearchInput)` + width: 100%; + max-width: 653px; +`; diff --git a/packages/client/src/pages/FormGallery/Header.js b/packages/client/src/pages/FormGallery/Header.js index 4c296d7d18..7356088e11 100644 --- a/packages/client/src/pages/FormGallery/Header.js +++ b/packages/client/src/pages/FormGallery/Header.js @@ -20,17 +20,23 @@ import api from "@docspace/common/api"; import { isMobileOnly } from "react-device-detect"; import DropDownItem from "@docspace/components/drop-down-item"; import { CategoryType } from "@docspace/client/src/helpers/constants"; +import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; const SectionHeaderContent = ({ t, - categorizeBy, - categoryUrl, + categoryType, + + currentCategory, + fetchCurrentCategory, + + oformsFilter, + filterOformsByCategory, + + setGallerySelected, isInfoPanelVisible, setIsInfoPanelVisible, - setGallerySelected, - categoryType, }) => { const navigate = useNavigate(); const { fromFolderId } = useParams(); @@ -54,39 +60,45 @@ const SectionHeaderContent = ({ ); }; + const onViewAllTemplates = () => filterOformsByCategory("", ""); + const onToggleInfoPanel = () => setIsInfoPanelVisible(!isInfoPanelVisible); useEffect(() => { - (async () => { - const newCheckboxOptions = []; + if (currentCategory) return; + fetchCurrentCategory(); + }, [oformsFilter.categorizeBy, oformsFilter.categoryId]); - if (categorizeBy && categoryUrl) { + useEffect(() => { + (async () => { + const prevFolderId = fromFolderId || CategoryType.SharedRoom; + const prevFolder = await api.files.getFolderInfo(prevFolderId); + + const newCheckboxOptions = []; + if (oformsFilter.categorizeBy && oformsFilter.categoryId) newCheckboxOptions.push( {}} + onClick={onViewAllTemplates} + /> + ); + if (prevFolder) + newCheckboxOptions.push( + ); - } - - const prevFolderId = fromFolderId || CategoryType.SharedRoom; - const prevFolder = await api.files.getFolderInfo(prevFolderId); - newCheckboxOptions.push( - - ); setCheckboxOptions(<>{newCheckboxOptions}); })(); - }, [fromFolderId, categoryUrl]); + }, [fromFolderId, oformsFilter.categorizeBy, oformsFilter.categoryId]); return ( @@ -99,7 +111,8 @@ const SectionHeaderContent = ({ /> - {t("Common:OFORMsGallery")} + {getOformCategoryTitle(oformsFilter.categorizeBy, currentCategory) || + t("Common:OFORMsGallery")} { return { categoryType: filesStore.categoryType, - categorizeBy: oformsStore.oformsFilter.categorizeBy, - categoryUrl: oformsStore.oformsFilter.categoryUrl, + currentCategory: oformsStore.currentCategory, + fetchCurrentCategory: oformsStore.fetchCurrentCategory, + + oformsFilter: oformsStore.oformsFilter, + filterOformsByCategory: oformsStore.filterOformsByCategory, setGallerySelected: oformsStore.setGallerySelected, diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index 1916aff7c3..faf26361fb 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -1,13 +1,18 @@ import { makeAutoObservable, runInAction } from "mobx"; import api from "@docspace/common/api"; +import { OformCategoryType } from "@docspace/client/src/helpers/constants"; const { OformsFilter } = api; +import { getCategoryById } from "@docspace/common/api/oforms"; + class OformsStore { authStore; oformFiles = null; oformsFilter = OformsFilter.getDefault(); + currentCategory = null; + oformsIsLoading = false; gallerySelected = null; @@ -18,6 +23,8 @@ class OformsStore { setOformFiles = (oformFiles) => (this.oformFiles = oformFiles); setOformsFilter = (oformsFilter) => (this.oformsFilter = oformsFilter); + setOformsCurrentCategory = (currentCategory) => + (this.currentCategory = currentCategory); setOformsIsLoading = (oformsIsLoading) => (this.oformsIsLoading = oformsIsLoading); setGallerySelected = (gallerySelected) => { @@ -58,33 +65,47 @@ class OformsStore { }); }; + fetchCurrentCategory = async () => { + const { categorizeBy, categoryId } = this.oformsFilter; + if (!categorizeBy || !categoryId) { + this.setOformsCurrentCategory(null); + return; + } + + const fetchedCategory = await getCategoryById(categorizeBy, categoryId); + + runInAction(() => { + this.setOformsCurrentCategory(fetchedCategory); + }); + }; + filterOformsByCategory = (categorizeBy, categoryId) => { - if (!categorizeBy || !categoryId) return; - + this.oformsFilter.page = 1; + this.oformsFilter.categorizeBy = categorizeBy; + this.oformsFilter.categoryId = categoryId; const newOformsFilter = this.oformsFilter.clone(); - newOformsFilter.page = 1; - newOformsFilter.categorizeBy = categorizeBy; - newOformsFilter.categoryId = categoryId; - runInAction(() => this.getOforms(newOformsFilter)); + runInAction(() => { + this.getOforms(newOformsFilter); + }); }; filterOformsByLocale = (locale) => { if (!locale) return; + this.oformsFilter.page = 1; + this.oformsFilter.locale = locale; + this.oformsFilter.categorizeBy = ""; + this.oformsFilter.categoryId = ""; const newOformsFilter = this.oformsFilter.clone(); - newOformsFilter.page = 1; - newOformsFilter.locale = locale; - newOformsFilter.categorizeBy = ""; - newOformsFilter.categoryId = ""; runInAction(() => this.getOforms(newOformsFilter)); }; filterOformsBySearch = (search) => { + this.oformsFilter.page = 1; + this.oformsFilter.search = search; const newOformsFilter = this.oformsFilter.clone(); - newOformsFilter.page = 1; - newOformsFilter.search = search; runInAction(() => this.getOforms(newOformsFilter)); }; @@ -92,10 +113,10 @@ class OformsStore { sortOforms = (sortBy, sortOrder) => { if (!sortBy || !sortOrder) return; + this.oformsFilter.page = 1; + this.oformsFilter.sortBy = sortBy; + this.oformsFilter.sortOrder = sortOrder; const newOformsFilter = this.oformsFilter.clone(); - newOformsFilter.page = 1; - newOformsFilter.sortBy = sortBy; - newOformsFilter.sortOrder = sortOrder; runInAction(() => this.getOforms(newOformsFilter)); }; diff --git a/packages/common/api/oforms/filter.js b/packages/common/api/oforms/filter.js index 17ca8a14b0..22572051f1 100644 --- a/packages/common/api/oforms/filter.js +++ b/packages/common/api/oforms/filter.js @@ -89,6 +89,8 @@ class OformsFilter { defaultFilter.total ); + console.log(location, newFilter); + return newFilter; } @@ -111,7 +113,8 @@ class OformsFilter { this; const dtoFilter = {}; - dtoFilter[categorizeBy] = categoryId; + dtoFilter[CATEGORIZE_BY] = categorizeBy; + dtoFilter[CATEGORY_ID] = categoryId; dtoFilter[LOCALE] = locale; dtoFilter[SEARCH] = search; dtoFilter[SORT_BY] = sortBy; diff --git a/packages/common/api/oforms/index.js b/packages/common/api/oforms/index.js index f61760ee89..ffd399355d 100644 --- a/packages/common/api/oforms/index.js +++ b/packages/common/api/oforms/index.js @@ -1,11 +1,16 @@ import { request } from "../oformClient"; -export const getCategoriesByBranch = async () => { - const options = { - method: "get", - url: `/categories`, - }; +export const getCategoryById = async (categorizeBy, id) => { + console.log(`/${categorizeBy}/${id}`); + const options = { method: "get", url: `/${categorizeBy}/${id}` }; + return request(options).then((res) => { + console.log(res); + return res; + }); +}; +export const getCategoriesByBranch = async () => { + const options = { method: "get", url: `/categories` }; return request(options).then((res) => { console.log(res); return res; @@ -13,11 +18,7 @@ export const getCategoriesByBranch = async () => { }; export const getCategoriesByType = async () => { - const options = { - method: "get", - url: `/types`, - }; - + const options = { method: "get", url: `/types` }; return request(options).then((res) => { console.log(res); return res; @@ -25,11 +26,7 @@ export const getCategoriesByType = async () => { }; export const getPopularCategories = async () => { - const options = { - method: "get", - url: `/compilations`, - }; - + const options = { method: "get", url: `/compilations` }; return request(options).then((res) => { console.log(res); return res; From bb0b9decf20a0731d647c29845243344d38fb6c9 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Thu, 31 Aug 2023 23:03:29 +0300 Subject: [PATCH 016/334] sort filter tweaks --- .../FormGallery/Filter/SortFilter/index.js | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js index 2bf91bbf60..e89d7ee98f 100644 --- a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js @@ -20,18 +20,23 @@ const sortData = [ }, ]; -const SortFilter = ({ t, sortBy, sortOrder, sortOforms }) => { +const SortFilter = ({ t, oformsFilter, sortOforms }) => { const [isOpen, setIsOpen] = useState(false); const onToggleCombobox = () => setIsOpen(!isOpen); - const onCloseCombobox = () => setIsOpen(false); - const onSort = async (newSortBy, newSortOrder = "asc") => { - await sortOforms(newSortBy, newSortOrder); + const onSort = (e, newSortBy, newSortOrder = "asc") => { + e.stopPropagation(); + if ( + oformsFilter.sortBy === newSortBy && + oformsFilter.sortOrder === newSortOrder + ) + return; + sortOforms(newSortBy, newSortOrder); }; const onToggleSortOrder = (e, newSortBy) => { e.stopPropagation(); - onSort(newSortBy, sortOrder === "desc" ? "asc" : "desc"); + onSort(e, newSortBy, oformsFilter.sortOrder === "desc" ? "asc" : "desc"); }; return ( @@ -67,11 +72,11 @@ const SortFilter = ({ t, sortBy, sortOrder, sortOforms }) => { {sortData?.map((item) => ( onSort(item.key)} + onClick={(e) => onSort(e, item.key)} key={item.key} data-value={item.key} - isSelected={sortBy === item.key} - isDescending={sortOrder === "desc"} + isSelected={oformsFilter.sortBy === item.key} + isDescending={oformsFilter.sortOrder === "desc"} > {t(`Common:${item.label}`)} { }; export default inject(({ oformsStore }) => ({ - sortBy: oformsStore.oformsFilter.sortBy, - sortOrder: oformsStore.oformsFilter.sortOrder, + oformsFilter: oformsStore.oformsFilter, sortOforms: oformsStore.sortOforms, }))(withTranslation(["FormGallery", "Common"])(SortFilter)); From 36aa3c52fe8d7d05eddea259a1f0e23dcd6991bb Mon Sep 17 00:00:00 2001 From: mushka-n Date: Thu, 31 Aug 2023 23:48:13 +0300 Subject: [PATCH 017/334] fixed empty non-en categories --- .../Filter/CategoryFilter/index.js | 20 +++++++++++---- packages/client/src/store/OformsStore.js | 25 ++++++++++++++++++- packages/common/api/oforms/index.js | 12 ++++----- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js index f2a26400ae..3f25c590e3 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js @@ -19,7 +19,13 @@ import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; const CategoryFilter = ({ t, + currentCategory, + + fetchCategoriesByBranch, + fetchCategoriesByType, + fetchPopularCategories, + oformsFilter, filterOformsByCategory, }) => { @@ -51,19 +57,19 @@ const CategoryFilter = ({ const [formsByCompilation, setFormsByCompilation] = useState([]); useEffect(() => { (async () => { - const branchData = await getCategoriesByBranch(); + const branchData = await fetchCategoriesByBranch(); setFormsByBranch(branchData); - const typeData = await getCategoriesByType(); + const typeData = await fetchCategoriesByType(); setFormsByType(typeData); - const compilationData = await getPopularCategories(); + const compilationData = await fetchPopularCategories(); setFormsByCompilation(compilationData); })(); - }, []); + }, [oformsFilter.locale]); return (
- + {getOformCategoryTitle(oformsFilter.categorizeBy, currentCategory) || t("FormGallery:Categories")} @@ -140,6 +146,10 @@ const CategoryFilter = ({ export default inject(({ oformsStore }) => ({ currentCategory: oformsStore.currentCategory, + fetchCategoriesByBranch: oformsStore.fetchCategoriesByBranch, + fetchCategoriesByType: oformsStore.fetchCategoriesByType, + fetchPopularCategories: oformsStore.fetchPopularCategories, + oformsFilter: oformsStore.oformsFilter, filterOformsByCategory: oformsStore.filterOformsByCategory, }))(withTranslation(["FormGallery"])(CategoryFilter)); diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index faf26361fb..4aa5b7a42b 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -4,7 +4,12 @@ import { OformCategoryType } from "@docspace/client/src/helpers/constants"; const { OformsFilter } = api; -import { getCategoryById } from "@docspace/common/api/oforms"; +import { + getCategoryById, + getCategoriesByBranch, + getCategoriesByType, + getPopularCategories, +} from "@docspace/common/api/oforms"; class OformsStore { authStore; @@ -79,6 +84,24 @@ class OformsStore { }); }; + fetchCategoriesByBranch = async () => { + const { locale } = this.oformsFilter; + const categoriesByBranch = await getCategoriesByBranch(locale); + return categoriesByBranch; + }; + + fetchCategoriesByType = async () => { + const { locale } = this.oformsFilter; + const categoriesByType = await getCategoriesByType(locale); + return categoriesByType; + }; + + fetchPopularCategories = async () => { + const { locale } = this.oformsFilter; + const popularCategories = await getPopularCategories(locale); + return popularCategories; + }; + filterOformsByCategory = (categorizeBy, categoryId) => { this.oformsFilter.page = 1; this.oformsFilter.categorizeBy = categorizeBy; diff --git a/packages/common/api/oforms/index.js b/packages/common/api/oforms/index.js index ffd399355d..50de1dc763 100644 --- a/packages/common/api/oforms/index.js +++ b/packages/common/api/oforms/index.js @@ -9,24 +9,24 @@ export const getCategoryById = async (categorizeBy, id) => { }); }; -export const getCategoriesByBranch = async () => { - const options = { method: "get", url: `/categories` }; +export const getCategoriesByBranch = async (locale = "en") => { + const options = { method: "get", url: `/categories?locale=${locale}` }; return request(options).then((res) => { console.log(res); return res; }); }; -export const getCategoriesByType = async () => { - const options = { method: "get", url: `/types` }; +export const getCategoriesByType = async (locale = "en") => { + const options = { method: "get", url: `/types?locale=${locale}` }; return request(options).then((res) => { console.log(res); return res; }); }; -export const getPopularCategories = async () => { - const options = { method: "get", url: `/compilations` }; +export const getPopularCategories = async (locale = "en") => { + const options = { method: "get", url: `/compilations?locale=${locale}` }; return request(options).then((res) => { console.log(res); return res; From 009c6f76fd4fd1f2647176edf26be8fe530291f6 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Mon, 4 Sep 2023 03:42:43 +0300 Subject: [PATCH 018/334] code clean --- .../src/pages/FormGallery/Filter/CategoryFilter/index.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js index 3f25c590e3..5131b2109a 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js @@ -10,11 +10,6 @@ import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; import CategorySubList from "./CategorySubList"; import { OformCategoryType } from "@docspace/client/src/helpers/constants"; -import { - getCategoriesByBranch, - getCategoriesByType, - getPopularCategories, -} from "@docspace/common/api/oforms"; import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; const CategoryFilter = ({ @@ -55,6 +50,7 @@ const CategoryFilter = ({ const [formsByBranch, setFormsByBranch] = useState([]); const [formsByType, setFormsByType] = useState([]); const [formsByCompilation, setFormsByCompilation] = useState([]); + useEffect(() => { (async () => { const branchData = await fetchCategoriesByBranch(); From 151ee059ab2d007694ea02487d814f1072daf191 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Wed, 6 Sep 2023 14:07:01 +0300 Subject: [PATCH 019/334] fix search filter translation bug --- .../client/src/pages/FormGallery/Filter/SearchFilter/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js b/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js index 31ba74d4c6..8c83873e13 100644 --- a/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js @@ -4,7 +4,7 @@ import { withTranslation } from "react-i18next"; import * as Styled from "./index.styled"; -const SearchFilter = ({ oformsFilter, filterOformsBySearch }) => { +const SearchFilter = ({ t, oformsFilter, filterOformsBySearch }) => { const [value, setValue] = useState(oformsFilter.search); const onSearch = (val) => filterOformsBySearch(val); const onClear = () => onChangeValue(""); @@ -31,7 +31,7 @@ const SearchFilter = ({ oformsFilter, filterOformsBySearch }) => { forwardedRef={ref} className="first-name" tabIndex={1} - placeholder={"Search"} + placeholder={t("Common:Search")} value={value} onChange={onChangeValue} onClick={onInputClick} From 7511e765e62be43389d0db5583cb9843c8f9a521 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Wed, 6 Sep 2023 14:07:52 +0300 Subject: [PATCH 020/334] styling update --- packages/client/src/pages/FormGallery/Filter/index.js | 2 +- packages/client/src/pages/FormGallery/index.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/client/src/pages/FormGallery/Filter/index.js b/packages/client/src/pages/FormGallery/Filter/index.js index 2a870c8a31..4e6803cb0f 100644 --- a/packages/client/src/pages/FormGallery/Filter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/index.js @@ -18,7 +18,7 @@ export const StyledFilter = styled.div` justify-content: space-between; gap: 8px; height: 32px; - padding: 8px 0; + padding: 8px 0 5px 0; .form-only-filters { display: flex; diff --git a/packages/client/src/pages/FormGallery/index.js b/packages/client/src/pages/FormGallery/index.js index 0b74a33d0c..202df37c59 100644 --- a/packages/client/src/pages/FormGallery/index.js +++ b/packages/client/src/pages/FormGallery/index.js @@ -34,15 +34,19 @@ const FormGallery = ({ getOforms, setOformFiles }) => { + + + + From e454ae55295c9caa28091137f30e81729066bc24 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Wed, 6 Sep 2023 15:19:01 +0300 Subject: [PATCH 021/334] styling update --- packages/client/src/pages/FormGallery/StyledGallery.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/client/src/pages/FormGallery/StyledGallery.js b/packages/client/src/pages/FormGallery/StyledGallery.js index 104283472f..55bf1a0150 100644 --- a/packages/client/src/pages/FormGallery/StyledGallery.js +++ b/packages/client/src/pages/FormGallery/StyledGallery.js @@ -59,6 +59,8 @@ const StyledHeadline = styled(Headline)` const StyledNavigationDrodown = styled(ComboBox)` width: 12px; margin-left: 4px; + box-sizing: border-box; + background: transparent; `; const StyledInfoPanelToggleWrapper = styled.div` From b48305ae352339b27f7f8f75b57dc8e8c581fc31 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Tue, 12 Sep 2023 11:42:45 +0300 Subject: [PATCH 022/334] category filter redo, finished desktop, in progress with mobile --- .../Filter/CategoryFilter/CategorySubList.js | 74 ++++++- .../DesktopView/CategorySubList.js | 60 ++++++ .../CategoryFilter/DesktopView/index.js | 126 ++++++++++++ .../DesktopView/index.styled.js | 75 +++++++ .../MobileView/CategorySubList.js | 36 ++++ .../Filter/CategoryFilter/MobileView/index.js | 188 ++++++++++++++++++ .../CategoryFilter/MobileView/index.styled.js | 104 ++++++++++ .../Filter/CategoryFilter/index.js | 127 +++--------- .../Filter/CategoryFilter/index.styled.js | 143 ++++--------- .../Filter/LanguageFilter/index.js | 7 +- packages/client/src/store/OformsStore.js | 2 +- packages/components/combobox/index.js | 1 + packages/components/drop-down/index.js | 6 +- 13 files changed, 734 insertions(+), 215 deletions(-) create mode 100644 packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/CategorySubList.js create mode 100644 packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js create mode 100644 packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js create mode 100644 packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js create mode 100644 packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js create mode 100644 packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.styled.js diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/CategorySubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/CategorySubList.js index 9d1ed5b422..3da0ab5fcd 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/CategorySubList.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/CategorySubList.js @@ -1,14 +1,19 @@ +import { useRef, memo } from "react"; import DropDownItem from "@docspace/components/drop-down-item"; -import { isMobileOnly } from "react-device-detect"; import { isMobile, isSmallTablet } from "@docspace/components/utils/device"; import { StyledSubList, StyledSubItemMobile } from "./index.styled"; import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; import { OformCategoryType } from "@docspace/client/src/helpers/constants"; import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; +import { isMobileOnly } from "react-device-detect"; +import VirtualList from "@docspace/components/drop-down/VirtualList"; const CategorySubList = ({ + theme, + isOpen, + isSubHovered, categoryType, categories, marginTop, @@ -16,6 +21,8 @@ const CategorySubList = ({ filterOformsByCategory, setOformsCurrentCategory, }) => { + const dropdownRef = useRef(null); + const onFilterByCategory = (category) => { setOformsCurrentCategory(category); filterOformsByCategory(categoryType, category.id); @@ -35,15 +42,25 @@ const CategorySubList = ({ return ( {}} - withBackdrop={false} + directionY={"bottom"} + manualY={"0px"} + manualX={"0px"} marginTop={marginTop} + open={true} + forwardedRef={dropdownRef} + clickOutsideAction={() => {}} + maxHeight={296} + manualWidth={"100%"} + showDisabledItems={false} + isDefaultMode={false} + withBackdrop={false} + withBackground={false} + isMobileView={false} + isNoFixedHeightOptions={false} > {categories.map((category) => ( ); + + // return ( + // {}} + // withBackdrop={false} + // marginTop={marginTop} + // > + // {categories.map((category) => ( + // onFilterByCategory(category)} + // /> + // ))} + // + // ); }; -export default inject(({ oformsStore }) => ({ +const Row = memo(({ data, index, style }) => { + const { children, theme, activedescendant, handleMouseMove } = data; + const option = children[index]; + const newStyle = { ...style, ...separator }; + return ( + handleMouseMove(index)} + isActiveDescendant={activedescendant === index} + {...option?.props} + /> + ); +}); + +export default inject(({ auth, oformsStore }) => ({ + theme: auth.settingsStore.theme, + getOforms: oformsStore.getOforms, oformsFilter: oformsStore.oformsFilter, filterOformsByCategory: oformsStore.filterOformsByCategory, diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/CategorySubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/CategorySubList.js new file mode 100644 index 0000000000..9dd70f3e1f --- /dev/null +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/CategorySubList.js @@ -0,0 +1,60 @@ +import DropDownItem from "@docspace/components/drop-down-item"; +import { StyledSubList } from "./index.styled"; +import { inject } from "mobx-react"; +import { withTranslation } from "react-i18next"; +import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; + +const CategorySubList = ({ + categoryType, + categories, + + isSubHovered, + marginTop, + + filterOformsByCategory, + setOformsCurrentCategory, +}) => { + const onFilterByCategory = (category) => { + setOformsCurrentCategory(category); + filterOformsByCategory(categoryType, category.id); + }; + + return ( + {}} + maxHeight={296} + manualWidth={"100%"} + showDisabledItems={false} + isDefaultMode={false} + withBackdrop={false} + withBackground={false} + isMobileView={false} + isNoFixedHeightOptions={false} + > + {categories.map((category) => ( + onFilterByCategory(category)} + /> + ))} + + ); +}; + +export default inject(({ oformsStore }) => ({ + getOforms: oformsStore.getOforms, + oformsFilter: oformsStore.oformsFilter, + filterOformsByCategory: oformsStore.filterOformsByCategory, + setOformsCurrentCategory: oformsStore.setOformsCurrentCategory, +}))(withTranslation(["FormGallery", "Common"])(CategorySubList)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js new file mode 100644 index 0000000000..7463630117 --- /dev/null +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js @@ -0,0 +1,126 @@ +import * as Styled from "./index.styled"; + +import DropDownItem from "@docspace/components/drop-down-item"; +import { useState } from "react"; +import { inject } from "mobx-react"; +import { withTranslation } from "react-i18next"; +import CategorySubList from "./CategorySubList"; +import { OformCategoryType } from "@docspace/client/src/helpers/constants"; + +const CategoryFilterDesktop = ({ + t, + + onViewAllTemplates, + formsByBranch, + formsByType, + formsByCompilation, +}) => { + const [isOpen, setIsOpen] = useState(false); + const toggleDropdownIsOpen = () => setIsOpen(!isOpen); + const onCloseDropdown = () => setIsOpen(false); + + const [isBranchHovered, setIsBranchHovered] = useState(false); + const [isTypeHovered, setIsTypeHovered] = useState(false); + const [isCompilationHovered, setIsCompilationHovered] = useState(false); + + const onMouseEnterBranch = () => setIsBranchHovered(true); + const onMouseLeaveBranch = () => setIsBranchHovered(false); + const onMouseEnterType = () => setIsTypeHovered(true); + const onMouseLeaveType = () => setIsTypeHovered(false); + const onMouseEnterCompilation = () => setIsCompilationHovered(true); + const onMouseLeaveCompilation = () => setIsCompilationHovered(false); + + return ( + + {}} + isDisabled={false} + manualWidth={"100%"} + showDisabledItems={true} + options={[]} + directionX={"right"} + directionY={"both"} + scaled={true} + size={"content"} + disableIconClick={false} + disableItemClick={false} + isDefaultMode={false} + fixedDirection={true} + advancedOptionsCount={5} + advancedOptions={ + <> + + + + + + + } + /> + + + + + + + ); +}; +export default inject(({ oformsStore }) => ({ + currentCategory: oformsStore.currentCategory, + + fetchCategoriesByBranch: oformsStore.fetchCategoriesByBranch, + fetchCategoriesByType: oformsStore.fetchCategoriesByType, + fetchPopularCategories: oformsStore.fetchPopularCategories, + + oformsFilter: oformsStore.oformsFilter, + filterOformsByCategory: oformsStore.filterOformsByCategory, +}))(withTranslation(["FormGallery"])(CategoryFilterDesktop)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js new file mode 100644 index 0000000000..bdb1ea1d5e --- /dev/null +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js @@ -0,0 +1,75 @@ +import styled, { css } from "styled-components"; + +import DropDown from "@docspace/components/drop-down"; +import DropDownItem from "@docspace/components/drop-down-item"; +import ComboBox from "@docspace/components/combobox"; + +export const CategoryFilterWrapper = styled.div` + position: relative; + width: 220px; + box-sizing: border-box; +`; + +export const CategoryFilter = styled(ComboBox)` + width: 220px; + box-sizing: border-box; + + .combo-button-label { + font-weight: 400; + font-size: 13px; + line-height: 20px; + } + + .dropdown-container { + margin-top: 4px; + } +`; + +export const CategoryFilterItem = styled(DropDownItem)` + width: 100%; + height: 32px; + box-sizing: border-box; + font-size: 12px; + font-weight: 600; + line-height: 16px; + padding-top: 8px; + padding-bottom: 8px; + + .submenu-arrow { + margin-right: 0; + svg { + height: 12px; + width: 12px; + } + } +`; + +export const StyledSubList = styled(DropDown)` + position: absolute; + top: 0; + margin-top: ${({ marginTop }) => marginTop}; + left: calc(100% + 4px); + + visibility: hidden; + &:hover { + visibility: visible; + } + ${({ isSubHovered }) => + isSubHovered && + css` + visibility: visible; + `}; + + &:before { + content: ""; + position: absolute; + left: -4px; + top: 0; + width: 4px; + height: 100%; + } +`; + +export const StyledSubItemMobile = styled(DropDownItem)` + margin-left: 16px; +`; diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js new file mode 100644 index 0000000000..3edd6d6e43 --- /dev/null +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js @@ -0,0 +1,36 @@ +import { StyledSubItemMobile } from "./index.styled"; +import { inject } from "mobx-react"; +import { withTranslation } from "react-i18next"; +import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; + +const CategorySubList = ({ + categoryType, + categories, + + filterOformsByCategory, + setOformsCurrentCategory, +}) => { + const onFilterByCategory = (category) => { + setOformsCurrentCategory(category); + filterOformsByCategory(categoryType, category.id); + }; + + if (isOpen) + return categories.map((category) => ( + onFilterByCategory(category)} + /> + )); +}; + +export default inject(({ auth, oformsStore }) => ({ + theme: auth.settingsStore.theme, + + getOforms: oformsStore.getOforms, + oformsFilter: oformsStore.oformsFilter, + filterOformsByCategory: oformsStore.filterOformsByCategory, + setOformsCurrentCategory: oformsStore.setOformsCurrentCategory, +}))(withTranslation(["FormGallery", "Common"])(CategorySubList)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js new file mode 100644 index 0000000000..883605daf2 --- /dev/null +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js @@ -0,0 +1,188 @@ +import * as Styled from "./index.styled"; + +import DropDownItem from "@docspace/components/drop-down-item"; +import { useState, useEffect, useRef } from "react"; +import { inject } from "mobx-react"; +import { withTranslation } from "react-i18next"; +import CategorySubList from "./CategorySubList"; +import { OformCategoryType } from "@docspace/client/src/helpers/constants"; +import Scrollbar from "@docspace/components/scrollbar"; +import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; + +const CategoryFilterMobile = ({ + t, + + onViewAllTemplates, + formsByBranch, + formsByType, + formsByCompilation, +}) => { + const dropdownRef = useRef(); + + const [openedCategory, setOpenedCategory] = useState(null); + const isBranchOpen = openedCategory === OformCategoryType.Branch; + const isTypeOpen = openedCategory === OformCategoryType.Type; + const isCompilationOpen = openedCategory === OformCategoryType.Compilation; + + const onToggleBranchCategory = () => + setOpenedCategory(isBranchOpen ? null : OformCategoryType.Branch); + const onToggleTypeCategory = () => + setOpenedCategory(isTypeOpen ? null : OformCategoryType.Type); + const onToggleCompilationCategory = () => + setOpenedCategory(isCompilationOpen ? null : OformCategoryType.Compilation); + + return ( + + + + + + {isBranchOpen && ( + + )} + + + + + ); + + // // general interactions + + // const [isOpen, setIsOpen] = useState(false); + // const toggleDropdownIsOpen = () => setIsOpen(!isOpen); + // const onCloseDropdown = () => setIsOpen(false); + + // // mobile interactions + + // const [openedCategory, setOpenedCategory] = useState(null); + // const isBranchOpen = openedCategory === OformCategoryType.Branch; + // const isTypeOpen = openedCategory === OformCategoryType.Type; + // const isCompilationOpen = openedCategory === OformCategoryType.Compilation; + + // const onToggleBranchCategory = () => + // setOpenedCategory(isBranchOpen ? null : OformCategoryType.Branch); + // const onToggleTypeCategory = () => + // setOpenedCategory(isTypeOpen ? null : OformCategoryType.Type); + // const onToggleCompilationCategory = () => + // setOpenedCategory(isCompilationOpen ? null : OformCategoryType.Compilation); + + // return ( + // + // {}} + // isDisabled={false} + // manualWidth={"100%"} + // showDisabledItems={true} + // options={[]} + // directionX={"right"} + // directionY={"both"} + // scaled={true} + // size={"content"} + // disableIconClick={false} + // disableItemClick={false} + // isDefaultMode={false} + // fixedDirection={true} + // advancedOptionsCount={5} + // advancedOptions={ + // <> + // + // + // + // + // + // + // } + // /> + // + // ); +}; + +export default inject(({ oformsStore }) => ({ + currentCategory: oformsStore.currentCategory, + + fetchCategoriesByBranch: oformsStore.fetchCategoriesByBranch, + fetchCategoriesByType: oformsStore.fetchCategoriesByType, + fetchPopularCategories: oformsStore.fetchPopularCategories, + + oformsFilter: oformsStore.oformsFilter, + filterOformsByCategory: oformsStore.filterOformsByCategory, +}))(withTranslation(["FormGallery"])(CategoryFilterMobile)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.styled.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.styled.js new file mode 100644 index 0000000000..4545e1ffad --- /dev/null +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.styled.js @@ -0,0 +1,104 @@ +import { smallTablet, mobile } from "@docspace/components/utils/device"; +import styled, { css } from "styled-components"; + +import DropDown from "@docspace/components/drop-down"; +import DropDownItem from "@docspace/components/drop-down-item"; +import ComboBox from "@docspace/components/combobox"; + +import { isMobileOnly } from "react-device-detect"; + +export const CategoryFilterMobile = styled(DropDown)` + position: relative; + width: 100%; + + /* bottom: ${(props) => props.theme.mainButtonMobile.dropDown.bottom}; + z-index: ${(props) => props.theme.mainButtonMobile.dropDown.zIndex}; */ + height: calc(100vw - 128px); + + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + + padding: 0px; + + .section-scroll, + .scroll-body { + ${({ theme }) => + theme.interfaceDirection === "rtl" + ? `padding-left: 0px !important;` + : `padding-right: 0px !important;`} + } + + .separator-wrapper { + padding: 12px 24px; + } + + /* .is-separator { + height: 1px !important; + width: calc(100% - 48px); + padding: 0 !important; + margin: 12px 24px !important; + background-color: ${(props) => + props.theme.mainButtonMobile.dropDown.separatorBackground}; + } */ + + /* .drop-down-item-button { + color: ${(props) => props.theme.mainButtonMobile.dropDown.buttonColor}; + + svg { + path[fill] { + fill: ${(props) => props.theme.mainButtonMobile.dropDown.buttonColor}; + } + + path[stroke] { + stroke: ${(props) => props.theme.mainButtonMobile.dropDown.buttonColor}; + } + } + + &:hover { + background-color: ${(props) => + isMobileOnly + ? props.theme.mainButtonMobile.buttonOptions.backgroundColor + : props.theme.mainButtonMobile.dropDown.hoverButtonColor}; + } + } */ + + /* .action-mobile-button { + width: 100%; + background-color: ${(props) => + props.theme.mainButtonMobile.dropDown.backgroundActionMobile}; + border-radius: 3px; + font-size: 13px; + display: block; + } */ +`; + +export const CategoryFilterItem = styled(DropDownItem)` + width: 100%; + height: 32px; + box-sizing: border-box; + font-size: 12px; + font-weight: 600; + line-height: 16px; + padding-top: 8px; + padding-bottom: 8px; + + .submenu-arrow { + margin-right: 0; + + svg { + height: 12px; + width: 12px; + } + + ${({ isMobileOpen }) => + isMobileOpen && + css` + transform: rotate(270deg); + `} + } +`; + +export const StyledSubItemMobile = styled(DropDownItem)` + margin-left: 16px; +`; diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js index 5131b2109a..4d766fb8c1 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js @@ -1,22 +1,22 @@ import * as Styled from "./index.styled"; -import DropDown from "@docspace/components/drop-down"; import DropDownItem from "@docspace/components/drop-down-item"; -import ExpanderDownReactSvgUrl from "PUBLIC_DIR/images/expander-down.react.svg?url"; -import { ReactSVG } from "react-svg"; -import Text from "@docspace/components/text"; -import { useRef, useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; import CategorySubList from "./CategorySubList"; import { OformCategoryType } from "@docspace/client/src/helpers/constants"; -import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; +import CategoryFilterDesktop from "./DesktopView"; +import CategoryFilterMobile from "./MobileView"; + +// + +import { isMobile, isSmallTablet } from "@docspace/components/utils/device"; +import { isMobileOnly } from "react-device-detect"; const CategoryFilter = ({ t, - currentCategory, - fetchCategoriesByBranch, fetchCategoriesByType, fetchPopularCategories, @@ -24,29 +24,8 @@ const CategoryFilter = ({ oformsFilter, filterOformsByCategory, }) => { - const dropdownRef = useRef(null); - - const [isOpen, setIsOpen] = useState(false); - const toggleDropdownIsOpen = () => setIsOpen(!isOpen); - const onCloseDropdown = () => setIsOpen(false); - - const [openedCategory, setOpenedCategory] = useState(null); - const isBranchCategoryOpen = openedCategory === OformCategoryType.Branch; - const isTypeCategoryOpen = openedCategory === OformCategoryType.Type; - const isCompilationCategoryOpen = - openedCategory === OformCategoryType.Compilation; - const onViewAllTemplates = () => filterOformsByCategory("", ""); - const onToggleBranchCategory = () => - setOpenedCategory(isBranchCategoryOpen ? null : OformCategoryType.Branch); - const onToggleTypeCategory = () => - setOpenedCategory(isTypeCategoryOpen ? null : OformCategoryType.Type); - const onToggleCompilationCategory = () => - setOpenedCategory( - isCompilationCategoryOpen ? null : OformCategoryType.Compilation - ); - const [formsByBranch, setFormsByBranch] = useState([]); const [formsByType, setFormsByType] = useState([]); const [formsByCompilation, setFormsByCompilation] = useState([]); @@ -62,81 +41,23 @@ const CategoryFilter = ({ })(); }, [oformsFilter.locale]); + if (isSmallTablet() || isMobile() || isMobileOnly) + return ( + + ); + return ( - -
- - {getOformCategoryTitle(oformsFilter.categorizeBy, currentCategory) || - t("FormGallery:Categories")} - - -
-
- - - - - - - - - - - - - - -
-
+ ); }; export default inject(({ oformsStore }) => ({ diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.styled.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.styled.js index c1332b5e18..8fe996d812 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.styled.js @@ -1,124 +1,62 @@ import { smallTablet } from "@docspace/components/utils/device"; -import styled from "styled-components"; +import styled, { css } from "styled-components"; import DropDown from "@docspace/components/drop-down"; import DropDownItem from "@docspace/components/drop-down-item"; +import ComboBox from "@docspace/components/combobox"; -export const CategoryFilter = styled.div` +export const CategoryFilterWrapper = styled.div` + position: relative; width: 220px; box-sizing: border-box; @media ${smallTablet} { width: 100%; } +`; + +export const CategoryFilter = styled(ComboBox)` + width: 100%; + box-sizing: border-box; .combobox { - cursor: pointer; width: 100%; - height: 32px; - box-sizing: border-box; - display: flex; - flex-direction: row; - justify-content: space-between; - padding: 5px 7px; - background: ${(props) => - props.theme.createEditRoomDialog.thirdpartyStorage.combobox.background}; - border-radius: 3px; - max-height: 32px; - - border: ${(props) => - `1px solid ${ - props.isOpen - ? props.theme.createEditRoomDialog.thirdpartyStorage.combobox - .isOpenDropdownBorderColor - : props.theme.createEditRoomDialog.thirdpartyStorage.combobox - .dropdownBorderColor - }`}; - - transition: all 0.2s ease; - &:hover { - border: ${(props) => - `1px solid ${ - props.isOpen - ? props.theme.createEditRoomDialog.thirdpartyStorage.combobox - .isOpenDropdownBorderColor - : props.theme.createEditRoomDialog.thirdpartyStorage.combobox - .hoverDropdownBorderColor - }`}; - } - - &-text { - font-weight: 400; - font-size: 13px; - line-height: 20px; - } - - &-expander { - display: flex; - align-items: center; - justify-content: center; - width: 6.35px; - svg { - transform: ${(props) => - props.isOpen ? "rotate(180deg)" : "rotate(0)"}; - width: 6.35px; - height: auto; - path { - fill: ${(props) => - props.theme.createEditRoomDialog.thirdpartyStorage.combobox - .arrowFill}; - } - } - } } - .dropdown-wrapper { - width: 100%; - box-sizing: border-box; - position: relative; + .combo-button-label { + font-weight: 400; + font-size: 13px; + line-height: 20px; + } - .dropdown-container { - width: 100%; - box-sizing: border-box; - margin-top: 4px; + .dropdown-container { + margin-top: 4px; + } +`; - .dropdown-item { - width: 100%; - height: 32px; - box-sizing: border-box; - font-size: 12px; - font-weight: 600; - line-height: 16px; - padding-top: 8px; - padding-bottom: 8px; +export const CategoryFilterItem = styled(DropDownItem)` + width: 100%; + height: 32px; + box-sizing: border-box; + font-size: 12px; + font-weight: 600; + line-height: 16px; + padding-top: 8px; + padding-bottom: 8px; - .submenu-arrow { - margin-right: 0; - svg { - height: 12px; - width: 12px; - } - } - } + .submenu-arrow { + margin-right: 0; - .mobile-sub-open { - .submenu-arrow { - transform: rotate(270deg); - } - } - - .item-by-categories:hover + .sub-by-categories { - visibility: visible; - } - - .item-by-types:hover + .sub-by-types { - visibility: visible; - } - - .item-by-compilations:hover + .sub-by-compilations { - visibility: visible; - } + svg { + height: 12px; + width: 12px; } + + ${({ isMobileOpen }) => + isMobileOpen && + css` + transform: rotate(270deg); + `} } `; @@ -132,6 +70,11 @@ export const StyledSubList = styled(DropDown)` &:hover { visibility: visible; } + ${({ isSubHovered }) => + isSubHovered && + css` + visibility: visible; + `}; &:before { content: ""; diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js index af9c79bb2c..6eca2f4228 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js @@ -18,8 +18,11 @@ const LanguageFilter = ({ oformsFilter, filterOformsByLocale }) => { const [isOpen, setIsOpen] = useState(false); const toggleDropdownIsOpen = () => setIsOpen(!isOpen); - const onFilterByLocale = (newLocale) => { - filterOformsByLocale(newLocale); + const onFilterByLocale = async (newLocale) => { + await filterOformsByLocale(newLocale); + + const [sectionScroll] = document.getElementsByClassName("section-scroll"); + sectionScroll.scrollTop = 0; }; return ( diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index 4aa5b7a42b..a72695887b 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -113,7 +113,7 @@ class OformsStore { }); }; - filterOformsByLocale = (locale) => { + filterOformsByLocale = async (locale) => { if (!locale) return; this.oformsFilter.page = 1; diff --git a/packages/components/combobox/index.js b/packages/components/combobox/index.js index d261edfd10..1f5cd8eda0 100644 --- a/packages/components/combobox/index.js +++ b/packages/components/combobox/index.js @@ -12,6 +12,7 @@ class ComboBox extends React.Component { constructor(props) { super(props); + console.log(props.advancedOptions); this.ref = React.createRef(); this.state = { diff --git a/packages/components/drop-down/index.js b/packages/components/drop-down/index.js index ecd4ebab2d..cbcd485b6e 100644 --- a/packages/components/drop-down/index.js +++ b/packages/components/drop-down/index.js @@ -319,7 +319,7 @@ class DropDown extends React.PureComponent { // Need to avoid conflict between inline styles from checkPositionPortal and styled-component styles const directionXStylesDisabled = this.props.isDefaultMode && - this.props.forwardedRef.current && + this.props.forwardedRef?.current && !this.props.fixedDirection; let cleanChildren = children; @@ -341,6 +341,10 @@ class DropDown extends React.PureComponent { ? { height: calculatedHeight + "px" } : {}; + console.log(cleanChildren, React.Children); + console.log(rowHeights); + console.log(calculatedHeight); + return ( Date: Thu, 14 Sep 2023 12:48:43 +0300 Subject: [PATCH 023/334] fix page freeze on dropdown render --- packages/components/drop-down/index.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/components/drop-down/index.js b/packages/components/drop-down/index.js index cbcd485b6e..6ca8056b46 100644 --- a/packages/components/drop-down/index.js +++ b/packages/components/drop-down/index.js @@ -341,10 +341,6 @@ class DropDown extends React.PureComponent { ? { height: calculatedHeight + "px" } : {}; - console.log(cleanChildren, React.Children); - console.log(rowHeights); - console.log(calculatedHeight); - return ( Date: Thu, 14 Sep 2023 12:48:57 +0300 Subject: [PATCH 024/334] fix page freeze on dropdown render 2 --- .../CategoryFilter/DesktopView/SubList.js | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js new file mode 100644 index 0000000000..27d9bc9d99 --- /dev/null +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js @@ -0,0 +1,61 @@ +import * as Styled from "./index.styled"; +import { inject } from "mobx-react"; +import { withTranslation } from "react-i18next"; +import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; + +const SubList = ({ + categoryType, + categories, + + isSubHovered, + marginTop, + + filterOformsByCategory, + setOformsCurrentCategory, +}) => { + const onFilterByCategory = (category) => { + setOformsCurrentCategory(category); + filterOformsByCategory(categoryType, category.id); + }; + + return ( + {}} + maxHeight={296} + manualWidth={"100%"} + showDisabledItems={false} + isDefaultMode={false} + withBackdrop={false} + withBackground={false} + isMobileView={false} + isNoFixedHeightOptions={false} + > + {categories.map((category) => ( + onFilterByCategory(category)} + /> + ))} + + ); +}; + +export default inject(({ oformsStore }) => ({ + getOforms: oformsStore.getOforms, + oformsFilter: oformsStore.oformsFilter, + filterOformsByCategory: oformsStore.filterOformsByCategory, + setOformsCurrentCategory: oformsStore.setOformsCurrentCategory, +}))(withTranslation(["FormGallery", "Common"])(SubList)); From 409ef5becd2372bc2e0dee9d359b1d78d91a53ca Mon Sep 17 00:00:00 2001 From: mushka-n Date: Thu, 14 Sep 2023 12:49:28 +0300 Subject: [PATCH 025/334] fix init render url parsing issues --- packages/client/src/pages/FormGallery/Filter/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/client/src/pages/FormGallery/Filter/index.js b/packages/client/src/pages/FormGallery/Filter/index.js index 4e6803cb0f..99d1e3e521 100644 --- a/packages/client/src/pages/FormGallery/Filter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/index.js @@ -68,6 +68,7 @@ const SectionFilterContent = ({ oformsFilter, setOformsFilter }) => { if (isInitLoading) return; navigate(`${location.pathname}?${oformsFilter.toUrlParams()}`); }, [ + oformsFilter, oformsFilter.categorizeBy, oformsFilter.categoryId, oformsFilter.locale, From 898cd3f00705cfed4d3f7635c407716cd40e77b2 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Thu, 14 Sep 2023 12:49:43 +0300 Subject: [PATCH 026/334] update on mobile accordion --- .../Filter/CategoryFilter/CategorySubList.js | 123 --------- .../DesktopView/CategorySubList.js | 60 ----- .../CategoryFilter/DesktopView/index.js | 15 +- .../DesktopView/index.styled.js | 39 ++- .../MobileView/CategorySubList.js | 17 +- .../Filter/CategoryFilter/MobileView/index.js | 248 ++++++++---------- .../CategoryFilter/MobileView/index.styled.js | 73 ++---- .../Filter/CategoryFilter/index.js | 23 +- .../Filter/CategoryFilter/index.styled.js | 91 ------- 9 files changed, 181 insertions(+), 508 deletions(-) delete mode 100644 packages/client/src/pages/FormGallery/Filter/CategoryFilter/CategorySubList.js delete mode 100644 packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/CategorySubList.js delete mode 100644 packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.styled.js diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/CategorySubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/CategorySubList.js deleted file mode 100644 index 3da0ab5fcd..0000000000 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/CategorySubList.js +++ /dev/null @@ -1,123 +0,0 @@ -import { useRef, memo } from "react"; -import DropDownItem from "@docspace/components/drop-down-item"; -import { isMobile, isSmallTablet } from "@docspace/components/utils/device"; -import { StyledSubList, StyledSubItemMobile } from "./index.styled"; -import { inject } from "mobx-react"; -import { withTranslation } from "react-i18next"; -import { OformCategoryType } from "@docspace/client/src/helpers/constants"; -import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; -import { isMobileOnly } from "react-device-detect"; -import VirtualList from "@docspace/components/drop-down/VirtualList"; - -const CategorySubList = ({ - theme, - - isOpen, - isSubHovered, - categoryType, - categories, - marginTop, - - filterOformsByCategory, - setOformsCurrentCategory, -}) => { - const dropdownRef = useRef(null); - - const onFilterByCategory = (category) => { - setOformsCurrentCategory(category); - filterOformsByCategory(categoryType, category.id); - }; - - if (isSmallTablet() || isMobile() || isMobileOnly) - if (isOpen) - return categories.map((category) => ( - onFilterByCategory(category)} - /> - )); - else return null; - - return ( - {}} - maxHeight={296} - manualWidth={"100%"} - showDisabledItems={false} - isDefaultMode={false} - withBackdrop={false} - withBackground={false} - isMobileView={false} - isNoFixedHeightOptions={false} - > - {categories.map((category) => ( - onFilterByCategory(category)} - /> - ))} - - ); - - // return ( - // {}} - // withBackdrop={false} - // marginTop={marginTop} - // > - // {categories.map((category) => ( - // onFilterByCategory(category)} - // /> - // ))} - // - // ); -}; - -const Row = memo(({ data, index, style }) => { - const { children, theme, activedescendant, handleMouseMove } = data; - const option = children[index]; - const newStyle = { ...style, ...separator }; - return ( - handleMouseMove(index)} - isActiveDescendant={activedescendant === index} - {...option?.props} - /> - ); -}); - -export default inject(({ auth, oformsStore }) => ({ - theme: auth.settingsStore.theme, - - getOforms: oformsStore.getOforms, - oformsFilter: oformsStore.oformsFilter, - filterOformsByCategory: oformsStore.filterOformsByCategory, - setOformsCurrentCategory: oformsStore.setOformsCurrentCategory, -}))(withTranslation(["FormGallery", "Common"])(CategorySubList)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/CategorySubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/CategorySubList.js deleted file mode 100644 index 9dd70f3e1f..0000000000 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/CategorySubList.js +++ /dev/null @@ -1,60 +0,0 @@ -import DropDownItem from "@docspace/components/drop-down-item"; -import { StyledSubList } from "./index.styled"; -import { inject } from "mobx-react"; -import { withTranslation } from "react-i18next"; -import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; - -const CategorySubList = ({ - categoryType, - categories, - - isSubHovered, - marginTop, - - filterOformsByCategory, - setOformsCurrentCategory, -}) => { - const onFilterByCategory = (category) => { - setOformsCurrentCategory(category); - filterOformsByCategory(categoryType, category.id); - }; - - return ( - {}} - maxHeight={296} - manualWidth={"100%"} - showDisabledItems={false} - isDefaultMode={false} - withBackdrop={false} - withBackground={false} - isMobileView={false} - isNoFixedHeightOptions={false} - > - {categories.map((category) => ( - onFilterByCategory(category)} - /> - ))} - - ); -}; - -export default inject(({ oformsStore }) => ({ - getOforms: oformsStore.getOforms, - oformsFilter: oformsStore.oformsFilter, - filterOformsByCategory: oformsStore.filterOformsByCategory, - setOformsCurrentCategory: oformsStore.setOformsCurrentCategory, -}))(withTranslation(["FormGallery", "Common"])(CategorySubList)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js index 7463630117..5ec0415b1b 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js @@ -4,12 +4,14 @@ import DropDownItem from "@docspace/components/drop-down-item"; import { useState } from "react"; import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; -import CategorySubList from "./CategorySubList"; +import SubList from "./SubList"; import { OformCategoryType } from "@docspace/client/src/helpers/constants"; const CategoryFilterDesktop = ({ t, + currentCategoryTitle, + onViewAllTemplates, formsByBranch, formsByType, @@ -36,7 +38,6 @@ const CategoryFilterDesktop = ({ id="comboBoxLanguage" tabIndex={1} className={"combobox"} - selectedOption={{ label: t("FormGallery:ViewAllTemplates") }} onSelect={() => {}} isDisabled={false} manualWidth={"100%"} @@ -51,6 +52,9 @@ const CategoryFilterDesktop = ({ isDefaultMode={false} fixedDirection={true} advancedOptionsCount={5} + selectedOption={{ + label: currentCategoryTitle || t("FormGallery:Categories"), + }} advancedOptions={ <> - - - - marginTop}; left: calc(100% + 4px); + max-height: 296px; + visibility: hidden; &:hover { visibility: visible; @@ -70,6 +73,18 @@ export const StyledSubList = styled(DropDown)` } `; -export const StyledSubItemMobile = styled(DropDownItem)` - margin-left: 16px; +export const CategoryFilterSubListItem = styled(DropDownItem)` + width: 208px; + height: 36px; + + box-sizing: border-box; + padding: 8px 16px; + + font-size: 13px; + font-weight: 600; + line-height: 20px; + + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; `; diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js index 3edd6d6e43..e64b85c430 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js @@ -15,15 +15,14 @@ const CategorySubList = ({ filterOformsByCategory(categoryType, category.id); }; - if (isOpen) - return categories.map((category) => ( - onFilterByCategory(category)} - /> - )); + return categories.map((category) => ( + onFilterByCategory(category)} + /> + )); }; export default inject(({ auth, oformsStore }) => ({ diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js index 883605daf2..613b73f732 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js @@ -8,6 +8,8 @@ import CategorySubList from "./CategorySubList"; import { OformCategoryType } from "@docspace/client/src/helpers/constants"; import Scrollbar from "@docspace/components/scrollbar"; import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; +import ComboBox from "@docspace/components/combobox"; +import ComboButton from "@docspace/components/combobox/sub-components/combo-button"; const CategoryFilterMobile = ({ t, @@ -17,6 +19,10 @@ const CategoryFilterMobile = ({ formsByType, formsByCompilation, }) => { + const [isOpen, setIsOpen] = useState(false); + const toggleDropdownIsOpen = () => setIsOpen(!isOpen); + const onCloseDropdown = () => setIsOpen(false); + const dropdownRef = useRef(); const [openedCategory, setOpenedCategory] = useState(null); @@ -31,149 +37,113 @@ const CategoryFilterMobile = ({ const onToggleCompilationCategory = () => setOpenedCategory(isCompilationOpen ? null : OformCategoryType.Compilation); + const maxCalculatedHeight = window.innerHeight - 240; + let calculatedHeight = + 36 + + 8.2 + + 36 * 3 + + 36 * + (isBranchOpen + ? formsByBranch.length + : isTypeOpen + ? formsByType.length + : isCompilationOpen + ? formsByCompilation.length + : 0); + if (calculatedHeight > maxCalculatedHeight) + calculatedHeight = maxCalculatedHeight; + return ( - - + + + - - - - {isBranchOpen && ( - + - )} - - - - + + + + + {isBranchOpen && ( + + )} + + + {isTypeOpen && ( + + )} + + + {isCompilationOpen && ( + + )} + + + ); - - // // general interactions - - // const [isOpen, setIsOpen] = useState(false); - // const toggleDropdownIsOpen = () => setIsOpen(!isOpen); - // const onCloseDropdown = () => setIsOpen(false); - - // // mobile interactions - - // const [openedCategory, setOpenedCategory] = useState(null); - // const isBranchOpen = openedCategory === OformCategoryType.Branch; - // const isTypeOpen = openedCategory === OformCategoryType.Type; - // const isCompilationOpen = openedCategory === OformCategoryType.Compilation; - - // const onToggleBranchCategory = () => - // setOpenedCategory(isBranchOpen ? null : OformCategoryType.Branch); - // const onToggleTypeCategory = () => - // setOpenedCategory(isTypeOpen ? null : OformCategoryType.Type); - // const onToggleCompilationCategory = () => - // setOpenedCategory(isCompilationOpen ? null : OformCategoryType.Compilation); - - // return ( - // - // {}} - // isDisabled={false} - // manualWidth={"100%"} - // showDisabledItems={true} - // options={[]} - // directionX={"right"} - // directionY={"both"} - // scaled={true} - // size={"content"} - // disableIconClick={false} - // disableItemClick={false} - // isDefaultMode={false} - // fixedDirection={true} - // advancedOptionsCount={5} - // advancedOptions={ - // <> - // - // - // - // - // - // - // } - // /> - // - // ); }; export default inject(({ oformsStore }) => ({ diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.styled.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.styled.js index 4545e1ffad..b2b922e24f 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.styled.js @@ -1,26 +1,26 @@ -import { smallTablet, mobile } from "@docspace/components/utils/device"; import styled, { css } from "styled-components"; import DropDown from "@docspace/components/drop-down"; import DropDownItem from "@docspace/components/drop-down-item"; -import ComboBox from "@docspace/components/combobox"; -import { isMobileOnly } from "react-device-detect"; +export const CategoryFilterMobileWrapper = styled.div` + width: 100%; + position: relative; +`; export const CategoryFilterMobile = styled(DropDown)` - position: relative; + position: absolute; + top: 36px; + left: 0; width: 100%; - /* bottom: ${(props) => props.theme.mainButtonMobile.dropDown.bottom}; - z-index: ${(props) => props.theme.mainButtonMobile.dropDown.zIndex}; */ - height: calc(100vw - 128px); + padding: 6px 0; + height: ${({ forcedHeight }) => forcedHeight}; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - padding: 0px; - .section-scroll, .scroll-body { ${({ theme }) => @@ -28,58 +28,17 @@ export const CategoryFilterMobile = styled(DropDown)` ? `padding-left: 0px !important;` : `padding-right: 0px !important;`} } - - .separator-wrapper { - padding: 12px 24px; - } - - /* .is-separator { - height: 1px !important; - width: calc(100% - 48px); - padding: 0 !important; - margin: 12px 24px !important; - background-color: ${(props) => - props.theme.mainButtonMobile.dropDown.separatorBackground}; - } */ - - /* .drop-down-item-button { - color: ${(props) => props.theme.mainButtonMobile.dropDown.buttonColor}; - - svg { - path[fill] { - fill: ${(props) => props.theme.mainButtonMobile.dropDown.buttonColor}; - } - - path[stroke] { - stroke: ${(props) => props.theme.mainButtonMobile.dropDown.buttonColor}; - } - } - - &:hover { - background-color: ${(props) => - isMobileOnly - ? props.theme.mainButtonMobile.buttonOptions.backgroundColor - : props.theme.mainButtonMobile.dropDown.hoverButtonColor}; - } - } */ - - /* .action-mobile-button { - width: 100%; - background-color: ${(props) => - props.theme.mainButtonMobile.dropDown.backgroundActionMobile}; - border-radius: 3px; - font-size: 13px; - display: block; - } */ `; -export const CategoryFilterItem = styled(DropDownItem)` +export const CategoryFilterItemMobile = styled(DropDownItem)` width: 100%; - height: 32px; + height: 36px; box-sizing: border-box; - font-size: 12px; + + font-size: 13px; font-weight: 600; - line-height: 16px; + line-height: 20px; + padding-top: 8px; padding-bottom: 8px; @@ -100,5 +59,5 @@ export const CategoryFilterItem = styled(DropDownItem)` `; export const StyledSubItemMobile = styled(DropDownItem)` - margin-left: 16px; + padding-left: 28px; `; diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js index 4d766fb8c1..0c262ce5bd 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js @@ -1,29 +1,28 @@ -import * as Styled from "./index.styled"; - -import DropDownItem from "@docspace/components/drop-down-item"; import { useState, useEffect } from "react"; import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; -import CategorySubList from "./CategorySubList"; -import { OformCategoryType } from "@docspace/client/src/helpers/constants"; import CategoryFilterDesktop from "./DesktopView"; import CategoryFilterMobile from "./MobileView"; - -// - +import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; import { isMobile, isSmallTablet } from "@docspace/components/utils/device"; import { isMobileOnly } from "react-device-detect"; const CategoryFilter = ({ t, + currentCategory, + oformsFilter, + filterOformsByCategory, + fetchCategoriesByBranch, fetchCategoriesByType, fetchPopularCategories, - - oformsFilter, - filterOformsByCategory, }) => { + const currentCategoryTitle = getOformCategoryTitle( + oformsFilter.categorizeBy, + currentCategory + ); + const onViewAllTemplates = () => filterOformsByCategory("", ""); const [formsByBranch, setFormsByBranch] = useState([]); @@ -44,6 +43,7 @@ const CategoryFilter = ({ if (isSmallTablet() || isMobile() || isMobileOnly) return ( - isMobileOpen && - css` - transform: rotate(270deg); - `} - } -`; - -export const StyledSubList = styled(DropDown)` - position: absolute; - top: 0; - margin-top: ${({ marginTop }) => marginTop}; - left: calc(100% + 4px); - - visibility: hidden; - &:hover { - visibility: visible; - } - ${({ isSubHovered }) => - isSubHovered && - css` - visibility: visible; - `}; - - &:before { - content: ""; - position: absolute; - left: -4px; - top: 0; - width: 4px; - height: 100%; - } -`; - -export const StyledSubItemMobile = styled(DropDownItem)` - margin-left: 16px; -`; From df4ad30a4c7a914c1f6e68bf3b4d633ac60fa31a Mon Sep 17 00:00:00 2001 From: mushka-n Date: Thu, 14 Sep 2023 13:02:54 +0300 Subject: [PATCH 027/334] fix dropdown autclose onClick --- .../CategoryFilter/DesktopView/SubList.js | 10 ++++++++-- .../CategoryFilter/DesktopView/index.js | 17 ++++++++++++++--- .../DesktopView/index.styled.js | 19 ++++++++++++------- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js index 27d9bc9d99..af040a1ced 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js @@ -7,19 +7,24 @@ const SubList = ({ categoryType, categories, + isDropdownOpen, isSubHovered, marginTop, + onCloseDropdown, filterOformsByCategory, setOformsCurrentCategory, }) => { - const onFilterByCategory = (category) => { + const onFilterByCategory = (e, category) => { + e.preventDefault(); + onCloseDropdown(); setOformsCurrentCategory(category); filterOformsByCategory(categoryType, category.id); }; return ( onFilterByCategory(category)} + onClick={(e) => onFilterByCategory(e, category)} + onMouseDown={(e) => e.preventDefault()} /> ))} diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js index 5ec0415b1b..1da45ec319 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js @@ -18,8 +18,11 @@ const CategoryFilterDesktop = ({ formsByCompilation, }) => { const [isOpen, setIsOpen] = useState(false); - const toggleDropdownIsOpen = () => setIsOpen(!isOpen); - const onCloseDropdown = () => setIsOpen(false); + const onToggleDropdownIsOpen = () => setIsOpen(!isOpen); + const onCloseDropdown = () => { + console.log("close"); + setIsOpen(false); + }; const [isBranchHovered, setIsBranchHovered] = useState(false); const [isTypeHovered, setIsTypeHovered] = useState(false); @@ -38,7 +41,9 @@ const CategoryFilterDesktop = ({ id="comboBoxLanguage" tabIndex={1} className={"combobox"} - onSelect={() => {}} + opened={isOpen} + onClick={onToggleDropdownIsOpen} + onSelect={onCloseDropdown} isDisabled={false} manualWidth={"100%"} showDisabledItems={true} @@ -99,20 +104,26 @@ const CategoryFilterDesktop = ({ ); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js index f39339070a..604754488c 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js @@ -54,14 +54,19 @@ export const CategoryFilterSubList = styled(DropDown)` max-height: 296px; visibility: hidden; - &:hover { - visibility: visible; - } - ${({ isSubHovered }) => - isSubHovered && + + visibility: hidden; + ${({ isDropdownOpen, isSubHovered }) => + isDropdownOpen && css` - visibility: visible; - `}; + &:hover { + visibility: visible; + } + ${isSubHovered && + css` + visibility: visible; + `} + `} &:before { content: ""; From 00f4fad073270a196e82fb5053b84982dd7bd3f1 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Thu, 14 Sep 2023 13:22:38 +0300 Subject: [PATCH 028/334] update on mobile dropdown height calculation --- .../Filter/CategoryFilter/MobileView/index.js | 19 ++++++++++++++----- packages/components/drop-down/index.js | 2 +- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js index 613b73f732..bc061aba86 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js @@ -19,12 +19,13 @@ const CategoryFilterMobile = ({ formsByType, formsByCompilation, }) => { + const wrapperRef = useRef(); + const scrollRef = useRef(); + const [isOpen, setIsOpen] = useState(false); const toggleDropdownIsOpen = () => setIsOpen(!isOpen); const onCloseDropdown = () => setIsOpen(false); - const dropdownRef = useRef(); - const [openedCategory, setOpenedCategory] = useState(null); const isBranchOpen = openedCategory === OformCategoryType.Branch; const isTypeOpen = openedCategory === OformCategoryType.Type; @@ -37,7 +38,15 @@ const CategoryFilterMobile = ({ const onToggleCompilationCategory = () => setOpenedCategory(isCompilationOpen ? null : OformCategoryType.Compilation); - const maxCalculatedHeight = window.innerHeight - 240; + const wrapperOffsetTop = wrapperRef?.current?.offsetTop; + const maxCalculatedHeight = window.innerHeight - wrapperOffsetTop - 64; + console.log(wrapperOffsetTop); + console.log( + window.innerHeight, + wrapperOffsetTop, + maxCalculatedHeight, + maxCalculatedHeight + wrapperOffsetTop + ); let calculatedHeight = 36 + 8.2 + @@ -54,7 +63,7 @@ const CategoryFilterMobile = ({ calculatedHeight = maxCalculatedHeight; return ( - + Date: Thu, 14 Sep 2023 13:36:32 +0300 Subject: [PATCH 029/334] optimized dropdown with media queries --- .../CategoryFilter/DesktopView/index.js | 4 +- .../Filter/CategoryFilter/MobileView/index.js | 4 +- .../Filter/CategoryFilter/index.js | 58 ++++++++++++++----- 3 files changed, 51 insertions(+), 15 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js index 1da45ec319..e36db30085 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js @@ -16,6 +16,8 @@ const CategoryFilterDesktop = ({ formsByBranch, formsByType, formsByCompilation, + + ...rest }) => { const [isOpen, setIsOpen] = useState(false); const onToggleDropdownIsOpen = () => setIsOpen(!isOpen); @@ -36,7 +38,7 @@ const CategoryFilterDesktop = ({ const onMouseLeaveCompilation = () => setIsCompilationHovered(false); return ( - + { const wrapperRef = useRef(); const scrollRef = useRef(); @@ -63,7 +65,7 @@ const CategoryFilterMobile = ({ calculatedHeight = maxCalculatedHeight; return ( - + - ); - - return ( - + + ); }; export default inject(({ oformsStore }) => ({ From 760e586a955dc57c2a8b31810083519c70badcd2 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Thu, 14 Sep 2023 22:37:18 +0300 Subject: [PATCH 030/334] fix categoryFilter truncation --- .../CategoryFilter/DesktopView/SubList.js | 48 ++++++++++++------- .../CategoryFilter/DesktopView/index.js | 1 - .../DesktopView/index.styled.js | 9 ++-- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js index af040a1ced..a576e21ef6 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js @@ -15,8 +15,9 @@ const SubList = ({ filterOformsByCategory, setOformsCurrentCategory, }) => { - const onFilterByCategory = (e, category) => { - e.preventDefault(); + const onPreventDefault = (e) => e.preventDefault(); + + const onFilterByCategory = (category) => { onCloseDropdown(); setOformsCurrentCategory(category); filterOformsByCategory(categoryType, category.id); @@ -24,7 +25,7 @@ const SubList = ({ return ( {}} maxHeight={296} - manualWidth={"100%"} + manualWidth={"206px"} showDisabledItems={false} isDefaultMode={false} withBackdrop={false} @@ -44,17 +44,33 @@ const SubList = ({ isMobileView={false} isNoFixedHeightOptions={false} > - {categories.map((category) => ( - onFilterByCategory(e, category)} - onMouseDown={(e) => e.preventDefault()} - /> - ))} + {categories.map((category) => { + const categoryTitle = getOformCategoryTitle(categoryType, category); + const onCategoryClick = () => onFilterByCategory(category); + return ( + +
+ {categoryTitle} +
+
+ ); + })}
); }; diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js index e36db30085..2ca5b87e1a 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js @@ -47,7 +47,6 @@ const CategoryFilterDesktop = ({ onClick={onToggleDropdownIsOpen} onSelect={onCloseDropdown} isDisabled={false} - manualWidth={"100%"} showDisabledItems={true} options={[]} directionX={"right"} diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js index 604754488c..42d638fc57 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js @@ -52,12 +52,13 @@ export const CategoryFilterSubList = styled(DropDown)` left: calc(100% + 4px); max-height: 296px; + max-width: auto; visibility: hidden; visibility: hidden; - ${({ isDropdownOpen, isSubHovered }) => - isDropdownOpen && + ${({ open, isSubHovered }) => + open && css` &:hover { visibility: visible; @@ -88,8 +89,4 @@ export const CategoryFilterSubListItem = styled(DropDownItem)` font-size: 13px; font-weight: 600; line-height: 20px; - - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; `; From 97e070ec1f05d9d41e2ad434bdccf56a303f76ad Mon Sep 17 00:00:00 2001 From: mushka-n Date: Thu, 14 Sep 2023 22:37:25 +0300 Subject: [PATCH 031/334] search filter bugfix --- .../src/pages/FormGallery/Filter/SearchFilter/index.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js b/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js index 8c83873e13..b3a44450a0 100644 --- a/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/SearchFilter/index.js @@ -6,12 +6,11 @@ import * as Styled from "./index.styled"; const SearchFilter = ({ t, oformsFilter, filterOformsBySearch }) => { const [value, setValue] = useState(oformsFilter.search); - const onSearch = (val) => filterOformsBySearch(val); - const onClear = () => onChangeValue(""); const onChangeValue = (val) => { setValue(val); - onSearch(val); + filterOformsBySearch(val); }; + const onClear = () => onChangeValue(""); useEffect(() => { if (value !== oformsFilter.search) setValue(oformsFilter.search); From 00dd93094b2c2c11a8d1312b8d994b30ec0ac820 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Tue, 19 Sep 2023 12:43:41 +0300 Subject: [PATCH 032/334] styling updates --- .../CategoryFilter/DesktopView/index.styled.js | 1 + .../FormGallery/Filter/LanguageFilter/index.js | 18 ++++++++++++------ .../Filter/LanguageFilter/index.styled.js | 6 ++---- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js index 42d638fc57..b4881a9767 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js @@ -50,6 +50,7 @@ export const CategoryFilterSubList = styled(DropDown)` top: 0; margin-top: ${({ marginTop }) => marginTop}; left: calc(100% + 4px); + padding: 4px 0; max-height: 296px; max-width: auto; diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js index 6eca2f4228..66ba348305 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js @@ -1,18 +1,20 @@ import * as Styled from "./index.styled"; import DropDown from "@docspace/components/drop-down"; -import DropDownItem from "@docspace/components/drop-down-item"; import ExpanderDownReactSvgUrl from "PUBLIC_DIR/images/expander-down.react.svg?url"; import { ReactSVG } from "react-svg"; import { useRef, useState } from "react"; import { inject } from "mobx-react"; -import { withTranslation } from "react-i18next"; import { flagsIcons } from "@docspace/common/utils/image-helpers"; import { convertToCulture } from "@docspace/common/utils"; const avialableLocales = ["en", "zh", "it", "fr", "es", "de", "ja"]; -const LanguageFilter = ({ oformsFilter, filterOformsByLocale }) => { +const LanguageFilter = ({ + oformsFilter, + filterOformsByLocale, + currentColorScheme, +}) => { const dropdownRef = useRef(null); const [isOpen, setIsOpen] = useState(false); @@ -26,7 +28,10 @@ const LanguageFilter = ({ oformsFilter, filterOformsByLocale }) => { }; return ( - +
{ ); }; -export default inject(({ oformsStore }) => ({ +export default inject(({ auth, oformsStore }) => ({ oformsFilter: oformsStore.oformsFilter, filterOformsByLocale: oformsStore.filterOformsByLocale, -}))(withTranslation(["FormGallery", "Common"])(LanguageFilter)); + currentColorScheme: auth.settingsStore.currentColorScheme, +}))(LanguageFilter); diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js index d4a0a59325..b74535948c 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js @@ -16,16 +16,14 @@ export const LanguageFilter = styled.div` justify-content: space-between; gap: 4px; padding: 8px; - background: ${(props) => - props.theme.createEditRoomDialog.thirdpartyStorage.combobox.background}; + background: transparent; border-radius: 3px; max-height: 32px; border: ${(props) => `1px solid ${ props.isOpen - ? props.theme.createEditRoomDialog.thirdpartyStorage.combobox - .isOpenDropdownBorderColor + ? props.currentColorScheme.main.accent : props.theme.createEditRoomDialog.thirdpartyStorage.combobox .dropdownBorderColor }`}; From b8ca2852e290bc57c9f8cda016654c102f03c4ff Mon Sep 17 00:00:00 2001 From: mushka-n Date: Tue, 19 Sep 2023 12:51:36 +0300 Subject: [PATCH 033/334] deleted unused logs --- packages/common/api/oformClient.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/packages/common/api/oformClient.js b/packages/common/api/oformClient.js index 4bff1abbbb..133d4a980e 100644 --- a/packages/common/api/oformClient.js +++ b/packages/common/api/oformClient.js @@ -2,14 +2,6 @@ import AxiosOformClient from "../utils/axiosOformClient"; const oformClient = new AxiosOformClient(); -// export const initSSR = (headers) => { -// oformClient.initSSR(headers); -// }; - export const request = (options) => { return oformClient.request(options); }; - -// export const setWithCredentialsStatus = (state) => { -// return oformClient.setWithCredentialsStatus(state); -// }; From 85423bd1dd17bb18c3eb0944a33281051e2b3f18 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Tue, 19 Sep 2023 13:56:34 +0300 Subject: [PATCH 034/334] code cleanup --- .../Filter/CategoryFilter/DesktopView/index.js | 5 +---- .../Filter/CategoryFilter/MobileView/index.js | 11 +---------- .../pages/FormGallery/Filter/CategoryFilter/index.js | 10 ++++++++-- packages/common/api/oforms/filter.js | 2 -- packages/common/api/oforms/index.js | 5 ----- packages/common/store/AuthStore.js | 1 - packages/components/combobox/index.js | 1 - packages/components/search-input/index.js | 1 - 8 files changed, 10 insertions(+), 26 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js index 2ca5b87e1a..c94c42131c 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js @@ -21,10 +21,7 @@ const CategoryFilterDesktop = ({ }) => { const [isOpen, setIsOpen] = useState(false); const onToggleDropdownIsOpen = () => setIsOpen(!isOpen); - const onCloseDropdown = () => { - console.log("close"); - setIsOpen(false); - }; + const onCloseDropdown = () => setIsOpen(false); const [isBranchHovered, setIsBranchHovered] = useState(false); const [isTypeHovered, setIsTypeHovered] = useState(false); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js index d1159e588b..02e4696bc5 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js @@ -42,17 +42,8 @@ const CategoryFilterMobile = ({ const wrapperOffsetTop = wrapperRef?.current?.offsetTop; const maxCalculatedHeight = window.innerHeight - wrapperOffsetTop - 64; - console.log(wrapperOffsetTop); - console.log( - window.innerHeight, - wrapperOffsetTop, - maxCalculatedHeight, - maxCalculatedHeight + wrapperOffsetTop - ); let calculatedHeight = - 36 + - 8.2 + - 36 * 3 + + 152.2 + 36 * (isBranchOpen ? formsByBranch.length diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js index 604bd19385..a815ed6c7c 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js @@ -76,7 +76,10 @@ const CategoryFilter = ({ { - console.log(`/${categorizeBy}/${id}`); const options = { method: "get", url: `/${categorizeBy}/${id}` }; return request(options).then((res) => { - console.log(res); return res; }); }; @@ -12,7 +10,6 @@ export const getCategoryById = async (categorizeBy, id) => { export const getCategoriesByBranch = async (locale = "en") => { const options = { method: "get", url: `/categories?locale=${locale}` }; return request(options).then((res) => { - console.log(res); return res; }); }; @@ -20,7 +17,6 @@ export const getCategoriesByBranch = async (locale = "en") => { export const getCategoriesByType = async (locale = "en") => { const options = { method: "get", url: `/types?locale=${locale}` }; return request(options).then((res) => { - console.log(res); return res; }); }; @@ -28,7 +24,6 @@ export const getCategoriesByType = async (locale = "en") => { export const getPopularCategories = async (locale = "en") => { const options = { method: "get", url: `/compilations?locale=${locale}` }; return request(options).then((res) => { - console.log(res); return res; }); }; diff --git a/packages/common/store/AuthStore.js b/packages/common/store/AuthStore.js index 2cd373b366..bf4a0e794d 100644 --- a/packages/common/store/AuthStore.js +++ b/packages/common/store/AuthStore.js @@ -438,7 +438,6 @@ class AuthStore { const promise = new Promise(async (resolve, reject) => { const apiUrl = `${this.settingsStore.urlOforms}${params}`; let oforms = await api.settings.getOforms(apiUrl); - console.log(oforms); resolve(oforms); }); diff --git a/packages/components/combobox/index.js b/packages/components/combobox/index.js index f99e8a0ab1..b7b8d682fc 100644 --- a/packages/components/combobox/index.js +++ b/packages/components/combobox/index.js @@ -12,7 +12,6 @@ class ComboBox extends React.Component { constructor(props) { super(props); - console.log(props.advancedOptions); this.ref = React.createRef(); this.state = { diff --git a/packages/components/search-input/index.js b/packages/components/search-input/index.js index 78ae82bcce..d8c2b10b14 100644 --- a/packages/components/search-input/index.js +++ b/packages/components/search-input/index.js @@ -11,7 +11,6 @@ class SearchInput extends React.Component { super(props); this.forwardedRef = props.forwardedRef || React.createRef(); - console.log(this.input); this.timerId = null; this.state = { From 6cbb1cce34b5400eea7db6f6b80b0d69794317bb Mon Sep 17 00:00:00 2001 From: mushka-n Date: Fri, 22 Sep 2023 18:38:37 +0300 Subject: [PATCH 035/334] implemented new localization structure + after-merge fixes --- packages/client/src/helpers/utils.js | 29 +++++-- .../CategoryFilter/DesktopView/SubList.js | 5 +- .../CategoryFilter/DesktopView/index.js | 19 ++++- .../DesktopView/index.styled.js | 9 ++- .../MobileView/CategorySubList.js | 5 +- .../Filter/CategoryFilter/index.js | 23 +++--- .../client/src/pages/FormGallery/Header.js | 44 ++++++----- .../src/pages/FormGallery/StyledGallery.js | 35 +++++++-- .../TilesView/sub-components/Tile.js | 2 +- .../Home/InfoPanel/Body/styles/common.js | 8 ++ .../Home/InfoPanel/Body/styles/gallery.js | 13 +++- .../ItemTitle/GalleryItemTitle.js | 1 + .../ItemTitle/ItemContextOptions.js | 18 ++--- .../InfoPanel/Body/views/Gallery/index.js | 13 ++-- .../client/src/store/ContextOptionsStore.js | 2 +- packages/client/src/store/OformsStore.js | 76 +++++++------------ packages/common/api/oformClient.js | 7 -- packages/common/api/oforms/index.js | 37 ++++----- packages/common/store/AuthStore.js | 11 +-- packages/common/utils/axiosOformClient.js | 30 -------- public/scripts/config.json | 5 -- 21 files changed, 203 insertions(+), 189 deletions(-) delete mode 100644 packages/common/api/oformClient.js delete mode 100644 packages/common/utils/axiosOformClient.js diff --git a/packages/client/src/helpers/utils.js b/packages/client/src/helpers/utils.js index 1cca55d61a..3a823c30ef 100644 --- a/packages/client/src/helpers/utils.js +++ b/packages/client/src/helpers/utils.js @@ -225,11 +225,26 @@ export const filterUserRoleOptions = ( return newOptions; }; -export const getOformCategoryTitle = (categorizeBy, category) => { - if (!categorizeBy || !category) return; - return categorizeBy === OformCategoryType.Branch - ? category.attributes.categorie - : categorizeBy === OformCategoryType.Type - ? category.attributes.type - : category.attributes.compilation; +export const getLocalizedOformCategoryTitle = (category, locale = null) => { + if (!category) return ""; +}; + +export const getOformCategoryTitle = (category, locale = null) => { + if (!category) return ""; + + let categoryType = category.attributes.categorie + ? "categorie" + : category.attributes.type + ? "type" + : "compilation"; + + const categoryTitle = category.attributes[categoryType]; + if (!locale) return categoryTitle; + + const [localizedCategory] = category.attributes.localizations?.data.filter( + (localization) => localization.attributes.locale === locale + ); + return localizedCategory + ? localizedCategory.attributes[categoryType] + : categoryTitle; }; diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js index a576e21ef6..0837d1b87f 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js @@ -2,6 +2,9 @@ import * as Styled from "./index.styled"; import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; +import { getDefaultOformLocale } from "@docspace/common/utils"; + +const categoryLocale = getDefaultOformLocale(); const SubList = ({ categoryType, @@ -45,7 +48,7 @@ const SubList = ({ isNoFixedHeightOptions={false} > {categories.map((category) => { - const categoryTitle = getOformCategoryTitle(categoryType, category); + const categoryTitle = getOformCategoryTitle(category, categoryLocale); const onCategoryClick = () => onFilterByCategory(category); return ( { + // const [menuItems, setMenuItems] = useState([]); + const [isOpen, setIsOpen] = useState(false); const onToggleDropdownIsOpen = () => setIsOpen(!isOpen); const onCloseDropdown = () => setIsOpen(false); @@ -34,6 +38,13 @@ const CategoryFilterDesktop = ({ const onMouseEnterCompilation = () => setIsCompilationHovered(true); const onMouseLeaveCompilation = () => setIsCompilationHovered(false); + // useEffect(() => { + // (async () => { + // const fetchedMenuItems = await fetchCategoryFilterMenuItems(); + // setMenuItems(fetchedMenuItems); + // })(); + // }, []); + return ( ({ + fetchCategoryFilterMenuItems: oformsStore.fetchCategoryFilterMenuItems, + currentCategory: oformsStore.currentCategory, fetchCategoriesByBranch: oformsStore.fetchCategoriesByBranch, diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js index b4881a9767..4ca62a507b 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js @@ -36,6 +36,13 @@ export const CategoryFilterItem = styled(DropDownItem)` font-weight: 600; line-height: 16px; + span { + width: 160px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + .submenu-arrow { margin-right: 0; svg { @@ -55,8 +62,6 @@ export const CategoryFilterSubList = styled(DropDown)` max-height: 296px; max-width: auto; - visibility: hidden; - visibility: hidden; ${({ open, isSubHovered }) => open && diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js index e64b85c430..5e18f02e5e 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js @@ -2,6 +2,9 @@ import { StyledSubItemMobile } from "./index.styled"; import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; +import { getDefaultOformLocale } from "@docspace/common/utils"; + +const categoryLocale = getDefaultOformLocale(); const CategorySubList = ({ categoryType, @@ -19,7 +22,7 @@ const CategorySubList = ({ onFilterByCategory(category)} /> )); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js index a815ed6c7c..0c3dd5c389 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js @@ -1,6 +1,5 @@ import { useState, useEffect } from "react"; import { inject } from "mobx-react"; -import { withTranslation } from "react-i18next"; import CategoryFilterDesktop from "./DesktopView"; import CategoryFilterMobile from "./MobileView"; import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; @@ -8,6 +7,7 @@ import { smallTablet } from "@docspace/components/utils/device"; import { isMobileOnly } from "react-device-detect"; import styled, { css } from "styled-components"; +import { getDefaultOformLocale } from "@docspace/common/utils"; export const StyledCategoryFilterWrapper = styled.div` width: 100%; @@ -39,9 +39,9 @@ export const StyledCategoryFilterWrapper = styled.div` `} `; -const CategoryFilter = ({ - t, +const categoryLocale = getDefaultOformLocale(); +const CategoryFilter = ({ currentCategory, oformsFilter, filterOformsByCategory, @@ -51,8 +51,8 @@ const CategoryFilter = ({ fetchPopularCategories, }) => { const currentCategoryTitle = getOformCategoryTitle( - oformsFilter.categorizeBy, - currentCategory + currentCategory, + categoryLocale ); const onViewAllTemplates = () => filterOformsByCategory("", ""); @@ -64,6 +64,7 @@ const CategoryFilter = ({ useEffect(() => { (async () => { const branchData = await fetchCategoriesByBranch(); + console.log(branchData); setFormsByBranch(branchData); const typeData = await fetchCategoriesByType(); setFormsByType(typeData); @@ -76,10 +77,7 @@ const CategoryFilter = ({ ({ oformsFilter: oformsStore.oformsFilter, filterOformsByCategory: oformsStore.filterOformsByCategory, -}))(withTranslation(["FormGallery"])(CategoryFilter)); +}))(CategoryFilter); diff --git a/packages/client/src/pages/FormGallery/Header.js b/packages/client/src/pages/FormGallery/Header.js index edd37e652e..552949e4b2 100644 --- a/packages/client/src/pages/FormGallery/Header.js +++ b/packages/client/src/pages/FormGallery/Header.js @@ -22,12 +22,14 @@ import { isMobileOnly } from "react-device-detect"; import DropDownItem from "@docspace/components/drop-down-item"; import { CategoryType } from "@docspace/client/src/helpers/constants"; import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; +import { getDefaultOformLocale } from "@docspace/common/utils"; + +const categoryLocale = getDefaultOformLocale(); const SectionHeaderContent = ({ t, canSubmitToFormGallery, - isInfoPanelVisible, - setIsInfoPanelVisible, + setGallerySelected, categoryType, setSubmitToGalleryDialogVisible, @@ -38,8 +40,6 @@ const SectionHeaderContent = ({ oformsFilter, filterOformsByCategory, - setGallerySelected, - isInfoPanelVisible, setIsInfoPanelVisible, }) => { @@ -110,7 +110,7 @@ const SectionHeaderContent = ({ }, [fromFolderId, oformsFilter.categorizeBy, oformsFilter.categoryId]); return ( - + - {getOformCategoryTitle(oformsFilter.categorizeBy, currentCategory) || + {getOformCategoryTitle(currentCategory, categoryLocale) || t("Common:OFORMsGallery")} @@ -162,23 +162,25 @@ const SectionHeaderContent = ({ ); }; -export default inject(({ auth, filesStore, oformsStore }) => { - return { - categoryType: filesStore.categoryType, +export default inject( + ({ auth, filesStore, oformsStore, accessRightsStore, dialogsStore }) => { + return { + categoryType: filesStore.categoryType, - currentCategory: oformsStore.currentCategory, - fetchCurrentCategory: oformsStore.fetchCurrentCategory, + currentCategory: oformsStore.currentCategory, + fetchCurrentCategory: oformsStore.fetchCurrentCategory, - oformsFilter: oformsStore.oformsFilter, - filterOformsByCategory: oformsStore.filterOformsByCategory, + oformsFilter: oformsStore.oformsFilter, + filterOformsByCategory: oformsStore.filterOformsByCategory, - setGallerySelected: oformsStore.setGallerySelected, + setGallerySelected: oformsStore.setGallerySelected, - canSubmitToFormGallery: accessRightsStore.canSubmitToFormGallery, - setSubmitToGalleryDialogVisible: - accessRightsStore.setSubmitToGalleryDialogVisible, + canSubmitToFormGallery: accessRightsStore.canSubmitToFormGallery, + setSubmitToGalleryDialogVisible: + dialogsStore.setSubmitToGalleryDialogVisible, - isInfoPanelVisible: auth.infoPanelStore.isVisible, - setIsInfoPanelVisible: auth.infoPanelStore.setIsVisible, - }; -})(withTranslation("Common")(observer(SectionHeaderContent))); + isInfoPanelVisible: auth.infoPanelStore.isVisible, + setIsInfoPanelVisible: auth.infoPanelStore.setIsVisible, + }; + } +)(withTranslation("Common")(observer(SectionHeaderContent))); diff --git a/packages/client/src/pages/FormGallery/StyledGallery.js b/packages/client/src/pages/FormGallery/StyledGallery.js index b26938ab53..9df0f8bfa8 100644 --- a/packages/client/src/pages/FormGallery/StyledGallery.js +++ b/packages/client/src/pages/FormGallery/StyledGallery.js @@ -1,18 +1,35 @@ import styled, { css } from "styled-components"; import { isMobile, isMobileOnly } from "react-device-detect"; -import { tablet, mobile } from "@docspace/components/utils/device"; +import { + tablet, + mobile, + hugeMobile, + smallTablet, +} from "@docspace/components/utils/device"; import Headline from "@docspace/common/components/Headline"; import ComboBox from "@docspace/components/combobox"; import { Base } from "@docspace/components/themes"; import { Button } from "@docspace/components"; +const calculateContainerGridColumns = (isRootFolder, isInfoPanelVisible) => { + let result = "min-content 12px auto"; + if (!isRootFolder) result = "29px " + result; + if (!isInfoPanelVisible) result += " 32px"; + return result; +}; + const StyledContainer = styled.div` width: 100%; height: 32px; display: grid; - grid-template-columns: ${(props) => - props.isRootFolder ? "1fr auto auto" : "29px 1fr auto auto"}; + grid-template-columns: ${({ isRootFolder, isInfoPanelVisible }) => + calculateContainerGridColumns(isRootFolder, isInfoPanelVisible)}; + + @media ${tablet} { + grid-template-columns: ${({ isRootFolder }) => + isRootFolder ? "min-content 12px auto" : "29px min-content 12px auto"}; + } align-items: center; @@ -65,14 +82,16 @@ const StyledNavigationDrodown = styled(ComboBox)` background: transparent; `; const StyledSubmitToGalleryButton = styled(Button)` - margin-left: auto; + @media ${smallTablet} { + display: none; + } ${(props) => props.theme.interfaceDirection === "ltr" ? css` - margin-right: 12px; + margin-left: auto; ` : css` - margin-left: 12px; + margin-right: auto; `} `; StyledSubmitToGalleryButton.defaultProps = { theme: Base }; @@ -81,10 +100,10 @@ const StyledInfoPanelToggleWrapper = styled.div` ${(props) => props.theme.interfaceDirection === "rtl" ? css` - margin-right: auto; + margin-right: 12px; ` : css` - margin-left: auto; + margin-left: 12px; `} display: ${(props) => (props.isInfoPanelVisible ? "none" : "flex")}; diff --git a/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js b/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js index e15ea31368..681a2e70f2 100644 --- a/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js +++ b/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js @@ -55,7 +55,7 @@ const Tile = (props) => { const getIconFile = () => { // const src = // item.attributes.template_image.data.attributes.formats.small.url; - const src = item.attributes.card_prewiew.data.attributes.url; + const src = item?.attributes.card_prewiew.data?.attributes.url; const svgLoader = () =>
; return src ? ( diff --git a/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js b/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js index 71c0b46cba..15a57569fb 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js @@ -91,6 +91,14 @@ const StyledTitle = styled.div` -webkit-line-clamp: 2; } + .free-label { + margin-left: auto; + color: #4781d1; + font-size: 14px; + font-weight: 600; + line-height: 16px; + } + ${(props) => props.withBottomBorder && css` diff --git a/packages/client/src/pages/Home/InfoPanel/Body/styles/gallery.js b/packages/client/src/pages/Home/InfoPanel/Body/styles/gallery.js index 5f785d3a27..d00ca649e9 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/styles/gallery.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/styles/gallery.js @@ -20,4 +20,15 @@ const StyledGalleryThumbnail = styled.div` StyledGalleryThumbnail.defaultProps = { theme: Base }; -export { StyledGalleryThumbnail }; +const StyledGalleryNoThumbnail = styled.div` + height: auto; + width: 100%; + display: flex; + justify-content: center; + .no-thumbnail-img { + height: 96px; + width: 96px; + } +`; + +export { StyledGalleryThumbnail, StyledGalleryNoThumbnail }; diff --git a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js index be0b1a7e92..d39a1a4a38 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js @@ -18,6 +18,7 @@ const GalleryItemTitle = ({ t, gallerySelected, getIcon }) => { {gallerySelected && ( !withLabel && "margin-left: auto;"} - ${(props) => - props.theme.interfaceDirection === "rtl" - ? css` - margin-right: auto; - ` - : css` - margin-left: auto; - `} + margin: ${({ withLabel, theme }) => + theme.interfaceDirection === "rtl" + ? withLabel + ? "0 8px 0 0" + : "0 auto 0 0" + : withLabel + ? "0 0 0 8px" + : "0 0 0 auto"}; `; const getFormContextOptions = (t) => [ @@ -54,6 +53,7 @@ const ItemContextOptions = ({ withLabel = false, }) => { + console.log(withLabel); if (!selection) return null; const [contextHelper, setContextHelper] = useState(null); diff --git a/packages/client/src/pages/Home/InfoPanel/Body/views/Gallery/index.js b/packages/client/src/pages/Home/InfoPanel/Body/views/Gallery/index.js index d09cdeb520..290b6abf8e 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/views/Gallery/index.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/views/Gallery/index.js @@ -9,7 +9,10 @@ import Loaders from "@docspace/common/components/Loaders/index.js"; import Text from "@docspace/components/text"; import { parseAndFormatDate } from "../../helpers/DetailsHelper.js"; -import { StyledGalleryThumbnail } from "../../styles/gallery.js"; +import { + StyledGalleryNoThumbnail, + StyledGalleryThumbnail, +} from "../../styles/gallery.js"; import { StyledDescription, StyledLink, @@ -21,8 +24,8 @@ import Link from "@docspace/components/link/index.js"; const Gallery = ({ t, gallerySelected, getIcon, culture, personal }) => { const thumbnailBlank = getIcon(96, ".docxf"); const thumbnailUrl = - gallerySelected?.attributes?.template_image?.data.attributes?.formats?.small - ?.url; + gallerySelected?.attributes?.template_image?.data?.attributes?.formats + ?.small?.url; return ( <> @@ -31,9 +34,9 @@ const Gallery = ({ t, gallerySelected, getIcon, culture, personal }) => { ) : ( -
+ -
+ )} diff --git a/packages/client/src/store/ContextOptionsStore.js b/packages/client/src/store/ContextOptionsStore.js index ef432bea25..a69a479b5c 100644 --- a/packages/client/src/store/ContextOptionsStore.js +++ b/packages/client/src/store/ContextOptionsStore.js @@ -1038,7 +1038,7 @@ class ContextOptionsStore { icon: FormFileReactSvgUrl, onClick: () => this.onClickSubmitToFormGallery(item), isOutsideLink: true, - disabled: !item.security.SubmitToFormGallery, + disabled: !item.security?.SubmitToFormGallery, }, { key: "separator-SubmitToGallery", diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index d490377317..502609a385 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -1,17 +1,16 @@ import { makeAutoObservable, runInAction } from "mobx"; -import api from "@docspace/common/api"; import OformsFilter from "@docspace/common/api/oforms/filter"; import { submitToGallery } from "@docspace/common/api/oforms"; -const { OformsFilter } = api; - import { getCategoryById, + getCategoryFilterMenuItems, getCategoriesByBranch, getCategoriesByType, getPopularCategories, } from "@docspace/common/api/oforms"; +import { getDefaultOformLocale } from "@docspace/common/utils"; class OformsStore { authStore; @@ -42,42 +41,6 @@ class OformsStore { setOformsIsLoading = (oformsIsLoading) => (this.oformsIsLoading = oformsIsLoading); - getOforms = async (filter = OformsFilter.getDefault()) => { - const oformData = await this.authStore.getOforms(filter); - const oformsFilter = oformData?.data?.meta?.pagination; - const newOformsFilter = this.oformsFilter.clone(); - - if (oformsFilter) { - newOformsFilter.page = oformsFilter.page; - newOformsFilter.total = oformsFilter.total; - } - - runInAction(() => { - this.setOformsFilter(newOformsFilter); - this.setOformFiles(oformData?.data?.data ?? []); - }); - }; - - submitToFormGallery = async (file, formName, language, signal = null) => { - const res = await submitToGallery( - this.authStore.settingsStore.formGallery.uploadUrl, - file, - formName, - language, - signal - ); - - return res; - }; - - setOformFiles = (oformFiles) => { - this.oformFiles = oformFiles; - }; - - setOformsFilter = (oformsFilter) => { - this.oformsFilter = oformsFilter; - }; - setGallerySelected = (gallerySelected) => { this.gallerySelected = gallerySelected; this.authStore.infoPanelStore.setSelection(gallerySelected); @@ -99,7 +62,6 @@ class OformsStore { }; loadMoreForms = async () => { - console.log("loadmore!!"); if (!this.hasMoreForms || this.oformsIsLoading) return; this.setOformsIsLoading(true); @@ -116,6 +78,12 @@ class OformsStore { }); }; + submitToFormGallery = async (file, formName, language, signal = null) => { + const url = this.authStore.settingsStore.formGallery.uploadUrl; + const res = await submitToGallery(url, file, formName, language, signal); + return res; + }; + fetchCurrentCategory = async () => { const { categorizeBy, categoryId } = this.oformsFilter; if (!categorizeBy || !categoryId) { @@ -130,21 +98,31 @@ class OformsStore { }); }; + fetchCategoryFilterMenuItems = async () => { + const url = "https://oforms.onlyoffice.com/dashboard/api/menu-translations"; + const locale = getDefaultOformLocale(); + const menuItems = await getCategoryFilterMenuItems(url, locale); + return menuItems; + }; + fetchCategoriesByBranch = async () => { + const url = "https://oforms.onlyoffice.com/dashboard/api/categories"; const { locale } = this.oformsFilter; - const categoriesByBranch = await getCategoriesByBranch(locale); + const categoriesByBranch = await getCategoriesByBranch(url, locale); return categoriesByBranch; }; fetchCategoriesByType = async () => { + const url = "https://oforms.onlyoffice.com/dashboard/api/types"; const { locale } = this.oformsFilter; - const categoriesByType = await getCategoriesByType(locale); + const categoriesByType = await getCategoriesByType(url, locale); return categoriesByType; }; fetchPopularCategories = async () => { + const url = "https://oforms.onlyoffice.com/dashboard/api/compilations"; const { locale } = this.oformsFilter; - const popularCategories = await getPopularCategories(locale); + const popularCategories = await getPopularCategories(url, locale); return popularCategories; }; @@ -162,6 +140,8 @@ class OformsStore { filterOformsByLocale = async (locale) => { if (!locale) return; + this.currentCategory = null; + this.oformsFilter.page = 1; this.oformsFilter.locale = locale; this.oformsFilter.categorizeBy = ""; @@ -190,6 +170,11 @@ class OformsStore { runInAction(() => this.getOforms(newOformsFilter)); }; + hideSubmitToGalleryTile = () => { + localStorage.setItem("submitToGalleryTileIsHidden", true); + this.submitToGalleryTileIsVisible = false; + }; + get hasGalleryFiles() { return this.oformFiles && !!this.oformFiles.length; } @@ -201,11 +186,6 @@ class OformsStore { get hasMoreForms() { return this.oformFiles.length < this.oformsFilterTotal; } - - hideSubmitToGalleryTile = () => { - localStorage.setItem("submitToGalleryTileIsHidden", true); - this.submitToGalleryTileIsVisible = false; - }; } export default OformsStore; diff --git a/packages/common/api/oformClient.js b/packages/common/api/oformClient.js deleted file mode 100644 index 133d4a980e..0000000000 --- a/packages/common/api/oformClient.js +++ /dev/null @@ -1,7 +0,0 @@ -import AxiosOformClient from "../utils/axiosOformClient"; - -const oformClient = new AxiosOformClient(); - -export const request = (options) => { - return oformClient.request(options); -}; diff --git a/packages/common/api/oforms/index.js b/packages/common/api/oforms/index.js index 5562d24018..6cbfd49e7b 100644 --- a/packages/common/api/oforms/index.js +++ b/packages/common/api/oforms/index.js @@ -1,36 +1,37 @@ import axios from "axios"; -import { request } from "../oformClient"; export function getOforms(url) { return axios.get(url); } -export const getCategoryById = async (categorizeBy, id) => { - const options = { method: "get", url: `/${categorizeBy}/${id}` }; +export const getCategoryById = async (categorizeBy, id, locale) => { + const options = { + method: "get", + url: `/${categorizeBy}/${id}?populate=*&locale=${locale}`, + }; return request(options).then((res) => { return res; }); }; -export const getCategoriesByBranch = async (locale = "en") => { - const options = { method: "get", url: `/categories?locale=${locale}` }; - return request(options).then((res) => { - return res; - }); +export const getCategoryFilterMenuItems = async (url, locale = "en") => { + const res = await axios.get(`${url}?populate=*&locale=${locale}`); + return res?.data; }; -export const getCategoriesByType = async (locale = "en") => { - const options = { method: "get", url: `/types?locale=${locale}` }; - return request(options).then((res) => { - return res; - }); +export const getCategoriesByBranch = async (url, locale = "en") => { + const res = await axios.get(`${url}?populate=*&locale=${locale}`); + return res?.data?.data; }; -export const getPopularCategories = async (locale = "en") => { - const options = { method: "get", url: `/compilations?locale=${locale}` }; - return request(options).then((res) => { - return res; - }); +export const getCategoriesByType = async (url, locale = "en") => { + const res = await axios.get(`${url}?populate=*&locale=${locale}`); + return res?.data?.data; +}; + +export const getPopularCategories = async (url, locale = "en") => { + const res = await axios.get(`${url}?populate=*&locale=${locale}`); + return res?.data?.data; }; export function submitToGallery(url, file, formName, language, signal) { diff --git a/packages/common/store/AuthStore.js b/packages/common/store/AuthStore.js index 141a7943fd..41edd527ac 100644 --- a/packages/common/store/AuthStore.js +++ b/packages/common/store/AuthStore.js @@ -443,20 +443,13 @@ class AuthStore { const params = `?${filter.toApiUrlParams()}${fields}`; const promise = new Promise(async (resolve, reject) => { - const apiUrl = `${this.settingsStore.urlOforms}${params}`; + const apiUrl = `${this.settingsStore.formGallery.url}${params}`; let oforms = await api.settings.getOforms(apiUrl); - // let oforms = await api.oforms.getOforms( - // combineUrl( - // this.settingsStore.urlOforms, - // `${params}&locale=${filter.locale}` - // ) - // ); - if (!oforms?.data?.data?.length) { + if (!oforms?.data?.data?.length) oforms = await api.oforms.getOforms( combineUrl(this.settingsStore.formGallery.url, `${params}&locale=en`) ); - } resolve(oforms); }); diff --git a/packages/common/utils/axiosOformClient.js b/packages/common/utils/axiosOformClient.js deleted file mode 100644 index 5c882775b1..0000000000 --- a/packages/common/utils/axiosOformClient.js +++ /dev/null @@ -1,30 +0,0 @@ -import axios from "axios"; -import defaultConfig from "PUBLIC_DIR/scripts/config.json"; -import combineUrl from "./combineUrl"; - -let { oformsApi: apiConf } = defaultConfig; -let { origin, prefix, timeout } = apiConf; - -class AxiosOformClient { - constructor() { - this.client = axios.create({ - baseURL: combineUrl(origin, prefix), - responseType: "json", - timeout: timeout, - withCredentials: true, - }); - } - - request = async (options) => - this.client(options) - .then((res) => { - if (res.data && res.data.error) throw new Error(res.data.error.message); - if (res.isAxiosError && res.message) throw new Error(res.message); - - if (!res || !res.data || res.isAxiosError) return null; - return res.data.data; - }) - .catch((err) => Promise.reject(err)); -} - -export default AxiosOformClient; diff --git a/public/scripts/config.json b/public/scripts/config.json index f68dfb8157..e99743671c 100644 --- a/public/scripts/config.json +++ b/public/scripts/config.json @@ -4,11 +4,6 @@ "prefix": "/api/2.0", "timeout": 30000 }, - "oformsApi": { - "origin": "https://cmsoforms.onlyoffice.com/", - "prefix": "/api", - "timeout": 30000 - }, "proxy": { "url": "" }, From c481f0ffea31caf2a943d7e8693140b28ca5888f Mon Sep 17 00:00:00 2001 From: mushka-n Date: Fri, 22 Sep 2023 20:04:09 +0300 Subject: [PATCH 036/334] empty container + acccent color styling --- packages/client/src/pages/FormGallery/Body.js | 70 +++++++++++++++++-- .../src/pages/FormGallery/Filter/index.js | 4 +- .../src/pages/FormGallery/StyledGallery.js | 26 +++---- .../Home/InfoPanel/Body/styles/common.js | 1 - .../ItemTitle/GalleryItemTitle.js | 11 ++- .../Body/sub-components/ItemTitle/index.js | 9 ++- 6 files changed, 91 insertions(+), 30 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Body.js b/packages/client/src/pages/FormGallery/Body.js index c50d6735df..ce4e1a7e5d 100644 --- a/packages/client/src/pages/FormGallery/Body.js +++ b/packages/client/src/pages/FormGallery/Body.js @@ -1,5 +1,7 @@ -import EmptyScreenFormGalleryReactSvgUrl from "PUBLIC_DIR/images/empty_screen_form-gallery.react.svg?url"; -import React, { useEffect } from "react"; +import EmptyScreenFilterAltSvgUrl from "PUBLIC_DIR/images/empty_screen_filter_alt.svg?url"; +import EmptyScreenFilterAltDarkSvgUrl from "PUBLIC_DIR/images/empty_screen_filter_alt_dark.svg?url"; + +import { useEffect } from "react"; import { observer, inject } from "mobx-react"; import EmptyScreenContainer from "@docspace/components/empty-screen-container"; import { withTranslation } from "react-i18next"; @@ -7,10 +9,36 @@ import TileContainer from "./TilesView/sub-components/TileContainer"; import FileTile from "./TilesView/FileTile"; import Loaders from "@docspace/common/components/Loaders"; import SubmitToGalleryTile from "./TilesView/sub-components/SubmitToGalleryTile"; +import Link from "@docspace/components/link"; +import ClearEmptyFilterSvgUrl from "PUBLIC_DIR/images/clear.empty.filter.svg?url"; +import IconButton from "@docspace/components/icon-button"; +import styled from "styled-components"; + +const StyledEmptyContainerLinks = styled.div` + display: grid; + margin: 13px 0; + grid-template-columns: 12px 1fr; + grid-column-gap: 8px; + + .icon { + height: 20px; + width: 12px; + margin: ${({ theme }) => + theme.interfaceDirection !== "rtl" ? "4px 4px 0 0;" : "4px 0 0 4px;"}; + cursor: pointer; + } + + .link { + color: ${({ theme }) => theme.filesEmptyContainer.linkColor}; + margin: ${({ theme }) => + theme.interfaceDirection !== "rtl" ? "0 7px 0 0" : "0 0 0 7px;"}; + } +`; const SectionBodyContent = ({ t, tReady, + theme, oformFiles, hasGalleryFiles, setGallerySelected, @@ -37,14 +65,41 @@ const SectionBodyContent = ({ }; }, [onMouseDown]); + const onResetFilter = () => {}; + return !tReady || !oformFiles ? ( ) : !hasGalleryFiles ? ( + + + {t("Common:ClearFilter")} + + + } /> ) : ( @@ -58,10 +113,11 @@ const SectionBodyContent = ({ ); }; -export default inject(({ accessRightsStore, oformsStore }) => ({ +export default inject(({ auth, accessRightsStore, oformsStore }) => ({ + theme: auth.settingsStore.theme, oformFiles: oformsStore.oformFiles, hasGalleryFiles: oformsStore.hasGalleryFiles, setGallerySelected: oformsStore.setGallerySelected, submitToGalleryTileIsVisible: oformsStore.submitToGalleryTileIsVisible, canSubmitToFormGallery: accessRightsStore.canSubmitToFormGallery, -}))(withTranslation("FormGallery")(observer(SectionBodyContent))); +}))(withTranslation("Common, FormGallery")(observer(SectionBodyContent))); diff --git a/packages/client/src/pages/FormGallery/Filter/index.js b/packages/client/src/pages/FormGallery/Filter/index.js index 99d1e3e521..4df14c2e87 100644 --- a/packages/client/src/pages/FormGallery/Filter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/index.js @@ -7,7 +7,7 @@ import CategoryFilter from "./CategoryFilter"; import LanguageFilter from "./LanguageFilter"; import SearchFilter from "./SearchFilter"; import SortFilter from "./SortFilter"; -import { smallTablet } from "@docspace/components/utils/device"; +import { smallTablet, tablet } from "@docspace/components/utils/device"; import { getDefaultOformLocale } from "@docspace/common/utils"; import OformsFilter from "@docspace/common/api/oforms/filter"; @@ -18,7 +18,7 @@ export const StyledFilter = styled.div` justify-content: space-between; gap: 8px; height: 32px; - padding: 8px 0 5px 0; + padding: 0 0 8px 0; .form-only-filters { display: flex; diff --git a/packages/client/src/pages/FormGallery/StyledGallery.js b/packages/client/src/pages/FormGallery/StyledGallery.js index 9df0f8bfa8..89f79ef2fa 100644 --- a/packages/client/src/pages/FormGallery/StyledGallery.js +++ b/packages/client/src/pages/FormGallery/StyledGallery.js @@ -14,7 +14,7 @@ import { Button } from "@docspace/components"; const calculateContainerGridColumns = (isRootFolder, isInfoPanelVisible) => { let result = "min-content 12px auto"; if (!isRootFolder) result = "29px " + result; - if (!isInfoPanelVisible) result += " 32px"; + if (!isInfoPanelVisible) result += " 52px"; return result; }; @@ -41,11 +41,6 @@ const StyledContainer = styled.div` theme.interfaceDirection === "rtl" && "transform: scaleX(-1);"} } - @media ${tablet} { - width: 100%; - padding: 16px 0 0px; - } - ${isMobile && css` width: 100% !important; @@ -97,26 +92,23 @@ const StyledSubmitToGalleryButton = styled(Button)` StyledSubmitToGalleryButton.defaultProps = { theme: Base }; const StyledInfoPanelToggleWrapper = styled.div` - ${(props) => - props.theme.interfaceDirection === "rtl" - ? css` - margin-right: 12px; - ` - : css` - margin-left: 12px; - `} - + box-sizing: border-box; display: ${(props) => (props.isInfoPanelVisible ? "none" : "flex")}; align-items: center; justify-content: center; + width: 16px; + height: 16px; + + margin: ${({ theme }) => + theme.interfaceDirection !== "rtl" ? "0 8px 0 28px" : "0 28px 0 8px"}; @media ${tablet} { display: none; } .info-panel-toggle-bg { - height: 32px; - width: 32px; + height: 16px; + width: 16px; display: flex; align-items: center; justify-content: center; diff --git a/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js b/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js index 15a57569fb..bcde29f5be 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js @@ -93,7 +93,6 @@ const StyledTitle = styled.div` .free-label { margin-left: auto; - color: #4781d1; font-size: 14px; font-weight: 600; line-height: 16px; diff --git a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js index d39a1a4a38..3f725ce0a2 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js @@ -6,7 +6,12 @@ import ItemContextOptions from "./ItemContextOptions"; import { Text } from "@docspace/components"; import { StyledTitle } from "../../styles/common"; -const GalleryItemTitle = ({ t, gallerySelected, getIcon }) => { +const GalleryItemTitle = ({ + t, + gallerySelected, + getIcon, + currentColorScheme, +}) => { const itemTitleRef = useRef(); return ( @@ -14,7 +19,9 @@ const GalleryItemTitle = ({ t, gallerySelected, getIcon }) => { {gallerySelected?.attributes?.name_form} - {t("FormGallery:Free")} + + {t("FormGallery:Free")} + {gallerySelected && ( { @@ -32,7 +33,11 @@ const ItemTitle = ({ if (isGallery) return ( - + ); const filesItemSelection = @@ -55,12 +60,14 @@ const ItemTitle = ({ }; export default inject(({ auth, settingsStore, peopleStore, oformsStore }) => { + const { currentColorScheme } = auth.settingsStore; const { selectionParentRoom, roomsView } = auth.infoPanelStore; const { getIcon } = settingsStore; const { getUserContextOptions } = peopleStore.contextOptionsStore; const { gallerySelected } = oformsStore; return { + currentColorScheme, gallerySelected, getUserContextOptions, selectionParentRoom, From 45bbbfa70affa1fca1329f782b0bef26df682e4d Mon Sep 17 00:00:00 2001 From: mushka-n Date: Fri, 22 Sep 2023 20:20:59 +0300 Subject: [PATCH 037/334] categoryFilter styling fix --- .../FormGallery/Filter/CategoryFilter/MobileView/index.js | 1 - .../Filter/CategoryFilter/MobileView/index.styled.js | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js index 02e4696bc5..d7f1b15f79 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js @@ -8,7 +8,6 @@ import CategorySubList from "./CategorySubList"; import { OformCategoryType } from "@docspace/client/src/helpers/constants"; import Scrollbar from "@docspace/components/scrollbar"; import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; -import ComboBox from "@docspace/components/combobox"; import ComboButton from "@docspace/components/combobox/sub-components/combo-button"; const CategoryFilterMobile = ({ diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.styled.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.styled.js index b2b922e24f..a2e50d4ed0 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.styled.js @@ -2,10 +2,17 @@ import styled, { css } from "styled-components"; import DropDown from "@docspace/components/drop-down"; import DropDownItem from "@docspace/components/drop-down-item"; +import ComboButton from "@docspace/components/combobox/sub-components/combo-button"; export const CategoryFilterMobileWrapper = styled.div` width: 100%; position: relative; + + .combo-button-label { + font-weight: 400; + font-size: 13px; + line-height: 20px; + } `; export const CategoryFilterMobile = styled(DropDown)` From 7f64f08d079e67217e57f252241a03093fc9fff2 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Fri, 22 Sep 2023 20:21:08 +0300 Subject: [PATCH 038/334] categoryFilter styling fix 2 --- .../CategoryFilter/DesktopView/index.styled.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js index 4ca62a507b..be5860da3e 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js @@ -14,14 +14,14 @@ export const CategoryFilter = styled(ComboBox)` width: 220px; box-sizing: border-box; + .combo-button-label { + font-weight: 400; + font-size: 13px; + line-height: 20px; + } + .dropdown-container { margin-top: 4px; - - .combo-button-label { - font-weight: 400; - font-size: 13px; - line-height: 20px; - } } `; From 00244b68a6967cc7bd9c64be73c3de5d7e391809 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Fri, 22 Sep 2023 20:30:38 +0300 Subject: [PATCH 039/334] filter reset methods --- .../src/components/dialogs/SubmitToFormGallery/index.js | 1 + packages/client/src/pages/FormGallery/Body.js | 8 ++++---- packages/client/src/store/OformsStore.js | 5 +++++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/client/src/components/dialogs/SubmitToFormGallery/index.js b/packages/client/src/components/dialogs/SubmitToFormGallery/index.js index 3483e0ead5..443cd94884 100644 --- a/packages/client/src/components/dialogs/SubmitToFormGallery/index.js +++ b/packages/client/src/components/dialogs/SubmitToFormGallery/index.js @@ -126,6 +126,7 @@ const SubmitToFormGallery = ({ color={currentColorScheme.main.accent} href="#" type={"page"} + target={"_blank"} isBold isHovered > diff --git a/packages/client/src/pages/FormGallery/Body.js b/packages/client/src/pages/FormGallery/Body.js index ce4e1a7e5d..854a69f79a 100644 --- a/packages/client/src/pages/FormGallery/Body.js +++ b/packages/client/src/pages/FormGallery/Body.js @@ -42,6 +42,7 @@ const SectionBodyContent = ({ oformFiles, hasGalleryFiles, setGallerySelected, + resetFilters, submitToGalleryTileIsVisible, canSubmitToFormGallery, }) => { @@ -65,8 +66,6 @@ const SectionBodyContent = ({ }; }, [onMouseDown]); - const onResetFilter = () => {}; - return !tReady || !oformFiles ? ( ) : !hasGalleryFiles ? ( @@ -84,13 +83,13 @@ const SectionBodyContent = ({ ({ oformFiles: oformsStore.oformFiles, hasGalleryFiles: oformsStore.hasGalleryFiles, setGallerySelected: oformsStore.setGallerySelected, + resetFilters: oformsStore.resetFilters, submitToGalleryTileIsVisible: oformsStore.submitToGalleryTileIsVisible, canSubmitToFormGallery: accessRightsStore.canSubmitToFormGallery, }))(withTranslation("Common, FormGallery")(observer(SectionBodyContent))); diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index 502609a385..7d0bf09ac5 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -170,6 +170,11 @@ class OformsStore { runInAction(() => this.getOforms(newOformsFilter)); }; + resetFilters = () => { + const newOformsFilter = OformsFilter.getDefault(); + runInAction(() => this.getOforms(newOformsFilter)); + }; + hideSubmitToGalleryTile = () => { localStorage.setItem("submitToGalleryTileIsHidden", true); this.submitToGalleryTileIsVisible = false; From 86764c6ba7fc5d1a0739f37384022304b8caa912 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Fri, 22 Sep 2023 20:34:28 +0300 Subject: [PATCH 040/334] suggest changes link accent color --- .../src/pages/Home/InfoPanel/Body/styles/common.js | 2 -- .../Home/InfoPanel/Body/views/Gallery/index.js | 13 +++++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js b/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js index bcde29f5be..92ea3ba44a 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js @@ -160,7 +160,6 @@ const StyledLink = styled.div` font-size: 13px; font-weight: 600; line-height: 15px; - color: #4781d1; } `; @@ -279,7 +278,6 @@ const StyledProperties = styled.div` StyledInfoPanelBody.defaultProps = { theme: Base }; StyledTitle.defaultProps = { theme: Base }; -StyledTitle.StyledLink = { theme: Base }; export { StyledInfoPanelBody, diff --git a/packages/client/src/pages/Home/InfoPanel/Body/views/Gallery/index.js b/packages/client/src/pages/Home/InfoPanel/Body/views/Gallery/index.js index 290b6abf8e..8ea0720ffa 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/views/Gallery/index.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/views/Gallery/index.js @@ -21,7 +21,14 @@ import { } from "../../styles/common.js"; import Link from "@docspace/components/link/index.js"; -const Gallery = ({ t, gallerySelected, getIcon, culture, personal }) => { +const Gallery = ({ + t, + gallerySelected, + getIcon, + culture, + personal, + currentColorScheme, +}) => { const thumbnailBlank = getIcon(96, ".docxf"); const thumbnailUrl = gallerySelected?.attributes?.template_image?.data?.attributes?.formats @@ -46,6 +53,7 @@ const Gallery = ({ t, gallerySelected, getIcon, culture, personal }) => { target="_blank" type="action" isHovered + color={currentColorScheme.main.accent} > {t("FormGallery:SuggestChanges")} @@ -99,7 +107,7 @@ const Gallery = ({ t, gallerySelected, getIcon, culture, personal }) => { }; export default inject(({ auth, settingsStore, oformsStore }) => { - const { personal, culture } = auth.settingsStore; + const { personal, culture, currentColorScheme } = auth.settingsStore; const { gallerySelected } = oformsStore; const { getIcon } = settingsStore; return { @@ -107,6 +115,7 @@ export default inject(({ auth, settingsStore, oformsStore }) => { gallerySelected, personal, culture, + currentColorScheme, }; })( withTranslation(["InfoPanel", "FormGallery", "Common", "Translations"])( From 7e56891fe619ca2457033efc59c427e095d1c7a7 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Fri, 22 Sep 2023 21:19:06 +0300 Subject: [PATCH 041/334] added template descripton fetching --- .../client/src/pages/Home/InfoPanel/Body/styles/common.js | 1 + .../src/pages/Home/InfoPanel/Body/views/Gallery/index.js | 8 ++++---- packages/common/store/AuthStore.js | 4 +++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js b/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js index 92ea3ba44a..e04cde8efd 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js @@ -176,6 +176,7 @@ const StyledDescription = styled.div` font-weight: 400; line-height: 20px; color: #657077; + white-space: pre-line; `; const StyledProperties = styled.div` diff --git a/packages/client/src/pages/Home/InfoPanel/Body/views/Gallery/index.js b/packages/client/src/pages/Home/InfoPanel/Body/views/Gallery/index.js index 8ea0720ffa..17ca7d6775 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/views/Gallery/index.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/views/Gallery/index.js @@ -34,6 +34,9 @@ const Gallery = ({ gallerySelected?.attributes?.template_image?.data?.attributes?.formats ?.small?.url; + const defaultDescription = gallerySelected?.attributes?.description_card; + const templateDescription = gallerySelected?.attributes?.template_desc; + return ( <> {thumbnailUrl ? ( @@ -66,10 +69,7 @@ const Gallery = ({ - Fill out the form online and get a recipe page ready, or just download - the template in the desirable format: DOCXF, OFORM, or PDF. Designing - custom recipe cards or pages helps create useful complimentary content - for cooking blogs, culinary websites, or restaurants. + {templateDescription || defaultDescription} diff --git a/packages/common/store/AuthStore.js b/packages/common/store/AuthStore.js index 41edd527ac..af737b6791 100644 --- a/packages/common/store/AuthStore.js +++ b/packages/common/store/AuthStore.js @@ -436,10 +436,12 @@ class AuthStore { const updatedAt = "&fields[1]=updatedAt"; const size = "&fields[2]=file_size"; const filePages = "&fields[3]=file_pages"; + const defaultDescription = "&fields[4]=description_card"; + const templateDescription = "&fields[5]=template_desc"; const cardPrewiew = "&populate[card_prewiew][fields][4]=url"; const templateImage = "&populate[template_image][fields][5]=formats"; - const fields = `${formName}${updatedAt}${size}${filePages}${cardPrewiew}${templateImage}`; + const fields = `${formName}${updatedAt}${size}${filePages}${defaultDescription}${templateDescription}${cardPrewiew}${templateImage}`; const params = `?${filter.toApiUrlParams()}${fields}`; const promise = new Promise(async (resolve, reject) => { From 56b1d1edae04085ea81f380714fe8c74cdcadb66 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Fri, 22 Sep 2023 21:22:23 +0300 Subject: [PATCH 042/334] infoPanel styling update --- .../client/src/pages/Home/InfoPanel/Body/styles/common.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js b/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js index e04cde8efd..ba4b1d8f01 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js @@ -8,10 +8,10 @@ const StyledInfoPanelBody = styled.div` ${(props) => props.theme.interfaceDirection === "rtl" ? css` - padding: 0px 20px 0 3px; + padding: 0px 20px 24px 3px; ` : css` - padding: 0px 3px 0 20px; + padding: 0px 3px 24px 20px; `} color: ${(props) => props.theme.infoPanel.textColor}; background-color: ${(props) => props.theme.infoPanel.backgroundColor}; From 7c97d496938af0eb80cff303a5cbaa4d1aafc37b Mon Sep 17 00:00:00 2001 From: mushka-n Date: Sat, 23 Sep 2023 00:41:19 +0300 Subject: [PATCH 043/334] moved getContextOptions to store + implemented to GalleryItemTitle --- .../ItemTitle/GalleryItemTitle.js | 73 +++++++++++++++---- .../ItemTitle/ItemContextOptions.js | 73 +++++-------------- .../Body/sub-components/ItemTitle/index.js | 1 - .../InfoPanel/Body/views/Gallery/index.js | 10 ++- packages/client/src/store/OformsStore.js | 53 +++++++++++++- 5 files changed, 134 insertions(+), 76 deletions(-) diff --git a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js index 3f725ce0a2..3d43765699 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js @@ -1,18 +1,46 @@ import { useRef } from "react"; import { withTranslation } from "react-i18next"; import { ReactSVG } from "react-svg"; -import ItemContextOptions from "./ItemContextOptions"; +import { ContextMenu, ContextMenuButton } from "@docspace/components"; +import { inject } from "mobx-react"; import { Text } from "@docspace/components"; import { StyledTitle } from "../../styles/common"; +import { useParams, useNavigate } from "react-router-dom"; +import styled from "styled-components"; + +const StyledGalleryContextOptions = styled.div` + height: 16px; + margin: ${({ theme }) => + theme.interfaceDirection === "rtl" ? "0 8px 0 0" : "0 0 0 8px"}; +`; const GalleryItemTitle = ({ t, + gallerySelected, getIcon, currentColorScheme, + + getFormContextOptions, + categoryType, }) => { const itemTitleRef = useRef(); + const contextMenuRef = useRef(); + + const params = useParams(); + const navigate = useNavigate(); + + console.log(gallerySelected); + + const onGetContextOptions = () => + getFormContextOptions(t, gallerySelected, categoryType, params, navigate); + + const onContextMenu = (e) => { + e.button === 2; + if (!contextMenuRef.current.menuRef.current) itemTitleRef.current.click(e); + contextMenuRef.current.show(e); + }; return ( @@ -23,23 +51,36 @@ const GalleryItemTitle = ({ {t("FormGallery:Free")} {gallerySelected && ( - + + + + )} ); }; -export default withTranslation([ - "FormGallery", - "Files", - "Common", - "Translations", - "InfoPanel", -])(GalleryItemTitle); +export default inject(({ oformsStore, filesStore }) => ({ + getFormContextOptions: oformsStore.getFormContextOptions, + categoryType: filesStore.categoryType, +}))( + withTranslation([ + "FormGallery", + "Files", + "Common", + "Translations", + "InfoPanel", + ])(GalleryItemTitle) +); diff --git a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/ItemContextOptions.js b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/ItemContextOptions.js index 4374c784e6..127910270e 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/ItemContextOptions.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/ItemContextOptions.js @@ -1,6 +1,6 @@ -import React, { useRef, useEffect, useState } from "react"; +import { useRef, useEffect, useState } from "react"; import { inject, observer } from "mobx-react"; -import styled, { css } from "styled-components"; +import styled from "styled-components"; import { ContextMenu, ContextMenuButton } from "@docspace/components"; @@ -18,32 +18,9 @@ const StyledItemContextOptions = styled.div` : "0 0 0 auto"}; `; -const getFormContextOptions = (t) => [ - { - key: "create", - label: t("Common:Create"), - onClick: () => {}, - }, - { - key: "preview", - label: t("Common:Preview"), - onClick: () => {}, - }, - { - key: "separator", - isSeparator: true, - }, - { - key: "suggest-changes", - label: t("FormGallery:SuggestChanges"), - onClick: () => {}, - }, -]; - const ItemContextOptions = ({ t, selection, - isForm = false, getContextOptions, getContextOptionActions, getUserContextOptions, @@ -53,49 +30,34 @@ const ItemContextOptions = ({ withLabel = false, }) => { - console.log(withLabel); if (!selection) return null; - const [contextHelper, setContextHelper] = useState(null); - const contextMenuRef = useRef(); + const [contextHelper, setContextHelper] = useState(null); + + const options = contextHelper?.getItemContextOptions(); + const getData = () => options; + const onContextMenu = (e) => { e.button === 2; - if (!contextMenuRef.current.menuRef.current) itemTitleRef.current.click(e); - contextMenuRef.current.show(e); + if (!contextMenuRef?.current.menuRef.current) + itemTitleRef?.current.click(e); + contextMenuRef?.current.show(e); }; useEffect(() => { - contextMenuRef.current.hide(); - }, [selection]); - - useEffect(() => { + contextMenuRef?.current.hide(); const contextHelper = new ContextHelper({ t, - isUser, selection, + isUser, getContextOptions, getContextOptionActions, getUserContextOptions, }); - setContextHelper(contextHelper); - }, [ - t, - isUser, - selection, - getContextOptions, - getContextOptionActions, - getUserContextOptions, - ]); - - const options = contextHelper?.getItemContextOptions(); - - const getData = () => { - if (isForm) return getFormContextOptions(t); - return options; - }; + }, [selection]); return ( @@ -125,15 +87,18 @@ const ItemContextOptions = ({ export default inject(({ filesStore, peopleStore, contextOptionsStore }) => { const { getUserContextOptions } = peopleStore.contextOptionsStore; - const { setBufferSelection, getFilesContextOptions: getContextOptions } = - filesStore; + const { + categoryType, + setBufferSelection, + getFilesContextOptions: getContextOptions, + } = filesStore; const { getFilesContextOptions: getContextOptionActions } = contextOptionsStore; - return { setBufferSelection, getContextOptions, getContextOptionActions, getUserContextOptions, + categoryType, }; })(observer(ItemContextOptions)); diff --git a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/index.js b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/index.js index a98abb31d9..f114273bd7 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/index.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/index.js @@ -1,4 +1,3 @@ -import React from "react"; import { inject, observer } from "mobx-react"; import AccountsItemTitle from "./AccountsItemTitle"; diff --git a/packages/client/src/pages/Home/InfoPanel/Body/views/Gallery/index.js b/packages/client/src/pages/Home/InfoPanel/Body/views/Gallery/index.js index 17ca7d6775..efcfc60a93 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/views/Gallery/index.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/views/Gallery/index.js @@ -34,8 +34,9 @@ const Gallery = ({ gallerySelected?.attributes?.template_image?.data?.attributes?.formats ?.small?.url; - const defaultDescription = gallerySelected?.attributes?.description_card; - const templateDescription = gallerySelected?.attributes?.template_desc; + console.log(gallerySelected); + + const formTitle = gallerySelected?.attributes?.name_form; return ( <> @@ -52,7 +53,7 @@ const Gallery = ({ - {templateDescription || defaultDescription} + {gallerySelected?.attributes?.template_desc || + gallerySelected?.attributes?.description_card} diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index 7d0bf09ac5..7cb7120356 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -10,7 +10,10 @@ import { getCategoriesByType, getPopularCategories, } from "@docspace/common/api/oforms"; -import { getDefaultOformLocale } from "@docspace/common/utils"; +import { combineUrl, getDefaultOformLocale } from "@docspace/common/utils"; +import FilesFilter from "@docspace/common/api/files/filter"; +import { getCategoryUrl } from "@docspace/client/src/helpers/utils"; +import config from "PACKAGE_FILE"; class OformsStore { authStore; @@ -78,6 +81,54 @@ class OformsStore { }); }; + getFormContextOptions = (t, item, categoryType, params, navigate) => [ + { + key: "create", + label: t("Common:Create"), + onClick: () => { + this.authStore.infoPanelStore.setIsVisible(false); + const filesFilter = FilesFilter.getDefault(); + filesFilter.folder = params?.fromFolderId; + const filterUrlParams = filesFilter.toUrlParams(); + const url = getCategoryUrl(categoryType, filterUrlParams.folder); + navigate( + combineUrl( + window.DocSpaceConfig?.proxy?.url, + config.homepage, + `${url}?${filterUrlParams}` + ) + ); + }, + }, + { + key: "preview", + label: t("Common:Preview"), + onClick: () => {}, + }, + { + key: "template-info", + label: t("TemplateInfo"), + onClick: () => { + this.authStore.infoPanelStore.setIsVisible(true); + this.setGallerySelected(item); + }, + }, + { + key: "separator", + isSeparator: true, + }, + { + key: "suggest-changes", + label: t("FormGallery:SuggestChanges"), + onClick: () => { + window.location = `mailto:marketing@onlyoffice.com + ?subject=Suggesting changes for ${item.attributes.name_form} + &body=Suggesting changes for ${item.attributes.name_form}. + `; + }, + }, + ]; + submitToFormGallery = async (file, formName, language, signal = null) => { const url = this.authStore.settingsStore.formGallery.uploadUrl; const res = await submitToGallery(url, file, formName, language, signal); From b868e18a0b637ae5addbc24e618c5a497e674737 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Sat, 23 Sep 2023 00:41:32 +0300 Subject: [PATCH 044/334] updated gallery tile component --- .../TilesView/sub-components/Tile.js | 178 +++++++----------- 1 file changed, 65 insertions(+), 113 deletions(-) diff --git a/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js b/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js index 681a2e70f2..1de6deacba 100644 --- a/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js +++ b/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js @@ -1,4 +1,4 @@ -import React from "react"; +import { useState, useRef } from "react"; import { inject, observer } from "mobx-react"; import ContextMenuButton from "@docspace/components/context-menu-button"; import PropTypes from "prop-types"; @@ -20,133 +20,62 @@ import { } from "../StyledTileView"; import { getCategoryUrl } from "SRC_DIR/helpers/utils"; -const Tile = (props) => { - const [errorLoadSrc, setErrorLoadSrc] = React.useState(false); +const Tile = ({ + t, + thumbnailClick, + item, + getFormContextOptions, - const cm = React.useRef(); - const tile = React.useRef(); - - const { - t, - thumbnailClick, - item, - - setIsInfoPanelVisible, - categoryType, - isInfoPanelVisible, - setGallerySelected, - children, - contextButtonSpacerWidth, - tileContextClick, - isActive, - isSelected, - title, - showHotkeyBorder, - getIcon, - } = props; + setIsInfoPanelVisible, + categoryType, + isInfoPanelVisible, + setGallerySelected, + children, + contextButtonSpacerWidth, + tileContextClick, + isActive, + isSelected, + title, + showHotkeyBorder, + getIcon, +}) => { + const cm = useRef(); + const tile = useRef(); const params = useParams(); const navigate = useNavigate(); - const onError = () => { - setErrorLoadSrc(true); - }; + const previewSrc = item?.attributes.card_prewiew.data?.attributes.url; + const previewLoader = () =>
; - const getIconFile = () => { - // const src = - // item.attributes.template_image.data.attributes.formats.small.url; - const src = item?.attributes.card_prewiew.data?.attributes.url; - const svgLoader = () =>
; + const formContextOptions = getFormContextOptions( + t, + item, + categoryType, + params, + navigate + ); - return src ? ( - - Thumbnail-img - - ) : ( - - ); - }; + const onSelectForm = () => setGallerySelected(item); - const getContextModel = () => { - return [ - { - key: "create", - label: t("Common:Create"), - onClick: onCreateForm, - }, - { - key: "preview", - label: t("Common:Preview"), - onClick: () => {}, - }, - { - key: "template-info", - label: t("TemplateInfo"), - onClick: onShowTemplateInfo, - }, - { - key: "separator", - isSeparator: true, - }, - { - key: "suggest-changes", - label: t("FormGallery:SuggestChanges"), - onClick: () => {}, - }, - ]; - }; + const getContextModel = () => formContextOptions; const onCreateForm = () => { - const filter = FilesFilter.getDefault(); - - filter.folder = params.folderId; - - const filterParamsStr = filter.toUrlParams(); - - const url = getCategoryUrl(categoryType, filter.folder); - - const pathname = `${url}?${filterParamsStr}`; - - setIsInfoPanelVisible(false); - - navigate( - combineUrl(window.DocSpaceConfig?.proxy?.url, config.homepage, pathname) + const [createFormOption] = formContextOptions.filter( + (contextOption) => contextOption.key === "create" ); + createFormOption?.onClick && createFormOption.onClick(); }; - const onShowTemplateInfo = () => { - onSelectForm(); - if (!isInfoPanelVisible) setIsInfoPanelVisible(true); - }; - - const getOptions = () => ["create", "template-info"]; - - const onSelectForm = () => { - setGallerySelected(item); - }; - - const src = getIcon(32, ".docxf"); - const element = ; + const getOptions = () => + formContextOptions.map((contextOption) => contextOption.key); const onContextMenu = (e) => { tileContextClick && tileContextClick(); - if (!cm.current.menuRef.current) { - tile.current.click(e); //TODO: need fix context menu to global - } + if (!cm.current.menuRef.current) tile.current.click(e); //TODO: need fix context menu to global cm.current.show(e); }; - const icon = getIconFile(); - //TODO: OFORM isActive return ( @@ -160,11 +89,33 @@ const Tile = (props) => { onClick={onSelectForm} className="files-item" > - {icon} + + {previewSrc ? ( + + Thumbnail-img + + ) : ( + + )} +
-
{element}
+
+ +
{children} @@ -177,7 +128,6 @@ const Tile = (props) => { onClick={onContextMenu} title={title} /> - { const { categoryType } = filesStore; - const { gallerySelected, setGallerySelected } = oformsStore; + const { gallerySelected, setGallerySelected, getFormContextOptions } = + oformsStore; const { getIcon } = settingsStore; const { isVisible, setIsVisible } = auth.infoPanelStore; @@ -219,6 +170,7 @@ export default inject( return { isSelected, setGallerySelected, + getFormContextOptions, getIcon, setIsInfoPanelVisible: setIsVisible, isInfoPanelVisible: isVisible, From 652662653b2332c90a8aa4bfa164e55cb6194c0d Mon Sep 17 00:00:00 2001 From: mushka-n Date: Sat, 23 Sep 2023 00:44:37 +0300 Subject: [PATCH 045/334] slight code cleanup and improvement --- .../sub-components/ItemTitle/FilesItemTitle.js | 8 +++----- .../sub-components/ItemTitle/GalleryItemTitle.js | 16 +++------------- .../ItemTitle/ItemContextOptions.js | 2 -- packages/client/src/store/OformsStore.js | 2 +- 4 files changed, 7 insertions(+), 21 deletions(-) diff --git a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/FilesItemTitle.js b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/FilesItemTitle.js index 2b82158909..debd7d85a8 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/FilesItemTitle.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/FilesItemTitle.js @@ -1,7 +1,5 @@ -import React, { useRef } from "react"; -import { inject, observer } from "mobx-react"; +import { useRef } from "react"; import { withTranslation } from "react-i18next"; -import { ReactSVG } from "react-svg"; import { Text } from "@docspace/components"; @@ -13,7 +11,7 @@ import RoomIcon from "@docspace/client/src/components/RoomIcon"; const FilesItemTitle = ({ t, selection, isSeveralItems }) => { const itemTitleRef = useRef(); - if (isSeveralItems) return <>; + if (isSeveralItems) return null; const icon = selection.icon; const isLoadedRoomIcon = !!selection.logo?.medium; @@ -54,4 +52,4 @@ export default withTranslation([ "Translations", "InfoPanel", "SharingPanel", -])(observer(FilesItemTitle)); +])(FilesItemTitle); diff --git a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js index 3d43765699..fb2ff97195 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js @@ -31,12 +31,10 @@ const GalleryItemTitle = ({ const params = useParams(); const navigate = useNavigate(); - console.log(gallerySelected); - const onGetContextOptions = () => getFormContextOptions(t, gallerySelected, categoryType, params, navigate); - const onContextMenu = (e) => { + const onClickContextMenu = (e) => { e.button === 2; if (!contextMenuRef.current.menuRef.current) itemTitleRef.current.click(e); contextMenuRef.current.show(e); @@ -61,7 +59,7 @@ const GalleryItemTitle = ({ id="info-options" className="expandButton" title={t("Translations:TitleShowActions")} - onClick={onContextMenu} + onClick={onClickContextMenu} getData={onGetContextOptions} directionX="right" displayType="toggle" @@ -75,12 +73,4 @@ const GalleryItemTitle = ({ export default inject(({ oformsStore, filesStore }) => ({ getFormContextOptions: oformsStore.getFormContextOptions, categoryType: filesStore.categoryType, -}))( - withTranslation([ - "FormGallery", - "Files", - "Common", - "Translations", - "InfoPanel", - ])(GalleryItemTitle) -); +}))(withTranslation(["FormGallery", "Common"])(GalleryItemTitle)); diff --git a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/ItemContextOptions.js b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/ItemContextOptions.js index 127910270e..1c9f0ce000 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/ItemContextOptions.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/ItemContextOptions.js @@ -1,9 +1,7 @@ import { useRef, useEffect, useState } from "react"; import { inject, observer } from "mobx-react"; import styled from "styled-components"; - import { ContextMenu, ContextMenuButton } from "@docspace/components"; - import ContextHelper from "../../helpers/ContextHelper"; const StyledItemContextOptions = styled.div` diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index 7cb7120356..bdab9e7717 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -107,7 +107,7 @@ class OformsStore { }, { key: "template-info", - label: t("TemplateInfo"), + label: t("FormGallery:TemplateInfo"), onClick: () => { this.authStore.infoPanelStore.setIsVisible(true); this.setGallerySelected(item); From d236bd9a22583186455d83d2c4f20d30ebaf54f3 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Sat, 23 Sep 2023 19:19:34 +0300 Subject: [PATCH 046/334] updated combobutton optional block to work with fillIcon prop --- .../combobox/sub-components/combo-button.js | 3 +- .../sub-components/styled-combobutton.js | 85 +++++++++++-------- 2 files changed, 53 insertions(+), 35 deletions(-) diff --git a/packages/components/combobox/sub-components/combo-button.js b/packages/components/combobox/sub-components/combo-button.js index b33d0a4f59..cbd7531dd2 100644 --- a/packages/components/combobox/sub-components/combo-button.js +++ b/packages/components/combobox/sub-components/combo-button.js @@ -12,7 +12,6 @@ import { import Text from "../../text"; - import { ColorTheme, ThemeType } from "@docspace/components/ColorTheme"; import Badge from "@docspace/components/badge"; @@ -67,6 +66,7 @@ const ComboButton = (props) => { isDisabled={isDisabled} defaultOption={defaultOption} isLoading={isLoading} + fillIcon={fillIcon} > {innerContainer} @@ -78,6 +78,7 @@ const ComboButton = (props) => { defaultOption={defaultOption} isSelected={isSelected} isLoading={isLoading} + fillIcon={fillIcon} > props.modernView && modernViewButton} - .optionalBlock { - svg { - path { - fill: ${(props) => - props.isOpen - ? props.theme.iconButton.hoverColor - : props.theme.iconButton.color}; + ${({ fillIcon }) => + fillIcon && + css` + .optionalBlock { + svg { + path { + fill: ${(props) => + props.isOpen + ? props.theme.iconButton.hoverColor + : props.theme.iconButton.color}; + } + } } - } - } + `}; + :hover { border-color: ${(props) => props.isOpen @@ -154,13 +159,17 @@ const StyledComboButton = styled.div` ${(props) => props.modernView && hoverModernViewButton} - .optionalBlock { - svg { - path { - fill: ${(props) => props.theme.iconButton.hoverColor}; + ${({ fillIcon }) => + fillIcon && + css` + .optionalBlock { + svg { + path { + fill: ${(props) => props.theme.iconButton.hoverColor}; + } + } } - } - } + `} } .combo-button-label { visibility: ${(props) => (props.isLoading ? "hidden" : "visible")}; @@ -201,16 +210,20 @@ const StyledComboButton = styled.div` ? props.theme.comboBox.button.hoverBorderColorOpen : props.theme.comboBox.button.hoverBorderColor}; - .optionalBlock { - svg { - path { - fill: ${(props) => - props.isOpen - ? props.theme.iconButton.hoverColor - : props.theme.iconButton.color}; + ${({ fillIcon }) => + fillIcon && + css` + .optionalBlock { + svg { + path { + fill: ${(props) => + props.isOpen + ? props.theme.iconButton.hoverColor + : props.theme.iconButton.color}; + } + } } - } - } + `} } `; StyledComboButton.defaultProps = { theme: Base }; @@ -226,16 +239,20 @@ const StyledOptionalItem = styled.div` `} visibility: ${(props) => (props.isLoading ? "hidden" : "visible")}; - path { - fill: ${(props) => - props.defaultOption - ? props.isDisabled - ? props.theme.comboBox.childrenButton.defaultDisabledColor - : props.theme.comboBox.childrenButton.defaultColor - : props.isDisabled - ? props.theme.comboBox.childrenButton.disabledColor - : props.theme.comboBox.childrenButton.color}; - } + ${({ fillIcon }) => + fillIcon && + css` + path { + fill: ${(props) => + props.defaultOption + ? props.isDisabled + ? props.theme.comboBox.childrenButton.defaultDisabledColor + : props.theme.comboBox.childrenButton.defaultColor + : props.isDisabled + ? props.theme.comboBox.childrenButton.disabledColor + : props.theme.comboBox.childrenButton.color}; + } + `} `; StyledOptionalItem.defaultProps = { theme: Base }; From 7535564535455f424798730d85a804bde739ddf7 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Sat, 23 Sep 2023 19:20:08 +0300 Subject: [PATCH 047/334] replaced language filter dropdown with combobutton component --- packages/client/src/pages/FormGallery/Body.js | 2 + .../Filter/LanguageFilter/index.js | 188 ++++++++++++++---- .../Filter/LanguageFilter/index.styled.js | 139 ++++++------- 3 files changed, 213 insertions(+), 116 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Body.js b/packages/client/src/pages/FormGallery/Body.js index 854a69f79a..4575c9b2a9 100644 --- a/packages/client/src/pages/FormGallery/Body.js +++ b/packages/client/src/pages/FormGallery/Body.js @@ -66,6 +66,8 @@ const SectionBodyContent = ({ }; }, [onMouseDown]); + // return ; + return !tReady || !oformFiles ? ( ) : !hasGalleryFiles ? ( diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js index 66ba348305..18c2c0fefe 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js @@ -3,12 +3,52 @@ import * as Styled from "./index.styled"; import DropDown from "@docspace/components/drop-down"; import ExpanderDownReactSvgUrl from "PUBLIC_DIR/images/expander-down.react.svg?url"; import { ReactSVG } from "react-svg"; -import { useRef, useState } from "react"; +import { useRef, useState, useEffect } from "react"; import { inject } from "mobx-react"; import { flagsIcons } from "@docspace/common/utils/image-helpers"; import { convertToCulture } from "@docspace/common/utils"; +import DropDownItem from "@docspace/components/drop-down-item"; +import ComboBox from "@docspace/components/combobox"; +import { OformCategoryType } from "@docspace/client/src/helpers/constants"; -const avialableLocales = ["en", "zh", "it", "fr", "es", "de", "ja"]; +import DeReactSvgUrl from "PUBLIC_DIR/images/flags/de.react.svg?url"; +import EnUSReactSvgUrl from "PUBLIC_DIR/images/flags/en-US.react.svg?url"; +import EsReactSvgUrl from "PUBLIC_DIR/images/flags/es.react.svg?url"; +import FrReactSvgUrl from "PUBLIC_DIR/images/flags/fr.react.svg?url"; +import ItReactSvgUrl from "PUBLIC_DIR/images/flags/it.react.svg?url"; +import JaJPReactSvgUrl from "PUBLIC_DIR/images/flags/ja-JP.react.svg?url"; +import ZhCNReactSvgUrl from "PUBLIC_DIR/images/flags/zh-CN.react.svg?url"; + +const locales = [ + { + key: "en", + icon: EnUSReactSvgUrl, + }, + { + key: "zh", + icon: ZhCNReactSvgUrl, + }, + { + key: "it", + icon: ItReactSvgUrl, + }, + { + key: "fr", + icon: FrReactSvgUrl, + }, + { + key: "es", + icon: EsReactSvgUrl, + }, + { + key: "de", + icon: DeReactSvgUrl, + }, + { + key: "ja", + icon: JaJPReactSvgUrl, + }, +]; const LanguageFilter = ({ oformsFilter, @@ -17,8 +57,25 @@ const LanguageFilter = ({ }) => { const dropdownRef = useRef(null); + const [currentOption] = locales.filter( + (locale) => locale.key === oformsFilter.locale + ); + + const [selectedOption, setSelectedOption] = useState(currentOption); + + const getSelectedOption = () => { + const [currentOption] = locales.filter( + (locale) => locale.key === oformsFilter.locale + ); + return currentOption; + }; + + console.log(selectedOption); + console.log(getSelectedOption()); + const [isOpen, setIsOpen] = useState(false); - const toggleDropdownIsOpen = () => setIsOpen(!isOpen); + const onToggleDropdownIsOpen = () => setIsOpen(!isOpen); + const onCloseDropdown = () => setIsOpen(false); const onFilterByLocale = async (newLocale) => { await filterOformsByLocale(newLocale); @@ -27,46 +84,99 @@ const LanguageFilter = ({ sectionScroll.scrollTop = 0; }; + useEffect(() => { + const [currentOption] = locales.filter( + (locale) => locale.key === oformsFilter.locale + ); + setSelectedOption(currentOption); + }, [oformsFilter.locale]); + return ( - -
- {oformsFilter.locale} + + {locales.map((locale) => ( + onFilterByLocale(locale.key)} + fillIcon={false} + /> + ))} + + } + > + - -
-
- - {avialableLocales.map((locale) => ( - onFilterByLocale(locale)} - fillIcon={false} - /> - ))} - -
+
); + + // return ( + // + //
+ // {oformsFilter.locale} + // + //
+ //
+ // + // {avialableLocales.map((locale) => ( + // onFilterByLocale(locale)} + // fillIcon={false} + // /> + // ))} + // + //
+ //
+ // ); }; export default inject(({ auth, oformsStore }) => ({ diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js index b74535948c..e8ba79c1bf 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js @@ -1,106 +1,91 @@ import DropDownItem from "@docspace/components/drop-down-item"; import styled, { css } from "styled-components"; import Base from "@docspace/components/themes/base"; +import ComboBox from "@docspace/components/combobox"; export const LanguageFilter = styled.div` width: 41px; box-sizing: border-box; - .combobox { - cursor: pointer; + .dropdown-container { width: 100%; - height: 32px; box-sizing: border-box; - display: flex; - flex-direction: row; - justify-content: space-between; - gap: 4px; - padding: 8px; - background: transparent; - border-radius: 3px; - max-height: 32px; - - border: ${(props) => - `1px solid ${ - props.isOpen - ? props.currentColorScheme.main.accent - : props.theme.createEditRoomDialog.thirdpartyStorage.combobox - .dropdownBorderColor - }`}; - - transition: all 0.2s ease; - &:hover { - border: ${(props) => - `1px solid ${ - props.isOpen - ? props.theme.createEditRoomDialog.thirdpartyStorage.combobox - .isOpenDropdownBorderColor - : props.theme.createEditRoomDialog.thirdpartyStorage.combobox - .hoverDropdownBorderColor - }`}; - } - - &-icon { - width: 16px; - height: 16px; - } - - &-expander { - display: flex; - align-items: center; - justify-content: center; - width: 6.35px; - svg { - transform: ${(props) => - props.isOpen ? "rotate(180deg)" : "rotate(0)"}; - width: 6.35px; - height: auto; - path { - fill: ${(props) => - props.theme.createEditRoomDialog.thirdpartyStorage.combobox - .arrowFill}; - } - } - } + margin-top: 4px; } +`; - .dropdown-wrapper { - width: 100%; - box-sizing: border-box; - position: relative; +export const LanguangeComboBox = styled(ComboBox)` + width: 41px; + padding: 0; + box-sizing: border-box; - .dropdown-container { - width: 100%; - box-sizing: border-box; - margin-top: 4px; - } + .combo-button { + padding: 8px; + gap: 4px; - .dropdown-item { - width: 100%; - height: 32px; - width: 41px; - box-sizing: border-box; - padding: 8px; - - display: flex; - align-items: center; - justify-content: center; - - .drop-down-icon { - margin-right: 0; + .optionalBlock { + margin: 0; + & > div { width: 16px; height: 16px; - line-height: 0 !important; + padding: 0; + display: flex; + align-items: center; + justify-content: center; } } + + .combo-button-label { + display: none; + } + + .combo-buttons_arrow-icon { + margin: 0; + } + } +`; + +export const LanguageFilterSelectedItem = styled(DropDownItem)` + box-sizing: border-box; + + display: flex; + align-items: center; + justify-content: center; + + .drop-down-icon { + margin-right: 0; + width: 16px; + height: 16px; + & > div { + display: flex; + align-items: center; + justify-content: center; + } } `; export const LanguageFilterItem = styled(DropDownItem)` + width: 100%; + height: 32px; + width: 41px; + box-sizing: border-box; + padding: 8px; + + display: flex; + align-items: center; + justify-content: center; + ${({ isSelected, theme }) => isSelected && css` background-color: ${theme.dropDownItem.hoverBackgroundColor}; `} + + .drop-down-icon { + margin-right: 0; + width: 16px; + height: 16px; + line-height: 0 !important; + } `; LanguageFilterItem.defaultProps = { theme: Base }; From 47715a37da5d73e4981c1d9ac522f9d6960da971 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Sat, 23 Sep 2023 22:07:49 +0300 Subject: [PATCH 048/334] fixed category filter selected item title not changing --- .../Filter/CategoryFilter/DesktopView/index.js | 9 ++++++++- .../CategoryFilter/DesktopView/index.styled.js | 2 ++ .../FormGallery/Filter/CategoryFilter/index.js | 5 ++--- packages/client/src/store/OformsStore.js | 13 ++++++++++++- packages/common/api/oforms/index.js | 13 +++++-------- 5 files changed, 29 insertions(+), 13 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js index e15ac78137..a23edc8453 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js @@ -6,6 +6,10 @@ import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; import SubList from "./SubList"; import { OformCategoryType } from "@docspace/client/src/helpers/constants"; +import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; +import { getDefaultOformLocale } from "@docspace/common/utils"; + +const categoryLocale = getDefaultOformLocale(); const CategoryFilterDesktop = ({ t, @@ -14,6 +18,7 @@ const CategoryFilterDesktop = ({ currentCategoryTitle, + currentCategory, onViewAllTemplates, formsByBranch, formsByType, @@ -67,7 +72,9 @@ const CategoryFilterDesktop = ({ fixedDirection={true} advancedOptionsCount={5} selectedOption={{ - label: currentCategoryTitle || t("FormGallery:Categories"), + label: + getOformCategoryTitle(currentCategory, categoryLocale) || + t("FormGallery:Categories"), }} advancedOptions={ <> diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js index be5860da3e..99beb74028 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js @@ -7,12 +7,14 @@ import ComboBox from "@docspace/components/combobox"; export const CategoryFilterWrapper = styled.div` position: relative; width: 220px; + height: 32px; box-sizing: border-box; `; export const CategoryFilter = styled(ComboBox)` width: 220px; box-sizing: border-box; + padding: 0; .combo-button-label { font-weight: 400; diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js index 0c3dd5c389..29516b6302 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js @@ -1,5 +1,5 @@ import { useState, useEffect } from "react"; -import { inject } from "mobx-react"; +import { inject, observer } from "mobx-react"; import CategoryFilterDesktop from "./DesktopView"; import CategoryFilterMobile from "./MobileView"; import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; @@ -64,7 +64,6 @@ const CategoryFilter = ({ useEffect(() => { (async () => { const branchData = await fetchCategoriesByBranch(); - console.log(branchData); setFormsByBranch(branchData); const typeData = await fetchCategoriesByType(); setFormsByType(typeData); @@ -103,4 +102,4 @@ export default inject(({ oformsStore }) => ({ oformsFilter: oformsStore.oformsFilter, filterOformsByCategory: oformsStore.filterOformsByCategory, -}))(CategoryFilter); +}))(observer(CategoryFilter)); diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index bdab9e7717..78b36727f7 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -136,13 +136,21 @@ class OformsStore { }; fetchCurrentCategory = async () => { + const url = "https://oforms.onlyoffice.com/dashboard/api"; const { categorizeBy, categoryId } = this.oformsFilter; + const locale = getDefaultOformLocale(); + if (!categorizeBy || !categoryId) { this.setOformsCurrentCategory(null); return; } - const fetchedCategory = await getCategoryById(categorizeBy, categoryId); + const fetchedCategory = await getCategoryById( + url, + categorizeBy, + categoryId, + locale + ); runInAction(() => { this.setOformsCurrentCategory(fetchedCategory); @@ -178,6 +186,8 @@ class OformsStore { }; filterOformsByCategory = (categorizeBy, categoryId) => { + if (!categorizeBy || !categoryId) this.currentCategory = null; + this.oformsFilter.page = 1; this.oformsFilter.categorizeBy = categorizeBy; this.oformsFilter.categoryId = categoryId; @@ -222,6 +232,7 @@ class OformsStore { }; resetFilters = () => { + this.currentCategory = null; const newOformsFilter = OformsFilter.getDefault(); runInAction(() => this.getOforms(newOformsFilter)); }; diff --git a/packages/common/api/oforms/index.js b/packages/common/api/oforms/index.js index 6cbfd49e7b..80c7f1ee1f 100644 --- a/packages/common/api/oforms/index.js +++ b/packages/common/api/oforms/index.js @@ -4,14 +4,11 @@ export function getOforms(url) { return axios.get(url); } -export const getCategoryById = async (categorizeBy, id, locale) => { - const options = { - method: "get", - url: `/${categorizeBy}/${id}?populate=*&locale=${locale}`, - }; - return request(options).then((res) => { - return res; - }); +export const getCategoryById = async (url, categorizeBy, id, locale) => { + const res = await axios.get( + `${url}/${categorizeBy}/${id}?populate=*&locale=${locale}` + ); + return res?.data?.data; }; export const getCategoryFilterMenuItems = async (url, locale = "en") => { From 690d8d70085eb95a61d441754e3c372976f8a966 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Sat, 23 Sep 2023 23:05:43 +0300 Subject: [PATCH 049/334] updated oformsStore an getContextOptions method --- .../pages/FormGallery/MediaViewer/index.js | 295 ++++++++++++++++++ .../TilesView/sub-components/Tile.js | 9 +- .../client/src/pages/FormGallery/index.js | 25 +- .../client/src/store/MediaViewerDataStore.js | 6 +- packages/client/src/store/OformsStore.js | 31 +- packages/client/src/store/index.js | 9 +- 6 files changed, 348 insertions(+), 27 deletions(-) create mode 100644 packages/client/src/pages/FormGallery/MediaViewer/index.js diff --git a/packages/client/src/pages/FormGallery/MediaViewer/index.js b/packages/client/src/pages/FormGallery/MediaViewer/index.js new file mode 100644 index 0000000000..79152a8792 --- /dev/null +++ b/packages/client/src/pages/FormGallery/MediaViewer/index.js @@ -0,0 +1,295 @@ +import React, { useEffect } from "react"; +import { inject, observer } from "mobx-react"; +import { withTranslation } from "react-i18next"; +import { useNavigate, useLocation } from "react-router-dom"; +import queryString from "query-string"; +import MediaViewer from "@docspace/common/components/MediaViewer"; + +const FilesMediaViewer = ({ + t, + files, + playlist, + currentPostionIndex, + visible, + currentMediaFileId, + deleteItemAction, + setMediaViewerData, + + setRemoveMediaItem, + userAccess, + deleteDialogVisible, + previewFile, + fetchFiles, + setIsLoading, + + setToPreviewFile, + setScrollToItem, + setCurrentId, + + setBufferSelection, + + archiveRoomsId, + + onShowInfoPanel, + onClickDownload, + + onClickLinkEdit, + onPreviewClick, + onCopyLink, + onClickRename, + onClickDelete, + onMoveAction, + onCopyAction, + getIcon, + onDuplicate, + extsImagePreviewed, + extsMediaPreviewed, + setIsPreview, + isPreview, + nextMedia, + prevMedia, + resetUrl, + getFirstUrl, + firstLoad, + setSelection, + activeFiles, + activeFolders, + onClickDownloadAs, + someDialogIsOpen, +}) => { + const navigate = useNavigate(); + const location = useLocation(); + + const onButtonBackHandler = () => { + const hash = window.location.hash; + const id = hash.slice(9); + if (!id) { + setMediaViewerData({ visible: false, id: null }); + return; + } + setMediaViewerData({ visible: true, id }); + }; + + const onChangeUrl = (id) => { + const url = "/form-gallery/null/#preview/" + id; + setCurrentId(id); + navigate(url); + }; + + const onDeleteMediaFile = (id) => {}; + + const onDownloadMediaFile = (id) => {}; + + const onMediaViewerClose = (e) => { + if (isPreview) { + setIsPreview(false); + resetUrl(); + if (previewFile) { + setScrollToItem({ id: previewFile.id, type: "file" }); + setBufferSelection(previewFile); + } + setToPreviewFile(null); + } + + setMediaViewerData({ visible: false, id: null }); + + const url = getFirstUrl(); + if (!url) return; + + const targetFile = files.find((item) => item.id === currentMediaFileId); + if (targetFile) setBufferSelection(targetFile); + + navigate(url, { replace: true }); + }; + + useEffect(() => { + const previewId = queryString.parse(location.search).preview; + + if (previewId) { + const queryParams = new URLSearchParams(location.search); + if (queryParams.has("preview")) { + queryParams.delete("preview"); + navigate(_, { + search: queryParams.toString(), + }); + } + + if (typeof +previewId !== "object") { + const item = { visible: true, id: +previewId }; + setMediaViewerData(item); + } + } + }, []); + + useEffect(() => { + if (visible) setSelection([]); + }, [visible]); + + useEffect(() => { + if (previewFile) + fetchFiles(previewFile.folderId).finally(() => { + setIsLoading(false); + }); + }, [previewFile]); + + useEffect(() => { + window.addEventListener("popstate", onButtonBackHandler); + return () => window.removeEventListener("popstate", onButtonBackHandler); + }, [onButtonBackHandler]); + + return ( + visible && ( + + ) + ); +}; + +export default inject( + ({ + filesStore, + mediaViewerDataStore, + filesActionsStore, + settingsStore, + dialogsStore, + treeFoldersStore, + contextOptionsStore, + clientLoadingStore, + }) => { + const { firstLoad, setIsSectionFilterLoading } = clientLoadingStore; + + const setIsLoading = (param) => { + setIsSectionFilterLoading(param); + }; + + const { + files, + userAccess, + fetchFiles, + setScrollToItem, + setBufferSelection, + setIsPreview, + isPreview, + resetUrl, + setSelection, + setAlreadyFetchingRooms, + activeFiles, + activeFolders, + } = filesStore; + + const { + visible, + id: currentMediaFileId, + currentPostionIndex, + setMediaViewerData, + getFirstUrl, + playlist, + previewFile, + setToPreviewFile, + setCurrentId, + nextMedia, + prevMedia, + } = mediaViewerDataStore; + + const { deleteItemAction } = filesActionsStore; + const { getIcon, extsImagePreviewed, extsMediaPreviewed } = settingsStore; + const { isFavoritesFolder, archiveRoomsId } = treeFoldersStore; + + const { + onClickFavorite, + onShowInfoPanel, + onClickDownloadAs, + onClickDownload, + onClickRename, + onClickDelete, + onMoveAction, + onCopyAction, + onDuplicate, + onClickLinkEdit, + onPreviewClick, + onCopyLink, + } = contextOptionsStore; + + return { + files, + playlist, + currentPostionIndex, + nextMedia, + prevMedia, + userAccess, + visible: playlist.length > 0 && visible, + currentMediaFileId, + deleteItemAction, + setMediaViewerData, + extsImagePreviewed, + extsMediaPreviewed, + setRemoveMediaItem: dialogsStore.setRemoveMediaItem, + deleteDialogVisible: dialogsStore.deleteDialogVisible, + someDialogIsOpen: dialogsStore.someDialogIsOpen, + fetchFiles, + previewFile, + setIsLoading, + firstLoad, + setToPreviewFile, + setIsPreview, + resetUrl, + isPreview, + setScrollToItem, + setCurrentId, + setBufferSelection, + setAlreadyFetchingRooms, + isFavoritesFolder, + onClickFavorite, + onClickDownloadAs, + onClickDelete, + onClickDownload, + onShowInfoPanel, + onClickLinkEdit, + onPreviewClick, + onCopyLink, + onClickRename, + onMoveAction, + getIcon, + onCopyAction, + onDuplicate, + archiveRoomsId, + setSelection, + getFirstUrl, + activeFiles, + activeFolders, + }; + } +)(withTranslation(["Files", "Translations"])(observer(FilesMediaViewer))); diff --git a/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js b/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js index 1de6deacba..e352f341f2 100644 --- a/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js +++ b/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js @@ -42,19 +42,12 @@ const Tile = ({ const cm = useRef(); const tile = useRef(); - const params = useParams(); const navigate = useNavigate(); const previewSrc = item?.attributes.card_prewiew.data?.attributes.url; const previewLoader = () =>
; - const formContextOptions = getFormContextOptions( - t, - item, - categoryType, - params, - navigate - ); + const formContextOptions = getFormContextOptions(t, item, navigate); const onSelectForm = () => setGallerySelected(item); diff --git a/packages/client/src/pages/FormGallery/index.js b/packages/client/src/pages/FormGallery/index.js index dd143f9afb..7e3a93c62d 100644 --- a/packages/client/src/pages/FormGallery/index.js +++ b/packages/client/src/pages/FormGallery/index.js @@ -1,7 +1,7 @@ import React, { useEffect } from "react"; import Section from "@docspace/common/components/Section"; import { observer, inject } from "mobx-react"; -import { useLocation, useNavigate } from "react-router-dom"; +import { useLocation, useNavigate, useParams } from "react-router-dom"; import SectionHeaderContent from "./Header"; import SectionBodyContent from "./Body"; @@ -10,10 +10,12 @@ import InfoPanelHeaderContent from "../Home/InfoPanel/Header"; import SectionFilterContent from "./Filter"; import OformsFilter from "@docspace/common/api/oforms/filter"; import Dialogs from "./Dialogs"; +import MediaViewer from "./MediaViewer"; -const FormGallery = ({ getOforms, setOformFiles }) => { +const FormGallery = ({ getOforms, setOformFiles, setOformFromFolderId }) => { const location = useLocation(); const navigate = useNavigate(); + const { fromFolderId } = useParams(); useEffect(() => { const firstLoadFilter = OformsFilter.getFilter(location); @@ -22,6 +24,10 @@ const FormGallery = ({ getOforms, setOformFiles }) => { return () => setOformFiles(null); }, [getOforms, setOformFiles]); + useEffect(() => { + setOformFromFolderId(fromFolderId); + }, [fromFolderId]); + return ( <>
{
+ + ); }; -export default inject(({ oformsStore }) => { - const { getOforms, setOformFiles } = oformsStore; - - return { - getOforms, - setOformFiles, - }; -})(observer(FormGallery)); +export default inject(({ oformsStore }) => ({ + getOforms: oformsStore.getOforms, + setOformFiles: oformsStore.setOformFiles, + setOformFromFolderId: oformsStore.setOformFromFolderId, +}))(observer(FormGallery)); diff --git a/packages/client/src/store/MediaViewerDataStore.js b/packages/client/src/store/MediaViewerDataStore.js index e04364e6a9..a78f01e1eb 100644 --- a/packages/client/src/store/MediaViewerDataStore.js +++ b/packages/client/src/store/MediaViewerDataStore.js @@ -73,10 +73,12 @@ class MediaViewerDataStore { localStorage.removeItem(FirstUrlKey); }; - changeUrl = (id) => { + changeUrl = (id, isForm = false, formFromFolderId = 2) => { if (this.publicRoomStore.isPublicRoom) return; - const url = "/products/files/#preview/" + id; + const url = !isForm + ? "/products/files/#preview/" + id + : `/form-gallery/${formFromFolderId}/#preview/${id}`; window.DocSpace.navigate(url); }; diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index 78b36727f7..3e0a57de4e 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -14,14 +14,19 @@ import { combineUrl, getDefaultOformLocale } from "@docspace/common/utils"; import FilesFilter from "@docspace/common/api/files/filter"; import { getCategoryUrl } from "@docspace/client/src/helpers/utils"; import config from "PACKAGE_FILE"; +import { CategoryType } from "@docspace/client/src/helpers/constants"; class OformsStore { authStore; + filesStore; + mediaViewerDataStore; oformFiles = null; oformsFilter = OformsFilter.getDefault(); currentCategory = null; + fromFolderId = CategoryType.SharedRoom; + oformsIsLoading = false; gallerySelected = null; @@ -29,8 +34,10 @@ class OformsStore { "submitToGalleryTileIsHidden" ); - constructor(authStore) { + constructor(authStore, filesStore, mediaViewerDataStore) { this.authStore = authStore; + this.filesStore = filesStore; + this.mediaViewerDataStore = mediaViewerDataStore; makeAutoObservable(this); } @@ -41,6 +48,8 @@ class OformsStore { setOformsCurrentCategory = (currentCategory) => (this.currentCategory = currentCategory); + setOformFromFolderId = (fromFolderId) => (this.fromFolderId = fromFolderId); + setOformsIsLoading = (oformsIsLoading) => (this.oformsIsLoading = oformsIsLoading); @@ -81,16 +90,19 @@ class OformsStore { }); }; - getFormContextOptions = (t, item, categoryType, params, navigate) => [ + getFormContextOptions = (t, item, navigate) => [ { key: "create", label: t("Common:Create"), onClick: () => { this.authStore.infoPanelStore.setIsVisible(false); const filesFilter = FilesFilter.getDefault(); - filesFilter.folder = params?.fromFolderId; + filesFilter.folder = this.fromFolderId; const filterUrlParams = filesFilter.toUrlParams(); - const url = getCategoryUrl(categoryType, filterUrlParams.folder); + const url = getCategoryUrl( + this.filesStore.categoryType, + filterUrlParams.folder + ); navigate( combineUrl( window.DocSpaceConfig?.proxy?.url, @@ -103,7 +115,16 @@ class OformsStore { { key: "preview", label: t("Common:Preview"), - onClick: () => {}, + onClick: () => { + this.mediaViewerDataStore.setMediaViewerData({ + visible: true, + id: item.id, + }); + this.mediaViewerDataStore.saveFirstUrl( + `${window.DocSpace.location.pathname}${window.DocSpace.location.search}` + ); + this.mediaViewerDataStore.changeUrl(item.id, true); + }, }, { key: "template-info", diff --git a/packages/client/src/store/index.js b/packages/client/src/store/index.js index 3010af5f37..8a79e1d37f 100644 --- a/packages/client/src/store/index.js +++ b/packages/client/src/store/index.js @@ -38,8 +38,6 @@ import PublicRoomStore from "./PublicRoomStore"; import WebhooksStore from "./WebhooksStore"; import ClientLoadingStore from "./ClientLoadingStore"; -const oformsStore = new OformsStore(authStore); - const selectedFolderStore = new SelectedFolderStore(authStore.settingsStore); const paymentStore = new PaymentStore(); @@ -83,6 +81,13 @@ const mediaViewerDataStore = new MediaViewerDataStore( settingsStore, publicRoomStore ); + +const oformsStore = new OformsStore( + authStore, + filesStore, + mediaViewerDataStore +); + const secondaryProgressDataStore = new SecondaryProgressDataStore(); const primaryProgressDataStore = new PrimaryProgressDataStore(); const versionHistoryStore = new VersionHistoryStore(filesStore); From ed057412a9ad67ae4c9a32586aadbeaf9b8a49d7 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Sat, 23 Sep 2023 23:39:15 +0300 Subject: [PATCH 050/334] moved fromfolderId to store --- .../Filter/LanguageFilter/index.js | 1 + .../client/src/pages/FormGallery/Header.js | 9 +++++--- .../client/src/pages/FormGallery/index.js | 23 +++++++++++++++---- packages/client/src/store/index.js | 6 +---- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js index 18c2c0fefe..f024a4876f 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js @@ -114,6 +114,7 @@ const LanguageFilter = ({ advancedOptionsCount={5} fillIcon={false} options={[]} + selectedOption={{}} advancedOptions={ <> {locales.map((locale) => ( diff --git a/packages/client/src/pages/FormGallery/Header.js b/packages/client/src/pages/FormGallery/Header.js index 552949e4b2..99a9dd9695 100644 --- a/packages/client/src/pages/FormGallery/Header.js +++ b/packages/client/src/pages/FormGallery/Header.js @@ -30,6 +30,8 @@ const SectionHeaderContent = ({ t, canSubmitToFormGallery, + fromFolderId, + setGallerySelected, categoryType, setSubmitToGalleryDialogVisible, @@ -44,7 +46,6 @@ const SectionHeaderContent = ({ setIsInfoPanelVisible, }) => { const navigate = useNavigate(); - const { fromFolderId } = useParams(); const [checkboxOptions, setCheckboxOptions] = useState(<>{[]}); @@ -80,8 +81,8 @@ const SectionHeaderContent = ({ useEffect(() => { (async () => { - const prevFolderId = fromFolderId || CategoryType.SharedRoom; - const prevFolder = await api.files.getFolderInfo(prevFolderId); + const prevFolder = + fromFolderId && (await api.files.getFolderInfo(fromFolderId)); const newCheckboxOptions = []; if (oformsFilter.categorizeBy && oformsFilter.categoryId) @@ -167,6 +168,8 @@ export default inject( return { categoryType: filesStore.categoryType, + fromFolderId: oformsStore.fromFolderId, + currentCategory: oformsStore.currentCategory, fetchCurrentCategory: oformsStore.fetchCurrentCategory, diff --git a/packages/client/src/pages/FormGallery/index.js b/packages/client/src/pages/FormGallery/index.js index 7e3a93c62d..67aaf98e79 100644 --- a/packages/client/src/pages/FormGallery/index.js +++ b/packages/client/src/pages/FormGallery/index.js @@ -11,8 +11,14 @@ import SectionFilterContent from "./Filter"; import OformsFilter from "@docspace/common/api/oforms/filter"; import Dialogs from "./Dialogs"; import MediaViewer from "./MediaViewer"; +import { CategoryType } from "@docspace/client/src/helpers/constants"; -const FormGallery = ({ getOforms, setOformFiles, setOformFromFolderId }) => { +const FormGallery = ({ + oformsFilter, + getOforms, + setOformFiles, + setOformFromFolderId, +}) => { const location = useLocation(); const navigate = useNavigate(); const { fromFolderId } = useParams(); @@ -20,12 +26,20 @@ const FormGallery = ({ getOforms, setOformFiles, setOformFromFolderId }) => { useEffect(() => { const firstLoadFilter = OformsFilter.getFilter(location); getOforms(firstLoadFilter); - return () => setOformFiles(null); - }, [getOforms, setOformFiles]); + }, []); useEffect(() => { - setOformFromFolderId(fromFolderId); + if (fromFolderId) { + setOformFromFolderId(fromFolderId); + } else { + setOformFromFolderId(CategoryType.SharedRoom); + navigate( + `/form-gallery/${ + CategoryType.SharedRoom + }/filter?${oformsFilter.toUrlParams()}` + ); + } }, [fromFolderId]); return ( @@ -63,6 +77,7 @@ const FormGallery = ({ getOforms, setOformFiles, setOformFromFolderId }) => { }; export default inject(({ oformsStore }) => ({ + oformsFilter: oformsStore.oformsFilter, getOforms: oformsStore.getOforms, setOformFiles: oformsStore.setOformFiles, setOformFromFolderId: oformsStore.setOformFromFolderId, diff --git a/packages/client/src/store/index.js b/packages/client/src/store/index.js index 8a79e1d37f..41bc2e4016 100644 --- a/packages/client/src/store/index.js +++ b/packages/client/src/store/index.js @@ -82,11 +82,7 @@ const mediaViewerDataStore = new MediaViewerDataStore( publicRoomStore ); -const oformsStore = new OformsStore( - authStore, - filesStore, - mediaViewerDataStore -); +const oformsStore = new OformsStore(authStore, mediaViewerDataStore); const secondaryProgressDataStore = new SecondaryProgressDataStore(); const primaryProgressDataStore = new PrimaryProgressDataStore(); From 5bf62a76d4d6ae5da11bac30cc48558c0826530a Mon Sep 17 00:00:00 2001 From: mushka-n Date: Sat, 23 Sep 2023 23:39:21 +0300 Subject: [PATCH 051/334] removed filesStore from oformsStore --- packages/client/src/store/OformsStore.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index 3e0a57de4e..71bdfebb77 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -18,14 +18,13 @@ import { CategoryType } from "@docspace/client/src/helpers/constants"; class OformsStore { authStore; - filesStore; mediaViewerDataStore; oformFiles = null; oformsFilter = OformsFilter.getDefault(); currentCategory = null; - fromFolderId = CategoryType.SharedRoom; + fromFolderId = CategoryType.Personal; oformsIsLoading = false; gallerySelected = null; @@ -34,9 +33,8 @@ class OformsStore { "submitToGalleryTileIsHidden" ); - constructor(authStore, filesStore, mediaViewerDataStore) { + constructor(authStore, mediaViewerDataStore) { this.authStore = authStore; - this.filesStore = filesStore; this.mediaViewerDataStore = mediaViewerDataStore; makeAutoObservable(this); } @@ -48,7 +46,10 @@ class OformsStore { setOformsCurrentCategory = (currentCategory) => (this.currentCategory = currentCategory); - setOformFromFolderId = (fromFolderId) => (this.fromFolderId = fromFolderId); + setOformFromFolderId = (fromFolderId) => { + if (!fromFolderId) return; + this.fromFolderId = fromFolderId; + }; setOformsIsLoading = (oformsIsLoading) => (this.oformsIsLoading = oformsIsLoading); @@ -100,7 +101,7 @@ class OformsStore { filesFilter.folder = this.fromFolderId; const filterUrlParams = filesFilter.toUrlParams(); const url = getCategoryUrl( - this.filesStore.categoryType, + CategoryType.Personal, filterUrlParams.folder ); navigate( From bc6052acbdad97f310f4376faf71d09235c66f9c Mon Sep 17 00:00:00 2001 From: mushka-n Date: Sat, 23 Sep 2023 23:48:31 +0300 Subject: [PATCH 052/334] media viewer update --- .../client/src/pages/FormGallery/MediaViewer/index.js | 8 +++++++- packages/client/src/store/OformsStore.js | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/client/src/pages/FormGallery/MediaViewer/index.js b/packages/client/src/pages/FormGallery/MediaViewer/index.js index 79152a8792..5feb26d385 100644 --- a/packages/client/src/pages/FormGallery/MediaViewer/index.js +++ b/packages/client/src/pages/FormGallery/MediaViewer/index.js @@ -26,6 +26,8 @@ const FilesMediaViewer = ({ setScrollToItem, setCurrentId, + fromFolderId, + setBufferSelection, archiveRoomsId, @@ -71,7 +73,7 @@ const FilesMediaViewer = ({ }; const onChangeUrl = (id) => { - const url = "/form-gallery/null/#preview/" + id; + const url = `/form-gallery/${fromFolderId}/#preview/${id}`; setCurrentId(id); navigate(url); }; @@ -180,6 +182,7 @@ const FilesMediaViewer = ({ export default inject( ({ + oformsStore, filesStore, mediaViewerDataStore, filesActionsStore, @@ -243,7 +246,10 @@ export default inject( onCopyLink, } = contextOptionsStore; + const { fromFolderId } = oformsStore; + return { + fromFolderId, files, playlist, currentPostionIndex, diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index 71bdfebb77..22d8d34c2c 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -124,7 +124,7 @@ class OformsStore { this.mediaViewerDataStore.saveFirstUrl( `${window.DocSpace.location.pathname}${window.DocSpace.location.search}` ); - this.mediaViewerDataStore.changeUrl(item.id, true); + this.mediaViewerDataStore.changeUrl(item.id, true, this.fromFolderId); }, }, { From 4cf63b74b73078e7134b17736233efbc6ffccaaf Mon Sep 17 00:00:00 2001 From: mushka-n Date: Sat, 23 Sep 2023 23:49:13 +0300 Subject: [PATCH 053/334] added empty screen translation key --- packages/client/public/locales/en/FormGallery.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/client/public/locales/en/FormGallery.json b/packages/client/public/locales/en/FormGallery.json index 4fbafa868d..f2c485ca6c 100644 --- a/packages/client/public/locales/en/FormGallery.json +++ b/packages/client/public/locales/en/FormGallery.json @@ -10,8 +10,11 @@ "FormsByType": "Forms by type", "PopularCompilations": "Popular Compilations", + "EmptyFormGalleryScreenDescription": "No results matching your query could be found", + "Free": "Free", "SuggestChanges": "Suggest changes", + "SubmitToGalleryBlockHeader": "ONLYOFFICE Form Gallery", "SubmitToGalleryBlockBody": "Submit your templates to share them with the ONLYOFFICE community.", "SubmitToGalleryDialogMainInfo": "Submit your form to the public gallery to let others use it in their work. Once the form passes moderation, you will be notified and rewarded for your contribution.", From aea9999c2b93430160d3bff5488b579c40aa2c41 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Sun, 24 Sep 2023 02:32:01 +0300 Subject: [PATCH 054/334] opmizied reloading --- .../components/Article/MainButton/index.js | 5 +- .../CategoryFilter/DesktopView/SubList.js | 2 - .../MobileView/CategorySubList.js | 6 +-- .../src/pages/FormGallery/Filter/index.js | 30 ----------- .../client/src/pages/FormGallery/Header.js | 22 +++----- .../client/src/pages/FormGallery/index.js | 53 ++++++++++++++----- packages/client/src/store/OformsStore.js | 16 +++--- 7 files changed, 62 insertions(+), 72 deletions(-) diff --git a/packages/client/src/components/Article/MainButton/index.js b/packages/client/src/components/Article/MainButton/index.js index 85674cce20..12e234993f 100644 --- a/packages/client/src/components/Article/MainButton/index.js +++ b/packages/client/src/components/Article/MainButton/index.js @@ -109,6 +109,7 @@ const ArticleMainButtonContent = (props) => { isRoomsFolder, isArchiveFolder, + setOformFromFolderId, oformsFilter, enablePlugins, @@ -208,6 +209,7 @@ const ArticleMainButtonContent = (props) => { const initOformFilter = ( oformsFilter || oformsFilter.getDefault() ).toUrlParams(); + setOformFromFolderId(currentFolderId); navigate(`/form-gallery/${currentFolderId}/filter?${initOformFilter}`); }; @@ -594,7 +596,7 @@ export default inject( const { isAdmin, isOwner } = auth.userStore.user; const { isGracePeriod } = auth.currentTariffStatusStore; - const { oformsFilter } = oformsStore; + const { setOformFromFolderId, oformsFilter } = oformsStore; return { isGracePeriod, @@ -620,6 +622,7 @@ export default inject( currentFolderId, + setOformFromFolderId, oformsFilter, enablePlugins, diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js index 0837d1b87f..f529f8953b 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js @@ -79,8 +79,6 @@ const SubList = ({ }; export default inject(({ oformsStore }) => ({ - getOforms: oformsStore.getOforms, - oformsFilter: oformsStore.oformsFilter, filterOformsByCategory: oformsStore.filterOformsByCategory, setOformsCurrentCategory: oformsStore.setOformsCurrentCategory, }))(withTranslation(["FormGallery", "Common"])(SubList)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js index 5e18f02e5e..946efce653 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js @@ -28,11 +28,7 @@ const CategorySubList = ({ )); }; -export default inject(({ auth, oformsStore }) => ({ - theme: auth.settingsStore.theme, - - getOforms: oformsStore.getOforms, - oformsFilter: oformsStore.oformsFilter, +export default inject(({ oformsStore }) => ({ filterOformsByCategory: oformsStore.filterOformsByCategory, setOformsCurrentCategory: oformsStore.setOformsCurrentCategory, }))(withTranslation(["FormGallery", "Common"])(CategorySubList)); diff --git a/packages/client/src/pages/FormGallery/Filter/index.js b/packages/client/src/pages/FormGallery/Filter/index.js index 4df14c2e87..b3bb17e747 100644 --- a/packages/client/src/pages/FormGallery/Filter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/index.js @@ -47,36 +47,6 @@ export const StyledFilter = styled.div` `; const SectionFilterContent = ({ oformsFilter, setOformsFilter }) => { - const location = useLocation(); - const navigate = useNavigate(); - - const [isInitLoading, setIsInitLoading] = useState(true); - - useEffect(() => { - const firstLoadFilter = OformsFilter.getFilter(location); - - if (!firstLoadFilter.locale) { - firstLoadFilter.locale = getDefaultOformLocale(); - setOformsFilter(firstLoadFilter); - navigate(`${location.pathname}?${oformsFilter.toUrlParams()}`); - } else setOformsFilter(firstLoadFilter); - - setIsInitLoading(false); - }, []); - - useEffect(() => { - if (isInitLoading) return; - navigate(`${location.pathname}?${oformsFilter.toUrlParams()}`); - }, [ - oformsFilter, - oformsFilter.categorizeBy, - oformsFilter.categoryId, - oformsFilter.locale, - oformsFilter.search, - oformsFilter.sortBy, - oformsFilter.sortOrder, - ]); - return (
diff --git a/packages/client/src/pages/FormGallery/Header.js b/packages/client/src/pages/FormGallery/Header.js index 99a9dd9695..65531fdb0d 100644 --- a/packages/client/src/pages/FormGallery/Header.js +++ b/packages/client/src/pages/FormGallery/Header.js @@ -30,7 +30,7 @@ const SectionHeaderContent = ({ t, canSubmitToFormGallery, - fromFolderId, + oformFromFolderId, setGallerySelected, categoryType, @@ -53,8 +53,8 @@ const SectionHeaderContent = ({ setGallerySelected(null); const filter = FilesFilter.getDefault(); - filter.folder = fromFolderId; - const url = getCategoryUrl(categoryType, fromFolderId); + filter.folder = oformFromFolderId; + const url = getCategoryUrl(categoryType, oformFromFolderId); const filterParamsStr = filter.toUrlParams(); navigate( @@ -68,21 +68,15 @@ const SectionHeaderContent = ({ const onViewAllTemplates = () => filterOformsByCategory("", ""); - const onToggleInfoPanel = () => setIsInfoPanelVisible(!isInfoPanelVisible); - - const onOpenSubmitToGalleryDialog = () => { + const onOpenSubmitToGalleryDialog = () => setSubmitToGalleryDialogVisible(true); - }; - useEffect(() => { - if (currentCategory) return; - fetchCurrentCategory(); - }, [oformsFilter.categorizeBy, oformsFilter.categoryId]); + const onToggleInfoPanel = () => setIsInfoPanelVisible(!isInfoPanelVisible); useEffect(() => { (async () => { const prevFolder = - fromFolderId && (await api.files.getFolderInfo(fromFolderId)); + oformFromFolderId && (await api.files.getFolderInfo(oformFromFolderId)); const newCheckboxOptions = []; if (oformsFilter.categorizeBy && oformsFilter.categoryId) @@ -108,7 +102,7 @@ const SectionHeaderContent = ({ setCheckboxOptions(<>{newCheckboxOptions}); })(); - }, [fromFolderId, oformsFilter.categorizeBy, oformsFilter.categoryId]); + }, [oformFromFolderId, oformsFilter.categorizeBy, oformsFilter.categoryId]); return ( @@ -168,7 +162,7 @@ export default inject( return { categoryType: filesStore.categoryType, - fromFolderId: oformsStore.fromFolderId, + oformFromFolderId: oformsStore.oformFromFolderId, currentCategory: oformsStore.currentCategory, fetchCurrentCategory: oformsStore.fetchCurrentCategory, diff --git a/packages/client/src/pages/FormGallery/index.js b/packages/client/src/pages/FormGallery/index.js index 67aaf98e79..23ac8a84fa 100644 --- a/packages/client/src/pages/FormGallery/index.js +++ b/packages/client/src/pages/FormGallery/index.js @@ -1,4 +1,4 @@ -import React, { useEffect } from "react"; +import React, { useState, useEffect } from "react"; import Section from "@docspace/common/components/Section"; import { observer, inject } from "mobx-react"; import { useLocation, useNavigate, useParams } from "react-router-dom"; @@ -14,7 +14,12 @@ import MediaViewer from "./MediaViewer"; import { CategoryType } from "@docspace/client/src/helpers/constants"; const FormGallery = ({ + currentCategory, + fetchCurrentCategory, + filterOformsByLocale, oformsFilter, + setOformsFilter, + oformFromFolderId, getOforms, setOformFiles, setOformFromFolderId, @@ -23,25 +28,36 @@ const FormGallery = ({ const navigate = useNavigate(); const { fromFolderId } = useParams(); - useEffect(() => { - const firstLoadFilter = OformsFilter.getFilter(location); - getOforms(firstLoadFilter); - return () => setOformFiles(null); - }, []); + const [isInitLoading, setIsInitLoading] = useState(true); useEffect(() => { - if (fromFolderId) { - setOformFromFolderId(fromFolderId); - } else { - setOformFromFolderId(CategoryType.SharedRoom); + if (!isInitLoading && location.search !== `?${oformsFilter.toUrlParams()}`) + navigate(`${location.pathname}?${oformsFilter.toUrlParams()}`); + }, [oformsFilter]); + + useEffect(() => { + if (!currentCategory) fetchCurrentCategory(); + }, [oformsFilter]); + + useEffect(() => { + if (fromFolderId) setOformFromFolderId(fromFolderId); + else navigate( - `/form-gallery/${ - CategoryType.SharedRoom - }/filter?${oformsFilter.toUrlParams()}` + `/form-gallery/${oformFromFolderId}/filter?${oformsFilter.toUrlParams()}` ); - } }, [fromFolderId]); + useEffect(() => { + const firstLoadFilter = OformsFilter.getFilter(location); + if (!firstLoadFilter.locale) + firstLoadFilter.locale = getDefaultOformLocale(); + + setOformsFilter(firstLoadFilter); + getOforms(firstLoadFilter); + + setIsInitLoading(false); + }, []); + return ( <>
({ + currentCategory: oformsStore.currentCategory, + fetchCurrentCategory: oformsStore.fetchCurrentCategory, + oformsFilter: oformsStore.oformsFilter, + setOformsFilter: oformsStore.setOformsFilter, + + filterOformsByLocale: oformsStore.filterOformsByLocale, + + oformFromFolderId: oformsStore.oformFromFolderId, + getOforms: oformsStore.getOforms, setOformFiles: oformsStore.setOformFiles, setOformFromFolderId: oformsStore.setOformFromFolderId, diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index 22d8d34c2c..668556da5e 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -24,7 +24,7 @@ class OformsStore { oformsFilter = OformsFilter.getDefault(); currentCategory = null; - fromFolderId = CategoryType.Personal; + oformFromFolderId = CategoryType.SharedRoom; oformsIsLoading = false; gallerySelected = null; @@ -46,9 +46,9 @@ class OformsStore { setOformsCurrentCategory = (currentCategory) => (this.currentCategory = currentCategory); - setOformFromFolderId = (fromFolderId) => { - if (!fromFolderId) return; - this.fromFolderId = fromFolderId; + setOformFromFolderId = (oformFromFolderId) => { + if (!oformFromFolderId) return; + this.oformFromFolderId = oformFromFolderId; }; setOformsIsLoading = (oformsIsLoading) => @@ -98,7 +98,7 @@ class OformsStore { onClick: () => { this.authStore.infoPanelStore.setIsVisible(false); const filesFilter = FilesFilter.getDefault(); - filesFilter.folder = this.fromFolderId; + filesFilter.folder = this.oformFromFolderId; const filterUrlParams = filesFilter.toUrlParams(); const url = getCategoryUrl( CategoryType.Personal, @@ -124,7 +124,11 @@ class OformsStore { this.mediaViewerDataStore.saveFirstUrl( `${window.DocSpace.location.pathname}${window.DocSpace.location.search}` ); - this.mediaViewerDataStore.changeUrl(item.id, true, this.fromFolderId); + this.mediaViewerDataStore.changeUrl( + item.id, + true, + this.oformFromFolderId + ); }, }, { From 04e48b579966144fae84cfb3755782b0e9388d6c Mon Sep 17 00:00:00 2001 From: mushka-n Date: Sun, 24 Sep 2023 03:35:25 +0300 Subject: [PATCH 055/334] fixed undefined fromFolderId --- packages/client/src/pages/FormGallery/index.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/client/src/pages/FormGallery/index.js b/packages/client/src/pages/FormGallery/index.js index 23ac8a84fa..ec866b716e 100644 --- a/packages/client/src/pages/FormGallery/index.js +++ b/packages/client/src/pages/FormGallery/index.js @@ -41,10 +41,13 @@ const FormGallery = ({ useEffect(() => { if (fromFolderId) setOformFromFolderId(fromFolderId); - else + else { + const sharedRoomId = CategoryType.SharedRoom; + setOformFromFolderId(sharedRoomId); navigate( - `/form-gallery/${oformFromFolderId}/filter?${oformsFilter.toUrlParams()}` + `/form-gallery/${sharedRoomId}/filter?${oformsFilter.toUrlParams()}` ); + } }, [fromFolderId]); useEffect(() => { From 75c7ff6a045e7ee28939856dc2e7e7a23fde1be4 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Mon, 25 Sep 2023 13:20:53 +0300 Subject: [PATCH 056/334] updated and implemented media viewer for oforms --- .../pages/FormGallery/MediaViewer/index.js | 183 ++- .../TilesView/sub-components/Tile.js | 26 +- .../client/src/pages/FormGallery/index.js | 7 +- .../src/pages/Home/MediaViewer/index.js | 2 +- .../client/src/store/ContextOptionsStore.js | 90 +- .../src/store/MediaFormViewerDataStore.js | 118 ++ .../client/src/store/MediaViewerDataStore.js | 2 + packages/client/src/store/OformsStore.js | 17 +- packages/client/src/store/index.js | 15 +- .../MediaViewer/MediaViewer.props.ts | 5 + .../MediaViewer/helpers/contextModel.ts | 34 + .../common/components/MediaViewer/index.tsx | 18 +- .../sub-components/OformViewer/index.tsx | 1042 +++++++++++++++++ .../sub-components/Viewer/Viewer.props.ts | 1 + .../sub-components/Viewer/index.tsx | 27 +- .../ViewerWrapper/ViewerWrapper.props.ts | 1 + .../sub-components/ViewerWrapper/index.tsx | 3 +- .../components/MediaViewer/types/index.ts | 2 +- 18 files changed, 1450 insertions(+), 143 deletions(-) create mode 100644 packages/client/src/store/MediaFormViewerDataStore.js create mode 100644 packages/common/components/MediaViewer/sub-components/OformViewer/index.tsx diff --git a/packages/client/src/pages/FormGallery/MediaViewer/index.js b/packages/client/src/pages/FormGallery/MediaViewer/index.js index 5feb26d385..3cf7220cf0 100644 --- a/packages/client/src/pages/FormGallery/MediaViewer/index.js +++ b/packages/client/src/pages/FormGallery/MediaViewer/index.js @@ -7,57 +7,36 @@ import MediaViewer from "@docspace/common/components/MediaViewer"; const FilesMediaViewer = ({ t, + files, playlist, + currentPostionIndex, visible, currentMediaFileId, - deleteItemAction, + setMediaViewerData, - setRemoveMediaItem, userAccess, - deleteDialogVisible, - previewFile, - fetchFiles, - setIsLoading, - - setToPreviewFile, - setScrollToItem, setCurrentId, - fromFolderId, + oformFromFolderId, + + onCreateOform, + onSuggestOformChanges, setBufferSelection, archiveRoomsId, - - onShowInfoPanel, - onClickDownload, - - onClickLinkEdit, - onPreviewClick, - onCopyLink, - onClickRename, - onClickDelete, - onMoveAction, - onCopyAction, getIcon, - onDuplicate, extsImagePreviewed, extsMediaPreviewed, - setIsPreview, isPreview, nextMedia, prevMedia, resetUrl, getFirstUrl, firstLoad, - setSelection, - activeFiles, - activeFolders, - onClickDownloadAs, - someDialogIsOpen, }) => { const navigate = useNavigate(); const location = useLocation(); @@ -73,7 +52,7 @@ const FilesMediaViewer = ({ }; const onChangeUrl = (id) => { - const url = `/form-gallery/${fromFolderId}/#preview/${id}`; + const url = `/form-gallery/${oformFromFolderId}/#preview/${id}`; setCurrentId(id); navigate(url); }; @@ -84,13 +63,7 @@ const FilesMediaViewer = ({ const onMediaViewerClose = (e) => { if (isPreview) { - setIsPreview(false); resetUrl(); - if (previewFile) { - setScrollToItem({ id: previewFile.id, type: "file" }); - setBufferSelection(previewFile); - } - setToPreviewFile(null); } setMediaViewerData({ visible: false, id: null }); @@ -123,17 +96,6 @@ const FilesMediaViewer = ({ } }, []); - useEffect(() => { - if (visible) setSelection([]); - }, [visible]); - - useEffect(() => { - if (previewFile) - fetchFiles(previewFile.folderId).finally(() => { - setIsLoading(false); - }); - }, [previewFile]); - useEffect(() => { window.addEventListener("popstate", onButtonBackHandler); return () => window.removeEventListener("popstate", onButtonBackHandler); @@ -143,32 +105,34 @@ const FilesMediaViewer = ({ visible && ( {}} archiveRoomsId={archiveRoomsId} files={files} - onClickDownload={onClickDownload} - onShowInfoPanel={onShowInfoPanel} - onClickDelete={onClickDelete} - onClickRename={onClickRename} - onMoveAction={onMoveAction} - onCopyAction={onCopyAction} - onDuplicate={onDuplicate} - onClickLinkEdit={onClickLinkEdit} - onPreviewClick={onPreviewClick} - onCopyLink={onCopyLink} - onClickDownloadAs={onClickDownloadAs} + onClickCreateOform={onCreateOform} + onClickSuggestOformChanges={onSuggestOformChanges} + onClickDownload={() => {}} + onShowInfoPanel={() => {}} + onClickDelete={() => {}} + onClickRename={() => {}} + onMoveAction={() => {}} + onCopyAction={() => {}} + onDuplicate={() => {}} + onClickLinkEdit={() => {}} + onPreviewClick={() => {}} + onCopyLink={() => {}} + onClickDownloadAs={() => {}} onClose={onMediaViewerClose} getIcon={getIcon} onEmptyPlaylistError={onMediaViewerClose} - deleteDialogVisible={deleteDialogVisible} + deleteDialogVisible={false} extsMediaPreviewed={extsMediaPreviewed} extsImagePreviewed={extsImagePreviewed} isPreviewFile={firstLoad} @@ -184,13 +148,12 @@ export default inject( ({ oformsStore, filesStore, - mediaViewerDataStore, - filesActionsStore, + mediaFormViewerDataStore, settingsStore, dialogsStore, treeFoldersStore, - contextOptionsStore, clientLoadingStore, + contextOptionsStore, }) => { const { firstLoad, setIsSectionFilterLoading } = clientLoadingStore; @@ -199,18 +162,13 @@ export default inject( }; const { - files, + // files, userAccess, - fetchFiles, setScrollToItem, setBufferSelection, - setIsPreview, isPreview, resetUrl, - setSelection, setAlreadyFetchingRooms, - activeFiles, - activeFolders, } = filesStore; const { @@ -220,36 +178,59 @@ export default inject( setMediaViewerData, getFirstUrl, playlist, - previewFile, - setToPreviewFile, setCurrentId, nextMedia, prevMedia, - } = mediaViewerDataStore; + } = mediaFormViewerDataStore; + + const { onCreateOform, onSuggestOformChanges } = contextOptionsStore; - const { deleteItemAction } = filesActionsStore; const { getIcon, extsImagePreviewed, extsMediaPreviewed } = settingsStore; const { isFavoritesFolder, archiveRoomsId } = treeFoldersStore; - const { - onClickFavorite, - onShowInfoPanel, - onClickDownloadAs, - onClickDownload, - onClickRename, - onClickDelete, - onMoveAction, - onCopyAction, - onDuplicate, - onClickLinkEdit, - onPreviewClick, - onCopyLink, - } = contextOptionsStore; + const { oformFromFolderId } = oformsStore; - const { fromFolderId } = oformsStore; + const oformFiles = oformsStore.oformFiles; + const files = !oformFiles + ? [] + : oformFiles.map((oform) => ({ + id: oform.id, + title: oform.attributes.name_form, + security: { + Read: true, + Comment: false, + FillForms: false, + Review: false, + Edit: false, + Delete: false, + CustomFilter: false, + Rename: false, + ReadHistory: false, + Lock: false, + EditHistory: false, + Copy: false, + Move: false, + Duplicate: false, + SubmitToFormGallery: false, + Download: false, + Convert: false, + }, + viewAccessability: { + ImageView: true, + MediaView: false, + WebView: false, + WebEdit: false, + WebReview: false, + WebCustomFilterEditing: false, + WebRestrictedEditing: false, + WebComment: false, + CoAuhtoring: false, + Convert: false, + }, + })); return { - fromFolderId, + oformFromFolderId, files, playlist, currentPostionIndex, @@ -258,19 +239,14 @@ export default inject( userAccess, visible: playlist.length > 0 && visible, currentMediaFileId, - deleteItemAction, setMediaViewerData, extsImagePreviewed, extsMediaPreviewed, - setRemoveMediaItem: dialogsStore.setRemoveMediaItem, - deleteDialogVisible: dialogsStore.deleteDialogVisible, someDialogIsOpen: dialogsStore.someDialogIsOpen, - fetchFiles, - previewFile, setIsLoading, firstLoad, - setToPreviewFile, - setIsPreview, + onCreateOform, + onSuggestOformChanges, resetUrl, isPreview, setScrollToItem, @@ -278,24 +254,9 @@ export default inject( setBufferSelection, setAlreadyFetchingRooms, isFavoritesFolder, - onClickFavorite, - onClickDownloadAs, - onClickDelete, - onClickDownload, - onShowInfoPanel, - onClickLinkEdit, - onPreviewClick, - onCopyLink, - onClickRename, - onMoveAction, getIcon, - onCopyAction, - onDuplicate, archiveRoomsId, - setSelection, getFirstUrl, - activeFiles, - activeFolders, }; } )(withTranslation(["Files", "Translations"])(observer(FilesMediaViewer))); diff --git a/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js b/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js index e352f341f2..bf61aa58cb 100644 --- a/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js +++ b/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js @@ -24,7 +24,9 @@ const Tile = ({ t, thumbnailClick, item, - getFormContextOptions, + + onCreateOform, + getFormGalleryContextOptions, setIsInfoPanelVisible, categoryType, @@ -47,21 +49,14 @@ const Tile = ({ const previewSrc = item?.attributes.card_prewiew.data?.attributes.url; const previewLoader = () =>
; - const formContextOptions = getFormContextOptions(t, item, navigate); - const onSelectForm = () => setGallerySelected(item); - const getContextModel = () => formContextOptions; + const onCreateForm = () => onCreateOform(navigate); - const onCreateForm = () => { - const [createFormOption] = formContextOptions.filter( - (contextOption) => contextOption.key === "create" - ); - createFormOption?.onClick && createFormOption.onClick(); - }; + const getContextModel = () => getFormGalleryContextOptions(item, t, navigate); const getOptions = () => - formContextOptions.map((contextOption) => contextOption.key); + getFormGalleryContextOptions(item, t, navigate).map((item) => item.key); const onContextMenu = (e) => { tileContextClick && tileContextClick(); @@ -151,7 +146,10 @@ Tile.defaultProps = { }; export default inject( - ({ filesStore, settingsStore, auth, oformsStore }, { item }) => { + ( + { filesStore, settingsStore, auth, oformsStore, contextOptionsStore }, + { item } + ) => { const { categoryType } = filesStore; const { gallerySelected, setGallerySelected, getFormContextOptions } = oformsStore; @@ -160,10 +158,14 @@ export default inject( const isSelected = item.id === gallerySelected?.id; + const { getFormGalleryContextOptions, onCreateOform } = contextOptionsStore; + return { isSelected, setGallerySelected, getFormContextOptions, + onCreateOform, + getFormGalleryContextOptions, getIcon, setIsInfoPanelVisible: setIsVisible, isInfoPanelVisible: isVisible, diff --git a/packages/client/src/pages/FormGallery/index.js b/packages/client/src/pages/FormGallery/index.js index ec866b716e..e67e7bab16 100644 --- a/packages/client/src/pages/FormGallery/index.js +++ b/packages/client/src/pages/FormGallery/index.js @@ -31,8 +31,13 @@ const FormGallery = ({ const [isInitLoading, setIsInitLoading] = useState(true); useEffect(() => { - if (!isInitLoading && location.search !== `?${oformsFilter.toUrlParams()}`) + if ( + !isInitLoading && + location.search !== `?${oformsFilter.toUrlParams()}` + ) { + console.log("NAVIGATE "); navigate(`${location.pathname}?${oformsFilter.toUrlParams()}`); + } }, [oformsFilter]); useEffect(() => { diff --git a/packages/client/src/pages/Home/MediaViewer/index.js b/packages/client/src/pages/Home/MediaViewer/index.js index 53a2e6bbef..6261bce43c 100644 --- a/packages/client/src/pages/Home/MediaViewer/index.js +++ b/packages/client/src/pages/Home/MediaViewer/index.js @@ -295,7 +295,7 @@ export default inject( onPreviewClick, onCopyLink, } = contextOptionsStore; - + console.log(files); return { files, playlist, diff --git a/packages/client/src/store/ContextOptionsStore.js b/packages/client/src/store/ContextOptionsStore.js index 142aeca5b6..efaff8efb7 100644 --- a/packages/client/src/store/ContextOptionsStore.js +++ b/packages/client/src/store/ContextOptionsStore.js @@ -35,6 +35,7 @@ import MailReactSvgUrl from "PUBLIC_DIR/images/mail.react.svg?url"; import RoomArchiveSvgUrl from "PUBLIC_DIR/images/room.archive.svg?url"; import LeaveRoomSvgUrl from "PUBLIC_DIR/images/logout.react.svg?url"; import CatalogRoomsReactSvgUrl from "PUBLIC_DIR/images/catalog.rooms.react.svg?url"; +import { getCategoryUrl } from "@docspace/client/src/helpers/utils"; import { makeAutoObservable } from "mobx"; import copy from "copy-to-clipboard"; @@ -54,6 +55,7 @@ import { connectedCloudsTypeTitleTranslation } from "@docspace/client/src/helper import { getOAuthToken } from "@docspace/common/utils"; import api from "@docspace/common/api"; import { FolderType } from "@docspace/common/constants"; +import FilesFilter from "@docspace/common/api/files/filter"; const LOADER_TIMER = 500; let loadingTime; @@ -65,12 +67,14 @@ class ContextOptionsStore { filesActionsStore; filesStore; mediaViewerDataStore; + mediaFormViewerDataStore; treeFoldersStore; uploadDataStore; versionHistoryStore; settingsStore; selectedFolderStore; publicRoomStore; + oformsStore; linksIsLoading = false; @@ -80,12 +84,14 @@ class ContextOptionsStore { filesActionsStore, filesStore, mediaViewerDataStore, + mediaFormViewerDataStore, treeFoldersStore, uploadDataStore, versionHistoryStore, settingsStore, selectedFolderStore, - publicRoomStore + publicRoomStore, + oformsStore ) { makeAutoObservable(this); this.authStore = authStore; @@ -93,12 +99,14 @@ class ContextOptionsStore { this.filesActionsStore = filesActionsStore; this.filesStore = filesStore; this.mediaViewerDataStore = mediaViewerDataStore; + this.mediaFormViewerDataStore = mediaFormViewerDataStore; this.treeFoldersStore = treeFoldersStore; this.uploadDataStore = uploadDataStore; this.versionHistoryStore = versionHistoryStore; this.settingsStore = settingsStore; this.selectedFolderStore = selectedFolderStore; this.publicRoomStore = publicRoomStore; + this.oformsStore = oformsStore; } onOpenFolder = (item) => { @@ -757,6 +765,85 @@ class ContextOptionsStore { } }; + onCreateOform = (navigate) => { + this.authStore.infoPanelStore.setIsVisible(false); + const filesFilter = FilesFilter.getDefault(); + filesFilter.folder = this.oformsStore.oformFromFolderId; + const filterUrlParams = filesFilter.toUrlParams(); + const url = getCategoryUrl( + this.filesStore.categoryType, + filterUrlParams.folder + ); + + this.mediaFormViewerDataStore.removeFirstUrl(); + this.mediaFormViewerDataStore.setMediaViewerData({ + visible: false, + id: null, + }); + + navigate( + combineUrl( + window.DocSpaceConfig?.proxy?.url, + config.homepage, + `${url}?${filterUrlParams}` + ) + ); + }; + + onPreviewOform = (item) => { + this.mediaFormViewerDataStore.setMediaViewerData({ + visible: true, + id: item.id, + }); + this.mediaFormViewerDataStore.saveFirstUrl( + `${window.DocSpace.location.pathname}${window.DocSpace.location.search}` + ); + this.mediaFormViewerDataStore.changeUrl(item.id); + }; + + onShowOformTemplateInfo = (item) => { + this.authStore.infoPanelStore.setIsVisible(true); + this.oformsStore.setGallerySelected(item); + }; + + onSuggestOformChanges = (item) => { + const formTitle = item.attributes ? item.attributes.name_form : item.title; + + window.location = `mailto:marketing@onlyoffice.com + ?subject=Suggesting changes for ${formTitle} + &body=Suggesting changes for ${formTitle}. + `; + }; + + getFormGalleryContextOptions = (item, t, navigate) => { + return [ + { + key: "create", + label: t("Common:Create"), + onClick: () => this.onCreateOform(navigate), + }, + { + key: "preview", + label: t("Common:Preview"), + onClick: () => this.onPreviewOform(item), + }, + { + key: "template-info", + label: t("FormGallery:TemplateInfo"), + onClick: () => this.onShowOformTemplateInfo(item), + }, + { + key: "separator", + isSeparator: true, + }, + { + key: "suggest-changes", + label: t("FormGallery:SuggestChanges"), + onClick: () => this.onSuggestOformChanges(item), + }, + ]; + }; + getRoomsRootContextOptions = (item, t) => { const { id, rootFolderId } = this.selectedFolderStore; const isRootRoom = item.isRoom && rootFolderId === id; @@ -811,6 +898,7 @@ class ContextOptionsStore { return { pinOptions, muteOptions }; }; + getFilesContextOptions = (item, t, isInfoPanel) => { const { contextOptions, isEditing } = item; diff --git a/packages/client/src/store/MediaFormViewerDataStore.js b/packages/client/src/store/MediaFormViewerDataStore.js new file mode 100644 index 0000000000..227395150d --- /dev/null +++ b/packages/client/src/store/MediaFormViewerDataStore.js @@ -0,0 +1,118 @@ +import { makeAutoObservable, runInAction } from "mobx"; +import { + isNullOrUndefined, + findNearestIndex, + isVideo, +} from "@docspace/common/components/MediaViewer/helpers"; +import { thumbnailStatuses } from "SRC_DIR/helpers/filesConstants"; + +const FirstUrlKey = "isFirstUrl"; + +class MediaFormViewerDataStore { + oformsStore; + settingsStore; + + id = null; + visible = false; + currentItem = null; + prevPostionIndex = 0; + + constructor(oformsStore, settingsStore) { + makeAutoObservable(this); + this.oformsStore = oformsStore; + this.settingsStore = settingsStore; + } + + setCurrentId = (id) => (this.id = id); + + setCurrentItem = (item) => (this.currentItem = item); + + setMediaViewerData = (mediaData) => { + this.id = mediaData.id; + this.visible = mediaData.visible; + + if (!mediaData.visible) this.setCurrentItem(null); + }; + + saveFirstUrl = (url) => localStorage.setItem(FirstUrlKey, url); + + getFirstUrl = () => localStorage.getItem(FirstUrlKey); + + removeFirstUrl = () => localStorage.removeItem(FirstUrlKey); + + changeUrl = (id) => { + const url = `/form-gallery/${this.oformsStore.oformFromFolderId}/#preview/${id}`; + window.DocSpace.navigate(url); + }; + + nextMedia = () => { + const { oformFiles, setGallerySelected } = this.oformsStore; + + const postionIndex = (this.currentPostionIndex + 1) % this.playlist.length; + if (postionIndex === 0) return; + + const currentFileId = this.playlist[postionIndex].fileId; + const targetFile = oformFiles.find((item) => item.id === currentFileId); + + if (!isNullOrUndefined(targetFile)) setGallerySelected(targetFile); + + const fileId = this.playlist[postionIndex].fileId; + this.setCurrentId(fileId); + this.changeUrl(fileId); + }; + + prevMedia = () => { + const { oformFiles, setGallerySelected } = this.oformsStore; + + const currentPlaylistPos = this.currentPostionIndex - 1; + if (currentPlaylistPos === -1) return; + + const currentFileId = this.playlist[currentPlaylistPos].fileId; + const targetFile = oformFiles.find((item) => item.id === currentFileId); + if (!isNullOrUndefined(targetFile)) setGallerySelected(targetFile); + + const fileId = this.playlist[currentPlaylistPos].fileId; + this.setCurrentId(fileId); + this.changeUrl(fileId); + }; + + get currentPostionIndex() { + if (this.playlist.length === 0) return 0; + + let index = this.playlist.find((file) => file.fileId === this.id)?.id; + + if (isNullOrUndefined(index)) + index = findNearestIndex(this.playlist, this.prevPostionIndex); + + runInAction(() => { + this.prevPostionIndex = index; + }); + + return index; + } + + get playlist() { + const { oformFiles } = this.oformsStore; + + if (!oformFiles) return []; + + const playlist = oformFiles.map((oform, index) => ({ + id: index, + fileId: oform.id, + src: oform.attributes.template_image.data.attributes.formats.large?.url, + title: oform.attributes.name_form, + fileExst: + oform.attributes.template_image.data.attributes.formats.large?.ext, + fileStatus: 0, + canShare: false, + version: 1, + thumbnailUrl: + oform.attributes.template_image.data.attributes.formats.large?.url, + })); + + console.log(playlist); + return playlist; + } +} + +export default MediaFormViewerDataStore; diff --git a/packages/client/src/store/MediaViewerDataStore.js b/packages/client/src/store/MediaViewerDataStore.js index a78f01e1eb..570db9df6e 100644 --- a/packages/client/src/store/MediaViewerDataStore.js +++ b/packages/client/src/store/MediaViewerDataStore.js @@ -218,6 +218,8 @@ class MediaViewerDataStore { this.filesStore.createThumbnails(itemsWithoutThumb); } + console.log(playlist); + return playlist; } } diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index 668556da5e..fb0656057a 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -18,7 +18,7 @@ import { CategoryType } from "@docspace/client/src/helpers/constants"; class OformsStore { authStore; - mediaViewerDataStore; + mediaFormViewerDataStore; oformFiles = null; oformsFilter = OformsFilter.getDefault(); @@ -33,9 +33,9 @@ class OformsStore { "submitToGalleryTileIsHidden" ); - constructor(authStore, mediaViewerDataStore) { + constructor(authStore, mediaFormViewerDataStore) { this.authStore = authStore; - this.mediaViewerDataStore = mediaViewerDataStore; + this.mediaFormViewerDataStore = mediaFormViewerDataStore; makeAutoObservable(this); } @@ -68,6 +68,7 @@ class OformsStore { filter.total = paginationData.total; } + console.log(oformData?.data?.data); runInAction(() => { this.setOformsFilter(filter); this.setOformFiles(oformData?.data?.data ?? []); @@ -117,18 +118,14 @@ class OformsStore { key: "preview", label: t("Common:Preview"), onClick: () => { - this.mediaViewerDataStore.setMediaViewerData({ + this.mediaFormViewerDataStore.setMediaViewerData({ visible: true, id: item.id, }); - this.mediaViewerDataStore.saveFirstUrl( + this.mediaFormViewerDataStore.saveFirstUrl( `${window.DocSpace.location.pathname}${window.DocSpace.location.search}` ); - this.mediaViewerDataStore.changeUrl( - item.id, - true, - this.oformFromFolderId - ); + this.mediaFormViewerDataStore.changeUrl(item.id); }, }, { diff --git a/packages/client/src/store/index.js b/packages/client/src/store/index.js index 41bc2e4016..2b71392a40 100644 --- a/packages/client/src/store/index.js +++ b/packages/client/src/store/index.js @@ -37,6 +37,7 @@ import PublicRoomStore from "./PublicRoomStore"; import WebhooksStore from "./WebhooksStore"; import ClientLoadingStore from "./ClientLoadingStore"; +import MediaFormViewerDataStore from "./MediaFormViewerDataStore"; const selectedFolderStore = new SelectedFolderStore(authStore.settingsStore); @@ -82,7 +83,14 @@ const mediaViewerDataStore = new MediaViewerDataStore( publicRoomStore ); -const oformsStore = new OformsStore(authStore, mediaViewerDataStore); +const mediaFormViewerDataStore = new MediaFormViewerDataStore( + filesStore, + settingsStore, + publicRoomStore +); + +const oformsStore = new OformsStore(authStore, mediaFormViewerDataStore); +mediaFormViewerDataStore.oformsStore = oformsStore; const secondaryProgressDataStore = new SecondaryProgressDataStore(); const primaryProgressDataStore = new PrimaryProgressDataStore(); @@ -134,12 +142,14 @@ const contextOptionsStore = new ContextOptionsStore( filesActionsStore, filesStore, mediaViewerDataStore, + mediaFormViewerDataStore, treeFoldersStore, uploadDataStore, versionHistoryStore, settingsStore, selectedFolderStore, - publicRoomStore + publicRoomStore, + oformsStore ); const hotkeyStore = new HotkeyStore( @@ -201,6 +211,7 @@ const store = { settingsStore, mediaViewerDataStore, + mediaFormViewerDataStore, versionHistoryStore, uploadDataStore, dialogsStore, diff --git a/packages/common/components/MediaViewer/MediaViewer.props.ts b/packages/common/components/MediaViewer/MediaViewer.props.ts index 7cef7c1c6b..0998470ecb 100644 --- a/packages/common/components/MediaViewer/MediaViewer.props.ts +++ b/packages/common/components/MediaViewer/MediaViewer.props.ts @@ -1,3 +1,4 @@ +import { NavigateFunction } from "react-router"; import { ContextMenuAction, IFile, @@ -9,6 +10,8 @@ import { export interface MediaViewerProps { t: TranslationType; + isFormGalleryViewer?: boolean; + userAccess: boolean; currentFileId: NumberOrString; @@ -50,6 +53,8 @@ export interface MediaViewerProps { onClickLinkEdit: OmitSecondArg; onPreviewClick: OmitSecondArg; onCopyLink: ContextMenuAction; + onClickCreateOform: (navigate: NavigateFunction) => {}; + onClickSuggestOformChanges: (item: any) => {}; nextMedia: VoidFunction; prevMedia: VoidFunction; diff --git a/packages/common/components/MediaViewer/helpers/contextModel.ts b/packages/common/components/MediaViewer/helpers/contextModel.ts index f41e464218..a92f3b17a1 100644 --- a/packages/common/components/MediaViewer/helpers/contextModel.ts +++ b/packages/common/components/MediaViewer/helpers/contextModel.ts @@ -17,6 +17,7 @@ import type { OmitSecondArg, TranslationType, } from "../types"; +import { NavigateFunction } from "react-router"; type Functions = { onClickDownloadAs: VoidFunction; @@ -32,6 +33,11 @@ type Functions = { onShowInfoPanel: OmitSecondArg; }; +type OformFunctions = { + onClickCreateOform: (navigate: NavigateFunction) => {}; + onClickSuggestOformChanges: (item: any) => {}; +}; + export const getPDFContextModel = ( t: TranslationType, item: IFile, @@ -123,6 +129,34 @@ export const getPDFContextModel = ( return options; }; +export const getOformContextModel = ( + t: TranslationType, + item: any, + navigate: NavigateFunction, + funcs: OformFunctions +) => { + const { onClickCreateOform, onClickSuggestOformChanges } = funcs; + + const options: ContextMenuModel[] = [ + { + id: "option_create_form", + key: "create", + label: t("Common:Create"), + onClick: () => onClickCreateOform(navigate), + disabled: false, + }, + { + id: "option_suggest-changes", + key: "suggest-changes", + label: t("FormGallery:SuggestChanges"), + onClick: () => onClickSuggestOformChanges(item), + disabled: false, + }, + ]; + + return options; +}; + export const getMobileMediaContextModel = ( t: TranslationType, targetFile: IFile, diff --git a/packages/common/components/MediaViewer/index.tsx b/packages/common/components/MediaViewer/index.tsx index d8c6cefc6e..c3a900a53e 100644 --- a/packages/common/components/MediaViewer/index.tsx +++ b/packages/common/components/MediaViewer/index.tsx @@ -22,10 +22,12 @@ import { getFileExtension } from "@docspace/common/utils"; import { getDesktopMediaContextModel, getMobileMediaContextModel, + getOformContextModel, getPDFContextModel, } from "./helpers/contextModel"; import { checkDialogsOpen } from "../../utils/checkDialogsOpen"; +import { useNavigate } from "react-router"; function MediaViewer({ playlistPos, @@ -33,6 +35,8 @@ function MediaViewer({ prevMedia, ...props }: MediaViewerProps): JSX.Element { + const navigate = useNavigate(); + const TiffXMLHttpRequestRef = useRef(); const [title, setTitle] = useState(""); @@ -155,6 +159,8 @@ function MediaViewer({ onCopyAction, onDuplicate, onCopyLink, + onClickCreateOform, + onClickSuggestOformChanges, } = props; if (!targetFile) return []; @@ -194,6 +200,12 @@ function MediaViewer({ onCopyLink, }); + if (props.isFormGalleryViewer) + return getOformContextModel(t, targetFile, navigate, { + onClickCreateOform, + onClickSuggestOformChanges, + }); + return isMobile ? model : isImage && !isMobile @@ -340,10 +352,11 @@ function MediaViewer({ const audioIcon = useMemo(() => props.getIcon(96, ext), [ext]); const headerIcon = useMemo(() => props.getIcon(24, ext), [ext]); - let isVideo = false; - let isAudio = false; let canOpen = true; let isImage = false; + let isVideo = false; + let isAudio = false; + let isForm = false; let isPdf = false; const archiveRoom = @@ -393,6 +406,7 @@ function MediaViewer({ isImage={isImage} isAudio={isAudio} isVideo={isVideo} + isForm={!!props.isFormGalleryViewer} isPdf={isPdf} isPreviewFile={props.isPreviewFile} onDownloadClick={onDownload} diff --git a/packages/common/components/MediaViewer/sub-components/OformViewer/index.tsx b/packages/common/components/MediaViewer/sub-components/OformViewer/index.tsx new file mode 100644 index 0000000000..3cb2bd3d39 --- /dev/null +++ b/packages/common/components/MediaViewer/sub-components/OformViewer/index.tsx @@ -0,0 +1,1042 @@ +import { useGesture } from "@use-gesture/react"; +import { isMobile, isDesktop } from "react-device-detect"; +import { useSpring, config } from "@react-spring/web"; +import React, { SyntheticEvent, useEffect, useRef, useState } from "react"; + +import indexedDBHelper from "../../../../utils/indexedDBHelper"; +import { IndexedDBStores } from "../../../../constants"; + +import ViewerLoader from "../ViewerLoader"; +import ImageViewerToolbar from "../ImageViewerToolbar"; + +import { + Image, + ImageViewerContainer, + ImageWrapper, +} from "../ImageViewer/ImageViewer.styled"; + +import ImageViewerProps from "../ImageViewer/ImageViewer.props"; +import { + ImperativeHandle, + ToolbarItemType, +} from "../ImageViewerToolbar/ImageViewerToolbar.props"; +import { ToolbarActionType, KeyboardEventKeys, compareTo } from "../../helpers"; +import PlayerMessageError from "../PlayerMessageError"; +import { checkDialogsOpen } from "../../../../utils/checkDialogsOpen"; + +const MaxScale = 5; +const MinScale = 0.5; +const DefaultSpeedScale = 0.5; +const RatioWheel = 400; + +type BoundsType = { + top: number; + bottom: number; + right: number; + left: number; +}; + +function OformViewer({ + src, + onPrev, + onNext, + onMask, + isFistImage, + isLastImage, + panelVisible, + generateContextMenu, + setIsOpenContextMenu, + resetToolbarVisibleTimer, + mobileDetails, + toolbar, + thumbnailSrc, + imageId, + version, + isTiff, + contextModel, + errorTitle, +}: ImageViewerProps) { + const imgRef = useRef(null); + const imgWrapperRef = useRef(null); + const containerRef = useRef(null); + + const unmountRef = useRef(false); + + const lastTapTimeRef = useRef(0); + const isDoubleTapRef = useRef(false); + const setTimeoutIDTapRef = useRef(); + const changeSourceTimeoutRef = useRef(); + const startAngleRef = useRef(0); + const toolbarRef = useRef(null); + + const [scale, setScale] = useState(1); + const [isError, setIsError] = useState(false); + const [isLoading, setIsLoading] = useState(false); + const [backgroundBlack, setBackgroundBlack] = useState(() => false); + + const [style, api] = useSpring(() => ({ + width: 0, + height: 0, + x: 0, + y: 0, + scale: 1, + rotate: 0, + opacity: 1, + })); + + useEffect(() => { + unmountRef.current = false; + + window.addEventListener("resize", resize); + + return () => { + setTimeoutIDTapRef.current && clearTimeout(setTimeoutIDTapRef.current); + window.removeEventListener("resize", resize); + unmountRef.current = true; + }; + }, []); + + useEffect(() => { + if (unmountRef.current || isTiff) return; + setIsLoading(true); + }, [src]); + + useEffect(() => { + document.addEventListener("keydown", onKeyDown); + + return () => { + document.removeEventListener("keydown", onKeyDown); + }; + }, []); + + const restartScaleAndSize = () => { + if (!imgRef.current || style.scale.isAnimating) return; + + const naturalWidth = imgRef.current.naturalWidth; + const naturalHeight = imgRef.current.naturalHeight; + + const imagePositionAndSize = getImagePositionAndSize( + naturalWidth, + naturalHeight + ); + + if (!imagePositionAndSize) return; + + const { x, y, width, height } = imagePositionAndSize; + + const ratio = 1 / style.scale.get(); + + const point = calculateAdjustImage({ x, y }, ratio); + + toolbarRef.current?.setPercentValue(1); + + api.start({ + ...point, + width, + height, + scale: 1, + }); + }; + + const changeSource = React.useCallback( + (src: any) => { + if (!window.DocSpaceConfig.imageThumbnails) return; + changeSourceTimeoutRef.current = setTimeout(() => { + if (imgRef.current && !unmountRef.current) { + if (!src) return; + + if (!isTiff) { + imgRef.current.src = URL.createObjectURL(src); + } else { + imgRef.current.src = src; + } + + setIsLoading(() => false); + } + }, 500); + }, + [src, isTiff, imageId] + ); + + React.useEffect(() => { + if (!window.DocSpaceConfig.imageThumbnails) return; + if (!thumbnailSrc) setIsLoading(true); + }, []); + + const loadImage = React.useCallback(async () => { + if (!src || !window.DocSpaceConfig.imageThumbnails) return; + + if (isTiff) { + return changeSource(src); + } + + const res = await fetch(src); + const blob = await res.blob(); + + indexedDBHelper.addItem(IndexedDBStores.images, { + id: imageId, + src: blob, + created: new Date(), + version, + }); + + changeSource(blob); + }, [src, imageId, version, isTiff, changeSource]); + + useEffect(() => { + changeSourceTimeoutRef.current && + clearTimeout(changeSourceTimeoutRef.current); + }, [src, version]); + + useEffect(() => { + if (!imageId || thumbnailSrc || !window.DocSpaceConfig.imageThumbnails) + return; + + indexedDBHelper.getItem(IndexedDBStores.images, imageId).then((result) => { + if (result && result.version === version) { + changeSource(result.src); + } else { + loadImage(); + } + }); + }, [src, imageId, version, isTiff, loadImage, changeSource, thumbnailSrc]); + + function resize() { + if (!imgRef.current || isLoading) return; + + const naturalWidth = imgRef.current.naturalWidth; + const naturalHeight = imgRef.current.naturalHeight; + + const imagePositionAndSize = getImagePositionAndSize( + naturalWidth, + naturalHeight + ); + if (imagePositionAndSize) { + api.set(imagePositionAndSize); + } + } + + function getImagePositionAndSize( + imageNaturalWidth: number, + imageNaturalHeight: number + ) { + if (!containerRef.current) return; + + const { width: containerWidth, height: containerHeight } = + containerRef.current.getBoundingClientRect(); + + let width = Math.min(containerWidth, imageNaturalWidth); + let height = (width / imageNaturalWidth) * imageNaturalHeight; + + if (height > containerHeight) { + height = containerHeight; + width = (height / imageNaturalHeight) * imageNaturalWidth; + } + const x = (containerWidth - width) / 2; + const y = (containerHeight - height) / 2; + + return { width, height, x, y }; + } + + function imageLoaded(event: SyntheticEvent) { + const naturalWidth = (event.target as HTMLImageElement).naturalWidth; + const naturalHeight = (event.target as HTMLImageElement).naturalHeight; + + const positionAndSize = getImagePositionAndSize( + naturalWidth, + naturalHeight + ); + + if (!positionAndSize) return; + + api.set({ + ...positionAndSize, + scale: 1, + rotate: 0, + }); + + setIsLoading(false); + } + + const getSizeByAngle = ( + width: number, + height: number, + angle: number + ): [number, number] => { + const { abs, cos, sin, PI } = Math; + + const angleByRadians = (PI / 180) * angle; + + const c = cos(angleByRadians); + const s = sin(angleByRadians); + const halfw = 0.5 * width; + const halfh = 0.5 * height; + const newWidth = 2 * (abs(c * halfw) + abs(s * halfh)); + const newHeight = 2 * (abs(s * halfw) + abs(c * halfh)); + + return [newWidth, newHeight]; + }; + + const getBounds = ( + diffScale: number = 1, + angle: number = 0 + ): BoundsType | null => { + if (!imgRef.current || !containerRef.current) return null; + + let imageBounds = imgRef.current.getBoundingClientRect(); + const containerBounds = containerRef.current.getBoundingClientRect(); + + const [width, height] = getSizeByAngle( + imageBounds.width, + imageBounds.height, + angle + ); + + if (diffScale !== 1) + imageBounds = { + ...imageBounds, + width: width * diffScale, + height: height * diffScale, + }; + else { + imageBounds = { + ...imageBounds, + width, + height, + }; + } + const originalWidth = imgRef.current.clientWidth; + const widthOverhang = (imageBounds.width - originalWidth) / 2; + + const originalHeight = imgRef.current.clientHeight; + const heightOverhang = (imageBounds.height - originalHeight) / 2; + + const isWidthOutContainer = imageBounds.width >= containerBounds.width; + + const isHeightOutContainer = imageBounds.height >= containerBounds.height; + + const bounds = { + right: isWidthOutContainer + ? widthOverhang + : containerBounds.width - imageBounds.width + widthOverhang, + left: isWidthOutContainer + ? -(imageBounds.width - containerBounds.width) + widthOverhang + : widthOverhang, + bottom: isHeightOutContainer + ? heightOverhang + : containerBounds.height - imageBounds.height + heightOverhang, + top: isHeightOutContainer + ? -(imageBounds.height - containerBounds.height) + heightOverhang + : heightOverhang, + }; + + return bounds; + }; + + const calculateAdjustBounds = ( + x: number, + y: number, + diffScale: number = 1, + angle: number = 0 + ) => { + const bounds = getBounds(diffScale, angle); + + if (!bounds) return { x, y }; + + const { left, right, top, bottom } = bounds; + + if (x > right) { + x = right; + } else if (x < left) { + x = left; + } + + if (y > bottom) { + y = bottom; + } else if (y < top) { + y = top; + } + + return { x, y }; + }; + + const calculateAdjustImage = ( + point: { x: number; y: number }, + diffScale: number = 1 + ) => { + if (!imgRef.current || !containerRef.current) return point; + + // debugger; + + let imageBounds = imgRef.current.getBoundingClientRect(); + const containerBounds = containerRef.current.getBoundingClientRect(); + + if (diffScale !== 1) { + const { x, y, width, height } = imageBounds; + + const newWidth = imageBounds.width * diffScale; + const newHeight = imageBounds.height * diffScale; + + const newX = x + width / 2 - newWidth / 2; + const newY = y + height / 2 - newHeight / 2; + + imageBounds = { + ...imageBounds, + width: newWidth, + height: newHeight, + left: newX, + top: newY, + right: newX + newWidth, + bottom: newY + newHeight, + x: newX, + y: newY, + }; + } + + const originalWidth = imgRef.current.clientWidth; + const widthOverhang = (imageBounds.width - originalWidth) / 2; + + const originalHeight = imgRef.current.clientHeight; + const heightOverhang = (imageBounds.height - originalHeight) / 2; + + const isWidthOutContainer = imageBounds.width >= containerBounds.width; + + const isHeightOutContainer = imageBounds.height >= containerBounds.height; + + if ( + compareTo(imageBounds.left, containerBounds.left) && + isWidthOutContainer + ) { + point.x = widthOverhang; + } else if ( + compareTo(containerBounds.right, imageBounds.right) && + isWidthOutContainer + ) { + point.x = containerBounds.width - imageBounds.width + widthOverhang; + } else if (!isWidthOutContainer) { + point.x = (containerBounds.width - imageBounds.width) / 2 + widthOverhang; + } + + if ( + compareTo(imageBounds.top, containerBounds.top) && + isHeightOutContainer + ) { + point.y = heightOverhang; + } else if ( + compareTo(containerBounds.bottom, imageBounds.bottom) && + isHeightOutContainer + ) { + point.y = containerBounds.height - imageBounds.height + heightOverhang; + } else if (!isHeightOutContainer) { + point.y = + (containerBounds.height - imageBounds.height) / 2 + heightOverhang; + } + + return point; + }; + + const rotateImage = (dir: number) => { + if (style.rotate.isAnimating) return; + + const rotate = style.rotate.get() + dir * 90; + + const point = calculateAdjustImage( + calculateAdjustBounds(style.x.get(), style.y.get(), 1, rotate) + ); + + api.start({ + ...point, + rotate, + config: { + // easing: easings.easeInBack, + duration: 200, + }, + onResolve(result) { + api.start({ + ...calculateAdjustImage({ + x: result.value.x, + y: result.value.y, + }), + config: { + duration: 100, + }, + }); + }, + }); + }; + + const zoomOut = () => { + if ( + style.scale.isAnimating || + style.scale.get() <= MinScale || + !imgRef.current || + !containerRef.current + ) + return; + + const { width, height, x, y } = imgRef.current.getBoundingClientRect(); + const { width: containerWidth, height: containerHeight } = + containerRef.current.getBoundingClientRect(); + + const scale = Math.max(style.scale.get() - DefaultSpeedScale, MinScale); + + const tx = ((containerWidth - width) / 2 - x) / style.scale.get(); + const ty = ((containerHeight - height) / 2 - y) / style.scale.get(); + + let dx = style.x.get() + DefaultSpeedScale * tx; + let dy = style.y.get() + DefaultSpeedScale * ty; + + const ratio = scale / style.scale.get(); + + const point = calculateAdjustImage(calculateAdjustBounds(dx, dy, ratio)); + toolbarRef.current?.setPercentValue(scale); + + api.start({ + scale, + ...point, + config: { + duration: 300, + }, + onResolve: (result) => { + api.start({ + ...calculateAdjustImage({ + x: result.value.x, + y: result.value.y, + }), + config: { + ...config.default, + duration: 100, + }, + }); + }, + }); + }; + + const zoomIn = () => { + if ( + style.scale.isAnimating || + style.scale.get() >= MaxScale || + !imgRef.current || + !containerRef.current + ) + return; + + const { width, height, x, y } = imgRef.current.getBoundingClientRect(); + const { width: containerWidth, height: containerHeight } = + containerRef.current.getBoundingClientRect(); + + const tx = ((containerWidth - width) / 2 - x) / style.scale.get(); + const ty = ((containerHeight - height) / 2 - y) / style.scale.get(); + + const dx = style.x.get() - DefaultSpeedScale * tx; + const dy = style.y.get() - DefaultSpeedScale * ty; + + const scale = Math.min(style.scale.get() + DefaultSpeedScale, MaxScale); + toolbarRef.current?.setPercentValue(scale); + api.start({ + x: dx, + y: dy, + scale, + config: { + duration: 300, + }, + }); + }; + + const onKeyDown = (event: KeyboardEvent) => { + const { code, ctrlKey } = event; + + const someDialogIsOpen = checkDialogsOpen(); + if (someDialogIsOpen) return; + + switch (code) { + case KeyboardEventKeys.ArrowLeft: + case KeyboardEventKeys.ArrowRight: + if (document.fullscreenElement) return; + if (ctrlKey) { + const dir = code === KeyboardEventKeys.ArrowRight ? 1 : -1; + rotateImage(dir); + } + break; + case KeyboardEventKeys.ArrowUp: + case KeyboardEventKeys.NumpadAdd: + case KeyboardEventKeys.Equal: + zoomIn(); + break; + case KeyboardEventKeys.ArrowDown: + case KeyboardEventKeys.NumpadSubtract: + case KeyboardEventKeys.Minus: + zoomOut(); + break; + case KeyboardEventKeys.Digit1: + case KeyboardEventKeys.Numpad1: + if (ctrlKey) { + restartScaleAndSize(); + } + break; + default: + break; + } + }; + + const handleDoubleTapOrClick = ( + event: + | TouchEvent + | MouseEvent + | React.MouseEvent + ) => { + if (style.scale.isAnimating) return; + + if (style.scale.get() !== 1) { + restartScaleAndSize(); + } else { + zoomOnDoubleTap(event); + } + }; + + const zoomOnDoubleTap = ( + event: + | TouchEvent + | MouseEvent + | React.MouseEvent, + scale = 1 + ) => { + if ( + !imgRef.current || + style.scale.get() >= MaxScale || + style.scale.isAnimating + ) + return; + + const isTouch = "touches" in event; + + const pageX = isTouch ? event.touches[0].pageX : event.pageX; + const pageY = isTouch ? event.touches[0].pageY : event.pageY; + + const { width, height, x, y } = imgRef.current.getBoundingClientRect(); + const tx = (pageX - (x + width / 2)) / style.scale.get(); + const ty = (pageY - (y + height / 2)) / style.scale.get(); + + const dx = style.x.get() - scale * tx; + const dy = style.y.get() - scale * ty; + + const newScale = Math.min(style.scale.get() + scale, MaxScale); + const ratio = newScale / style.scale.get(); + + const point = calculateAdjustImage( + calculateAdjustBounds(dx, dy, ratio), + ratio + ); + + toolbarRef.current?.setPercentValue(newScale); + + api.start({ + ...point, + scale: newScale, + config: config.default, + // onChange(result) { + // api.start(maybeAdjustImage({ x: dx, y: dy })); + // }, + onResolve() { + api.start(calculateAdjustImage(calculateAdjustBounds(dx, dy, 1))); + }, + }); + }; + + useGesture( + { + onDragStart: ({ pinching }) => { + if (pinching) return; + + setScale(style.scale.get()); + }, + onDrag: ({ + offset: [dx, dy], + movement: [mdx, mdy], + cancel, + pinching, + canceled, + }) => { + if (!imgRef.current) return; + + if (isDoubleTapRef.current || unmountRef.current) { + isDoubleTapRef.current = false; + return; + } + + if (pinching || canceled) cancel(); + if (!imgRef.current || !containerRef.current) return; + + api.start({ + x: + style.scale.get() === 1 && + !isDesktop && + ((isFistImage && mdx > 0) || (isLastImage && mdx < 0)) + ? style.x.get() + : dx, + y: dy, + opacity: + style.scale.get() === 1 && !isDesktop && mdy > 0 + ? imgRef.current.height / 10 / mdy + : style.opacity.get(), + immediate: true, + config: config.default, + }); + }, + + onDragEnd: ({ cancel, canceled, movement: [mdx, mdy] }) => { + if (unmountRef.current || !imgRef.current) { + return; + } + + if (canceled || isDoubleTapRef.current) { + isDoubleTapRef.current = false; + cancel(); + } + + if (style.scale.get() === 1 && !isDesktop) { + if (mdx < -imgRef.current.width / 4) { + return onNext(); + } else if (mdx > imgRef.current.width / 4) { + return onPrev(); + } + if (mdy > 150) { + return onMask(); + } + } + + const newPoint = calculateAdjustImage({ + x: style.x.get(), + y: style.y.get(), + }); + + api.start({ + ...newPoint, + opacity: 1, + config: config.default, + }); + }, + + onPinchStart: ({ event, cancel }) => { + if (event.target === containerRef.current) { + cancel(); + } else { + const roundedAngle = Math.round(style.rotate.get()); + startAngleRef.current = roundedAngle - (roundedAngle % 90); + } + }, + + onPinch: ({ + origin: [ox, oy], + offset: [dScale, dRotate], + lastOffset: [LScale], + movement: [mScale], + memo, + first, + canceled, + event, + pinching, + cancel, + }) => { + if ( + canceled || + event.target === containerRef.current || + !imgRef.current + ) + return memo; + + if (!pinching) cancel(); + + if (first) { + const { width, height, x, y } = + imgRef.current.getBoundingClientRect(); + const tx = ox - (x + width / 2); + const ty = oy - (y + height / 2); + memo = [style.x.get(), style.y.get(), tx, ty]; + } + + const x = memo[0] - (mScale - 1) * memo[2]; + const y = memo[1] - (mScale - 1) * memo[3]; + + const ratio = dScale / LScale; + + const { x: dx, y: dy } = calculateAdjustImage({ x, y }, ratio); + + const point = calculateAdjustBounds(dx, dy, ratio, dRotate); + + api.start({ + ...point, + scale: dScale, + rotate: dRotate, + delay: 0, + onChange(result) { + api.start({ + ...calculateAdjustImage( + { + x: result.value.x, + y: result.value.y, + }, + ratio + ), + delay: 0, + config: { + duration: 200, + }, + }); + }, + config: config.default, + }); + return memo; + }, + onPinchEnd: ({ + movement: [, mRotate], + direction: [, dirRotate], + canceled, + }) => { + if (unmountRef.current || canceled) { + return; + } + const rotate = + Math.abs(mRotate / 90) > 1 / 3 + ? Math.trunc( + startAngleRef.current + + 90 * + Math.max(Math.trunc(Math.abs(mRotate) / 90), 1) * + dirRotate + ) + : startAngleRef.current; + + const newPoint = calculateAdjustImage({ + x: style.x.get(), + y: style.y.get(), + }); + + api.start({ + ...newPoint, + rotate, + delay: 0, + onResolve: () => { + api.start({ + ...calculateAdjustImage({ + x: style.x.get(), + y: style.y.get(), + }), + delay: 0, + config: { + ...config.default, + duration: 200, + }, + }); + }, + onChange(result) { + api.start({ + ...calculateAdjustImage({ + x: result.value.x, + y: result.value.y, + }), + delay: 0, + config: { + ...config.default, + duration: 200, + }, + }); + }, + config: config.default, + }); + }, + + onClick: ({ pinching, event }) => { + if (isDesktop && event.target === imgWrapperRef.current) + return onMask(); + + if (!imgRef.current || !containerRef.current || pinching || isDesktop) + return; + + const time = new Date().getTime(); + + if (time - lastTapTimeRef.current < 300) { + //on Double Tap + lastTapTimeRef.current = 0; + isDoubleTapRef.current = true; + + handleDoubleTapOrClick(event); + + clearTimeout(setTimeoutIDTapRef.current); + } else { + lastTapTimeRef.current = time; + setTimeoutIDTapRef.current = setTimeout(() => { + // onTap + setBackgroundBlack((state) => !state); + }, 300); + } + }, + onWheel: ({ + first, + offset: [, yWheel], + movement: [, mYWheel], + pinching, + memo, + event, + }) => { + if ( + !imgRef.current || + pinching || + style.scale.isAnimating || + event.target !== imgRef.current + ) + return memo; + + resetToolbarVisibleTimer(); + const dScale = (-1 * yWheel) / RatioWheel; + const mScale = (-1 * mYWheel) / RatioWheel; + + if (first || !memo) { + const { width, height, x, y } = + imgRef.current.getBoundingClientRect(); + const tx = (event.pageX - (x + width / 2)) / style.scale.get(); + const ty = (event.pageY - (y + height / 2)) / style.scale.get(); + memo = [style.x.get(), style.y.get(), tx, ty]; + } + const dx = memo[0] - mScale * memo[2]; + const dy = memo[1] - mScale * memo[3]; + + const ratio = dScale / style.scale.get(); + + const point = calculateAdjustImage( + calculateAdjustBounds(dx, dy, ratio), + ratio + ); + toolbarRef.current?.setPercentValue(dScale); + api.start({ + ...point, + scale: dScale, + config: { + ...config.default, + duration: 300, + }, + onResolve(result) { + api.start( + calculateAdjustImage( + calculateAdjustBounds(result.value.x, result.value.y) + ) + ); + }, + }); + + return memo; + }, + }, + { + drag: { + from: () => [style.x.get(), style.y.get()], + axis: scale === 1 && !isDesktop ? "lock" : undefined, + rubberband: isDesktop, + bounds: () => { + if (style.scale.get() === 1 && !isDesktop) return {}; + + return getBounds() ?? {}; + }, + }, + pinch: { + scaleBounds: { min: MinScale, max: MaxScale }, + rubberband: false, + from: () => [style.scale.get(), style.rotate.get()], + threshold: [0.1, 5], + pinchOnWheel: false, + }, + + wheel: { + from: () => [0, -style.scale.get() * RatioWheel], + bounds: () => ({ + top: -MaxScale * RatioWheel, + bottom: -MinScale * RatioWheel, + }), + axis: "y", + }, + + target: containerRef, + } + ); + + const handleAction = (action: ToolbarActionType) => { + resetToolbarVisibleTimer(); + + switch (action) { + case ToolbarActionType.ZoomOut: + zoomOut(); + break; + case ToolbarActionType.ZoomIn: + zoomIn(); + break; + + case ToolbarActionType.RotateLeft: + case ToolbarActionType.RotateRight: + const dir = action === ToolbarActionType.RotateRight ? 1 : -1; + rotateImage(dir); + break; + case ToolbarActionType.Reset: + restartScaleAndSize(); + break; + default: + break; + } + }; + + function toolbarEvent(item: ToolbarItemType) { + if (item.onClick) { + item.onClick(); + } else { + handleAction(item.actionType); + } + } + + const onError = () => { + setIsError(true); + }; + + const model = React.useMemo(contextModel, [contextModel]); + + return ( + <> + {isMobile && !backgroundBlack && mobileDetails} + + {isError ? ( + + ) : ( + + )} + + + + + + + {isDesktop && panelVisible && !isError && ( + + )} + + ); +} + +export default OformViewer; diff --git a/packages/common/components/MediaViewer/sub-components/Viewer/Viewer.props.ts b/packages/common/components/MediaViewer/sub-components/Viewer/Viewer.props.ts index e014a758e4..62bdeb0855 100644 --- a/packages/common/components/MediaViewer/sub-components/Viewer/Viewer.props.ts +++ b/packages/common/components/MediaViewer/sub-components/Viewer/Viewer.props.ts @@ -9,6 +9,7 @@ interface ViewerProps { isVideo: boolean; visible: boolean; isImage: boolean; + isForm: boolean; isPdf: boolean; playlist: PlaylistType[]; diff --git a/packages/common/components/MediaViewer/sub-components/Viewer/index.tsx b/packages/common/components/MediaViewer/sub-components/Viewer/index.tsx index 33e0fabf8a..a638851172 100644 --- a/packages/common/components/MediaViewer/sub-components/Viewer/index.tsx +++ b/packages/common/components/MediaViewer/sub-components/Viewer/index.tsx @@ -7,6 +7,7 @@ import { StyledViewerContainer } from "../../StyledComponents"; import NextButton from "../NextButton"; import PrevButton from "../PrevButton"; import ImageViewer from "../ImageViewer"; +import OformViewer from "../OformViewer"; import MobileDetails from "../MobileDetails"; import DesktopDetails from "../DesktopDetails"; import ViewerPlayer from "../ViewerPlayer"; @@ -188,7 +189,7 @@ function Viewer(props: ViewerProps) { )} - {props.isImage + {props.isImage && !props.isForm ? ReactDOM.createPortal( , containerRef.current ) + : props.isForm + ? ReactDOM.createPortal( + , + containerRef.current + ) : props.isPdf && ReactDOM.createPortal( Date: Mon, 25 Sep 2023 13:25:21 +0300 Subject: [PATCH 057/334] fixed template info option in info panel --- .../ItemTitle/GalleryItemTitle.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js index fb2ff97195..dcd317b482 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/GalleryItemTitle.js @@ -6,7 +6,7 @@ import { inject } from "mobx-react"; import { Text } from "@docspace/components"; import { StyledTitle } from "../../styles/common"; -import { useParams, useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; import styled from "styled-components"; const StyledGalleryContextOptions = styled.div` @@ -22,17 +22,18 @@ const GalleryItemTitle = ({ getIcon, currentColorScheme, - getFormContextOptions, - categoryType, + getFormGalleryContextOptions, }) => { const itemTitleRef = useRef(); const contextMenuRef = useRef(); - const params = useParams(); const navigate = useNavigate(); - const onGetContextOptions = () => - getFormContextOptions(t, gallerySelected, categoryType, params, navigate); + const onGetContextOptions = () => { + let options = getFormGalleryContextOptions(gallerySelected, t, navigate); + options = options.filter((option) => option.key !== "template-info"); + return options; + }; const onClickContextMenu = (e) => { e.button === 2; @@ -70,7 +71,7 @@ const GalleryItemTitle = ({ ); }; -export default inject(({ oformsStore, filesStore }) => ({ - getFormContextOptions: oformsStore.getFormContextOptions, - categoryType: filesStore.categoryType, +export default inject(({ contextOptionsStore }) => ({ + getFormGalleryContextOptions: + contextOptionsStore.getFormGalleryContextOptions, }))(withTranslation(["FormGallery", "Common"])(GalleryItemTitle)); From 991994ee82b876f63341bc5eb841f8117ef90b8d Mon Sep 17 00:00:00 2001 From: mushka-n Date: Mon, 25 Sep 2023 14:23:47 +0300 Subject: [PATCH 058/334] rtl fix --- .../DesktopView/index.styled.js | 35 ++++++++++++++++--- .../CategoryFilter/MobileView/index.styled.js | 6 +++- .../Filter/LanguageFilter/index.styled.js | 4 +-- .../Filter/SortFilter/index.styled.js | 2 +- .../src/pages/FormGallery/Filter/index.js | 7 +++- 5 files changed, 45 insertions(+), 9 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js index 99beb74028..b0101052bd 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js @@ -3,6 +3,7 @@ import styled, { css } from "styled-components"; import DropDown from "@docspace/components/drop-down"; import DropDownItem from "@docspace/components/drop-down-item"; import ComboBox from "@docspace/components/combobox"; +import { Base } from "@docspace/components/themes"; export const CategoryFilterWrapper = styled.div` position: relative; @@ -31,8 +32,12 @@ export const CategoryFilterItem = styled(DropDownItem)` width: 220px; height: 32px; + display: flex; + align-items: center; + justify-content: space-between; + box-sizing: border-box; - padding: 8px 16px; + padding: 8px 12px; font-size: 12px; font-weight: 600; @@ -43,24 +48,36 @@ export const CategoryFilterItem = styled(DropDownItem)` white-space: nowrap; overflow: hidden; text-overflow: ellipsis; + + text-align: ${({ theme }) => + theme.interfaceDirection === "ltl" ? `left` : `right`}; } .submenu-arrow { - margin-right: 0; + margin: 0; svg { height: 12px; width: 12px; } } `; +CategoryFilterItem.defaultProps = { theme: Base }; export const CategoryFilterSubList = styled(DropDown)` position: absolute; top: 0; margin-top: ${({ marginTop }) => marginTop}; - left: calc(100% + 4px); padding: 4px 0; + ${({ theme }) => + theme.interfaceDirection === "ltl" + ? css` + left: calc(100% + 4px); + ` + : css` + right: calc(100% + 4px); + `}; + max-height: 296px; max-width: auto; @@ -80,12 +97,22 @@ export const CategoryFilterSubList = styled(DropDown)` &:before { content: ""; position: absolute; - left: -4px; + + ${({ theme }) => + theme.interfaceDirection === "ltl" + ? css` + left: -4px; + ` + : css` + right: -4px; + `}; + top: 0; width: 4px; height: 100%; } `; +CategoryFilterSubList.defaultProps = { theme: Base }; export const CategoryFilterSubListItem = styled(DropDownItem)` width: 208px; diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.styled.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.styled.js index a2e50d4ed0..ce33507956 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.styled.js @@ -3,6 +3,7 @@ import styled, { css } from "styled-components"; import DropDown from "@docspace/components/drop-down"; import DropDownItem from "@docspace/components/drop-down-item"; import ComboButton from "@docspace/components/combobox/sub-components/combo-button"; +import { Base } from "@docspace/components/themes"; export const CategoryFilterMobileWrapper = styled.div` width: 100%; @@ -50,7 +51,8 @@ export const CategoryFilterItemMobile = styled(DropDownItem)` padding-bottom: 8px; .submenu-arrow { - margin-right: 0; + margin: ${({ theme }) => + theme.interfaceDirection === "ltl" ? `0 0 0 auto` : `0 auto 0 0`}; svg { height: 12px; @@ -65,6 +67,8 @@ export const CategoryFilterItemMobile = styled(DropDownItem)` } `; +CategoryFilterItemMobile.defaultProps = { theme: Base }; + export const StyledSubItemMobile = styled(DropDownItem)` padding-left: 28px; `; diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js index e8ba79c1bf..3609df70cf 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.styled.js @@ -53,7 +53,7 @@ export const LanguageFilterSelectedItem = styled(DropDownItem)` justify-content: center; .drop-down-icon { - margin-right: 0; + margin: 0; width: 16px; height: 16px; & > div { @@ -82,7 +82,7 @@ export const LanguageFilterItem = styled(DropDownItem)` `} .drop-down-icon { - margin-right: 0; + margin: 0; width: 16px; height: 16px; line-height: 0 !important; diff --git a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js index 03ca0f90da..1ccc56cb4f 100644 --- a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.styled.js @@ -28,7 +28,7 @@ export const SortButton = styled.div` display: flex; align-items: center; justify-content: center; - margin-right: 0; + margin: 0; } .combo-buttons_arrow-icon { diff --git a/packages/client/src/pages/FormGallery/Filter/index.js b/packages/client/src/pages/FormGallery/Filter/index.js index b3bb17e747..0956b013d4 100644 --- a/packages/client/src/pages/FormGallery/Filter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/index.js @@ -10,6 +10,7 @@ import SortFilter from "./SortFilter"; import { smallTablet, tablet } from "@docspace/components/utils/device"; import { getDefaultOformLocale } from "@docspace/common/utils"; import OformsFilter from "@docspace/common/api/oforms/filter"; +import { Base } from "@docspace/components/themes"; export const StyledFilter = styled.div` display: flex; @@ -38,7 +39,9 @@ export const StyledFilter = styled.div` @media ${smallTablet} { height: 72px; - flex-direction: column-reverse; + + flex-direction: ${({ theme }) => + theme.interfaceDirection === "ltl" ? `column-reverse` : `column`}; .form-only-filters { width: 100%; @@ -46,6 +49,8 @@ export const StyledFilter = styled.div` } `; +StyledFilter.defaultProps = { theme: Base }; + const SectionFilterContent = ({ oformsFilter, setOformsFilter }) => { return ( From 2a8605b0a542e76f26266f802476085f5dfda2e0 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Mon, 25 Sep 2023 14:33:46 +0300 Subject: [PATCH 059/334] rtl fix 2 --- .../client/src/pages/Home/InfoPanel/Body/styles/common.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js b/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js index ba4b1d8f01..3d860d43e7 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js @@ -92,10 +92,12 @@ const StyledTitle = styled.div` } .free-label { - margin-left: auto; font-size: 14px; font-weight: 600; line-height: 16px; + + margin: ${({ theme }) => + theme.interfaceDirection === "rtl" ? "0 auto 0 0" : "0 0 0 auro"}; } ${(props) => From 8ce77b7d35880b82b041fab3e97445756bec4fc2 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Mon, 25 Sep 2023 14:38:35 +0300 Subject: [PATCH 060/334] rtl fix 3 --- .../Filter/CategoryFilter/DesktopView/index.styled.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js index b0101052bd..11f9f2da43 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js @@ -50,7 +50,7 @@ export const CategoryFilterItem = styled(DropDownItem)` text-overflow: ellipsis; text-align: ${({ theme }) => - theme.interfaceDirection === "ltl" ? `left` : `right`}; + theme.interfaceDirection !== "rtl" ? `left` : `right`}; } .submenu-arrow { @@ -70,7 +70,7 @@ export const CategoryFilterSubList = styled(DropDown)` padding: 4px 0; ${({ theme }) => - theme.interfaceDirection === "ltl" + theme.interfaceDirection !== "rtl" ? css` left: calc(100% + 4px); ` @@ -99,7 +99,7 @@ export const CategoryFilterSubList = styled(DropDown)` position: absolute; ${({ theme }) => - theme.interfaceDirection === "ltl" + theme.interfaceDirection !== "rtl" ? css` left: -4px; ` From 1cc4a655874fc3ff876b49d337e7969e3c6553d0 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Mon, 25 Sep 2023 14:44:34 +0300 Subject: [PATCH 061/334] rtl fix 4 --- packages/client/src/pages/Home/InfoPanel/Body/styles/common.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js b/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js index 3d860d43e7..4fc5b45d73 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js @@ -97,7 +97,7 @@ const StyledTitle = styled.div` line-height: 16px; margin: ${({ theme }) => - theme.interfaceDirection === "rtl" ? "0 auto 0 0" : "0 0 0 auro"}; + theme.interfaceDirection === "rtl" ? "0 auto 0 0" : "0 0 0 auto"}; } ${(props) => From a184219005c86da86165a386c4fd65424032148b Mon Sep 17 00:00:00 2001 From: mushka-n Date: Thu, 28 Sep 2023 17:24:46 +0300 Subject: [PATCH 062/334] updated category filter structurization + removed from preview --- .../CategoryFilter/DesktopView/index.js | 115 +++----- .../DesktopView/index.styled.js | 4 +- .../MobileView/CategorySubList.js | 3 + .../Filter/CategoryFilter/MobileView/index.js | 96 ++----- .../CategoryFilter/MobileView/index.styled.js | 2 +- .../Filter/CategoryFilter/index.js | 60 ++-- .../Filter/LanguageFilter/index.js | 3 - .../pages/FormGallery/MediaViewer/index.js | 262 ------------------ .../TilesView/sub-components/Tile.js | 13 +- .../client/src/pages/FormGallery/index.js | 3 - .../client/src/store/ContextOptionsStore.js | 38 +-- .../src/store/MediaFormViewerDataStore.js | 118 -------- packages/client/src/store/OformsStore.js | 78 +----- packages/client/src/store/index.js | 12 +- packages/common/api/oforms/index.js | 9 +- 15 files changed, 134 insertions(+), 682 deletions(-) delete mode 100644 packages/client/src/pages/FormGallery/MediaViewer/index.js delete mode 100644 packages/client/src/store/MediaFormViewerDataStore.js diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js index a23edc8453..2ad819c593 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js @@ -1,11 +1,10 @@ import * as Styled from "./index.styled"; import DropDownItem from "@docspace/components/drop-down-item"; -import { useState, useEffect } from "react"; -import { inject } from "mobx-react"; +import { useState } from "react"; +import { inject, observer } from "mobx-react"; import { withTranslation } from "react-i18next"; import SubList from "./SubList"; -import { OformCategoryType } from "@docspace/client/src/helpers/constants"; import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; import { getDefaultOformLocale } from "@docspace/common/utils"; @@ -14,41 +13,26 @@ const categoryLocale = getDefaultOformLocale(); const CategoryFilterDesktop = ({ t, - fetchCategoryFilterMenuItems, - - currentCategoryTitle, + fetchCategoryList, currentCategory, - onViewAllTemplates, + + filterOformsByCategory, + + menuItems, formsByBranch, formsByType, formsByCompilation, ...rest }) => { - // const [menuItems, setMenuItems] = useState([]); - const [isOpen, setIsOpen] = useState(false); const onToggleDropdownIsOpen = () => setIsOpen(!isOpen); const onCloseDropdown = () => setIsOpen(false); - const [isBranchHovered, setIsBranchHovered] = useState(false); - const [isTypeHovered, setIsTypeHovered] = useState(false); - const [isCompilationHovered, setIsCompilationHovered] = useState(false); + const [hoveredSub, setHoveredSub] = useState(null); - const onMouseEnterBranch = () => setIsBranchHovered(true); - const onMouseLeaveBranch = () => setIsBranchHovered(false); - const onMouseEnterType = () => setIsTypeHovered(true); - const onMouseLeaveType = () => setIsTypeHovered(false); - const onMouseEnterCompilation = () => setIsCompilationHovered(true); - const onMouseLeaveCompilation = () => setIsCompilationHovered(false); - - // useEffect(() => { - // (async () => { - // const fetchedMenuItems = await fetchCategoryFilterMenuItems(); - // setMenuItems(fetchedMenuItems); - // })(); - // }, []); + const onViewAllTemplates = () => filterOformsByCategory("", ""); return ( @@ -85,71 +69,40 @@ const CategoryFilterDesktop = ({ className="dropdown-item" label={t("FormGallery:ViewAllTemplates")} onClick={onViewAllTemplates} + onMouseEnter={() => setHoveredSub(null)} /> - - - + {menuItems?.map((item) => ( + setHoveredSub(item.key)} + onMouseLeave={() => setHoveredSub(null)} + isSubMenu + /> + ))} } /> - - - + {menuItems.map((item, index) => ( + + ))} ); }; export default inject(({ oformsStore }) => ({ - fetchCategoryFilterMenuItems: oformsStore.fetchCategoryFilterMenuItems, + fetchCategoryList: oformsStore.fetchCategoryList, currentCategory: oformsStore.currentCategory, @@ -159,4 +112,4 @@ export default inject(({ oformsStore }) => ({ oformsFilter: oformsStore.oformsFilter, filterOformsByCategory: oformsStore.filterOformsByCategory, -}))(withTranslation(["FormGallery"])(CategoryFilterDesktop)); +}))(withTranslation(["FormGallery"])(observer(CategoryFilterDesktop))); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js index 11f9f2da43..1e6f30ca7f 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.styled.js @@ -101,10 +101,10 @@ export const CategoryFilterSubList = styled(DropDown)` ${({ theme }) => theme.interfaceDirection !== "rtl" ? css` - left: -4px; + left: -5px; ` : css` - right: -4px; + right: -5px; `}; top: 0; diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js index 946efce653..140f67cd5f 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js @@ -7,6 +7,7 @@ import { getDefaultOformLocale } from "@docspace/common/utils"; const categoryLocale = getDefaultOformLocale(); const CategorySubList = ({ + isOpen, categoryType, categories, @@ -18,6 +19,8 @@ const CategorySubList = ({ filterOformsByCategory(categoryType, category.id); }; + if (!isOpen) return null; + return categories.map((category) => ( setIsOpen(!isOpen); - const onCloseDropdown = () => setIsOpen(false); const [openedCategory, setOpenedCategory] = useState(null); - const isBranchOpen = openedCategory === OformCategoryType.Branch; - const isTypeOpen = openedCategory === OformCategoryType.Type; - const isCompilationOpen = openedCategory === OformCategoryType.Compilation; + const onToggleCategory = (category) => { + if (openedCategory?.key !== category.key) setOpenedCategory(category); + else setOpenedCategory(null); + }; - const onToggleBranchCategory = () => - setOpenedCategory(isBranchOpen ? null : OformCategoryType.Branch); - const onToggleTypeCategory = () => - setOpenedCategory(isTypeOpen ? null : OformCategoryType.Type); - const onToggleCompilationCategory = () => - setOpenedCategory(isCompilationOpen ? null : OformCategoryType.Compilation); - - const wrapperOffsetTop = wrapperRef?.current?.offsetTop; - const maxCalculatedHeight = window.innerHeight - wrapperOffsetTop - 64; let calculatedHeight = - 152.2 + - 36 * - (isBranchOpen - ? formsByBranch.length - : isTypeOpen - ? formsByType.length - : isCompilationOpen - ? formsByCompilation.length - : 0); + 152.2 + (!openedCategory ? 0 : 36 * openedCategory.categories.length); + const maxCalculatedHeight = + window.innerHeight - wrapperRef?.current?.offsetTop - 64; if (calculatedHeight > maxCalculatedHeight) calculatedHeight = maxCalculatedHeight; @@ -94,53 +79,22 @@ const CategoryFilterMobile = ({ - - {isBranchOpen && ( + {menuItems.map((item) => [ + onToggleCategory(item)} + isSubMenu + />, - )} - - - {isTypeOpen && ( - - )} - - - {isCompilationOpen && ( - - )} + key={`${item.key}-sublist`} + isOpen={openedCategory?.key === item.key} + categoryType={item.key} + categories={item.categories} + />, + ])} diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.styled.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.styled.js index ce33507956..f967043422 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.styled.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.styled.js @@ -52,7 +52,7 @@ export const CategoryFilterItemMobile = styled(DropDownItem)` .submenu-arrow { margin: ${({ theme }) => - theme.interfaceDirection === "ltl" ? `0 0 0 auto` : `0 auto 0 0`}; + theme.interfaceDirection !== "rtl" ? `0 0 0 auto` : `0 auto 0 0`}; svg { height: 12px; diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js index 29516b6302..5304a35e29 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js @@ -46,29 +46,40 @@ const CategoryFilter = ({ oformsFilter, filterOformsByCategory, - fetchCategoriesByBranch, - fetchCategoriesByType, - fetchPopularCategories, + fetchCategoryList, + fetchCategories, }) => { - const currentCategoryTitle = getOformCategoryTitle( - currentCategory, - categoryLocale - ); + const [menuItems, setMenuItems] = useState([]); const onViewAllTemplates = () => filterOformsByCategory("", ""); - const [formsByBranch, setFormsByBranch] = useState([]); - const [formsByType, setFormsByType] = useState([]); - const [formsByCompilation, setFormsByCompilation] = useState([]); - useEffect(() => { (async () => { - const branchData = await fetchCategoriesByBranch(); - setFormsByBranch(branchData); - const typeData = await fetchCategoriesByType(); - setFormsByType(typeData); - const compilationData = await fetchPopularCategories(); - setFormsByCompilation(compilationData); + let newMenuItems = await fetchCategoryList(); + + const categoryPromises = newMenuItems.map( + (item) => + new Promise((res) => res(fetchCategories(item.attributes.categoryId))) + ); + + Promise.all(categoryPromises) + .then( + (results) => + (newMenuItems = newMenuItems.map((item, index) => ({ + key: item.attributes.categoryId, + label: item.attributes.name, + categories: results[index], + }))) + ) + .catch((err) => { + console.error(err); + newMenuItems = newMenuItems.map((item) => ({ + key: item.attributes.categoryId, + label: item.attributes.name, + categories: [], + })); + }) + .finally(() => setMenuItems(newMenuItems)); })(); }, [oformsFilter.locale]); @@ -78,24 +89,17 @@ const CategoryFilter = ({ className="mobileView" currentCategoryTitle={getOformCategoryTitle(currentCategory)} onViewAllTemplates={onViewAllTemplates} - formsByBranch={formsByBranch} - formsByType={formsByType} - formsByCompilation={formsByCompilation} - /> - + ); }; export default inject(({ oformsStore }) => ({ currentCategory: oformsStore.currentCategory, + fetchCategoryList: oformsStore.fetchCategoryList, + fetchCategories: oformsStore.fetchCategories, fetchCategoriesByBranch: oformsStore.fetchCategoriesByBranch, fetchCategoriesByType: oformsStore.fetchCategoriesByType, fetchPopularCategories: oformsStore.fetchPopularCategories, diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js index f024a4876f..f1fb793476 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js @@ -70,9 +70,6 @@ const LanguageFilter = ({ return currentOption; }; - console.log(selectedOption); - console.log(getSelectedOption()); - const [isOpen, setIsOpen] = useState(false); const onToggleDropdownIsOpen = () => setIsOpen(!isOpen); const onCloseDropdown = () => setIsOpen(false); diff --git a/packages/client/src/pages/FormGallery/MediaViewer/index.js b/packages/client/src/pages/FormGallery/MediaViewer/index.js deleted file mode 100644 index 3cf7220cf0..0000000000 --- a/packages/client/src/pages/FormGallery/MediaViewer/index.js +++ /dev/null @@ -1,262 +0,0 @@ -import React, { useEffect } from "react"; -import { inject, observer } from "mobx-react"; -import { withTranslation } from "react-i18next"; -import { useNavigate, useLocation } from "react-router-dom"; -import queryString from "query-string"; -import MediaViewer from "@docspace/common/components/MediaViewer"; - -const FilesMediaViewer = ({ - t, - - files, - playlist, - - currentPostionIndex, - visible, - currentMediaFileId, - - setMediaViewerData, - - userAccess, - setCurrentId, - - oformFromFolderId, - - onCreateOform, - onSuggestOformChanges, - - setBufferSelection, - - archiveRoomsId, - getIcon, - extsImagePreviewed, - extsMediaPreviewed, - isPreview, - nextMedia, - prevMedia, - resetUrl, - getFirstUrl, - firstLoad, -}) => { - const navigate = useNavigate(); - const location = useLocation(); - - const onButtonBackHandler = () => { - const hash = window.location.hash; - const id = hash.slice(9); - if (!id) { - setMediaViewerData({ visible: false, id: null }); - return; - } - setMediaViewerData({ visible: true, id }); - }; - - const onChangeUrl = (id) => { - const url = `/form-gallery/${oformFromFolderId}/#preview/${id}`; - setCurrentId(id); - navigate(url); - }; - - const onDeleteMediaFile = (id) => {}; - - const onDownloadMediaFile = (id) => {}; - - const onMediaViewerClose = (e) => { - if (isPreview) { - resetUrl(); - } - - setMediaViewerData({ visible: false, id: null }); - - const url = getFirstUrl(); - if (!url) return; - - const targetFile = files.find((item) => item.id === currentMediaFileId); - if (targetFile) setBufferSelection(targetFile); - - navigate(url, { replace: true }); - }; - - useEffect(() => { - const previewId = queryString.parse(location.search).preview; - - if (previewId) { - const queryParams = new URLSearchParams(location.search); - if (queryParams.has("preview")) { - queryParams.delete("preview"); - navigate(_, { - search: queryParams.toString(), - }); - } - - if (typeof +previewId !== "object") { - const item = { visible: true, id: +previewId }; - setMediaViewerData(item); - } - } - }, []); - - useEffect(() => { - window.addEventListener("popstate", onButtonBackHandler); - return () => window.removeEventListener("popstate", onButtonBackHandler); - }, [onButtonBackHandler]); - - return ( - visible && ( - {}} - archiveRoomsId={archiveRoomsId} - files={files} - onClickCreateOform={onCreateOform} - onClickSuggestOformChanges={onSuggestOformChanges} - onClickDownload={() => {}} - onShowInfoPanel={() => {}} - onClickDelete={() => {}} - onClickRename={() => {}} - onMoveAction={() => {}} - onCopyAction={() => {}} - onDuplicate={() => {}} - onClickLinkEdit={() => {}} - onPreviewClick={() => {}} - onCopyLink={() => {}} - onClickDownloadAs={() => {}} - onClose={onMediaViewerClose} - getIcon={getIcon} - onEmptyPlaylistError={onMediaViewerClose} - deleteDialogVisible={false} - extsMediaPreviewed={extsMediaPreviewed} - extsImagePreviewed={extsImagePreviewed} - isPreviewFile={firstLoad} - onChangeUrl={onChangeUrl} - nextMedia={nextMedia} - prevMedia={prevMedia} - /> - ) - ); -}; - -export default inject( - ({ - oformsStore, - filesStore, - mediaFormViewerDataStore, - settingsStore, - dialogsStore, - treeFoldersStore, - clientLoadingStore, - contextOptionsStore, - }) => { - const { firstLoad, setIsSectionFilterLoading } = clientLoadingStore; - - const setIsLoading = (param) => { - setIsSectionFilterLoading(param); - }; - - const { - // files, - userAccess, - setScrollToItem, - setBufferSelection, - isPreview, - resetUrl, - setAlreadyFetchingRooms, - } = filesStore; - - const { - visible, - id: currentMediaFileId, - currentPostionIndex, - setMediaViewerData, - getFirstUrl, - playlist, - setCurrentId, - nextMedia, - prevMedia, - } = mediaFormViewerDataStore; - - const { onCreateOform, onSuggestOformChanges } = contextOptionsStore; - - const { getIcon, extsImagePreviewed, extsMediaPreviewed } = settingsStore; - const { isFavoritesFolder, archiveRoomsId } = treeFoldersStore; - - const { oformFromFolderId } = oformsStore; - - const oformFiles = oformsStore.oformFiles; - const files = !oformFiles - ? [] - : oformFiles.map((oform) => ({ - id: oform.id, - title: oform.attributes.name_form, - security: { - Read: true, - Comment: false, - FillForms: false, - Review: false, - Edit: false, - Delete: false, - CustomFilter: false, - Rename: false, - ReadHistory: false, - Lock: false, - EditHistory: false, - Copy: false, - Move: false, - Duplicate: false, - SubmitToFormGallery: false, - Download: false, - Convert: false, - }, - viewAccessability: { - ImageView: true, - MediaView: false, - WebView: false, - WebEdit: false, - WebReview: false, - WebCustomFilterEditing: false, - WebRestrictedEditing: false, - WebComment: false, - CoAuhtoring: false, - Convert: false, - }, - })); - - return { - oformFromFolderId, - files, - playlist, - currentPostionIndex, - nextMedia, - prevMedia, - userAccess, - visible: playlist.length > 0 && visible, - currentMediaFileId, - setMediaViewerData, - extsImagePreviewed, - extsMediaPreviewed, - someDialogIsOpen: dialogsStore.someDialogIsOpen, - setIsLoading, - firstLoad, - onCreateOform, - onSuggestOformChanges, - resetUrl, - isPreview, - setScrollToItem, - setCurrentId, - setBufferSelection, - setAlreadyFetchingRooms, - isFavoritesFolder, - getIcon, - archiveRoomsId, - getFirstUrl, - }; - } -)(withTranslation(["Files", "Translations"])(observer(FilesMediaViewer))); diff --git a/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js b/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js index bf61aa58cb..0bb2c585cc 100644 --- a/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js +++ b/packages/client/src/pages/FormGallery/TilesView/sub-components/Tile.js @@ -6,10 +6,7 @@ import ContextMenu from "@docspace/components/context-menu"; import Link from "@docspace/components/link"; import { withTranslation } from "react-i18next"; import { ReactSVG } from "react-svg"; -import { combineUrl } from "@docspace/common/utils"; -import config from "PACKAGE_FILE"; -import FilesFilter from "@docspace/common/api/files/filter"; -import { useParams, useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; import { StyledTile, @@ -18,7 +15,6 @@ import { StyledContent, StyledOptionButton, } from "../StyledTileView"; -import { getCategoryUrl } from "SRC_DIR/helpers/utils"; const Tile = ({ t, @@ -28,9 +24,6 @@ const Tile = ({ onCreateOform, getFormGalleryContextOptions, - setIsInfoPanelVisible, - categoryType, - isInfoPanelVisible, setGallerySelected, children, contextButtonSpacerWidth, @@ -151,8 +144,7 @@ export default inject( { item } ) => { const { categoryType } = filesStore; - const { gallerySelected, setGallerySelected, getFormContextOptions } = - oformsStore; + const { gallerySelected, setGallerySelected } = oformsStore; const { getIcon } = settingsStore; const { isVisible, setIsVisible } = auth.infoPanelStore; @@ -163,7 +155,6 @@ export default inject( return { isSelected, setGallerySelected, - getFormContextOptions, onCreateOform, getFormGalleryContextOptions, getIcon, diff --git a/packages/client/src/pages/FormGallery/index.js b/packages/client/src/pages/FormGallery/index.js index e67e7bab16..349c7450cd 100644 --- a/packages/client/src/pages/FormGallery/index.js +++ b/packages/client/src/pages/FormGallery/index.js @@ -10,7 +10,6 @@ import InfoPanelHeaderContent from "../Home/InfoPanel/Header"; import SectionFilterContent from "./Filter"; import OformsFilter from "@docspace/common/api/oforms/filter"; import Dialogs from "./Dialogs"; -import MediaViewer from "./MediaViewer"; import { CategoryType } from "@docspace/client/src/helpers/constants"; const FormGallery = ({ @@ -35,7 +34,6 @@ const FormGallery = ({ !isInitLoading && location.search !== `?${oformsFilter.toUrlParams()}` ) { - console.log("NAVIGATE "); navigate(`${location.pathname}?${oformsFilter.toUrlParams()}`); } }, [oformsFilter]); @@ -94,7 +92,6 @@ const FormGallery = ({
- ); diff --git a/packages/client/src/store/ContextOptionsStore.js b/packages/client/src/store/ContextOptionsStore.js index efaff8efb7..3ccb4b8449 100644 --- a/packages/client/src/store/ContextOptionsStore.js +++ b/packages/client/src/store/ContextOptionsStore.js @@ -67,7 +67,6 @@ class ContextOptionsStore { filesActionsStore; filesStore; mediaViewerDataStore; - mediaFormViewerDataStore; treeFoldersStore; uploadDataStore; versionHistoryStore; @@ -84,7 +83,6 @@ class ContextOptionsStore { filesActionsStore, filesStore, mediaViewerDataStore, - mediaFormViewerDataStore, treeFoldersStore, uploadDataStore, versionHistoryStore, @@ -99,7 +97,6 @@ class ContextOptionsStore { this.filesActionsStore = filesActionsStore; this.filesStore = filesStore; this.mediaViewerDataStore = mediaViewerDataStore; - this.mediaFormViewerDataStore = mediaFormViewerDataStore; this.treeFoldersStore = treeFoldersStore; this.uploadDataStore = uploadDataStore; this.versionHistoryStore = versionHistoryStore; @@ -775,11 +772,11 @@ class ContextOptionsStore { filterUrlParams.folder ); - this.mediaFormViewerDataStore.removeFirstUrl(); - this.mediaFormViewerDataStore.setMediaViewerData({ - visible: false, - id: null, - }); + // this.mediaFormViewerDataStore.removeFirstUrl(); + // this.mediaFormViewerDataStore.setMediaViewerData({ + // visible: false, + // id: null, + // }); navigate( combineUrl( @@ -790,16 +787,16 @@ class ContextOptionsStore { ); }; - onPreviewOform = (item) => { - this.mediaFormViewerDataStore.setMediaViewerData({ - visible: true, - id: item.id, - }); - this.mediaFormViewerDataStore.saveFirstUrl( - `${window.DocSpace.location.pathname}${window.DocSpace.location.search}` - ); - this.mediaFormViewerDataStore.changeUrl(item.id); - }; + // onPreviewOform = (item) => { + // this.mediaFormViewerDataStore.setMediaViewerData({ + // visible: true, + // id: item.id, + // }); + // this.mediaFormViewerDataStore.saveFirstUrl( + // `${window.DocSpace.location.pathname}${window.DocSpace.location.search}` + // ); + // this.mediaFormViewerDataStore.changeUrl(item.id); + // }; onShowOformTemplateInfo = (item) => { this.authStore.infoPanelStore.setIsVisible(true); @@ -822,11 +819,6 @@ class ContextOptionsStore { label: t("Common:Create"), onClick: () => this.onCreateOform(navigate), }, - { - key: "preview", - label: t("Common:Preview"), - onClick: () => this.onPreviewOform(item), - }, { key: "template-info", label: t("FormGallery:TemplateInfo"), diff --git a/packages/client/src/store/MediaFormViewerDataStore.js b/packages/client/src/store/MediaFormViewerDataStore.js deleted file mode 100644 index 227395150d..0000000000 --- a/packages/client/src/store/MediaFormViewerDataStore.js +++ /dev/null @@ -1,118 +0,0 @@ -import { makeAutoObservable, runInAction } from "mobx"; -import { - isNullOrUndefined, - findNearestIndex, - isVideo, -} from "@docspace/common/components/MediaViewer/helpers"; -import { thumbnailStatuses } from "SRC_DIR/helpers/filesConstants"; - -const FirstUrlKey = "isFirstUrl"; - -class MediaFormViewerDataStore { - oformsStore; - settingsStore; - - id = null; - visible = false; - currentItem = null; - prevPostionIndex = 0; - - constructor(oformsStore, settingsStore) { - makeAutoObservable(this); - this.oformsStore = oformsStore; - this.settingsStore = settingsStore; - } - - setCurrentId = (id) => (this.id = id); - - setCurrentItem = (item) => (this.currentItem = item); - - setMediaViewerData = (mediaData) => { - this.id = mediaData.id; - this.visible = mediaData.visible; - - if (!mediaData.visible) this.setCurrentItem(null); - }; - - saveFirstUrl = (url) => localStorage.setItem(FirstUrlKey, url); - - getFirstUrl = () => localStorage.getItem(FirstUrlKey); - - removeFirstUrl = () => localStorage.removeItem(FirstUrlKey); - - changeUrl = (id) => { - const url = `/form-gallery/${this.oformsStore.oformFromFolderId}/#preview/${id}`; - window.DocSpace.navigate(url); - }; - - nextMedia = () => { - const { oformFiles, setGallerySelected } = this.oformsStore; - - const postionIndex = (this.currentPostionIndex + 1) % this.playlist.length; - if (postionIndex === 0) return; - - const currentFileId = this.playlist[postionIndex].fileId; - const targetFile = oformFiles.find((item) => item.id === currentFileId); - - if (!isNullOrUndefined(targetFile)) setGallerySelected(targetFile); - - const fileId = this.playlist[postionIndex].fileId; - this.setCurrentId(fileId); - this.changeUrl(fileId); - }; - - prevMedia = () => { - const { oformFiles, setGallerySelected } = this.oformsStore; - - const currentPlaylistPos = this.currentPostionIndex - 1; - if (currentPlaylistPos === -1) return; - - const currentFileId = this.playlist[currentPlaylistPos].fileId; - const targetFile = oformFiles.find((item) => item.id === currentFileId); - if (!isNullOrUndefined(targetFile)) setGallerySelected(targetFile); - - const fileId = this.playlist[currentPlaylistPos].fileId; - this.setCurrentId(fileId); - this.changeUrl(fileId); - }; - - get currentPostionIndex() { - if (this.playlist.length === 0) return 0; - - let index = this.playlist.find((file) => file.fileId === this.id)?.id; - - if (isNullOrUndefined(index)) - index = findNearestIndex(this.playlist, this.prevPostionIndex); - - runInAction(() => { - this.prevPostionIndex = index; - }); - - return index; - } - - get playlist() { - const { oformFiles } = this.oformsStore; - - if (!oformFiles) return []; - - const playlist = oformFiles.map((oform, index) => ({ - id: index, - fileId: oform.id, - src: oform.attributes.template_image.data.attributes.formats.large?.url, - title: oform.attributes.name_form, - fileExst: - oform.attributes.template_image.data.attributes.formats.large?.ext, - fileStatus: 0, - canShare: false, - version: 1, - thumbnailUrl: - oform.attributes.template_image.data.attributes.formats.large?.url, - })); - - console.log(playlist); - return playlist; - } -} - -export default MediaFormViewerDataStore; diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index fb0656057a..e71d9c2b44 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -5,7 +5,8 @@ import { submitToGallery } from "@docspace/common/api/oforms"; import { getCategoryById, - getCategoryFilterMenuItems, + getCategoryList, + getCategories, getCategoriesByBranch, getCategoriesByType, getPopularCategories, @@ -18,7 +19,6 @@ import { CategoryType } from "@docspace/client/src/helpers/constants"; class OformsStore { authStore; - mediaFormViewerDataStore; oformFiles = null; oformsFilter = OformsFilter.getDefault(); @@ -33,9 +33,8 @@ class OformsStore { "submitToGalleryTileIsHidden" ); - constructor(authStore, mediaFormViewerDataStore) { + constructor(authStore) { this.authStore = authStore; - this.mediaFormViewerDataStore = mediaFormViewerDataStore; makeAutoObservable(this); } @@ -92,66 +91,6 @@ class OformsStore { }); }; - getFormContextOptions = (t, item, navigate) => [ - { - key: "create", - label: t("Common:Create"), - onClick: () => { - this.authStore.infoPanelStore.setIsVisible(false); - const filesFilter = FilesFilter.getDefault(); - filesFilter.folder = this.oformFromFolderId; - const filterUrlParams = filesFilter.toUrlParams(); - const url = getCategoryUrl( - CategoryType.Personal, - filterUrlParams.folder - ); - navigate( - combineUrl( - window.DocSpaceConfig?.proxy?.url, - config.homepage, - `${url}?${filterUrlParams}` - ) - ); - }, - }, - { - key: "preview", - label: t("Common:Preview"), - onClick: () => { - this.mediaFormViewerDataStore.setMediaViewerData({ - visible: true, - id: item.id, - }); - this.mediaFormViewerDataStore.saveFirstUrl( - `${window.DocSpace.location.pathname}${window.DocSpace.location.search}` - ); - this.mediaFormViewerDataStore.changeUrl(item.id); - }, - }, - { - key: "template-info", - label: t("FormGallery:TemplateInfo"), - onClick: () => { - this.authStore.infoPanelStore.setIsVisible(true); - this.setGallerySelected(item); - }, - }, - { - key: "separator", - isSeparator: true, - }, - { - key: "suggest-changes", - label: t("FormGallery:SuggestChanges"), - onClick: () => { - window.location = `mailto:marketing@onlyoffice.com - ?subject=Suggesting changes for ${item.attributes.name_form} - &body=Suggesting changes for ${item.attributes.name_form}. - `; - }, - }, - ]; - submitToFormGallery = async (file, formName, language, signal = null) => { const url = this.authStore.settingsStore.formGallery.uploadUrl; const res = await submitToGallery(url, file, formName, language, signal); @@ -180,13 +119,20 @@ class OformsStore { }); }; - fetchCategoryFilterMenuItems = async () => { + fetchCategoryList = async () => { const url = "https://oforms.onlyoffice.com/dashboard/api/menu-translations"; const locale = getDefaultOformLocale(); - const menuItems = await getCategoryFilterMenuItems(url, locale); + const menuItems = await getCategoryList(url, locale); return menuItems; }; + fetchCategories = async (id) => { + const url = `https://oforms.onlyoffice.com/dashboard/api/${id}`; + const locale = getDefaultOformLocale(); + const categories = await getCategories(url, locale); + return categories; + }; + fetchCategoriesByBranch = async () => { const url = "https://oforms.onlyoffice.com/dashboard/api/categories"; const { locale } = this.oformsFilter; diff --git a/packages/client/src/store/index.js b/packages/client/src/store/index.js index 2b71392a40..e70948b74f 100644 --- a/packages/client/src/store/index.js +++ b/packages/client/src/store/index.js @@ -37,7 +37,6 @@ import PublicRoomStore from "./PublicRoomStore"; import WebhooksStore from "./WebhooksStore"; import ClientLoadingStore from "./ClientLoadingStore"; -import MediaFormViewerDataStore from "./MediaFormViewerDataStore"; const selectedFolderStore = new SelectedFolderStore(authStore.settingsStore); @@ -83,14 +82,7 @@ const mediaViewerDataStore = new MediaViewerDataStore( publicRoomStore ); -const mediaFormViewerDataStore = new MediaFormViewerDataStore( - filesStore, - settingsStore, - publicRoomStore -); - -const oformsStore = new OformsStore(authStore, mediaFormViewerDataStore); -mediaFormViewerDataStore.oformsStore = oformsStore; +const oformsStore = new OformsStore(authStore); const secondaryProgressDataStore = new SecondaryProgressDataStore(); const primaryProgressDataStore = new PrimaryProgressDataStore(); @@ -142,7 +134,6 @@ const contextOptionsStore = new ContextOptionsStore( filesActionsStore, filesStore, mediaViewerDataStore, - mediaFormViewerDataStore, treeFoldersStore, uploadDataStore, versionHistoryStore, @@ -211,7 +202,6 @@ const store = { settingsStore, mediaViewerDataStore, - mediaFormViewerDataStore, versionHistoryStore, uploadDataStore, dialogsStore, diff --git a/packages/common/api/oforms/index.js b/packages/common/api/oforms/index.js index 80c7f1ee1f..4c27d72985 100644 --- a/packages/common/api/oforms/index.js +++ b/packages/common/api/oforms/index.js @@ -11,9 +11,14 @@ export const getCategoryById = async (url, categorizeBy, id, locale) => { return res?.data?.data; }; -export const getCategoryFilterMenuItems = async (url, locale = "en") => { +export const getCategoryList = async (url, locale = "en") => { const res = await axios.get(`${url}?populate=*&locale=${locale}`); - return res?.data; + return res?.data?.data; +}; + +export const getCategories = async (url, locale = "en") => { + const res = await axios.get(`${url}?populate=*&locale=${locale}`); + return res?.data?.data; }; export const getCategoriesByBranch = async (url, locale = "en") => { From 0049d1638592e91933ae45d0e455ec7fc70275cf Mon Sep 17 00:00:00 2001 From: mushka-n Date: Mon, 2 Oct 2023 03:30:15 +0300 Subject: [PATCH 063/334] fixed category filtering bug --- .../CategoryFilter/DesktopView/index.js | 4 ++-- .../Filter/CategoryFilter/MobileView/index.js | 22 +++++++++---------- .../Filter/CategoryFilter/index.js | 17 ++------------ .../client/src/pages/FormGallery/index.js | 6 +---- packages/client/src/store/OformsStore.js | 5 +---- 5 files changed, 16 insertions(+), 38 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js index 2ad819c593..cbf0850d92 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js @@ -88,7 +88,7 @@ const CategoryFilterDesktop = ({ } /> - {menuItems.map((item, index) => ( + {menuItems?.map((item, index) => ( ({ oformsFilter: oformsStore.oformsFilter, filterOformsByCategory: oformsStore.filterOformsByCategory, -}))(withTranslation(["FormGallery"])(observer(CategoryFilterDesktop))); +}))(withTranslation(["FormGallery"])(CategoryFilterDesktop)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js index c4b8e2b1b6..0ee483ccae 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js @@ -2,21 +2,21 @@ import * as Styled from "./index.styled"; import DropDownItem from "@docspace/components/drop-down-item"; import { useState, useRef } from "react"; -import { inject } from "mobx-react"; +import { inject, observer } from "mobx-react"; import { withTranslation } from "react-i18next"; import CategorySubList from "./CategorySubList"; import Scrollbar from "@docspace/components/scrollbar"; import ComboButton from "@docspace/components/combobox/sub-components/combo-button"; +import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; +import { getDefaultOformLocale } from "@docspace/common/utils"; const CategoryFilterMobile = ({ t, menuItems, - onViewAllTemplates, - formsByBranch, - formsByType, - formsByCompilation, + currentCategory, + filterOformsByCategory, ...rest }) => { @@ -39,11 +39,15 @@ const CategoryFilterMobile = ({ if (calculatedHeight > maxCalculatedHeight) calculatedHeight = maxCalculatedHeight; + const onViewAllTemplates = () => filterOformsByCategory("", ""); + return ( ({ currentCategory: oformsStore.currentCategory, - - fetchCategoriesByBranch: oformsStore.fetchCategoriesByBranch, - fetchCategoriesByType: oformsStore.fetchCategoriesByType, - fetchPopularCategories: oformsStore.fetchPopularCategories, - - oformsFilter: oformsStore.oformsFilter, filterOformsByCategory: oformsStore.filterOformsByCategory, }))(withTranslation(["FormGallery"])(CategoryFilterMobile)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js index 5304a35e29..bda91f768a 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js @@ -2,12 +2,10 @@ import { useState, useEffect } from "react"; import { inject, observer } from "mobx-react"; import CategoryFilterDesktop from "./DesktopView"; import CategoryFilterMobile from "./MobileView"; -import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; import { smallTablet } from "@docspace/components/utils/device"; import { isMobileOnly } from "react-device-detect"; import styled, { css } from "styled-components"; -import { getDefaultOformLocale } from "@docspace/common/utils"; export const StyledCategoryFilterWrapper = styled.div` width: 100%; @@ -39,20 +37,14 @@ export const StyledCategoryFilterWrapper = styled.div` `} `; -const categoryLocale = getDefaultOformLocale(); - const CategoryFilter = ({ - currentCategory, oformsFilter, - filterOformsByCategory, fetchCategoryList, fetchCategories, }) => { const [menuItems, setMenuItems] = useState([]); - const onViewAllTemplates = () => filterOformsByCategory("", ""); - useEffect(() => { (async () => { let newMenuItems = await fetchCategoryList(); @@ -81,16 +73,11 @@ const CategoryFilter = ({ }) .finally(() => setMenuItems(newMenuItems)); })(); - }, [oformsFilter.locale]); + }, []); return ( - + ); diff --git a/packages/client/src/pages/FormGallery/index.js b/packages/client/src/pages/FormGallery/index.js index 349c7450cd..a455e224f8 100644 --- a/packages/client/src/pages/FormGallery/index.js +++ b/packages/client/src/pages/FormGallery/index.js @@ -30,12 +30,8 @@ const FormGallery = ({ const [isInitLoading, setIsInitLoading] = useState(true); useEffect(() => { - if ( - !isInitLoading && - location.search !== `?${oformsFilter.toUrlParams()}` - ) { + if (!isInitLoading && location.search !== `?${oformsFilter.toUrlParams()}`) navigate(`${location.pathname}?${oformsFilter.toUrlParams()}`); - } }, [oformsFilter]); useEffect(() => { diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index e71d9c2b44..c9bae07703 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -67,7 +67,6 @@ class OformsStore { filter.total = paginationData.total; } - console.log(oformData?.data?.data); runInAction(() => { this.setOformsFilter(filter); this.setOformFiles(oformData?.data?.data ?? []); @@ -162,9 +161,7 @@ class OformsStore { this.oformsFilter.categoryId = categoryId; const newOformsFilter = this.oformsFilter.clone(); - runInAction(() => { - this.getOforms(newOformsFilter); - }); + runInAction(() => this.getOforms(newOformsFilter)); }; filterOformsByLocale = async (locale) => { From e91f1f2e61aedb54887452ab79789ced56f590aa Mon Sep 17 00:00:00 2001 From: mushka-n Date: Mon, 2 Oct 2023 03:52:47 +0300 Subject: [PATCH 064/334] added translation keys --- packages/client/public/locales/de/FormGallery.json | 8 +++++++- packages/client/public/locales/en/FormGallery.json | 5 ----- packages/client/public/locales/es/FormGallery.json | 8 +++++++- packages/client/public/locales/fr/FormGallery.json | 8 +++++++- packages/client/public/locales/it/FormGallery.json | 8 +++++++- packages/client/public/locales/ja-JP/FormGallery.json | 8 +++++++- packages/client/public/locales/zh-CN/FormGallery.json | 8 +++++++- packages/client/src/helpers/utils.js | 4 ---- 8 files changed, 42 insertions(+), 15 deletions(-) diff --git a/packages/client/public/locales/de/FormGallery.json b/packages/client/public/locales/de/FormGallery.json index 665acd8dc6..1a6cbeba28 100644 --- a/packages/client/public/locales/de/FormGallery.json +++ b/packages/client/public/locales/de/FormGallery.json @@ -2,5 +2,11 @@ "EmptyScreenDescription": "Bitte überprüfen Sie Ihre Internetverbindung und laden Sie die Seite neu oder versuchen Sie es später.", "GalleryEmptyScreenDescription": "Wählen Sie eine beliebige Formularvorlage aus, um die Details zu sehen", "GalleryEmptyScreenHeader": "Formularvorlagen konnten nicht geladen werden", - "TemplateInfo": "Informationen zur Vorlage" + "TemplateInfo": "Informationen zur Vorlage", + + "Categories": "Kategorien", + "ViewAllTemplates": "Alle Vorlagen ansehen", + "EmptyFormGalleryScreenDescription": "Es konnten keine Ergebnisse gefunden werden, die Ihrer Anfrage entsprechen", + "Free": "Kostenlos", + "SuggestChanges": "Änderungen vorschlagen" } diff --git a/packages/client/public/locales/en/FormGallery.json b/packages/client/public/locales/en/FormGallery.json index b6430c6290..a4569b1964 100644 --- a/packages/client/public/locales/en/FormGallery.json +++ b/packages/client/public/locales/en/FormGallery.json @@ -6,12 +6,7 @@ "Categories": "Categories", "ViewAllTemplates": "View all templates", - "FormsByBranch": "Forms by branch", - "FormsByType": "Forms by type", - "PopularCompilations": "Popular Compilations", - "EmptyFormGalleryScreenDescription": "No results matching your query could be found", - "Free": "Free", "SuggestChanges": "Suggest changes", diff --git a/packages/client/public/locales/es/FormGallery.json b/packages/client/public/locales/es/FormGallery.json index 4db943ff82..ab37879ff4 100644 --- a/packages/client/public/locales/es/FormGallery.json +++ b/packages/client/public/locales/es/FormGallery.json @@ -2,5 +2,11 @@ "EmptyScreenDescription": "Por favor, compruebe su conexión a Internet y actualice la página o inténtelo más tarde.", "GalleryEmptyScreenDescription": "Seleccione cualquier plantilla de formulario para ver los detalles", "GalleryEmptyScreenHeader": "Error al cargar las plantillas de formulario", - "TemplateInfo": "Información sobre la plantilla" + "TemplateInfo": "Información sobre la plantilla", + + "Categories": "Categorías", + "ViewAllTemplates": "Ver todas las plantillas", + "EmptyFormGalleryScreenDescription": "No se han encontrado resultados que coincidan con la búsqueda", + "Free": "Gratis", + "SuggestChanges": "Sugerir cambios" } diff --git a/packages/client/public/locales/fr/FormGallery.json b/packages/client/public/locales/fr/FormGallery.json index 46ffd61f25..6ae5f84722 100644 --- a/packages/client/public/locales/fr/FormGallery.json +++ b/packages/client/public/locales/fr/FormGallery.json @@ -2,5 +2,11 @@ "EmptyScreenDescription": "Veuillez vérifier votre connexion Internet et actualisez la page ou réessayez ultérieurement.", "GalleryEmptyScreenDescription": "Sélectionnez un modèle de formulaire pour voir les détails", "GalleryEmptyScreenHeader": "Chargement des modèles de formulaire a échoué", - "TemplateInfo": "Informations sur le modèle" + "TemplateInfo": "Informations sur le modèle", + + "Categories": "Catégories", + "ViewAllTemplates": "Afficher tous les formulaires", + "EmptyFormGalleryScreenDescription": "Aucun résultat correspondant à votre requête n'a pu être trouvé", + "Free": "Gratuit", + "SuggestChanges": "Proposer des modifications" } diff --git a/packages/client/public/locales/it/FormGallery.json b/packages/client/public/locales/it/FormGallery.json index 6908c01c80..ad26f9e94c 100644 --- a/packages/client/public/locales/it/FormGallery.json +++ b/packages/client/public/locales/it/FormGallery.json @@ -2,5 +2,11 @@ "EmptyScreenDescription": "Ti preghiamo di controllare la tua connessione Internet e aggiorna la pagina o riprova più tardi.", "GalleryEmptyScreenDescription": "Seleziona qualsiasi modello di modulo per vedere i dettagli", "GalleryEmptyScreenHeader": "Impossibile caricare i modelli di modulo", - "TemplateInfo": "Informazioni sul modello" + "TemplateInfo": "Informazioni sul modello", + + "Categories": "Categorie", + "ViewAllTemplates": "Visualizzare tutti i modelli", + "EmptyFormGalleryScreenDescription": "Non è stato possibile trovare alcun risultato corrispondente alla tua ricerca", + "Free": "Gratis", + "SuggestChanges": "Suggerire modifiche" } diff --git a/packages/client/public/locales/ja-JP/FormGallery.json b/packages/client/public/locales/ja-JP/FormGallery.json index dae18c7d0a..40e34daff1 100644 --- a/packages/client/public/locales/ja-JP/FormGallery.json +++ b/packages/client/public/locales/ja-JP/FormGallery.json @@ -2,5 +2,11 @@ "EmptyScreenDescription": "インターネット接続をご確認のうえ、ページを更新するか、後でお試しください", "GalleryEmptyScreenDescription": "フォームテンプレートを選択すると、詳細が表示されます", "GalleryEmptyScreenHeader": "フォームテンプレートの読み込みに失敗しました", - "TemplateInfo": "テンプレート情報" + "TemplateInfo": "テンプレート情報", + + "Categories": "カテゴリー", + "ViewAllTemplates": "テンプレート一覧を見る", + "EmptyFormGalleryScreenDescription": "検索条件に一致する結果は見つかりませんでした。", + "Free": "無料", + "SuggestChanges": "変更点のご提案" } diff --git a/packages/client/public/locales/zh-CN/FormGallery.json b/packages/client/public/locales/zh-CN/FormGallery.json index ce9189646f..a2c32566e1 100644 --- a/packages/client/public/locales/zh-CN/FormGallery.json +++ b/packages/client/public/locales/zh-CN/FormGallery.json @@ -2,5 +2,11 @@ "EmptyScreenDescription": "请检查您的互联网连接,刷新页面或稍后再试", "GalleryEmptyScreenDescription": "选择任何表单模板来查看细节、", "GalleryEmptyScreenHeader": "表单模板加载失败、", - "TemplateInfo": "模板信息" + "TemplateInfo": "模板信息", + + "Categories": "类别", + "ViewAllTemplates": "查看模板大全", + "EmptyFormGalleryScreenDescription": "没有找到匹配查询的结果", + "Free": "免费", + "SuggestChanges": "提出修改建议" } diff --git a/packages/client/src/helpers/utils.js b/packages/client/src/helpers/utils.js index 3a823c30ef..db4ebd0f54 100644 --- a/packages/client/src/helpers/utils.js +++ b/packages/client/src/helpers/utils.js @@ -225,10 +225,6 @@ export const filterUserRoleOptions = ( return newOptions; }; -export const getLocalizedOformCategoryTitle = (category, locale = null) => { - if (!category) return ""; -}; - export const getOformCategoryTitle = (category, locale = null) => { if (!category) return ""; From fdb633feff67764dbfb889aa9107b4b3bc7ae6ce Mon Sep 17 00:00:00 2001 From: mushka-n Date: Mon, 2 Oct 2023 04:26:50 +0300 Subject: [PATCH 065/334] code cleanup --- .../CategoryFilter/DesktopView/index.js | 1 + .../Filter/CategoryFilter/index.js | 15 ++-- .../Filter/LanguageFilter/index.js | 87 ++----------------- .../FormGallery/Filter/SortFilter/index.js | 22 ++--- .../src/pages/FormGallery/Filter/index.js | 14 +-- .../Body/views/NoItem/NoGalleryItem.js | 9 +- 6 files changed, 37 insertions(+), 111 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js index cbf0850d92..980a34bebf 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js @@ -90,6 +90,7 @@ const CategoryFilterDesktop = ({ {menuItems?.map((item, index) => ( - (newMenuItems = newMenuItems.map((item, index) => ({ - key: item.attributes.categoryId, - label: item.attributes.name, - categories: results[index], - }))) - ) + .then((results) => { + newMenuItems = newMenuItems.map((item, index) => ({ + key: item.attributes.categoryId, + label: item.attributes.name, + categories: results[index], + })); + }) .catch((err) => { console.error(err); newMenuItems = newMenuItems.map((item) => ({ diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js index f1fb793476..5a00ec168d 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js @@ -1,15 +1,7 @@ import * as Styled from "./index.styled"; -import DropDown from "@docspace/components/drop-down"; -import ExpanderDownReactSvgUrl from "PUBLIC_DIR/images/expander-down.react.svg?url"; -import { ReactSVG } from "react-svg"; -import { useRef, useState, useEffect } from "react"; -import { inject } from "mobx-react"; -import { flagsIcons } from "@docspace/common/utils/image-helpers"; -import { convertToCulture } from "@docspace/common/utils"; -import DropDownItem from "@docspace/components/drop-down-item"; -import ComboBox from "@docspace/components/combobox"; -import { OformCategoryType } from "@docspace/client/src/helpers/constants"; +import { useState } from "react"; +import { inject, observer } from "mobx-react"; import DeReactSvgUrl from "PUBLIC_DIR/images/flags/de.react.svg?url"; import EnUSReactSvgUrl from "PUBLIC_DIR/images/flags/en-US.react.svg?url"; @@ -50,25 +42,8 @@ const locales = [ }, ]; -const LanguageFilter = ({ - oformsFilter, - filterOformsByLocale, - currentColorScheme, -}) => { - const dropdownRef = useRef(null); - - const [currentOption] = locales.filter( - (locale) => locale.key === oformsFilter.locale - ); - - const [selectedOption, setSelectedOption] = useState(currentOption); - - const getSelectedOption = () => { - const [currentOption] = locales.filter( - (locale) => locale.key === oformsFilter.locale - ); - return currentOption; - }; +const LanguageFilter = ({ oformsFilter, filterOformsByLocale }) => { + const [selectedOption] = locales.filter((l) => l.key === oformsFilter.locale); const [isOpen, setIsOpen] = useState(false); const onToggleDropdownIsOpen = () => setIsOpen(!isOpen); @@ -81,13 +56,6 @@ const LanguageFilter = ({ sectionScroll.scrollTop = 0; }; - useEffect(() => { - const [currentOption] = locales.filter( - (locale) => locale.key === oformsFilter.locale - ); - setSelectedOption(currentOption); - }, [oformsFilter.locale]); - return ( ); - - // return ( - // - //
- // {oformsFilter.locale} - // - //
- //
- // - // {avialableLocales.map((locale) => ( - // onFilterByLocale(locale)} - // fillIcon={false} - // /> - // ))} - // - //
- //
- // ); }; export default inject(({ auth, oformsStore }) => ({ oformsFilter: oformsStore.oformsFilter, filterOformsByLocale: oformsStore.filterOformsByLocale, currentColorScheme: auth.settingsStore.currentColorScheme, -}))(LanguageFilter); +}))(observer(LanguageFilter)); diff --git a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js index e89d7ee98f..2ac50c771e 100644 --- a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js @@ -10,16 +10,6 @@ import SortDesc from "PUBLIC_DIR/images/sort.desc.react.svg"; import Backdrop from "@docspace/components/backdrop"; import Text from "@docspace/components/text"; -const sortData = [ - { - id: "sort-by_name", - key: "name_form", - label: "Name", - default: false, - isSelected: false, - }, -]; - const SortFilter = ({ t, oformsFilter, sortOforms }) => { const [isOpen, setIsOpen] = useState(false); const onToggleCombobox = () => setIsOpen(!isOpen); @@ -39,6 +29,16 @@ const SortFilter = ({ t, oformsFilter, sortOforms }) => { onSort(e, newSortBy, oformsFilter.sortOrder === "desc" ? "asc" : "desc"); }; + const sortData = [ + { + id: "sort-by_name", + key: "name_form", + label: t("Common:Name"), + default: false, + isSelected: false, + }, + ]; + return ( <> { export default inject(({ oformsStore }) => ({ oformsFilter: oformsStore.oformsFilter, sortOforms: oformsStore.sortOforms, -}))(withTranslation(["FormGallery", "Common"])(SortFilter)); +}))(withTranslation(["Common"])(SortFilter)); diff --git a/packages/client/src/pages/FormGallery/Filter/index.js b/packages/client/src/pages/FormGallery/Filter/index.js index 0956b013d4..4be2c6cdb7 100644 --- a/packages/client/src/pages/FormGallery/Filter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/index.js @@ -1,15 +1,10 @@ import styled from "styled-components"; -import { inject, observer } from "mobx-react"; -import { useState, useEffect } from "react"; -import { useLocation, useNavigate } from "react-router-dom"; import CategoryFilter from "./CategoryFilter"; import LanguageFilter from "./LanguageFilter"; import SearchFilter from "./SearchFilter"; import SortFilter from "./SortFilter"; -import { smallTablet, tablet } from "@docspace/components/utils/device"; -import { getDefaultOformLocale } from "@docspace/common/utils"; -import OformsFilter from "@docspace/common/api/oforms/filter"; +import { smallTablet } from "@docspace/components/utils/device"; import { Base } from "@docspace/components/themes"; export const StyledFilter = styled.div` @@ -51,7 +46,7 @@ export const StyledFilter = styled.div` StyledFilter.defaultProps = { theme: Base }; -const SectionFilterContent = ({ oformsFilter, setOformsFilter }) => { +const SectionFilterContent = ({}) => { return (
@@ -66,7 +61,4 @@ const SectionFilterContent = ({ oformsFilter, setOformsFilter }) => { ); }; -export default inject(({ oformsStore }) => ({ - oformsFilter: oformsStore.oformsFilter, - setOformsFilter: oformsStore.setOformsFilter, -}))(SectionFilterContent); +export default SectionFilterContent; diff --git a/packages/client/src/pages/Home/InfoPanel/Body/views/NoItem/NoGalleryItem.js b/packages/client/src/pages/Home/InfoPanel/Body/views/NoItem/NoGalleryItem.js index 5cc458b5fa..ae3ddec805 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/views/NoItem/NoGalleryItem.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/views/NoItem/NoGalleryItem.js @@ -9,6 +9,13 @@ const StyledGalleryEmptyScreen = styled.div` margin: 0 auto; padding: 56px 0 48px 0; } + + .info-panel_gallery-empty-screen-text { + font-weight: 600; + font-size: 14px; + line-height: 16px; + text-align: center; + } `; const NoGalleryItem = ({ t }) => { @@ -19,7 +26,7 @@ const NoGalleryItem = ({ t }) => { src={FormGallerySearchReactSvgUrl} alt="Empty Screen Gallery image" /> - + {t("FormGallery:GalleryEmptyScreenDescription")} From 773a6185bd68e83a37fbd8bcc507c6f7d82c3452 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Mon, 2 Oct 2023 04:46:57 +0300 Subject: [PATCH 066/334] code cleanup --- .../Filter/CategoryFilter/DesktopView/index.js | 10 +--------- .../FormGallery/Filter/CategoryFilter/index.js | 15 +-------------- packages/client/src/pages/FormGallery/index.js | 8 -------- 3 files changed, 2 insertions(+), 31 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js index 980a34bebf..1b8341126a 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js @@ -13,17 +13,11 @@ const categoryLocale = getDefaultOformLocale(); const CategoryFilterDesktop = ({ t, - fetchCategoryList, + menuItems, currentCategory, - filterOformsByCategory, - menuItems, - formsByBranch, - formsByType, - formsByCompilation, - ...rest }) => { const [isOpen, setIsOpen] = useState(false); @@ -103,8 +97,6 @@ const CategoryFilterDesktop = ({ ); }; export default inject(({ oformsStore }) => ({ - fetchCategoryList: oformsStore.fetchCategoryList, - currentCategory: oformsStore.currentCategory, fetchCategoriesByBranch: oformsStore.fetchCategoriesByBranch, diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js index 6d600a6c92..a68d9f977c 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js @@ -37,12 +37,7 @@ export const StyledCategoryFilterWrapper = styled.div` `} `; -const CategoryFilter = ({ - oformsFilter, - - fetchCategoryList, - fetchCategories, -}) => { +const CategoryFilter = ({ fetchCategoryList, fetchCategories }) => { const [menuItems, setMenuItems] = useState([]); useEffect(() => { @@ -82,14 +77,6 @@ const CategoryFilter = ({ ); }; export default inject(({ oformsStore }) => ({ - currentCategory: oformsStore.currentCategory, - fetchCategoryList: oformsStore.fetchCategoryList, fetchCategories: oformsStore.fetchCategories, - fetchCategoriesByBranch: oformsStore.fetchCategoriesByBranch, - fetchCategoriesByType: oformsStore.fetchCategoriesByType, - fetchPopularCategories: oformsStore.fetchPopularCategories, - - oformsFilter: oformsStore.oformsFilter, - filterOformsByCategory: oformsStore.filterOformsByCategory, }))(observer(CategoryFilter)); diff --git a/packages/client/src/pages/FormGallery/index.js b/packages/client/src/pages/FormGallery/index.js index a455e224f8..7d0c0fe70c 100644 --- a/packages/client/src/pages/FormGallery/index.js +++ b/packages/client/src/pages/FormGallery/index.js @@ -15,12 +15,9 @@ import { CategoryType } from "@docspace/client/src/helpers/constants"; const FormGallery = ({ currentCategory, fetchCurrentCategory, - filterOformsByLocale, oformsFilter, setOformsFilter, - oformFromFolderId, getOforms, - setOformFiles, setOformFromFolderId, }) => { const location = useLocation(); @@ -100,11 +97,6 @@ export default inject(({ oformsStore }) => ({ oformsFilter: oformsStore.oformsFilter, setOformsFilter: oformsStore.setOformsFilter, - filterOformsByLocale: oformsStore.filterOformsByLocale, - - oformFromFolderId: oformsStore.oformFromFolderId, - getOforms: oformsStore.getOforms, - setOformFiles: oformsStore.setOformFiles, setOformFromFolderId: oformsStore.setOformFromFolderId, }))(observer(FormGallery)); From 0de01527a5b7757ba181e821c1953e02b46a98c8 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Mon, 2 Oct 2023 06:18:18 +0300 Subject: [PATCH 067/334] moved all side methods to store + dark theme fix --- packages/client/src/helpers/utils.js | 20 ---- .../CategoryFilter/DesktopView/SubList.js | 10 +- .../CategoryFilter/DesktopView/index.js | 17 +--- .../MobileView/CategorySubList.js | 10 +- .../Filter/CategoryFilter/MobileView/index.js | 9 +- .../Filter/CategoryFilter/index.js | 15 ++- .../Filter/LanguageFilter/index.js | 66 ++++---------- .../client/src/pages/FormGallery/Header.js | 15 +-- .../client/src/pages/FormGallery/index.js | 6 +- .../Home/InfoPanel/Body/styles/common.js | 9 -- .../Home/InfoPanel/Body/styles/gallery.js | 19 +++- .../InfoPanel/Body/views/Gallery/index.js | 6 +- packages/client/src/store/OformsStore.js | 91 ++++++++++--------- packages/common/api/oforms/filter.js | 4 +- packages/common/api/oforms/index.js | 19 +--- packages/common/utils/index.ts | 43 +++++---- packages/components/themes/base.js | 1 + packages/components/themes/dark.js | 1 + 18 files changed, 153 insertions(+), 208 deletions(-) diff --git a/packages/client/src/helpers/utils.js b/packages/client/src/helpers/utils.js index db4ebd0f54..4e8c862d23 100644 --- a/packages/client/src/helpers/utils.js +++ b/packages/client/src/helpers/utils.js @@ -224,23 +224,3 @@ export const filterUserRoleOptions = ( return newOptions; }; - -export const getOformCategoryTitle = (category, locale = null) => { - if (!category) return ""; - - let categoryType = category.attributes.categorie - ? "categorie" - : category.attributes.type - ? "type" - : "compilation"; - - const categoryTitle = category.attributes[categoryType]; - if (!locale) return categoryTitle; - - const [localizedCategory] = category.attributes.localizations?.data.filter( - (localization) => localization.attributes.locale === locale - ); - return localizedCategory - ? localizedCategory.attributes[categoryType] - : categoryTitle; -}; diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js index f529f8953b..669d44a01b 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/SubList.js @@ -1,10 +1,6 @@ import * as Styled from "./index.styled"; import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; -import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; -import { getDefaultOformLocale } from "@docspace/common/utils"; - -const categoryLocale = getDefaultOformLocale(); const SubList = ({ categoryType, @@ -15,6 +11,7 @@ const SubList = ({ marginTop, onCloseDropdown, + getCategoryTitle, filterOformsByCategory, setOformsCurrentCategory, }) => { @@ -48,7 +45,7 @@ const SubList = ({ isNoFixedHeightOptions={false} > {categories.map((category) => { - const categoryTitle = getOformCategoryTitle(category, categoryLocale); + const categoryTitle = getCategoryTitle(category); const onCategoryClick = () => onFilterByCategory(category); return ( ({ - filterOformsByCategory: oformsStore.filterOformsByCategory, + getCategoryTitle: oformsStore.getCategoryTitle, setOformsCurrentCategory: oformsStore.setOformsCurrentCategory, + filterOformsByCategory: oformsStore.filterOformsByCategory, }))(withTranslation(["FormGallery", "Common"])(SubList)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js index 1b8341126a..8ee8e9adce 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/DesktopView/index.js @@ -5,10 +5,6 @@ import { useState } from "react"; import { inject, observer } from "mobx-react"; import { withTranslation } from "react-i18next"; import SubList from "./SubList"; -import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; -import { getDefaultOformLocale } from "@docspace/common/utils"; - -const categoryLocale = getDefaultOformLocale(); const CategoryFilterDesktop = ({ t, @@ -16,6 +12,7 @@ const CategoryFilterDesktop = ({ menuItems, currentCategory, + getCategoryTitle, filterOformsByCategory, ...rest @@ -51,8 +48,7 @@ const CategoryFilterDesktop = ({ advancedOptionsCount={5} selectedOption={{ label: - getOformCategoryTitle(currentCategory, categoryLocale) || - t("FormGallery:Categories"), + getCategoryTitle(currentCategory) || t("FormGallery:Categories"), }} advancedOptions={ <> @@ -98,11 +94,6 @@ const CategoryFilterDesktop = ({ }; export default inject(({ oformsStore }) => ({ currentCategory: oformsStore.currentCategory, - - fetchCategoriesByBranch: oformsStore.fetchCategoriesByBranch, - fetchCategoriesByType: oformsStore.fetchCategoriesByType, - fetchPopularCategories: oformsStore.fetchPopularCategories, - - oformsFilter: oformsStore.oformsFilter, + getCategoryTitle: oformsStore.getCategoryTitle, filterOformsByCategory: oformsStore.filterOformsByCategory, -}))(withTranslation(["FormGallery"])(CategoryFilterDesktop)); +}))(withTranslation(["FormGallery"])(observer(CategoryFilterDesktop))); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js index 140f67cd5f..1a8bc90a04 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/CategorySubList.js @@ -1,16 +1,13 @@ import { StyledSubItemMobile } from "./index.styled"; import { inject } from "mobx-react"; import { withTranslation } from "react-i18next"; -import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; -import { getDefaultOformLocale } from "@docspace/common/utils"; - -const categoryLocale = getDefaultOformLocale(); const CategorySubList = ({ isOpen, categoryType, categories, + getCategoryTitle, filterOformsByCategory, setOformsCurrentCategory, }) => { @@ -25,13 +22,14 @@ const CategorySubList = ({ onFilterByCategory(category)} /> )); }; export default inject(({ oformsStore }) => ({ - filterOformsByCategory: oformsStore.filterOformsByCategory, + getCategoryTitle: oformsStore.getCategoryTitle, setOformsCurrentCategory: oformsStore.setOformsCurrentCategory, + filterOformsByCategory: oformsStore.filterOformsByCategory, }))(withTranslation(["FormGallery", "Common"])(CategorySubList)); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js index 0ee483ccae..17494a43e6 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js @@ -7,8 +7,6 @@ import { withTranslation } from "react-i18next"; import CategorySubList from "./CategorySubList"; import Scrollbar from "@docspace/components/scrollbar"; import ComboButton from "@docspace/components/combobox/sub-components/combo-button"; -import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; -import { getDefaultOformLocale } from "@docspace/common/utils"; const CategoryFilterMobile = ({ t, @@ -16,6 +14,7 @@ const CategoryFilterMobile = ({ menuItems, currentCategory, + getCategoryTitle, filterOformsByCategory, ...rest @@ -46,8 +45,7 @@ const CategoryFilterMobile = ({ ({ currentCategory: oformsStore.currentCategory, + getCategoryTitle: oformsStore.getCategoryTitle, filterOformsByCategory: oformsStore.filterOformsByCategory, -}))(withTranslation(["FormGallery"])(CategoryFilterMobile)); +}))(withTranslation(["FormGallery"])(observer(CategoryFilterMobile))); diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js index a68d9f977c..6db6209c25 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js @@ -37,16 +37,21 @@ export const StyledCategoryFilterWrapper = styled.div` `} `; -const CategoryFilter = ({ fetchCategoryList, fetchCategories }) => { +const CategoryFilter = ({ + fetchCategoryTypes, + fetchCategoriesOfCategoryType, +}) => { const [menuItems, setMenuItems] = useState([]); useEffect(() => { (async () => { - let newMenuItems = await fetchCategoryList(); + let newMenuItems = await fetchCategoryTypes(); const categoryPromises = newMenuItems.map( (item) => - new Promise((res) => res(fetchCategories(item.attributes.categoryId))) + new Promise((res) => + res(fetchCategoriesOfCategoryType(item.attributes.categoryId)) + ) ); Promise.all(categoryPromises) @@ -77,6 +82,6 @@ const CategoryFilter = ({ fetchCategoryList, fetchCategories }) => { ); }; export default inject(({ oformsStore }) => ({ - fetchCategoryList: oformsStore.fetchCategoryList, - fetchCategories: oformsStore.fetchCategories, + fetchCategoryTypes: oformsStore.fetchCategoryTypes, + fetchCategoriesOfCategoryType: oformsStore.fetchCategoriesOfCategoryType, }))(observer(CategoryFilter)); diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js index 5a00ec168d..3f8ad6d9da 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js @@ -3,48 +3,14 @@ import * as Styled from "./index.styled"; import { useState } from "react"; import { inject, observer } from "mobx-react"; -import DeReactSvgUrl from "PUBLIC_DIR/images/flags/de.react.svg?url"; -import EnUSReactSvgUrl from "PUBLIC_DIR/images/flags/en-US.react.svg?url"; -import EsReactSvgUrl from "PUBLIC_DIR/images/flags/es.react.svg?url"; -import FrReactSvgUrl from "PUBLIC_DIR/images/flags/fr.react.svg?url"; -import ItReactSvgUrl from "PUBLIC_DIR/images/flags/it.react.svg?url"; -import JaJPReactSvgUrl from "PUBLIC_DIR/images/flags/ja-JP.react.svg?url"; -import ZhCNReactSvgUrl from "PUBLIC_DIR/images/flags/zh-CN.react.svg?url"; - -const locales = [ - { - key: "en", - icon: EnUSReactSvgUrl, - }, - { - key: "zh", - icon: ZhCNReactSvgUrl, - }, - { - key: "it", - icon: ItReactSvgUrl, - }, - { - key: "fr", - icon: FrReactSvgUrl, - }, - { - key: "es", - icon: EsReactSvgUrl, - }, - { - key: "de", - icon: DeReactSvgUrl, - }, - { - key: "ja", - icon: JaJPReactSvgUrl, - }, -]; - -const LanguageFilter = ({ oformsFilter, filterOformsByLocale }) => { - const [selectedOption] = locales.filter((l) => l.key === oformsFilter.locale); +import { flagsIcons } from "@docspace/common/utils/image-flags"; +import { convertToCulture } from "@docspace/common/utils"; +const LanguageFilter = ({ + oformsFilter, + oformLocales, + filterOformsByLocale, +}) => { const [isOpen, setIsOpen] = useState(false); const onToggleDropdownIsOpen = () => setIsOpen(!isOpen); const onCloseDropdown = () => setIsOpen(false); @@ -82,12 +48,12 @@ const LanguageFilter = ({ oformsFilter, filterOformsByLocale }) => { selectedOption={{}} advancedOptions={ <> - {locales.map((locale) => ( + {oformLocales.map((locale) => ( onFilterByLocale(locale.key)} + key={locale} + isSelected={locale === oformsFilter.locale} + icon={flagsIcons?.get(`${convertToCulture(locale)}.react.svg`)} + onClick={() => onFilterByLocale(locale)} fillIcon={false} /> ))} @@ -95,8 +61,10 @@ const LanguageFilter = ({ oformsFilter, filterOformsByLocale }) => { } > @@ -106,6 +74,6 @@ const LanguageFilter = ({ oformsFilter, filterOformsByLocale }) => { export default inject(({ auth, oformsStore }) => ({ oformsFilter: oformsStore.oformsFilter, + oformLocales: oformsStore.oformLocales, filterOformsByLocale: oformsStore.filterOformsByLocale, - currentColorScheme: auth.settingsStore.currentColorScheme, }))(observer(LanguageFilter)); diff --git a/packages/client/src/pages/FormGallery/Header.js b/packages/client/src/pages/FormGallery/Header.js index 65531fdb0d..977c8b6862 100644 --- a/packages/client/src/pages/FormGallery/Header.js +++ b/packages/client/src/pages/FormGallery/Header.js @@ -1,10 +1,10 @@ import PanelReactSvgUrl from "PUBLIC_DIR/images/panel.react.svg?url"; import ArrowPathReactSvgUrl from "PUBLIC_DIR/images/arrow.path.react.svg?url"; -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import { inject, observer } from "mobx-react"; import IconButton from "@docspace/components/icon-button"; import { withTranslation } from "react-i18next"; -import { useNavigate, useParams } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; import { StyledContainer, StyledHeadline, @@ -20,16 +20,11 @@ import TriangleNavigationDownReactSvgUrl from "PUBLIC_DIR/images/triangle.naviga import api from "@docspace/common/api"; import { isMobileOnly } from "react-device-detect"; import DropDownItem from "@docspace/components/drop-down-item"; -import { CategoryType } from "@docspace/client/src/helpers/constants"; -import { getOformCategoryTitle } from "@docspace/client/src/helpers/utils"; -import { getDefaultOformLocale } from "@docspace/common/utils"; - -const categoryLocale = getDefaultOformLocale(); const SectionHeaderContent = ({ t, canSubmitToFormGallery, - + getCategoryTitle, oformFromFolderId, setGallerySelected, @@ -115,8 +110,7 @@ const SectionHeaderContent = ({ /> - {getOformCategoryTitle(currentCategory, categoryLocale) || - t("Common:OFORMsGallery")} + {getCategoryTitle(currentCategory) || t("Common:OFORMsGallery")} { return { categoryType: filesStore.categoryType, + getCategoryTitle: oformsStore.getCategoryTitle, oformFromFolderId: oformsStore.oformFromFolderId, diff --git a/packages/client/src/pages/FormGallery/index.js b/packages/client/src/pages/FormGallery/index.js index 7d0c0fe70c..b42f7f7ac8 100644 --- a/packages/client/src/pages/FormGallery/index.js +++ b/packages/client/src/pages/FormGallery/index.js @@ -15,6 +15,7 @@ import { CategoryType } from "@docspace/client/src/helpers/constants"; const FormGallery = ({ currentCategory, fetchCurrentCategory, + defaultOformLocale, oformsFilter, setOformsFilter, getOforms, @@ -48,8 +49,7 @@ const FormGallery = ({ useEffect(() => { const firstLoadFilter = OformsFilter.getFilter(location); - if (!firstLoadFilter.locale) - firstLoadFilter.locale = getDefaultOformLocale(); + if (!firstLoadFilter.locale) firstLoadFilter.locale = defaultOformLocale; setOformsFilter(firstLoadFilter); getOforms(firstLoadFilter); @@ -94,6 +94,8 @@ export default inject(({ oformsStore }) => ({ currentCategory: oformsStore.currentCategory, fetchCurrentCategory: oformsStore.fetchCurrentCategory, + defaultOformLocale: oformsStore.defaultOformLocale, + oformsFilter: oformsStore.oformsFilter, setOformsFilter: oformsStore.setOformsFilter, diff --git a/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js b/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js index 4fc5b45d73..d1f5aec3f5 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/styles/common.js @@ -173,14 +173,6 @@ const StyledSubtitle = styled.div` padding: 24px 0; `; -const StyledDescription = styled.div` - font-size: 13px; - font-weight: 400; - line-height: 20px; - color: #657077; - white-space: pre-line; -`; - const StyledProperties = styled.div` display: flex; flex-direction: column; @@ -288,5 +280,4 @@ export { StyledSubtitle, StyledProperties, StyledLink, - StyledDescription, }; diff --git a/packages/client/src/pages/Home/InfoPanel/Body/styles/gallery.js b/packages/client/src/pages/Home/InfoPanel/Body/styles/gallery.js index d00ca649e9..484c54297e 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/styles/gallery.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/styles/gallery.js @@ -18,8 +18,6 @@ const StyledGalleryThumbnail = styled.div` } `; -StyledGalleryThumbnail.defaultProps = { theme: Base }; - const StyledGalleryNoThumbnail = styled.div` height: auto; width: 100%; @@ -31,4 +29,19 @@ const StyledGalleryNoThumbnail = styled.div` } `; -export { StyledGalleryThumbnail, StyledGalleryNoThumbnail }; +const StyledGalleryFormDescription = styled.div` + font-size: 13px; + font-weight: 400; + line-height: 20px; + color: ${(props) => props.theme.infoPanel.gallery.descriptionColor}; + white-space: pre-line; +`; + +StyledGalleryThumbnail.defaultProps = { theme: Base }; +StyledGalleryFormDescription.defaultProps = { theme: Base }; + +export { + StyledGalleryThumbnail, + StyledGalleryNoThumbnail, + StyledGalleryFormDescription, +}; diff --git a/packages/client/src/pages/Home/InfoPanel/Body/views/Gallery/index.js b/packages/client/src/pages/Home/InfoPanel/Body/views/Gallery/index.js index efcfc60a93..de179e9ac5 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/views/Gallery/index.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/views/Gallery/index.js @@ -12,9 +12,9 @@ import { parseAndFormatDate } from "../../helpers/DetailsHelper.js"; import { StyledGalleryNoThumbnail, StyledGalleryThumbnail, + StyledGalleryFormDescription, } from "../../styles/gallery.js"; import { - StyledDescription, StyledLink, StyledProperties, StyledSubtitle, @@ -69,10 +69,10 @@ const Gallery = ({ - + {gallerySelected?.attributes?.template_desc || gallerySelected?.attributes?.description_card} - + diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index c9bae07703..aaa3c0defb 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -5,29 +5,31 @@ import { submitToGallery } from "@docspace/common/api/oforms"; import { getCategoryById, - getCategoryList, - getCategories, - getCategoriesByBranch, - getCategoriesByType, - getPopularCategories, + getCategoryTypes, + getCategoriesOfCategoryType, } from "@docspace/common/api/oforms"; -import { combineUrl, getDefaultOformLocale } from "@docspace/common/utils"; -import FilesFilter from "@docspace/common/api/files/filter"; -import { getCategoryUrl } from "@docspace/client/src/helpers/utils"; -import config from "PACKAGE_FILE"; + +import { getCookie } from "@docspace/common/utils"; +import { LANGUAGE } from "@docspace/common/constants"; + import { CategoryType } from "@docspace/client/src/helpers/constants"; class OformsStore { authStore; oformFiles = null; + gallerySelected = null; + oformsIsLoading = false; + oformsFilter = OformsFilter.getDefault(); - currentCategory = null; oformFromFolderId = CategoryType.SharedRoom; - oformsIsLoading = false; - gallerySelected = null; + currentCategory = null; + // categoryIds = ["categories", "types", "compilations"]; + categoryTypeTitles = ["categorie", "type", "compilation"]; + + oformLocales = ["en", "zh", "it", "fr", "es", "de", "ja"]; submitToGalleryTileIsVisible = !localStorage.getItem( "submitToGalleryTileIsHidden" @@ -38,6 +40,11 @@ class OformsStore { makeAutoObservable(this); } + get defaultOformLocale() { + const userLocale = getCookie(LANGUAGE) || "en"; + return this.oformLocales.includes(userLocale) ? userLocale : "en"; + } + setOformFiles = (oformFiles) => (this.oformFiles = oformFiles); setOformsFilter = (oformsFilter) => (this.oformsFilter = oformsFilter); @@ -90,6 +97,20 @@ class OformsStore { }); }; + getCategoryTitle = (category, locale = this.defaultOformLocale) => { + if (!category) return ""; + + const categoryType = this.categoryTypeTitles.filter( + (categoryTitle) => !!category.attributes[categoryTitle] + ); + const categoryTitle = category.attributes[categoryType]; + + const [localizedCategory] = category.attributes.localizations?.data.filter( + (localization) => localization.attributes.locale === locale + ); + return localizedCategory?.attributes[categoryType] || categoryTitle; + }; + submitToFormGallery = async (file, formName, language, signal = null) => { const url = this.authStore.settingsStore.formGallery.uploadUrl; const res = await submitToGallery(url, file, formName, language, signal); @@ -99,7 +120,7 @@ class OformsStore { fetchCurrentCategory = async () => { const url = "https://oforms.onlyoffice.com/dashboard/api"; const { categorizeBy, categoryId } = this.oformsFilter; - const locale = getDefaultOformLocale(); + const locale = this.defaultOformLocale; if (!categorizeBy || !categoryId) { this.setOformsCurrentCategory(null); @@ -118,41 +139,29 @@ class OformsStore { }); }; - fetchCategoryList = async () => { + fetchCategoryTypes = async () => { const url = "https://oforms.onlyoffice.com/dashboard/api/menu-translations"; - const locale = getDefaultOformLocale(); - const menuItems = await getCategoryList(url, locale); + const locale = this.defaultOformLocale; + + const menuItems = await getCategoryTypes(url, locale); + // this.categoryTypeTitles = menuItems.map((item) => item.attributes.categoryTitle); + // this.locales = menuItems.map((item) => item.attributes.categoryTitle); + this.categoryTypeTitles = ["categorie", "type", "compilation"]; + this.oformLocales = ["en", "zh", "it", "fr", "es", "de", "ja"]; + return menuItems; }; - fetchCategories = async (id) => { - const url = `https://oforms.onlyoffice.com/dashboard/api/${id}`; - const locale = getDefaultOformLocale(); - const categories = await getCategories(url, locale); + fetchCategoriesOfCategoryType = async (categoryTypeId) => { + const url = `https://oforms.onlyoffice.com/dashboard/api/${categoryTypeId}`; + + const categories = await getCategoriesOfCategoryType( + url, + this.defaultOformLocale + ); return categories; }; - fetchCategoriesByBranch = async () => { - const url = "https://oforms.onlyoffice.com/dashboard/api/categories"; - const { locale } = this.oformsFilter; - const categoriesByBranch = await getCategoriesByBranch(url, locale); - return categoriesByBranch; - }; - - fetchCategoriesByType = async () => { - const url = "https://oforms.onlyoffice.com/dashboard/api/types"; - const { locale } = this.oformsFilter; - const categoriesByType = await getCategoriesByType(url, locale); - return categoriesByType; - }; - - fetchPopularCategories = async () => { - const url = "https://oforms.onlyoffice.com/dashboard/api/compilations"; - const { locale } = this.oformsFilter; - const popularCategories = await getPopularCategories(url, locale); - return popularCategories; - }; - filterOformsByCategory = (categorizeBy, categoryId) => { if (!categorizeBy || !categoryId) this.currentCategory = null; diff --git a/packages/common/api/oforms/filter.js b/packages/common/api/oforms/filter.js index da45209fb8..4e64ba08cd 100644 --- a/packages/common/api/oforms/filter.js +++ b/packages/common/api/oforms/filter.js @@ -1,4 +1,4 @@ -import { getDefaultOformLocale, toUrlParams } from "../../utils"; +import { toUrlParams } from "../../utils"; const PAGE = "pagination[page]"; const PAGE_SIZE = "pagination[pageSize]"; @@ -13,7 +13,7 @@ const SORT_ORDER = "sortorder"; const DEFAULT_PAGE = 1; const DEFAULT_PAGE_SIZE = 150; const DEFAULT_TOTAL = 0; -const DEFAULT_LOCALE = getDefaultOformLocale(); +const DEFAULT_LOCALE = null; const DEFAULT_SEARCH = ""; const DEFAULT_SORT_BY = ""; const DEFAULT_SORT_ORDER = ""; diff --git a/packages/common/api/oforms/index.js b/packages/common/api/oforms/index.js index 4c27d72985..5e62e97289 100644 --- a/packages/common/api/oforms/index.js +++ b/packages/common/api/oforms/index.js @@ -11,27 +11,12 @@ export const getCategoryById = async (url, categorizeBy, id, locale) => { return res?.data?.data; }; -export const getCategoryList = async (url, locale = "en") => { +export const getCategoryTypes = async (url, locale = "en") => { const res = await axios.get(`${url}?populate=*&locale=${locale}`); return res?.data?.data; }; -export const getCategories = async (url, locale = "en") => { - const res = await axios.get(`${url}?populate=*&locale=${locale}`); - return res?.data?.data; -}; - -export const getCategoriesByBranch = async (url, locale = "en") => { - const res = await axios.get(`${url}?populate=*&locale=${locale}`); - return res?.data?.data; -}; - -export const getCategoriesByType = async (url, locale = "en") => { - const res = await axios.get(`${url}?populate=*&locale=${locale}`); - return res?.data?.data; -}; - -export const getPopularCategories = async (url, locale = "en") => { +export const getCategoriesOfCategoryType = async (url, locale = "en") => { const res = await axios.get(`${url}?populate=*&locale=${locale}`); return res?.data?.data; }; diff --git a/packages/common/utils/index.ts b/packages/common/utils/index.ts index 81d1cb7ed7..13f5760a63 100644 --- a/packages/common/utils/index.ts +++ b/packages/common/utils/index.ts @@ -205,8 +205,8 @@ export function getCookie(name) { let matches = document.cookie.match( new RegExp( "(?:^|; )" + - name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, "\\$1") + - "=([^;]*)" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, "\\$1") + + "=([^;]*)" ) ); return matches ? decodeURIComponent(matches[1]) : undefined; @@ -275,7 +275,12 @@ export function toCommunityHostname(hostname) { return communityHostname; } -export function getProviderTranslation(provider, t, linked = false, signUp = false) { +export function getProviderTranslation( + provider, + t, + linked = false, + signUp = false +) { const capitalizeProvider = provider.charAt(0).toUpperCase() + provider.slice(1); if (linked) { @@ -286,15 +291,25 @@ export function getProviderTranslation(provider, t, linked = false, signUp = fal case "apple": return signUp ? t("Common:SignUpWithApple") : t("Common:SignInWithApple"); case "google": - return signUp ? t("Common:SignUpWithGoogle") : t("Common:SignInWithGoogle"); + return signUp + ? t("Common:SignUpWithGoogle") + : t("Common:SignInWithGoogle"); case "facebook": - return signUp ? t("Common:SignUpWithFacebook") : t("Common:SignInWithFacebook"); + return signUp + ? t("Common:SignUpWithFacebook") + : t("Common:SignInWithFacebook"); case "twitter": - return signUp ? t("Common:SignUpWithTwitter") : t("Common:SignInWithTwitter"); + return signUp + ? t("Common:SignUpWithTwitter") + : t("Common:SignInWithTwitter"); case "linkedin": - return signUp ? t("Common:SignUpWithLinkedIn") : t("Common:SignInWithLinkedIn"); + return signUp + ? t("Common:SignUpWithLinkedIn") + : t("Common:SignInWithLinkedIn"); case "microsoft": - return signUp ? t("Common:SignUpWithMicrosoft") : t("Common:SignInWithMicrosoft"); + return signUp + ? t("Common:SignUpWithMicrosoft") + : t("Common:SignInWithMicrosoft"); case "sso": return signUp ? t("Common:SignUpWithSso") : t("Common:SignInWithSso"); case "zoom": @@ -322,12 +337,6 @@ export function getLanguage(lng) { return lng; } -export const getDefaultOformLocale = () => { - const avialableLocales = ["en", "zh", "it", "fr", "es", "de", "ja"]; - const userLocale = getCookie(LANGUAGE) || "en"; - return avialableLocales.includes(userLocale) ? userLocale : "en"; -}; - export const isLanguageRtl = (lng: string) => { if (!lng) return; @@ -442,7 +451,7 @@ export function isElementInViewport(el) { rect.top >= 0 && rect.left >= 0 && rect.bottom <= - (window.innerHeight || document.documentElement.clientHeight) && + (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth) ); } @@ -652,6 +661,6 @@ export const getSystemTheme = () => { : ThemeKeys.BaseStr : window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches - ? ThemeKeys.DarkStr - : ThemeKeys.BaseStr; + ? ThemeKeys.DarkStr + : ThemeKeys.BaseStr; }; diff --git a/packages/components/themes/base.js b/packages/components/themes/base.js index 05018bd7d0..eab5533da0 100644 --- a/packages/components/themes/base.js +++ b/packages/components/themes/base.js @@ -2049,6 +2049,7 @@ const Base = { gallery: { borderColor: "#d0d5da", + descriptionColor: "#657077", }, }, diff --git a/packages/components/themes/dark.js b/packages/components/themes/dark.js index c93386853d..9b45fe55c6 100644 --- a/packages/components/themes/dark.js +++ b/packages/components/themes/dark.js @@ -2045,6 +2045,7 @@ const Dark = { gallery: { borderColor: "#292929", + descriptionColor: "#eeeeee", }, }, From f19ebfde8be3c901cac21418091a53b4c8e634fc Mon Sep 17 00:00:00 2001 From: mushka-n Date: Mon, 2 Oct 2023 06:23:17 +0300 Subject: [PATCH 068/334] code cleanup --- packages/client/src/pages/FormGallery/index.js | 7 +++---- packages/client/src/store/OformsStore.js | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/client/src/pages/FormGallery/index.js b/packages/client/src/pages/FormGallery/index.js index b42f7f7ac8..f0cf67a5a4 100644 --- a/packages/client/src/pages/FormGallery/index.js +++ b/packages/client/src/pages/FormGallery/index.js @@ -10,7 +10,6 @@ import InfoPanelHeaderContent from "../Home/InfoPanel/Header"; import SectionFilterContent from "./Filter"; import OformsFilter from "@docspace/common/api/oforms/filter"; import Dialogs from "./Dialogs"; -import { CategoryType } from "@docspace/client/src/helpers/constants"; const FormGallery = ({ currentCategory, @@ -39,10 +38,10 @@ const FormGallery = ({ useEffect(() => { if (fromFolderId) setOformFromFolderId(fromFolderId); else { - const sharedRoomId = CategoryType.SharedRoom; - setOformFromFolderId(sharedRoomId); + const myDocumentsFolderId = 2; + setOformFromFolderId(myDocumentsFolderId); navigate( - `/form-gallery/${sharedRoomId}/filter?${oformsFilter.toUrlParams()}` + `/form-gallery/${myDocumentsFolderId}/filter?${oformsFilter.toUrlParams()}` ); } }, [fromFolderId]); diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index aaa3c0defb..1969371cdf 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -12,7 +12,7 @@ import { import { getCookie } from "@docspace/common/utils"; import { LANGUAGE } from "@docspace/common/constants"; -import { CategoryType } from "@docspace/client/src/helpers/constants"; +const myDocumentsFolderId = 2; class OformsStore { authStore; @@ -23,7 +23,7 @@ class OformsStore { oformsFilter = OformsFilter.getDefault(); - oformFromFolderId = CategoryType.SharedRoom; + oformFromFolderId = myDocumentsFolderId; currentCategory = null; // categoryIds = ["categories", "types", "compilations"]; From a22635b7a81f33f50021377bda949fab384ad9e1 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Thu, 5 Oct 2023 11:29:18 +0300 Subject: [PATCH 069/334] move to new repo model --- .../client/src/pages/FormGallery/Header.js | 64 ++++++++++------- .../pages/FormGallery/TilesView/FileTile.js | 1 - .../TilesView/sub-components/InfiniteGrid.js | 4 +- .../client/src/pages/FormGallery/index.js | 34 +++++---- packages/client/src/store/OformsStore.js | 72 +++++++++++++------ packages/common/api/oforms/index.js | 5 ++ packages/common/api/settings/index.js | 4 -- .../common/components/MediaViewer/index.tsx | 2 - .../sub-components/Viewer/Viewer.props.ts | 1 - .../sub-components/Viewer/index.tsx | 27 +------ .../ViewerWrapper/ViewerWrapper.props.ts | 1 - .../sub-components/ViewerWrapper/index.tsx | 1 - packages/common/store/AuthStore.js | 28 -------- 13 files changed, 117 insertions(+), 127 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Header.js b/packages/client/src/pages/FormGallery/Header.js index 977c8b6862..b4c28b1ce7 100644 --- a/packages/client/src/pages/FormGallery/Header.js +++ b/packages/client/src/pages/FormGallery/Header.js @@ -42,7 +42,10 @@ const SectionHeaderContent = ({ }) => { const navigate = useNavigate(); - const [checkboxOptions, setCheckboxOptions] = useState(<>{[]}); + const [checkboxOptions, setCheckboxOptions] = useState({ + fromFolder: null, + viewAll: null, + }); const onNavigateBack = () => { setGallerySelected(null); @@ -73,31 +76,37 @@ const SectionHeaderContent = ({ const prevFolder = oformFromFolderId && (await api.files.getFolderInfo(oformFromFolderId)); - const newCheckboxOptions = []; - if (oformsFilter.categorizeBy && oformsFilter.categoryId) - newCheckboxOptions.push( - - ); if (prevFolder) - newCheckboxOptions.push( - - ); - - setCheckboxOptions(<>{newCheckboxOptions}); + setCheckboxOptions((prev) => ({ + ...prev, + fromFolder: ( + + ), + })); })(); - }, [oformFromFolderId, oformsFilter.categorizeBy, oformsFilter.categoryId]); + }, [oformFromFolderId]); + + useEffect(() => { + let viewAll = null; + if (oformsFilter.categorizeBy && oformsFilter.categoryId) + viewAll = ( + + ); + + setCheckboxOptions((prev) => ({ ...prev, viewAll })); + }, [oformsFilter.categorizeBy, oformsFilter.categoryId]); return ( @@ -117,7 +126,6 @@ const SectionHeaderContent = ({ id="oform-header-combobox" comboIcon={TriangleNavigationDownReactSvgUrl} noBorder - advancedOptions={checkboxOptions} className="oform-header-combobox not-selectable" options={[]} selectedOption={{}} @@ -125,6 +133,12 @@ const SectionHeaderContent = ({ manualX="-32px" title={t("Common:TitleSelectFile")} isMobileView={isMobileOnly} + advancedOptions={ + <> + {!!checkboxOptions.fromFolder && checkboxOptions.fromFolder} + {!!checkboxOptions.viewAll && checkboxOptions.viewAll} + + } /> {canSubmitToFormGallery() && ( diff --git a/packages/client/src/pages/FormGallery/TilesView/FileTile.js b/packages/client/src/pages/FormGallery/TilesView/FileTile.js index 09c91284aa..317e280dfa 100644 --- a/packages/client/src/pages/FormGallery/TilesView/FileTile.js +++ b/packages/client/src/pages/FormGallery/TilesView/FileTile.js @@ -1,4 +1,3 @@ -import React from "react"; import Tile from "./sub-components/Tile"; import { SimpleFilesTileContent } from "./StyledTileView"; import Link from "@docspace/components/link"; diff --git a/packages/client/src/pages/FormGallery/TilesView/sub-components/InfiniteGrid.js b/packages/client/src/pages/FormGallery/TilesView/sub-components/InfiniteGrid.js index 86de474eff..722191587c 100644 --- a/packages/client/src/pages/FormGallery/TilesView/sub-components/InfiniteGrid.js +++ b/packages/client/src/pages/FormGallery/TilesView/sub-components/InfiniteGrid.js @@ -129,7 +129,7 @@ const InfiniteGrid = (props) => { }; export default inject(({ auth, filesStore, oformsStore }) => { - const { oformFiles, hasMoreForms, oformsFilterTotal, loadMoreForms } = + const { oformFiles, hasMoreForms, oformsFilterTotal, fetchMoreOforms } = oformsStore; const { getCountTilesInRow } = filesStore; @@ -141,7 +141,7 @@ export default inject(({ auth, filesStore, oformsStore }) => { filesList: oformFiles, hasMoreFiles: hasMoreForms, filterTotal: oformsFilterTotal, - fetchMoreFiles: loadMoreForms, + fetchMoreFiles: fetchMoreOforms, filesLength, getCountTilesInRow, isVisible, diff --git a/packages/client/src/pages/FormGallery/index.js b/packages/client/src/pages/FormGallery/index.js index f0cf67a5a4..d7d6176b52 100644 --- a/packages/client/src/pages/FormGallery/index.js +++ b/packages/client/src/pages/FormGallery/index.js @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import Section from "@docspace/common/components/Section"; import { observer, inject } from "mobx-react"; import { useLocation, useNavigate, useParams } from "react-router-dom"; @@ -15,9 +15,10 @@ const FormGallery = ({ currentCategory, fetchCurrentCategory, defaultOformLocale, + fetchOformLocales, oformsFilter, setOformsFilter, - getOforms, + fetchOforms, setOformFromFolderId, }) => { const location = useLocation(); @@ -27,13 +28,25 @@ const FormGallery = ({ const [isInitLoading, setIsInitLoading] = useState(true); useEffect(() => { - if (!isInitLoading && location.search !== `?${oformsFilter.toUrlParams()}`) + const firstLoadFilter = OformsFilter.getFilter(location); + fetchOforms(firstLoadFilter); + fetchOformLocales(); + setIsInitLoading(false); + }, []); + + useEffect(() => { + if ( + !isInitLoading && + location.search !== `?${oformsFilter.toUrlParams()}` + ) { + if (!oformsFilter.locale) oformsFilter.locale = defaultOformLocale; navigate(`${location.pathname}?${oformsFilter.toUrlParams()}`); + } }, [oformsFilter]); useEffect(() => { if (!currentCategory) fetchCurrentCategory(); - }, [oformsFilter]); + }, [oformsFilter.categorizeBy, oformsFilter.categoryId]); useEffect(() => { if (fromFolderId) setOformFromFolderId(fromFolderId); @@ -46,16 +59,6 @@ const FormGallery = ({ } }, [fromFolderId]); - useEffect(() => { - const firstLoadFilter = OformsFilter.getFilter(location); - if (!firstLoadFilter.locale) firstLoadFilter.locale = defaultOformLocale; - - setOformsFilter(firstLoadFilter); - getOforms(firstLoadFilter); - - setIsInitLoading(false); - }, []); - return ( <>
({ fetchCurrentCategory: oformsStore.fetchCurrentCategory, defaultOformLocale: oformsStore.defaultOformLocale, + fetchOformLocales: oformsStore.fetchOformLocales, oformsFilter: oformsStore.oformsFilter, setOformsFilter: oformsStore.setOformsFilter, - getOforms: oformsStore.getOforms, + fetchOforms: oformsStore.fetchOforms, setOformFromFolderId: oformsStore.setOformFromFolderId, }))(observer(FormGallery)); diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index 1969371cdf..41ff1f94b8 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -4,6 +4,8 @@ import OformsFilter from "@docspace/common/api/oforms/filter"; import { submitToGallery } from "@docspace/common/api/oforms"; import { + getOformLocales, + getOforms, getCategoryById, getCategoryTypes, getCategoriesOfCategoryType, @@ -26,10 +28,9 @@ class OformsStore { oformFromFolderId = myDocumentsFolderId; currentCategory = null; - // categoryIds = ["categories", "types", "compilations"]; - categoryTypeTitles = ["categorie", "type", "compilation"]; + categoryTitles = []; - oformLocales = ["en", "zh", "it", "fr", "es", "de", "ja"]; + oformLocales = []; submitToGalleryTileIsVisible = !localStorage.getItem( "submitToGalleryTileIsHidden" @@ -65,8 +66,39 @@ class OformsStore { this.authStore.infoPanelStore.setSelection(gallerySelected); }; - getOforms = async (filter = OformsFilter.getDefault()) => { - const oformData = await this.authStore.getOforms(filter); + fetchOformLocales = async () => { + const url = "https://oforms.onlyoffice.com/dashboard/api/i18n/locales"; + const fetchedLocales = await getOformLocales(url); + + const localeKeys = fetchedLocales.map((locale) => locale.code); + this.oformLocales = localeKeys; + + return oformLocales; + }; + + getOforms = (filter = OformsFilter.getDefault()) => { + const formName = "&fields[0]=name_form"; + const updatedAt = "&fields[1]=updatedAt"; + const size = "&fields[2]=file_size"; + const filePages = "&fields[3]=file_pages"; + const defaultDescription = "&fields[4]=description_card"; + const templateDescription = "&fields[5]=template_desc"; + const cardPrewiew = "&populate[card_prewiew][fields][4]=url"; + const templateImage = "&populate[template_image][fields][5]=formats"; + + const fields = `${formName}${updatedAt}${size}${filePages}${defaultDescription}${templateDescription}${cardPrewiew}${templateImage}`; + const params = `?${fields}${filter.toApiUrlParams()}`; + + return new Promise(async (resolve) => { + const apiUrl = `${this.authStore.settingsStore.formGallery.url}${params}`; + let oforms = await getOforms(apiUrl); + console.log(oforms); + resolve(oforms); + }); + }; + + fetchOforms = async (filter = OformsFilter.getDefault()) => { + const oformData = await this.getOforms(filter); const paginationData = oformData?.data?.meta?.pagination; if (paginationData) { @@ -80,14 +112,14 @@ class OformsStore { }); }; - loadMoreForms = async () => { + fetchMoreOforms = async () => { if (!this.hasMoreForms || this.oformsIsLoading) return; this.setOformsIsLoading(true); const newOformsFilter = this.oformsFilter.clone(); newOformsFilter.page += 1; - const oformData = await this.authStore.getOforms(newOformsFilter, true); + const oformData = await this.getOforms(newOformsFilter, true); const newForms = oformData?.data?.data ?? []; runInAction(() => { @@ -100,7 +132,7 @@ class OformsStore { getCategoryTitle = (category, locale = this.defaultOformLocale) => { if (!category) return ""; - const categoryType = this.categoryTypeTitles.filter( + const categoryType = this.categoryTitles.filter( (categoryTitle) => !!category.attributes[categoryTitle] ); const categoryTitle = category.attributes[categoryType]; @@ -123,7 +155,7 @@ class OformsStore { const locale = this.defaultOformLocale; if (!categorizeBy || !categoryId) { - this.setOformsCurrentCategory(null); + this.currentCategory = null; return; } @@ -134,9 +166,7 @@ class OformsStore { locale ); - runInAction(() => { - this.setOformsCurrentCategory(fetchedCategory); - }); + this.currentCategory = fetchedCategory; }; fetchCategoryTypes = async () => { @@ -144,10 +174,8 @@ class OformsStore { const locale = this.defaultOformLocale; const menuItems = await getCategoryTypes(url, locale); - // this.categoryTypeTitles = menuItems.map((item) => item.attributes.categoryTitle); - // this.locales = menuItems.map((item) => item.attributes.categoryTitle); - this.categoryTypeTitles = ["categorie", "type", "compilation"]; - this.oformLocales = ["en", "zh", "it", "fr", "es", "de", "ja"]; + //ToDo configure after api change + this.categoryTitles = ["categorie", "type", "compilation"]; return menuItems; }; @@ -170,7 +198,7 @@ class OformsStore { this.oformsFilter.categoryId = categoryId; const newOformsFilter = this.oformsFilter.clone(); - runInAction(() => this.getOforms(newOformsFilter)); + runInAction(() => this.fetchOforms(newOformsFilter)); }; filterOformsByLocale = async (locale) => { @@ -184,7 +212,7 @@ class OformsStore { this.oformsFilter.categoryId = ""; const newOformsFilter = this.oformsFilter.clone(); - runInAction(() => this.getOforms(newOformsFilter)); + runInAction(() => this.fetchOforms(newOformsFilter)); }; filterOformsBySearch = (search) => { @@ -192,7 +220,7 @@ class OformsStore { this.oformsFilter.search = search; const newOformsFilter = this.oformsFilter.clone(); - runInAction(() => this.getOforms(newOformsFilter)); + runInAction(() => this.fetchOforms(newOformsFilter)); }; sortOforms = (sortBy, sortOrder) => { @@ -203,13 +231,15 @@ class OformsStore { this.oformsFilter.sortOrder = sortOrder; const newOformsFilter = this.oformsFilter.clone(); - runInAction(() => this.getOforms(newOformsFilter)); + runInAction(() => this.fetchOforms(newOformsFilter)); }; resetFilters = () => { this.currentCategory = null; const newOformsFilter = OformsFilter.getDefault(); - runInAction(() => this.getOforms(newOformsFilter)); + newOformsFilter.locale = this.defaultOformLocale; + + runInAction(() => this.fetchOforms(newOformsFilter)); }; hideSubmitToGalleryTile = () => { diff --git a/packages/common/api/oforms/index.js b/packages/common/api/oforms/index.js index 5e62e97289..66fd73cfbf 100644 --- a/packages/common/api/oforms/index.js +++ b/packages/common/api/oforms/index.js @@ -4,6 +4,11 @@ export function getOforms(url) { return axios.get(url); } +export const getOformLocales = async (url) => { + const res = await axios.get(url); + return res?.data; +}; + export const getCategoryById = async (url, categorizeBy, id, locale) => { const res = await axios.get( `${url}/${categorizeBy}/${id}?populate=*&locale=${locale}` diff --git a/packages/common/api/settings/index.js b/packages/common/api/settings/index.js index d1ece08803..6743e607ab 100644 --- a/packages/common/api/settings/index.js +++ b/packages/common/api/settings/index.js @@ -745,10 +745,6 @@ export function getMetadata() { return axios.get("/sso/metadata"); } -export function getOforms(url) { - return axios.get(url); -} - export function submitToGallery(url, file, formName, language) { const formData = new FormData(); formData.append("file", file); diff --git a/packages/common/components/MediaViewer/index.tsx b/packages/common/components/MediaViewer/index.tsx index e4bb7a8469..6c9ee19f52 100644 --- a/packages/common/components/MediaViewer/index.tsx +++ b/packages/common/components/MediaViewer/index.tsx @@ -400,7 +400,6 @@ function MediaViewer({ let isImage = false; let isVideo = false; let isAudio = false; - let isForm = false; let isPdf = false; const archiveRoom = @@ -450,7 +449,6 @@ function MediaViewer({ isImage={isImage} isAudio={isAudio} isVideo={isVideo} - isForm={!!props.isFormGalleryViewer} isPdf={isPdf} isPreviewFile={props.isPreviewFile} onDownloadClick={onDownload} diff --git a/packages/common/components/MediaViewer/sub-components/Viewer/Viewer.props.ts b/packages/common/components/MediaViewer/sub-components/Viewer/Viewer.props.ts index 62bdeb0855..e014a758e4 100644 --- a/packages/common/components/MediaViewer/sub-components/Viewer/Viewer.props.ts +++ b/packages/common/components/MediaViewer/sub-components/Viewer/Viewer.props.ts @@ -9,7 +9,6 @@ interface ViewerProps { isVideo: boolean; visible: boolean; isImage: boolean; - isForm: boolean; isPdf: boolean; playlist: PlaylistType[]; diff --git a/packages/common/components/MediaViewer/sub-components/Viewer/index.tsx b/packages/common/components/MediaViewer/sub-components/Viewer/index.tsx index a638851172..33e0fabf8a 100644 --- a/packages/common/components/MediaViewer/sub-components/Viewer/index.tsx +++ b/packages/common/components/MediaViewer/sub-components/Viewer/index.tsx @@ -7,7 +7,6 @@ import { StyledViewerContainer } from "../../StyledComponents"; import NextButton from "../NextButton"; import PrevButton from "../PrevButton"; import ImageViewer from "../ImageViewer"; -import OformViewer from "../OformViewer"; import MobileDetails from "../MobileDetails"; import DesktopDetails from "../DesktopDetails"; import ViewerPlayer from "../ViewerPlayer"; @@ -189,7 +188,7 @@ function Viewer(props: ViewerProps) { )} - {props.isImage && !props.isForm + {props.isImage ? ReactDOM.createPortal( , containerRef.current ) - : props.isForm - ? ReactDOM.createPortal( - , - containerRef.current - ) : props.isPdf && ReactDOM.createPortal( { - const formName = "&fields[0]=name_form"; - const updatedAt = "&fields[1]=updatedAt"; - const size = "&fields[2]=file_size"; - const filePages = "&fields[3]=file_pages"; - const defaultDescription = "&fields[4]=description_card"; - const templateDescription = "&fields[5]=template_desc"; - const cardPrewiew = "&populate[card_prewiew][fields][4]=url"; - const templateImage = "&populate[template_image][fields][5]=formats"; - - const fields = `${formName}${updatedAt}${size}${filePages}${defaultDescription}${templateDescription}${cardPrewiew}${templateImage}`; - const params = `?${filter.toApiUrlParams()}${fields}`; - - const promise = new Promise(async (resolve, reject) => { - const apiUrl = `${this.settingsStore.formGallery.url}${params}`; - let oforms = await api.settings.getOforms(apiUrl); - - if (!oforms?.data?.data?.length) - oforms = await api.oforms.getOforms( - combineUrl(this.settingsStore.formGallery.url, `${params}&locale=en`) - ); - - resolve(oforms); - }); - - return promise; - }; - getAuthProviders = async () => { const providers = await api.settings.getAuthProviders(); if (providers) this.setProviders(providers); From 858ea68645d1632db035bf8d46ccf6c4055adc6c Mon Sep 17 00:00:00 2001 From: mushka-n Date: Thu, 5 Oct 2023 14:38:53 +0300 Subject: [PATCH 070/334] fix bad merge --- .../InfoPanel/Body/sub-components/ItemTitle/FilesItemTitle.js | 2 +- packages/client/src/store/ContextOptionsStore.js | 2 +- packages/client/src/store/OformsStore.js | 3 --- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/FilesItemTitle.js b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/FilesItemTitle.js index afa9ef2e00..d8a78f0455 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/FilesItemTitle.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/sub-components/ItemTitle/FilesItemTitle.js @@ -2,7 +2,7 @@ import { useRef } from "react"; import { withTranslation } from "react-i18next"; import { Text } from "@docspace/components"; - +import { inject, observer } from "mobx-react"; import PersonPlusReactSvgUrl from "PUBLIC_DIR/images/person+.react.svg?url"; import IconButton from "@docspace/components/icon-button"; import ItemContextOptions from "./ItemContextOptions"; diff --git a/packages/client/src/store/ContextOptionsStore.js b/packages/client/src/store/ContextOptionsStore.js index aee877870f..49d8e9bddd 100644 --- a/packages/client/src/store/ContextOptionsStore.js +++ b/packages/client/src/store/ContextOptionsStore.js @@ -91,7 +91,7 @@ class ContextOptionsStore { settingsStore, selectedFolderStore, publicRoomStore, - oformsStore + oformsStore, pluginStore ) { makeAutoObservable(this); diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index 41ff1f94b8..62353afc88 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -69,11 +69,8 @@ class OformsStore { fetchOformLocales = async () => { const url = "https://oforms.onlyoffice.com/dashboard/api/i18n/locales"; const fetchedLocales = await getOformLocales(url); - const localeKeys = fetchedLocales.map((locale) => locale.code); this.oformLocales = localeKeys; - - return oformLocales; }; getOforms = (filter = OformsFilter.getDefault()) => { From 19208b5e9427bf23498cdcb4062dfeb402486dfe Mon Sep 17 00:00:00 2001 From: mushka-n Date: Wed, 18 Oct 2023 14:26:23 +0300 Subject: [PATCH 071/334] fix merge --- packages/components/utils/cookie.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/components/utils/cookie.js b/packages/components/utils/cookie.js index 695854eac6..2bfc138ffe 100644 --- a/packages/components/utils/cookie.js +++ b/packages/components/utils/cookie.js @@ -1,4 +1,4 @@ -export function getCookie(name) { +function getCookie(name) { let matches = document.cookie.match( new RegExp( "(?:^|; )" + @@ -8,3 +8,5 @@ export function getCookie(name) { ); return matches ? decodeURIComponent(matches[1]) : undefined; } + +export { getCookie }; From 07f7283b72bcf901e996c3504dacc154d695d789 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Wed, 18 Oct 2023 14:41:28 +0300 Subject: [PATCH 072/334] fix after-merge style bugs --- .../Filter/CategoryFilter/index.js | 17 +++----------- .../FormGallery/Filter/SortFilter/index.js | 22 +++++++++---------- .../src/pages/FormGallery/Filter/index.js | 4 ++-- 3 files changed, 16 insertions(+), 27 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js index 6db6209c25..5e710d8a8e 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/index.js @@ -2,10 +2,9 @@ import { useState, useEffect } from "react"; import { inject, observer } from "mobx-react"; import CategoryFilterDesktop from "./DesktopView"; import CategoryFilterMobile from "./MobileView"; -import { smallTablet } from "@docspace/components/utils/device"; -import { isMobileOnly } from "react-device-detect"; +import { mobile, tablet } from "@docspace/components/utils/device"; -import styled, { css } from "styled-components"; +import styled from "styled-components"; export const StyledCategoryFilterWrapper = styled.div` width: 100%; @@ -17,7 +16,7 @@ export const StyledCategoryFilterWrapper = styled.div` display: block; } - @media ${smallTablet} { + @media ${mobile} { .mobileView { display: block; } @@ -25,16 +24,6 @@ export const StyledCategoryFilterWrapper = styled.div` display: none; } } - - ${isMobileOnly && - css` - .mobileView { - display: block; - } - .desktopView { - display: none; - } - `} `; const CategoryFilter = ({ diff --git a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js index 2ac50c771e..d6b4e31ab3 100644 --- a/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/SortFilter/index.js @@ -14,6 +14,16 @@ const SortFilter = ({ t, oformsFilter, sortOforms }) => { const [isOpen, setIsOpen] = useState(false); const onToggleCombobox = () => setIsOpen(!isOpen); + const sortData = [ + { + id: "sort-by_name", + key: "name_form", + label: t("Common:Name"), + default: false, + isSelected: false, + }, + ]; + const onSort = (e, newSortBy, newSortOrder = "asc") => { e.stopPropagation(); if ( @@ -29,16 +39,6 @@ const SortFilter = ({ t, oformsFilter, sortOforms }) => { onSort(e, newSortBy, oformsFilter.sortOrder === "desc" ? "asc" : "desc"); }; - const sortData = [ - { - id: "sort-by_name", - key: "name_form", - label: t("Common:Name"), - default: false, - isSelected: false, - }, - ]; - return ( <> { isSelected={oformsFilter.sortBy === item.key} isDescending={oformsFilter.sortOrder === "desc"} > - {t(`Common:${item.label}`)} + {item.label} onToggleSortOrder(e, item.key)} className="sortorder-arrow" diff --git a/packages/client/src/pages/FormGallery/Filter/index.js b/packages/client/src/pages/FormGallery/Filter/index.js index 4be2c6cdb7..680af69b27 100644 --- a/packages/client/src/pages/FormGallery/Filter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/index.js @@ -4,7 +4,7 @@ import CategoryFilter from "./CategoryFilter"; import LanguageFilter from "./LanguageFilter"; import SearchFilter from "./SearchFilter"; import SortFilter from "./SortFilter"; -import { smallTablet } from "@docspace/components/utils/device"; +import { mobile, tablet } from "@docspace/components/utils/device"; import { Base } from "@docspace/components/themes"; export const StyledFilter = styled.div` @@ -32,7 +32,7 @@ export const StyledFilter = styled.div` gap: 8px; } - @media ${smallTablet} { + @media ${mobile} { height: 72px; flex-direction: ${({ theme }) => From ac26c30397438cccaa643530628e479c1216d436 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Wed, 18 Oct 2023 14:44:28 +0300 Subject: [PATCH 073/334] added categoryTitle parsing from changed api --- packages/client/src/store/OformsStore.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index 62353afc88..54532c7329 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -171,8 +171,9 @@ class OformsStore { const locale = this.defaultOformLocale; const menuItems = await getCategoryTypes(url, locale); - //ToDo configure after api change - this.categoryTitles = ["categorie", "type", "compilation"]; + this.categoryTitles = menuItems.map( + (item) => item.attributes.categoryTitle + ); return menuItems; }; From 7fd0b892c63f1941952fc6017c0a909d1fcce3ab Mon Sep 17 00:00:00 2001 From: mushka-n Date: Wed, 18 Oct 2023 14:46:32 +0300 Subject: [PATCH 074/334] empty language filter on init render fix --- .../src/pages/FormGallery/Filter/LanguageFilter/index.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js index 3f8ad6d9da..9c04b389e1 100644 --- a/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/LanguageFilter/index.js @@ -8,6 +8,7 @@ import { convertToCulture } from "@docspace/common/utils"; const LanguageFilter = ({ oformsFilter, + defaultOformLocale, oformLocales, filterOformsByLocale, }) => { @@ -63,7 +64,9 @@ const LanguageFilter = ({ @@ -72,8 +75,9 @@ const LanguageFilter = ({ ); }; -export default inject(({ auth, oformsStore }) => ({ +export default inject(({ oformsStore }) => ({ oformsFilter: oformsStore.oformsFilter, + defaultOformLocale: oformsStore.defaultOformLocale, oformLocales: oformsStore.oformLocales, filterOformsByLocale: oformsStore.filterOformsByLocale, }))(observer(LanguageFilter)); From fbefa552dd34ac7c86e18f6941b6351aeed8d4b0 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Wed, 18 Oct 2023 14:52:03 +0300 Subject: [PATCH 075/334] fixed template images --- packages/client/src/store/OformsStore.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index 54532c7329..34ba7d4a9a 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -80,11 +80,11 @@ class OformsStore { const filePages = "&fields[3]=file_pages"; const defaultDescription = "&fields[4]=description_card"; const templateDescription = "&fields[5]=template_desc"; - const cardPrewiew = "&populate[card_prewiew][fields][4]=url"; - const templateImage = "&populate[template_image][fields][5]=formats"; + const cardPrewiew = "&populate[card_prewiew][fields][6]=url"; + const templateImage = "&populate[template_image][fields][7]=formats"; const fields = `${formName}${updatedAt}${size}${filePages}${defaultDescription}${templateDescription}${cardPrewiew}${templateImage}`; - const params = `?${fields}${filter.toApiUrlParams()}`; + const params = `?${fields}&${filter.toApiUrlParams()}`; return new Promise(async (resolve) => { const apiUrl = `${this.authStore.settingsStore.formGallery.url}${params}`; From 8a43c9859f90a64b5f3bb80162e150370b7e0764 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Wed, 18 Oct 2023 15:30:48 +0300 Subject: [PATCH 076/334] fix styling after merge 2 --- .../src/pages/FormGallery/Filter/index.js | 10 +++- .../src/pages/FormGallery/StyledGallery.js | 50 +++++++++++-------- .../client/src/pages/FormGallery/index.js | 3 +- packages/common/components/Section/index.js | 3 ++ .../Section/sub-components/section-header.js | 9 ++++ 5 files changed, 53 insertions(+), 22 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Filter/index.js b/packages/client/src/pages/FormGallery/Filter/index.js index 680af69b27..a4f23dd115 100644 --- a/packages/client/src/pages/FormGallery/Filter/index.js +++ b/packages/client/src/pages/FormGallery/Filter/index.js @@ -4,7 +4,7 @@ import CategoryFilter from "./CategoryFilter"; import LanguageFilter from "./LanguageFilter"; import SearchFilter from "./SearchFilter"; import SortFilter from "./SortFilter"; -import { mobile, tablet } from "@docspace/components/utils/device"; +import { hugeDesktop, mobile, tablet } from "@docspace/components/utils/device"; import { Base } from "@docspace/components/themes"; export const StyledFilter = styled.div` @@ -32,6 +32,14 @@ export const StyledFilter = styled.div` gap: 8px; } + @media ${hugeDesktop} { + padding-bottom: 5px; + } + + @media ${tablet} { + padding-bottom: 16px; + } + @media ${mobile} { height: 72px; diff --git a/packages/client/src/pages/FormGallery/StyledGallery.js b/packages/client/src/pages/FormGallery/StyledGallery.js index 7d89817217..8d3a3fc407 100644 --- a/packages/client/src/pages/FormGallery/StyledGallery.js +++ b/packages/client/src/pages/FormGallery/StyledGallery.js @@ -1,6 +1,11 @@ import styled, { css } from "styled-components"; -import { tablet, mobile } from "@docspace/components/utils/device"; +import { + tablet, + mobile, + hugeDesktop, + desktop, +} from "@docspace/components/utils/device"; import Headline from "@docspace/common/components/Headline"; import ComboBox from "@docspace/components/combobox"; import { Base } from "@docspace/components/themes"; @@ -13,21 +18,6 @@ const calculateContainerGridColumns = (isRootFolder, isInfoPanelVisible) => { return result; }; -const StyledHeadline = styled(Headline)` - width: 100%; - font-weight: 700; - font-size: 18px; - line-height: 24px; - @media ${tablet} { - font-size: 21px; - line-height: 28px; - } - @media ${mobile} { - font-size: 18px; - line-height: 24px; - } -`; - const StyledContainer = styled.div` width: 100%; height: 32px; @@ -51,14 +41,34 @@ const StyledContainer = styled.div` theme.interfaceDirection === "rtl" && "transform: scaleX(-1);"} } + height: 69px; + box-sizing: border-box; + @media ${tablet} { - width: 100%; - padding: 16px 0 16px; + height: 69px; + padding: 0; } @media ${mobile} { - width: 100%; - padding: 12px 0 12px; + height: 53px; + padding: 0; + } +`; + +const StyledHeadline = styled(Headline)` + width: 100%; + font-weight: 700; + font-size: 18px; + line-height: 24px; + box-sizing: border-box; + + @media ${tablet} { + font-size: 21px; + line-height: 28px; + } + @media ${mobile} { + font-size: 18px; + line-height: 24px; } `; diff --git a/packages/client/src/pages/FormGallery/index.js b/packages/client/src/pages/FormGallery/index.js index d7d6176b52..8d486131e3 100644 --- a/packages/client/src/pages/FormGallery/index.js +++ b/packages/client/src/pages/FormGallery/index.js @@ -65,8 +65,9 @@ const FormGallery = ({ // withBodyScroll // withBodyAutoFocus={!isMobile} withPaging={false} + isFormGallery > - + diff --git a/packages/common/components/Section/index.js b/packages/common/components/Section/index.js index 9a87305f5e..d2601f0ccf 100644 --- a/packages/common/components/Section/index.js +++ b/packages/common/components/Section/index.js @@ -47,6 +47,7 @@ const Section = (props) => { isInfoPanelScrollLocked, isEmptyPage, isTrashFolder, + isFormGallery, currentDeviceType, } = props; @@ -173,6 +174,7 @@ const Section = (props) => { showText={showText} isEmptyPage={isEmptyPage} isTrashFolder={isTrashFolder} + isFormGallery={isFormGallery} > {sectionHeaderContent ? sectionHeaderContent.props.children @@ -215,6 +217,7 @@ const Section = (props) => { settingsStudio={settingsStudio} isEmptyPage={isEmptyPage} isTrashFolder={isTrashFolder} + isFormGallery={isFormGallery} > {sectionHeaderContent ? sectionHeaderContent.props.children diff --git a/packages/common/components/Section/sub-components/section-header.js b/packages/common/components/Section/sub-components/section-header.js index 57e679a61b..c35d4cbf17 100644 --- a/packages/common/components/Section/sub-components/section-header.js +++ b/packages/common/components/Section/sub-components/section-header.js @@ -17,6 +17,13 @@ const StyledSectionHeader = styled.div` height: 61px; min-height: 61px; + ${({ isFormGallery }) => + isFormGallery && + css` + height: 69px; + min-height: 69px; + `} + .header-container { margin-bottom: 1px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); @@ -85,6 +92,7 @@ const SectionHeader = (props) => { className, isEmptyPage, isTrashFolder, + isFormGallery, ...rest } = props; @@ -95,6 +103,7 @@ const SectionHeader = (props) => { viewAs={viewAs} settingsStudio={settingsStudio} isTrashFolder={isTrashFolder} + isFormGallery={isFormGallery} {...rest} /> ); From b512cc01ba41110d581a5f53a12b16b4e0c0646a Mon Sep 17 00:00:00 2001 From: Vladimir Khvan Date: Thu, 19 Oct 2023 18:38:16 +0500 Subject: [PATCH 077/334] fix Bug 63907 --- packages/client/src/pages/Confirm/sub-components/createUser.js | 2 ++ .../Body/sub-components/main-profile/styled-main-profile.js | 1 + 2 files changed, 3 insertions(+) diff --git a/packages/client/src/pages/Confirm/sub-components/createUser.js b/packages/client/src/pages/Confirm/sub-components/createUser.js index 4fde080def..cfd51748c5 100644 --- a/packages/client/src/pages/Confirm/sub-components/createUser.js +++ b/packages/client/src/pages/Confirm/sub-components/createUser.js @@ -566,6 +566,7 @@ const CreateUserForm = (props) => { isDisabled={isLoading} onChange={onChangeFname} onKeyDown={onKeyPress} + maxLength={40} /> @@ -591,6 +592,7 @@ const CreateUserForm = (props) => { isDisabled={isLoading} onChange={onChangeSname} onKeyDown={onKeyPress} + maxLength={40} /> diff --git a/packages/client/src/pages/Profile/Section/Body/sub-components/main-profile/styled-main-profile.js b/packages/client/src/pages/Profile/Section/Body/sub-components/main-profile/styled-main-profile.js index 6cf85b41b7..19b2aebefc 100644 --- a/packages/client/src/pages/Profile/Section/Body/sub-components/main-profile/styled-main-profile.js +++ b/packages/client/src/pages/Profile/Section/Body/sub-components/main-profile/styled-main-profile.js @@ -83,6 +83,7 @@ export const StyledInfo = styled.div` .profile-block { display: flex; flex-direction: column; + overflow: hidden; .profile-block-field { display: flex; From d612ad2775e0bb92451b1c4ac9f20f23321cd0bc Mon Sep 17 00:00:00 2001 From: Vladimir Khvan Date: Fri, 20 Oct 2023 12:19:50 +0500 Subject: [PATCH 078/334] max length limits were removed --- packages/client/src/pages/Confirm/sub-components/createUser.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/client/src/pages/Confirm/sub-components/createUser.js b/packages/client/src/pages/Confirm/sub-components/createUser.js index cfd51748c5..4fde080def 100644 --- a/packages/client/src/pages/Confirm/sub-components/createUser.js +++ b/packages/client/src/pages/Confirm/sub-components/createUser.js @@ -566,7 +566,6 @@ const CreateUserForm = (props) => { isDisabled={isLoading} onChange={onChangeFname} onKeyDown={onKeyPress} - maxLength={40} /> @@ -592,7 +591,6 @@ const CreateUserForm = (props) => { isDisabled={isLoading} onChange={onChangeSname} onKeyDown={onKeyPress} - maxLength={40} /> From a88b64402f389fa806c0119070a6a183b85eefb2 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Fri, 20 Oct 2023 14:22:32 +0300 Subject: [PATCH 079/334] fix deselect on close action in DownloadAs, Copy, Move and Delete panels --- .../FilesSelector/FilesSelector.types.ts | 1 + .../client/src/components/FilesSelector/index.tsx | 15 +++++++++++---- .../dialogs/ConflictResolveDialog/index.js | 12 ++++++++++-- .../src/components/dialogs/DeleteDialog/index.js | 14 ++++++++++++-- .../components/dialogs/DownloadDialog/index.js | 7 +++++-- .../components/dialogs/MoveToPublicRoom/index.js | 5 ++++- packages/client/src/store/DialogsStore.js | 6 ------ .../selector/sub-components/BreadCrumbs/index.tsx | 2 +- 8 files changed, 44 insertions(+), 18 deletions(-) diff --git a/packages/client/src/components/FilesSelector/FilesSelector.types.ts b/packages/client/src/components/FilesSelector/FilesSelector.types.ts index ff64c5c168..288c398ab2 100644 --- a/packages/client/src/components/FilesSelector/FilesSelector.types.ts +++ b/packages/client/src/components/FilesSelector/FilesSelector.types.ts @@ -151,6 +151,7 @@ export type FilesSelectorProps = { setRestoreAllPanelVisible: (value: boolean) => void; setIsFolderActions: (value: boolean) => void; setMovingInProgress: (value: boolean) => void; + setSelected: (selected: "close" | "none", clearBuffer?: boolean) => void; setConflictDialogData: (conflicts: any, operationData: any) => void; itemOperationToFolder: (operationData: any) => Promise; clearActiveOperations: ( diff --git a/packages/client/src/components/FilesSelector/index.tsx b/packages/client/src/components/FilesSelector/index.tsx index 9c0ae8b6cc..8784ce8a59 100644 --- a/packages/client/src/components/FilesSelector/index.tsx +++ b/packages/client/src/components/FilesSelector/index.tsx @@ -68,6 +68,7 @@ const FilesSelector = ({ itemOperationToFolder, clearActiveOperations, setMovingInProgress, + setSelected, setMoveToPanelVisible, setCopyPanelVisible, setRestoreAllPanelVisible, @@ -300,9 +301,9 @@ const FilesSelector = ({ const onCloseAction = () => { setInfoPanelIsMobileHidden(false); + if (onClose) { onClose(); - return; } @@ -316,6 +317,11 @@ const FilesSelector = ({ } }; + const onCloseAndDeselectAction = () => { + setSelected("none"); + onCloseAction(); + }; + const onSearchAction = (value: string) => { setIsFirstLoad(true); setItems(null); @@ -401,7 +407,7 @@ const FilesSelector = ({ setIsRequestRunning(false); } else { setIsRequestRunning(false); - onCloseAction(); + onCloseAndDeselectAction(); const move = !isCopy; if (move) setMovingInProgress(move); sessionStorage.setItem("filesSelectorPath", `${selectedItemId}`); @@ -425,7 +431,7 @@ const FilesSelector = ({ onSave(null, selectedItemId, fileName, isChecked); onSelectTreeNode && onSelectTreeNode(selectedTreeNode); onSelectFile && onSelectFile(selectedFileInfo, breadCrumbs); - onCloseAction(); + onCloseAndDeselectAction(); //!withoutImmediatelyClose && onCloseAction(); } }; @@ -617,8 +623,8 @@ export default inject( selection, bufferSelection, filesList, - setMovingInProgress, + setSelected, } = filesStore; const selections = @@ -669,6 +675,7 @@ export default inject( itemOperationToFolder, clearActiveOperations, setMovingInProgress, + setSelected, setCopyPanelVisible, setRestoreAllPanelVisible, setIsFolderActions, diff --git a/packages/client/src/components/dialogs/ConflictResolveDialog/index.js b/packages/client/src/components/dialogs/ConflictResolveDialog/index.js index 48e097e7dc..426516cd43 100644 --- a/packages/client/src/components/dialogs/ConflictResolveDialog/index.js +++ b/packages/client/src/components/dialogs/ConflictResolveDialog/index.js @@ -71,6 +71,7 @@ const ConflictResolveDialog = (props) => { activeFiles, setActiveFiles, updateActiveFiles, + setSelected, setMoveToPanelVisible, setCopyPanelVisible, setRestoreAllPanelVisible, @@ -139,7 +140,11 @@ const ConflictResolveDialog = (props) => { } updateActiveFiles(newActiveFiles); - if (!folderIds.length && !newFileIds.length) return onClosePanels(); + if (!folderIds.length && !newFileIds.length) { + setSelected("none"); + onClosePanels(); + return; + } const data = { destFolderId, @@ -151,6 +156,7 @@ const ConflictResolveDialog = (props) => { translations, }; + setSelected("none"); onClosePanels(); try { sessionStorage.setItem("filesSelectorPath", `${destFolderId}`); @@ -274,7 +280,8 @@ export default inject(({ auth, dialogsStore, uploadDataStore, filesStore }) => { } = dialogsStore; const { itemOperationToFolder } = uploadDataStore; - const { activeFiles, setActiveFiles, updateActiveFiles } = filesStore; + const { activeFiles, setActiveFiles, updateActiveFiles, setSelected } = + filesStore; const { settingsStore } = auth; const { theme } = settingsStore; return { @@ -287,6 +294,7 @@ export default inject(({ auth, dialogsStore, uploadDataStore, filesStore }) => { activeFiles, setActiveFiles, updateActiveFiles, + setSelected, setMoveToPanelVisible, setRestoreAllPanelVisible, setCopyPanelVisible, diff --git a/packages/client/src/components/dialogs/DeleteDialog/index.js b/packages/client/src/components/dialogs/DeleteDialog/index.js index 4e86492a9d..9329717487 100644 --- a/packages/client/src/components/dialogs/DeleteDialog/index.js +++ b/packages/client/src/components/dialogs/DeleteDialog/index.js @@ -13,6 +13,7 @@ const DeleteDialogComponent = (props) => { deleteAction, unsubscribeAction, setBufferSelection, + setSelected, setRemoveMediaItem, setDeleteDialogVisible, visible, @@ -56,6 +57,7 @@ const DeleteDialogComponent = (props) => { }; const onDelete = () => { + setSelected("none"); onClose(); const translations = { @@ -72,6 +74,7 @@ const DeleteDialogComponent = (props) => { }; const onUnsubscribe = () => { + setSelected("none"); onClose(); if (!selection.length) return; @@ -95,6 +98,7 @@ const DeleteDialogComponent = (props) => { successRemoveRooms: t("Files:RoomsRemoved"), }; + setSelected("none"); onClose(); const itemsIdDeleteHaveRights = selection @@ -261,8 +265,13 @@ const DeleteDialog = withTranslation([ export default inject( ({ filesStore, dialogsStore, filesActionsStore, treeFoldersStore, auth }) => { - const { selection, isLoading, bufferSelection, setBufferSelection } = - filesStore; + const { + selection, + isLoading, + bufferSelection, + setBufferSelection, + setSelected, + } = filesStore; const { deleteAction, unsubscribeAction, deleteRoomsAction } = filesActionsStore; const { isPrivacyFolder, isRecycleBinFolder, isPersonalRoom, isRoom } = @@ -296,6 +305,7 @@ export default inject( setRemoveMediaItem, setBufferSelection, + setSelected, isRoomDelete, setIsRoomDelete, diff --git a/packages/client/src/components/dialogs/DownloadDialog/index.js b/packages/client/src/components/dialogs/DownloadDialog/index.js index a775f96546..08d3c1ae19 100644 --- a/packages/client/src/components/dialogs/DownloadDialog/index.js +++ b/packages/client/src/components/dialogs/DownloadDialog/index.js @@ -93,13 +93,15 @@ class DownloadDialogComponent extends React.Component { const viewUrl = `${singleFileUrl}&outputtype=${file.value}`; window.open(viewUrl, "_self"); } + this.props.setSelected("none"); this.onClose(); } else if (fileConvertIds.length || folderIds.length) { - this.onClose(); downloadFiles(fileConvertIds, folderIds, { label: t("Translations:ArchivingData"), error: t("Common:ErrorInternalServer"), }); + this.props.setSelected("none"); + this.onClose(); } }; @@ -396,7 +398,7 @@ const DownloadDialog = withTranslation([ export default inject( ({ auth, filesStore, dialogsStore, filesActionsStore, settingsStore }) => { - const { sortedFiles } = filesStore; + const { sortedFiles, setSelected } = filesStore; const { extsConvertible } = settingsStore; const { theme } = auth.settingsStore; @@ -411,6 +413,7 @@ export default inject( extsConvertible, setDownloadDialogVisible, + setSelected, downloadFiles, theme, diff --git a/packages/client/src/components/dialogs/MoveToPublicRoom/index.js b/packages/client/src/components/dialogs/MoveToPublicRoom/index.js index 7d043e7b21..43411f1c4b 100644 --- a/packages/client/src/components/dialogs/MoveToPublicRoom/index.js +++ b/packages/client/src/components/dialogs/MoveToPublicRoom/index.js @@ -26,6 +26,7 @@ const MoveToPublicRoomComponent = (props) => { itemOperationToFolder, clearActiveOperations, setSelectedItems, + setSelected, } = props; const [isLoading, setIsLoading] = useState(false); @@ -53,6 +54,7 @@ const MoveToPublicRoomComponent = (props) => { const onClosePanels = () => { setIsVisible(false); setConflictResolveDialogVisible(false); + setSelected("none"); setMoveToPanelVisible(false); setCopyPanelVisible(false); setRestoreAllPanelVisible(false); @@ -143,7 +145,7 @@ const MoveToPublicRoomDialog = withTranslation([ export default inject( ({ dialogsStore, filesActionsStore, filesStore, uploadDataStore }) => { - const { setMovingInProgress } = filesStore; + const { setMovingInProgress, setSelected } = filesStore; const { moveToPublicRoomVisible, @@ -173,6 +175,7 @@ export default inject( itemOperationToFolder, clearActiveOperations, setSelectedItems, + setSelected, }; } )(observer(MoveToPublicRoomDialog)); diff --git a/packages/client/src/store/DialogsStore.js b/packages/client/src/store/DialogsStore.js index dcb0cbd706..d47ed21177 100644 --- a/packages/client/src/store/DialogsStore.js +++ b/packages/client/src/store/DialogsStore.js @@ -127,8 +127,6 @@ class DialogsStore { }; setMoveToPanelVisible = (visible) => { - !visible && this.deselectActiveFiles(); - if ( visible && !this.filesStore.hasSelection && @@ -144,8 +142,6 @@ class DialogsStore { }; setCopyPanelVisible = (visible) => { - !visible && this.deselectActiveFiles(); - if ( visible && !this.filesStore.hasSelection && @@ -181,7 +177,6 @@ class DialogsStore { }; setDeleteDialogVisible = (deleteDialogVisible) => { - !deleteDialogVisible && this.deselectActiveFiles(); this.deleteDialogVisible = deleteDialogVisible; }; @@ -190,7 +185,6 @@ class DialogsStore { }; setDownloadDialogVisible = (downloadDialogVisible) => { - !downloadDialogVisible && this.deselectActiveFiles(); this.downloadDialogVisible = downloadDialogVisible; }; diff --git a/packages/components/selector/sub-components/BreadCrumbs/index.tsx b/packages/components/selector/sub-components/BreadCrumbs/index.tsx index 3dd744e2dc..2d5639cd6a 100644 --- a/packages/components/selector/sub-components/BreadCrumbs/index.tsx +++ b/packages/components/selector/sub-components/BreadCrumbs/index.tsx @@ -39,7 +39,7 @@ const BreadCrumbs = ({ items.forEach((item) => oldItems.push({ ...item, - id: item.id.toString(), + id: item.id?.toString(), }) ); if (itemsLength > 0) { From 916e4f28dc2cc5a2ca448ed05a2337cdb22c029e Mon Sep 17 00:00:00 2001 From: mushka-n Date: Wed, 25 Oct 2023 10:26:51 +0300 Subject: [PATCH 080/334] fixed categoryFilter mobile offset --- .../pages/FormGallery/Filter/CategoryFilter/MobileView/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js index 17494a43e6..ac1d56e72d 100644 --- a/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js +++ b/packages/client/src/pages/FormGallery/Filter/CategoryFilter/MobileView/index.js @@ -34,7 +34,7 @@ const CategoryFilterMobile = ({ let calculatedHeight = 152.2 + (!openedCategory ? 0 : 36 * openedCategory.categories.length); const maxCalculatedHeight = - window.innerHeight - wrapperRef?.current?.offsetTop - 64; + window.innerHeight - wrapperRef?.current?.offsetTop - 64 - 48; if (calculatedHeight > maxCalculatedHeight) calculatedHeight = maxCalculatedHeight; From 93fab6927ce7726096e2a7eca3e53a2d78d23663 Mon Sep 17 00:00:00 2001 From: mushka-n Date: Wed, 25 Oct 2023 10:38:01 +0300 Subject: [PATCH 081/334] fixed locales parsing --- packages/client/src/store/OformsStore.js | 10 +++++++--- packages/common/utils/index.ts | 23 +++++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/packages/client/src/store/OformsStore.js b/packages/client/src/store/OformsStore.js index 34ba7d4a9a..cbebff9db6 100644 --- a/packages/client/src/store/OformsStore.js +++ b/packages/client/src/store/OformsStore.js @@ -11,7 +11,7 @@ import { getCategoriesOfCategoryType, } from "@docspace/common/api/oforms"; -import { getCookie } from "@docspace/common/utils"; +import { convertToLanguage, getCookie } from "@docspace/common/utils"; import { LANGUAGE } from "@docspace/common/constants"; const myDocumentsFolderId = 2; @@ -42,7 +42,8 @@ class OformsStore { } get defaultOformLocale() { - const userLocale = getCookie(LANGUAGE) || "en"; + const userLocale = convertToLanguage(getCookie(LANGUAGE)) || "en"; + console.log(userLocale); return this.oformLocales.includes(userLocale) ? userLocale : "en"; } @@ -69,7 +70,10 @@ class OformsStore { fetchOformLocales = async () => { const url = "https://oforms.onlyoffice.com/dashboard/api/i18n/locales"; const fetchedLocales = await getOformLocales(url); - const localeKeys = fetchedLocales.map((locale) => locale.code); + const localeKeys = fetchedLocales.map((locale) => + convertToLanguage(locale.code) + ); + console.log(localeKeys); this.oformLocales = localeKeys; }; diff --git a/packages/common/utils/index.ts b/packages/common/utils/index.ts index 64c5118b54..78718bd6a0 100644 --- a/packages/common/utils/index.ts +++ b/packages/common/utils/index.ts @@ -436,7 +436,30 @@ export function convertToCulture(key: string) { case "zh": return "zh-CN"; } + return key; +} +export function convertToLanguage(key: string) { + switch (key) { + case "en-US": + return "en"; + case "el-GR": + return "el"; + case "hy-AM": + return "hy"; + case "ko-KR": + return "ko"; + case "lo-LA": + return "lo"; + case "pt-BR": + return "pt"; + case "uk-UA": + return "uk"; + case "ja-JP": + return "ja"; + case "zh-CN": + return "zh"; + } return key; } From 9ca10c1fcb7d0359da1cf9028703653ec742833b Mon Sep 17 00:00:00 2001 From: Akmal Isomadinov Date: Wed, 25 Oct 2023 13:56:57 +0500 Subject: [PATCH 082/334] Web:Navigation: Fixed the add icon and fixed margin --- .../components/Navigation/sub-components/control-btn.js | 4 ++-- .../common/components/Navigation/sub-components/plus-btn.js | 4 ++-- public/images/icons/17/plus.svg | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 public/images/icons/17/plus.svg diff --git a/packages/common/components/Navigation/sub-components/control-btn.js b/packages/common/components/Navigation/sub-components/control-btn.js index 171eb771d1..8472f17f80 100644 --- a/packages/common/components/Navigation/sub-components/control-btn.js +++ b/packages/common/components/Navigation/sub-components/control-btn.js @@ -14,10 +14,10 @@ const StyledContainer = styled.div` ${(props) => props.theme.interfaceDirection === "rtl" ? css` - margin-right: 20px; + margin-right: 16px; ` : css` - margin-left: 20px; + margin-left: 16px; `} display: flex; align-items: center; diff --git a/packages/common/components/Navigation/sub-components/plus-btn.js b/packages/common/components/Navigation/sub-components/plus-btn.js index 925cdec7b1..13438eb627 100644 --- a/packages/common/components/Navigation/sub-components/plus-btn.js +++ b/packages/common/components/Navigation/sub-components/plus-btn.js @@ -1,7 +1,7 @@ import React, { useState, useRef } from "react"; import PropTypes from "prop-types"; -import PlusReactSvgUrl from "PUBLIC_DIR/images/plus.svg?url"; +import PlusReactSvgUrl from "PUBLIC_DIR/images/icons/17/plus.svg?url"; import IconButton from "@docspace/components/icon-button"; import ContextMenu from "@docspace/components/context-menu"; @@ -35,7 +35,7 @@ const PlusButton = (props) => { onClick={onClick} iconName={PlusReactSvgUrl} id={props.id} - size={15} + size={17} isFill /> + + From 6743b6a2a555d5c00832ce65a27cf5931b085008 Mon Sep 17 00:00:00 2001 From: Akmal Isomadinov Date: Wed, 25 Oct 2023 18:01:39 +0500 Subject: [PATCH 083/334] Web:Client:Article: Fixed catalog icons --- .../components/Article/Body/AccountsItem.js | 8 +- .../components/Article/Body/Items.helper.ts | 74 +++++++++++++++++++ .../src/components/Article/Body/Items.js | 63 +++------------- packages/common/constants/index.js | 1 + .../icons/20/catalog.accounts.react.svg | 3 + .../images/icons/20/catalog.archive.react.svg | 3 + .../icons/20/catalog.favorites.react.svg | 3 + .../images/icons/20/catalog.folder.react.svg | 3 + .../icons/20/catalog.portfolio.react.svg | 3 + .../images/icons/20/catalog.private.react.svg | 10 +++ .../images/icons/20/catalog.recent.react.svg | 10 +++ .../images/icons/20/catalog.rooms.react.svg | 3 + .../images/icons/20/catalog.shared.react.svg | 3 + .../images/icons/20/catalog.trash.react.svg | 3 + public/images/icons/20/catalog.user.react.svg | 10 +++ 15 files changed, 146 insertions(+), 54 deletions(-) create mode 100644 packages/client/src/components/Article/Body/Items.helper.ts create mode 100644 public/images/icons/20/catalog.accounts.react.svg create mode 100644 public/images/icons/20/catalog.archive.react.svg create mode 100644 public/images/icons/20/catalog.favorites.react.svg create mode 100644 public/images/icons/20/catalog.folder.react.svg create mode 100644 public/images/icons/20/catalog.portfolio.react.svg create mode 100644 public/images/icons/20/catalog.private.react.svg create mode 100644 public/images/icons/20/catalog.recent.react.svg create mode 100644 public/images/icons/20/catalog.rooms.react.svg create mode 100644 public/images/icons/20/catalog.shared.react.svg create mode 100644 public/images/icons/20/catalog.trash.react.svg create mode 100644 public/images/icons/20/catalog.user.react.svg diff --git a/packages/client/src/components/Article/Body/AccountsItem.js b/packages/client/src/components/Article/Body/AccountsItem.js index cd11b04202..334884a7f7 100644 --- a/packages/client/src/components/Article/Body/AccountsItem.js +++ b/packages/client/src/components/Article/Body/AccountsItem.js @@ -2,20 +2,24 @@ import { inject, observer } from "mobx-react"; import { withTranslation } from "react-i18next"; +import { FolderType } from "@docspace/common/constants"; + import CatalogItem from "@docspace/components/catalog-item"; -import CatalogAccountsReactSvgUrl from "PUBLIC_DIR/images/catalog.accounts.react.svg?url"; +import { getCatalogIconByFolderType } from "./Items.helper"; const PureAccountsItem = ({ showText, isActive, onClick, t }) => { const onClickAction = React.useCallback(() => { onClick && onClick("accounts"); }, [onClick]); + const icon = getCatalogIconByFolderType(FolderType.Account); + return ( = { + 16: CatalogFolderReactSvgUrl, + 20: CatalogFolder20ReactSvgUrl, +}; + +const icons: Record>> = { + 16: { + [FolderType.USER]: CatalogUserReactSvgUrl, + [FolderType.Rooms]: CatalogRoomsReactSvgUrl, + [FolderType.Archive]: CatalogArchiveReactSvgUrl, + [FolderType.SHARE]: CatalogSharedReactSvgUrl, + [FolderType.COMMON]: CatalogPortfolioReactSvgUrl, + [FolderType.Favorites]: CatalogFavoritesReactSvgUrl, + [FolderType.Recent]: CatalogRecentReactSvgUrl, + [FolderType.Privacy]: CatalogPrivateReactSvgUrl, + [FolderType.TRASH]: CatalogTrashReactSvgUrl, + [FolderType.Account]: CatalogAccountsReactSvgUrl, + }, + 20: { + [FolderType.USER]: CatalogUser20ReactSvgUrl, + [FolderType.Rooms]: CatalogRooms20ReactSvgUrl, + [FolderType.Archive]: CatalogArchive20ReactSvgUrl, + [FolderType.SHARE]: CatalogShared20ReactSvgUrl, + [FolderType.COMMON]: CatalogPortfolio20ReactSvgUrl, + [FolderType.Favorites]: CatalogFavorites20ReactSvgUrl, + [FolderType.Recent]: CatalogRecent20ReactSvgUrl, + [FolderType.Privacy]: CatalogPrivate20ReactSvgUrl, + [FolderType.TRASH]: CatalogTrash20ReactSvgUrl, + [FolderType.Account]: CatalogAccounts20ReactSvgUrl, + }, +}; + +const MobileIconSize = 20; +const DesktopIconSize = 16; + +export const getCatalogIconByFolderType = ( + folderType: FolderUnionType +): string => { + const size: SizeType = + isMobile() || isTablet() ? MobileIconSize : DesktopIconSize; + + return icons[size]?.[folderType] ?? defaultIcon[size]; +}; diff --git a/packages/client/src/components/Article/Body/Items.js b/packages/client/src/components/Article/Body/Items.js index 1ab3adc4e6..40c05f28bf 100644 --- a/packages/client/src/components/Article/Body/Items.js +++ b/packages/client/src/components/Article/Body/Items.js @@ -1,31 +1,24 @@ -import CatalogFolderReactSvgUrl from "PUBLIC_DIR/images/catalog.folder.react.svg?url"; -import ClearTrashReactSvgUrl from "PUBLIC_DIR/images/clear.trash.react.svg?url"; -import CatalogUserReactSvgUrl from "PUBLIC_DIR/images/catalog.user.react.svg?url"; -import CatalogRoomsReactSvgUrl from "PUBLIC_DIR/images/catalog.rooms.react.svg?url"; -import CatalogArchiveReactSvgUrl from "PUBLIC_DIR/images/catalog.archive.react.svg?url"; -import CatalogSharedReactSvgUrl from "PUBLIC_DIR/images/catalog.shared.react.svg?url"; -import CatalogPortfolioReactSvgUrl from "PUBLIC_DIR/images/catalog.portfolio.react.svg?url"; -import CatalogFavoritesReactSvgUrl from "PUBLIC_DIR/images/catalog.favorites.react.svg?url"; -import CatalogRecentReactSvgUrl from "PUBLIC_DIR/images/catalog.recent.react.svg?url"; -import CatalogPrivateReactSvgUrl from "PUBLIC_DIR/images/catalog.private.react.svg?url"; -import CatalogTrashReactSvgUrl from "PUBLIC_DIR/images/catalog.trash.react.svg?url"; -import React, { useState } from "react"; +import PropTypes from "prop-types"; import styled from "styled-components"; -import PropTypes from "prop-types"; +import React, { useState } from "react"; import { inject, observer } from "mobx-react"; -import CatalogItem from "@docspace/components/catalog-item"; +import { withTranslation } from "react-i18next"; + import { FolderType, ShareAccessRights, FolderNames, DeviceType, } from "@docspace/common/constants"; -import { withTranslation } from "react-i18next"; + +import CatalogItem from "@docspace/components/catalog-item"; import DragAndDrop from "@docspace/components/drag-and-drop"; -import SettingsItem from "./SettingsItem"; -import AccountsItem from "./AccountsItem"; import BonusItem from "./BonusItem"; +import AccountsItem from "./AccountsItem"; +import { getCatalogIconByFolderType } from "./Items.helper"; + +import ClearTrashReactSvgUrl from "PUBLIC_DIR/images/clear.trash.react.svg?url"; const StyledDragAndDrop = styled(DragAndDrop)` display: contents; @@ -204,41 +197,7 @@ const Items = ({ ); const getFolderIcon = React.useCallback((item) => { - let iconUrl = CatalogFolderReactSvgUrl; - - switch (item.rootFolderType) { - case FolderType.USER: - iconUrl = CatalogUserReactSvgUrl; - break; - case FolderType.Rooms: - iconUrl = CatalogRoomsReactSvgUrl; - break; - case FolderType.Archive: - iconUrl = CatalogArchiveReactSvgUrl; - break; - case FolderType.SHARE: - iconUrl = CatalogSharedReactSvgUrl; - break; - case FolderType.COMMON: - iconUrl = CatalogPortfolioReactSvgUrl; - break; - case FolderType.Favorites: - iconUrl = CatalogFavoritesReactSvgUrl; - break; - case FolderType.Recent: - iconUrl = CatalogRecentReactSvgUrl; - break; - case FolderType.Privacy: - iconUrl = CatalogPrivateReactSvgUrl; - break; - case FolderType.TRASH: - iconUrl = CatalogTrashReactSvgUrl; - break; - default: - break; - } - - return iconUrl; + return getCatalogIconByFolderType(item.rootFolderType); }, []); const showDragItems = React.useCallback( diff --git a/packages/common/constants/index.js b/packages/common/constants/index.js index 420d572e21..93c8c586de 100644 --- a/packages/common/constants/index.js +++ b/packages/common/constants/index.js @@ -215,6 +215,7 @@ export const FolderType = Object.freeze({ Privacy: 13, Rooms: 14, Archive: 20, + Account: 30, }); // extends FolderType keys diff --git a/public/images/icons/20/catalog.accounts.react.svg b/public/images/icons/20/catalog.accounts.react.svg new file mode 100644 index 0000000000..f4a12bd169 --- /dev/null +++ b/public/images/icons/20/catalog.accounts.react.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/icons/20/catalog.archive.react.svg b/public/images/icons/20/catalog.archive.react.svg new file mode 100644 index 0000000000..07bfbe04e7 --- /dev/null +++ b/public/images/icons/20/catalog.archive.react.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/icons/20/catalog.favorites.react.svg b/public/images/icons/20/catalog.favorites.react.svg new file mode 100644 index 0000000000..98c9a79e1c --- /dev/null +++ b/public/images/icons/20/catalog.favorites.react.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/icons/20/catalog.folder.react.svg b/public/images/icons/20/catalog.folder.react.svg new file mode 100644 index 0000000000..f9492506d8 --- /dev/null +++ b/public/images/icons/20/catalog.folder.react.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/icons/20/catalog.portfolio.react.svg b/public/images/icons/20/catalog.portfolio.react.svg new file mode 100644 index 0000000000..34836194dc --- /dev/null +++ b/public/images/icons/20/catalog.portfolio.react.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/icons/20/catalog.private.react.svg b/public/images/icons/20/catalog.private.react.svg new file mode 100644 index 0000000000..2f43649691 --- /dev/null +++ b/public/images/icons/20/catalog.private.react.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/public/images/icons/20/catalog.recent.react.svg b/public/images/icons/20/catalog.recent.react.svg new file mode 100644 index 0000000000..f58d038a5f --- /dev/null +++ b/public/images/icons/20/catalog.recent.react.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/public/images/icons/20/catalog.rooms.react.svg b/public/images/icons/20/catalog.rooms.react.svg new file mode 100644 index 0000000000..f1e47a8b5a --- /dev/null +++ b/public/images/icons/20/catalog.rooms.react.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/icons/20/catalog.shared.react.svg b/public/images/icons/20/catalog.shared.react.svg new file mode 100644 index 0000000000..18c896ad22 --- /dev/null +++ b/public/images/icons/20/catalog.shared.react.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/icons/20/catalog.trash.react.svg b/public/images/icons/20/catalog.trash.react.svg new file mode 100644 index 0000000000..aced764b82 --- /dev/null +++ b/public/images/icons/20/catalog.trash.react.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/icons/20/catalog.user.react.svg b/public/images/icons/20/catalog.user.react.svg new file mode 100644 index 0000000000..37fd747262 --- /dev/null +++ b/public/images/icons/20/catalog.user.react.svg @@ -0,0 +1,10 @@ + + + + + + + + + + From 05ac738d55d81817393e461f7e04b5fd5e8b3576 Mon Sep 17 00:00:00 2001 From: Akmal Isomadinov Date: Wed, 25 Oct 2023 18:33:42 +0500 Subject: [PATCH 084/334] Web:Article: Fixed the icon of the article menu button --- .../Article/sub-components/article-hide-menu-button.js | 2 +- public/images/article-hide-menu.react.svg | 6 +++--- public/images/article-show-menu.react.svg | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/common/components/Article/sub-components/article-hide-menu-button.js b/packages/common/components/Article/sub-components/article-hide-menu-button.js index 6c0d668a93..3a9b4456e3 100644 --- a/packages/common/components/Article/sub-components/article-hide-menu-button.js +++ b/packages/common/components/Article/sub-components/article-hide-menu-button.js @@ -76,7 +76,7 @@ const StyledHideArticleMenuButton = styled.div` .article-hide-menu-icon_svg, .article-show-menu-icon_svg { - height: 28px; + height: 20px; ${(props) => props.theme.interfaceDirection === "rtl" && css` diff --git a/public/images/article-hide-menu.react.svg b/public/images/article-hide-menu.react.svg index de75c0ce87..2739b8fad2 100644 --- a/public/images/article-hide-menu.react.svg +++ b/public/images/article-hide-menu.react.svg @@ -1,4 +1,4 @@ - - - + + + diff --git a/public/images/article-show-menu.react.svg b/public/images/article-show-menu.react.svg index dbc3cab5dd..9b561f44fe 100644 --- a/public/images/article-show-menu.react.svg +++ b/public/images/article-show-menu.react.svg @@ -1,3 +1,3 @@ - - + + From 8beadcea0d977e968872dacf06c2636731b4e457 Mon Sep 17 00:00:00 2001 From: Akmal Isomadinov Date: Thu, 26 Oct 2023 16:58:40 +0500 Subject: [PATCH 085/334] Web:Badges Fixed convert icon --- packages/client/src/components/Badges.js | 6 +- .../Section/Body/TableView/StyledTable.js | 100 ++++++++---------- public/images/icons/12/refresh.react.svg | 3 + 3 files changed, 54 insertions(+), 55 deletions(-) create mode 100644 public/images/icons/12/refresh.react.svg diff --git a/packages/client/src/components/Badges.js b/packages/client/src/components/Badges.js index 8044a662f4..9b7d5ba26a 100644 --- a/packages/client/src/components/Badges.js +++ b/packages/client/src/components/Badges.js @@ -5,6 +5,7 @@ import FileActionsConvertEditDocReactSvgUrl from "PUBLIC_DIR/images/file.actions import LinkReactSvgUrl from "PUBLIC_DIR/images/link.react.svg?url"; import TabletLinkReactSvgUrl from "PUBLIC_DIR/images/tablet-link.reat.svg?url"; import RefreshReactSvgUrl from "PUBLIC_DIR/images/refresh.react.svg?url"; +import Refresh12ReactSvgUrl from "PUBLIC_DIR/images/icons/12/refresh.react.svg?url"; import React, { useState } from "react"; import styled from "styled-components"; import Badge from "@docspace/components/badge"; @@ -15,7 +16,7 @@ import { FileStatus, RoomsType } from "@docspace/common/constants"; import { Base } from "@docspace/components/themes"; import { ColorTheme, ThemeType } from "@docspace/components/ColorTheme"; -import { isTablet } from "@docspace/components/utils/device"; +import { isTablet, isDesktop } from "@docspace/components/utils/device"; import { classNames } from "@docspace/components/utils/classNames"; const StyledWrapper = styled.div` @@ -102,6 +103,7 @@ const Badges = ({ const contentNewItems = newItems > 999 ? "999+" : newItems; const tabletViewBadge = !isTile && isTablet(); + const desktopView = !isTile && isDesktop(); const sizeBadge = isTile || tabletViewBadge ? "medium" : "small"; @@ -116,7 +118,7 @@ const Badges = ({ const iconEdit = !isForm ? FileActionsConvertEditDocReactSvgUrl : iconForm; - const iconRefresh = RefreshReactSvgUrl; + const iconRefresh = desktopView ? Refresh12ReactSvgUrl : RefreshReactSvgUrl; const iconPin = UnpinReactSvgUrl; diff --git a/packages/client/src/pages/Home/Section/Body/TableView/StyledTable.js b/packages/client/src/pages/Home/Section/Body/TableView/StyledTable.js index 04e05dc8ec..f34267245a 100644 --- a/packages/client/src/pages/Home/Section/Body/TableView/StyledTable.js +++ b/packages/client/src/pages/Home/Section/Body/TableView/StyledTable.js @@ -11,7 +11,7 @@ const hotkeyBorderStyle = css` `; const rowCheckboxDraggingStyle = css` - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-right: -20px; @@ -24,12 +24,12 @@ const rowCheckboxDraggingStyle = css` border-bottom: 1px solid; border-image-slice: 1; - border-image-source: ${props => `linear-gradient(to right, + border-image-source: ${(props) => `linear-gradient(to right, ${props.theme.filesSection.tableView.row.borderColorTransition} 17px, ${props.theme.filesSection.tableView.row.borderColor} 31px)`}; `; const contextMenuWrapperDraggingStyle = css` - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-left: -20px; @@ -42,12 +42,12 @@ const contextMenuWrapperDraggingStyle = css` border-bottom: 1px solid; border-image-slice: 1; - border-image-source: ${props => `linear-gradient(to left, + border-image-source: ${(props) => `linear-gradient(to left, ${props.theme.filesSection.tableView.row.borderColorTransition} 17px, ${props.theme.filesSection.tableView.row.borderColor} 31px)`}; `; const StyledTableRow = styled(TableRow)` - ${props => + ${(props) => props.isRoom && css` .table-container_cell { @@ -55,26 +55,26 @@ const StyledTableRow = styled(TableRow)` max-height: 48px; } `} - ${props => + ${(props) => !props.isDragging && css` :hover { .table-container_cell { cursor: pointer; - background: ${props => + background: ${(props) => `${props.theme.filesSection.tableView.row.backgroundActive} !important`}; - margin-top: ${props => (props.showHotkeyBorder ? "-2px" : "-1px")}; + margin-top: ${(props) => (props.showHotkeyBorder ? "-2px" : "-1px")}; - ${props => + ${(props) => !props.showHotkeyBorder && css` - border-top: ${props => + border-top: ${(props) => `1px solid ${props.theme.filesSection.tableView.row.borderColor}`}; `} } .table-container_file-name-cell { - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-right: -24px; @@ -86,7 +86,7 @@ const StyledTableRow = styled(TableRow)` `} } .table-container_row-context-menu-wrapper { - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-left: -20px; @@ -100,27 +100,27 @@ const StyledTableRow = styled(TableRow)` } `} .table-container_cell { - background: ${props => + background: ${(props) => (props.checked || props.isActive) && `${props.theme.filesSection.tableView.row.backgroundActive} !important`}; - cursor: ${props => + cursor: ${(props) => !props.isThirdPartyFolder && (props.checked || props.isActive) && `url(${CursorPalmSvgUrl}), auto !important`}; - ${props => + ${(props) => props.inProgress && css` pointer-events: none; /* cursor: wait; */ `} - ${props => props.showHotkeyBorder && "border-color: #2DA7DB"} + ${(props) => props.showHotkeyBorder && "border-color: #2DA7DB"} } .table-container_element-wrapper, .table-container_quick-buttons-wrapper { - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` padding-left: 0px; @@ -132,9 +132,9 @@ const StyledTableRow = styled(TableRow)` .table-container_element-wrapper, .table-container_row-loader { - min-width: ${props => (props.isRoom ? "40px" : "36px")}; + min-width: ${(props) => (props.isRoom ? "40px" : "36px")}; - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-right: -20px; @@ -157,7 +157,7 @@ const StyledTableRow = styled(TableRow)` .table-container_row-loader { svg { - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-right: 4px; @@ -173,10 +173,10 @@ const StyledTableRow = styled(TableRow)` } .table-container_file-name-cell { - ${props => + ${(props) => props.showHotkeyBorder && css` - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-right: -24px; @@ -189,11 +189,11 @@ const StyledTableRow = styled(TableRow)` ${hotkeyBorderStyle} `}; - ${props => props.dragging && rowCheckboxDraggingStyle}; + ${(props) => props.dragging && rowCheckboxDraggingStyle}; } .table-container_row-context-menu-wrapper { - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` padding-left: 0px; @@ -202,11 +202,11 @@ const StyledTableRow = styled(TableRow)` padding-right: 0px; `} - ${props => props.dragging && contextMenuWrapperDraggingStyle}; - ${props => + ${(props) => props.dragging && contextMenuWrapperDraggingStyle}; + ${(props) => props.showHotkeyBorder && css` - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-left: -20px; @@ -229,17 +229,10 @@ const StyledTableRow = styled(TableRow)` } .item-file-name { - ${props => - props.theme.interfaceDirection === "rtl" - ? css` - padding: 12px 0px 12px 12px; - ` - : css` - padding: 12px 12px 12px 0px; - `} + padding: 12px 0; } - ${props => + ${(props) => props.showHotkeyBorder && css` .table-container_cell { @@ -265,7 +258,7 @@ const StyledTableRow = styled(TableRow)` } `} - ${props => + ${(props) => props.isHighlight && css` .table-container_cell:not(.table-container_element-wrapper) { @@ -273,7 +266,7 @@ const StyledTableRow = styled(TableRow)` @keyframes Highlight { 0% { - background: ${props => props.theme.filesSection.animationColor}; + background: ${(props) => props.theme.filesSection.animationColor}; } 100% { @@ -286,18 +279,18 @@ const StyledTableRow = styled(TableRow)` .table-container_element-wrapper, .table-container_file-name-cell ) { - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` - padding-left: ${props => props.hideColumns && `0px`}; + padding-left: ${(props) => props.hideColumns && `0px`}; ` : css` - padding-right: ${props => props.hideColumns && `0px`}; + padding-right: ${(props) => props.hideColumns && `0px`}; `} } .table-container_file-name-cell { - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-right: -24px; @@ -309,7 +302,7 @@ const StyledTableRow = styled(TableRow)` `} } .table-container_row-context-menu-wrapper { - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-left: -20px; @@ -328,7 +321,7 @@ const StyledDragAndDrop = styled(DragAndDrop)` `; const StyledBadgesContainer = styled.div` - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-right: 8px; @@ -340,7 +333,7 @@ const StyledBadgesContainer = styled.div` display: flex; align-items: center; - ${props => + ${(props) => props.showHotkeyBorder && css` margin-top: 1px; @@ -349,7 +342,7 @@ const StyledBadgesContainer = styled.div` .badges { display: flex; align-items: center; - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-left: 12px; @@ -360,7 +353,7 @@ const StyledBadgesContainer = styled.div` } .badges:last-child { - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-right: 0px; @@ -372,7 +365,7 @@ const StyledBadgesContainer = styled.div` .badge { cursor: pointer; - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-left: 8px; @@ -395,7 +388,7 @@ const StyledBadgesContainer = styled.div` .badge-version { width: max-content; - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin: 0 -2px -2px 5px; @@ -405,7 +398,7 @@ const StyledBadgesContainer = styled.div` `} > div { - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` padding: 0 4px 0 3.3px; @@ -436,7 +429,7 @@ const StyledQuickButtonsContainer = styled.div` } .badge { - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-left: 14px; @@ -447,7 +440,7 @@ const StyledQuickButtonsContainer = styled.div` } .badge:last-child { - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-left: 10px; @@ -470,7 +463,8 @@ const StyledQuickButtonsContainer = styled.div` .share-button-icon:hover { cursor: pointer; path { - fill: ${props => props.theme.filesSection.tableView.row.shareHoverColor}; + fill: ${(props) => + props.theme.filesSection.tableView.row.shareHoverColor}; } -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } diff --git a/public/images/icons/12/refresh.react.svg b/public/images/icons/12/refresh.react.svg new file mode 100644 index 0000000000..75bca4c34f --- /dev/null +++ b/public/images/icons/12/refresh.react.svg @@ -0,0 +1,3 @@ + + + From 88899dd81940bb23caf9bd00f4ba95f4c1fb6773 Mon Sep 17 00:00:00 2001 From: Akmal Isomadinov Date: Thu, 26 Oct 2023 17:04:29 +0500 Subject: [PATCH 086/334] Web:ContextOptionsStore: Fixed the external link icon --- packages/client/src/store/ContextOptionsStore.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/client/src/store/ContextOptionsStore.js b/packages/client/src/store/ContextOptionsStore.js index 5782239ab9..feb6970ccd 100644 --- a/packages/client/src/store/ContextOptionsStore.js +++ b/packages/client/src/store/ContextOptionsStore.js @@ -31,6 +31,7 @@ import MuteReactSvgUrl from "PUBLIC_DIR/images/mute.react.svg?url"; import ShareReactSvgUrl from "PUBLIC_DIR/images/share.react.svg?url"; import InvitationLinkReactSvgUrl from "PUBLIC_DIR/images/invitation.link.react.svg?url"; import CopyToReactSvgUrl from "PUBLIC_DIR/images/copyTo.react.svg?url"; +import TabletLinkReactSvgUrl from "PUBLIC_DIR/images/tablet-link.reat.svg?url"; import MailReactSvgUrl from "PUBLIC_DIR/images/mail.react.svg?url"; import RoomArchiveSvgUrl from "PUBLIC_DIR/images/room.archive.svg?url"; import PluginActionsSvgUrl from "PUBLIC_DIR/images/plugin.actions.react.svg?url"; @@ -1158,7 +1159,7 @@ class ContextOptionsStore { id: "option_copy-external-link", key: "external-link", label: t("Files:CopyGeneralLink"), - icon: CopyToReactSvgUrl, + icon: TabletLinkReactSvgUrl, disabled: this.treeFoldersStore.isArchiveFolder || (item.roomType !== RoomsType.PublicRoom && From 5bd428ce16753b88a25a55b5933b02cf21055c1c Mon Sep 17 00:00:00 2001 From: Akmal Isomadinov Date: Thu, 26 Oct 2023 17:33:16 +0500 Subject: [PATCH 087/334] Web:Modal: Fixed close icon --- packages/components/modal-dialog/components/CloseButton.js | 4 ++-- public/images/icons/17/cross.react.svg | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 public/images/icons/17/cross.react.svg diff --git a/packages/components/modal-dialog/components/CloseButton.js b/packages/components/modal-dialog/components/CloseButton.js index 5562f37a50..cf5c11e001 100644 --- a/packages/components/modal-dialog/components/CloseButton.js +++ b/packages/components/modal-dialog/components/CloseButton.js @@ -1,6 +1,6 @@ import React from "react"; import PropTypes from "prop-types"; -import CrossIconReactSvgUrl from "PUBLIC_DIR/images/cross.react.svg?url"; +import CrossIconReactSvgUrl from "PUBLIC_DIR/images/icons/17/cross.react.svg?url"; import styled, { css } from "styled-components"; import { mobile } from "../../utils/device"; import IconButton from "../../icon-button"; @@ -59,7 +59,7 @@ const StyledCloseButtonWrapper = styled.div` .close-button, .close-button:hover { cursor: pointer; path { - fill: ${(props) => props.theme.modalDialog.closeButton.fillColor}; + stroke: ${(props) => props.theme.modalDialog.closeButton.fillColor}; } } `; diff --git a/public/images/icons/17/cross.react.svg b/public/images/icons/17/cross.react.svg new file mode 100644 index 0000000000..cd087f4c73 --- /dev/null +++ b/public/images/icons/17/cross.react.svg @@ -0,0 +1,3 @@ + + + From be29044b3fd874e65aa5e310d1e768f82c040b85 Mon Sep 17 00:00:00 2001 From: Akmal Isomadinov Date: Thu, 26 Oct 2023 17:33:40 +0500 Subject: [PATCH 088/334] Web:Article: Fixed close icon --- packages/common/components/Article/styled-article.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/common/components/Article/styled-article.js b/packages/common/components/Article/styled-article.js index c0ac7e396b..fc286d1a8b 100644 --- a/packages/common/components/Article/styled-article.js +++ b/packages/common/components/Article/styled-article.js @@ -4,7 +4,7 @@ import { mobile, tablet } from "@docspace/components/utils/device"; import { Base } from "@docspace/components/themes"; import MenuIcon from "PUBLIC_DIR/images/menu.react.svg"; -import CrossIcon from "PUBLIC_DIR/images/cross.react.svg"; +import CrossIcon from "PUBLIC_DIR/images/icons/17/cross.react.svg"; import { getCorrectFourValuesStyle } from "@docspace/components/utils/rtlUtils"; const StyledArticle = styled.article` @@ -228,7 +228,7 @@ const StyledCrossIcon = styled(CrossIcon)` width: 17px; height: 17px; path { - fill: ${(props) => props.theme.catalog.control.fill}; + stroke: ${(props) => props.theme.catalog.control.fill}; } `; From 2726113dc0f17b9fe17bb8a95ba2c5663bb491bd Mon Sep 17 00:00:00 2001 From: Akmal Isomadinov Date: Thu, 26 Oct 2023 18:51:31 +0500 Subject: [PATCH 089/334] Web:Floating-Button Fixed icons and optimization --- .../floating-button/floating-button.js | 39 +++++++++---------- public/images/icons/16/button.minus.react.svg | 3 ++ public/images/icons/16/button.plus.react.svg | 3 ++ 3 files changed, 24 insertions(+), 21 deletions(-) create mode 100644 public/images/icons/16/button.minus.react.svg create mode 100644 public/images/icons/16/button.plus.react.svg diff --git a/packages/components/floating-button/floating-button.js b/packages/components/floating-button/floating-button.js index 6256d49733..bea8b73218 100644 --- a/packages/components/floating-button/floating-button.js +++ b/packages/components/floating-button/floating-button.js @@ -17,8 +17,8 @@ import ButtonMoveIcon from "PUBLIC_DIR/images/button.move.react.svg"; import ButtonDuplicateIcon from "PUBLIC_DIR/images/button.duplicate.react.svg"; import ButtonAlertIcon from "PUBLIC_DIR/images/button.alert.react.svg"; import commonIconsStyles from "@docspace/components/utils/common-icons-style"; -import ButtonPlusIcon from "PUBLIC_DIR/images/actions.button.plus.react.svg"; -import ButtonMinusIcon from "PUBLIC_DIR/images/actions.button.minus.react.svg"; +import ButtonPlusIcon from "PUBLIC_DIR/images/icons/16/button.plus.react.svg"; +import ButtonMinusIcon from "PUBLIC_DIR/images/icons/16/button.minus.react.svg"; import RefreshIcon from "PUBLIC_DIR/images/refresh.react.svg"; import CloseIcon from "PUBLIC_DIR/images/close-icon.react.svg"; @@ -29,6 +29,17 @@ const StyledButtonAlertIcon = styled(ButtonAlertIcon)` `; const Delay = 1000; + +const icons = { + upload: , + file: , + trash: , + move: , + plus: , + minus: , + icon: , +}; + const FloatingButton = (props) => { const { id, @@ -67,6 +78,10 @@ const FloatingButton = (props) => { }; }, [percent, setAnimationCompleted]); + const iconComponent = useMemo(() => { + return icons[icon] ?? ; + }, [icon]); + return ( {
- - {icon == "upload" ? ( - - ) : icon == "file" ? ( - - ) : icon == "trash" ? ( - - ) : icon == "move" ? ( - - ) : icon == "plus" ? ( - - ) : icon == "minus" ? ( - - ) : icon == "refresh" ? ( - - ) : ( - - )} - + {iconComponent} {alert ? : <>} diff --git a/public/images/icons/16/button.minus.react.svg b/public/images/icons/16/button.minus.react.svg new file mode 100644 index 0000000000..8f9df3e392 --- /dev/null +++ b/public/images/icons/16/button.minus.react.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/icons/16/button.plus.react.svg b/public/images/icons/16/button.plus.react.svg new file mode 100644 index 0000000000..c5bf6c96d4 --- /dev/null +++ b/public/images/icons/16/button.plus.react.svg @@ -0,0 +1,3 @@ + + + From d14a699f5ba697ba30a7f9ec4fc13a221b39e7e1 Mon Sep 17 00:00:00 2001 From: Alexey Safronov Date: Fri, 27 Oct 2023 11:47:37 +0400 Subject: [PATCH 090/334] Fix Bug 64823 - Files. The edit icon next to the new file only appears after the page is refreshed. --- packages/client/src/store/FilesStore.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/client/src/store/FilesStore.js b/packages/client/src/store/FilesStore.js index ab9b68917f..44be661186 100644 --- a/packages/client/src/store/FilesStore.js +++ b/packages/client/src/store/FilesStore.js @@ -2600,6 +2600,7 @@ class FilesStore { addItem = (item, isFolder) => { const { socketHelper } = this.authStore.settingsStore; + const { addSocketSubscribersId } = this.selectedFolderStore; if (isFolder) { const foundIndex = this.folders.findIndex((x) => x.id === item?.id); @@ -2609,6 +2610,8 @@ class FilesStore { console.log("[WS] subscribe to folder changes", item.id, item.title); + addSocketSubscribersId(`DIR-${item.id}`); + socketHelper.emit({ command: "subscribe", data: { @@ -2622,6 +2625,8 @@ class FilesStore { console.log("[WS] subscribe to file changes", item.id, item.title); + addSocketSubscribersId(`FILE-${item.id}`); + socketHelper.emit({ command: "subscribe", data: { roomParts: `FILE-${item.id}`, individual: true }, From 0afb1ea1039a658dcb35bbdf54c1ec2d3e315021 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 27 Oct 2023 11:15:47 +0300 Subject: [PATCH 091/334] Fixed Bug 64819 - Mobile. Fixed embedding settings panel z-index --- .../components/panels/EmbeddingPanel/index.js | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/packages/client/src/components/panels/EmbeddingPanel/index.js b/packages/client/src/components/panels/EmbeddingPanel/index.js index 093dfda39c..111dbdbbd4 100644 --- a/packages/client/src/components/panels/EmbeddingPanel/index.js +++ b/packages/client/src/components/panels/EmbeddingPanel/index.js @@ -6,9 +6,18 @@ import Aside from "@docspace/components/aside"; import { withTranslation } from "react-i18next"; import { StyledEmbeddingPanel, StyledScrollbar } from "./StyledEmbeddingPanel"; import EmbeddingBody from "./EmbeddingBody"; +import Portal from "@docspace/components/portal"; +import { DeviceType } from "@docspace/common/constants"; const EmbeddingPanelComponent = (props) => { - const { t, link, roomId, visible, setEmbeddingPanelIsVisible } = props; + const { + t, + link, + roomId, + visible, + setEmbeddingPanelIsVisible, + currentDeviceType, + } = props; const scrollRef = useRef(null); @@ -27,13 +36,13 @@ const EmbeddingPanelComponent = (props) => { return () => document.removeEventListener("keyup", onKeyPress); }); - return ( + const embeddingPanelComponent = ( ); + + const renderPortal = () => { + const rootElement = document.getElementById("root"); + + return ( + + ); + }; + + return currentDeviceType === DeviceType.mobile + ? renderPortal() + : embeddingPanelComponent; }; -export default inject(({ dialogsStore }) => { +export default inject(({ auth, dialogsStore }) => { const { embeddingPanelIsVisible, setEmbeddingPanelIsVisible, linkParams } = dialogsStore; + const { currentDeviceType } = auth.settingsStore; return { visible: embeddingPanelIsVisible, setEmbeddingPanelIsVisible, link: linkParams?.link?.sharedTo?.shareLink, roomId: linkParams?.roomId, + currentDeviceType, }; })( withTranslation(["Files", "EmbeddingPanel"])( From 29f087bdbd6aeb0766999966fc6013c828da4676 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Fri, 27 Oct 2023 12:00:35 +0300 Subject: [PATCH 092/334] Web: PortalSettings: Backup: Fixed styles for floating button. --- .../data-management/backup/StyledBackup.js | 14 ++++++++++++++ packages/client/src/store/BackupStore.js | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/client/src/pages/PortalSettings/categories/data-management/backup/StyledBackup.js b/packages/client/src/pages/PortalSettings/categories/data-management/backup/StyledBackup.js index 73116d71d5..25ef6a0fe5 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-management/backup/StyledBackup.js +++ b/packages/client/src/pages/PortalSettings/categories/data-management/backup/StyledBackup.js @@ -10,6 +10,13 @@ import { tablet, mobile } from "@docspace/components/utils/device"; const INPUT_LENGTH = "350px"; const TEXT_LENGTH = "700px"; +const floatingButtonStyles = css` + .layout-progress-bar { + position: fixed; + right: 24px; + bottom: 24px; + } +`; const commonStyles = css` .backup_modules-description { margin-bottom: 24px; @@ -97,6 +104,9 @@ const commonStyles = css` const StyledManualBackup = styled.div` ${commonStyles} + + ${floatingButtonStyles} + .manual-backup_buttons { margin-top: 16px; ${(props) => @@ -190,6 +200,8 @@ const StyledManualBackup = styled.div` const StyledAutoBackup = styled.div` ${commonStyles} + + ${floatingButtonStyles} .auto-backup_third-party-module { margin-top: 16px; ${(props) => @@ -328,6 +340,8 @@ const StyledStoragesModule = styled.div` `; const StyledRestoreBackup = styled.div` ${commonStyles} + ${floatingButtonStyles} + .restore-backup_third-party-module { margin-top: 16px; diff --git a/packages/client/src/store/BackupStore.js b/packages/client/src/store/BackupStore.js index af218b55ff..4a5706245a 100644 --- a/packages/client/src/store/BackupStore.js +++ b/packages/client/src/store/BackupStore.js @@ -436,7 +436,7 @@ class BackupStore { return; } - if (progress !== this.downloadingProgress) { + if (progress > 0 && progress !== this.downloadingProgress) { this.downloadingProgress = progress; } From c6745e03fafc88d778eb9477df3301dc3901b2dc Mon Sep 17 00:00:00 2001 From: Aleksandr Date: Fri, 27 Oct 2023 11:49:39 +0200 Subject: [PATCH 093/334] Fix Bug 64811 - Files. Fix deselecting file when click on search input in Move to/Copy panel --- packages/client/src/pages/Home/Section/Body/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/pages/Home/Section/Body/index.js b/packages/client/src/pages/Home/Section/Body/index.js index bf66622e93..386b5c94dd 100644 --- a/packages/client/src/pages/Home/Section/Body/index.js +++ b/packages/client/src/pages/Home/Section/Body/index.js @@ -139,7 +139,7 @@ const SectionBodyContent = (props) => { !e.target.closest(".document-catalog")) || e.target.closest(".files-main-button") || e.target.closest(".add-button") || - e.target.closest(".search-input-block") + e.target.closest("#filter_search-input") ) { setSelection([]); setBufferSelection(null); From 43eaa64ba778ac745e07dabacc3c0fb80ffa16ad Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Fri, 27 Oct 2023 13:29:39 +0300 Subject: [PATCH 094/334] Web: Fixed empty screen styles. --- .../EmptyContainer/EmptyContainer.js | 12 ++++++---- .../sub-components/CommonButtons.js | 24 ++++++++++--------- .../Section/sub-components/info-panel.js | 14 +++++++---- .../styled-empty-screen-container.js | 10 +++++--- packages/components/utils/device.js | 9 +++---- 5 files changed, 43 insertions(+), 26 deletions(-) diff --git a/packages/client/src/components/EmptyContainer/EmptyContainer.js b/packages/client/src/components/EmptyContainer/EmptyContainer.js index 68ed54b348..e0155b225b 100644 --- a/packages/client/src/components/EmptyContainer/EmptyContainer.js +++ b/packages/client/src/components/EmptyContainer/EmptyContainer.js @@ -7,16 +7,20 @@ import { classNames } from "@docspace/components/utils/classNames"; const EmptyFolderWrapper = styled.div` .empty-folder_container { .empty-folder_container-links { - display: grid; - grid-template-columns: 12px 1fr; - grid-column-gap: 8px; - + display: flex; .flex-wrapper_container { display: flex; flex-wrap: wrap; row-gap: 16px; column-gap: 8px; justify-content: center; + + .first-button { + display: flex; + .empty-folder_container-icon { + margin-right: 8px; + } + } } } diff --git a/packages/client/src/components/EmptyContainer/sub-components/CommonButtons.js b/packages/client/src/components/EmptyContainer/sub-components/CommonButtons.js index de00bc5418..fecf06a985 100644 --- a/packages/client/src/components/EmptyContainer/sub-components/CommonButtons.js +++ b/packages/client/src/components/EmptyContainer/sub-components/CommonButtons.js @@ -23,18 +23,20 @@ const OptionsComponent = (props) => { return ( <>
- - - {t("Document")}, - +
+ + + {t("Document")}, + +
{t("Spreadsheet")}, diff --git a/packages/common/components/Section/sub-components/info-panel.js b/packages/common/components/Section/sub-components/info-panel.js index 1efb19def4..423e31c511 100644 --- a/packages/common/components/Section/sub-components/info-panel.js +++ b/packages/common/components/Section/sub-components/info-panel.js @@ -1,5 +1,9 @@ import { Base } from "@docspace/components/themes"; -import { tablet, mobile } from "@docspace/components/utils/device"; +import { + tablet, + mobile, + infoPanelWidth, +} from "@docspace/components/utils/device"; import { inject } from "mobx-react"; import PropTypes from "prop-types"; import React, { useEffect } from "react"; @@ -30,7 +34,7 @@ const StyledInfoPanelWrapper = styled.div.attrs(({ id }) => ({ const StyledInfoPanel = styled.div` height: 100%; - width: 400px; + width: ${infoPanelWidth}px; background-color: ${(props) => props.theme.infoPanel.backgroundColor}; ${(props) => props.theme.interfaceDirection === "rtl" @@ -160,11 +164,13 @@ const InfoPanel = ({ + id="InfoPanelWrapper" + > + onClick={closeInfoPanel} + > diff --git a/packages/components/empty-screen-container/styled-empty-screen-container.js b/packages/components/empty-screen-container/styled-empty-screen-container.js index 9b59235dc7..712cf3199b 100644 --- a/packages/components/empty-screen-container/styled-empty-screen-container.js +++ b/packages/components/empty-screen-container/styled-empty-screen-container.js @@ -1,5 +1,5 @@ -import styled, { css } from "styled-components"; -import { mobile, tablet } from "../utils/device"; +import styled from "styled-components"; +import { mobile, tablet, transitionalScreenSize } from "../utils/device"; import NoUserSelect from "../utils/commonStyles"; const EmptyContentBody = styled.div` @@ -73,13 +73,17 @@ const EmptyContentBody = styled.div` color: ${(props) => props.theme.emptyContent.button.colorText}; } } + @media ${transitionalScreenSize} { + width: fit-content; + max-width: 640px; + } @media ${tablet} { padding-top: ${(props) => props.withoutFilter ? "109px" //calculated without section body padding and without filter : "71px"}; //calculated without section body padding, margin of filter - width: 480px; + max-width: 480px; } @media ${mobile} { diff --git a/packages/components/utils/device.js b/packages/components/utils/device.js index f76beb7d0e..010c62c40e 100644 --- a/packages/components/utils/device.js +++ b/packages/components/utils/device.js @@ -1,11 +1,9 @@ import { checkIsSSR } from "@docspace/common/utils"; -import { isMobile as isMobileUtil } from "react-device-detect"; export const size = { mobile: 600, // table: is between desktop: 1024, - hugeDesktop: 1439, }; export const mobile = `(max-width: ${size.mobile}px)`; @@ -16,9 +14,12 @@ export const tablet = `(max-width: ${size.desktop - 1}px)`; export const desktop = `(min-width: ${size.desktop}px)`; -export const hugeDesktop = `(max-width: ${size.hugeDesktop}px)`; - export const mobileFooterHeight = "64px"; +export const infoPanelWidth = 400; + +export const transitionalScreenSize = `(max-width: ${ + size.desktop + infoPanelWidth +}px)`; export const isMobile = () => { return window.innerWidth <= size.mobile; From 7dfdf3b2f3823839f39e0c918a82eb645b28742d Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 27 Oct 2023 14:40:36 +0300 Subject: [PATCH 095/334] Fixed Bug 64857 - Rooms. Fixed redirect after leaving the room --- .../client/src/components/dialogs/LeaveRoomDialog/index.js | 2 +- packages/client/src/store/SelectedFolderStore.js | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/client/src/components/dialogs/LeaveRoomDialog/index.js b/packages/client/src/components/dialogs/LeaveRoomDialog/index.js index 46f5d7c288..2e1309f548 100644 --- a/packages/client/src/components/dialogs/LeaveRoomDialog/index.js +++ b/packages/client/src/components/dialogs/LeaveRoomDialog/index.js @@ -56,7 +56,7 @@ const LeaveRoomDialog = (props) => { }) .then(() => { if (!isAdmin) { - if (isRoot) { + if (!isRoot) { const filter = RoomsFilter.getDefault(); navigate(`rooms/shared/filter?${filter.toUrlParams()}`); } else { diff --git a/packages/client/src/store/SelectedFolderStore.js b/packages/client/src/store/SelectedFolderStore.js index a9e998f055..8a5f57b41b 100644 --- a/packages/client/src/store/SelectedFolderStore.js +++ b/packages/client/src/store/SelectedFolderStore.js @@ -31,6 +31,7 @@ class SelectedFolderStore { rootFolderId = null; settingsStore = null; security = null; + inRoom = true; socketSubscribersId = new Set(); @@ -68,6 +69,7 @@ class SelectedFolderStore { tags: this.tags, rootFolderId: this.rootFolderId, security: this.security, + inRoom: this.inRoom, }; }; @@ -103,6 +105,7 @@ class SelectedFolderStore { this.tags = null; this.rootFolderId = null; this.security = null; + this.inRoom = true; this.socketSubscribersId = new Set(); }; From 79b59ac36cc9d8642566b31d089b9c989c95537f Mon Sep 17 00:00:00 2001 From: Alexey Safronov Date: Fri, 27 Oct 2023 15:44:48 +0400 Subject: [PATCH 096/334] Update input-phone.stories.js --- packages/components/input-phone/input-phone.stories.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/components/input-phone/input-phone.stories.js b/packages/components/input-phone/input-phone.stories.js index 41f94bea4a..da861e411f 100644 --- a/packages/components/input-phone/input-phone.stories.js +++ b/packages/components/input-phone/input-phone.stories.js @@ -29,12 +29,12 @@ const Template = ({ onChange, value, ...args }) => { export const Default = Template.bind({}); Default.args = { defaultCountry: { - locale: options[182].code, // default locale RU - dialCode: options[182].dialCode, // default dialCode +7 - mask: options[182].mask, // default Russia mask - icon: options[182].flag, // default Russia flag + locale: options[236].code, // default locale US + dialCode: options[236].dialCode, // default dialCode +1 + mask: options[236].mask, // default US mask + icon: options[236].flag, // default US flag }, - phonePlaceholderText: "7 XXX XXX-XX-XX", + phonePlaceholderText: "1 XXX XXX-XXXX", searchPlaceholderText: "Search", scaled: false, searchEmptyMessage: "Nothing found", From f854e67875ec2b1ef00d90a7bbcfe14b4f95e3b9 Mon Sep 17 00:00:00 2001 From: Tatiana Lopaeva Date: Fri, 27 Oct 2023 16:00:42 +0300 Subject: [PATCH 097/334] Web: PortalSettings: Restore: Error display fixed. --- packages/client/src/pages/PreparationPortal/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/client/src/pages/PreparationPortal/index.js b/packages/client/src/pages/PreparationPortal/index.js index f87903f0d6..e1b2063e06 100644 --- a/packages/client/src/pages/PreparationPortal/index.js +++ b/packages/client/src/pages/PreparationPortal/index.js @@ -155,9 +155,9 @@ const PreparationPortal = (props) => { if (typeof error !== "object") return error; return ( - err?.response?.data?.error?.message || - err?.statusText || - err?.message || + error?.response?.data?.error?.message || + error?.statusText || + error?.message || t("Common:ErrorInternalServer") ); }; From aac8d68dcf1f4a035096193a69ab9c9756d45d2c Mon Sep 17 00:00:00 2001 From: Vladimir Khvan Date: Fri, 27 Oct 2023 18:10:40 +0500 Subject: [PATCH 098/334] fixed incorrect name display in profile article --- .../Article/sub-components/article-profile.js | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/packages/common/components/Article/sub-components/article-profile.js b/packages/common/components/Article/sub-components/article-profile.js index 4ff89bf9a6..e65752f3f3 100644 --- a/packages/common/components/Article/sub-components/article-profile.js +++ b/packages/common/components/Article/sub-components/article-profile.js @@ -6,11 +6,7 @@ import Text from "@docspace/components/text"; import ContextMenuButton from "@docspace/components/context-menu-button"; import ContextMenu from "@docspace/components/context-menu"; -import { - StyledArticleProfile, - StyledUserName, - StyledProfileWrapper, -} from "../styled-article"; +import { StyledArticleProfile, StyledUserName, StyledProfileWrapper } from "../styled-article"; import VerticalDotsReactSvgUrl from "PUBLIC_DIR/images/vertical-dots.react.svg?url"; import DefaultUserPhotoPngUrl from "PUBLIC_DIR/images/default_user_photo_size_82-82.png"; import { useTheme } from "styled-components"; @@ -52,7 +48,12 @@ const ArticleProfile = (props) => { }; const model = getActions(t); - const username = user.displayName.split(" "); + + const username = user.displayName.split(" ").filter((name) => name.trim().length > 0); + + const firstName = username.pop(); + const lastName = username.join(" "); + const { interfaceDirection } = useTheme(); const isRtl = interfaceDirection === "rtl"; const userAvatar = user.hasAvatar ? user.avatar : DefaultUserPhotoPngUrl; @@ -60,10 +61,7 @@ const ArticleProfile = (props) => { if (currentDeviceType === DeviceType.mobile) return <>; return ( - +
{
{(!isTabletView || showText) && ( <> - + - {username[0]} + {lastName}   - {username[1]} + {firstName} Date: Fri, 27 Oct 2023 18:12:01 +0500 Subject: [PATCH 099/334] fix Bug 63907 | first name and last name validation was added --- .../ChangeNameDialog/StyledChangeName.js | 13 ++ .../dialogs/ChangeNameDialog/index.js | 72 ++++++--- .../Confirm/sub-components/createUser.js | 140 +++++++----------- .../Body/sub-components/main-profile/index.js | 72 +++------ packages/common/store/SettingsStore.js | 88 +++-------- public/locales/en/Common.json | 2 + public/locales/ru/Common.json | 2 + 7 files changed, 161 insertions(+), 228 deletions(-) create mode 100644 packages/client/src/components/dialogs/ChangeNameDialog/StyledChangeName.js diff --git a/packages/client/src/components/dialogs/ChangeNameDialog/StyledChangeName.js b/packages/client/src/components/dialogs/ChangeNameDialog/StyledChangeName.js new file mode 100644 index 0000000000..f333ee5e7b --- /dev/null +++ b/packages/client/src/components/dialogs/ChangeNameDialog/StyledChangeName.js @@ -0,0 +1,13 @@ +import React from "react"; +import ModalDialogContainer from "../ModalDialogContainer"; +import styled from "styled-components"; + +export const ChangeNameContainer = styled(ModalDialogContainer)` + #modal-dialog { + max-height: none; + } + + .error-label { + position: relative; + } +`; diff --git a/packages/client/src/components/dialogs/ChangeNameDialog/index.js b/packages/client/src/components/dialogs/ChangeNameDialog/index.js index 299d91c723..10a5b7af3e 100644 --- a/packages/client/src/components/dialogs/ChangeNameDialog/index.js +++ b/packages/client/src/components/dialogs/ChangeNameDialog/index.js @@ -8,14 +8,10 @@ import TextInput from "@docspace/components/text-input"; import Button from "@docspace/components/button"; import toastr from "@docspace/components/toast/toastr"; -import ModalDialogContainer from "../ModalDialogContainer"; +import { ChangeNameContainer } from "./StyledChangeName"; const ChangeNameDialog = (props) => { - const { t, ready } = useTranslation([ - "ProfileAction", - "PeopleTranslations", - "Common", - ]); + const { t, ready } = useTranslation(["ProfileAction", "PeopleTranslations", "Common"]); const { visible, onClose, @@ -23,11 +19,26 @@ const ChangeNameDialog = (props) => { updateProfile, updateProfileInUsers, fromList, + userNameRegex, } = props; const [firstName, setFirstName] = useState(profile.firstName); const [lastName, setLastName] = useState(profile.lastName); const [isSaving, setIsSaving] = useState(false); + const nameRegex = new RegExp(userNameRegex, "gu"); + + const [isNameValid, setIsNameValid] = useState(true); + const [isSurnameValid, setIsSurnameValid] = useState(true); + + const handleNameChange = (e) => { + setFirstName(e.target.value); + setIsNameValid(nameRegex.test(e.target.value.trim())); + }; + const handleSurnameChange = (e) => { + setLastName(e.target.value); + setIsSurnameValid(nameRegex.test(e.target.value.trim())); + }; + const onCloseAction = () => { if (!isSaving) { onClose(); @@ -39,6 +50,14 @@ const ChangeNameDialog = (props) => { }; const onSaveClick = async () => { + if ( + !isNameValid || + !isSurnameValid || + firstName.trim().length === 0 || + lastName.trim().length === 0 + ) + return; + const newProfile = profile; newProfile.firstName = firstName; newProfile.lastName = lastName; @@ -58,31 +77,34 @@ const ChangeNameDialog = (props) => { }; return ( - - - {t("PeopleTranslations:NameChangeButton")} - + displayType="modal"> + {t("PeopleTranslations:NameChangeButton")} + hasError={!isNameValid} + errorMessage={ + firstName.trim().length === 0 + ? t("Common:RequiredField") + : t("Common:IncorrectFirstName") + }> setFirstName(e.target.value)} + onChange={handleNameChange} placeholder={t("Common:FirstName")} isDisabled={isSaving} onKeyDown={onKeyDown} tabIndex={1} + hasError={!isNameValid} /> @@ -90,16 +112,20 @@ const ChangeNameDialog = (props) => { isVertical labelText={t("Common:LastName")} className="field" - > + hasError={!isSurnameValid} + errorMessage={ + lastName.trim().length === 0 ? t("Common:RequiredField") : t("Common:IncorrectLastName") + }> setLastName(e.target.value)} + onChange={handleSurnameChange} placeholder={t("Common:LastName")} isDisabled={isSaving} onKeyDown={onKeyDown} tabIndex={2} + hasError={!isSurnameValid} /> @@ -114,6 +140,12 @@ const ChangeNameDialog = (props) => { onClick={onSaveClick} isLoading={isSaving} tabIndex={3} + isDisabled={ + !isNameValid || + !isSurnameValid || + firstName.trim().length === 0 || + lastName.trim().length === 0 + } />