Merge branch 'feature/modal-redesign' of https://github.com/ONLYOFFICE/AppServer into feature/modal-redesign

This commit is contained in:
Alexey Safronov 2022-07-12 12:59:36 +03:00
commit 91b652aa8e
120 changed files with 891 additions and 20949 deletions

View File

@ -65,6 +65,7 @@ public class DbTenant : IMapFrom<Tenant>
public void Mapping(Profile profile)
{
profile.CreateMap<Tenant, DbTenant>()
.ForMember(dest => dest.TrustedDomainsEnabled, opt => opt.MapFrom(dest => dest.TrustedDomainsType))
.ForMember(dest => dest.TrustedDomainsRaw, opt => opt.MapFrom(dest => dest.GetTrustedDomains()))
.ForMember(dest => dest.Alias, opt => opt.MapFrom(dest => dest.Alias.ToLowerInvariant()))
.ForMember(dest => dest.LastModified, opt => opt.MapFrom(dest => DateTime.UtcNow))

View File

@ -149,7 +149,8 @@ public class Tenant : IMapFrom<DbTenant>
public void Mapping(Profile profile)
{
profile.CreateMap<DbTenant, Tenant>();
profile.CreateMap<DbTenant, Tenant>()
.ForMember(r => r.TrustedDomainsType, opt => opt.MapFrom(src => src.TrustedDomainsEnabled));
profile.CreateMap<TenantUserSecurity, Tenant>()
.IncludeMembers(src => src.DbTenant);

View File

@ -59,7 +59,8 @@ public class IPRestrictionsRepository
using var tx = TenantDbContext.Database.BeginTransaction();
var restrictions = TenantDbContext.TenantIpRestrictions.Where(r => r.Tenant == tenant).ToList();
TenantDbContext.TenantIpRestrictions.RemoveRange(restrictions);
TenantDbContext.TenantIpRestrictions.RemoveRange(restrictions);
TenantDbContext.SaveChanges();
var ipsList = ips.Select(r => new TenantIpRestrictions
{
@ -67,7 +68,8 @@ public class IPRestrictionsRepository
Ip = r
});
TenantDbContext.TenantIpRestrictions.AddRange(ipsList);
TenantDbContext.TenantIpRestrictions.AddRange(ipsList);
TenantDbContext.SaveChanges();
tx.Commit();
});

View File

@ -7,9 +7,9 @@ const StyledModalBackdrop = styled.div.attrs((props) => ({
backdropFilter: `${
props.modalSwipeOffset
? `blur(${
props.modalSwipeOffset < 0 && 18 - props.modalSwipeOffset * -0.14
props.modalSwipeOffset < 0 && 8 - props.modalSwipeOffset * -0.0667
}px)`
: "blur(18px)"
: "blur(8px)"
}`,
background: `${
@ -22,7 +22,9 @@ const StyledModalBackdrop = styled.div.attrs((props) => ({
},
}))`
display: block;
height: 100vh;
height: 100%;
min-height: fill-available;
max-height: 100vh;
width: 100vw;
position: fixed;

View File

@ -8,7 +8,6 @@ const StyledModal = styled.div`
&.modal-active {
pointer-events: all;
}
.loader-wrapper {
padding: 0 16px 16px;
}

View File

@ -52,6 +52,7 @@ const Modal = ({
>
<Dialog
className={`${className} dialog not-selectable`}
currentDisplayType={currentDisplayType}
id={id}
style={style}
onClick={onClose}

View File

@ -29,6 +29,7 @@ import {
ArticleMainButtonContent,
} from "./components/Article";
import FormGallery from "./pages/FormGallery";
import GlobalEvents from "./components/GlobalEvents";
const { proxyURL } = AppServerConfig;
const homepage = config.homepage;
@ -169,6 +170,7 @@ class FilesContent extends React.Component {
return (
<>
<GlobalEvents />
<Panels />
<FilesArticle history={this.props.history} />
<FilesSection />

View File

@ -21,384 +21,19 @@ export default function withContent(WrappedContent) {
constructor(props) {
super(props);
const {
item,
fileActionId,
fileActionExt,
fileActionTemplateId,
fromTemplate,
} = props;
let titleWithoutExt = props.titleWithoutExt;
if (
fileActionId === -1 &&
item.id === fileActionId &&
fileActionTemplateId === null &&
!fromTemplate
) {
titleWithoutExt = getDefaultFileName(fileActionExt);
}
this.state = { itemTitle: titleWithoutExt };
}
componentDidUpdate(prevProps) {
const {
fileActionId,
fileActionExt,
setIsUpdatingRowItem,
isUpdatingRowItem,
isEdit,
titleWithoutExt,
} = this.props;
if (fileActionId === -1 && fileActionExt !== prevProps.fileActionExt) {
const itemTitle = getDefaultFileName(fileActionExt);
this.setState({ itemTitle });
}
if (fileActionId === null && prevProps.fileActionId !== fileActionId) {
isUpdatingRowItem && setIsUpdatingRowItem(false);
}
const { titleWithoutExt } = this.props;
if (!isEdit && titleWithoutExt !== this.state.itemTitle) {
if (titleWithoutExt !== this.state.itemTitle) {
this.setState({ itemTitle: titleWithoutExt });
}
}
completeAction = (id) => {
const { editCompleteAction, item } = this.props;
const isCancel =
(id.currentTarget && id.currentTarget.dataset.action === "cancel") ||
id.keyCode === 27;
editCompleteAction(id, item, isCancel);
};
updateItem = () => {
const {
t,
updateFile,
renameFolder,
item,
setIsLoading,
fileActionId,
editCompleteAction,
addActiveItems,
clearActiveOperations,
} = this.props;
const { itemTitle } = this.state;
const originalTitle = getTitleWithoutExst(item);
setIsLoading(true);
let timerId;
const isSameTitle =
originalTitle.trim() === itemTitle.trim() || itemTitle.trim() === "";
const isFile = item.fileExst || item.contentLength;
if (isSameTitle) {
this.setState({
itemTitle: originalTitle,
});
return editCompleteAction(fileActionId, item, isSameTitle);
} else {
timerId = setTimeout(() => {
isFile ? addActiveItems([item.id]) : addActiveItems(null, [item.id]);
}, 500);
}
isFile
? updateFile(fileActionId, itemTitle)
.then(() => this.completeAction(fileActionId))
.then(() =>
toastr.success(
t("FileRenamed", {
oldTitle: item.title,
newTitle: itemTitle + item.fileExst,
})
)
)
.catch((err) => {
toastr.error(err);
this.completeAction(fileActionId);
})
.finally(() => {
clearTimeout(timerId);
timerId = null;
clearActiveOperations([item.id]);
setIsLoading(false);
})
: renameFolder(fileActionId, itemTitle)
.then(() => this.completeAction(fileActionId))
.then(() =>
toastr.success(
t("FolderRenamed", {
folderTitle: item.title,
newFoldedTitle: itemTitle,
})
)
)
.catch((err) => {
toastr.error(err);
this.completeAction(fileActionId);
})
.finally(() => {
clearTimeout(timerId);
timerId = null;
clearActiveOperations(null, [item.id]);
setIsLoading(false);
});
};
cancelUpdateItem = (e) => {
const { item } = this.props;
const originalTitle = getTitleWithoutExst(item);
this.setState({
itemTitle: originalTitle,
});
return this.completeAction(e);
};
onClickUpdateItem = (e, open = true) => {
const {
fileActionType,
setIsUpdatingRowItem,
addActiveItems,
item,
} = this.props;
setIsUpdatingRowItem(true);
if (fileActionType === FileAction.Create) {
!item.fileExst && !item.contentLength
? addActiveItems(null, [item.id])
: addActiveItems([item.id]);
this.createItem(e, open);
} else {
this.updateItem(e);
}
};
createItem = (e, open) => {
const {
createFile,
createFolder,
fileActionTemplateId,
isDesktop,
isPrivacy,
item,
openDocEditor,
replaceFileStream,
setEncryptionAccess,
setIsLoading,
t,
setConvertPasswordDialogVisible,
setFormCreationInfo,
setIsUpdatingRowItem,
clearActiveOperations,
addActiveItems,
fileCopyAs,
fromTemplate,
gallerySelected,
setCreatedItem,
} = this.props;
const { itemTitle } = this.state;
const { parentId, fileExst } = item;
const isMakeFormFromFile = fileActionTemplateId ? true : false;
let title = itemTitle;
setIsLoading(true);
const itemId = e.currentTarget.dataset.itemid;
let createdFileId, createdFolderId;
if (itemTitle.trim() === "") {
title =
fileActionTemplateId === null
? getDefaultFileName(item.fileExst)
: getTitleWithoutExst(item);
this.setState({
itemTitle: title,
});
}
let tab =
!isDesktop && item.fileExst && open
? window.open(
combineUrl(
AppServerConfig.proxyURL,
config.homepage,
"/doceditor"
),
"_blank"
)
: null;
if (!item.fileExst && !item.contentLength) {
createFolder(item.parentId, title)
.then((folder) => {
createdFolderId = folder.id;
addActiveItems(null, [folder.id]);
setCreatedItem({ id: createdFolderId, type: "folder" });
})
.then(() => this.completeAction(itemId))
.catch((e) => {
toastr.error(e);
this.completeAction(itemId);
})
.finally(() => {
const folderIds = [+itemId];
createdFolderId && folderIds.push(createdFolderId);
setIsUpdatingRowItem(false);
clearActiveOperations(null, folderIds);
return setIsLoading(false);
});
} else {
if (isMakeFormFromFile) {
fileCopyAs(
fileActionTemplateId,
`${title}.${item.fileExst}`,
item.parentId
)
.then((file) => {
createdFileId = file.id;
addActiveItems([file.id]);
open && openDocEditor(file.id, file.providerKey, tab);
})
.then(() => this.completeAction(itemId))
.catch((err) => {
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);
});
} else if (fromTemplate) {
createFile(
parentId,
`${itemTitle}.${fileExst}`,
undefined,
gallerySelected.id
)
.then((file) => {
createdFileId = file.id;
setCreatedItem({ id: createdFileId, type: "file" });
addActiveItems([file.id]);
return open && openDocEditor(file.id, file.providerKey, tab);
})
.then(() => this.completeAction(itemId))
.catch((e) => {
toastr.error(e);
tab && tab.close();
this.completeAction(itemId);
})
.finally(() => {
const fileIds = [+itemId];
createdFileId && fileIds.push(createdFileId);
setIsUpdatingRowItem(false);
clearActiveOperations(fileIds);
return setIsLoading(false);
});
} else {
createFile(item.parentId, `${title}.${item.fileExst}`)
.then((file) => {
createdFileId = file.id;
setCreatedItem({ id: createdFileId, type: "file" });
addActiveItems([file.id]);
if (isPrivacy) {
return setEncryptionAccess(file).then((encryptedFile) => {
if (!encryptedFile) return Promise.resolve();
toastr.info(t("Translations:EncryptedFileSaving"));
return replaceFileStream(
file.id,
encryptedFile,
true,
false
).then(
() => open && openDocEditor(file.id, file.providerKey, tab)
);
});
}
return open && openDocEditor(file.id, file.providerKey, tab);
})
.then(() => this.completeAction(itemId))
.catch((e) => {
toastr.error(e);
tab && tab.close();
this.completeAction(itemId);
})
.finally(() => {
const fileIds = [+itemId];
createdFileId && fileIds.push(createdFileId);
setIsUpdatingRowItem(false);
clearActiveOperations(fileIds);
return setIsLoading(false);
});
}
}
};
renameTitle = (e) => {
const { t, folderFormValidation } = this.props;
let title = e.target.value;
//const chars = '*+:"<>?|/'; TODO: think how to solve problem with interpolation escape values in i18n translate
if (title.match(folderFormValidation)) {
toastr.warning(t("ContainsSpecCharacter"));
}
title = title.replace(folderFormValidation, "_");
return this.setState({ itemTitle: title });
};
getStatusByDate = (create) => {
const { culture, item, personal } = this.props;
const { created, updated } = item;
@ -413,7 +48,6 @@ export default function withContent(WrappedContent) {
};
render() {
const { itemTitle } = this.state;
const {
element,
isDesktop,
@ -421,23 +55,13 @@ export default function withContent(WrappedContent) {
item,
onFilesClick,
t,
viewAs,
viewer,
isUpdatingRowItem,
passwordEntryProcess,
isEdit,
titleWithoutExt,
} = this.props;
const {
access,
createdBy,
fileExst,
fileStatus,
href,
icon,
id,
isFolder,
} = item;
const { access, createdBy, fileExst, fileStatus, href, icon, id } = item;
const updatedDate = this.getStatusByDate(false);
const createdDate = this.getStatusByDate(true);
@ -462,27 +86,8 @@ export default function withContent(WrappedContent) {
const newItems =
item.new || (fileStatus & FileStatus.IsNew) === FileStatus.IsNew;
const showNew = !!newItems;
const elementIcon = element ? (
element
) : (
<ItemIcon id={id} icon={icon} fileExst={fileExst} />
);
return isEdit ? (
<EditingWrapperComponent
className={"editing-wrapper-component"}
elementIcon={elementIcon}
itemTitle={itemTitle}
itemId={id}
viewAs={viewAs}
renameTitle={this.renameTitle}
onClickUpdateItem={this.onClickUpdateItem}
cancelUpdateItem={this.cancelUpdateItem}
isUpdatingRowItem={isUpdatingRowItem}
passwordEntryProcess={passwordEntryProcess}
isFolder={item.fileExst ? false : true}
/>
) : (
return (
<WrappedContent
titleWithoutExt={titleWithoutExt}
updatedDate={updatedDate}
@ -531,13 +136,6 @@ export default function withContent(WrappedContent) {
const { clearActiveOperations, fileCopyAs } = uploadDataStore;
const { isRecycleBinFolder, isPrivacyFolder } = treeFoldersStore;
const {
extension: fileActionExt,
id: fileActionId,
templateId: fileActionTemplateId,
type: fileActionType,
fromTemplate,
} = filesStore.fileActionStore;
const { replaceFileStream, setEncryptionAccess } = auth;
const {
@ -553,20 +151,14 @@ export default function withContent(WrappedContent) {
setFormCreationInfo,
} = dialogsStore;
const isEdit =
item.id === fileActionId && item.fileExst === fileActionExt;
const titleWithoutExt = getTitleWithoutExst(item, fromTemplate);
const titleWithoutExt = getTitleWithoutExst(item, false);
return {
createFile,
createFolder,
culture,
editCompleteAction,
fileActionExt,
fileActionId,
fileActionTemplateId,
fileActionType,
folderFormValidation,
homepage: config.homepage,
isDesktop: isDesktopClient,
@ -589,9 +181,9 @@ export default function withContent(WrappedContent) {
addActiveItems,
clearActiveOperations,
fileCopyAs,
isEdit,
titleWithoutExt,
fromTemplate,
gallerySelected,
setCreatedItem,
personal,

View File

@ -172,9 +172,7 @@ export default function withFileActions(WrappedFileItem) {
draggable,
allowShareIn,
isPrivacy,
actionType,
actionExtension,
actionId,
sectionWidth,
checked,
dragging,
@ -186,9 +184,6 @@ export default function withFileActions(WrappedFileItem) {
} = this.props;
const { fileExst, access, id } = item;
const isEdit =
actionType !== null && actionId === id && fileExst === actionExtension;
const isDragging = isFolder && access < 2 && !isTrashFolder && !isPrivacy;
let className = isDragging ? " droppable" : "";
@ -209,13 +204,12 @@ export default function withFileActions(WrappedFileItem) {
const showShare =
!isShareable ||
isEdit ||
(isPrivacy && (!isDesktop || !fileExst)) ||
(personal && !canWebEdit && !canViewedDocs)
? false
: true;
const checkedProps = isEdit || id <= 0 ? false : checked;
const checkedProps = id <= 0 ? false : checked;
return (
<WrappedFileItem
@ -235,7 +229,6 @@ export default function withFileActions(WrappedFileItem) {
showShare={showShare}
checkedProps={checkedProps}
dragging={dragging}
isEdit={isEdit}
getContextModel={this.getContextModel}
{...this.props}
/>
@ -277,7 +270,7 @@ export default function withFileActions(WrappedFileItem) {
selection,
setTooltipPosition,
setStartDrag,
fileActionStore,
getFolderInfo,
viewAs,
bufferSelection,
@ -290,14 +283,12 @@ export default function withFileActions(WrappedFileItem) {
} = filesStore;
const { startUpload } = uploadDataStore;
const { type, extension, id } = fileActionStore;
const selectedItem = selection.find(
(x) => x.id === item.id && x.fileExst === item.fileExst
);
const draggable =
!isRecycleBinFolder && selectedItem && selectedItem.id !== id;
const draggable = !isRecycleBinFolder && selectedItem;
const isFolder = selectedItem ? false : !item.isFolder ? false : true;
const canWebEdit = settingsStore.canWebEdit(item.fileExst);
@ -338,9 +329,7 @@ export default function withFileActions(WrappedFileItem) {
setStartDrag,
isFolder,
allowShareIn: filesStore.canShare,
actionType: type,
actionExtension: extension,
actionId: id,
checked: !!selectedItem,
//parentFolder: selectedFolderStore.parentId,
setParentId: selectedFolderStore.setParentId,

View File

@ -2,6 +2,7 @@ import React, { useEffect } from "react";
import { useHotkeys } from "react-hotkeys-hook";
import { observer, inject } from "mobx-react";
import { FileAction } from "@appserver/common/constants";
import { Events } from "../helpers/constants";
import toastr from "studio/toastr";
const withHotkeys = (Component) => {
@ -12,7 +13,6 @@ const withHotkeys = (Component) => {
setSelected,
viewAs,
setViewAs,
setAction,
setHotkeyPanelVisible,
confirmDelete,
setDeleteDialogVisible,
@ -65,6 +65,20 @@ const withHotkeys = (Component) => {
const folderWithNoAction =
isFavoritesFolder || isRecentFolder || isTrashFolder;
const onCreate = (extension) => {
if (folderWithNoAction) return;
const event = new Event(Events.CREATE);
const payload = {
extension: extension,
id: -1,
};
event.payload = payload;
window.dispatchEvent(event);
};
useEffect(() => {
window.addEventListener("keydown", onKeyDown);
@ -163,48 +177,28 @@ const withHotkeys = (Component) => {
);
//Crete document
useHotkeys(
"Shift+d",
() => {
if (folderWithNoAction) return;
setAction({ type: FileAction.Create, extension: "docx", id: -1 });
},
{ ...hotkeysFilter, ...{ keyup: true } }
);
useHotkeys("Shift+d", () => onCreate("docx"), {
...hotkeysFilter,
...{ keyup: true },
});
//Crete spreadsheet
useHotkeys(
"Shift+s",
() => {
if (folderWithNoAction) return;
setAction({ type: FileAction.Create, extension: "xlsx", id: -1 });
},
{ ...hotkeysFilter, ...{ keyup: true } }
);
useHotkeys("Shift+s", () => onCreate("xlsx"), {
...hotkeysFilter,
...{ keyup: true },
});
//Crete presentation
useHotkeys(
"Shift+p",
() => {
if (folderWithNoAction) return;
setAction({ type: FileAction.Create, extension: "pptx", id: -1 });
},
{ ...hotkeysFilter, ...{ keyup: true } }
);
useHotkeys("Shift+p", () => onCreate("pptx"), {
...hotkeysFilter,
...{ keyup: true },
});
//Crete form template
useHotkeys(
"Shift+o",
() => {
if (folderWithNoAction) return;
setAction({ type: FileAction.Create, extension: "docxf", id: -1 });
},
{ ...hotkeysFilter, ...{ keyup: true } }
);
useHotkeys("Shift+o", () => onCreate("docxf"), {
...hotkeysFilter,
...{ keyup: true },
});
//Crete form template from file
useHotkeys(
@ -218,14 +212,10 @@ const withHotkeys = (Component) => {
);
//Crete folder
useHotkeys(
"Shift+f",
() => {
if (folderWithNoAction) return;
setAction({ type: FileAction.Create, id: -1 });
},
{ ...hotkeysFilter, ...{ keyup: true } }
);
useHotkeys("Shift+f", () => onCreate(null), {
...hotkeysFilter,
...{ keyup: true },
});
//Delete selection
useHotkeys(
@ -329,7 +319,6 @@ const withHotkeys = (Component) => {
enabledHotkeys,
selection,
} = filesStore;
const { setAction } = fileActionStore;
const {
selectFile,
@ -376,7 +365,6 @@ const withHotkeys = (Component) => {
setSelected,
viewAs,
setViewAs,
setAction,
setHotkeyPanelVisible,
setDeleteDialogVisible,

View File

@ -67,8 +67,6 @@ export default function withQuickButtons(WrappedComponent) {
isTrashFolder,
isAdmin,
showShare,
fileActionExt,
fileActionId,
sectionWidth,
viewAs,
} = this.props;
@ -79,9 +77,7 @@ export default function withQuickButtons(WrappedComponent) {
access === ShareAccessRights.FullAccess ||
access === ShareAccessRights.None; // TODO: fix access type for owner (now - None)
const isEdit = id === fileActionId && fileExst === fileActionExt;
const quickButtonsComponent = !isEdit ? (
const quickButtonsComponent = (
<QuickButtons
t={t}
theme={theme}
@ -98,7 +94,7 @@ export default function withQuickButtons(WrappedComponent) {
onClickFavorite={this.onClickFavorite}
onClickShare={this.onClickShare}
/>
) : null;
);
return (
<WrappedComponent
@ -125,10 +121,6 @@ export default function withQuickButtons(WrappedComponent) {
onSelectItem,
} = filesActionsStore;
const {
extension: fileActionExt,
id: fileActionId,
} = filesStore.fileActionStore;
const { setSharingPanelVisible } = dialogsStore;
const { canWebEdit } = settingsStore;
return {
@ -137,8 +129,6 @@ export default function withQuickButtons(WrappedComponent) {
isTrashFolder: isRecycleBinFolder,
lockFileAction,
setFavoriteAction,
fileActionExt,
fileActionId,
onSelectItem,
setSharingPanelVisible,
canWebEdit,

View File

@ -14,6 +14,7 @@ import MobileView from "./MobileView";
import { combineUrl } from "@appserver/common/utils";
import config from "../../../../package.json";
import withLoader from "../../../HOCs/withLoader";
import { Events } from "../../../helpers/constants";
const ArticleMainButtonContent = (props) => {
const {
@ -47,11 +48,16 @@ const ArticleMainButtonContent = (props) => {
const onCreate = React.useCallback(
(e) => {
const format = e.action || null;
setAction({
type: FileAction.Create,
const event = new Event(Events.CREATE);
const payload = {
extension: format,
id: -1,
});
};
event.payload = payload;
window.dispatchEvent(event);
},
[setAction]
);
@ -286,13 +292,7 @@ export default inject(
treeFoldersStore,
selectedFolderStore,
}) => {
const {
isLoaded,
firstLoad,
isLoading,
fileActionStore,
canCreate,
} = filesStore;
const { isLoaded, firstLoad, isLoading, canCreate } = filesStore;
const {
isPrivacyFolder,
isFavoritesFolder,
@ -321,7 +321,6 @@ export default inject(
isShareFolder,
canCreate,
setAction: fileActionStore.setAction,
startUpload,
setSelectFileDialogVisible,

View File

@ -5,6 +5,7 @@ import EmptyFilterContainer from "./EmptyFilterContainer";
import EmptyFolderContainer from "./EmptyFolderContainer";
import { FileAction } from "@appserver/common/constants";
import { isMobile } from "react-device-detect";
import { Events } from "../../helpers/constants";
const linkStyles = {
isHovered: true,
@ -16,7 +17,6 @@ const linkStyles = {
const EmptyContainer = ({
isFiltered,
setAction,
isPrivacyFolder,
parentId,
isEncryptionSupport,
@ -26,11 +26,16 @@ const EmptyContainer = ({
const onCreate = (e) => {
const format = e.currentTarget.dataset.format || null;
setAction({
type: FileAction.Create,
const event = new Event(Events.CREATE);
const payload = {
extension: format,
id: -1,
});
};
event.payload = payload;
window.dispatchEvent(event);
};
return isFiltered ? (
@ -59,7 +64,6 @@ export default inject(
isEncryptionSupport: auth.settingsStore.isEncryptionSupport,
theme: auth.settingsStore.theme,
isFiltered,
setAction: filesStore.fileActionStore.setAction,
isPrivacyFolder,
parentId: selectedFolderStore.parentId,
};

View File

@ -0,0 +1,312 @@
import React from "react";
import { inject, observer } from "mobx-react";
import { useTranslation } from "react-i18next";
import toastr from "studio/toastr";
import { AppServerConfig } from "@appserver/common/constants";
import { combineUrl } from "@appserver/common/utils";
import config from "../../../package.json";
import { getTitleWithoutExst } from "../../helpers/files-helpers";
import { getDefaultFileName } from "../../helpers/utils";
import Dialog from "./sub-components/Dialog";
const CreateEvent = ({
id,
type,
extension,
title,
templateId,
fromTemplate,
onClose,
setIsLoading,
createFile,
createFolder,
addActiveItems,
openDocEditor,
setIsUpdatingRowItem,
gallerySelected,
setCreatedItem,
parentId,
isPrivacy,
isDesktop,
editCompleteAction,
clearActiveOperations,
fileCopyAs,
setConvertPasswordDialogVisible,
setFormCreationInfo,
replaceFileStream,
setEncryptionAccess,
}) => {
const [visible, setVisible] = React.useState(false);
const [headerTitle, setHeaderTitle] = React.useState(null);
const [startValue, setStartValue] = React.useState("");
const { t } = useTranslation(["Translations", "Common"]);
React.useEffect(() => {
const defaultName = getDefaultFileName(extension);
if (title) {
const item = { fileExst: extension, title: title };
setStartValue(getTitleWithoutExst(item, fromTemplate));
} else {
setStartValue(defaultName);
}
setHeaderTitle(defaultName);
setVisible(true);
}, [extension, title, fromTemplate]);
const onSave = (e, value, open = true) => {
let item;
let createdFileId, createdFolderId;
const isMakeFormFromFile = templateId ? true : false;
setIsLoading(true);
const newValue = value;
if (value.trim() === "") {
newValue =
templateId === null
? getDefaultFileName(extension)
: getTitleWithoutExst({ fileExst: extension });
setStartValue(newValue);
}
let tab =
!isDesktop && extension && open
? window.open(
combineUrl(AppServerConfig.proxyURL, config.homepage, "/doceditor"),
"_blank"
)
: null;
if (!extension) {
createFolder(parentId, newValue)
.then((folder) => {
item = folder;
createdFolderId = folder.id;
addActiveItems(null, [folder.id]);
setCreatedItem({ id: createdFolderId, type: "folder" });
})
.then(() => editCompleteAction(id, item, false, type))
.catch((e) => toastr.error(e))
.finally(() => {
const folderIds = [+id];
createdFolderId && folderIds.push(createdFolderId);
clearActiveOperations(null, folderIds);
onClose();
return setIsLoading(false);
});
} else {
if (isMakeFormFromFile) {
fileCopyAs(templateId, `${newValue}.${extension}`, parentId)
.then((file) => {
item = file;
createdFileId = file.id;
addActiveItems([file.id]);
open && openDocEditor(file.id, file.providerKey, tab);
})
.then(() => editCompleteAction(id, item, false, type))
.catch((err) => {
if (err.indexOf("password") == -1) {
toastr.error(err, t("Common:Warning"));
return;
}
toastr.error(t("Translations:FileProtected"), t("Common:Warning"));
setVisible(false);
setFormCreationInfo({
newTitle: `${newValue}.${extension}`,
fromExst: ".docx",
toExst: extension,
open,
actionId: id,
fileInfo: {
id: templateId,
folderId: parentId,
fileExst: extension,
},
});
setConvertPasswordDialogVisible(true);
open && openDocEditor(null, null, tab);
})
.finally(() => {
const fileIds = [+id];
createdFileId && fileIds.push(createdFileId);
clearActiveOperations(fileIds);
onClose();
return setIsLoading(false);
});
} else if (fromTemplate) {
createFile(
parentId,
`${newValue}.${extension}`,
undefined,
gallerySelected.id
)
.then((file) => {
item = file;
createdFileId = file.id;
setCreatedItem({ id: createdFileId, type: "file" });
addActiveItems([file.id]);
return open && openDocEditor(file.id, file.providerKey, tab);
})
.then(() => editCompleteAction(id, item, false, type))
.catch((e) => toastr.error(e))
.finally(() => {
const fileIds = [+id];
createdFileId && fileIds.push(createdFileId);
clearActiveOperations(fileIds);
onClose();
return setIsLoading(false);
});
} else {
createFile(parentId, `${newValue}.${extension}`)
.then((file) => {
createdFileId = file.id;
item = file;
setCreatedItem({ id: createdFileId, type: "file" });
addActiveItems([file.id]);
if (isPrivacy) {
return setEncryptionAccess(file).then((encryptedFile) => {
if (!encryptedFile) return Promise.resolve();
toastr.info(t("Translations:EncryptedFileSaving"));
return replaceFileStream(
file.id,
encryptedFile,
true,
false
).then(
() => open && openDocEditor(file.id, file.providerKey, tab)
);
});
}
return open && openDocEditor(file.id, file.providerKey, tab);
})
.then(() => editCompleteAction(id, item, false, type))
.catch((e) => toastr.error(e))
.finally(() => {
const fileIds = [+id];
createdFileId && fileIds.push(createdFileId);
clearActiveOperations(fileIds);
onClose();
return setIsLoading(false);
});
}
}
};
const onCancel = React.useCallback(
(e) => {
onClose && onClose();
},
[onClose]
);
return (
<Dialog
t={t}
visible={visible}
title={headerTitle}
startValue={startValue}
onSave={onSave}
onCancel={onCancel}
onClose={onClose}
/>
);
};
export default inject(
({
auth,
filesStore,
filesActionsStore,
selectedFolderStore,
treeFoldersStore,
uploadDataStore,
dialogsStore,
}) => {
const {
setIsLoading,
createFile,
createFolder,
addActiveItems,
openDocEditor,
setIsUpdatingRowItem,
gallerySelected,
setCreatedItem,
} = filesStore;
const { editCompleteAction } = filesActionsStore;
const { clearActiveOperations, fileCopyAs } = uploadDataStore;
const { isRecycleBinFolder, isPrivacyFolder } = treeFoldersStore;
const { id: parentId } = selectedFolderStore;
const { replaceFileStream, setEncryptionAccess } = auth;
const { isDesktopClient } = auth.settingsStore;
const {
setConvertPasswordDialogVisible,
setFormCreationInfo,
} = dialogsStore;
return {
setIsLoading,
createFile,
createFolder,
addActiveItems,
openDocEditor,
setIsUpdatingRowItem,
gallerySelected,
setCreatedItem,
parentId,
isDesktop: isDesktopClient,
isPrivacy: isPrivacyFolder,
isTrashFolder: isRecycleBinFolder,
editCompleteAction,
clearActiveOperations,
fileCopyAs,
setConvertPasswordDialogVisible,
setFormCreationInfo,
replaceFileStream,
setEncryptionAccess,
};
}
)(observer(CreateEvent));

View File

@ -0,0 +1,142 @@
import React from "react";
import { inject, observer } from "mobx-react";
import { useTranslation } from "react-i18next";
import toastr from "studio/toastr";
import { getTitleWithoutExst } from "../../helpers/files-helpers";
import Dialog from "./sub-components/Dialog";
const RenameEvent = ({
type,
item,
onClose,
setIsLoading,
addActiveItems,
updateFile,
renameFolder,
editCompleteAction,
clearActiveOperations,
}) => {
const [visible, setVisible] = React.useState(false);
const [startValue, setStartValue] = React.useState("");
const { t } = useTranslation(["Home"]);
React.useEffect(() => {
setStartValue(getTitleWithoutExst(item, false));
setVisible(true);
}, [item]);
const onUpdate = React.useCallback((e, value) => {
const originalTitle = getTitleWithoutExst(item);
setIsLoading(true);
let timerId;
const isSameTitle =
originalTitle.trim() === value.trim() || value.trim() === "";
const isFile = item.fileExst || item.contentLength;
if (isSameTitle) {
setStartValue(originalTitle);
return editCompleteAction(item.id, item, isSameTitle, type);
} else {
timerId = setTimeout(() => {
isFile ? addActiveItems([item.id]) : addActiveItems(null, [item.id]);
}, 500);
}
isFile
? updateFile(item.id, value)
.then(() => editCompleteAction(item.id, item, false, type))
.then(() =>
toastr.success(
t("FileRenamed", {
oldTitle: item.title,
newTitle: value + item.fileExst,
})
)
)
.catch((err) => {
toastr.error(err);
editCompleteAction(item.id, item, false, type);
})
.finally(() => {
clearTimeout(timerId);
timerId = null;
clearActiveOperations([item.id]);
setIsLoading(false);
onClose();
})
: renameFolder(item.id, value)
.then(() => editCompleteAction(item.id, item, false, type))
.then(() =>
toastr.success(
t("FolderRenamed", {
folderTitle: item.title,
newFoldedTitle: value,
})
)
)
.catch((err) => {
toastr.error(err);
editCompleteAction(item.id, item, false, type);
})
.finally(() => {
clearTimeout(timerId);
timerId = null;
clearActiveOperations(null, [item.id]);
setIsLoading(false);
onClose();
});
}, []);
const onCancel = React.useCallback(
(e) => {
onClose && onClose();
},
[onClose]
);
return (
<Dialog
t={t}
visible={visible}
title={t("Home: Rename")}
startValue={startValue}
onSave={onUpdate}
onCancel={onCancel}
onClose={onClose}
/>
);
};
export default inject(({ filesStore, filesActionsStore, uploadDataStore }) => {
const { setIsLoading, addActiveItems, updateFile, renameFolder } = filesStore;
const { editCompleteAction } = filesActionsStore;
const { clearActiveOperations } = uploadDataStore;
return {
setIsLoading,
addActiveItems,
updateFile,
renameFolder,
editCompleteAction,
clearActiveOperations,
};
})(observer(RenameEvent));

View File

@ -0,0 +1,93 @@
import React from "react";
import { FileAction } from "@appserver/common/constants";
import { Events } from "../../helpers/constants";
import CreateEvent from "./CreateEvent";
import RenameEvent from "./RenameEvent";
const GlobalEvents = () => {
const [createDialogProps, setCreateDialogProps] = React.useState({
visible: false,
id: null,
type: null,
extension: null,
title: "",
templateId: null,
fromTemplate: null,
onClose: null,
});
const [renameDialogProps, setRenameDialogProps] = React.useState({
visible: false,
item: null,
onClose: null,
});
const onCreate = React.useCallback((e) => {
const { payload } = e;
const visible = payload.id ? true : false;
setCreateDialogProps({
visible: visible,
id: payload.id,
type: FileAction.Create,
extension: payload.extension,
title: payload.title || null,
templateId: payload.templateId || null,
fromTemplate: payload.fromTemplate || null,
onClose: () => {
setCreateDialogProps({
visible: false,
id: null,
type: null,
extension: null,
title: "",
templateId: null,
fromTemplate: null,
onClose: null,
});
},
});
}, []);
const onRename = React.useCallback((e) => {
const visible = e.item ? true : false;
setRenameDialogProps({
visible: visible,
type: FileAction.Rename,
item: e.item,
onClose: () => {
setRenameDialogProps({
visible: false,
typ: null,
item: null,
});
},
});
}, []);
React.useEffect(() => {
window.addEventListener(Events.CREATE, onCreate);
window.addEventListener(Events.RENAME, onRename);
return () => {
window.removeEventListener(Events.CREATE, onCreate);
window.removeEventListener(Events.RENAME, onRename);
};
}, [onRename, onCreate]);
return [
createDialogProps.visible && (
<CreateEvent key={Events.CREATE} {...createDialogProps} />
),
renameDialogProps.visible && (
<RenameEvent key={Events.RENAME} {...renameDialogProps} />
),
];
};
export default React.memo(GlobalEvents);

View File

@ -0,0 +1,100 @@
import React from "react";
import { inject, observer } from "mobx-react";
import toastr from "@appserver/components/toast/toastr";
import ModalDialog from "@appserver/components/modal-dialog";
import TextInput from "@appserver/components/text-input";
import Button from "@appserver/components/button";
const Dialog = ({
t,
title,
startValue,
visible,
folderFormValidation,
onSave,
onCancel,
onClose,
}) => {
const [value, setValue] = React.useState("");
const [isDisabled, setIsDisabled] = React.useState(false);
React.useEffect(() => {
if (startValue) setValue(startValue);
}, [startValue]);
const onChange = React.useCallback((e) => {
let newValue = e.target.value;
if (newValue.match(folderFormValidation)) {
toastr.warning(t("ContainsSpecCharacter"));
}
newValue = newValue.replace(folderFormValidation, "_");
setValue(newValue);
}, []);
const onFocus = React.useCallback((e) => {
e.target.select();
}, []);
const onSaveAction = React.useCallback(
(e) => {
setIsDisabled(true);
onSave && onSave(e, value);
},
[onSave, value]
);
const onCancelAction = React.useCallback((e) => {
onCancel && onCancel(e);
}, []);
return (
<ModalDialog
visible={visible}
displayType={"modal"}
scale={true}
onClose={onClose}
>
<ModalDialog.Header>{title}</ModalDialog.Header>
<ModalDialog.Body>
<TextInput
name={"create"}
type={"text"}
scale={true}
value={value}
isAutoFocussed={true}
tabIndex={1}
onChange={onChange}
onFocus={onFocus}
isDisabled={isDisabled}
/>
</ModalDialog.Body>
<ModalDialog.Footer>
<Button
key="SendBtn"
label={t("Common:SaveButton")}
size="normal"
scale
primary
onClick={onSaveAction}
/>
<Button
key="CloseBtn"
label={t("Common:CancelButton")}
size="normal"
scale
onClick={onCancelAction}
/>
</ModalDialog.Footer>
</ModalDialog>
);
};
export default inject(({ auth }) => {
const { folderFormValidation } = auth.settingsStore;
return { folderFormValidation };
})(observer(Dialog));

View File

@ -23,35 +23,42 @@ const ItemIcon = ({
fileExst,
isPrivacy,
viewAs,
actionType,
actionExtension,
actionId,
// actionType,
// actionExtension,
// actionId,
}) => {
const isEdit =
(actionType !== null && actionId === id && fileExst === actionExtension) ||
id <= 0;
// const isEdit =
// (actionType !== null && actionId === id && fileExst === actionExtension) ||
// id <= 0;
// return (
// <>
// <StyledIcon
// className={`react-svg-icon${isEdit ? " is-edit" : ""}`}
// src={icon}
// />
// {isPrivacy && fileExst && (
// <EncryptedFileIcon isEdit={isEdit && viewAs !== "tile"} />
// )}
// </>
// );
return (
<>
<StyledIcon
className={`react-svg-icon${isEdit ? " is-edit" : ""}`}
src={icon}
/>
{isPrivacy && fileExst && (
<EncryptedFileIcon isEdit={isEdit && viewAs !== "tile"} />
)}
<StyledIcon className={`react-svg-icon`} src={icon} />
{isPrivacy && fileExst && <EncryptedFileIcon isEdit={false} />}
</>
);
};
export default inject(({ filesStore, treeFoldersStore }) => {
const { type, extension, id } = filesStore.fileActionStore;
// const { type, extension, id } = filesStore.fileActionStore;
return {
viewAs: filesStore.viewAs,
isPrivacy: treeFoldersStore.isPrivacyFolder,
actionType: type,
actionExtension: extension,
actionId: id,
// actionType: type,
// actionExtension: extension,
// actionId: id,
};
})(observer(ItemIcon));

View File

@ -77,7 +77,6 @@ const FilesListBody = ({
const loadMoreItems = useCallback(() => {
if (folderId && page == 0 && isNextPageLoading) {
loadNextPage && loadNextPage();
return;
}
@ -178,7 +177,7 @@ const FilesListBody = ({
{({ onItemsRendered, ref }) => (
<List
theme={theme}
height={height}
height={384}
itemCount={itemCount}
itemSize={48}
onItemsRendered={onItemsRendered}

View File

@ -56,7 +56,6 @@ const SelectionPanelBody = ({
displayType="modal"
isLoading={isLoading}
withFooterBorder
autoMaxHeight
autoMaxWidth
>
<ModalDialog.Header theme={theme} className={"select-panel-modal-header"}>

View File

@ -19,6 +19,10 @@ const commonStyles = css`
`;
const StyledModalDialog = styled(ModalDialog)`
#modal-dialog {
max-height: 560px;
}
.select-panel-modal-header {
margin-bottom: 0;
}
@ -38,7 +42,7 @@ const StyledModalDialog = styled(ModalDialog)`
const StyledBody = styled.div`
.selection-panel_body {
height: 495px;
height: 434px;
display: grid;
grid-template-columns: 245px 1fr;
grid-template-areas: "tree files" "footer footer";
@ -53,7 +57,7 @@ const StyledBody = styled.div`
grid-template-rows: max-content auto;
}
.selection-panel_files-list-body {
height: 100%;
height: 384px;
}
.selection-panel_tree-body {
grid-area: tree;
@ -67,7 +71,9 @@ const StyledBody = styled.div`
padding: 12px 20px 14px 0px;
}
.selection-panel_tree-folder {
margin-left: -12px;
height: 387px;
max-height: 384px;
margin-left: -17px;
}
.span.rc-tree-switcher {

View File

@ -10,3 +10,5 @@ export const thumbnailStatuses = {
};
export const ADS_TIMEOUT = 300000; // 5 min
export const Events = Object.freeze({ CREATE: "create", RENAME: "rename" });

View File

@ -20,7 +20,6 @@ const SectionBodyContent = (props) => {
const {
t,
tReady,
fileActionId,
isEmptyFilesList,
folderId,
dragging,
@ -243,7 +242,7 @@ const SectionBodyContent = (props) => {
return (
<Consumer>
{(context) =>
(!fileActionId && isEmptyFilesList) || null ? (
isEmptyFilesList || null ? (
<>
<EmptyContainer />
</>
@ -277,7 +276,6 @@ export default inject(
uploadDataStore,
}) => {
const {
fileActionStore,
isEmptyFilesList,
dragging,
setDragging,
@ -299,7 +297,7 @@ export default inject(
dragging,
startDrag,
setStartDrag,
fileActionId: fileActionStore.id,
isEmptyFilesList,
setDragging,
folderId: selectedFolderStore.id,

View File

@ -13,6 +13,7 @@ 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 { Events } from "../../../../helpers/constants";
import config from "../../../../../package.json";
import { combineUrl } from "@appserver/common/utils";
@ -49,11 +50,16 @@ class SectionHeaderContent extends React.Component {
}
onCreate = (format) => {
this.props.setAction({
type: FileAction.Create,
const event = new Event(Events.CREATE);
const payload = {
extension: format,
id: -1,
});
};
event.payload = payload;
window.dispatchEvent(event);
};
createDocument = () => this.onCreate("docx");
@ -445,7 +451,7 @@ export default inject(
const {
setSelected,
setSelection,
fileActionStore,
canCreate,
isHeaderVisible,
isHeaderIndeterminate,
@ -462,7 +468,7 @@ export default inject(
activeFiles,
activeFolders,
} = filesStore;
const { setAction } = fileActionStore;
const {
setSharingPanelVisible,
setMoveToPanelVisible,
@ -509,7 +515,7 @@ export default inject(
setSelected,
setSelection,
setAction,
setSharingPanelVisible,
setMoveToPanelVisible,
setCopyPanelVisible,

View File

@ -32,7 +32,7 @@ import DragTooltip from "../../components/DragTooltip";
import { observer, inject } from "mobx-react";
import config from "../../../package.json";
import { Consumer } from "@appserver/components/utils/context";
import { FileAction } from "@appserver/common/constants";
import { Events } from "../../helpers/constants";
class PureHome extends React.Component {
componentDidMount() {
@ -48,7 +48,6 @@ class PureHome extends React.Component {
isMediaOrImage,
getFileInfo,
gallerySelected,
setAction,
setIsUpdatingRowItem,
} = this.props;
@ -169,13 +168,19 @@ class PureHome extends React.Component {
.then(() => {
if (gallerySelected) {
setIsUpdatingRowItem(false);
setAction({
type: FileAction.Create,
const event = new Event(Events.CREATE);
const payload = {
extension: "docxf",
id: -1,
fromTemplate: true,
title: gallerySelected.attributes.name_form,
id: -1,
});
};
event.payload = payload;
window.dispatchEvent(event);
}
})
.finally(() => {
@ -290,7 +295,7 @@ class PureHome extends React.Component {
//console.log("Home render");
const {
viewAs,
fileActionId,
firstLoad,
isHeaderVisible,
isPrivacyFolder,
@ -337,9 +342,7 @@ class PureHome extends React.Component {
clearUploadedFilesHistory={clearUploadedFilesHistory}
viewAs={viewAs}
hideAside={
!!fileActionId ||
primaryProgressDataVisible ||
secondaryProgressDataStoreVisible //TODO: use hideArticle action
primaryProgressDataVisible || secondaryProgressDataStoreVisible //TODO: use hideArticle action
}
isLoaded={!firstLoad}
isHeaderVisible={isHeaderVisible}
@ -412,7 +415,6 @@ export default inject(
firstLoad,
setFirstLoad,
fetchFiles,
fileActionStore,
selection,
setSelections,
dragging,
@ -425,7 +427,6 @@ export default inject(
setIsUpdatingRowItem,
} = filesStore;
const { id, setAction } = fileActionStore;
const {
isRecycleBinFolder,
isPrivacyFolder,
@ -478,7 +479,6 @@ export default inject(
homepage: config.homepage,
firstLoad,
dragging,
fileActionId: id,
viewAs,
uploaded,
converted,
@ -527,7 +527,6 @@ export default inject(
isMediaOrImage: settingsStore.isMediaOrImage,
getFileInfo,
gallerySelected,
setAction,
setIsUpdatingRowItem,
};
}

View File

@ -10,6 +10,7 @@ import {
isMobile as isMobileUtils,
isTablet as isTabletUtils,
} from "@appserver/components/utils/device";
import { Events } from "../helpers/constants";
class ContextOptionsStore {
authStore;
@ -246,12 +247,11 @@ class ContextOptionsStore {
};
onClickRename = (item) => {
const { id, fileExst } = item;
this.filesStore.fileActionStore.setAction({
type: FileAction.Rename,
extension: fileExst,
id,
});
const event = new Event(Events.RENAME);
event.item = item;
window.dispatchEvent(event);
};
onChangeThirdPartyInfo = (providerKey) => {
@ -793,13 +793,11 @@ class ContextOptionsStore {
getModel = (item, t) => {
const { selection } = this.filesStore;
const { type, id, extension } = this.filesStore.fileActionStore;
const { fileExst, contextOptions } = item;
const isEdit = !!type && id === item.id && fileExst === extension;
const contextOptionsProps =
!isEdit && contextOptions && contextOptions.length > 0
contextOptions && contextOptions.length > 0
? selection.length > 1
? this.getGroupContextOptions(t)
: this.getFilesContextOptions(item, t)

View File

@ -1,6 +1,7 @@
import { getNewFiles } from "@appserver/common/api/files";
import { FileAction } from "@appserver/common/constants";
import { makeAutoObservable } from "mobx";
import { Events } from "../helpers/constants";
class DialogsStore {
authStore;
@ -212,18 +213,21 @@ class DialogsStore {
};
createMasterForm = async (fileInfo) => {
const { setAction } = this.filesStore.fileActionStore;
let newTitle = fileInfo.title;
newTitle = newTitle.substring(0, newTitle.lastIndexOf("."));
setAction({
type: FileAction.Create,
const event = new Event(Events.CREATE);
const payload = {
extension: "docxf",
id: -1,
title: `${newTitle}.docxf`,
templateId: fileInfo.id,
});
};
event.payload = payload;
window.dispatchEvent(event);
};
get someDialogIsOpen() {

View File

@ -1,27 +0,0 @@
import { makeAutoObservable } from "mobx";
class FileActionStore {
id = null;
type = null;
extension = null;
title = "";
templateId = null;
fromTemplate = null;
constructor() {
makeAutoObservable(this);
}
setAction = (fileAction) => {
if (fileAction.fromTemplate === undefined && this.fromTemplate) return;
const fileActionItems = Object.keys(fileAction);
for (let key of fileActionItems) {
if (key in this) {
this[key] = fileAction[key];
}
}
};
}
export default new FileActionStore();

View File

@ -20,7 +20,7 @@ import {
import { makeAutoObservable } from "mobx";
import toastr from "studio/toastr";
import { TIMEOUT } from "../helpers/constants";
import { Events, TIMEOUT } from "../helpers/constants";
import { loopTreeFolders, checkProtocol } from "../helpers/files-helpers";
import { combineUrl } from "@appserver/common/utils";
import { AppServerConfig } from "@appserver/common/constants";
@ -453,16 +453,16 @@ class FilesActionStore {
return this.downloadFiles(fileIds, folderIds, label);
};
editCompleteAction = async (id, selectedItem, isCancelled = false) => {
editCompleteAction = async (id, selectedItem, isCancelled = false, type) => {
const {
filter,
folders,
files,
fileActionStore,
fetchFiles,
setIsLoading,
} = this.filesStore;
const { type, setAction } = fileActionStore;
const { treeFolders, setTreeFolders } = this.treeFoldersStore;
const items = [...folders, ...files];
@ -480,14 +480,7 @@ class FilesActionStore {
setTreeFolders(treeFolders);
}
}
setAction({
type: null,
id: null,
extension: null,
title: "",
templateId: null,
fromTemplate: null,
});
setIsLoading(false);
type === FileAction.Rename &&
this.onSelectItem(

View File

@ -26,7 +26,7 @@ class FilesStore {
authStore;
settingsStore;
userStore;
fileActionStore;
selectedFolderStore;
treeFoldersStore;
filesSettingsStore;
@ -78,7 +78,7 @@ class FilesStore {
authStore,
settingsStore,
userStore,
fileActionStore,
selectedFolderStore,
treeFoldersStore,
filesSettingsStore
@ -90,7 +90,7 @@ class FilesStore {
this.authStore = authStore;
this.settingsStore = settingsStore;
this.userStore = userStore;
this.fileActionStore = fileActionStore;
this.selectedFolderStore = selectedFolderStore;
this.treeFoldersStore = treeFoldersStore;
this.filesSettingsStore = filesSettingsStore;
@ -654,7 +654,6 @@ class FilesStore {
});
if (clearFilter) {
this.fileActionStore.setAction({ type: null });
if (clearSelection) {
this.setSelected("close");
}
@ -1669,10 +1668,6 @@ class FilesStore {
};
});
if (this.fileActionStore.type === FileAction.Create) {
this.onCreateAddTempItem(newItem);
}
return newItem;
}

View File

@ -1,5 +1,4 @@
import FilesStore from "./FilesStore";
import fileActionStore from "./FileActionStore";
import SelectedFolderStore from "./SelectedFolderStore";
import TreeFoldersStore from "./TreeFoldersStore";
import thirdPartyStore from "./ThirdPartyStore";
@ -26,7 +25,6 @@ const filesStore = new FilesStore(
store.auth,
store.auth.settingsStore,
store.auth.userStore,
fileActionStore,
selectedFolderStore,
treeFoldersStore,
settingsStore,

View File

@ -49,7 +49,7 @@ internal class FolderDao : AbstractDao, IFolderDao<int>
private readonly IMapper _mapper;
private static readonly List<FilterType> _constraintFolderFilters =
new List<FilterType> { FilterType.FilesOnly, FilterType.ByExtension, FilterType.DocumentsOnly, FilterType.ImagesOnly,
new List<FilterType> { FilterType.FilesOnly, FilterType.ByExtension, FilterType.DocumentsOnly, FilterType.ImagesOnly,
FilterType.PresentationsOnly, FilterType.SpreadsheetsOnly, FilterType.ArchiveOnly, FilterType.MediaOnly };
public FolderDao(
@ -350,14 +350,14 @@ internal class FolderDao : AbstractDao, IFolderDao<int>
folderId = await InternalSaveFolderToDbAsync(folder);
await tx.CommitAsync().ConfigureAwait(false);
await tx.CommitAsync().ConfigureAwait(false);
});
}
else
{
folderId = await InternalSaveFolderToDbAsync(folder);
}
//FactoryIndexer.IndexAsync(FoldersWrapper.GetFolderWrapper(ServiceProvider, folder));
return folderId;
}
@ -1365,7 +1365,7 @@ internal class FolderDao : AbstractDao, IFolderDao<int>
private IQueryable<DbFolder> SetFilterByTypes(IQueryable<DbFolder> q, IEnumerable<FilterType> filterTypes)
{
if (filterTypes.Any() && !filterTypes.Contains(FilterType.None))
if (filterTypes.Any() && !filterTypes.Contains(FilterType.None) && !filterTypes.Contains(FilterType.FoldersOnly))
{
var filter = filterTypes.Select(f => f switch
{

View File

@ -14,6 +14,19 @@ BEGIN
ALTER TABLE files_thirdparty_account ADD folder_id TEXT NULL COLLATE UTF8_GENERAL_CI;
END IF;
IF NOT EXISTS(SELECT * FROM information_schema.`TABLES` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'hosting_instance_registration') THEN
CREATE TABLE hosting_instance_registration (
instance_registration_id VARCHAR(255) NOT NULL COLLATE 'utf8_general_ci',
last_updated DATETIME NULL DEFAULT NULL,
worker_type_name VARCHAR(255) NOT NULL COLLATE 'utf8_general_ci',
is_active TINYINT(3) NOT NULL,
PRIMARY KEY (instance_registration_id) USING BTREE,
INDEX worker_type_name (worker_type_name) USING BTREE
)
COLLATE='utf8mb4_0900_ai_ci'
ENGINE=InnoDB;
END IF;
END DLM00
CALL docspace_upgrade1() DLM00

View File

@ -60,7 +60,15 @@ public class IpRestrictionsController : BaseSettingsController
{
_permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
return _iPRestrictionsService.Save(inDto.Ips, Tenant.Id);
}
}
[HttpGet("iprestrictions/settings")]
public IPRestrictionsSettings ReadIpRestrictionsSettings()
{
_permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
return _settingsManager.Load<IPRestrictionsSettings>();
}
[HttpPut("iprestrictions/settings")]
public IPRestrictionsSettings UpdateIpRestrictionsSettings(IpRestrictionsRequestsDto inDto)

View File

@ -219,6 +219,7 @@ public class SettingsController : BaseSettingsController
if (inDto.Type == TenantTrustedDomainsType.Custom)
{
Tenant.TrustedDomainsRaw = "";
Tenant.TrustedDomains.Clear();
foreach (var d in inDto.Domains.Select(domain => (domain ?? "").Trim().ToLower()))
{

View File

@ -1,5 +0,0 @@
{
"projects": {
"default": "appserver-c011a"
}
}

View File

@ -1,66 +0,0 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
firebase-debug.log*
firebase-debug.*.log*
# Firebase cache
.firebase/
# Firebase config
# Uncomment this if you'd like others to create their own Firebase project.
# For a team working on the same Firebase project(s), it is recommended to leave
# it commented so all members can deploy to the same project(s) in .firebaserc.
# .firebaserc
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env

View File

@ -1,12 +0,0 @@
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.@(js|jsx|ts|tsx)"
],
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions"
],
"framework": "@storybook/react"
}

View File

@ -1,9 +0,0 @@
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
}

View File

@ -1,3 +0,0 @@
{
"defaultLanguage": "en"
}

View File

@ -1,26 +0,0 @@
{
"hosting": {
"public": "public",
"headers": [
{
"source": "**",
"headers": [
{
"key": "Access-Control-Allow-Origin",
"value": "*"
}
]
},
{
"source": "**/*.@(png|json)",
"headers": [
{
"key": "Cache-Control",
"value": "max-age=7200"
}
]
}
],
"ignore": ["firebase.json", "**/node_modules/**"]
}
}

View File

@ -1,51 +0,0 @@
const languages = require("./languages.json");
const availableLanguages = languages.map((el) => el.shortKey);
const {
defaultLanguage,
} = require("./config.json");
module.exports = {
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${__dirname}/src/locales`,
name: `locale`
}
},
{
resolve: `gatsby-plugin-react-i18next`,
options: {
localeJsonSourceName: `locale`,
languages: availableLanguages,
defaultLanguage,
redirect: false,
generateDefaultLanguagePage: `/en`,
i18nextOptions: {
fallbackLng: defaultLanguage,
interpolation: {
escapeValue: false
},
keySeparator: false,
nsSeparator: false
},
pages: [
{
matchPath: '/preview',
languages: [""],
},
],
}
},
{
resolve: "gatsby-plugin-google-fonts",
options: {
fonts: ["Open Sans:600,700"],
},
},
'gatsby-plugin-no-javascript'
],
}

View File

@ -1,9 +0,0 @@
exports.createPages = async ({ actions }) => {
const { createPage } = actions
createPage({
path: "/using-dsg",
component: require.resolve("./src/templates/using-dsg.js"),
context: {},
defer: true,
})
}

View File

@ -1,137 +0,0 @@
[
{
"key": "az-Latn-AZ",
"shortKey": "az",
"iconName": "az.svg"
},
{
"key": "bg-BG",
"shortKey": "bg",
"iconName": "bg.svg"
},
{
"key": "zh-CN",
"shortKey": "zh",
"iconName": "zh.svg"
},
{
"key": "cs-CZ",
"shortKey": "cs",
"iconName": "cs.svg"
},
{
"key": "nl-NL",
"shortKey": "nl",
"iconName": "nl.svg"
},
{
"key": "en-GB",
"shortKey": "en-GB",
"iconName": "en-GB.svg"
},
{
"key": "en-US",
"shortKey": "en",
"iconName": "en.svg"
},
{
"key": "fi-FI",
"shortKey": "fi",
"iconName": "fi.svg"
},
{
"key": "fr-FR",
"shortKey": "fr",
"iconName": "fr.svg"
},
{
"key": "de-DE",
"shortKey": "de",
"iconName": "de.svg"
},
{
"key": "de-CH",
"shortKey": "de-CH",
"iconName": "de-CH.svg"
},
{
"key": "el-GR",
"shortKey": "el",
"iconName": "el.svg"
},
{
"key": "it-IT",
"shortKey": "it",
"iconName": "it.svg"
},
{
"key": "ja-JP",
"shortKey": "ja",
"iconName": "ja.svg"
},
{
"key": "ko-KR",
"shortKey": "ko",
"iconName": "ko.svg"
},
{
"key": "lv-LV",
"shortKey": "lv",
"iconName": "lv.svg"
},
{
"key": "pl-PL",
"shortKey": "pl",
"iconName": "pl.svg"
},
{
"key": "pt-BR",
"shortKey": "pt-BR",
"iconName": "pt-BR.svg"
},
{
"key": "pt-PT",
"shortKey": "pt",
"iconName": "pt.svg"
},
{
"key": "ru-RU",
"shortKey": "ru",
"iconName": "ru.svg"
},
{
"key": "sk-SK",
"shortKey": "sk",
"iconName": "sk.svg"
},
{
"key": "sl-SI",
"shortKey": "sl",
"iconName": "sl.svg"
},
{
"key": "es-MX",
"shortKey": "es-MX",
"iconName": "es-MX.svg"
},
{
"key": "es-ES",
"shortKey": "es",
"iconName": "es.svg"
},
{
"key": "tr-TR",
"shortKey": "tr",
"iconName": "tr.svg"
},
{
"key": "uk-UA",
"shortKey": "uk",
"iconName": "uk.svg"
},
{
"key": "vi-VN",
"shortKey": "vi",
"iconName": "vi.svg"
}
]

View File

@ -1,53 +0,0 @@
{
"name": "gatsby-starter-default",
"private": true,
"version": "0.1.0",
"dependencies": {
"firebase-tools": "^10.2.0",
"gatsby": "^4.4.0",
"gatsby-plugin-gatsby-cloud": "^4.4.0",
"gatsby-plugin-google-fonts": "^1.0.1",
"gatsby-plugin-image": "^2.4.0",
"gatsby-plugin-manifest": "^4.4.0",
"gatsby-plugin-no-javascript": "^2.0.5",
"gatsby-plugin-offline": "^5.4.0",
"gatsby-plugin-react-helmet": "^5.4.0",
"gatsby-plugin-react-i18next": "^1.2.2",
"gatsby-plugin-sharp": "^4.4.0",
"gatsby-source-filesystem": "^4.4.0",
"gatsby-transformer-sharp": "^4.4.0",
"i18next": "^21.6.5",
"prop-types": "^15.7.2",
"react": "^17.0.1",
"react-device-detect": "^2.2.2",
"react-dom": "^17.0.1",
"react-helmet": "^6.1.0",
"react-i18next": "^11.15.3",
"styled-components": "^5.3.5"
},
"devDependencies": {
"@babel/core": "^7.17.12",
"@storybook/addon-actions": "^6.4.22",
"@storybook/addon-essentials": "^6.4.22",
"@storybook/addon-interactions": "^6.4.22",
"@storybook/addon-links": "^6.4.22",
"@storybook/react": "^6.4.22",
"@storybook/testing-library": "^0.0.11",
"babel-loader": "^8.2.5",
"prettier": "^2.4.1"
},
"scripts": {
"build": "gatsby build",
"develop": "gatsby develop",
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"",
"start": "gatsby develop",
"serve": "gatsby serve",
"clean": "gatsby clean",
"test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\" && exit 1",
"firebase:login": "firebase login",
"firebase:logout": "firebase logout",
"firebase:deploy": "firebase deploy",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
}
}

View File

@ -1,33 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Page Not Found</title>
<style media="screen">
body { background: #ECEFF1; color: rgba(0,0,0,0.87); font-family: Roboto, Helvetica, Arial, sans-serif; margin: 0; padding: 0; }
#message { background: white; max-width: 360px; margin: 100px auto 16px; padding: 32px 24px 16px; border-radius: 3px; }
#message h3 { color: #888; font-weight: normal; font-size: 16px; margin: 16px 0 12px; }
#message h2 { color: #ffa100; font-weight: bold; font-size: 16px; margin: 0 0 8px; }
#message h1 { font-size: 22px; font-weight: 300; color: rgba(0,0,0,0.6); margin: 0 0 16px;}
#message p { line-height: 140%; margin: 16px 0 24px; font-size: 14px; }
#message a { display: block; text-align: center; background: #039be5; text-transform: uppercase; text-decoration: none; color: white; padding: 16px; border-radius: 4px; }
#message, #message a { box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); }
#load { color: rgba(0,0,0,0.4); text-align: center; font-size: 13px; }
@media (max-width: 600px) {
body, #message { margin-top: 0; background: white; box-shadow: none; }
body { border-top: 16px solid #ffa100; }
}
</style>
</head>
<body>
<div id="message">
<h2>404</h2>
<h1>Page Not Found</h1>
<p>The specified file was not found on this website. Please check the URL for mistakes and try again.</p>
<h3>Why am I seeing this?</h3>
<p>This page was generated by the Firebase Command-Line Interface. To modify it, edit the <code>404.html</code> file in your project's configured <code>public</code> directory.</p>
</div>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

View File

@ -1,89 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Welcome to Firebase Hosting</title>
<!-- update the version number as needed -->
<script defer src="/__/firebase/9.6.6/firebase-app-compat.js"></script>
<!-- include only the Firebase features as you need -->
<script defer src="/__/firebase/9.6.6/firebase-auth-compat.js"></script>
<script defer src="/__/firebase/9.6.6/firebase-database-compat.js"></script>
<script defer src="/__/firebase/9.6.6/firebase-firestore-compat.js"></script>
<script defer src="/__/firebase/9.6.6/firebase-functions-compat.js"></script>
<script defer src="/__/firebase/9.6.6/firebase-messaging-compat.js"></script>
<script defer src="/__/firebase/9.6.6/firebase-storage-compat.js"></script>
<script defer src="/__/firebase/9.6.6/firebase-analytics-compat.js"></script>
<script defer src="/__/firebase/9.6.6/firebase-remote-config-compat.js"></script>
<script defer src="/__/firebase/9.6.6/firebase-performance-compat.js"></script>
<!--
initialize the SDK after all desired features are loaded, set useEmulator to false
to avoid connecting the SDK to running emulators.
-->
<script defer src="/__/firebase/init.js?useEmulator=true"></script>
<style media="screen">
body { background: #ECEFF1; color: rgba(0,0,0,0.87); font-family: Roboto, Helvetica, Arial, sans-serif; margin: 0; padding: 0; }
#message { background: white; max-width: 360px; margin: 100px auto 16px; padding: 32px 24px; border-radius: 3px; }
#message h2 { color: #ffa100; font-weight: bold; font-size: 16px; margin: 0 0 8px; }
#message h1 { font-size: 22px; font-weight: 300; color: rgba(0,0,0,0.6); margin: 0 0 16px;}
#message p { line-height: 140%; margin: 16px 0 24px; font-size: 14px; }
#message a { display: block; text-align: center; background: #039be5; text-transform: uppercase; text-decoration: none; color: white; padding: 16px; border-radius: 4px; }
#message, #message a { box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); }
#load { color: rgba(0,0,0,0.4); text-align: center; font-size: 13px; }
@media (max-width: 600px) {
body, #message { margin-top: 0; background: white; box-shadow: none; }
body { border-top: 16px solid #ffa100; }
}
</style>
</head>
<body>
<div id="message">
<h2>Welcome</h2>
<h1>Firebase Hosting Setup Complete</h1>
<p>You're seeing this because you've successfully setup Firebase Hosting. Now it's time to go build something extraordinary!</p>
<a target="_blank" href="https://firebase.google.com/docs/hosting/">Open Hosting Documentation</a>
</div>
<p id="load">Firebase SDK Loading&hellip;</p>
<script>
document.addEventListener('DOMContentLoaded', function() {
const loadEl = document.querySelector('#load');
// // 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥
// // The Firebase SDK is initialized and available here!
//
// firebase.auth().onAuthStateChanged(user => { });
// firebase.database().ref('/path/to/ref').on('value', snapshot => { });
// firebase.firestore().doc('/foo/bar').get().then(() => { });
// firebase.functions().httpsCallable('yourFunction')().then(() => { });
// firebase.messaging().requestPermission().then(() => { });
// firebase.storage().ref('/path/to/ref').getDownloadURL().then(() => { });
// firebase.analytics(); // call to activate
// firebase.analytics().logEvent('tutorial_completed');
// firebase.performance(); // call to activate
//
// // 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥
try {
let app = firebase.app();
let features = [
'auth',
'database',
'firestore',
'functions',
'messaging',
'storage',
'analytics',
'remoteConfig',
'performance',
].filter(feature => typeof app[feature] === 'function');
loadEl.textContent = `Firebase SDK loaded with ${features.join(', ')}`;
} catch (e) {
console.error(e);
loadEl.textContent = 'Error loading the Firebase SDK, check the console.';
}
});
</script>
</body>
</html>

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE für Business",
"SubHeader": "Dokumente, Projekte, Kunden & E-Mails",
"ButtonLabel": "Kostenlos testen",
"Link": "https://www.onlyoffice.com/de/registration.aspx?utm_source=personal&utm_campaign=BannerPersonalCloud"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE für PC",
"SubHeader": "Gratis Alternative zu MS Office",
"ButtonLabel": "Herunterladen",
"Link": "https://www.onlyoffice.com/de/download-desktop.aspx?utm_source=personal&utm_campaign=BannerPersonalDesktop"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE für Schulen",
"SubHeader": "Endecken Sie alle Rabatte",
"ButtonLabel": "Mehr erfahren",
"Link": "https://www.onlyoffice.com/de/education.aspx?utm_source=personal&utm_campaign=BannerPersonalEducation"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE On-Premises",
"SubHeader": "Schützen Sie Ihre Dokumente",
"ButtonLabel": "Jetzt erhalten",
"Link": "https://www.onlyoffice.com/de/download-workspace.aspx?utm_source=personal&utm_campaign=BannerPersonalEnterprise"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE Integration",
"SubHeader": "Editoren für Ihre Plattform",
"ButtonLabel": "Jetzt integrieren",
"Link": "https://www.onlyoffice.com/de/connectors.aspx?utm_source=personal&utm_campaign=BannerPersonalIntegration"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE for business",
"SubHeader": "Docs, projects, clients & emails",
"ButtonLabel": "Start free trial",
"Link": "https://www.onlyoffice.com/registration.aspx?utm_source=personal&utm_campaign=BannerPersonalCloud"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE for PC",
"SubHeader": "Get a free alternative to MS Office",
"ButtonLabel": "Download",
"Link": "https://www.onlyoffice.com/download-desktop.aspx?utm_source=personal&utm_campaign=BannerPersonalDesktop"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE for schools",
"SubHeader": "Learn about education discounts",
"ButtonLabel": "Learn more",
"Link": "https://www.onlyoffice.com/education.aspx?utm_source=personal&utm_campaign=BannerPersonalEducation"
}

View File

@ -1,7 +0,0 @@
{
"Header": "ONLYOFFICE on-premises",
"SubHeader": "Keep your docs and projects safe",
"ButtonLabel": "Get it now",
"Link": "https://www.onlyoffice.com/download-commercial.aspx?utm_source=personal&utm_campaign=BannerPersonalEnterprise"
}

View File

@ -1,7 +0,0 @@
{
"Header": "ONLYOFFICE for integration",
"SubHeader": "Use online editors with your platform",
"ButtonLabel": "Integrate now",
"Link": "https://www.onlyoffice.com/connectors.aspx?utm_source=personal&utm_campaign=BannerPersonalIntegration"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE pour les entreprises",
"SubHeader": "Documents, projets, clients et mails.",
"ButtonLabel": "Commencer lessai gratuit",
"Link": "https://www.onlyoffice.com/fr/registration.aspx?utm_source=personal&utm_campaign=BannerPersonalCloud"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE pour le PC",
"SubHeader": "Alternative gratuite à MS Office",
"ButtonLabel": "Télécharger",
"Link": "https://www.onlyoffice.com/fr/download-desktop.aspx?utm_source=personal&utm_campaign=BannerPersonalDesktop"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE éducation",
"SubHeader": "Voir toutes les offres",
"ButtonLabel": "En savoir plus",
"Link": "https://www.onlyoffice.com/fr/education.aspx?utm_source=personal&utm_campaign=BannerPersonalEducation"
}

View File

@ -1,6 +0,0 @@
{
"Header": "Solution auto-hébergée",
"SubHeader": "Vos docs en toute sécurité",
"ButtonLabel": "Obtenir maintenant",
"Link": "https://www.onlyoffice.com/fr/download-workspace.aspx?utm_source=personal&utm_campaign=BannerPersonalEnterprise"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE intégration",
"SubHeader": "Éditeurs pour votre plateforme",
"ButtonLabel": "Intégrer maintenant",
"Link": "https://www.onlyoffice.com/fr/connectors.aspx?utm_source=personal&utm_campaign=BannerPersonalIntegration"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE per business",
"SubHeader": "Documenti, progetti, clienti ed e-mail",
"ButtonLabel": "Inizia la prova gratuita",
"Link": "https://www.onlyoffice.com/it/registration.aspx?utm_source=personal&utm_campaign=BannerPersonalCloud"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE per PC",
"SubHeader": "Alternativa gratuita a MS Office",
"ButtonLabel": "Scarica",
"Link": "https://www.onlyoffice.com/it/download-desktop.aspx?utm_source=personal&utm_campaign=BannerPersonalDesktop"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE per scuole",
"SubHeader": "Informazioni sugli sconti",
"ButtonLabel": "Per saperne di più",
"Link": "https://www.onlyoffice.com/it/education.aspx?utm_source=personal&utm_campaign=BannerPersonalEducation"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE sul server",
"SubHeader": "Mantieni documenti al sicuro",
"ButtonLabel": "Scaricalo ora",
"Link": "https://www.onlyoffice.com/it/download-workspace.aspx?utm_source=personal&utm_campaign=BannerPersonalEnterprise"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE integrazioni",
"SubHeader": "Editor per la tua piattaforma",
"ButtonLabel": "Connetti ora",
"Link": "https://www.onlyoffice.com/it/connectors.aspx?utm_source=personal&utm_campaign=BannerPersonalIntegration"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE for business",
"SubHeader": "Docs, projects, clients & emails",
"ButtonLabel": "Start free trial",
"Link": "https://www.onlyoffice.com/pt/registration.aspx?utm_source=personal&utm_campaign=BannerPersonalCloud"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE for PC",
"SubHeader": "Get a free alternative to MS Office",
"ButtonLabel": "Download",
"Link": "https://www.onlyoffice.com/pt/download-desktop.aspx?utm_source=personal&utm_campaign=BannerPersonalDesktop"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE for schools",
"SubHeader": "Learn about education discounts",
"ButtonLabel": "Learn more",
"Link": "https://www.onlyoffice.com/pt/education.aspx?utm_source=personal&utm_campaign=BannerPersonalEducation"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE on-premises",
"SubHeader": "Keep your docs and projects safe",
"ButtonLabel": "Get it now",
"Link": "https://www.onlyoffice.com/pt/download-workspace.aspx?utm_source=personal&utm_campaign=BannerPersonalEnterprise"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE for integration",
"SubHeader": "Use online editors with your platform",
"ButtonLabel": "Integrate now",
"Link": "https://www.onlyoffice.com/pt/connectors.aspx?utm_source=personal&utm_campaign=BannerPersonalIntegration"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE для бизнеса",
"SubHeader": "Документы, проекты, клиенты и почта",
"ButtonLabel": "Начните бесплатно",
"Link": "https://www.onlyoffice.com/ru/registration.aspx?utm_source=personal&utm_campaign=BannerPersonalCloud"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE для ПК",
"SubHeader": "Получите бесплатную альтернативу MS Office",
"ButtonLabel": "Скачать",
"Link": "https://www.onlyoffice.com/ru/download-desktop.aspx?utm_source=personal&utm_campaign=BannerPersonalDesktop"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE для школ",
"SubHeader": "Узнайте больше об образовательных скидках",
"ButtonLabel": "Узнать больше",
"Link": "https://www.onlyoffice.com/ru/education.aspx?utm_source=personal&utm_campaign=BannerPersonalEducation"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE локально",
"SubHeader": "Обеспечьте сохранность документов и проектов",
"ButtonLabel": "Получить сейчас",
"Link": "https://www.onlyoffice.com/ru/download-workspace.aspx?utm_source=personal&utm_campaign=BannerPersonalEnterprise"
}

View File

@ -1,6 +0,0 @@
{
"Header": "ONLYOFFICE для интеграции",
"SubHeader": "Используйте онлайн-редакторы с вашей платформой",
"ButtonLabel": "Интегрировать сейчас",
"Link": "https://www.onlyoffice.com/ru/connectors.aspx?utm_source=personal&utm_campaign=BannerPersonalIntegration"
}

View File

@ -1,35 +0,0 @@
import React from 'react';
import { Layout } from '../Layout';
export default {
title: 'Example/Docs_7_1',
component: Layout,
parameters: {
layout: 'fullscreen',
},
argTypes: {
theme: {
control: {
type: "select",
options: ["light", "dark"]
}
},
language: {
control: {
type: "select",
options: ["en", "ru", "cs", "de", "es", "fr", "it", "ja", "nl", "pt", "zh"]
}
}
}
};
const Template = (args) => <Layout {...args} />;
export const Default = Template.bind({});
Default.args = {
origin: "http://localhost:8000", // use your source
name: "Docs_7_1",
language: "en",
theme: "light"
}

View File

@ -1,41 +0,0 @@
import React, {useState, useEffect} from 'react';
import { Header } from './header/Header';
import { Article } from './article/Article';
import { Section } from './section/Section';
import {Dark, Base} from './theme/index';
import { ThemeProvider } from "styled-components";
export const Layout = ({theme, name, origin, language}) => {
const [visible, setVisible] = useState(true);
const themes = {
light: Base,
dark: Dark
}
const onResize = () => {
if (window.innerWidth < 1025) {
setVisible(false);
} else {
setVisible(true);
}
}
useEffect(() => {
window.addEventListener('resize', onResize)
return () => window.removeEventListener('resize', onResize);
}, [])
return (
<ThemeProvider theme={themes[theme || 'light']}>
<Header />
<div className='container' style={{display: "flex"}}>
{visible && window.innerWidth > 1025 && <Article />}
<Section name={name} origin={origin} lang={language} />
</div>
</ThemeProvider>
);
};

View File

@ -1,35 +0,0 @@
import React from 'react';
import { Layout } from '../Layout';
export default {
title: 'Example/NewYear',
component: Layout,
parameters: {
layout: 'fullscreen',
},
argTypes: {
theme: {
control: {
type: "select",
options: ["light", "dark"]
}
},
language: {
control: {
type: "select",
options: ["en", "ru"]
}
}
}
};
const Template = (args) => <Layout {...args} />;
export const Default = Template.bind({});
Default.args = {
origin: "http://localhost:8000", // use your source
name: "NewYear",
language: "en",
theme: "light"
}

View File

@ -1,24 +0,0 @@
import React from 'react';
import { StyledArticle, ArticleHeader, Header, StyledButtonWrapper, Button, Block, ArticleWrapper } from './styled-article';
export const Article = () => {
const elements = [];
for (let i = 0; i < 7; i++) {
elements.push(<Block key={i} />)
}
return <StyledArticle>
<ArticleHeader>
<Header>Documents</Header>
</ArticleHeader>
<StyledButtonWrapper>
<Button>Actions</Button>
</StyledButtonWrapper>
<ArticleWrapper>
{elements}
</ArticleWrapper>
</StyledArticle>
}

View File

@ -1,49 +0,0 @@
import styled from "styled-components";
const StyledArticle = styled.div`
width: 302px;
background-color: ${props => props.theme.article};
`;
const ArticleHeader = styled.div`
padding: 11px 20px 14px;
`;
const Header = styled.div`
font-size: 26px;
font-weight: 700;
padding: 0;
margin: 0;
color: ${props => props.theme.color};
`;
const StyledButtonWrapper = styled.div`
padding: 0px 20px 16px;
`;
const Button = styled.button`
padding: 6px 10px;
width: 100%;
text-align: left;
border: none;
background-color: #ED7309;
box-sizing: border-box;
color: ${props => props.theme.articleButton};
font-weight: 900;
border-radius: 3px;
`;
const Block = styled.div`
height: 28px;
width: 100%;
background-color: ${props => props.theme.loaders};
margin-top: 10px;
`;
const ArticleWrapper = styled.div`
padding: 0 20px;
`;
export {StyledArticle, ArticleHeader, Header, StyledButtonWrapper, Button, Block, ArticleWrapper};

View File

@ -1,21 +0,0 @@
import React from 'react';
import styled from "styled-components";
import logo from './nav.svg'
const StyledHeader = styled.div`
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
padding: 8px 20px;
display: flex;
align-items: center;
justify-content: space-between;
background-color: ${props => props.theme.headerColor};
`;
export const Header = () => (
<StyledHeader>
<img src={logo} />
</StyledHeader>
);

View File

@ -1,29 +0,0 @@
<svg width="147" height="24" viewBox="0 0 147 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M34.1654 6.82411C32.7061 8.0184 32 9.85576 32 12.2903C32 14.7248 32.7061 16.5621 34.1654 17.8023C35.6248 19.0426 37.2725 19.6397 39.2026 19.6397C41.0855 19.6397 42.7803 19.0426 44.1925 17.8023C45.6048 16.6081 46.311 14.7707 46.311 12.3362C46.311 9.85576 45.6048 8.06433 44.1925 6.82411C42.7803 5.58389 41.1326 4.98676 39.2026 4.98676C37.2725 4.98676 35.5777 5.58389 34.1654 6.82411ZM36.0485 15.9651C35.4365 15.1842 35.107 13.9898 35.107 12.2904C35.107 10.6366 35.4365 9.4424 36.0485 8.70746C36.7075 7.92658 37.4136 7.4213 38.1669 7.23756C38.3551 7.19162 38.5434 7.14569 38.6847 7.14569C38.8259 7.09976 38.9671 7.09976 39.1553 7.09976H39.1554C39.2496 7.09976 39.332 7.11124 39.4143 7.12273C39.4967 7.13421 39.5791 7.14569 39.6732 7.14569C39.8145 7.14569 40.0029 7.19162 40.1912 7.23756C40.9443 7.4213 41.6505 7.92658 42.2624 8.70746C42.8744 9.48833 43.2039 10.7286 43.2039 12.3362C43.2039 13.944 42.8744 15.1842 42.2624 15.9651C41.6505 16.7459 40.9443 17.2512 40.1912 17.435C40.1587 17.4429 40.1276 17.4508 40.0974 17.4585C39.9527 17.4953 39.8291 17.5268 39.6732 17.5268C39.485 17.5727 39.3437 17.5727 39.1554 17.5727H39.1554C39.0848 17.5727 39.0024 17.5612 38.9201 17.5498C38.8377 17.5383 38.7553 17.5268 38.6847 17.5268C38.5289 17.5268 38.4053 17.4953 38.2606 17.4585C38.2304 17.4508 38.1993 17.4429 38.1669 17.435C37.4136 17.2512 36.7075 16.7459 36.0485 15.9651Z" fill="white"/>
<path d="M47.8643 5.12457H51.7245L56.8086 14.1736L57.5618 16.1029H57.6088L57.5618 13.5764V5.12457H60.5275V19.456H56.6674L51.5832 10.0855L50.83 8.47776H50.7829L50.83 11.0041V19.456H47.8643V5.12457Z" fill="white"/>
<path d="M63.1172 5.12457H66.0829V17.0215H71.9202V19.456H63.1172V5.12457Z" fill="white"/>
<path d="M70.084 5.12457H73.5205L76.5332 10.1773L77.004 11.1419H77.0982L77.5689 10.1773L80.6289 5.12457H83.7829L78.4633 13.6224V19.456H75.4976V13.6224L70.084 5.12457Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M86.0424 6.82411C84.583 8.0184 83.877 9.85576 83.877 12.2903C83.877 14.7248 84.6302 16.5621 86.0424 17.8023C87.5017 19.0426 89.1493 19.6397 91.0794 19.6397C92.9625 19.6397 94.6572 19.0426 96.0694 17.8023C97.4817 16.6081 98.1878 14.7707 98.1878 12.3362C98.1878 9.85576 97.4817 8.06433 96.0694 6.82411C94.6572 5.58389 93.0095 4.98676 91.0794 4.98676C89.1493 4.98676 87.4547 5.58389 86.0424 6.82411ZM87.9254 15.9651C87.3134 15.1842 86.9839 13.9898 86.9839 12.2904C86.9839 10.6366 87.3134 9.4424 87.9254 8.70746C88.5845 7.92658 89.2906 7.4213 90.0438 7.23756C90.2321 7.19162 90.4204 7.14569 90.5616 7.14569C90.7028 7.09976 90.844 7.09976 91.0323 7.09976H91.0324C91.1265 7.09976 91.2089 7.11124 91.2913 7.12273C91.3737 7.13421 91.456 7.14569 91.5502 7.14569C91.6913 7.14569 91.8794 7.19156 92.0677 7.23746L92.0681 7.23756C92.8212 7.4213 93.5274 7.92658 94.1393 8.70746C94.7513 9.48833 95.0809 10.7286 95.0809 12.3362C95.0809 13.944 94.7513 15.1842 94.1393 15.9651C93.5274 16.7459 92.8212 17.2512 92.0681 17.435C92.0355 17.4429 92.0044 17.4508 91.9742 17.4585C91.8295 17.4954 91.7059 17.5268 91.5502 17.5268C91.3619 17.5727 91.2207 17.5727 91.0324 17.5727H91.0324C90.9618 17.5727 90.8794 17.5612 90.797 17.5498C90.7146 17.5383 90.6322 17.5268 90.5616 17.5268C90.4208 17.5268 90.2332 17.4811 90.0455 17.4354L90.0438 17.435C89.2435 17.2512 88.5845 16.7459 87.9254 15.9651Z" fill="white"/>
<path d="M99.7881 5.12457H107.979V7.55908H102.754V11.0041H107.743V13.4386H102.754V19.456H99.7881V5.12457Z" fill="white"/>
<path d="M109.722 5.12457H117.913V7.55908H112.687V11.0041H117.677V13.4386H112.687V19.456H109.722V5.12457Z" fill="white"/>
<path d="M119.654 19.456V5.12457H122.621V19.456H119.654Z" fill="white"/>
<path d="M136.014 5.44608V7.92652C135.496 7.74278 134.978 7.60499 134.414 7.51312C133.849 7.42125 133.237 7.37531 132.577 7.37531C131.024 7.37531 129.848 7.83465 129 8.79927C128.153 9.71796 127.729 10.9122 127.729 12.3362C127.729 13.7142 128.105 14.8626 128.906 15.7813C129.706 16.6999 130.836 17.2052 132.295 17.2052C132.813 17.2052 133.331 17.1593 133.943 17.1134C134.554 17.0214 135.166 16.8837 135.826 16.6081L136.014 19.0425C135.92 19.0885 135.779 19.1345 135.638 19.1804C135.45 19.2263 135.261 19.2722 135.026 19.3182C134.649 19.41 134.178 19.456 133.613 19.5479C133.049 19.5937 132.483 19.6397 131.871 19.6397C131.777 19.6397 131.683 19.6397 131.636 19.6397C131.542 19.6397 131.448 19.6397 131.401 19.6397C129.706 19.5479 128.153 18.9048 126.741 17.8023C125.328 16.654 124.622 14.8626 124.622 12.474C124.622 10.1314 125.328 8.294 126.693 7.00784C128.058 5.72169 129.942 5.07861 132.249 5.07861C132.86 5.07861 133.425 5.07861 133.896 5.12454C134.414 5.17047 134.884 5.26234 135.402 5.35421C135.496 5.40015 135.638 5.40015 135.732 5.44608C135.779 5.40015 135.873 5.44608 136.014 5.44608Z" fill="white"/>
<path d="M137.866 5.12457H146.669V7.37534H140.879V10.9582H146.105V13.209H140.879V17.2053H146.669V19.456H137.866V5.12457Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.3099 23.7112L0.67919 18.8606C-0.226397 18.4371 -0.226397 17.7827 0.67919 17.3976L4.38028 15.7038L11.2707 18.8606C12.1762 19.284 13.6331 19.284 14.4992 18.8606L21.3895 15.7038L25.0907 17.3976C25.9963 17.8212 25.9963 18.4756 25.0907 18.8606L14.4598 23.7112C13.6331 24.0962 12.1762 24.0962 11.3099 23.7112Z" fill="url(#paint0_linear)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.31 17.5139L0.67919 12.6633C-0.226397 12.2398 -0.226397 11.5853 0.67919 11.2003L4.30154 9.54492L11.31 12.7403C12.2156 13.1637 13.6723 13.1637 14.5386 12.7403L21.5471 9.54492L25.1694 11.2003C26.075 11.6238 26.075 12.2783 25.1694 12.6633L14.5386 17.5139C13.6331 17.9374 12.1762 17.9374 11.31 17.5139Z" fill="url(#paint1_linear)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.31 11.4819L0.67919 6.63119C-0.226397 6.20772 -0.226397 5.55326 0.67919 5.16829L11.31 0.317604C12.2155 -0.105868 13.6724 -0.105868 14.5387 0.317604L25.1694 5.16829C26.075 5.59176 26.075 6.24622 25.1694 6.63119L14.5387 11.4819C13.633 11.8669 12.1763 11.8669 11.31 11.4819Z" fill="url(#paint2_linear)"/>
<defs>
<linearGradient id="paint0_linear" x1="40.4198" y1="28.3092" x2="40.4198" y2="10.5998" gradientUnits="userSpaceOnUse">
<stop stop-color="#FCC2B1"/>
<stop offset="0.8848" stop-color="#D9420B"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="31.0804" y1="20.4113" x2="31.0804" y2="8.76439" gradientUnits="userSpaceOnUse">
<stop stop-color="#DEEDC9"/>
<stop offset="0.6606" stop-color="#8BBA25"/>
</linearGradient>
<linearGradient id="paint2_linear" x1="30.3174" y1="15.4763" x2="30.3174" y2="-0.372617" gradientUnits="userSpaceOnUse">
<stop stop-color="#C2EBFA"/>
<stop offset="1" stop-color="#26A8DE"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -1,49 +0,0 @@
import React, {useState, useEffect} from "react";
import {
StyledSection,
Icon,
Name,
MainLoader,
FilterLoader,
SectionContent,
SectionHeader,
SectionWrapper,
StyledIframe,
StyledAction } from "./styled-section";
import cross from './images/cross.react.svg'
export const Section = ({name, origin, lang}) => {
useEffect(() => {
setLanguage(lang);
}, [lang])
const [language, setLanguage] = useState(lang || "en");
const url = `${origin}/${language}/${name}`
const elements = [];
for (let i = 0; i < 14; i++) {
elements.push(<SectionContent key={i}>
<Icon />
<Name />
<MainLoader />
</SectionContent>)
}
return <StyledSection>
<div style={{position: "relative"}}>
<StyledIframe scrolling="no" className="iframe" src={url} />
<StyledAction>
<img style={{width: "16px"}} src={cross} />
</StyledAction>
</div>
<SectionWrapper>
<SectionHeader>My documents</SectionHeader>
<FilterLoader />
{elements}
</SectionWrapper>
</StyledSection>
}

View File

@ -1,3 +0,0 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.76288 6.35869C7.56764 6.16343 7.56764 5.84687 7.76288 5.65161L10.9493 2.46498C11.1445 2.26973 11.1445 1.95316 10.9493 1.75791L10.2422 1.05077C10.0469 0.855489 9.73031 0.855489 9.53504 1.05077L6.34878 4.23729C6.15352 4.43257 5.83691 4.43257 5.64165 4.23729L2.46017 1.05556C2.26491 0.860275 1.9483 0.860275 1.75304 1.05556L1.04596 1.76269C0.850716 1.95795 0.850716 2.27451 1.04596 2.46977L4.22755 5.65161C4.42279 5.84687 4.42279 6.16343 4.22755 6.35869L1.0501 9.53639C0.854858 9.73165 0.854858 10.0482 1.0501 10.2435L1.75718 10.9506C1.95245 11.1459 2.26905 11.1459 2.46432 10.9506L5.64165 7.77302C5.83691 7.57774 6.15352 7.57774 6.34878 7.77302L9.5309 10.9554C9.72616 11.1507 10.0428 11.1507 10.238 10.9554L10.9451 10.2483C11.1404 10.053 11.1404 9.73644 10.9451 9.54118L7.76288 6.35869Z" fill="#999976"/>
</svg>

Before

Width:  |  Height:  |  Size: 958 B

View File

@ -1,71 +0,0 @@
import styled, { css } from "styled-components";
import { isMobile } from "react-device-detect";
const StyledSection = styled.div`
width: 100%;
background-color: ${props => props.theme.background};
`;
const Icon = styled.div`
width: 14px;
height: 14px;
background-color: ${props => props.theme.loaders};
`;
const Name = styled.div`
width: 24px;
height: 24px;
background-color: ${props => props.theme.loaders};
margin-left: 10px;
`;
const MainLoader = styled.div`
background-color: ${props => props.theme.loaders};
width: 100%;
margin-left: 10px;
height: 13px;
`;
const FilterLoader = styled.div`
height: 30px;
background-color: ${props => props.theme.loaders};
`;
const SectionContent = styled.div`
display: flex;
align-items: baseline;
margin: 20px 0;
`;
const SectionWrapper = styled.div`
padding: 0px 20px;
`;
const SectionHeader = styled.h2`
color: ${props => props.theme.color};
`;
const StyledIframe = styled.iframe`
border: none;
height: 60px;
width: 100%;
`;
const StyledAction = styled.div`
position: absolute;
right: 8px;
top: 10px;
background: inherit;
display: inline-block;
border: none;
font-size: inherit;
color: "#333";
cursor: pointer;
text-decoration: underline;
${isMobile &&
css`
right: 14px;
`};
`;
export {StyledSection, Icon, Name, MainLoader, FilterLoader, SectionContent, SectionHeader, SectionWrapper, StyledIframe, StyledAction}

View File

@ -1,21 +0,0 @@
const Base = {
headerColor: "#0F4071",
loaders: "#eee",
background: "#fff",
article: "#f8f9f9",
color: "#333",
articleButton: "#fff"
}
const Dark = {
article: "#292929",
headerColor: "#1f1f1f",
loaders: "#232323",
background: "#333",
color: "#fff",
articleButton: "#333"
}
export {Dark, Base};

View File

@ -1,4 +0,0 @@
{
"BannerTextDesktop": "<0>Objevte <1>ONLYOFFICE Docs v7.1</1>:</0> kompatibilitu s ARM, vylepšený prohlížeč PDF/XPS/DjVu, převod PDF do DOCX, náhled tisku pro listy a další funkce",
"BannerTextMob": "<0>Objevte ONLYOFFICE <1>Docs v7.1</1></0>"
}

View File

@ -1,4 +0,0 @@
{
"BannerTextDesktop": "<0>Entdecken Sie <1>ONLYOFFICE Docs v7.1</1>:</0> ARM-Kompatibilität, verbesserter PDF/XPS/DjVu-Unterstützung, Konvertierung von PDF in DOCX, Druckvorschau für Arbeitsblätter und mehr",
"BannerTextMob": "<0>ONLYOFFICE <1>Docs v7.1</1> entdecken</0>"
}

View File

@ -1,4 +0,0 @@
{
"BannerTextDesktop": "<0>Discover <1>ONLYOFFICE Docs v7.1</1>:</0> ARM compatibility, upgraded PDF/XPS/DjVu viewer, PDF to DOCX conversion, Print preview for sheets and more",
"BannerTextMob": "<0>Discover ONLYOFFICE <1>Docs v7.1</1></0>"
}

View File

@ -1,4 +0,0 @@
{
"Title":"ONLYOFFICE Advent Calendar",
"Text": "Spend 24 days of Christmas with ONLYOFFICE. Get <1>new gifts and discounts</1> each day - up to 99% off!"
}

View File

@ -1,4 +0,0 @@
{
"BannerTextDesktop": "<0>Descubre <1>ONLYOFFICE Docs v7.1</1>:</0> compatibilidad con ARM, visor mejorado de PDF/XPS/DjVu, conversión de PDF a DOCX, vista previa de impresión para hojas y mucho más",
"BannerTextMob": "<0>Descubre ONLYOFFICE <1>Docs v7.1</1></0>"
}

View File

@ -1,4 +0,0 @@
{
"BannerTextDesktop": "<0>Découvrez <1>ONLYOFFICE Docs v7.1</1>:</0> Compatibilité ARM, visionneuse PDF/XPS/DjVu améliorée, conversion de PDF en DOCX, aperçu avant impression pour les feuilles de calcul et plus encore",
"BannerTextMob": "<0>Découvrir ONLYOFFICE <1>Docs v7.1</1></0>"
}

View File

@ -1,4 +0,0 @@
{
"BannerTextDesktop": "<0>Scopri <1>ONLYOFFICE Docs v7.1</1>:</0> compatibilità ARM, lettore PDF/XPS/DjVu aggiornato, conversione da PDF a DOCX, anteprima di stampa per fogli di calcolo e altro ancora",
"BannerTextMob": "<0>Scopri ONLYOFFICE <1>Docs v7.1</1></0>"
}

Some files were not shown because too many files have changed in this diff Show More