Merge branch 'feature/update-react-router-dom' of https://github.com/ONLYOFFICE/DocSpace-client into feature/update-react-router-dom

This commit is contained in:
Timofey Boyko 2024-06-20 13:07:37 +03:00
commit 7ad654c02a
26 changed files with 209 additions and 132 deletions

View File

@ -6,6 +6,7 @@ on:
branches:
- 'hotfix/v*'
- 'release/v*'
- 'develop'
jobs:
dispatch:

View File

@ -101,7 +101,7 @@ const Panels = (props) => {
selectFileFormRoomDialogVisible,
selectFileFormRoomFilterParam,
setSelectFileFormRoomDialogVisible,
createFromTemplateForm,
copyFromTemplateForm,
hotkeyPanelVisible,
invitePanelVisible,
convertPasswordDialogVisible,
@ -301,7 +301,7 @@ const Panels = (props) => {
key="select-file-form-room-dialog"
onClose={onCloseFileFormRoomDialog}
openRoot={selectFileFormRoomOpenRoot}
onSelectFile={createFromTemplateForm}
onSelectFile={(file) => copyFromTemplateForm(file, t)}
filterParam={selectFileFormRoomFilterParam}
descriptionText={descriptionTextFileFormRoomDialog}
/>
@ -367,6 +367,7 @@ export default inject(
createEditRoomStore,
pluginStore,
filesStore,
filesActionsStore,
}) => {
const {
ownerPanelVisible,
@ -397,7 +398,6 @@ export default inject(
selectFileFormRoomDialogVisible,
selectFileFormRoomFilterParam,
setSelectFileFormRoomDialogVisible,
createFromTemplateForm,
invitePanelOptions,
inviteUsersWarningDialogVisible,
changeUserTypeDialogVisible,
@ -417,6 +417,7 @@ export default inject(
} = dialogsStore;
const { preparationPortalDialogVisible } = backup;
const { copyFromTemplateForm } = filesActionsStore;
const { uploadPanelVisible } = uploadDataStore;
const { isVisible: versionHistoryPanelVisible } = versionHistoryStore;
@ -455,7 +456,7 @@ export default inject(
selectFileFormRoomDialogVisible,
selectFileFormRoomFilterParam,
setSelectFileFormRoomDialogVisible,
createFromTemplateForm,
copyFromTemplateForm,
hotkeyPanelVisible,
restoreAllPanelVisible,
invitePanelVisible: invitePanelOptions.visible,

View File

@ -71,6 +71,8 @@ const CreateEvent = ({
publicRoomKey,
actionEdit,
openOnNewPage,
openEditor,
createFile,
}) => {
const [headerTitle, setHeaderTitle] = React.useState(null);
const [startValue, setStartValue] = React.useState("");
@ -112,7 +114,7 @@ const CreateEvent = ({
};
}, [extension, title, fromTemplate, withoutDialog]);
const onSave = (e, value, open = true) => {
const onSave = async (e, value, open = true) => {
let item;
let createdFolderId;
@ -157,46 +159,63 @@ const CreateEvent = ({
return setIsLoading(false);
});
} else {
const searchParams = new URLSearchParams();
try {
if (openEditor) {
const searchParams = new URLSearchParams();
searchParams.append("parentId", parentId);
searchParams.append("fileTitle", `${newValue}.${extension}`);
searchParams.append("open", open);
searchParams.append("id", id);
searchParams.append("parentId", parentId);
searchParams.append("fileTitle", `${newValue}.${extension}`);
searchParams.append("open", open);
searchParams.append("id", id);
if (preview) {
searchParams.append("action", "view");
if (preview) {
searchParams.append("action", "view");
}
if (actionEdit) {
searchParams.append("action", "edit");
}
if (publicRoomKey) {
searchParams.append("share", publicRoomKey);
}
if (isMakeFormFromFile) {
searchParams.append("fromFile", isMakeFormFromFile);
searchParams.append("templateId", templateId);
} else if (fromTemplate) {
searchParams.append("fromTemplate", fromTemplate);
searchParams.append("formId", gallerySelected.id);
}
searchParams.append("hash", new Date().getTime());
const url = combineUrl(
window.location.origin,
window.ClientConfig?.proxy?.url,
config.homepage,
`/doceditor/create?${searchParams.toString()}`,
);
window.open(url, openOnNewPage ? "_blank" : "_self");
return;
}
return await createFile(
+parentId,
`${newValue}.${extension}`,
templateId,
gallerySelected?.id,
).catch((error) => {
toastr.error(error);
});
} catch (error) {
toastr.error(error);
} finally {
setIsLoading(false);
onCloseAction();
}
if (actionEdit) {
searchParams.append("action", "edit");
}
if (publicRoomKey) {
searchParams.append("share", publicRoomKey);
}
if (isMakeFormFromFile) {
searchParams.append("fromFile", isMakeFormFromFile);
searchParams.append("templateId", templateId);
} else if (fromTemplate) {
searchParams.append("fromTemplate", fromTemplate);
searchParams.append("formId", gallerySelected.id);
}
searchParams.append("hash", new Date().getTime());
const url = combineUrl(
window.location.origin,
window.ClientConfig?.proxy?.url,
config.homepage,
`/doceditor/create?${searchParams.toString()}`,
);
window.open(url, openOnNewPage ? "_blank" : "_self");
setIsLoading(false);
onCloseAction();
}
};

View File

@ -115,6 +115,7 @@ const GlobalEvents = ({ enablePlugins, eventListenerItemsList }) => {
withoutDialog: payload.withoutDialog ?? false,
preview: payload.preview ?? false,
actionEdit: payload.edit ?? false,
openEditor: payload.openEditor ?? true,
onClose: () => {
setCreateDialogProps({
visible: false,
@ -128,6 +129,7 @@ const GlobalEvents = ({ enablePlugins, eventListenerItemsList }) => {
withoutDialog: false,
preview: false,
actionEdit: false,
openEditor: true,
});
},
});

View File

@ -63,7 +63,7 @@ const ConflictResolveDialog = (props: ConflictResolveDialogProps) => {
handleFilesUpload,
} = props;
const { t, ready } = useTranslation(["ConflictResolveDialog", "Common"]);
const { t, ready } = useTranslation(["Common"]);
const {
destFolderId,
@ -198,7 +198,7 @@ const ConflictResolveDialog = (props: ConflictResolveDialogProps) => {
items.length === 1 ? (
<Trans
t={t}
ns="ConflictResolveDialog"
ns="Common"
i18nKey="ConflictResolveDescription"
values={{ file: items[0].title, folder: folderTitle }}
components={{ 1: <span className="bold" /> }}
@ -206,7 +206,7 @@ const ConflictResolveDialog = (props: ConflictResolveDialogProps) => {
) : (
<Trans
t={t}
ns="ConflictResolveDialog"
ns="Common"
i18nKey="ConflictResolveDescriptionFiles"
values={{ filesCount: items.length, folder: folderTitle }}
components={{ 1: <span className="bold" /> }}
@ -216,20 +216,20 @@ const ConflictResolveDialog = (props: ConflictResolveDialogProps) => {
return (
<ConflictResolve
visible={visible}
headerLabel={t("ConflictResolveTitle")}
headerLabel={t("Common:ConflictResolveTitle")}
isLoading={!ready}
onSubmit={isUploadConflict ? onAcceptUploadType : onAcceptType}
onClose={onCloseDialog}
cancelButtonLabel={t("Common:CancelButton")}
submitButtonLabel={t("Common:OKButton")}
messageText={messageText}
selectActionText={t("ConflictResolveSelectAction")}
overwriteTitle={t("OverwriteTitle")}
overwriteDescription={t("OverwriteDescription")}
selectActionText={t("Common:ConflictResolveSelectAction")}
overwriteTitle={t("Common:OverwriteTitle")}
overwriteDescription={t("Common:OverwriteDescription")}
duplicateTitle={t("Common:CreateFileCopy")}
duplicateDescription={t("CreateDescription")}
skipTitle={t("SkipTitle")}
skipDescription={t("SkipDescription")}
duplicateDescription={t("Common:CreateDescription")}
skipTitle={t("Common:SkipTitle")}
skipDescription={t("Common:SkipDescription")}
/>
);
};

View File

@ -34,7 +34,12 @@ import { getGroup } from "@docspace/shared/api/groups";
import { getUserById } from "@docspace/shared/api/people";
import { MEDIA_VIEW_URL } from "@docspace/shared/constants";
import { Events, RoomSearchArea } from "@docspace/shared/enums";
import {
Events,
FolderType,
RoomSearchArea,
RoomsType,
} from "@docspace/shared/enums";
import { getObjectByLocation } from "@docspace/shared/utils/common";
import { useParams } from "react-router-dom";
@ -72,6 +77,7 @@ const useFiles = ({
userId,
scrollToTop,
selectedFolderStore,
}) => {
const navigate = useNavigate();
const { id } = useParams();
@ -298,11 +304,16 @@ const useFiles = ({
const event = new Event(Events.CREATE);
const isFormRoom =
selectedFolderStore.roomType === RoomsType.FormRoom ||
selectedFolderStore.type === FolderType.FormRoom;
const payload = {
extension: "pdf",
id: -1,
fromTemplate: true,
title: gallerySelected.attributes.name_form,
openEditor: !isFormRoom,
};
event.payload = payload;

View File

@ -278,12 +278,16 @@ class DetailsHelper {
getAuthorDecoration = (byField = "createdBy") => {
const onClick = () => this.openUser(this.item[byField], this.navigate);
const isAnonim = this.item[byField]?.isAnonim;
const displayName = this.item[byField]?.displayName;
const name = displayName ? decode(displayName) : "";
let name = displayName ? decode(displayName) : "";
if (isAnonim) name = this.t("Common:Anonymous");
//console.log("getAuthorDecoration", { name, displayName });
return this.isVisitor || this.isCollaborator
return this.isVisitor || this.isCollaborator || isAnonim
? text(name)
: link(name, onClick);
};

View File

@ -83,7 +83,11 @@ const HistoryBlock = ({
/>
<div className="info">
<div className="title">
<Text className="name">{decode(initiator.displayName)}</Text>
<Text className="name">
{initiator?.isAnonim
? t("Common:Anonymous")
: decode(initiator.displayName)}
</Text>
{initiator.isOwner && (
<Text className="secondary-info">
{t("Common:Owner").toLowerCase()}

View File

@ -1225,14 +1225,15 @@ export default inject(
const sharedItem = navigationPath.find((r) => r.shared);
const showNavigationButton = isLoading
? false
: (!isPublicRoom &&
!isArchive &&
canCopyPublicLink &&
(isPublicRoomType || isCustomRoomType || isFormRoomType) &&
shared) ||
(sharedItem && sharedItem.canCopyPublicLink);
const showNavigationButton =
isLoading || !security?.CopyLink
? false
: (!isPublicRoom &&
!isArchive &&
canCopyPublicLink &&
(isPublicRoomType || isCustomRoomType || isFormRoomType) &&
shared) ||
(sharedItem && sharedItem.canCopyPublicLink);
return {
isGracePeriod,

View File

@ -201,6 +201,7 @@ const PureHome = (props) => {
userId,
scrollToTop,
selectedFolderStore,
});
const { showUploadPanel } = useOperations({

View File

@ -31,7 +31,7 @@ import { useTranslation } from "react-i18next";
import { Box } from "@docspace/shared/components/box";
import { Text } from "@docspace/shared/components/text";
import { Button, ButtonSize } from "@docspace/shared/components/button";
import { Cron } from "@docspace/shared/components/cron";
import { Cron, getNextSynchronization } from "@docspace/shared/components/cron";
import { toastr } from "@docspace/shared/components/toast";
import ProgressContainer from "./ProgressContainer";
@ -50,7 +50,6 @@ const SyncContainer = ({
onChangeCron,
cron,
serverCron,
nextSyncDate,
theme,
isLdapEnabledOnServer,
@ -87,6 +86,10 @@ const SyncContainer = ({
const buttonSize = isDesktop() ? ButtonSize.small : ButtonSize.normal;
const nextSyncDate = React.useMemo(() => {
if (cron) return getNextSynchronization(cron);
}, [cron]);
const renderBody = () => (
<Box className="ldap_sync-container">
{!isMobileView && (
@ -144,7 +147,7 @@ const SyncContainer = ({
/>
</div>
<Text fontSize="12px" fontWeight={600} lineHeight="16px" noSelect>
{`${t("LdapNextSync")}: ${nextSyncDate.toFormat("DDDD tt")} UTC`}
{`${t("LdapNextSync")}: ${nextSyncDate?.toFormat("DDDD tt")} UTC`}
</Text>
<Button
tabIndex={-1}
@ -186,7 +189,6 @@ export default inject(({ currentQuotaStore, settingsStore, ldapStore }) => {
onChangeCron,
cron,
serverCron,
nextSyncDate,
isUIDisabled,
@ -202,7 +204,6 @@ export default inject(({ currentQuotaStore, settingsStore, ldapStore }) => {
onChangeCron,
cron,
serverCron,
nextSyncDate,
theme,
isLdapEnabledOnServer: serverSettings.EnableLdapAuthentication,

View File

@ -1400,7 +1400,8 @@ class ContextOptionsStore {
onClick: () => this.onCopyLink(item, t),
disabled:
(isPublicRoomType && item.canCopyPublicLink && !isArchive) ||
this.publicRoomStore.isPublicRoom,
this.publicRoomStore.isPublicRoom ||
!item.security.CopyLink,
},
{
id: "option_copy-external-link",

View File

@ -380,13 +380,6 @@ class DialogsStore {
this.selectFileFormRoomOpenRoot = openRoot;
};
createFromTemplateForm = (fileInfo) => {
this.createMasterForm(fileInfo, {
extension: "pdf",
withoutDialog: true,
});
};
createMasterForm = async (fileInfo, options) => {
const { extension = "pdf", withoutDialog, preview } = options;

View File

@ -2714,6 +2714,37 @@ class FilesActionStore {
await deleteFilesFromRecent(fileIds);
await refreshFiles();
};
copyFromTemplateForm = async (fileInfo, t) => {
const selectedItemId = this.selectedFolderStore.id;
const fileIds = [fileInfo.id];
const operationData = {
destFolderId: selectedItemId,
folderIds: [],
fileIds,
deleteAfter: false,
isCopy: true,
folderTitle: this.selectedFolderStore.title,
translations: {
copy: t("Common:CopyOperation"),
},
};
this.uploadDataStore.secondaryProgressDataStore.setItemsSelectionTitle(
fileInfo.title,
);
const conflicts = await checkFileConflicts(selectedItemId, [], fileIds);
if (conflicts.length) {
return this.setConflictDialogData(conflicts, operationData);
}
this.uploadDataStore
.itemOperationToFolder(operationData)
.catch((error) => toastr.error(error));
};
}
export default FilesActionStore;

View File

@ -2600,12 +2600,13 @@ class FilesStore {
}
};
createFile = (folderId, title, templateId, formId) => {
createFile = async (folderId, title, templateId, formId) => {
return api.files
.createFile(folderId, title, templateId, formId)
.then((file) => {
return Promise.resolve(file);
});
})
.then(() => this.fetchFiles(folderId, this.filter, true, true, false));
};
createFolder(parentFolderId, title) {

View File

@ -7,7 +7,6 @@ import {
saveCronLdap,
getCronLdap,
} from "@docspace/shared/api/settings";
import { getNextSynchronization } from "@docspace/shared/components/cron";
import { EmployeeType, LDAPOperation } from "@docspace/shared/enums";
import { makeAutoObservable, runInAction } from "mobx";
import isEqual from "lodash/isEqual";
@ -567,10 +566,6 @@ class LdapFormStore {
this.cron = cron;
};
get nextSyncDate() {
return getNextSynchronization(this.cron ?? "* * * * *");
}
setIsSslEnabled = (enabled) => {
this.isSslEnabled = enabled;
};

View File

@ -296,7 +296,8 @@ const Editor = ({
}
if (config?.startFilling) {
newConfig.events.onRequestStartFilling = onSDKRequestStartFilling;
newConfig.events.onRequestStartFilling = () =>
onSDKRequestStartFilling?.(t("Common:StartFilling"));
}
newConfig.events.onSubmit = () => {

View File

@ -125,12 +125,6 @@ const Root = ({
selectFileDialogFileTypeDetection,
selectFileDialogVisible,
} = useSelectFileDialog({ instanceId: instanceId ?? "" });
const {
isSharingDialogVisible,
onCloseSharingDialog,
onSDKRequestSharingSettings,
} = useShareDialog();
const {
getIsDisabledStartFillingSelectDialog,
@ -139,8 +133,16 @@ const Root = ({
onSubmitStartFillingSelectDialog,
onSDKRequestStartFilling,
conflictDataDialog,
headerLabelSFSDialog,
} = useStartFillingSelectDialog(fileInfo);
const {
isSharingDialogVisible,
onCloseSharingDialog,
onSDKRequestSharingSettings,
} = useShareDialog(config, onSDKRequestStartFilling);
useUpdateSearchParamId(fileId, hash);
React.useEffect(() => {
@ -254,11 +256,12 @@ const Root = ({
<StartFillingSelectorDialog
fileInfo={fileInfo}
socketHelper={socketHelper}
filesSettings={filesSettings}
headerLabel={headerLabelSFSDialog}
isVisible={isVisibleStartFillingSelectDialog}
onClose={onCloseStartFillingSelectDialog}
onSubmit={onSubmitStartFillingSelectDialog}
getIsDisabled={getIsDisabledStartFillingSelectDialog}
filesSettings={filesSettings}
/>
)}
{conflictDataDialog.visible && (

View File

@ -40,6 +40,7 @@ function StartFillingSelectorDialog({
onClose,
onSubmit,
filesSettings,
headerLabel,
}: StartFillingSelectorDialogPprops) {
const { t } = useTranslation(["Common", "Editor"]);
@ -67,7 +68,7 @@ function StartFillingSelectorDialog({
filesSettings={filesSettings}
currentDeviceType={DeviceType.desktop}
socketSubscribers={socketHelper.socketSubscribers}
headerLabel={t("Common:StartFilling")}
headerLabel={headerLabel}
submitButtonLabel={t("Common:CopyHere")}
onSubmit={onSubmit}
getIsDisabled={getIsDisabled}

View File

@ -25,13 +25,23 @@
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
import React from "react";
import { useTranslation } from "react-i18next";
const useShareDialog = () => {
import type { IInitialConfig } from "@/types";
const useShareDialog = (
config: IInitialConfig | undefined,
onSDKRequestStartFilling: (headerLabel: string) => void,
) => {
const { t } = useTranslation(["Common"]);
const [isVisible, setIsVisible] = React.useState(false);
const onSDKRequestSharingSettings = React.useCallback(() => {
if (config?.startFilling)
return onSDKRequestStartFilling(t("Common:ShareToFillOut"));
setIsVisible(true);
}, []);
}, [config?.startFilling, onSDKRequestStartFilling, t]);
const onClose = React.useCallback(() => {
setIsVisible(false);
@ -45,4 +55,3 @@ const useShareDialog = () => {
};
export default useShareDialog;

View File

@ -41,7 +41,7 @@ import type { TRoomSecurity } from "@docspace/shared/api/rooms/types";
import type { TBreadCrumb } from "@docspace/shared/components/selector/Selector.types";
import type { TSelectedFileInfo } from "@docspace/shared/selectors/Files/FilesSelector.types";
import type { ConflictStateType } from "@/types";
import { useTranslation } from "react-i18next";
// import { useTranslation } from "react-i18next";
const DefaultConflictDataDialogState: ConflictStateType = {
visible: false,
@ -52,7 +52,8 @@ const DefaultConflictDataDialogState: ConflictStateType = {
};
const useStartFillingSelectDialog = (fileInfo: TFile | undefined) => {
const { t } = useTranslation(["Common"]);
// const { t } = useTranslation(["Common"]);
const [headerLabelSFSDialog, setHeaderLabelSFSDialog] = useState("");
const [isVisible, setIsVisible] = useState(false);
const [conflictDataDialog, setConflictDataDialog] = useState(
@ -61,7 +62,8 @@ const useStartFillingSelectDialog = (fileInfo: TFile | undefined) => {
const requestRunning = useRef(false);
const onSDKRequestStartFilling = useCallback((_: object) => {
const onSDKRequestStartFilling = useCallback((headerLabel: string) => {
setHeaderLabelSFSDialog(headerLabel);
setIsVisible(true);
}, []);
@ -180,6 +182,7 @@ const useStartFillingSelectDialog = (fileInfo: TFile | undefined) => {
getIsDisabledStartFillingSelectDialog: getIsDisabled,
isVisibleStartFillingSelectDialog: isVisible,
conflictDataDialog,
headerLabelSFSDialog,
};
};

View File

@ -233,7 +233,7 @@ export type EditorProps = {
onSDKRequestSelectSpreadsheet?: (event: object) => void;
onSDKRequestSelectDocument?: (event: object) => void;
onSDKRequestReferenceSource?: (event: object) => void;
onSDKRequestStartFilling?: (event: object) => void;
onSDKRequestStartFilling?: (haederLabel: string) => void;
};
export type TEventData = {
@ -405,6 +405,7 @@ export type StartFillingSelectorDialogPprops = {
fileInfo: TFile;
isVisible: boolean;
onClose: VoidFunction;
headerLabel: string;
getIsDisabled: (
isFirstLoad: boolean,

View File

@ -77,7 +77,6 @@ export async function fileCopyAs(
enableExternalExt,
password,
}),
false,
);
const file = await (await fetch(createFile)).json();
@ -139,7 +138,6 @@ export async function createFile(
[["Content-Type", "application/json;charset=utf-8"]],
"POST",
JSON.stringify({ title, templateId, formId }),
false,
);
const file = await (await fetch(createFile)).json();
@ -311,7 +309,6 @@ export async function getUser(share?: string) {
[share ? ["Request-Token", share] : ["", ""]],
"GET",
undefined,
false,
);
if (!cookie?.includes("asc_auth_key")) return undefined;
@ -337,7 +334,6 @@ export async function getSettings(share?: string) {
[share ? ["Request-Token", share] : ["", ""]],
"GET",
undefined,
false,
);
const settingsRes = await fetch(getSettings);
@ -363,7 +359,6 @@ export async function checkFillFromDraft(
],
"POST",
JSON.stringify({ fileId: templateFileId }),
false,
);
const response = await fetch(checkFillFormDraft);
@ -389,7 +384,6 @@ export async function openEdit(
[share ? ["Request-Token", share] : ["", ""]],
"GET",
undefined,
false,
);
const res = await fetch(getConfig);
@ -452,7 +446,6 @@ export async function getEditorUrl(
[share ? ["Request-Token", share] : ["", ""]],
"GET",
undefined,
false,
);
const res = await fetch(request);

View File

@ -474,12 +474,12 @@ export const enum ErrorKeys {
}
export enum RoomsType {
PublicRoom = 6,
FormRoom = 1,
// FillingFormsRoom= 1, //TODO: Restore when certs will be done
EditingRoom = 2,
// ReviewRoom: 3, //TODO: Restore when certs will be done
// ReadOnlyRoom: 4, //TODO: Restore when certs will be done
PublicRoom = 6,
CustomRoom = 5,
}

View File

@ -24,7 +24,7 @@
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
import { headers } from "next/headers";
import { headers, cookies } from "next/headers";
const API_PREFIX = "api/2.0";
@ -39,12 +39,8 @@ export const getBaseUrl = () => {
return baseURL;
};
export const getAPIUrl = (internalRequest: boolean) => {
const baseUrl = internalRequest
? process.env.API_HOST?.trim() ?? getBaseUrl()
: getBaseUrl();
// const baseUrl = getBaseUrl();
export const getAPIUrl = () => {
const baseUrl = process.env.API_HOST?.trim() ?? getBaseUrl();
const baseAPIUrl = `${baseUrl}/${API_PREFIX}`;
@ -56,11 +52,11 @@ export const createRequest = (
newHeaders: [string, string][],
method: string,
body?: string,
internalRequest: boolean = true,
) => {
const hdrs = new Headers(headers());
const cookieStore = cookies();
const apiURL = getAPIUrl(internalRequest);
const apiURL = getAPIUrl();
newHeaders.forEach((hdr) => {
if (hdr[0]) hdrs.set(hdr[0], hdr[1]);
@ -70,6 +66,10 @@ export const createRequest = (
if (baseURL && process.env.API_HOST?.trim()) hdrs.set("origin", baseURL);
const authToken = cookieStore.get("asc_auth_key")?.value;
if (authToken) hdrs.set("Authorization", authToken);
const urls = paths.map((path) => `${apiURL}${path}`);
const requests = urls.map(

View File

@ -14,6 +14,7 @@
"AddUsers": "Add users",
"AdvancedFilter": "Search options",
"Alert": "Alert",
"Anonymous": "Anonymous",
"AnyoneWithLink": "Anyone with the link",
"ApplyButton": "Apply",
"Archive": "Archive",
@ -52,6 +53,10 @@
"CommonFiles": "Common files",
"CompanyName": "Company name",
"Confirmation": "Confirmation",
"ConflictResolveDescription": "The file with the name <1>{{file}}</1> already exists in the folder <1>{{folder}}</1>.",
"ConflictResolveDescriptionFiles": "{{filesCount}} documents with the same name already exist in the folder <1>{{folder}}</1>.",
"ConflictResolveSelectAction": "Please select the action:",
"ConflictResolveTitle": "Overwrite confirmation",
"Connect": "Connect",
"Content": "Content",
"Context": "Context",
@ -65,6 +70,7 @@
"Create": "Create",
"CreateAndCopy": "Create and copy",
"CreateCopy": "Create copy",
"CreateDescription": "There will be two different files in the folder.",
"CreateFileCopy": "Create file copy",
"CreateMasterFormFromFile": "Create Form Template from file",
"CreatePDFForm": "Create PDF Form",
@ -176,13 +182,13 @@
"ExpiredLink": "Expired link",
"FeedbackAndSupport": "Feedback & Support",
"Fill": "Fill out",
"FillFormButton": "Fill in the form",
"FillFormButton": "Fill",
"FillingFormRooms": "Filling form",
"FillingFormsRoomDescription": "Build, share and fill document templates or work with the ready presets to quickly create documents of any type.",
"FillingFormsRoomTitle": "Filling forms room",
"Finish": "Finish",
"FirstName": "First name",
"FormFilingRoomDescription": "Invite users to fill out a ready PDF form. Check the complete forms and analyze data automatically collected in a spreadsheet.",
"FormFilingRoomDescription": "Upload PDF forms into the room. Invite users to fill out a PDF form. Review completed forms and analyze data automatically collected in a spreadsheet.",
"FormFilingRoomTitle": "Form Filling Room",
"FormRoom": "Form room",
"Free": "Free",
@ -270,8 +276,8 @@
"Name": "Name",
"NeedPassword": "You need a password to access the room",
"NewDocument": "New document",
"NewFolder": "New folder",
"NewFillingFormRoom": "New Filling form room",
"NewFolder": "New folder",
"NewMasterForm": "New form template",
"NewPresentation": "New presentation",
"NewRoom": "New room",
@ -293,6 +299,8 @@
"orContinueWith": "or continue with",
"OtherLabel": "Other",
"OtherOperations": "Other operations",
"OverwriteDescription": "The new file will replace the existing one as a new version.",
"OverwriteTitle": "Overwrite with version update",
"Owner": "Owner",
"PageOfTotalPage": "{{page}} of {{totalPage}}",
"Pages": "Pages",
@ -328,8 +336,6 @@
"ProviderSsoSetting": "Single sign-on",
"ProviderTwitter": "Twitter",
"ProviderZoom": "Zoom",
"PublicRoom": "Public room",
"PublicRoomDescription": "Invite users via external links to view documents without registration. You can also embed this room into any web interface.",
"PublicLink": "Public link",
"PublicRoom": "Public room",
"PublicRoomDescription": "Invite users via external links to view documents without registration. You can also embed this room into any web interface.",
@ -399,6 +405,7 @@
"ShareDocument": "Share this document",
"ShareDocumentDescription": "Provide access to the document and set the permission levels.",
"SharedWithMe": "Shared with me",
"ShareToFillOut": "Share to fill out",
"ShareVia": "Share via",
"ShowMore": "Show more",
"SignInWithApple": "Sign in with Apple",
@ -419,6 +426,8 @@
"SignUpWithZoom": "Sign up with Zoom",
"Size": "Size",
"SizeImageLarge": "The image size is too large, please select another image.",
"SkipDescription": "No file will be copied. The original file will be retained in the destination folder.",
"SkipTitle": "Skip",
"SomethingWentWrong": "Something went wrong.",
"SortBy": "Sort by",
"SpaceManagement": "Space Management",
@ -477,14 +486,5 @@
"Website": "Website",
"Yes": "Yes",
"Yesterday": "Yesterday",
"You": "You",
"ConflictResolveDescription": "The file with the name <1>{{file}}</1> already exists in the folder <1>{{folder}}</1>.",
"ConflictResolveDescriptionFiles": "{{filesCount}} documents with the same name already exist in the folder <1>{{folder}}</1>.",
"ConflictResolveSelectAction": "Please select the action:",
"ConflictResolveTitle": "Overwrite confirmation",
"CreateDescription": "There will be two different files in the folder.",
"OverwriteDescription": "The new file will replace the existing one as a new version.",
"OverwriteTitle": "Overwrite with version update",
"SkipDescription": "No file will be copied. The original file will be retained in the destination folder.",
"SkipTitle": "Skip"
"You": "You"
}