Merge branch 'develop' into feature/update-react-router-dom
This commit is contained in:
commit
c4f611289e
@ -44,9 +44,6 @@ import { ComboBox, TOption } from "@docspace/shared/components/combobox";
|
||||
import { TData } from "@docspace/shared/components/toast/Toast.type";
|
||||
import { TTranslation } from "@docspace/shared/types";
|
||||
import { TColorScheme, TTheme } from "@docspace/shared/themes";
|
||||
|
||||
import { SettingsStore } from "@docspace/shared/store/SettingsStore";
|
||||
import { UserStore } from "@docspace/shared/store/UserStore";
|
||||
import {
|
||||
ModalDialog,
|
||||
ModalDialogType,
|
||||
@ -65,8 +62,6 @@ import { StyledModalDialog, StyledBody } from "./StyledEmbeddingPanel";
|
||||
|
||||
import { DisplayBlock } from "./sub-components/DisplayBlock";
|
||||
import { CheckboxElement } from "./sub-components/CheckboxElement";
|
||||
import PublicRoomStore from "../../../store/PublicRoomStore";
|
||||
import DialogsStore from "../../../store/DialogsStore";
|
||||
|
||||
type LinkParamsLinkShareToType = {
|
||||
denyDownload: boolean;
|
||||
|
@ -29,7 +29,7 @@ import { inject, observer } from "mobx-react";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
|
||||
import { RoomsType, ShareAccessRights } from "@docspace/shared/enums";
|
||||
import { RoomsType } from "@docspace/shared/enums";
|
||||
import { LINKS_LIMIT_COUNT } from "@docspace/shared/constants";
|
||||
import InfoPanelViewLoader from "@docspace/shared/skeletons/info-panel/body";
|
||||
import MembersHelper from "../../helpers/MembersHelper";
|
||||
@ -182,6 +182,8 @@ const Members = ({
|
||||
key="general-link"
|
||||
link={primaryLink}
|
||||
setIsScrollLocked={setIsScrollLocked}
|
||||
isShareLink
|
||||
isPrimaryLink
|
||||
/>,
|
||||
);
|
||||
}
|
||||
@ -193,6 +195,7 @@ const Members = ({
|
||||
link={link}
|
||||
key={link?.sharedTo?.id}
|
||||
setIsScrollLocked={setIsScrollLocked}
|
||||
isShareLink
|
||||
/>,
|
||||
);
|
||||
});
|
||||
@ -202,6 +205,7 @@ const Members = ({
|
||||
key="create-additional-link"
|
||||
className="additional-link"
|
||||
onClick={onAddNewLink}
|
||||
isShareLink
|
||||
>
|
||||
<div className="create-link-icon">
|
||||
<IconButton size={12} iconName={PlusIcon} isDisabled />
|
||||
|
@ -24,70 +24,77 @@
|
||||
// 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 React, { useState } from "react";
|
||||
import { observer, inject } from "mobx-react";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import copy from "copy-to-clipboard";
|
||||
import { Avatar } from "@docspace/shared/components/avatar";
|
||||
import { Link } from "@docspace/shared/components/link";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import { IconButton } from "@docspace/shared/components/icon-button";
|
||||
import { ContextMenuButton } from "@docspace/shared/components/context-menu-button";
|
||||
import moment from "moment";
|
||||
import LinkRowComponent from "@docspace/shared/components/share/sub-components/LinkRow";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
import CopyReactSvgUrl from "PUBLIC_DIR/images/copy.react.svg?url";
|
||||
import LinkReactSvgUrl from "PUBLIC_DIR/images/tablet-link.react.svg?url";
|
||||
import SettingsReactSvgUrl from "PUBLIC_DIR/images/catalog.settings.react.svg?url";
|
||||
import ShareReactSvgUrl from "PUBLIC_DIR/images/share.react.svg?url";
|
||||
import CodeReactSvgUrl from "PUBLIC_DIR/images/code.react.svg?url";
|
||||
import CopyToReactSvgUrl from "PUBLIC_DIR/images/copyTo.react.svg?url";
|
||||
import OutlineReactSvgUrl from "PUBLIC_DIR/images/outline-true.react.svg?url";
|
||||
import LockedReactSvgUrl from "PUBLIC_DIR/images/locked.react.svg?url";
|
||||
import LoadedReactSvgUrl from "PUBLIC_DIR/images/loaded.react.svg?url";
|
||||
import TrashReactSvgUrl from "PUBLIC_DIR/images/trash.react.svg?url";
|
||||
import ClockReactSvg from "PUBLIC_DIR/images/clock.react.svg";
|
||||
import moment from "moment-timezone";
|
||||
import { RoomsType } from "@docspace/shared/enums";
|
||||
import { TTranslation } from "@docspace/shared/types";
|
||||
import { TFileLink } from "@docspace/shared/api/files/types";
|
||||
import { useState } from "react";
|
||||
import { TOption } from "@docspace/shared/components/combobox";
|
||||
|
||||
import { StyledLinkRow } from "./Styled";
|
||||
type LinkRowProps = {
|
||||
t: TTranslation;
|
||||
link: TFileLink;
|
||||
roomId: string | number;
|
||||
setLinkParams: (linkParams: {
|
||||
roomId: number | string;
|
||||
isEdit?: boolean;
|
||||
link: TFileLink;
|
||||
isPublic?: boolean;
|
||||
isFormRoom?: boolean;
|
||||
}) => void;
|
||||
setEditLinkPanelIsVisible: (value: boolean) => void;
|
||||
setDeleteLinkDialogVisible: (value: boolean) => void;
|
||||
setEmbeddingPanelData: (value: {
|
||||
visible: boolean;
|
||||
itemId?: string | number;
|
||||
}) => void;
|
||||
|
||||
const LinkRow = (props) => {
|
||||
isArchiveFolder: boolean;
|
||||
setIsScrollLocked: (isScrollLocked: boolean) => void;
|
||||
isPublicRoomType: boolean;
|
||||
isFormRoom: boolean;
|
||||
isPrimaryLink: boolean;
|
||||
};
|
||||
|
||||
const LinkRow = (props: LinkRowProps) => {
|
||||
const {
|
||||
t,
|
||||
link,
|
||||
roomId,
|
||||
setLinkParams,
|
||||
setExternalLink,
|
||||
editExternalLink,
|
||||
setEditLinkPanelIsVisible,
|
||||
setDeleteLinkDialogVisible,
|
||||
setEmbeddingPanelData,
|
||||
isArchiveFolder,
|
||||
theme,
|
||||
setIsScrollLocked,
|
||||
isPublicRoomType,
|
||||
isFormRoom,
|
||||
...rest
|
||||
isPrimaryLink,
|
||||
editExternalLink,
|
||||
setExternalLink,
|
||||
} = props;
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const {
|
||||
title,
|
||||
shareLink,
|
||||
password,
|
||||
disabled,
|
||||
expirationDate,
|
||||
isExpired,
|
||||
primary,
|
||||
} = link.sharedTo;
|
||||
const { shareLink, password, isExpired, primary } = link.sharedTo;
|
||||
|
||||
const isLocked = !!password;
|
||||
const expiryDate = !!expirationDate;
|
||||
const date = moment(expirationDate).tz(window.timezone).format("LLL");
|
||||
const isDisabled = isExpired;
|
||||
|
||||
const tooltipContent = isExpired
|
||||
? t("Translations:LinkHasExpiredAndHasBeenDisabled")
|
||||
: t("Translations:PublicRoomLinkValidTime", { date });
|
||||
const [loadingLinks, setLoadingLinks] = useState<(string | number)[]>([]);
|
||||
|
||||
const onCloseContextMenu = () => {
|
||||
setIsScrollLocked(false);
|
||||
};
|
||||
|
||||
const onEditLink = () => {
|
||||
setEditLinkPanelIsVisible(true);
|
||||
@ -101,33 +108,11 @@ const LinkRow = (props) => {
|
||||
onCloseContextMenu();
|
||||
};
|
||||
|
||||
// const onDisableLink = () => {
|
||||
// if (isExpired) {
|
||||
// setEditLinkPanelIsVisible(true);
|
||||
// setLinkParams({ isEdit: true, link, roomId, isPublic: isPublicRoomType, isFormRoom });
|
||||
// return;
|
||||
// }
|
||||
|
||||
// setIsLoading(true);
|
||||
|
||||
// const newLink = JSON.parse(JSON.stringify(link));
|
||||
// newLink.sharedTo.disabled = !newLink.sharedTo.disabled;
|
||||
|
||||
// editExternalLink(roomId, newLink)
|
||||
// .then((link) => {
|
||||
// setExternalLink(link);
|
||||
|
||||
// disabled
|
||||
// ? toastr.success(t("Files:LinkEnabledSuccessfully"))
|
||||
// : toastr.success(t("Files:LinkDisabledSuccessfully"));
|
||||
// })
|
||||
// .catch((err) => toastr.error(err?.message))
|
||||
// .finally(() => setIsLoading(false));
|
||||
// };
|
||||
|
||||
const onCopyPassword = () => {
|
||||
copy(password);
|
||||
toastr.success(t("Files:PasswordSuccessfullyCopied"));
|
||||
if (password) {
|
||||
copy(password);
|
||||
toastr.success(t("Files:PasswordSuccessfullyCopied"));
|
||||
}
|
||||
};
|
||||
|
||||
const onEmbeddingClick = () => {
|
||||
@ -152,12 +137,6 @@ const LinkRow = (props) => {
|
||||
setIsScrollLocked(true);
|
||||
};
|
||||
|
||||
const onCloseContextMenu = () => {
|
||||
setIsScrollLocked(false);
|
||||
};
|
||||
|
||||
const isDisabled = disabled || isExpired;
|
||||
|
||||
const getData = () => {
|
||||
return [
|
||||
{
|
||||
@ -166,17 +145,6 @@ const LinkRow = (props) => {
|
||||
icon: SettingsReactSvgUrl,
|
||||
onClick: onEditLink,
|
||||
},
|
||||
// {
|
||||
// key: "edit-link-separator",
|
||||
// isSeparator: true,
|
||||
// },
|
||||
// {
|
||||
// key: "share-key",
|
||||
// label: t("Files:Share"),
|
||||
// icon: ShareReactSvgUrl,
|
||||
// // onClick: () => args.onClickLabel("label2"),
|
||||
// },
|
||||
|
||||
!isDisabled && {
|
||||
key: "copy-link-settings-key",
|
||||
label: t("Files:CopySharedLink"),
|
||||
@ -184,27 +152,21 @@ const LinkRow = (props) => {
|
||||
onClick: onCopyExternalLink,
|
||||
},
|
||||
|
||||
!isDisabled &&
|
||||
isLocked && {
|
||||
key: "copy-link-password-key",
|
||||
label: t("Files:CopyLinkPassword"),
|
||||
icon: LockedReactSvgUrl,
|
||||
onClick: onCopyPassword,
|
||||
},
|
||||
|
||||
!isDisabled && {
|
||||
key: "embedding-settings-key",
|
||||
label: t("Files:EmbeddingSettings"),
|
||||
label: t("Files:Embed"),
|
||||
icon: CodeReactSvgUrl,
|
||||
onClick: onEmbeddingClick,
|
||||
},
|
||||
|
||||
// disabled
|
||||
// ? {
|
||||
// key: "enable-link-key",
|
||||
// label: t("Files:EnableLink"),
|
||||
// icon: LoadedReactSvgUrl,
|
||||
// onClick: onDisableLink,
|
||||
// }
|
||||
// : {
|
||||
// key: "disable-link-key",
|
||||
// label: t("Files:DisableLink"),
|
||||
// icon: OutlineReactSvgUrl,
|
||||
// onClick: onDisableLink,
|
||||
// },
|
||||
|
||||
{
|
||||
key: "delete-link-separator",
|
||||
isSeparator: true,
|
||||
@ -222,91 +184,66 @@ const LinkRow = (props) => {
|
||||
];
|
||||
};
|
||||
|
||||
const textColor = disabled ? theme.text.disableColor : theme.text.color;
|
||||
const editExternalLinkAction = (newLink: TFileLink) => {
|
||||
setLoadingLinks([newLink.sharedTo.id]);
|
||||
|
||||
editExternalLink(roomId, newLink)
|
||||
.then((linkData: TFileLink) => {
|
||||
setExternalLink(linkData);
|
||||
setLinkParams({
|
||||
link: linkData,
|
||||
roomId,
|
||||
isPublic: isPublicRoomType,
|
||||
isFormRoom,
|
||||
});
|
||||
|
||||
copy(link?.sharedTo?.shareLink);
|
||||
toastr.success(t("Files:LinkEditedSuccessfully"));
|
||||
})
|
||||
.catch((err: Error) => toastr.error(err?.message))
|
||||
.finally(() => setLoadingLinks([]));
|
||||
};
|
||||
|
||||
const onAccessRightsSelect = (opt: TOption) => {
|
||||
const newLink = { ...link };
|
||||
if (opt.access) newLink.access = opt.access;
|
||||
editExternalLinkAction(newLink);
|
||||
};
|
||||
|
||||
const changeExpirationOption = async (
|
||||
linkData: TFileLink,
|
||||
expirationDate: moment.Moment | null,
|
||||
) => {
|
||||
const newLink = { ...link };
|
||||
newLink.sharedTo.expirationDate = expirationDate
|
||||
? moment(expirationDate)
|
||||
: null;
|
||||
editExternalLinkAction(newLink);
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledLinkRow
|
||||
{...rest}
|
||||
<LinkRowComponent
|
||||
loadingLinks={loadingLinks}
|
||||
links={[link]}
|
||||
getData={getData}
|
||||
onOpenContextMenu={onOpenContextMenu}
|
||||
onCloseContextMenu={onCloseContextMenu}
|
||||
isRoomsLink
|
||||
isPrimaryLink={isPrimaryLink}
|
||||
onAccessRightsSelect={onAccessRightsSelect}
|
||||
changeExpirationOption={changeExpirationOption}
|
||||
isArchiveFolder={isArchiveFolder}
|
||||
isExpired={isExpired}
|
||||
>
|
||||
<Avatar
|
||||
size="min"
|
||||
source={LinkReactSvgUrl}
|
||||
roleIcon={
|
||||
expiryDate ? (
|
||||
<div className="clock-icon">
|
||||
<ClockReactSvg />
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
withTooltip={expiryDate}
|
||||
tooltipContent={tooltipContent}
|
||||
/>
|
||||
{isArchiveFolder ? (
|
||||
<Text fontSize="14px" fontWeight={600} className="external-row-link">
|
||||
{title}
|
||||
</Text>
|
||||
) : (
|
||||
<Link
|
||||
type="action"
|
||||
fontSize="14px"
|
||||
fontWeight={600}
|
||||
onClick={onEditLink}
|
||||
isDisabled={disabled}
|
||||
color={textColor}
|
||||
className="external-row-link"
|
||||
>
|
||||
{title}
|
||||
</Link>
|
||||
)}
|
||||
|
||||
{disabled && <Text color={textColor}>{t("Settings:Disabled")}</Text>}
|
||||
|
||||
<div className="external-row-icons">
|
||||
{!disabled && !isExpired && !isArchiveFolder && (
|
||||
<>
|
||||
{isLocked && (
|
||||
<IconButton
|
||||
className="locked-icon"
|
||||
size={16}
|
||||
iconName={LockedReactSvgUrl}
|
||||
onClick={onCopyPassword}
|
||||
title={t("Files:CopyLinkPassword")}
|
||||
/>
|
||||
)}
|
||||
<IconButton
|
||||
className="copy-icon"
|
||||
size={16}
|
||||
iconName={CopyReactSvgUrl}
|
||||
onClick={onCopyExternalLink}
|
||||
title={t("Files:CopySharedLink")}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
{!isArchiveFolder && (
|
||||
<ContextMenuButton
|
||||
getData={getData}
|
||||
isDisabled={isLoading}
|
||||
title={t("Files:ShowLinkActions")}
|
||||
directionY="both"
|
||||
onClick={onOpenContextMenu}
|
||||
onClose={onCloseContextMenu}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</StyledLinkRow>
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(
|
||||
export default inject<TStore>(
|
||||
({
|
||||
settingsStore,
|
||||
dialogsStore,
|
||||
publicRoomStore,
|
||||
treeFoldersStore,
|
||||
infoPanelStore,
|
||||
publicRoomStore,
|
||||
}) => {
|
||||
const { infoPanelSelection } = infoPanelStore;
|
||||
const { theme } = settingsStore;
|
||||
@ -317,23 +254,25 @@ export default inject(
|
||||
setEmbeddingPanelData,
|
||||
setLinkParams,
|
||||
} = dialogsStore;
|
||||
const { editExternalLink, setExternalLink } = publicRoomStore;
|
||||
const { isArchiveFolderRoot } = treeFoldersStore;
|
||||
|
||||
const { id, roomType } = infoPanelSelection!;
|
||||
|
||||
const { editExternalLink, setExternalLink } = publicRoomStore;
|
||||
|
||||
return {
|
||||
setLinkParams,
|
||||
editExternalLink,
|
||||
roomId: infoPanelSelection.id,
|
||||
setExternalLink,
|
||||
roomId: id,
|
||||
setEditLinkPanelIsVisible,
|
||||
setDeleteLinkDialogVisible,
|
||||
setEmbeddingPanelData,
|
||||
isArchiveFolder: isArchiveFolderRoot,
|
||||
theme,
|
||||
isPublicRoomType:
|
||||
infoPanelSelection.roomType === RoomsType.PublicRoom ||
|
||||
infoPanelSelection.roomType === RoomsType.FormRoom,
|
||||
isFormRoom: infoPanelSelection?.roomType === RoomsType.FormRoom,
|
||||
roomType === RoomsType.PublicRoom || roomType === RoomsType.FormRoom,
|
||||
isFormRoom: roomType === RoomsType.FormRoom,
|
||||
editExternalLink,
|
||||
setExternalLink,
|
||||
};
|
||||
},
|
||||
)(
|
@ -78,6 +78,7 @@ const StyledList = styled(List)`
|
||||
`;
|
||||
|
||||
const itemSize = 48;
|
||||
const shareLinkItemSize = 68;
|
||||
|
||||
const MembersList = (props) => {
|
||||
const {
|
||||
@ -151,6 +152,16 @@ const MembersList = (props) => {
|
||||
[isNextPageLoading, loadNextPage],
|
||||
);
|
||||
|
||||
const getItemSize = ({ index }) => {
|
||||
const elem = list[index];
|
||||
|
||||
if (elem?.props?.isShareLink) {
|
||||
return shareLinkItemSize;
|
||||
}
|
||||
|
||||
return itemSize;
|
||||
};
|
||||
|
||||
const onScroll = (e) => {
|
||||
const header = document.getElementById("members-list-header");
|
||||
|
||||
@ -221,7 +232,7 @@ const MembersList = (props) => {
|
||||
onRowsRendered={onRowsRendered}
|
||||
ref={registerChild}
|
||||
rowCount={itemsCount}
|
||||
rowHeight={itemSize}
|
||||
rowHeight={getItemSize}
|
||||
rowRenderer={renderRow}
|
||||
width={width}
|
||||
isScrolling={isScrolling}
|
||||
|
@ -78,7 +78,6 @@ class InfoPanelStore {
|
||||
|
||||
infoPanelSelection = null;
|
||||
selectionHistory = null;
|
||||
selectionHistory = null;
|
||||
|
||||
roomsView = infoMembers;
|
||||
fileView = infoHistory;
|
||||
@ -94,7 +93,6 @@ class InfoPanelStore {
|
||||
publicRoomStore = null;
|
||||
|
||||
infoPanelMembers = null;
|
||||
infoPanelSelection = null;
|
||||
infoPanelRoom = null;
|
||||
membersIsLoading = false;
|
||||
isMembersPanelUpdating = false;
|
||||
|
@ -24,6 +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 moment from "moment";
|
||||
import { TCreatedBy, TPathParts } from "../../types";
|
||||
import { TUser } from "../people/types";
|
||||
import {
|
||||
@ -395,9 +396,11 @@ export type TFileLink = {
|
||||
requestToken: string;
|
||||
shareLink: string;
|
||||
title: string;
|
||||
expirationDate?: string;
|
||||
expirationDate?: moment.Moment | null;
|
||||
internal?: boolean;
|
||||
password?: string;
|
||||
};
|
||||
subjectType: number;
|
||||
};
|
||||
|
||||
export type TFilesUsedSpace = {
|
||||
|
@ -27,7 +27,8 @@
|
||||
/* eslint-disable @typescript-eslint/default-param-last */
|
||||
import { AxiosRequestConfig } from "axios";
|
||||
|
||||
import { FolderType, MembersSubjectType } from "../../enums";
|
||||
import moment from "moment";
|
||||
import { FolderType, MembersSubjectType, ShareAccessRights } from "../../enums";
|
||||
import { request } from "../client";
|
||||
import {
|
||||
checkFilterInstance,
|
||||
@ -397,15 +398,15 @@ export const acceptInvitationByLink = async () => {
|
||||
};
|
||||
|
||||
export function editExternalLink(
|
||||
roomId,
|
||||
linkId,
|
||||
title,
|
||||
access,
|
||||
expirationDate,
|
||||
linkType,
|
||||
password,
|
||||
disabled,
|
||||
denyDownload,
|
||||
roomId: number | string,
|
||||
linkId: number | string,
|
||||
title: string,
|
||||
access: ShareAccessRights,
|
||||
expirationDate: moment.Moment,
|
||||
linkType: number,
|
||||
password: string,
|
||||
disabled: boolean,
|
||||
denyDownload: boolean,
|
||||
) {
|
||||
const skipRedirect = true;
|
||||
|
||||
|
@ -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 styled from "styled-components";
|
||||
import styled, { css } from "styled-components";
|
||||
|
||||
import { Base } from "../../themes";
|
||||
import { mobile } from "../../utils";
|
||||
@ -36,6 +36,25 @@ const StyledWrapper = styled(ComboBox)`
|
||||
padding-inline: 8px;
|
||||
}
|
||||
|
||||
${({ type, theme }) =>
|
||||
type === "onlyIcon" &&
|
||||
css`
|
||||
.combo-button {
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
.combo-button_selected-icon-container {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.combo-buttons_arrow-icon,
|
||||
.combo-button_selected-icon-container {
|
||||
svg path {
|
||||
fill: ${theme.iconButton.color};
|
||||
}
|
||||
}
|
||||
`}
|
||||
|
||||
@media ${mobile} {
|
||||
.backdrop-active {
|
||||
top: -64px;
|
||||
@ -77,8 +96,16 @@ const StyledItemDescription = styled.div`
|
||||
|
||||
StyledItemDescription.defaultProps = { theme: Base };
|
||||
|
||||
const StyledItemIcon = styled.img`
|
||||
const StyledItemIcon = styled.img<{ isShortenIcon?: boolean }>`
|
||||
margin-inline-end: 8px;
|
||||
|
||||
${({ isShortenIcon }) =>
|
||||
isShortenIcon &&
|
||||
css`
|
||||
padding-top: 2px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
`}
|
||||
`;
|
||||
|
||||
const StyledItemContent = styled.div`
|
||||
|
@ -46,6 +46,7 @@ export const AccessRightSelectPure = ({
|
||||
advancedOptions,
|
||||
selectedOption,
|
||||
className,
|
||||
type,
|
||||
...props
|
||||
}: AccessRightSelectProps) => {
|
||||
const [currentItem, setCurrentItem] = useState(selectedOption);
|
||||
@ -76,7 +77,12 @@ export const AccessRightSelectPure = ({
|
||||
onClick={() => onSelectCurrentItem(item)}
|
||||
>
|
||||
<StyledItem>
|
||||
{item.icon && <StyledItemIcon src={item.icon} />}
|
||||
{item.icon && (
|
||||
<StyledItemIcon
|
||||
src={item.icon}
|
||||
isShortenIcon={type === "onlyIcon"}
|
||||
/>
|
||||
)}
|
||||
<StyledItemContent>
|
||||
<StyledItemTitle>
|
||||
{item.label}
|
||||
@ -108,6 +114,7 @@ export const AccessRightSelectPure = ({
|
||||
return (
|
||||
<StyledWrapper
|
||||
className={className}
|
||||
type={type}
|
||||
advancedOptions={formattedOptions}
|
||||
onSelect={onSelectCurrentItem}
|
||||
options={[]}
|
||||
@ -116,7 +123,7 @@ export const AccessRightSelectPure = ({
|
||||
icon: currentItem?.icon,
|
||||
default: true,
|
||||
key: currentItem?.key,
|
||||
label: currentItem?.label,
|
||||
label: type === "onlyIcon" ? "" : currentItem?.label,
|
||||
} as TOption
|
||||
}
|
||||
forceCloseClickOutside
|
||||
|
@ -44,6 +44,9 @@ type PropsFromCombobox = Pick<
|
||||
| "withoutBackground"
|
||||
| "withBackground"
|
||||
| "withBlur"
|
||||
| "type"
|
||||
| "noBorder"
|
||||
| "isDisabled"
|
||||
>;
|
||||
|
||||
export type AccessRightSelectProps = PropsFromCombobox & {
|
||||
|
@ -77,7 +77,7 @@ export interface ContextMenuButtonProps {
|
||||
/** Sets the number of columns */
|
||||
columnCount?: number;
|
||||
/** Sets the display type */
|
||||
displayType: ContextMenuButtonDisplayType;
|
||||
displayType?: ContextMenuButtonDisplayType;
|
||||
/** Closing event */
|
||||
onClose?: () => void;
|
||||
/** Sets the drop down open with the portal */
|
||||
|
@ -116,6 +116,39 @@ export const getAccessOptions = (
|
||||
return items;
|
||||
};
|
||||
|
||||
export const getRoomAccessOptions = (t: TTranslation) => {
|
||||
return [
|
||||
{
|
||||
access: ShareAccessRights.Editing,
|
||||
description: t("Translations:RoleEditorDescription"),
|
||||
key: "editing",
|
||||
label: t("Common:Editor"),
|
||||
icon: AccessEditReactSvgUrl,
|
||||
},
|
||||
{
|
||||
access: ShareAccessRights.Review,
|
||||
description: t("Translations:RoleReviewerDescription"),
|
||||
key: "review",
|
||||
label: t("Translations:RoleReviewer"),
|
||||
icon: AccessReviewReactSvgUrl,
|
||||
},
|
||||
{
|
||||
access: ShareAccessRights.Comment,
|
||||
description: t("Translations:RoleCommentatorDescription"),
|
||||
key: "commenting",
|
||||
label: t("Commentator"),
|
||||
icon: AccessCommentReactSvgUrl,
|
||||
},
|
||||
{
|
||||
access: ShareAccessRights.ReadOnly,
|
||||
description: t("Translations:RoleViewerDescription"),
|
||||
key: "viewing",
|
||||
label: t("JavascriptSdk:Viewer"),
|
||||
icon: EyeReactSvgUrl,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
export const getExpiredOptions = (
|
||||
t: TTranslation,
|
||||
setTwelveHours: VoidFunction,
|
||||
|
@ -24,7 +24,8 @@
|
||||
// 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 styled from "styled-components";
|
||||
import styled, { css } from "styled-components";
|
||||
import { DropDown } from "../drop-down";
|
||||
|
||||
const StyledLinks = styled.div`
|
||||
margin-top: 20px;
|
||||
@ -49,11 +50,30 @@ const StyledLinks = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledLinkRow = styled.div`
|
||||
padding: 8px 0;
|
||||
const StyledLinkRow = styled.div<{ isExpired?: boolean; isDisabled?: boolean }>`
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
height: 68px;
|
||||
|
||||
opacity: ${({ isDisabled }) => (isDisabled ? 0.4 : 1)};
|
||||
|
||||
.avatar-wrapper,
|
||||
.avatar-wrapper:hover {
|
||||
svg {
|
||||
path {
|
||||
fill: ${({ theme }) => theme.infoPanel.avatarColor};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.avatar_role-wrapper {
|
||||
svg {
|
||||
path:nth-child(3) {
|
||||
fill: ${({ theme }) => theme.backgroundColor};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.combo-box {
|
||||
padding: 0;
|
||||
@ -67,23 +87,41 @@ const StyledLinkRow = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.internal-combobox {
|
||||
padding: 0px;
|
||||
|
||||
.combo-button-label {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.internal-combobox_expiered {
|
||||
.link-options_title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 16px;
|
||||
margin: 6px 8px;
|
||||
color: ${({ theme }) => theme.infoPanel.members.linkAccessComboboxExpired};
|
||||
|
||||
${({ theme, isExpired }) =>
|
||||
isExpired &&
|
||||
css`
|
||||
color: ${theme.infoPanel.members.linkAccessComboboxExpired};
|
||||
`};
|
||||
}
|
||||
|
||||
.expired-options {
|
||||
padding: 0px;
|
||||
|
||||
.text {
|
||||
color: ${({ theme }) => theme.infoPanel.links.color};
|
||||
:hover {
|
||||
color: ${({ theme }) => theme.infoPanel.links.color};
|
||||
background: unset;
|
||||
}
|
||||
}
|
||||
|
||||
& > span > a {
|
||||
padding: 0px !important;
|
||||
}
|
||||
@ -91,6 +129,7 @@ const StyledLinkRow = styled.div`
|
||||
|
||||
.expire-text {
|
||||
margin-inline-start: 8px;
|
||||
color: ${({ theme }) => theme.infoPanel.links.primaryColor};
|
||||
}
|
||||
|
||||
.link-actions {
|
||||
@ -98,6 +137,11 @@ const StyledLinkRow = styled.div`
|
||||
gap: 16px;
|
||||
align-items: center;
|
||||
margin-inline-start: auto;
|
||||
|
||||
.link-row_copy-icon {
|
||||
min-width: 16px;
|
||||
min-height: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.loader {
|
||||
@ -131,4 +175,10 @@ const StyledSquare = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
export { StyledLinks, StyledLinkRow, StyledSquare };
|
||||
const StyledDropDown = styled(DropDown)`
|
||||
.share-link_calendar {
|
||||
position: fixed;
|
||||
}
|
||||
`;
|
||||
|
||||
export { StyledLinks, StyledLinkRow, StyledSquare, StyledDropDown };
|
||||
|
@ -39,21 +39,50 @@ export type ShareCalendarProps = {
|
||||
closeCalendar: (formattedDate: moment.Moment) => void;
|
||||
calendarRef: React.RefObject<HTMLDivElement>;
|
||||
locale: string;
|
||||
bodyRef?: React.MutableRefObject<HTMLDivElement | null>;
|
||||
useDropDown?: boolean;
|
||||
};
|
||||
export type TLink = TFileLink | { isLoaded: boolean };
|
||||
|
||||
export type LinkRowProps = {
|
||||
onAddClick: () => Promise<void>;
|
||||
links: TLink[] | null;
|
||||
changeShareOption: (item: TOption, link: TFileLink) => Promise<void>;
|
||||
changeAccessOption: (item: TOption, link: TFileLink) => Promise<void>;
|
||||
changeExpirationOption: (
|
||||
link: TFileLink,
|
||||
expirationDate: moment.Moment | null,
|
||||
) => Promise<void>;
|
||||
availableExternalRights: TAvailableExternalRights;
|
||||
loadingLinks: (string | number)[];
|
||||
};
|
||||
export type LinkRowProps =
|
||||
| {
|
||||
onAddClick: () => Promise<void>;
|
||||
links: TLink[] | null;
|
||||
changeShareOption: (item: TOption, link: TFileLink) => Promise<void>;
|
||||
changeAccessOption: (item: TOption, link: TFileLink) => Promise<void>;
|
||||
changeExpirationOption: (
|
||||
link: TFileLink,
|
||||
expirationDate: moment.Moment | null,
|
||||
) => Promise<void>;
|
||||
availableExternalRights: TAvailableExternalRights;
|
||||
loadingLinks: (string | number)[];
|
||||
isRoomsLink?: undefined;
|
||||
isPrimaryLink?: undefined;
|
||||
isArchiveFolder?: undefined;
|
||||
getData: () => undefined;
|
||||
onOpenContextMenu?: undefined;
|
||||
onCloseContextMenu?: undefined;
|
||||
onAccessRightsSelect?: undefined;
|
||||
}
|
||||
| {
|
||||
onAddClick: () => Promise<void>;
|
||||
links: TLink[] | null;
|
||||
changeShareOption: (item: TOption, link: TFileLink) => Promise<void>;
|
||||
changeAccessOption: (item: TOption, link: TFileLink) => Promise<void>;
|
||||
changeExpirationOption: (
|
||||
link: TFileLink,
|
||||
expirationDate: moment.Moment | null,
|
||||
) => Promise<void>;
|
||||
availableExternalRights: TAvailableExternalRights;
|
||||
loadingLinks: (string | number)[];
|
||||
isRoomsLink?: boolean;
|
||||
isPrimaryLink: boolean;
|
||||
isArchiveFolder: boolean;
|
||||
getData: () => ContextMenuModel[];
|
||||
onOpenContextMenu: (e: React.MouseEvent) => void;
|
||||
onCloseContextMenu: () => void;
|
||||
onAccessRightsSelect: (option: TOption) => void;
|
||||
};
|
||||
|
||||
export type ExpiredComboBoxProps = {
|
||||
link: TFileLink;
|
||||
@ -62,6 +91,9 @@ export type ExpiredComboBoxProps = {
|
||||
expirationDate: moment.Moment | null,
|
||||
) => Promise<void>;
|
||||
isDisabled?: boolean;
|
||||
isRoomsLink?: boolean;
|
||||
changeAccessOption: (item: TOption, link: TFileLink) => Promise<void>;
|
||||
accessOptions: TOption[];
|
||||
};
|
||||
|
||||
export type ShareProps = {
|
||||
|
@ -244,11 +244,7 @@ const Share = (props: ShareProps) => {
|
||||
|
||||
if (item.access === ShareAccessRights.None) {
|
||||
deleteLink(link.sharedTo.id);
|
||||
if (link.sharedTo.primary) {
|
||||
toastr.success(t("Common:GeneralAccessLinkRemove"));
|
||||
} else {
|
||||
toastr.success(t("Common:AdditionalLinkRemove"));
|
||||
}
|
||||
toastr.success(t("Common:LinkRemoved"));
|
||||
} else {
|
||||
updateLink(link, res);
|
||||
if (item.access === ShareAccessRights.DenyAccess) {
|
||||
|
@ -37,11 +37,15 @@ import { getExpiredOptions } from "../Share.helpers";
|
||||
import { ExpiredComboBoxProps } from "../Share.types";
|
||||
|
||||
import ShareCalendar from "./ShareCalendar";
|
||||
import { ShareAccessRights } from "../../../enums";
|
||||
|
||||
const ExpiredComboBox = ({
|
||||
link,
|
||||
changeExpirationOption,
|
||||
isDisabled,
|
||||
isRoomsLink,
|
||||
changeAccessOption,
|
||||
accessOptions,
|
||||
}: ExpiredComboBoxProps) => {
|
||||
const { t, i18n } = useTranslation(["Common"]);
|
||||
const calendarRef = useRef<HTMLDivElement | null>(null);
|
||||
@ -107,8 +111,9 @@ const ExpiredComboBox = ({
|
||||
return { date: calculatedDate + 1, label: t("Common:Days") };
|
||||
};
|
||||
|
||||
const onRegenerateClick = () => {
|
||||
setSevenDays();
|
||||
const onRemoveLink = () => {
|
||||
const opt = accessOptions.find((o) => o.access === ShareAccessRights.None);
|
||||
if (opt) changeAccessOption(opt, link);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@ -150,7 +155,7 @@ const ExpiredComboBox = ({
|
||||
</Trans>
|
||||
);
|
||||
}
|
||||
const date = t("Common:Unlimited");
|
||||
const date = t("Common:Unlimited").toLowerCase();
|
||||
|
||||
return (
|
||||
<Trans t={t} i18nKey="LinkIsValid" ns="Common">
|
||||
@ -181,9 +186,9 @@ const ExpiredComboBox = ({
|
||||
fontWeight={400}
|
||||
fontSize="12px"
|
||||
color="#4781D1"
|
||||
onClick={onRegenerateClick}
|
||||
onClick={onRemoveLink}
|
||||
>
|
||||
{t("Common:Regenerate")}
|
||||
{t("Common:RemoveLink")}
|
||||
</Link>
|
||||
</Text>
|
||||
) : (
|
||||
@ -193,10 +198,12 @@ const ExpiredComboBox = ({
|
||||
)}
|
||||
{showCalendar && (
|
||||
<ShareCalendar
|
||||
bodyRef={bodyRef}
|
||||
onDateSet={setDateFromCalendar}
|
||||
calendarRef={calendarRef}
|
||||
closeCalendar={onCalendarClose}
|
||||
locale={i18n.language}
|
||||
useDropDown={isRoomsLink}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
@ -30,6 +30,7 @@ import PlusIcon from "PUBLIC_DIR/images/plus.react.svg?url";
|
||||
import UniverseIcon from "PUBLIC_DIR/images/universe.react.svg?url";
|
||||
import PeopleIcon from "PUBLIC_DIR/images/people.react.svg?url";
|
||||
import CopyIcon from "PUBLIC_DIR/images/copy.react.svg?url";
|
||||
import LockedReactSvg from "PUBLIC_DIR/images/icons/12/locked.react.svg";
|
||||
|
||||
import { RowSkeleton } from "../../../skeletons/share";
|
||||
import { TFileLink } from "../../../api/files/types";
|
||||
@ -43,11 +44,18 @@ import { Loader, LoaderTypes } from "../../loader";
|
||||
import { Text } from "../../text";
|
||||
|
||||
import { StyledLinkRow, StyledSquare } from "../Share.styled";
|
||||
import { getShareOptions, getAccessOptions } from "../Share.helpers";
|
||||
import {
|
||||
getShareOptions,
|
||||
getAccessOptions,
|
||||
getRoomAccessOptions,
|
||||
} from "../Share.helpers";
|
||||
import { LinkRowProps } from "../Share.types";
|
||||
|
||||
import ExpiredComboBox from "./ExpiredComboBox";
|
||||
|
||||
import { AccessRightSelect } from "../../access-right-select";
|
||||
import { ContextMenuButton } from "../../context-menu-button";
|
||||
|
||||
const LinkRow = ({
|
||||
onAddClick,
|
||||
links,
|
||||
@ -56,11 +64,22 @@ const LinkRow = ({
|
||||
changeExpirationOption,
|
||||
availableExternalRights,
|
||||
loadingLinks,
|
||||
isRoomsLink,
|
||||
isPrimaryLink,
|
||||
isArchiveFolder,
|
||||
getData,
|
||||
onOpenContextMenu,
|
||||
onCloseContextMenu,
|
||||
onAccessRightsSelect,
|
||||
}: LinkRowProps) => {
|
||||
const { t } = useTranslation(["Common"]);
|
||||
const { t } = useTranslation(["Common", "Translations"]);
|
||||
|
||||
const shareOptions = getShareOptions(t) as TOption[];
|
||||
const accessOptions = getAccessOptions(t, availableExternalRights);
|
||||
const accessOptions = availableExternalRights
|
||||
? getAccessOptions(t, availableExternalRights)
|
||||
: [];
|
||||
|
||||
const roomAccessOptions = isRoomsLink ? getRoomAccessOptions(t) : [];
|
||||
|
||||
const onCopyLink = (link: TFileLink) => {
|
||||
copyShareLink(link.sharedTo.shareLink);
|
||||
@ -88,14 +107,26 @@ const LinkRow = ({
|
||||
(option) =>
|
||||
option && "access" in option && option.access === link.access,
|
||||
);
|
||||
|
||||
const roomSelectedOptions = roomAccessOptions.find(
|
||||
(option) =>
|
||||
option && "access" in option && option.access === link.access,
|
||||
);
|
||||
|
||||
const avatar = shareOption?.key === "anyone" ? UniverseIcon : PeopleIcon;
|
||||
|
||||
const isExpiredLink = link.sharedTo.isExpired;
|
||||
const isLocked = !!link.sharedTo.password;
|
||||
const linkTitle = link.sharedTo.title;
|
||||
|
||||
const isLoaded = loadingLinks.includes(link.sharedTo.id);
|
||||
|
||||
return (
|
||||
<StyledLinkRow key={`share-link-row-${index * 5}`}>
|
||||
<StyledLinkRow
|
||||
isExpired={isExpiredLink}
|
||||
key={`share-link-row-${index * 5}`}
|
||||
isDisabled={isArchiveFolder}
|
||||
>
|
||||
{isLoaded ? (
|
||||
<Loader className="loader" size="20px" type={LoaderTypes.track} />
|
||||
) : (
|
||||
@ -103,10 +134,15 @@ const LinkRow = ({
|
||||
size={AvatarSize.min}
|
||||
role={AvatarRole.user}
|
||||
source={avatar}
|
||||
roleIcon={isLocked ? <LockedReactSvg /> : undefined}
|
||||
/>
|
||||
)}
|
||||
<div className="link-options">
|
||||
{!isExpiredLink ? (
|
||||
{isRoomsLink ? (
|
||||
<Text className="link-options_title" truncate>
|
||||
{linkTitle}
|
||||
</Text>
|
||||
) : !isExpiredLink ? (
|
||||
<ComboBox
|
||||
className="internal-combobox"
|
||||
directionY="both"
|
||||
@ -122,39 +158,71 @@ const LinkRow = ({
|
||||
isDisabled={isLoaded}
|
||||
/>
|
||||
) : (
|
||||
<Text className="internal-combobox_expiered">
|
||||
{shareOption?.label}
|
||||
</Text>
|
||||
<Text className="link-options_title">{shareOption?.label}</Text>
|
||||
)}
|
||||
{!isPrimaryLink && (
|
||||
<ExpiredComboBox
|
||||
link={link}
|
||||
accessOptions={accessOptions}
|
||||
changeExpirationOption={changeExpirationOption}
|
||||
isDisabled={isLoaded || isArchiveFolder}
|
||||
isRoomsLink={isRoomsLink}
|
||||
changeAccessOption={changeAccessOption}
|
||||
/>
|
||||
)}
|
||||
<ExpiredComboBox
|
||||
link={link}
|
||||
changeExpirationOption={changeExpirationOption}
|
||||
isDisabled={isLoaded}
|
||||
/>
|
||||
</div>
|
||||
<div className="link-actions">
|
||||
<IconButton
|
||||
size={16}
|
||||
iconName={CopyIcon}
|
||||
onClick={() => onCopyLink(link)}
|
||||
title={t("Common:CreateAndCopy")}
|
||||
isDisabled={isExpiredLink || isLoaded}
|
||||
/>
|
||||
<ComboBox
|
||||
directionY="both"
|
||||
options={accessOptions}
|
||||
selectedOption={accessOption ?? ({} as TOption)}
|
||||
onSelect={(item) => changeAccessOption(item, link)}
|
||||
scaled={false}
|
||||
scaledOptions={false}
|
||||
showDisabledItems
|
||||
size={ComboBoxSize.content}
|
||||
fillIcon
|
||||
modernView
|
||||
type="onlyIcon"
|
||||
isDisabled={isExpiredLink || isLoaded}
|
||||
manualWidth="fit-content"
|
||||
/>
|
||||
{!isArchiveFolder && (
|
||||
<IconButton
|
||||
size={16}
|
||||
className="link-row_copy-icon"
|
||||
iconName={CopyIcon}
|
||||
onClick={() => onCopyLink(link)}
|
||||
title={t("Common:CreateAndCopy")}
|
||||
isDisabled={isExpiredLink || isLoaded}
|
||||
/>
|
||||
)}
|
||||
{isRoomsLink ? (
|
||||
<>
|
||||
<AccessRightSelect
|
||||
selectedOption={roomSelectedOptions ?? ({} as TOption)}
|
||||
onSelect={onAccessRightsSelect}
|
||||
accessOptions={roomAccessOptions}
|
||||
noBorder
|
||||
directionX="right"
|
||||
directionY="bottom"
|
||||
type="onlyIcon"
|
||||
manualWidth="300px"
|
||||
isDisabled={isExpiredLink || isLoaded || isArchiveFolder}
|
||||
/>
|
||||
{!isArchiveFolder && (
|
||||
<ContextMenuButton
|
||||
getData={getData}
|
||||
title={t("Files:ShowLinkActions")}
|
||||
directionY="both"
|
||||
onClick={onOpenContextMenu}
|
||||
onClose={onCloseContextMenu}
|
||||
isDisabled={isExpiredLink || isLoaded}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<ComboBox
|
||||
directionY="both"
|
||||
options={accessOptions}
|
||||
selectedOption={accessOption ?? ({} as TOption)}
|
||||
onSelect={(item) => changeAccessOption(item, link)}
|
||||
scaled={false}
|
||||
scaledOptions={false}
|
||||
showDisabledItems
|
||||
size={ComboBoxSize.content}
|
||||
fillIcon
|
||||
modernView
|
||||
type="onlyIcon"
|
||||
isDisabled={isExpiredLink || isLoaded}
|
||||
manualWidth="fit-content"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</StyledLinkRow>
|
||||
);
|
||||
|
@ -31,6 +31,7 @@ import { isMobile } from "../../../utils/device";
|
||||
|
||||
import { Calendar } from "../../calendar";
|
||||
import { ShareCalendarProps } from "../Share.types";
|
||||
import { StyledDropDown } from "../Share.styled";
|
||||
|
||||
const StyledCalendar = styled(Calendar)`
|
||||
position: absolute;
|
||||
@ -50,12 +51,15 @@ const ShareCalendar = ({
|
||||
closeCalendar,
|
||||
calendarRef,
|
||||
locale,
|
||||
bodyRef,
|
||||
useDropDown,
|
||||
}: ShareCalendarProps) => {
|
||||
const selectedDate = moment();
|
||||
const maxDate = moment().add(10, "years");
|
||||
|
||||
return (
|
||||
const calendarComponent = (
|
||||
<StyledCalendar
|
||||
className="share-link_calendar"
|
||||
selectedDate={selectedDate}
|
||||
setSelectedDate={onDateSet}
|
||||
onChange={closeCalendar}
|
||||
@ -66,6 +70,19 @@ const ShareCalendar = ({
|
||||
maxDate={maxDate}
|
||||
/>
|
||||
);
|
||||
|
||||
return useDropDown ? (
|
||||
<StyledDropDown
|
||||
open
|
||||
isDefaultMode
|
||||
forwardedRef={bodyRef}
|
||||
eventTypes={["mousedown"]}
|
||||
>
|
||||
{calendarComponent}
|
||||
</StyledDropDown>
|
||||
) : (
|
||||
calendarComponent
|
||||
);
|
||||
};
|
||||
|
||||
export default ShareCalendar;
|
||||
|
@ -2085,8 +2085,10 @@ export const getBaseTheme = () => {
|
||||
closeButtonBg: "transparent",
|
||||
|
||||
nameColor: "#858585",
|
||||
avatarColor: "#555F65",
|
||||
|
||||
links: {
|
||||
color: "#4781D1",
|
||||
iconColor: "#3B72A7",
|
||||
iconErrorColor: "#F24724",
|
||||
primaryColor: "#555F65",
|
||||
|
@ -2057,8 +2057,10 @@ const Dark: TTheme = {
|
||||
closeButtonBg: "#a2a2a2",
|
||||
|
||||
nameColor: "#A3A9AE",
|
||||
avatarColor: "#A3A9AE",
|
||||
|
||||
links: {
|
||||
color: "#4781D1",
|
||||
iconColor: "#858585",
|
||||
iconErrorColor: "#E06451",
|
||||
primaryColor: "#ADADAD",
|
||||
|
15
public/images/icons/12/locked.react.svg
Normal file
15
public/images/icons/12/locked.react.svg
Normal file
@ -0,0 +1,15 @@
|
||||
<svg width="12" height="14" viewBox="0 0 12 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_622_21524)">
|
||||
<mask id="path-1-outside-1_622_21524" maskUnits="userSpaceOnUse" x="0" y="0" width="12" height="14" fill="black">
|
||||
<rect fill="white" width="12" height="14"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3 4C3 2.34315 4.34315 1 6 1C7.65685 1 9 2.34315 9 4V5C10.1046 5 11 5.89543 11 7V11C11 12.1046 10.1046 13 9 13H3C1.89543 13 1 12.1046 1 11V7C1 5.89543 1.89543 5 3 5V4ZM7 4V5H5V4C5 3.44772 5.44772 3 6 3C6.55228 3 7 3.44772 7 4ZM3 7V11H9V7H3ZM6 10C6.55228 10 7 9.55229 7 9C7 8.44772 6.55228 8 6 8C5.44772 8 5 8.44772 5 9C5 9.55229 5.44772 10 6 10Z"/>
|
||||
</mask>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3 4C3 2.34315 4.34315 1 6 1C7.65685 1 9 2.34315 9 4V5C10.1046 5 11 5.89543 11 7V11C11 12.1046 10.1046 13 9 13H3C1.89543 13 1 12.1046 1 11V7C1 5.89543 1.89543 5 3 5V4ZM7 4V5H5V4C5 3.44772 5.44772 3 6 3C6.55228 3 7 3.44772 7 4ZM3 7V11H9V7H3ZM6 10C6.55228 10 7 9.55229 7 9C7 8.44772 6.55228 8 6 8C5.44772 8 5 8.44772 5 9C5 9.55229 5.44772 10 6 10Z" fill="#4781D1"/>
|
||||
<path d="M9 5H8C8 5.55228 8.44772 6 9 6V5ZM3 5V6C3.55228 6 4 5.55228 4 5H3ZM7 5V6C7.55228 6 8 5.55228 8 5H7ZM5 5H4C4 5.55228 4.44772 6 5 6V5ZM3 11H2C2 11.5523 2.44772 12 3 12V11ZM3 7V6C2.44772 6 2 6.44772 2 7H3ZM9 11V12C9.55228 12 10 11.5523 10 11H9ZM9 7H10C10 6.44772 9.55228 6 9 6V7ZM6 0C3.79086 0 2 1.79086 2 4H4C4 2.89543 4.89543 2 6 2V0ZM10 4C10 1.79086 8.20914 0 6 0V2C7.10457 2 8 2.89543 8 4H10ZM10 5V4H8V5H10ZM12 7C12 5.34315 10.6569 4 9 4V6C9.55228 6 10 6.44772 10 7H12ZM12 11V7H10V11H12ZM9 14C10.6569 14 12 12.6569 12 11H10C10 11.5523 9.55228 12 9 12V14ZM3 14H9V12H3V14ZM0 11C0 12.6569 1.34315 14 3 14V12C2.44772 12 2 11.5523 2 11H0ZM0 7V11H2V7H0ZM3 4C1.34315 4 0 5.34315 0 7H2C2 6.44772 2.44772 6 3 6V4ZM2 4V5H4V4H2ZM8 5V4H6V5H8ZM5 6H7V4H5V6ZM4 4V5H6V4H4ZM6 2C4.89543 2 4 2.89543 4 4H6V2ZM8 4C8 2.89543 7.10457 2 6 2V4H8ZM4 11V7H2V11H4ZM9 10H3V12H9V10ZM8 7V11H10V7H8ZM3 8H9V6H3V8ZM6 9V11C7.10457 11 8 10.1046 8 9H6ZM6 9H8C8 7.89543 7.10457 7 6 7V9ZM6 9V7C4.89543 7 4 7.89543 4 9H6ZM6 9H4C4 10.1046 4.89543 11 6 11V9Z" fill="white" mask="url(#path-1-outside-1_622_21524)"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_622_21524">
|
||||
<rect width="12" height="14" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
@ -147,6 +147,7 @@
|
||||
"EditButton": "Edit",
|
||||
"Editing": "Editing",
|
||||
"Editor": "Editor",
|
||||
"Commentator": "Commentator",
|
||||
"Email": "Email",
|
||||
"EmptyDescription": "The list of users previously invited to {{productName}} or separate rooms will appear here. You will be able to invite these users for collaboration at any time.",
|
||||
"EmptyEmail": "No email address parsed",
|
||||
@ -386,6 +387,8 @@
|
||||
"RecoverDescribeYourProblemPlaceholder": "Describe your problem",
|
||||
"RecoverTitle": "Access recovery",
|
||||
"Regenerate": "Regenerate",
|
||||
"RemoveLink": "Remove link",
|
||||
"LinkRemoved": "Link removed",
|
||||
"RegistrationEmail": "Your registration email address",
|
||||
"ReloadPage": "Reload page",
|
||||
"Remember": "Remember me",
|
||||
|
Loading…
Reference in New Issue
Block a user