Merge branch 'feature/download-dialog' of github.com:ONLYOFFICE/AppServer into feature/download-dialog

This commit is contained in:
Nikita Gopienko 2022-06-22 11:53:01 +03:00
commit b88dadf961
76 changed files with 522 additions and 365 deletions

View File

@ -47,7 +47,7 @@ public class DarkThemeSettings : ISettings
{
return new DarkThemeSettings
{
Theme = DarkThemeSettingsEnum.Base,
Theme = DarkThemeSettingsEnum.System,
};
}
}

View File

@ -33,6 +33,8 @@ const Article = ({
setIsMobileArticle,
isLoadedPage,
children,
isBannerVisible,
...rest
}) => {
const [articleHeaderContent, setArticleHeaderContent] = React.useState(null);
@ -111,6 +113,7 @@ const Article = ({
id={"article-container"}
showText={showText}
articleOpen={articleOpen}
isBannerVisible={isBannerVisible}
{...rest}
>
<Resizable
@ -176,9 +179,11 @@ Article.Body = () => {
};
Article.Body.displayName = "Body";
export default inject(({ auth }) => {
export default inject(({ auth, bannerStore }) => {
const { settingsStore } = auth;
const { isBannerVisible } = bannerStore;
const {
showText,
setShowText,
@ -195,5 +200,7 @@ export default inject(({ auth }) => {
setIsMobileArticle,
toggleShowText,
toggleArticleOpen,
isBannerVisible,
};
})(observer(Article));

View File

@ -53,10 +53,11 @@ const StyledArticle = styled.article`
width: 100%;
position: fixed;
margin-top: 64px !important;
height: calc(100% - 64px) !important;
margin: 0;
padding: 0;
margin-top: ${(props) =>
props.isBannerVisible ? "-16px" : "64px"} !important;
height: calc(100% - 64px) !important;
`}
z-index: ${(props) =>

View File

@ -65,7 +65,6 @@ const FilterInput = React.memo(
onChange={onSearch}
onClearSearch={onClearSearch}
/>
<FilterButton
t={t}
selectedFilterData={selectedFilterData}
@ -74,38 +73,36 @@ const FilterInput = React.memo(
onFilter={onFilter}
headerLabel={headerLabel}
/>
{(viewSettings &&
{(isMobile ||
isTabletUtils() ||
isMobileUtils() ||
viewAs === "row") && (
<SortButton
t={t}
selectedFilterData={selectedFilterData}
getSortData={getSortData}
onChangeViewAs={onChangeViewAs}
viewAs={viewAs === "table" ? "row" : viewAs}
viewSettings={viewSettings}
onSort={onSort}
viewSelectorVisible={
viewSelectorVisible &&
(isMobile || isMobileUtils() || isTabletUtils())
}
/>
)}
{((viewSettings &&
!isMobile &&
viewSelectorVisible &&
!isMobileUtils() &&
!isTabletUtils() &&
viewAs !== "row") ||
isRecentFolder ? (
!isTabletUtils()) ||
isRecentFolder) && (
<ViewSelector
style={{ marginLeft: "8px" }}
onChangeView={onChangeViewAs}
viewAs={viewAs === "table" ? "row" : viewAs}
viewSettings={viewSettings}
/>
) : (
<>
{(isMobile ||
isTabletUtils() ||
isMobileUtils() ||
viewAs === "row") && (
<SortButton
t={t}
selectedFilterData={selectedFilterData}
getSortData={getSortData}
onChangeViewAs={onChangeViewAs}
viewAs={viewAs === "table" ? "row" : viewAs}
viewSettings={viewSettings}
onSort={onSort}
viewSelectorVisible={viewSelectorVisible}
/>
)}
</>
)}
</StyledFilterInput>
);

View File

@ -60,6 +60,7 @@ class MediaViewer extends React.Component {
playlist: props.playlist,
playlistPos,
fileUrl: item.src,
canSwipeImage: true,
};
this.detailsContainer = React.createRef();
@ -346,6 +347,9 @@ class MediaViewer extends React.Component {
? playlist.find((file) => file.id === playlistPos).fileId
: 0;
this.props.onDelete && this.props.onDelete(currentFileId);
this.setState({
canSwipeImage: false,
});
};
onDownload = () => {
@ -376,22 +380,26 @@ class MediaViewer extends React.Component {
if (isActionKey) {
switch (e.keyCode) {
case ButtonKeys.leftArrow:
ctrIsPressed
? document.getElementsByClassName("iconContainer rotateLeft")
.length > 0 &&
document
.getElementsByClassName("iconContainer rotateLeft")[0]
.click()
: this.prevMedia();
this.state.canSwipeImage
? ctrIsPressed
? document.getElementsByClassName("iconContainer rotateLeft")
.length > 0 &&
document
.getElementsByClassName("iconContainer rotateLeft")[0]
.click()
: this.prevMedia()
: null;
break;
case ButtonKeys.rightArrow:
ctrIsPressed
? document.getElementsByClassName("iconContainer rotateRight")
.length > 0 &&
document
.getElementsByClassName("iconContainer rotateRight")[0]
.click()
: this.nextMedia();
this.state.canSwipeImage
? ctrIsPressed
? document.getElementsByClassName("iconContainer rotateRight")
.length > 0 &&
document
.getElementsByClassName("iconContainer rotateRight")[0]
.click()
: this.nextMedia()
: null;
break;
case ButtonKeys.esc:
if (!this.props.deleteDialogVisible) this.props.onClose();

View File

@ -1,6 +1,11 @@
import styled, { css } from "styled-components";
import { isMobile, isMobileOnly } from "react-device-detect";
import { tablet, mobile, desktop } from "@appserver/components/utils/device";
import {
tablet,
mobile,
desktop,
hugeMobile,
} from "@appserver/components/utils/device";
const StyledContainer = styled.div`
${(props) =>
@ -50,7 +55,7 @@ const StyledContainer = styled.div`
padding: ${(props) => (props.isDropBox ? "10px 0 5px" : "10px 0 11px")};
}
@media ${mobile} {
@media ${mobile}, ${hugeMobile} {
padding: ${(props) =>
props.isDropBox ? "10px 0 5px" : "10px 0 11px"} !important;
}

View File

@ -29,6 +29,10 @@ const StyledContainer = styled.div`
`}
}
.add-drop-down {
margin-top: 8px;
}
.option-button {
margin-right: 16px;
min-width: 15px;
@ -151,6 +155,8 @@ const ControlButtons = ({
isFill
getData={getContextOptionsPlus}
isDisabled={false}
usePortal={false}
dropDownClassName="add-drop-down"
/>
)}
{!isDesktop && (

View File

@ -55,6 +55,7 @@ const StyledInfoPanelToggleWrapper = styled.div`
${isMobile &&
css`
display: none;
margin-left: ${(props) => (props.isRootFolder ? "auto" : "0")};
`}

View File

@ -31,16 +31,15 @@ const StyledInfoPanelWrapper = styled.div.attrs(({ id }) => ({
right: 0;
}
/* ${(props) =>
(props.isRowView || isMobile) &&
css`
z-index: 309;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
`} */
${isMobile &&
css`
z-index: 309;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
`}
`;
const StyledInfoPanel = styled.div`
@ -63,6 +62,15 @@ const StyledInfoPanel = styled.div`
max-width: calc(100vw - 69px);
}
${isMobile &&
css`
position: absolute;
border: none;
right: 0;
width: 480px;
max-width: calc(100vw - 69px);
`}
/* ${(props) =>
(props.isRowView || isMobile) &&
css`
@ -103,6 +111,14 @@ const StyledControlContainer = styled.div`
left: -34px;
}
${isMobile &&
css`
display: flex;
top: 16px;
left: -34px;
`}
/* ${(props) =>
(props.isRowView || isMobile) &&
css`

View File

@ -165,6 +165,8 @@ class ContextMenuButton extends React.Component {
isNew,
title,
zIndex,
usePortal,
dropDownClassName,
} = this.props;
const { isOpen, displayType, offsetX, offsetY } = this.state;
@ -196,6 +198,7 @@ class ContextMenuButton extends React.Component {
/>
{displayType === "dropdown" ? (
<DropDown
className={dropDownClassName}
directionX={directionX}
directionY={directionY}
open={isOpen}
@ -204,6 +207,7 @@ class ContextMenuButton extends React.Component {
columnCount={columnCount}
withBackdrop={!!isMobile}
zIndex={zIndex}
isDefaultMode={usePortal}
>
{this.state.data.map(
(item, index) =>
@ -316,6 +320,8 @@ ContextMenuButton.propTypes = {
/** Set the display type */
displayType: PropTypes.string,
isNew: PropTypes.bool,
usePortal: PropTypes.bool,
dropDownClassName: PropTypes.string,
};
ContextMenuButton.defaultProps = {
@ -329,6 +335,7 @@ ContextMenuButton.defaultProps = {
isFill: false,
displayType: "dropdown",
isNew: false,
usePortal: true,
};
export default ContextMenuButton;

View File

@ -3,7 +3,7 @@ import PropTypes from "prop-types";
import { ReactSVG } from "react-svg";
import styled from "styled-components";
import Button from "../button";
import { mobile, tablet } from "../utils/device";
import { mobile, tablet, hugeMobile } from "../utils/device";
import { Base } from "../themes";
const StyledButton = styled(Button)`
@ -74,7 +74,7 @@ const StyledButton = styled(Button)`
}
}
@media ${mobile} {
@media ${mobile}, ${hugeMobile} {
padding: 0 16px;
height: 50px;
font-size: 0;

View File

@ -1,6 +1,6 @@
import styled, { css } from "styled-components";
import Base from "../themes/base";
import { mobile, tablet } from "../utils/device";
import { mobile, tablet, hugeMobile } from "../utils/device";
import Scrollbar from "../scrollbar";
import { isMobile } from "react-device-detect";
@ -99,7 +99,7 @@ const StyledTableGroupMenu = styled.div`
height: 60px;
}
@media ${mobile} {
@media ${mobile}, ${hugeMobile} {
height: 52px;
}

View File

@ -1,5 +1,6 @@
export const size = {
mobile: 375,
hugeMobile: 414,
smallTablet: 600,
tablet: 1024,
desktop: 1025,
@ -7,6 +8,8 @@ export const size = {
export const mobile = `(max-width: ${size.mobile}px)`;
export const hugeMobile = `(max-width: ${size.hugeMobile}px)`;
export const smallTablet = `(max-width: ${size.smallTablet}px)`;
export const tablet = `(max-width: ${size.tablet}px)`;
@ -17,12 +20,18 @@ export const isMobile = () => {
return window.innerWidth <= size.mobile;
};
export const isHugeMobile = () => {
return window.innerWidth <= size.hugeMobile;
};
export const isSmallTablet = () => {
return window.innerWidth < size.smallTablet;
};
export const isTablet = () => {
return window.innerWidth <= size.tablet && window.innerWidth >= size.mobile;
return (
window.innerWidth <= size.tablet && window.innerWidth >= size.hugeMobile
);
};
export const isDesktop = () => {

View File

@ -52,13 +52,13 @@ const globalColors = {
hoverInfo: "#EED27B",
hoverWarning: "#EEB97B",
firstDefaultСolorScheme: "#4781D1",
secondDefaultСolorScheme: "#ED7309",
thirdDefaultСolorScheme: "#08AAA0",
fourthDefaultСolorScheme: "#F2665A",
fifthDefaultСolorScheme: "#6D4EC2",
sixthDefaultСolorScheme: "#11A3D4",
seventhDefaultСolorScheme: "#444444",
colorSchemeDefault_1: "#4781D1",
colorSchemeDefault_2: "#ED7309",
colorSchemeDefault_3: "#08AAA0",
colorSchemeDefault_4: "#F2665A",
colorSchemeDefault_5: "#6D4EC2",
colorSchemeDefault_6: "#11A3D4",
colorSchemeDefault_7: "#444444",
};
export default globalColors;

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Seçilmiş elementlər",
"LastModifiedBy": "tərəfindən Son Dəyişiklik",
"Members": "üzvlər",
"OFORMsDescription": "Formanı onlayn doldurun və sadə Dizayn Layihəsi Təklifini hazırlayın, yaxud da DOCXF, OFORM və ya PDF formatlarında doldurulabilən şablonu endirin. <1>Frilans dizayner komandasına layihə və ya layihələr silsiləsi təklif edin. Layihə və tapşırıq strukturunu, ödəniş və şərtləri təsvir edin.</1>",
"OpenSharingSettings": "Paylaşma ayarlarınıın",
"SystemProperties": "Sistem xüsusiyyətləri",
"Versions": "Versiyalar",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Избрани елементи",
"LastModifiedBy": "Последно модифициран от",
"Members": "членове",
"OFORMsDescription": "Попълнете формуляра онлайн и получете готово просто предложение за проект на дизайна или просто изтеглете шаблона за попълване в желания формат: DOCXF, OFORM или PDF. <1>Предложете проект или поредица от проекти на фрийленс дизайнерски екип. Очертайте структурата на проекта и задачата, плащанията и условията.</1>",
"OpenSharingSettings": "Отваряне на настройките за споделяне",
"SystemProperties": "Свойства на системата",
"Versions": "Версии",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Vybrané položky",
"LastModifiedBy": "Naposledy upravil(a)",
"Members": "členové",
"OFORMsDescription": "Vyplňte formulář online a získejte jednoduchý návrh projektu nebo si stáhněte vyplnitelnou šablonu v požadovaném formátu: DOCXF, OFORM nebo PDF. Navrhněte projekt nebo sérii projektů týmu nezávislých designérů. Načrtněte strukturu projektu a úkolů, platby a podmínky.",
"OpenSharingSettings": "Otevřít nastavení sdílení",
"SystemProperties": "Vlastnosti systému",
"Versions": "Verze",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Ausgewählte Elemente",
"LastModifiedBy": "Zuletzt geändert von",
"Members": "mitglieder",
"OFORMsDescription": "Füllen Sie das Formular online aus und erhalten Sie einen einfachen Projektvorschlag oder laden Sie eine ausfüllbare Vorlage im gewünschten Format herunter: DOCXF, OFORM oder PDF. <1>Schlagen Sie dem freiberuflichen Entwicklungsteam ein Projekt oder eine Reihe von Projekten vor. Beschreiben Sie die Projekt- und Aufgabenstruktur, die Zahlungsmöglichkeiten und Bedingungen.</1>",
"OpenSharingSettings": "Freigabeeinstellungen öffnen",
"SystemProperties": "Eigenschaften des Systems",
"Versions": "Versionen",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Επιλεγμένα στοιχεία",
"LastModifiedBy": "Τελευταία Τροποποίηση Από",
"Members": "mέλη",
"OFORMsDescription": "Συμπληρώστε τη φόρμα ηλεκτρονικά και λάβετε μια απλή Πρόταση Σχεδιασμού Έργου ή απλά κατεβάστε το υπόδειγμα που μπορεί να συμπληρωθεί στην επιθυμητή μορφή: DOCXF, OFORM ή PDF. <1>Προτείνετε ένα έργο ή μια σειρά έργων σε μια ομάδα ελεύθερων επαγγελματιών σχεδιαστών. Περιγράψτε τη δομή των εργασιών και του έργου, τις πληρωμές και τους όρους.</1>",
"OpenSharingSettings": "Άνοιγμα ρυθμίσεων κοινής χρήσης",
"SystemProperties": "Ιδιότητες συστήματος",
"Versions": "Εκδόσεις",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Items selected",
"LastModifiedBy": "Last modified by",
"Members": "members",
"OFORMsDescription": "Fill out the form online and get a simple Design Project Proposal ready, or just download the fillable template in the desirable format: DOCXF, OFORM, or PDF. <1>Propose a project or a series of projects to a freelance designer team. Outline project and task structure, payments, and terms.</1>",
"OpenSharingSettings": "Open sharing settings",
"SystemProperties": "System properties",
"Versions": "Versions",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Elementos seleccionados",
"LastModifiedBy": "Ultima modificación por",
"Members": "miembros",
"OFORMsDescription": "Rellene el formulario en línea y obtenga una sencilla propuesta de proyecto de diseño, o descárguese la plantilla rellenable en el formato deseado: DOCXF, OFORM o PDF. <1>Proponga un proyecto o una serie de proyectos a un equipo de diseñadores autónomos. Describa la estructura del proyecto y de las tareas, los pagos y las condiciones.</1>",
"OpenSharingSettings": "Abrir los ajustes de uso compartido",
"SystemProperties": "Propiedades del sistema",
"Versions": "Versiones",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Valitut kohteet",
"LastModifiedBy": "Viimeksi muokannut",
"Members": "jäsenet",
"OFORMsDescription": "Täytä lomake verkossa ja saat vaivattomasti suunnitteluprojektiehdotuksen valmiiksi tai lataa täytettävä malli haluamassasi muodossa: DOCXF, OFORM, tai PDF. <1>Ehdota projektia tai projekteja freelance-suunnittelutiimille. Esittele projektin ja tehtävän rakenne, maksut ja ehdot.</1>",
"OpenSharingSettings": "Avaa jakamisasetukset",
"SystemProperties": "Järjestelmän ominaisuudet",
"Versions": "Versiot",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Éléments sélectionnés",
"LastModifiedBy": "Dernière modification par",
"Members": "membres",
"OFORMsDescription": "Remplissez le formulaire en ligne et obtenez une proposition de projet de conception simple, ou téléchargez le modèle à remplir dans le format souhaité : DOCXF, OFORM, ou PDF. <1>Proposez un projet ou une série de projets à une équipe de designers indépendants. Décrivez la structure du projet et les tâches, les modalités de paiement et les conditions.</1>",
"OpenSharingSettings": "Ouvrir les paramètres de partage",
"SystemProperties": "Propriétés du système",
"Versions": "Versions",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Elementi selezionati",
"LastModifiedBy": "Ultima modifica di",
"Members": "membri",
"OFORMsDescription": "Compila il modulo online e ottieni una semplice Proposta di Progettazione pronta, oppure scarica semplicemente il modello compilabile nel formato desiderato: DOCXF, OFORM o PDF. <1>Proponi un progetto o una serie di progetti a un team di designer freelance. Definisci il progetto e la struttura delle attività, i pagamenti e i termini.</1>",
"OpenSharingSettings": "Aprire impostazioni di condivisione",
"SystemProperties": "Proprietà di sistema",
"Versions": "Versioni",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "選択されているアイテム",
"LastModifiedBy": "最終更新者",
"Members": "メンバー",
"OFORMsDescription": "オンラインでフォームに記入して、簡単なプロジェクト提案書を受け取るか、必要なフォーマットDOCXF、OFORM、PDFで記入可能なテンプレートをダウンロードできます。 <1>フリーランスの開発チームにプロジェクトまたは一連のプロジェクトを提案して、プロジェクトやタスクの構成、支払い方法、条件などを教えてください。</1>",
"OpenSharingSettings": "共有設定を開く",
"SystemProperties": "システムのプロパティ",
"Versions": "バージョン",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "선택된 항목",
"LastModifiedBy": "최종 편집자",
"Members": "구성원",
"OFORMsDescription": "온라인으로 양식을 작성하고 간단한 디자인 프로젝트 제안서를 준비하거나, 원하는 형식(DOCXF, OFORM 또는 PDF)의 템플릿을 다운로드하세요.<1>프리랜스 디자이너 팀에 하나 이상의 프로젝트를 제안해주세요. 프로젝트 및 작업 구조, 지불 및 조건을 간략하게 설명해주세요.</1>",
"OpenSharingSettings": "공유 설정 열기",
"SystemProperties": "시스템 속성",
"Versions": "버전",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Atlasītie vienumi",
"LastModifiedBy": "Pēdējo reizi modificēja:",
"Members": "locekļi",
"OFORMsDescription": "Aizpildiet veidlapu tiešsaistē un sagatavojiet vienkāršu dizaina projekta priekšlikumu vai vienkārši lejupielādējiet aizpildāmo veidni vēlamajā formātā: DOCXF, OFORM vai PDF. <1>Ierosiniet projektu vai projektu sēriju ārštata dizaineru komandai. Ieskicējiet projekta un uzdevuma struktūru, maksājumus un termiņus.</1>",
"OpenSharingSettings": "Atvērt koplietošanas iestatījumus",
"SystemProperties": "Sistēmas īpašības",
"Versions": "Versijas",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Geselecteerde items",
"LastModifiedBy": "Laatst aangepast door",
"Members": "leden",
"OFORMsDescription": "Vul het formulier online in en u krijgt een eenvoudig Ontwerp Projectvoorstel in handen, of download gewoon het invulbare sjabloon in het gewenste formaat: DOCXF, OFORM, of PDF. <1>Stel een project of een reeks projecten voor aan een freelance ontwerpersteam. Schets de project- en taakstructuur, de betalingen, en de voorwaarden.</1>",
"OpenSharingSettings": "Instellingen voor delen openen",
"SystemProperties": "Systeemeigenschappen",
"Versions": "Versies",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Wybrano elementy",
"LastModifiedBy": "Ostatnio zmodyfikowany przez",
"Members": "członkowie",
"OFORMsDescription": "Wypełnij formularz online, aby otrzymać prostą gotową Propozycję Projektu lub po prostu pobierz i wypełnij szablon w preferowanym formacie: DOCXF, OFORM lub PDF. <1>Zaproponuj projekt lub serię projektów zespołowi freelancerów zajmujących się designem. Przedstaw strukturę projektu, zadań oraz płatności i warunków współpracy.</1>",
"OpenSharingSettings": "Otwórz ustawienia udostępniania",
"SystemProperties": "Właściwości systemu",
"Versions": "Wersje",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Itens selecionados",
"LastModifiedBy": "Última Modificação Por",
"Members": "membros",
"OFORMsDescription": "Preencha o formulário online e elabore uma Proposta de Projeto de Design simples, ou apenas baixe o modelo preenchível no formato desejado: DOCXF, OFORM ou PDF. Proponha um projeto ou uma série de projetos para uma equipe de designers freelance. Esboce a estrutura, pagamentos e termos do projeto e da tarefa.",
"OpenSharingSettings": "Abrir as configurações de rede",
"SystemProperties": "Propriedades do sistema",
"Versions": "Versões",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Itens selecionados",
"LastModifiedBy": "Modificado por",
"Members": "membros",
"OFORMsDescription": "Preencha o formulário online e obtenha uma Proposta de Projeto com um Design simples, ou simplesmente descarregue o modelo a preenchível no formato que desejar: DOCXF, OFORM ou PDF. Proponha um projeto ou uma série de projetos a uma equipa de designers freelancers (trabalhadores independentes). Faça um esboço do projeto e da estrutura de tarefas, pagamentos, e dos termos.",
"OpenSharingSettings": "Abrir definições de compartilhamento",
"SystemProperties": "Propriedades do sistema",
"Versions": "Versões",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Elemente selectate",
"LastModifiedBy": "Modificat ultima dată de către",
"Members": "membrii",
"OFORMsDescription": "Completați formularul online și obțineți un simplu Proiect de Design, sau descărcați șablonul spre completare în formatul dorit: DOCXF, OFORM sau PDF. <1>Propuneți un proiect sau o serie de proiecte unei echipe de designeri freelance. Descrieți structura proiectului și sarcinilor, metodele de plată și condițiile.</1>",
"OpenSharingSettings": "Deschide setările de partajare",
"SystemProperties": "Proprietăți sistem",
"Versions": "Versiuni",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Выбрано элементов",
"LastModifiedBy": "Автор последнего корректива",
"Members": "участников",
"OFORMsDescription": "Заполните форму онлайн и получите простое проектное предложение или скачайте заполняемый шаблон в нужном формате: DOCXF, OFORM или PDF. <1>Предложите проект или серию проектов команде внештатных разработчиков. Опишите проект и структуру задачи, способы оплаты и условия.</1>",
"OpenSharingSettings": "Открыть настройки общего доступа",
"SystemProperties": "Системные свойства",
"Versions": "Версии",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Vybraté položky",
"LastModifiedBy": "Naposledy upravené",
"Members": "členovia",
"OFORMsDescription": "Vyplňte formulár online a dostanete jednoduchý návrh dizajn-projektu, alebo si jednoducho stiahnite šablónu, ktorú možno vyplniť v požadovanom formáte: DOCXF, OFORM alebo PDF. Navrhnite projekt alebo sériu projektov tímu dizajnérov-freelancerov. Načrtnite štruktúru projektu a úloh, platieb a podmienok.",
"OpenSharingSettings": "Otvoriť nastavenia zdieľania",
"SystemProperties": "Vlastnosti systému",
"Versions": "Verzie",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Predmeti izbrani",
"LastModifiedBy": "Nazadnje spremenjeno",
"Members": "člani",
"OFORMsDescription": "Izpolnite spletni obrazec in uredite preprost predlog projekta ali pa enostavno v izbranem formatu prenesite predlogo, ki jo lahko izpolnite: DOCXF, OFORM ali PDF. <1>Predlagajte projekt ali vrsto projektov samostojni oblikovalski skupini. Opišite strukturo projekta in naloge, plačila in pogoje.</1>",
"OpenSharingSettings": "Odpri nastavitve skupne rabe",
"SystemProperties": "Lastnosti sistema",
"Versions": "Verzije",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Seçili öğeler",
"LastModifiedBy": "Son Düzenleyen",
"Members": "üyeler",
"OFORMsDescription": "Formu çevrimiçi olarak doldurun ve basit bir Tasarım Projesi Teklifi hazırlayın veya doldurulabilir şablonu istediğiniz formatta indirin: DOCXF, OFORM veya PDF. Serbest çalışan bir tasarımcı ekibine bir proje veya bir dizi proje önerin. Proje ve görev yapısı, ödemeler ve şartları belirleyin.",
"OpenSharingSettings": "Paylaşım ayarlarını aç",
"SystemProperties": "Sistem özellikleri",
"Versions": "Sürümler",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Вибрані елементи",
"LastModifiedBy": "Автор останньої зміни",
"Members": "учасники",
"OFORMsDescription": "Заповніть форму онлайн та отримайте готову просту пропозицію дизайн-проекту або просто завантажте шаблон для заповнення в бажаному форматі: DOCXF, OFORM або PDF. Запропонуйте проект або серію проектів команді фріланс-дизайнерів. Опишіть структуру проекту та завдань, платежі та умови.",
"OpenSharingSettings": "Відкрити параметри спільного доступу",
"SystemProperties": "Властивості системи",
"Versions": "Версії",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "Các mục đã chọn",
"LastModifiedBy": "Sửa lần cuối bởi",
"Members": "thành viên",
"OFORMsDescription": "Điền vào biểu mẫu trực tuyến và có Đề xuất Dự án Thiết kế đơn giản, hoặc chỉ cần tải xuống mẫu có thể điền ở định dạng mong muốn: DOCXF, OFORM, hay PDF. Đề xuất một dự án hoặc một loạt các dự án cho một nhóm thiết kế tự do. Phác thảo dự án và cấu trúc nhiệm vụ, thanh toán và điều khoản.",
"OpenSharingSettings": "Mở cài đặt chia sẻ",
"SystemProperties": "Thuộc tính hệ thống",
"Versions": "Phiên Bản",

View File

@ -4,7 +4,6 @@
"ItemsSelected": "选定的项目",
"LastModifiedBy": "上次修改时间",
"Members": "成员",
"OFORMsDescription": "在线填写表单并准备简单的设计项目提案表或者直接下载可填写模板格式为DOCXF, OFORM, 或PDF。 这样,您可以向设计师团队提出一个项目或一系列项目的提案。概述项目和任务结构、付款和条款。",
"OpenSharingSettings": "打开共享设置",
"SystemProperties": "系统属性",
"Versions": "版本",

View File

@ -258,6 +258,7 @@ export default function withContent(WrappedContent) {
const folderIds = [+itemId];
createdFolderId && folderIds.push(createdFolderId);
setIsUpdatingRowItem(false);
clearActiveOperations(null, folderIds);
return setIsLoading(false);
@ -277,37 +278,37 @@ export default function withContent(WrappedContent) {
})
.then(() => this.completeAction(itemId))
.catch((err) => {
console.log("err", err);
const isPasswordError = new RegExp(/\(password\)*$/);
if (isPasswordError.test(err)) {
toastr.error(
t("Translations:FileProtected"),
t("Common:Warning")
);
setIsUpdatingRowItem(false);
setFormCreationInfo({
newTitle: `${title}.${item.fileExst}`,
fromExst: ".docx",
toExst: item.fileExst,
open,
actionId: itemId,
fileInfo: {
id: fileActionTemplateId,
folderId: item.parentId,
fileExst: item.fileExst,
},
});
setConvertPasswordDialogVisible(true);
open && openDocEditor(null, null, tab);
if (err.indexOf("password") == -1) {
toastr.error(err, t("Common:Warning"));
return;
}
toastr.error(
t("Translations:FileProtected"),
t("Common:Warning")
);
setFormCreationInfo({
newTitle: `${title}.${item.fileExst}`,
fromExst: ".docx",
toExst: item.fileExst,
open,
actionId: itemId,
fileInfo: {
id: fileActionTemplateId,
folderId: item.parentId,
fileExst: item.fileExst,
},
});
setConvertPasswordDialogVisible(true);
open && openDocEditor(null, null, tab);
})
.finally(() => {
const fileIds = [+itemId];
createdFileId && fileIds.push(createdFileId);
setIsUpdatingRowItem(false);
clearActiveOperations(fileIds);
return setIsLoading(false);
@ -336,6 +337,7 @@ export default function withContent(WrappedContent) {
const fileIds = [+itemId];
createdFileId && fileIds.push(createdFileId);
setIsUpdatingRowItem(false);
clearActiveOperations(fileIds);
return setIsLoading(false);
@ -373,6 +375,7 @@ export default function withContent(WrappedContent) {
const fileIds = [+itemId];
createdFileId && fileIds.push(createdFileId);
setIsUpdatingRowItem(false);
clearActiveOperations(fileIds);
return setIsLoading(false);

View File

@ -156,7 +156,7 @@ const withHotkeys = (Component) => {
useHotkeys(
"Shift+d",
() => setAction({ type: FileAction.Create, extension: "docx", id: -1 }),
hotkeysFilter
{ ...hotkeysFilter, ...{ keyup: true } }
);
//Crete spreadsheet

View File

@ -6,6 +6,7 @@ import Loaders from "@appserver/common/components/Loaders";
const pathname = window.location.pathname.toLowerCase();
const isEditor = pathname.indexOf("doceditor") !== -1;
const isGallery = pathname.indexOf("form-gallery") !== -1;
let loadTimeout = null;
const withLoader = (WrappedComponent) => (Loader) => {
@ -52,7 +53,7 @@ const withLoader = (WrappedComponent) => (Loader) => {
}
}, [isEditor, firstLoad, isLoaded, isMobile, inLoad]);
return (!isEditor && firstLoad) ||
return (!isEditor && firstLoad && !isGallery) ||
!isLoaded ||
(isMobile && inLoad) ||
(isLoadingFilesFind && !Loader) ||

View File

@ -5,10 +5,7 @@ import { inject, observer } from "mobx-react";
import MainButton from "@appserver/components/main-button";
import { withTranslation } from "react-i18next";
import { isMobile } from "react-device-detect";
import {
isMobile as isMobileUtils,
isTablet as isTabletUtils,
} from "@appserver/components/utils/device";
import { isTablet as isTabletUtils } from "@appserver/components/utils/device";
import Loaders from "@appserver/common/components/Loaders";
import { AppServerConfig, FileAction } from "@appserver/common/constants";
import { encryptionUploadDialog } from "../../../helpers/desktop";
@ -47,6 +44,7 @@ const ArticleMainButtonContent = (props) => {
const [actions, setActions] = React.useState([]);
const [uploadActions, setUploadActions] = React.useState([]);
const [model, setModel] = React.useState([]);
const [isTablet, setIsTablet] = React.useState(isTabletUtils());
const onCreate = React.useCallback(
(e) => {
@ -104,7 +102,14 @@ const ArticleMainButtonContent = (props) => {
);
};
const onResize = React.useCallback(() => {
const isTabletView = isTabletUtils();
setIsTablet(isTabletView);
}, []);
React.useEffect(() => {
window.addEventListener("resize", onResize);
const folderUpload = !isMobile
? [
{
@ -120,7 +125,7 @@ const ArticleMainButtonContent = (props) => {
: [];
const formActions =
!isMobile && !isTabletUtils()
!isMobile && !isTablet
? [
{
className: "main-button_drop-down",
@ -171,7 +176,7 @@ const ArticleMainButtonContent = (props) => {
},
];
if (isMobile || isTabletUtils()) {
if (isMobile || isTablet) {
formActions.push({
className: "main-button_drop-down_sub",
icon: "images/form.react.svg",
@ -245,14 +250,20 @@ const ArticleMainButtonContent = (props) => {
setModel(menuModel);
setActions(actions);
setUploadActions(uploadActions);
return () => {
window.removeEventListener("resize", onResize);
};
}, [
t,
isPrivacy,
currentFolderId,
isTablet,
onCreate,
onShowSelectFileDialog,
onUploadFileClick,
onUploadFolderClick,
onResize,
]);
return (

View File

@ -92,17 +92,18 @@ const ConvertPasswordDialogComponent = (props) => {
onClose();
})
.catch((err) => {
console.log("err", err);
const isPasswordError = new RegExp(/\(password\)*$/);
if (isPasswordError.test(err)) {
toastr.error(t("CreationError"), t("Common:Warning"));
if (_isMounted) {
setPasswordValid(false);
focusInput();
}
if (err.indexOf("password") == -1) {
toastr.error(err, t("Common:Warning"));
return;
}
toastr.error(t("CreationError"), t("Common:Warning"));
if (_isMounted) {
setPasswordValid(false);
focusInput();
}
})
.finally(() => {
_isMounted && setIsLoading(false);
});
} else {
@ -116,17 +117,19 @@ const ConvertPasswordDialogComponent = (props) => {
editCompleteAction(actionId, fileInfo, false);
})
.catch((err) => {
console.log("err", err);
const isPasswordError = new RegExp(/\(password\)*$/);
if (isPasswordError.test(err)) {
toastr.error(t("CreationError"), t("Common:Warning"));
open && openDocEditor(null, null, tab);
if (_isMounted) {
setPasswordValid(false);
focusInput();
}
if (err.indexOf("password") == -1) {
toastr.error(err, t("Common:Warning"));
return;
}
toastr.error(t("CreationError"), t("Common:Warning"));
open && openDocEditor(null, null, tab);
if (_isMounted) {
setPasswordValid(false);
focusInput();
}
})
.finally(() => {
_isMounted && setIsLoading(false);
});
}

View File

@ -81,6 +81,7 @@ const ServiceItem = (props) => {
className,
getThirdPartyIcon,
serviceName,
serviceKey,
onClick,
} = props;
@ -93,7 +94,7 @@ const ServiceItem = (props) => {
"data-key": capabilityKey,
};
const src = getThirdPartyIcon(capabilityKey);
const src = getThirdPartyIcon(serviceKey || capabilityKey);
const capabilityName = connectedCloudsTypeTitleTranslation(capabilityKey, t);
@ -282,7 +283,8 @@ const ThirdPartyDialog = (props) => {
<ServiceItem
t={t}
serviceName="Nextcloud"
capability={webDavConnectItem}
serviceKey="NextCloud"
capability={nextCloudConnectItem}
onClick={onShowService}
getThirdPartyIcon={getThirdPartyIcon}
/>
@ -292,7 +294,8 @@ const ThirdPartyDialog = (props) => {
<ServiceItem
t={t}
serviceName="ownCloud"
capability={webDavConnectItem}
serviceKey="OwnCloud"
capability={ownCloudConnectItem}
onClick={onShowService}
getThirdPartyIcon={getThirdPartyIcon}
/>

View File

@ -71,22 +71,6 @@ const SingleItem = (props) => {
{selectedItem.attributes.file_pages}
</Text>
</div>
<Text
as="div"
fontSize="12px"
fontWeight={400}
className="oforms-description"
>
<Trans t={t} i18nKey="OFORMsDescription" ns="InfoPanel">
Fill out the form online and get a simple Design Project Proposal
ready, or just download the fillable template in the desirable
format: DOCXF, OFORM, or PDF.
<p className="oforms-description-text">
Propose a project or a series of projects to an freelance designer
team. Outline project and task structure, payments, and terms.
</p>
</Trans>
</Text>
</StyledProperties>
</>
);

View File

@ -167,6 +167,9 @@ const SingleItem = (props) => {
},
];
if (item.providerKey && item.isFolder)
result = result.filter((x) => x.id !== "Size");
if (dontShowOwner) result.shift();
if (item.isFolder) return result;

View File

@ -126,14 +126,6 @@ const StyledProperties = styled.div`
font-size: 13px;
}
}
.oforms-description {
margin-top: 36px;
.oforms-description-text {
margin: 0;
}
}
`;
const StyledAccess = styled.div`

View File

@ -133,22 +133,22 @@ const FilesRowContent = ({
{updatedDate && updatedDate}
</Text>
{!isMobileOnly && (
<Text
containerMinWidth="90px"
containerWidth="10%"
as="div"
className="row-content-text"
fontSize="12px"
fontWeight={400}
title=""
truncate={true}
>
{!fileExst && !contentLength && !providerKey
? `${foldersCount} ${t("Folders")} | ${filesCount} ${t("Files")}`
: ""}
</Text>
)}
<Text
containerMinWidth="90px"
containerWidth="10%"
as="div"
className="row-content-text"
fontSize="12px"
fontWeight={400}
title=""
truncate={true}
>
{!fileExst && !contentLength && !providerKey && !isMobileOnly
? `${foldersCount} ${t("Folders")} | ${filesCount} ${t("Files")}`
: fileExst
? `${fileExst.toUpperCase().replace(/^\./, "")}`
: ""}
</Text>
</SimpleFilesRowContent>
</>
);

View File

@ -373,13 +373,21 @@ class Tile extends React.PureComponent {
onFileClick = (e) => {
const { onSelect, item, checked, setSelection } = this.props;
if (e.detail === 1) {
if (e.target.nodeName === "INPUT" || e.target.nodeName === "rect") {
onSelect && onSelect(!checked, item);
} else {
if (
e.detail === 1 &&
!e.target.closest(".badge") &&
!e.target.closest(".item-file-name")
) {
if (
e.target.nodeName !== "IMG" &&
e.target.nodeName !== "INPUT" &&
e.target.nodeName !== "rect"
) {
setSelection && setSelection([]);
onSelect && onSelect(!checked, item);
}
onSelect && onSelect(!checked, item);
}
};

View File

@ -4,15 +4,17 @@ import styled, { css } from "styled-components";
import { withRouter } from "react-router";
import toastr from "studio/toastr";
import Loaders from "@appserver/common/components/Loaders";
import { FileAction } from "@appserver/common/constants";
import { AppServerConfig, FileAction } from "@appserver/common/constants";
import { withTranslation } from "react-i18next";
import { isMobile } from "react-device-detect";
import { isMobile, isTablet } from "react-device-detect";
import DropDownItem from "@appserver/components/drop-down-item";
import { tablet } from "@appserver/components/utils/device";
import { Consumer } from "@appserver/components/utils/context";
import { inject, observer } from "mobx-react";
import TableGroupMenu from "@appserver/components/table-container/TableGroupMenu";
import Navigation from "@appserver/common/components/Navigation";
import config from "../../../../../package.json";
import { combineUrl } from "@appserver/common/utils";
const StyledContainer = styled.div`
.table-container_group-menu {
@ -67,6 +69,17 @@ class SectionHeaderContent extends React.Component {
setSelectFileDialogVisible(true);
};
onShowGallery = () => {
const { history, currentFolderId } = this.props;
history.push(
combineUrl(
AppServerConfig.proxyURL,
config.homepage,
`/form-gallery/${currentFolderId}/`
)
);
};
createFolder = () => this.onCreate();
uploadToFolder = () => console.log("Upload To Folder click");
@ -104,6 +117,12 @@ class SectionHeaderContent extends React.Component {
disabled: isPrivacyFolder,
icon: "images/form.file.react.svg",
},
{
label: t("Common:OFORMsGallery"),
onClick: this.onShowGallery,
disabled: isPrivacyFolder || (isMobile && isTablet),
icon: "images/form.react.svg",
},
{
key: "new-folder",
label: t("NewFolder"),

View File

@ -68,19 +68,19 @@ class ContextOptionsStore {
this.settingsStore.extsWebRestrictedEditing[0];
this.uploadDataStore.copyAsAction(id, newTitle, folderId).catch((err) => {
console.log("err", err);
const isPasswordError = new RegExp(/\(password\)*$/);
if (isPasswordError.test(err)) {
toastr.error(t("Translations:FileProtected"), t("Common:Warning"));
setFormCreationInfo({
newTitle,
fromExst: fileExst,
toExst: this.settingsStore.extsWebRestrictedEditing[0],
fileInfo: item,
});
setConvertPasswordDialogVisible(true);
if (err.indexOf("password") == -1) {
toastr.error(err, t("Common:Warning"));
return;
}
toastr.error(t("Translations:FileProtected"), t("Common:Warning"));
setFormCreationInfo({
newTitle,
fromExst: fileExst,
toExst: this.settingsStore.extsWebRestrictedEditing[0],
fileInfo: item,
});
setConvertPasswordDialogVisible(true);
});
};

View File

@ -1492,7 +1492,7 @@ class FilesStore {
if (items.length && items[0].id === -1) return; //TODO: if change media collection from state remove this;
const iconSize = this.viewAs === "tile" && isMobile ? 32 : 24;
const iconSize = this.viewAs === "table" ? 24 : 32;
const icon = extension
? getFileIcon(`.${extension}`, iconSize)
: getFolderIcon(null, iconSize);

View File

@ -158,7 +158,10 @@ class HotkeyStore {
filesList,
setHotkeyCaretStart,
selection,
viewAs,
} = this.filesStore;
if (viewAs !== "tile") return;
if (!hotkeyCaret && !selection.length) {
this.selectFirstFile();
@ -174,7 +177,9 @@ class HotkeyStore {
filesList,
setHotkeyCaretStart,
selection,
viewAs,
} = this.filesStore;
if (viewAs !== "tile") return;
if (!hotkeyCaret && !selection.length) {
this.selectFirstFile();
@ -266,6 +271,7 @@ class HotkeyStore {
hotkeyCaretStart,
filesList,
} = this.filesStore;
if (viewAs !== "tile") return;
if (!hotkeyCaret && !selection.length) return this.selectFirstFile();
@ -324,6 +330,7 @@ class HotkeyStore {
filesList,
hotkeyCaretStart,
} = this.filesStore;
if (viewAs !== "tile") return;
if (!hotkeyCaret && !selection.length) return this.selectFirstFile();

View File

@ -28,6 +28,7 @@ using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
@ -43,7 +44,7 @@ using ASC.Files.Core.Data;
using ASC.Files.Core.Resources;
using ASC.Files.Core.Security;
using ASC.Web.Core;
using ASC.Web.Core.Files;
using ASC.Web.Core.Files;
using ASC.Web.Core.Users;
using ASC.Web.Core.WhiteLabel;
using ASC.Web.Files.Utils;
@ -592,10 +593,11 @@ namespace ASC.Web.Files.Classes
}
private async Task SaveStartDocumentAsync(FileMarker fileMarker, FolderDao folderDao, FileDao fileDao, int folderId, string path, IDataStore storeTemplate)
{
await foreach (var file in storeTemplate.ListFilesRelativeAsync("", path, "*", false))
{
var files = await storeTemplate.ListFilesRelativeAsync("", path, "*", false).ToListAsync();
foreach (var file in files)
{
await SaveFileAsync(fileMarker, fileDao, folderId, path + file, storeTemplate);
await SaveFileAsync(fileMarker, fileDao, folderId, path + file, storeTemplate, files);
}
await foreach (var folderName in storeTemplate.ListDirectoriesRelativeAsync(path, false))
@ -610,15 +612,18 @@ namespace ASC.Web.Files.Classes
}
}
private async Task SaveFileAsync(FileMarker fileMarker, FileDao fileDao, int folder, string filePath, IDataStore storeTemp)
private async Task SaveFileAsync(FileMarker fileMarker, FileDao fileDao, int folder, string filePath, IDataStore storeTemp, IEnumerable<string> files)
{
try
{
if (FileUtility.GetFileExtension(filePath) == "." + Global.ThumbnailExtension
&& await storeTemp.IsFileAsync("", Regex.Replace(filePath, "\\." + Global.ThumbnailExtension + "$", "")))
return;
var fileName = Path.GetFileName(filePath);
foreach (var ext in Enum.GetValues<ThumbnailExtension>())
{
if (FileUtility.GetFileExtension(filePath) == "." + ext
&& files.Contains(Regex.Replace(fileName, "\\." + ext + "$", "")))
return;
}
var file = ServiceProvider.GetService<File<int>>();
file.Title = fileName;
@ -631,21 +636,6 @@ namespace ASC.Web.Files.Classes
file = await fileDao.SaveFileAsync(file, stream, false);
}
foreach (var size in _thumbnailSettings.Sizes)
{
var pathThumb = $"{filePath}.{size.Width}x{size.Height}.{Global.ThumbnailExtension}";
if (await storeTemp.IsFileAsync("", pathThumb))
{
using (var streamThumb = await storeTemp.GetReadStreamAsync("", pathThumb))
{
await fileDao.SaveThumbnailAsync(file, streamThumb, size.Width, size.Height);
}
}
}
file.ThumbnailStatus = Thumbnail.Created;
await fileMarker.MarkAsNewAsync(file);
}
catch (Exception ex)

View File

@ -118,12 +118,13 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
MimeMapping.GetMimeMapping(path),
"attachment; filename=\"" + fileName + "\"");
Result = string.Format("{0}?{1}=bulk&ext={2}", filesLinkUtility.FileHandlerPath, FilesLinkUtility.Action, archiveExtension);
}
}
TaskInfo.SetProperty(FINISHED, true);
FillDistributedTask();
TaskInfo.PublishChanges();
}
}
public override void PublishChanges(DistributedTask task)
{
var thirdpartyTask = ThirdPartyOperation.GetDistributedTask();
@ -139,15 +140,7 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
else if (!string.IsNullOrEmpty(error2))
{
Error = error2;
}
var finished1 = thirdpartyTask.GetProperty<bool?>(FINISHED);
var finished2 = daoTask.GetProperty<bool?>(FINISHED);
if (finished1 != null && finished2 != null)
{
TaskInfo.SetProperty(FINISHED, finished1);
}
}
successProcessed = thirdpartyTask.GetProperty<int>(PROCESSED) + daoTask.GetProperty<int>(PROCESSED);
@ -383,6 +376,7 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
filesMessageService.Send(file, headers, MessageAction.FileDownloaded, file.Title);
}
}
compressTo.CloseEntry();
}
catch (Exception ex)
{
@ -393,8 +387,9 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
else
{
compressTo.PutNextEntry();
compressTo.CloseEntry();
}
compressTo.CloseEntry();
counter++;
}

View File

@ -605,6 +605,12 @@
<None Update="DocStore\new\zh-CN\xlsx.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DocStore\sample\de-DE\my\ONLYOFFICE Sample Form Template.docxf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DocStore\sample\de-DE\my\ONLYOFFICE Sample Form.oform">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DocStore\sample\de-DE\my\ONLYOFFICE-Musteraudio.mp3">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
@ -612,7 +618,7 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DocStore\sample\de-DE\my\ONLYOFFICE-Musterpraesentation.pptx.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
<None Update="DocStore\sample\de-DE\my\ONLYOFFICE-Musterpräsentation.pptx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
@ -629,6 +635,12 @@
<None Update="DocStore\sample\en-US\my\ONLYOFFICE Sample Document.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DocStore\sample\en-US\my\ONLYOFFICE Sample Form Template.docxf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DocStore\sample\en-US\my\ONLYOFFICE Sample Form.oform">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DocStore\sample\en-US\my\ONLYOFFICE Sample Presentation.pptx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
@ -644,6 +656,12 @@
<None Update="DocStore\sample\es-ES\my\ONLYOFFICE Sample Document.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DocStore\sample\es-ES\my\ONLYOFFICE Sample Form Template.docxf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DocStore\sample\es-ES\my\ONLYOFFICE Sample Form.oform">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DocStore\sample\es-ES\my\ONLYOFFICE Sample Presentation.pptx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
@ -659,6 +677,12 @@
<None Update="DocStore\sample\fr-FR\my\ONLYOFFICE Sample Document.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DocStore\sample\fr-FR\my\ONLYOFFICE Sample Form Template.docxf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DocStore\sample\fr-FR\my\ONLYOFFICE Sample Form.oform">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DocStore\sample\fr-FR\my\ONLYOFFICE Sample Presentation.pptx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
@ -674,6 +698,12 @@
<None Update="DocStore\sample\it-IT\my\ONLYOFFICE Sample Document.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DocStore\sample\it-IT\my\ONLYOFFICE Sample Form Template.docxf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DocStore\sample\it-IT\my\ONLYOFFICE Sample Form.oform">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DocStore\sample\it-IT\my\ONLYOFFICE Sample Presentation.pptx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
@ -689,6 +719,12 @@
<None Update="DocStore\sample\ru-RU\my\ONLYOFFICE Sample Document.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DocStore\sample\ru-RU\my\ONLYOFFICE Sample Form Template.docxf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DocStore\sample\ru-RU\my\ONLYOFFICE Sample Form.oform">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DocStore\sample\ru-RU\my\ONLYOFFICE Sample Presentation.pptx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>

View File

@ -1,4 +1,4 @@
{
"MessageSendPasswordChangeInstructionsOnEmail": "Envoyer le mot de passe.",
"MessageSendPasswordChangeInstructionsOnEmail": "Envoyer le mot de passe à <1>{{email}}</1>",
"PasswordChangeTitle": "Changement de mot de passe"
}

View File

@ -15,13 +15,10 @@ class ChangeEmailDialogComponent extends React.Component {
constructor(props) {
super(props);
const { user } = props;
const { email } = user;
this.state = {
isEmailValid: true,
isRequestRunning: false,
email,
email: "",
hasError: false,
errorMessage: "",
emailErrors: [],
@ -32,14 +29,6 @@ class ChangeEmailDialogComponent extends React.Component {
window.addEventListener("keyup", this.onKeyPress);
}
componentDidUpdate(prevProps) {
const { user } = this.props;
const { email } = user;
if (prevProps.user.email !== email) {
this.setState({ email });
}
}
componentWillUnmount() {
window.removeEventListener("keyup", this.onKeyPress);
}
@ -156,6 +145,7 @@ class ChangeEmailDialogComponent extends React.Component {
onValidateInput={this.onValidateEmailInput}
onKeyUp={this.onKeyPress}
hasError={hasError}
placeholder={t("EnterEmail")}
/>
</FieldContainer>
</>

View File

@ -310,17 +310,21 @@ class ProfileInfo extends React.PureComponent {
/>
</IconButtonWrapper>
)}
<Link
className="email-link"
type="page"
fontSize="13px"
isHovered={true}
title={email}
data-email={email}
onClick={this.onEmailClick}
>
{email}
</Link>
{isSelf ? (
<InfoItemValue>{email}</InfoItemValue>
) : (
<Link
className="email-link"
type="page"
fontSize="13px"
isHovered={true}
title={email}
data-email={email}
onClick={this.onEmailClick}
>
{email}
</Link>
)}
</>
</InfoItemValue>
</InfoItem>

View File

@ -516,7 +516,11 @@ class SectionBodyContent extends React.PureComponent {
{isSelf && (
<ToggleWrapper>
<ToggleContent label={t("InterfaceTheme")} isOpen={true}>
<ToggleContent
label={t("InterfaceTheme")}
isOpen={true}
enableToggle={false}
>
<RadioButtonGroup
orientation={"vertical"}
name={"interface-theme"}

View File

@ -475,6 +475,7 @@ class SectionHeaderContent extends React.PureComponent {
size={17}
getData={contextOptions}
isDisabled={false}
usePortal={false}
/>
)}
{visibleAvatarEditor && (

View File

@ -841,34 +841,35 @@ class UpdateUserForm extends React.Component {
maxLength={50}
maxLabelWidth={maxLabelWidth}
/>
{!personal && (
<DateField
calendarHeaderContent={`${t("CalendarSelectDate")}:`}
labelText={`${t("Translations:Birthdate")}:`}
inputName="birthday"
inputClassName="date-picker_input-birthday"
inputValue={birthdayDateValue}
inputIsDisabled={isLoading}
inputOnChange={this.onBirthdayDateChange}
inputTabIndex={6}
locale={language}
maxLabelWidth={maxLabelWidth}
/>
)}
<RadioField
labelText={`${t("Translations:Sex")}:`}
radioName="sex"
radioValue={profile.sex}
radioOptions={[
{ value: "male", label: t("Translations:MaleSexStatus") },
{ value: "female", label: t("Translations:FemaleSexStatus") },
]}
radioIsDisabled={isLoading}
radioOnChange={this.onInputChange}
maxLabelWidth={maxLabelWidth}
/>
{!personal && (
<>
<DateField
calendarHeaderContent={`${t("CalendarSelectDate")}:`}
labelText={`${t("Translations:Birthdate")}:`}
inputName="birthday"
inputClassName="date-picker_input-birthday"
inputValue={birthdayDateValue}
inputIsDisabled={isLoading}
inputOnChange={this.onBirthdayDateChange}
inputTabIndex={6}
locale={language}
maxLabelWidth={maxLabelWidth}
/>
<RadioField
labelText={`${t("Translations:Sex")}:`}
radioName="sex"
radioValue={profile.sex}
radioOptions={[
{ value: "male", label: t("Translations:MaleSexStatus") },
{
value: "female",
label: t("Translations:FemaleSexStatus"),
},
]}
radioIsDisabled={isLoading}
radioOnChange={this.onInputChange}
maxLabelWidth={maxLabelWidth}
/>
<RadioField
labelText={`${t("Common:Type")}:`}
radioName="isVisitor"

View File

@ -0,0 +1,3 @@
<svg width="16" height="12" viewBox="0 0 16 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.20718 11.2072L15.7072 1.70718L14.293 0.292969L5.50007 9.08586L1.70718 5.29297L0.292969 6.70718L4.79296 11.2072C5.18349 11.5977 5.81665 11.5977 6.20718 11.2072Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 331 B

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from "react";
import React, { useEffect } from "react";
import { Router, Switch, Route, Redirect } from "react-router-dom";
import { inject, observer } from "mobx-react";
import NavMenu from "./components/NavMenu";
@ -198,11 +198,8 @@ const Shell = ({ items = [], page = "home", ...rest }) => {
roomsMode,
setSnackbarExist,
userTheme,
currentProductId,
} = rest;
const [isDocuments, setIsDocuments] = useState(false);
useEffect(() => {
try {
if (!window.AppServer) {
@ -429,14 +426,6 @@ const Shell = ({ items = [], page = "home", ...rest }) => {
if (userTheme) setTheme(userTheme);
}, [userTheme]);
useEffect(() => {
if (window.location.pathname.toLowerCase().includes("files")) {
setIsDocuments(true);
} else {
setIsDocuments(false);
}
}, [currentProductId]);
const pathname = window.location.pathname.toLowerCase();
const isEditor = pathname.indexOf("doceditor") !== -1;
@ -522,7 +511,7 @@ const Shell = ({ items = [], page = "home", ...rest }) => {
<Layout>
<Router history={history}>
<>
{isDocuments ? <ReactSmartBanner t={t} ready={ready} /> : <></>}
<ReactSmartBanner t={t} ready={ready} />
{isEditor ? <></> : <NavMenu />}
<ScrollToTop />
<Main isDesktop={isDesktop}>
@ -585,7 +574,6 @@ const ShellWrapper = inject(({ auth, backup }) => {
setSnackbarExist,
socketHelper,
setTheme,
currentProductId,
} = settingsStore;
const { setPreparationPortalDialogVisible } = backup;
@ -614,7 +602,6 @@ const ShellWrapper = inject(({ auth, backup }) => {
roomsMode,
setSnackbarExist,
userTheme: auth?.userStore?.user?.theme,
currentProductId,
};
})(observer(Shell));

View File

@ -109,7 +109,7 @@ const Layout = (props) => {
if (isMobileOnly && isIOS && isChrome) {
if (window.innerHeight < window.innerWidth && isPortrait) {
height = window.screen.availWidth - correctorMobileChrome;
height = window.screen.availWidth - correctorMobileChrome + "px";
}
}

View File

@ -10,9 +10,17 @@ const Wrapper = styled.div`
`;
const ReactSmartBanner = (props) => {
const { t, ready, isBannerVisible, setIsBannerVisible } = props;
const {
t,
ready,
isBannerVisible,
setIsBannerVisible,
currentProductId,
} = props;
const force = isIOS ? "ios" : "android";
const [isDocuments, setIsDocuments] = useState(false);
const getCookie = (name) => {
let matches = document.cookie.match(
new RegExp(
@ -34,6 +42,14 @@ const ReactSmartBanner = (props) => {
if (cookieClosed || cookieInstalled) hideBanner();
}, []);
useEffect(() => {
if (window.location.pathname.toLowerCase().includes("files")) {
setIsDocuments(true);
} else {
setIsDocuments(false);
}
}, [currentProductId]);
const storeText = {
ios: t("SmartBanner:AppStore"),
android: t("SmartBanner:GooglePlay"),
@ -60,7 +76,11 @@ const ReactSmartBanner = (props) => {
navigator.maxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0;
return isMobile && isBannerVisible && ready && isTouchDevice ? (
return isMobile &&
isBannerVisible &&
ready &&
isTouchDevice &&
isDocuments ? (
<Wrapper>
<SmartBanner
title={t("SmartBanner:AppName")}
@ -79,9 +99,10 @@ const ReactSmartBanner = (props) => {
);
};
export default inject(({ bannerStore }) => {
export default inject(({ auth, bannerStore }) => {
return {
isBannerVisible: bannerStore.isBannerVisible,
setIsBannerVisible: bannerStore.setIsBannerVisible,
currentProductId: auth.settingsStore.currentProductId,
};
})(observer(ReactSmartBanner));

View File

@ -1,8 +1,8 @@
import React, { useState, useEffect } from "react";
import React, { useState, useEffect, useCallback, useMemo } from "react";
import { withTranslation } from "react-i18next";
import { inject, observer } from "mobx-react";
import Button from "@appserver/components/button";
import withLoading from "../../../../../HOCs/withLoading";
import globalColors from "@appserver/components/utils/globalColors";
import styled from "styled-components";
@ -18,58 +18,98 @@ const StyledComponent = styled.div`
height: 46px;
margin-right: 12px;
}
.first-color-scheme {
background: ${globalColors.firstDefaultСolorScheme};
#color-scheme_1 {
background: ${globalColors.colorSchemeDefault_1};
}
.second-color-scheme {
background: ${globalColors.secondDefaultСolorScheme};
#color-scheme_2 {
background: ${globalColors.colorSchemeDefault_2};
}
.third-color-scheme {
background: ${globalColors.thirdDefaultСolorScheme};
#color-scheme_3 {
background: ${globalColors.colorSchemeDefault_3};
}
.fourth-color-scheme {
background: ${globalColors.fourthDefaultСolorScheme};
#color-scheme_4 {
background: ${globalColors.colorSchemeDefault_4};
}
.fifth-color-scheme {
background: ${globalColors.fifthDefaultСolorScheme};
#color-scheme_5 {
background: ${globalColors.colorSchemeDefault_5};
}
.sixth-color-scheme {
background: ${globalColors.sixthDefaultСolorScheme};
#color-scheme_6 {
background: ${globalColors.colorSchemeDefault_6};
}
.sevent-color-scheme {
background: ${globalColors.seventhDefaultСolorScheme};
#color-scheme_7 {
background: ${globalColors.colorSchemeDefault_7};
}
`;
const Appearance = (props) => {
const array_items = [
{
key: "0",
title: "Light theme",
content: <Preview />,
},
{
key: "1",
title: "Dark theme",
content: <div>Tab 2 content</div>,
},
];
const [selectedColor, setSelectedColor] = useState(1);
const checkImg = <img src="/static/images/check.white.svg" />;
const array_items = useMemo(
() => [
{
key: "0",
title: "Light theme",
content: <Preview selectedColor={selectedColor} />,
},
{
key: "1",
title: "Dark theme",
content: <Preview selectedColor={selectedColor} />,
},
],
[selectedColor]
);
useEffect(() => {}, [selectedColor]);
const onColorSelection = (e) => {
if (!e.target.id) return;
const colorNumber = e.target.id[e.target.id.length - 1];
setSelectedColor(+colorNumber);
};
const onShowCheck = (colorNumber) => {
return selectedColor && selectedColor === colorNumber && checkImg;
};
return (
<StyledComponent>
<div>Color</div>
<div>Header color is displayed only when light theme is applied</div>
<div className="container">
<div className="box first-color-scheme"></div>
<div className="box second-color-scheme"></div>
<div className="box third-color-scheme"></div>
<div className="box fourth-color-scheme"></div>
<div className="box fifth-color-scheme"></div>
<div className="box sixth-color-scheme"></div>
<div className="box sevent-color-scheme"></div>
<div id="color-scheme_1" className="box" onClick={onColorSelection}>
{onShowCheck(1)}
</div>
<div id="color-scheme_2" className="box" onClick={onColorSelection}>
{onShowCheck(2)}
</div>
<div id="color-scheme_3" className="box" onClick={onColorSelection}>
{onShowCheck(3)}
</div>
<div id="color-scheme_4" className="box" onClick={onColorSelection}>
{onShowCheck(4)}
</div>
<div id="color-scheme_5" className="box" onClick={onColorSelection}>
{onShowCheck(5)}
</div>
<div id="color-scheme_6" className="box" onClick={onColorSelection}>
{onShowCheck(6)}
</div>
<div id="color-scheme_7" className="box" onClick={onColorSelection}>
{onShowCheck(7)}
</div>
</div>
<div>Preview</div>
<TabContainer elements={array_items} />
<Button
label="Save"
onClick={function noRefCheck() {}}
primary
size="small"
/>
</StyledComponent>
);
};

View File

@ -44,12 +44,12 @@ const SubmenuCommon = (props) => {
},
{
id: "branding",
name: t("Branding"),
name: "Branding",
content: <Branding />,
},
{
id: "appearance",
name: t("Appearance"),
name: "Appearance",
content: <Appearance />,
},
];

View File

@ -8,6 +8,7 @@ import { inject, observer } from "mobx-react";
import Loaders from "@appserver/common/components/Loaders";
import MainButton from "@appserver/components/main-button";
import ContextMenuButton from "@appserver/components/context-menu-button";
import globalColors from "@appserver/components/utils/globalColors";
const StyledComponent = styled.div`
display: flex;
@ -155,12 +156,30 @@ const StyledComponent = styled.div`
`;
const Preview = (props) => {
const { selectedColor } = props;
const [color, setColor] = useState();
const globalColors = "globalColors.colorSchemeDefault_";
useEffect(() => {
setColor(globalColors + `${selectedColor}`);
}, [selectedColor]);
return (
<StyledComponent>
<div className="menu">
<Loaders.Rectangle width="211" height="24" className="header" />
<Loaders.Rectangle
width="211"
height="24"
className="header"
style={{ background: `${color}` }}
/>
<MainButton text="Actions" className="main-button-preview" />
<MainButton
text="Actions"
className="main-button-preview"
style={{ background: `${color}` }}
/>
<div className="menu-section">
<Loaders.Rectangle width="37" height="12" className="title-section" />

View File

@ -73,7 +73,7 @@ const SettingsContainer = ({
{titleEmail}
{contentEmail}
<Text fontSize="13px">{t("Language")}:</Text>
<Text fontSize="13px">{t("Common:Language")}:</Text>
<ComboBox
className="drop-down"
options={languages}

View File

@ -290,7 +290,7 @@
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="PublicResources\WebstudioNotifyPatternResource.resx">
<Generator>ResXFileCodeGenerator</Generator>
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>WebstudioNotifyPatternResource.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="PublicResources\WebstudioNotifyPatternResource.ru.resx">

View File

@ -19,7 +19,7 @@ namespace ASC.Web.Core.PublicResources {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class CustomModeResource {
@ -175,11 +175,11 @@ namespace ASC.Web.Core.PublicResources {
/// <summary>
/// Looks up a localized string similar to You have requested a termination of your account at personal.onlyoffice.com. Follow the link to complete the request (the link is active for a 7-day period):
///
///Confirm account termination
///$GreenButton
///
///*Note*: After the deletion, your account and all data associated with it will be erased permanently in accordance with our &quot;Privacy statement&quot;:&quot;https://help.onlyoffice.com/products/files/doceditor.aspx?fileid=5048502&amp;doc=SXhWMEVzSEYxNlVVaXJJeUVtS0kyYk14YWdXTEFUQmRWL250NllHNUFGbz0_IjUwNDg1MDIi0&quot;.
///
///&quot;Read more about account [rest of string was truncated]&quot;;.
///&quot;Read more about account termination&quot;:&quot;h [rest of string was truncated]&quot;;.
/// </summary>
public static string pattern_personal_custom_mode_profile_delete {
get {

View File

@ -181,7 +181,7 @@ ONLYOFFICE team</value>
<data name="pattern_personal_custom_mode_profile_delete" xml:space="preserve">
<value>You have requested a termination of your account at personal.onlyoffice.com. Follow the link to complete the request (the link is active for a 7-day period):
Confirm account termination
$GreenButton
*Note*: After the deletion, your account and all data associated with it will be erased permanently in accordance with our "Privacy statement":"https://help.onlyoffice.com/products/files/doceditor.aspx?fileid=5048502&amp;doc=SXhWMEVzSEYxNlVVaXJJeUVtS0kyYk14YWdXTEFUQmRWL250NllHNUFGbz0_IjUwNDg1MDIi0".

View File

@ -19,7 +19,7 @@ namespace ASC.Web.Core.PublicResources {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class WebstudioNotifyPatternResource {
@ -1586,11 +1586,11 @@ namespace ASC.Web.Core.PublicResources {
/// <summary>
/// Looks up a localized string similar to You have requested a termination of your account at personal.onlyoffice.com. Follow the link to complete the request (the link is active for a 7-day period):
///
///Confirm account termination
///$GreenButton
///
///*Note*: After the deletion, your account and all data associated with it will be erased permanently in accordance with our &quot;Privacy statement&quot;:&quot;https://help.onlyoffice.com/products/files/doceditor.aspx?fileid=5048502&amp;doc=SXhWMEVzSEYxNlVVaXJJeUVtS0kyYk14YWdXTEFUQmRWL250NllHNUFGbz0_IjUwNDg1MDIi0&quot;.
///
///&quot;Read more about account [rest of string was truncated]&quot;;.
///&quot;Read more about account termination&quot;:&quot;h [rest of string was truncated]&quot;;.
/// </summary>
public static string pattern_personal_profile_delete {
get {

View File

@ -1057,7 +1057,7 @@ ONLYOFFICE team</value>
<data name="pattern_personal_profile_delete" xml:space="preserve">
<value>You have requested a termination of your account at personal.onlyoffice.com. Follow the link to complete the request (the link is active for a 7-day period):
Confirm account termination
$GreenButton
*Note*: After the deletion, your account and all data associated with it will be erased permanently in accordance with our "Privacy statement":"https://help.onlyoffice.com/products/files/doceditor.aspx?fileid=5048502&amp;doc=SXhWMEVzSEYxNlVVaXJJeUVtS0kyYk14YWdXTEFUQmRWL250NllHNUFGbz0_IjUwNDg1MDIi0".