Web: Files: EditLinkPanel: added password settings
This commit is contained in:
parent
153bae389c
commit
c3e7777667
@ -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 { useRef } from "react";
|
||||
import ToggleBlock from "./ToggleBlock";
|
||||
import { IconButton } from "@docspace/shared/components/icon-button";
|
||||
import { Link } from "@docspace/shared/components/link";
|
||||
@ -31,8 +32,8 @@ import RefreshReactSvgUrl from "PUBLIC_DIR/images/refresh.react.svg?url";
|
||||
import { FieldContainer } from "@docspace/shared/components/field-container";
|
||||
import copy from "copy-to-clipboard";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
import SimulatePassword from "../../../components/SimulatePassword";
|
||||
import { getNewPassword } from "@docspace/shared/utils";
|
||||
import { ALLOWED_PASSWORD_CHARACTERS } from "@docspace/shared/constants";
|
||||
import { PasswordInput } from "@docspace/shared/components/password-input";
|
||||
|
||||
const PasswordAccessBlock = (props) => {
|
||||
const {
|
||||
@ -43,15 +44,21 @@ const PasswordAccessBlock = (props) => {
|
||||
setPasswordValue,
|
||||
isPasswordValid,
|
||||
setIsPasswordValid,
|
||||
passwordSettings,
|
||||
isPasswordErrorShow,
|
||||
setIsPasswordErrorShow,
|
||||
} = props;
|
||||
|
||||
const passwordInputRef = useRef(null);
|
||||
|
||||
const onGeneratePasswordClick = () => {
|
||||
const password = getNewPassword();
|
||||
setPasswordValue(password);
|
||||
passwordInputRef.current.onGeneratePassword();
|
||||
};
|
||||
|
||||
const onCleanClick = () => {
|
||||
const onCleanClick = (e) => {
|
||||
e.stopPropagation();
|
||||
setPasswordValue("");
|
||||
setIsPasswordValid(false);
|
||||
};
|
||||
|
||||
const onCopyClick = () => {
|
||||
@ -62,9 +69,36 @@ const PasswordAccessBlock = (props) => {
|
||||
}
|
||||
};
|
||||
|
||||
const onChangePassword = (password) => {
|
||||
setPasswordValue(password);
|
||||
const onChangePassword = (e, value) => {
|
||||
setPasswordValue(value);
|
||||
setIsPasswordValid(true);
|
||||
setIsPasswordErrorShow(false);
|
||||
};
|
||||
|
||||
// const onBlurPassword = () => {
|
||||
// setIsPasswordErrorShow(true);
|
||||
// };
|
||||
|
||||
const onValidatePassword = (isValidate) => {
|
||||
setIsPasswordValid(isValidate);
|
||||
};
|
||||
|
||||
const errorMessage = !passwordValue
|
||||
? t("Common:RequiredField")
|
||||
: t("Common:IncorrectPassword");
|
||||
|
||||
const hasError = isPasswordErrorShow && !isPasswordValid;
|
||||
|
||||
const tooltipData = {
|
||||
tooltipPasswordTitle: `${t("Common:PasswordLimitMessage")}:`,
|
||||
tooltipPasswordLength: `${t("Common:PasswordMinimumLength")}: ${
|
||||
passwordSettings ? passwordSettings.minLength : 8
|
||||
}`,
|
||||
tooltipPasswordDigits: `${t("Common:PasswordLimitDigits")}`,
|
||||
tooltipPasswordCapital: `${t("Common:PasswordLimitUpperCase")}`,
|
||||
tooltipPasswordSpecial: `${t("Common:PasswordLimitSpecialSymbols")}`,
|
||||
generatePasswordTitle: t("Wizard:GeneratePassword"),
|
||||
tooltipAllowedCharacters: `${t("Common:AllowedCharacters")}: ${ALLOWED_PASSWORD_CHARACTERS}`,
|
||||
};
|
||||
|
||||
return (
|
||||
@ -74,17 +108,26 @@ const PasswordAccessBlock = (props) => {
|
||||
<div className="edit-link_password-block">
|
||||
<FieldContainer
|
||||
isVertical
|
||||
hasError={!isPasswordValid}
|
||||
errorMessage={t("Common:RequiredField")}
|
||||
hasError={hasError}
|
||||
errorMessage={errorMessage}
|
||||
className="edit-link_password-block"
|
||||
>
|
||||
<SimulatePassword
|
||||
<PasswordInput
|
||||
id="conversion-password"
|
||||
className="edit-link_password-input"
|
||||
ref={passwordInputRef}
|
||||
isDisabled={isLoading}
|
||||
hasError={!isPasswordValid}
|
||||
inputValue={passwordValue}
|
||||
onChange={onChangePassword}
|
||||
inputMaxWidth="100%"
|
||||
passwordSettings={passwordSettings}
|
||||
simpleView={false}
|
||||
placeholder={t("Common:Password")}
|
||||
hasError={hasError}
|
||||
// onBlur={onBlurPassword}
|
||||
onValidateInput={onValidatePassword}
|
||||
isSimulateType
|
||||
simulateSymbol="•"
|
||||
{...tooltipData}
|
||||
/>
|
||||
</FieldContainer>
|
||||
|
||||
|
@ -65,6 +65,8 @@ const EditLinkPanel = (props) => {
|
||||
isFormRoom,
|
||||
currentDeviceType,
|
||||
setLinkParams,
|
||||
passwordSettings,
|
||||
getPortalPasswordSettings,
|
||||
} = props;
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
@ -80,6 +82,7 @@ const EditLinkPanel = (props) => {
|
||||
const [isExpired, setIsExpired] = useState(isExpiredDate);
|
||||
|
||||
const [isPasswordValid, setIsPasswordValid] = useState(true);
|
||||
const [isPasswordErrorShow, setIsPasswordErrorShow] = useState(false);
|
||||
|
||||
const [linkValue, setLinkValue] = useState(shareLink);
|
||||
const [hasChanges, setHasChanges] = useState(false);
|
||||
@ -101,10 +104,12 @@ const EditLinkPanel = (props) => {
|
||||
|
||||
const onClose = () => setIsVisible(false);
|
||||
const onSave = () => {
|
||||
const isPasswordValid = !!passwordValue.trim();
|
||||
|
||||
if (!isPasswordValid && passwordAccessIsChecked) {
|
||||
if (
|
||||
(!passwordValue.trim() || !isPasswordValid) &&
|
||||
passwordAccessIsChecked
|
||||
) {
|
||||
setIsPasswordValid(false);
|
||||
setIsPasswordErrorShow(true);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -140,11 +145,14 @@ const EditLinkPanel = (props) => {
|
||||
|
||||
toastr.success(t("Files:LinkSuccessfullyCreatedAndCopied"));
|
||||
}
|
||||
onClose();
|
||||
})
|
||||
.catch((err) => {
|
||||
const error = err?.response?.data?.error?.message ?? err?.message;
|
||||
toastr.error(error);
|
||||
})
|
||||
.catch((err) => toastr.error(err?.message))
|
||||
.finally(() => {
|
||||
setIsLoading(false);
|
||||
onClose();
|
||||
});
|
||||
};
|
||||
|
||||
@ -183,6 +191,18 @@ const EditLinkPanel = (props) => {
|
||||
return () => window.removeEventListener("keydown", onKeyPress);
|
||||
}, [onKeyPress]);
|
||||
|
||||
const getPasswordSettings = async () => {
|
||||
setIsLoading(true);
|
||||
await getPortalPasswordSettings();
|
||||
setIsLoading(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!passwordSettings) {
|
||||
getPasswordSettings();
|
||||
}
|
||||
}, [passwordSettings]);
|
||||
|
||||
const linkNameIsValid = !!linkNameValue.trim();
|
||||
|
||||
const expiredLinkText = isExpired
|
||||
@ -239,6 +259,9 @@ const EditLinkPanel = (props) => {
|
||||
setPasswordValue={setPasswordValue}
|
||||
setIsPasswordValid={setIsPasswordValid}
|
||||
onChange={onPasswordAccessChange}
|
||||
passwordSettings={passwordSettings}
|
||||
isPasswordErrorShow={isPasswordErrorShow}
|
||||
setIsPasswordErrorShow={setIsPasswordErrorShow}
|
||||
/>
|
||||
{!isFormRoom && (
|
||||
<ToggleBlock
|
||||
@ -313,11 +336,13 @@ export default inject(
|
||||
} = dialogsStore;
|
||||
const { externalLinks, editExternalLink, setExternalLink } =
|
||||
publicRoomStore;
|
||||
const { currentDeviceType, passwordSettings, getPortalPasswordSettings } =
|
||||
settingsStore;
|
||||
|
||||
const { isEdit, roomId, isPublic, isFormRoom } = linkParams;
|
||||
|
||||
const linkId = linkParams?.link?.sharedTo?.id;
|
||||
const link = externalLinks.find((l) => l?.sharedTo?.id === linkId);
|
||||
|
||||
const shareLink = link?.sharedTo?.shareLink;
|
||||
|
||||
return {
|
||||
@ -340,10 +365,14 @@ export default inject(
|
||||
language: authStore.language,
|
||||
isPublic,
|
||||
isFormRoom,
|
||||
currentDeviceType: settingsStore.currentDeviceType,
|
||||
currentDeviceType,
|
||||
setLinkParams,
|
||||
passwordSettings,
|
||||
getPortalPasswordSettings,
|
||||
};
|
||||
},
|
||||
)(
|
||||
withTranslation(["SharingPanel", "Common", "Files"])(observer(EditLinkPanel)),
|
||||
withTranslation(["SharingPanel", "Common", "Files", "Wizard"])(
|
||||
observer(EditLinkPanel),
|
||||
),
|
||||
);
|
||||
|
@ -32,6 +32,7 @@ import React, {
|
||||
ChangeEvent,
|
||||
FocusEvent,
|
||||
MouseEvent,
|
||||
useEffect,
|
||||
} from "react";
|
||||
import { TooltipRefProps } from "react-tooltip";
|
||||
|
||||
@ -109,6 +110,16 @@ const PasswordInput = React.forwardRef(
|
||||
}: PasswordInputProps,
|
||||
ref,
|
||||
) => {
|
||||
const usePrevious = (value: string) => {
|
||||
const inputValueRef = useRef<string>();
|
||||
useEffect(() => {
|
||||
inputValueRef.current = value;
|
||||
});
|
||||
return inputValueRef.current;
|
||||
};
|
||||
|
||||
const prevInputValue = usePrevious(inputValue ?? "");
|
||||
|
||||
const [state, setState] = useState({
|
||||
type: inputType,
|
||||
value: inputValue,
|
||||
@ -276,6 +287,8 @@ const PasswordInput = React.forwardRef(
|
||||
(newPassword: string) => {
|
||||
let newValue;
|
||||
|
||||
if (!state.value) return newPassword;
|
||||
|
||||
const oldPassword = state.value ?? "";
|
||||
const oldPasswordLength = oldPassword.length;
|
||||
const newCaretPosition = document.getElementById(
|
||||
@ -465,6 +478,14 @@ const PasswordInput = React.forwardRef(
|
||||
}
|
||||
}, [caretPosition, state.type, state.value, isSimulateType]);
|
||||
|
||||
useEffect(() => {
|
||||
if (inputValue !== prevInputValue) {
|
||||
onChangeAction?.({
|
||||
target: { value: inputValue },
|
||||
} as ChangeEvent<HTMLInputElement>);
|
||||
}
|
||||
}, [inputValue, prevInputValue, onChangeAction]);
|
||||
|
||||
React.useImperativeHandle(
|
||||
ref,
|
||||
() => {
|
||||
|
Loading…
Reference in New Issue
Block a user