mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-09-10 19:57:40 +02:00
Compare commits
12
Commits
v1.4.0-beta
...
v1.4.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0bf07c2703 | ||
|
|
10a0c60056 | ||
|
|
036c9b8d4a | ||
|
|
1f50368259 | ||
|
|
6d5e07dac7 | ||
|
|
3656175f11 | ||
|
|
febb50c3cd | ||
|
|
f8ba0d357b | ||
|
|
5a25b2d874 | ||
|
|
d1e7b9a2ab | ||
|
|
60140885e0 | ||
|
|
a06723ff3f |
@@ -42,24 +42,24 @@ Please star ⭐ the repo to support us! 😀
|
|||||||
|
|
||||||
### Introduction
|
### Introduction
|
||||||
|
|
||||||
Welcome to OpenSign, the premier open-source docusign alternative - document e-signing solution designed to provide a secure, reliable, and free alternative to commercial platforms like DocuSign, PandaDoc, SignNow, Adobe Sign, Smartwaiver, SignRequest, HelloSign & Zoho sign. Developed under the OpenSignLabs organization, our mission is to democratize the e-signing process, making it accessible and straightforward for everyone.
|
Welcome to OpenSign, the premier open source docusign alternative - document e-signing solution designed to provide a secure, reliable and free alternative to commercial esign platforms like DocuSign, PandaDoc, SignNow, Adobe Sign, Smartwaiver, SignRequest, HelloSign & Zoho sign. Our mission is to democratize the e-signing process, making it accessible and straightforward for everyone.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
- **Secure PDF E-Signing:** With the help of Robust encryption algorithms, OpenSign™ ensures maximum security, privacy & compatibility.
|
- **Secure PDF E-Signing:** With the help of robust encryption algorithms, OpenSign™ ensures maximum security, privacy & compatibility.
|
||||||
- **Annotate Documents:** OpenSign™ allows you to annotate PDF documents with an advanced signing pad that comes with hand drawn signatures support as well as uploaded images & saved signatures for the simplest signing experience.
|
- **Annotate Documents:** OpenSign™ allows you to annotate PDF documents with an advanced signing pad that allows hand drawn signatures, uploaded images, typed signatures & saved signatures for the simplest signing experience ever.
|
||||||
- **User-Friendly Interface:** OpenSign™ was built while keeping Intuitive design in mind for ease of use. Features like "Sign yourself", "One click signatures" and "OpenSign Drive" makes it stand out of the crowd and even makes it better than a lot of so-called industry leaders.
|
- **User-Friendly Interface:** OpenSign™ was built while keeping Intuitive design in mind for ease of use. Features like "Sign yourself", "Templates", "One click signatures" and "OpenSign™ Drive" makes it stand out of the crowd and even makes it better than a lot of so-called industry leaders.
|
||||||
- **Multi-signer Support:** OpenSign's ability to invite multiple signers for signing along with the ability to invite witnesses & being able to enforce signing in a sequence makes it the only open source solution that is fully loaded and allows it to compete head-to-head with established players.
|
- **Multi-signer Support:** OpenSign's ability to invite multiple signers for signing along with the ability to invite witnesses & being able to enforce signing in a sequence makes it the only open source solution that is fully loaded and allows it to compete head-to-head with established players in e-signature space.
|
||||||
- **Email Unique Code(OTP) verification support for guest signers:** With OpenSign™, your documents are fully secure even when being signed by guest users. Guest signers can only sign the document after entering a unique code sent to their email address.
|
- **Email Unique Code(OTP) verification support for guest signers:** With OpenSign™, your documents are fully secure even when being signed by guest users. Guest signers can only sign the document after entering a unique code sent to their email address.
|
||||||
- **"Expiring Docs" & "Rejection":** You can set documents to expire after certain number of days after which nobody will be able to sign it. Not just this, OpenSign also allows signers to reject signing a document.
|
- **"Expiring Docs" & "Rejection":** You can set documents to expire after certain number of days after which nobody will be able to sign. Not just this, OpenSign™ also allows signers to reject signing a document.
|
||||||
- **Beautiful email templates:** All document signing invitations, completion notifications & reminders are formatted using great looking email templates.
|
- **Beautiful email templates:** All document signing invitations, completion notifications & reminders are formatted using great looking email templates.
|
||||||
- **PDF Template Creation(coming soon):** OpenSign™ allows you to create and store PDF document templates for repeated use thereby saving you a lot of time.
|
- **PDF Template Creation:** OpenSign™ allows you to create and store PDF document templates for repeated use thereby saving you a lot of time & collect e-signatures seamlessly.
|
||||||
- **OpenSign™ Drive:** It is a centralised secure vault for your signed documents that makes storing, signing, organizing, sharing & achieving your docs a breeze.
|
- **OpenSign™ Drive:** It is a centralised secure vault for your digital documents that makes storing, signing, organizing, sharing & achieving your docs a breeze.
|
||||||
- **Audit Trails & completion certificate:** Being a security focused solution, OpenSign™ makes it a top priority to save detailed logs for tracking document activities along with time-stamps, IP addresses, email IDs & phone numbers. A completion certificate is generated as soon as document is completed which contains all the document related logs for added safety.
|
- **Audit Trails & completion certificate:** Being a security focused solution, OpenSign™ makes it a top priority to save detailed logs for tracking document activities along with time-stamps, IP addresses, email IDs & phone numbers. A completion certificate is generated as soon as document is completed which contains all the document related logs for added safety.
|
||||||
- **API Support(coming soon):** OpenSign™ API allows seamless integration into existing systems and software. APIs will soon be available as a cloud hosted solution.
|
- **API Support:** OpenSign™ API allows seamless integration into existing systems and software. You can generate an API key from the app and refer the [docs](https://docs.opensignlabs.com) to start integrating it in your existing applications.
|
||||||
- **Integrations:** Seamless integrations with various Cloud storage systems, CRMs & enterprise platforms is coming soon.
|
- **Integrations:** Seamless integrations with various Cloud storage systems, CRMs & enterprise platforms is available. We also have a Zapier integration that allows you to integrate it with virtually any application.
|
||||||
|
|
||||||
<img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/b37ff443-7099-4273-9aeb-21c46d7154cf height='200'>
|
<img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/b37ff443-7099-4273-9aeb-21c46d7154cf height='200'>
|
||||||
<img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/86db91b7-6c2f-4885-a33c-58f4fd35ec89 height='200'>
|
<img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/86db91b7-6c2f-4885-a33c-58f4fd35ec89 height='200'>
|
||||||
@@ -76,7 +76,7 @@ Please refer to the [Installation Guide](INSTALLATION.md) for detailed instructi
|
|||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
For comprehensive guidelines on how to use OpenSign, please consult our [User Manual](USAGE.md).
|
For comprehensive guidelines on how to use OpenSign™, please consult our [User Manual](USAGE.md).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -353,7 +353,7 @@ const DashboardCard = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs absolute top-1 right-1">
|
<div className="text-xs absolute top-2 right-1">
|
||||||
<Tooltip id={props.Label} iconColor={"white"} message={props?.Data?.tourMessage} />
|
<Tooltip id={props.Label} iconColor={"white"} message={props?.Data?.tourMessage} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -275,6 +275,7 @@ function Placeholder(props) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const handleOnClickPlaceholder = () => {
|
const handleOnClickPlaceholder = () => {
|
||||||
|
props.setCurrWidgetsDetails && props.setCurrWidgetsDetails(props.pos);
|
||||||
if (!props.isNeedSign) {
|
if (!props.isNeedSign) {
|
||||||
props.setWidgetType(props.pos.type);
|
props.setWidgetType(props.pos.type);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -307,6 +307,7 @@ function PlaceholderType(props) {
|
|||||||
return props.pos.SignUrl ? (
|
return props.pos.SignUrl ? (
|
||||||
<img
|
<img
|
||||||
alt="signimg"
|
alt="signimg"
|
||||||
|
draggable="false"
|
||||||
src={props.pos.SignUrl}
|
src={props.pos.SignUrl}
|
||||||
style={{
|
style={{
|
||||||
width: "99%",
|
width: "99%",
|
||||||
@@ -328,6 +329,7 @@ function PlaceholderType(props) {
|
|||||||
return props.pos.SignUrl ? (
|
return props.pos.SignUrl ? (
|
||||||
<img
|
<img
|
||||||
alt="signimg"
|
alt="signimg"
|
||||||
|
draggable="false"
|
||||||
src={props.pos.SignUrl}
|
src={props.pos.SignUrl}
|
||||||
style={{
|
style={{
|
||||||
width: "99%",
|
width: "99%",
|
||||||
@@ -483,6 +485,7 @@ function PlaceholderType(props) {
|
|||||||
return props.pos.SignUrl ? (
|
return props.pos.SignUrl ? (
|
||||||
<img
|
<img
|
||||||
alt="signimg"
|
alt="signimg"
|
||||||
|
draggable="false"
|
||||||
src={props.pos.SignUrl}
|
src={props.pos.SignUrl}
|
||||||
style={{
|
style={{
|
||||||
width: "99%",
|
width: "99%",
|
||||||
@@ -668,6 +671,7 @@ function PlaceholderType(props) {
|
|||||||
return props.pos.SignUrl ? (
|
return props.pos.SignUrl ? (
|
||||||
<img
|
<img
|
||||||
alt="signimg"
|
alt="signimg"
|
||||||
|
draggable="false"
|
||||||
src={props.pos.SignUrl}
|
src={props.pos.SignUrl}
|
||||||
style={{
|
style={{
|
||||||
width: "99%",
|
width: "99%",
|
||||||
@@ -787,6 +791,7 @@ function PlaceholderType(props) {
|
|||||||
<div style={{ pointerEvents: "none" }}>
|
<div style={{ pointerEvents: "none" }}>
|
||||||
<img
|
<img
|
||||||
alt="signimg"
|
alt="signimg"
|
||||||
|
draggable="false"
|
||||||
src={props.pos.SignUrl}
|
src={props.pos.SignUrl}
|
||||||
style={{
|
style={{
|
||||||
width: "99%",
|
width: "99%",
|
||||||
|
|||||||
@@ -116,7 +116,13 @@ const RecipientList = (props) => {
|
|||||||
data-tut="reactourFirst"
|
data-tut="reactourFirst"
|
||||||
onMouseEnter={() => setIsHover(ind)}
|
onMouseEnter={() => setIsHover(ind)}
|
||||||
onMouseLeave={() => setIsHover(null)}
|
onMouseLeave={() => setIsHover(null)}
|
||||||
className={props.sendInOrder && "dragCursor"}
|
className={
|
||||||
|
props.sendInOrder
|
||||||
|
? props.isMailSend
|
||||||
|
? "disabled"
|
||||||
|
: "dragCursor"
|
||||||
|
: props.isMailSend && "disabled"
|
||||||
|
}
|
||||||
style={
|
style={
|
||||||
(!isMobile && isHover === ind) || props.isSelectListId === ind
|
(!isMobile && isHover === ind) || props.isSelectListId === ind
|
||||||
? onHoverStyle(ind, obj?.blockColor)
|
? onHoverStyle(ind, obj?.blockColor)
|
||||||
|
|||||||
@@ -272,6 +272,7 @@ function RenderPdf({
|
|||||||
unSignedWidgetId={unSignedWidgetId}
|
unSignedWidgetId={unSignedWidgetId}
|
||||||
setSelectWidgetId={setSelectWidgetId}
|
setSelectWidgetId={setSelectWidgetId}
|
||||||
selectWidgetId={selectWidgetId}
|
selectWidgetId={selectWidgetId}
|
||||||
|
setCurrWidgetsDetails={setCurrWidgetsDetails}
|
||||||
/>
|
/>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ function SignPad({
|
|||||||
isInitial,
|
isInitial,
|
||||||
setIsInitial,
|
setIsInitial,
|
||||||
setIsStamp,
|
setIsStamp,
|
||||||
widgetType
|
widgetType,
|
||||||
|
currWidgetsDetails,
|
||||||
|
setCurrWidgetsDetails
|
||||||
}) {
|
}) {
|
||||||
const [penColor, setPenColor] = useState("blue");
|
const [penColor, setPenColor] = useState("blue");
|
||||||
const allColor = ["blue", "red", "black"];
|
const allColor = ["blue", "red", "black"];
|
||||||
@@ -31,6 +33,7 @@ function SignPad({
|
|||||||
const [signValue, setSignValue] = useState("");
|
const [signValue, setSignValue] = useState("");
|
||||||
const [textWidth, setTextWidth] = useState(null);
|
const [textWidth, setTextWidth] = useState(null);
|
||||||
const [textHeight, setTextHeight] = useState(null);
|
const [textHeight, setTextHeight] = useState(null);
|
||||||
|
const [signatureType, setSignatureType] = useState("draw");
|
||||||
const fontOptions = [
|
const fontOptions = [
|
||||||
{ value: "Fasthand" },
|
{ value: "Fasthand" },
|
||||||
{ value: "Dancing Script" },
|
{ value: "Dancing Script" },
|
||||||
@@ -48,19 +51,11 @@ function SignPad({
|
|||||||
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
||||||
);
|
);
|
||||||
const jsonSender = JSON.parse(senderUser);
|
const jsonSender = JSON.parse(senderUser);
|
||||||
|
|
||||||
const currentUserName = jsonSender && jsonSender.name;
|
const currentUserName = jsonSender && jsonSender.name;
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const trimmedName = currentUserName.trim();
|
|
||||||
const firstCharacter = trimmedName.charAt(0);
|
|
||||||
const userName = isInitial ? firstCharacter : currentUserName;
|
|
||||||
setSignValue(userName);
|
|
||||||
setFontSelect("Fasthand");
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, []);
|
|
||||||
//function for clear signature image
|
//function for clear signature image
|
||||||
const handleClear = () => {
|
const handleClear = () => {
|
||||||
|
setCurrWidgetsDetails({});
|
||||||
if (isTab === "draw") {
|
if (isTab === "draw") {
|
||||||
if (canvasRef.current) {
|
if (canvasRef.current) {
|
||||||
canvasRef.current.clear();
|
canvasRef.current.clear();
|
||||||
@@ -72,7 +67,7 @@ function SignPad({
|
|||||||
} else if (isTab === "uploadImage") {
|
} else if (isTab === "uploadImage") {
|
||||||
setImage("");
|
setImage("");
|
||||||
}
|
}
|
||||||
setIsInitial(false);
|
// setIsInitial(false);
|
||||||
};
|
};
|
||||||
//function for set signature url
|
//function for set signature url
|
||||||
const handleSignatureChange = () => {
|
const handleSignatureChange = () => {
|
||||||
@@ -100,27 +95,28 @@ function SignPad({
|
|||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
setCurrWidgetsDetails({});
|
||||||
if (!image) {
|
if (!image) {
|
||||||
if (isTab === "mysignature") {
|
if (isTab === "mysignature") {
|
||||||
setIsSignImg("");
|
setIsSignImg("");
|
||||||
if (isInitial) {
|
if (isInitial) {
|
||||||
onSaveSign("initials");
|
onSaveSign(signatureType, "initials");
|
||||||
} else {
|
} else {
|
||||||
onSaveSign("default");
|
onSaveSign(null, "default");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (isTab === "type") {
|
if (isTab === "type") {
|
||||||
setIsSignImg("");
|
setIsSignImg("");
|
||||||
onSaveSign(false, textWidth, textHeight);
|
onSaveSign(null, false, textWidth, textHeight);
|
||||||
} else {
|
} else {
|
||||||
onSaveSign();
|
onSaveSign(signatureType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setPenColor("blue");
|
setPenColor("blue");
|
||||||
} else {
|
} else {
|
||||||
setIsSignImg("");
|
setIsSignImg("");
|
||||||
onSaveImage();
|
onSaveImage(signatureType);
|
||||||
}
|
}
|
||||||
setIsSignPad(false);
|
setIsSignPad(false);
|
||||||
setIsInitial(false);
|
setIsInitial(false);
|
||||||
@@ -150,11 +146,27 @@ function SignPad({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
//useEffect for set already draw or save signature url/text url of signature text type and draw type for initial type and signature type widgets
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (canvasRef.current && isSignImg) {
|
if (currWidgetsDetails && canvasRef.current) {
|
||||||
canvasRef.current.fromDataURL(isSignImg);
|
const isWidgetType = currWidgetsDetails?.type;
|
||||||
|
const signatureType = currWidgetsDetails?.signatureType;
|
||||||
|
const url = currWidgetsDetails?.SignUrl;
|
||||||
|
|
||||||
|
//checking widget type and draw type signature url
|
||||||
|
if (isInitial) {
|
||||||
|
if (isWidgetType === "initials" && signatureType === "draw" && url) {
|
||||||
|
canvasRef.current.fromDataURL(url);
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
isWidgetType === "signature" &&
|
||||||
|
signatureType === "draw" &&
|
||||||
|
url
|
||||||
|
) {
|
||||||
|
canvasRef.current.fromDataURL(url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const trimmedName = currentUserName.trim();
|
const trimmedName = currentUserName.trim();
|
||||||
const firstCharacter = trimmedName.charAt(0);
|
const firstCharacter = trimmedName.charAt(0);
|
||||||
const userName = isInitial ? firstCharacter : currentUserName;
|
const userName = isInitial ? firstCharacter : currentUserName;
|
||||||
@@ -349,6 +361,7 @@ function SignPad({
|
|||||||
setIsDefaultSign(false);
|
setIsDefaultSign(false);
|
||||||
setIsImageSelect(true);
|
setIsImageSelect(true);
|
||||||
setIsTab("uploadImage");
|
setIsTab("uploadImage");
|
||||||
|
setSignatureType("");
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
color:
|
color:
|
||||||
@@ -373,6 +386,7 @@ function SignPad({
|
|||||||
setIsDefaultSign(false);
|
setIsDefaultSign(false);
|
||||||
setIsImageSelect(false);
|
setIsImageSelect(false);
|
||||||
setIsTab("type");
|
setIsTab("type");
|
||||||
|
setSignatureType("");
|
||||||
setImage();
|
setImage();
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
@@ -400,6 +414,7 @@ function SignPad({
|
|||||||
setIsDefaultSign(true);
|
setIsDefaultSign(true);
|
||||||
setIsImageSelect(true);
|
setIsImageSelect(true);
|
||||||
setIsTab("mysignature");
|
setIsTab("mysignature");
|
||||||
|
setSignatureType("");
|
||||||
setImage();
|
setImage();
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
@@ -430,6 +445,7 @@ function SignPad({
|
|||||||
setIsDefaultSign(true);
|
setIsDefaultSign(true);
|
||||||
setIsImageSelect(true);
|
setIsImageSelect(true);
|
||||||
setIsTab("mysignature");
|
setIsTab("mysignature");
|
||||||
|
setSignatureType("");
|
||||||
setImage();
|
setImage();
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
@@ -469,6 +485,7 @@ function SignPad({
|
|||||||
setIsDefaultSign(false);
|
setIsDefaultSign(false);
|
||||||
setImage();
|
setImage();
|
||||||
setIsTab("draw");
|
setIsTab("draw");
|
||||||
|
setSignatureType("draw");
|
||||||
setSignValue("");
|
setSignValue("");
|
||||||
setIsStamp(false);
|
setIsStamp(false);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ function SignerListPlace(props) {
|
|||||||
data-tut="reactourAddbtn"
|
data-tut="reactourAddbtn"
|
||||||
className="p-[10px] my-[2px] flex flex-row items-center justify-center border-[1px] border-[#47a3ad] hover:bg-[#47a3ad] text-[#47a3ad] hover:text-white cursor-pointer"
|
className="p-[10px] my-[2px] flex flex-row items-center justify-center border-[1px] border-[#47a3ad] hover:bg-[#47a3ad] text-[#47a3ad] hover:text-white cursor-pointer"
|
||||||
onClick={() => props.handleAddSigner()}
|
onClick={() => props.handleAddSigner()}
|
||||||
|
style={{
|
||||||
|
opacity: props.isMailSend && "0.5",
|
||||||
|
pointerEvents: props.isMailSend && "none"
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<i className="fa-solid fa-plus"></i>
|
<i className="fa-solid fa-plus"></i>
|
||||||
<span style={{ marginLeft: 2 }}>Add role</span>
|
<span style={{ marginLeft: 2 }}>Add role</span>
|
||||||
|
|||||||
@@ -364,7 +364,12 @@ function WidgetComponent({
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
<div data-tut={dataTut} className="signerComponent">
|
<div
|
||||||
|
data-tut={dataTut}
|
||||||
|
className={
|
||||||
|
isMailSend ? "disabled signerComponent " : "signerComponent"
|
||||||
|
}
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
background: themeColor,
|
background: themeColor,
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ const SelectFolder = ({ required, onSuccess, folderCls, isReset }) => {
|
|||||||
{selectFolder && selectFolder.Name ? `(${folderPath})` : ""}
|
{selectFolder && selectFolder.Name ? `(${folderPath})` : ""}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="absolute top-1 right-1 cursor-pointer">
|
<div className="absolute top-2 right-1 cursor-pointer">
|
||||||
<Tooltip
|
<Tooltip
|
||||||
message={
|
message={
|
||||||
"If you do not select a folder, your signed document will be saved in the Main OpenSign drive folder."
|
"If you do not select a folder, your signed document will be saved in the Main OpenSign drive folder."
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ const SignersInput = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="text-xs mt-2 ">
|
<div className="text-xs mt-2 ">
|
||||||
<label className="block">
|
<label className="block relative">
|
||||||
Signers
|
Signers
|
||||||
{props.required && <span className="text-red-500 text-[13px]">*</span>}
|
{props.required && <span className="text-red-500 text-[13px]">*</span>}
|
||||||
<span className="absolute ml-1 text-xs z-50">
|
<span className="absolute ml-1 text-xs z-50">
|
||||||
|
|||||||
@@ -935,6 +935,7 @@ export const embedDocId = async (pdfDoc, documentId, allPages) => {
|
|||||||
|
|
||||||
//function for save button to save signature or image url
|
//function for save button to save signature or image url
|
||||||
export function onSaveSign(
|
export function onSaveSign(
|
||||||
|
type,
|
||||||
xyPostion,
|
xyPostion,
|
||||||
index,
|
index,
|
||||||
signKey,
|
signKey,
|
||||||
@@ -975,6 +976,7 @@ export function onSaveSign(
|
|||||||
Width: posWidth,
|
Width: posWidth,
|
||||||
Height: posHeight,
|
Height: posHeight,
|
||||||
SignUrl: signatureImg,
|
SignUrl: signatureImg,
|
||||||
|
signatureType: type && type,
|
||||||
options: {
|
options: {
|
||||||
...position.options,
|
...position.options,
|
||||||
response: signatureImg
|
response: signatureImg
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ function Opensigndrive() {
|
|||||||
const scrollRef = useRef(null);
|
const scrollRef = useRef(null);
|
||||||
const [isList, setIsList] = useState(false);
|
const [isList, setIsList] = useState(false);
|
||||||
const [selectedSort, setSelectedSort] = useState("Date");
|
const [selectedSort, setSelectedSort] = useState("Date");
|
||||||
const [sortingOrder, setSortingOrder] = useState("Decending");
|
const [sortingOrder, setSortingOrder] = useState("Descending");
|
||||||
const [pdfData, setPdfData] = useState([]);
|
const [pdfData, setPdfData] = useState([]);
|
||||||
const [isFolder, setIsFolder] = useState(false);
|
const [isFolder, setIsFolder] = useState(false);
|
||||||
const [newFolderName, setNewFolderName] = useState();
|
const [newFolderName, setNewFolderName] = useState();
|
||||||
@@ -54,6 +54,14 @@ function Opensigndrive() {
|
|||||||
const [skip, setSkip] = useState(0);
|
const [skip, setSkip] = useState(0);
|
||||||
const limit = 100;
|
const limit = 100;
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
const sortOrder = ["Ascending", "Descending"];
|
||||||
|
const sortingValue = ["Name", "Date"];
|
||||||
|
const orderName = {
|
||||||
|
Ascending: "Ascending",
|
||||||
|
Descending: "Descending",
|
||||||
|
Name: "Name",
|
||||||
|
Date: "Date"
|
||||||
|
};
|
||||||
const currentUser =
|
const currentUser =
|
||||||
localStorage.getItem(
|
localStorage.getItem(
|
||||||
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
`Parse/${localStorage.getItem("parseAppId")}/currentUser`
|
||||||
@@ -80,7 +88,7 @@ function Opensigndrive() {
|
|||||||
setHandleError("Error: Something went wrong!");
|
setHandleError("Error: Something went wrong!");
|
||||||
} else if (driveDetails && driveDetails.length > 0) {
|
} else if (driveDetails && driveDetails.length > 0) {
|
||||||
setSkip((prevSkip) => prevSkip + limit);
|
setSkip((prevSkip) => prevSkip + limit);
|
||||||
sortApps("Date", "Decending", driveDetails, true);
|
sortingData(null, null, driveDetails, true);
|
||||||
}
|
}
|
||||||
if (!docId) {
|
if (!docId) {
|
||||||
setFolderName([{ name: "OpenSign™ Drive", objectId: "" }]);
|
setFolderName([{ name: "OpenSign™ Drive", objectId: "" }]);
|
||||||
@@ -114,6 +122,7 @@ function Opensigndrive() {
|
|||||||
//disableLoading is used disable initial loader
|
//disableLoading is used disable initial loader
|
||||||
const disableLoading = true;
|
const disableLoading = true;
|
||||||
// If the fetched data length is less than the limit, it means there's no more data to fetch
|
// If the fetched data length is less than the limit, it means there's no more data to fetch
|
||||||
|
|
||||||
if (!loading && pdfData.length % 100 === 0) {
|
if (!loading && pdfData.length % 100 === 0) {
|
||||||
getPdfDocumentList(disableLoading);
|
getPdfDocumentList(disableLoading);
|
||||||
}
|
}
|
||||||
@@ -129,7 +138,7 @@ function Opensigndrive() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
}, [loading]); // Add/remove scroll event listener when loading changes
|
}, [loading, sortingOrder, selectedSort]); // Add/remove scroll event listener when loading changes
|
||||||
|
|
||||||
//function for handle folder name path
|
//function for handle folder name path
|
||||||
const handleRoute = (index) => {
|
const handleRoute = (index) => {
|
||||||
@@ -210,35 +219,38 @@ function Opensigndrive() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const sortingApp = (appInfo, type, order) => {
|
//function to use sorting document list according to type and order
|
||||||
if (type === "Name") {
|
const sortedBy = (appInfo, type, order) => {
|
||||||
if (order === "Accending") {
|
if (type === orderName.Name) {
|
||||||
|
if (order === orderName.Ascending) {
|
||||||
return appInfo.sort((a, b) => (a.Name > b.Name ? 1 : -1));
|
return appInfo.sort((a, b) => (a.Name > b.Name ? 1 : -1));
|
||||||
} else if (order === "Decending") {
|
} else if (order === orderName.Descending) {
|
||||||
return appInfo.sort((a, b) => (a.Name > b.Name ? -1 : 1));
|
return appInfo.sort((a, b) => (a.Name > b.Name ? -1 : 1));
|
||||||
}
|
}
|
||||||
} else if (type === "Date") {
|
} else if (type === orderName.Date) {
|
||||||
if (order === "Accending") {
|
if (order === orderName.Ascending) {
|
||||||
return appInfo.sort((a, b) => (a.createdAt > b.createdAt ? 1 : -1));
|
return appInfo.sort((a, b) => (a.createdAt > b.createdAt ? 1 : -1));
|
||||||
} else if (order === "Decending") {
|
} else if (order === orderName.Descending) {
|
||||||
return appInfo.sort((a, b) => (a.createdAt > b.createdAt ? -1 : 1));
|
return appInfo.sort((a, b) => (a.createdAt > b.createdAt ? -1 : 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const sortApps = (type, order, driveDetails, isInitial) => {
|
//function to use get sorting type, order and document list to sort
|
||||||
const selectedSortType = type ? type : selectedSort ? selectedSort : "Date";
|
const sortingData = (type, order, driveDetails, isInitial) => {
|
||||||
const sortOrder = order ? order : sortingOrder ? sortingOrder : "Decending";
|
const selectedSortType = type ? type : selectedSort;
|
||||||
if (selectedSortType === "Name") {
|
const sortOrder = order ? order : sortingOrder;
|
||||||
sortingApp(driveDetails, "Name", sortOrder);
|
|
||||||
} else if (selectedSortType === "Date") {
|
//check isInitial true it means sort previous 20 and get on scrolling 20 = 40 document list
|
||||||
sortingApp(driveDetails, "Date", sortOrder);
|
const allPdfData = isInitial ? [...pdfData, ...driveDetails] : driveDetails;
|
||||||
}
|
//call sortedBy function according to selected Type and order
|
||||||
if (isInitial) {
|
if (selectedSortType === orderName.Name) {
|
||||||
setPdfData([...pdfData, ...driveDetails]);
|
sortedBy(allPdfData, orderName.Name, sortOrder);
|
||||||
} else {
|
} else if (selectedSortType === orderName.Date) {
|
||||||
setPdfData(driveDetails);
|
sortedBy(allPdfData, orderName.Date, sortOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setPdfData(allPdfData);
|
||||||
};
|
};
|
||||||
|
|
||||||
//function for handle auto scroll on folder path
|
//function for handle auto scroll on folder path
|
||||||
@@ -611,95 +623,56 @@ function Opensigndrive() {
|
|||||||
aria-labelledby="dropdownMenuButton"
|
aria-labelledby="dropdownMenuButton"
|
||||||
aria-expanded={isShowSort ? "true" : "false"}
|
aria-expanded={isShowSort ? "true" : "false"}
|
||||||
>
|
>
|
||||||
<span
|
{sortingValue.map((value, ind) => {
|
||||||
onClick={() => {
|
return (
|
||||||
setSelectedSort("Name");
|
<span
|
||||||
sortApps("Name", null, pdfData);
|
key={ind}
|
||||||
}}
|
onClick={() => {
|
||||||
className="dropdown-item itemColor"
|
setSelectedSort(value);
|
||||||
>
|
sortingData(value, null, pdfData);
|
||||||
{selectedSort !== "Name" ? (
|
}}
|
||||||
<i
|
className="dropdown-item itemColor"
|
||||||
className="fa fa-arrow-up"
|
style={{
|
||||||
aria-hidden="true"
|
paddingLeft: selectedSort !== value && "33px"
|
||||||
style={{ marginRight: "5px" }}
|
}}
|
||||||
></i>
|
>
|
||||||
) : (
|
{selectedSort === value && (
|
||||||
<i
|
<i
|
||||||
className="fa fa-check"
|
className="fa fa-check"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
style={{ marginRight: "5px" }}
|
style={{ marginRight: "5px" }}
|
||||||
></i>
|
></i>
|
||||||
)}
|
)}
|
||||||
Name
|
{value}
|
||||||
</span>
|
</span>
|
||||||
<span
|
);
|
||||||
onClick={() => {
|
})}
|
||||||
setSelectedSort("Date");
|
|
||||||
sortApps("Date", null, pdfData);
|
|
||||||
}}
|
|
||||||
className="dropdown-item itemColor"
|
|
||||||
>
|
|
||||||
{selectedSort !== "Date" ? (
|
|
||||||
<i
|
|
||||||
className="fa fa-arrow-up"
|
|
||||||
aria-hidden="true"
|
|
||||||
style={{ marginRight: "5px" }}
|
|
||||||
></i>
|
|
||||||
) : (
|
|
||||||
<i
|
|
||||||
className="fa fa-check"
|
|
||||||
aria-hidden="true"
|
|
||||||
style={{ marginRight: "5px" }}
|
|
||||||
></i>
|
|
||||||
)}
|
|
||||||
Date
|
|
||||||
</span>
|
|
||||||
<hr className="hrStyle" />
|
<hr className="hrStyle" />
|
||||||
<span
|
{sortOrder.map((order, ind) => {
|
||||||
onClick={() => {
|
return (
|
||||||
setSortingOrder("Accending");
|
<span
|
||||||
sortApps(null, "Accending", pdfData);
|
key={ind}
|
||||||
}}
|
onClick={() => {
|
||||||
className="dropdown-item itemColor"
|
setSortingOrder(order);
|
||||||
>
|
sortingData(null, order, pdfData);
|
||||||
{sortingOrder !== "Accending" ? (
|
}}
|
||||||
<i
|
className="dropdown-item itemColor"
|
||||||
className="fa fa-arrow-up"
|
style={{
|
||||||
aria-hidden="true"
|
paddingLeft: sortingOrder !== order && "33px"
|
||||||
style={{ marginRight: "5px" }}
|
}}
|
||||||
></i>
|
>
|
||||||
) : (
|
{sortingOrder === order && (
|
||||||
<i
|
<i
|
||||||
className="fa fa-check"
|
className="fa fa-check"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
style={{ marginRight: "5px" }}
|
style={{ marginRight: "5px" }}
|
||||||
></i>
|
></i>
|
||||||
)}
|
)}
|
||||||
Accending
|
{order}
|
||||||
</span>
|
</span>
|
||||||
<span
|
);
|
||||||
onClick={() => {
|
})}
|
||||||
setSortingOrder("Decending");
|
|
||||||
sortApps(null, "Decending", pdfData);
|
|
||||||
}}
|
|
||||||
className="dropdown-item itemColor"
|
|
||||||
>
|
|
||||||
{sortingOrder !== "Decending" ? (
|
|
||||||
<i
|
|
||||||
className="fa fa-arrow-up"
|
|
||||||
aria-hidden="true"
|
|
||||||
style={{ marginRight: "5px" }}
|
|
||||||
></i>
|
|
||||||
) : (
|
|
||||||
<i
|
|
||||||
className="fa fa-check"
|
|
||||||
aria-hidden="true"
|
|
||||||
style={{ marginRight: "5px" }}
|
|
||||||
></i>
|
|
||||||
)}
|
|
||||||
Decending
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { useParams } from "react-router-dom";
|
|||||||
import SignPad from "../components/pdf/SignPad";
|
import SignPad from "../components/pdf/SignPad";
|
||||||
import RenderAllPdfPage from "../components/pdf/RenderAllPdfPage";
|
import RenderAllPdfPage from "../components/pdf/RenderAllPdfPage";
|
||||||
import Tour from "reactour";
|
import Tour from "reactour";
|
||||||
|
import moment from "moment";
|
||||||
import {
|
import {
|
||||||
contractDocument,
|
contractDocument,
|
||||||
multiSignEmbed,
|
multiSignEmbed,
|
||||||
@@ -65,6 +66,7 @@ function PdfRequestFiles() {
|
|||||||
const [currentSigner, setCurrentSigner] = useState(false);
|
const [currentSigner, setCurrentSigner] = useState(false);
|
||||||
const [isAlert, setIsAlert] = useState({ isShow: false, alertMessage: "" });
|
const [isAlert, setIsAlert] = useState({ isShow: false, alertMessage: "" });
|
||||||
const [unSignedWidgetId, setUnSignedWidgetId] = useState("");
|
const [unSignedWidgetId, setUnSignedWidgetId] = useState("");
|
||||||
|
const [expiredDate, setExpiredDate] = useState("");
|
||||||
const [defaultSignAlert, setDefaultSignAlert] = useState({
|
const [defaultSignAlert, setDefaultSignAlert] = useState({
|
||||||
isShow: false,
|
isShow: false,
|
||||||
alertMessage: ""
|
alertMessage: ""
|
||||||
@@ -87,6 +89,7 @@ function PdfRequestFiles() {
|
|||||||
const [widgetsTour, setWidgetsTour] = useState(false);
|
const [widgetsTour, setWidgetsTour] = useState(false);
|
||||||
const [minRequiredCount, setminRequiredCount] = useState();
|
const [minRequiredCount, setminRequiredCount] = useState();
|
||||||
const [sendInOrder, setSendInOrder] = useState(false);
|
const [sendInOrder, setSendInOrder] = useState(false);
|
||||||
|
const [currWidgetsDetails, setCurrWidgetsDetails] = useState({});
|
||||||
const divRef = useRef(null);
|
const divRef = useRef(null);
|
||||||
const isMobile = window.innerWidth < 767;
|
const isMobile = window.innerWidth < 767;
|
||||||
const rowLevel =
|
const rowLevel =
|
||||||
@@ -167,7 +170,11 @@ function PdfRequestFiles() {
|
|||||||
};
|
};
|
||||||
setIsDecline(currentDecline);
|
setIsDecline(currentDecline);
|
||||||
} else if (currDate > expireUpdateDate) {
|
} else if (currDate > expireUpdateDate) {
|
||||||
|
const expireDateFormat = moment(new Date(expireDate)).format(
|
||||||
|
"MMM DD, YYYY"
|
||||||
|
);
|
||||||
setIsExpired(true);
|
setIsExpired(true);
|
||||||
|
setExpiredDate(expireDateFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (documentData.length > 0) {
|
if (documentData.length > 0) {
|
||||||
@@ -367,7 +374,6 @@ function PdfRequestFiles() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//function for embed signature or image url in pdf
|
//function for embed signature or image url in pdf
|
||||||
async function embedWidgetsData() {
|
async function embedWidgetsData() {
|
||||||
const validateSigning = checkSendInOrder();
|
const validateSigning = checkSendInOrder();
|
||||||
@@ -731,7 +737,7 @@ function PdfRequestFiles() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//function for save button to save signature or image url
|
//function for save button to save signature or image url
|
||||||
const saveSign = (isDefaultSign, width, height) => {
|
const saveSign = (type, isDefaultSign, width, height) => {
|
||||||
const isTypeText = width && height ? true : false;
|
const isTypeText = width && height ? true : false;
|
||||||
const signatureImg = isDefaultSign
|
const signatureImg = isDefaultSign
|
||||||
? isDefaultSign === "initials"
|
? isDefaultSign === "initials"
|
||||||
@@ -767,6 +773,7 @@ function PdfRequestFiles() {
|
|||||||
const placeholderPosition = currentSigner[0].placeHolder;
|
const placeholderPosition = currentSigner[0].placeHolder;
|
||||||
//function of save signature image and get updated position with signature image url
|
//function of save signature image and get updated position with signature image url
|
||||||
const getUpdatePosition = onSaveSign(
|
const getUpdatePosition = onSaveSign(
|
||||||
|
type,
|
||||||
placeholderPosition,
|
placeholderPosition,
|
||||||
getIndex,
|
getIndex,
|
||||||
signKey,
|
signKey,
|
||||||
@@ -926,7 +933,17 @@ function PdfRequestFiles() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="signatureContainer" ref={divRef}>
|
<div
|
||||||
|
className="signatureContainer"
|
||||||
|
style={{
|
||||||
|
pointerEvents:
|
||||||
|
isExpired ||
|
||||||
|
(isDecline.isDeclined && isDecline.currnt === "another")
|
||||||
|
? "none"
|
||||||
|
: "auto"
|
||||||
|
}}
|
||||||
|
ref={divRef}
|
||||||
|
>
|
||||||
<ModalUi
|
<ModalUi
|
||||||
headerColor={"#dc3545"}
|
headerColor={"#dc3545"}
|
||||||
isOpen={isAlert.isShow}
|
isOpen={isAlert.isShow}
|
||||||
@@ -999,7 +1016,7 @@ function PdfRequestFiles() {
|
|||||||
containerWH={containerWH}
|
containerWH={containerWH}
|
||||||
show={isExpired}
|
show={isExpired}
|
||||||
headMsg="Document Expired!"
|
headMsg="Document Expired!"
|
||||||
bodyMssg="This Document is no longer available."
|
bodyMssg={`This document expired on ${expiredDate} and is no longer available to sign.`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ModalUi
|
<ModalUi
|
||||||
@@ -1133,6 +1150,8 @@ function PdfRequestFiles() {
|
|||||||
isInitial={isInitial}
|
isInitial={isInitial}
|
||||||
setIsInitial={setIsInitial}
|
setIsInitial={setIsInitial}
|
||||||
setIsStamp={setIsStamp}
|
setIsStamp={setIsStamp}
|
||||||
|
currWidgetsDetails={currWidgetsDetails}
|
||||||
|
setCurrWidgetsDetails={setCurrWidgetsDetails}
|
||||||
/>
|
/>
|
||||||
{/* pdf header which contain funish back button */}
|
{/* pdf header which contain funish back button */}
|
||||||
<Header
|
<Header
|
||||||
@@ -1179,6 +1198,7 @@ function PdfRequestFiles() {
|
|||||||
unSignedWidgetId={unSignedWidgetId}
|
unSignedWidgetId={unSignedWidgetId}
|
||||||
setSelectWidgetId={setSelectWidgetId}
|
setSelectWidgetId={setSelectWidgetId}
|
||||||
selectWidgetId={selectWidgetId}
|
selectWidgetId={selectWidgetId}
|
||||||
|
setCurrWidgetsDetails={setCurrWidgetsDetails}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ function PlaceHolderSign() {
|
|||||||
const [widgetType, setWidgetType] = useState("");
|
const [widgetType, setWidgetType] = useState("");
|
||||||
const [isUiLoading, setIsUiLoading] = useState(false);
|
const [isUiLoading, setIsUiLoading] = useState(false);
|
||||||
const [isRadio, setIsRadio] = useState(false);
|
const [isRadio, setIsRadio] = useState(false);
|
||||||
const [currWidgetsDetails, setCurrWidgetsDetails] = useState([]);
|
const [currWidgetsDetails, setCurrWidgetsDetails] = useState({});
|
||||||
const [selectWidgetId, setSelectWidgetId] = useState("");
|
const [selectWidgetId, setSelectWidgetId] = useState("");
|
||||||
const [isCheckbox, setIsCheckbox] = useState(false);
|
const [isCheckbox, setIsCheckbox] = useState(false);
|
||||||
const [isNameModal, setIsNameModal] = useState(false);
|
const [isNameModal, setIsNameModal] = useState(false);
|
||||||
@@ -1450,7 +1450,7 @@ function PlaceHolderSign() {
|
|||||||
{isSendAlert.mssg === "sure" ? (
|
{isSendAlert.mssg === "sure" ? (
|
||||||
<p>Please add field for all recipients.</p>
|
<p>Please add field for all recipients.</p>
|
||||||
) : isSendAlert.mssg === textWidget ? (
|
) : isSendAlert.mssg === textWidget ? (
|
||||||
<p>Please confirm that you have filled label widget.</p>
|
<p>Please confirm that you have filled the text field.</p>
|
||||||
) : (
|
) : (
|
||||||
isSendAlert.mssg === "confirm" && (
|
isSendAlert.mssg === "confirm" && (
|
||||||
<p>
|
<p>
|
||||||
@@ -1716,9 +1716,11 @@ function PlaceHolderSign() {
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div>
|
<div>
|
||||||
<div className="signerComponent">
|
<div className="signerComponent" aria-disabled>
|
||||||
<div
|
<div
|
||||||
style={{ maxHeight: window.innerHeight - 70 + "px" }}
|
style={{
|
||||||
|
maxHeight: window.innerHeight - 70 + "px"
|
||||||
|
}}
|
||||||
className="autoSignScroll"
|
className="autoSignScroll"
|
||||||
>
|
>
|
||||||
<SignerListPlace
|
<SignerListPlace
|
||||||
@@ -1734,11 +1736,12 @@ function PlaceHolderSign() {
|
|||||||
setSignersData={setSignersData}
|
setSignersData={setSignersData}
|
||||||
blockColor={blockColor}
|
blockColor={blockColor}
|
||||||
setBlockColor={setBlockColor}
|
setBlockColor={setBlockColor}
|
||||||
|
isMailSend={isMailSend}
|
||||||
// handleAddSigner={handleAddSigner}
|
// handleAddSigner={handleAddSigner}
|
||||||
/>
|
/>
|
||||||
<div data-tut="reactourSecond">
|
<div data-tut="reactourSecond">
|
||||||
<WidgetComponent
|
<WidgetComponent
|
||||||
pdfUrl={isMailSend}
|
isMailSend={isMailSend}
|
||||||
dragSignature={dragSignature}
|
dragSignature={dragSignature}
|
||||||
signRef={signRef}
|
signRef={signRef}
|
||||||
handleDivClick={handleDivClick}
|
handleDivClick={handleDivClick}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ function SignYourSelf() {
|
|||||||
const [showAlreadySignDoc, setShowAlreadySignDoc] = useState({
|
const [showAlreadySignDoc, setShowAlreadySignDoc] = useState({
|
||||||
status: false
|
status: false
|
||||||
});
|
});
|
||||||
const [currWidgetsDetails, setCurrWidgetsDetails] = useState([]);
|
const [currWidgetsDetails, setCurrWidgetsDetails] = useState({});
|
||||||
const [isCheckbox, setIsCheckbox] = useState(false);
|
const [isCheckbox, setIsCheckbox] = useState(false);
|
||||||
const [widgetType, setWidgetType] = useState("");
|
const [widgetType, setWidgetType] = useState("");
|
||||||
const [pdfLoadFail, setPdfLoadFail] = useState({
|
const [pdfLoadFail, setPdfLoadFail] = useState({
|
||||||
@@ -180,14 +180,14 @@ function SignYourSelf() {
|
|||||||
|
|
||||||
//function for get document details for perticular signer with signer'object id
|
//function for get document details for perticular signer with signer'object id
|
||||||
const getDocumentDetails = async (showComplete) => {
|
const getDocumentDetails = async (showComplete) => {
|
||||||
|
let isCompleted;
|
||||||
//getting document details
|
//getting document details
|
||||||
const documentData = await contractDocument(documentId);
|
const documentData = await contractDocument(documentId);
|
||||||
|
|
||||||
if (documentData && documentData.length > 0) {
|
if (documentData && documentData.length > 0) {
|
||||||
setPdfDetails(documentData);
|
setPdfDetails(documentData);
|
||||||
|
|
||||||
const isCompleted =
|
isCompleted = documentData[0].IsCompleted && documentData[0].IsCompleted;
|
||||||
documentData[0].IsCompleted && documentData[0].IsCompleted;
|
|
||||||
if (isCompleted) {
|
if (isCompleted) {
|
||||||
const docStatus = {
|
const docStatus = {
|
||||||
isCompleted: isCompleted
|
isCompleted: isCompleted
|
||||||
@@ -263,8 +263,7 @@ function SignYourSelf() {
|
|||||||
setSignerUserId(contractUsersRes[0].objectId);
|
setSignerUserId(contractUsersRes[0].objectId);
|
||||||
const tourstatuss =
|
const tourstatuss =
|
||||||
contractUsersRes[0].TourStatus && contractUsersRes[0].TourStatus;
|
contractUsersRes[0].TourStatus && contractUsersRes[0].TourStatus;
|
||||||
|
if (tourstatuss && tourstatuss.length > 0 && !isCompleted) {
|
||||||
if (tourstatuss && tourstatuss.length > 0) {
|
|
||||||
setTourStatus(tourstatuss);
|
setTourStatus(tourstatuss);
|
||||||
const checkTourRecipients = tourstatuss.filter(
|
const checkTourRecipients = tourstatuss.filter(
|
||||||
(data) => data.signyourself
|
(data) => data.signyourself
|
||||||
@@ -272,6 +271,8 @@ function SignYourSelf() {
|
|||||||
if (checkTourRecipients && checkTourRecipients.length > 0) {
|
if (checkTourRecipients && checkTourRecipients.length > 0) {
|
||||||
setCheckTourStatus(checkTourRecipients[0].signyourself);
|
setCheckTourStatus(checkTourRecipients[0].signyourself);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
setCheckTourStatus(true);
|
||||||
}
|
}
|
||||||
const loadObj = {
|
const loadObj = {
|
||||||
isLoad: false
|
isLoad: false
|
||||||
@@ -291,7 +292,8 @@ function SignYourSelf() {
|
|||||||
const tourstatuss =
|
const tourstatuss =
|
||||||
contractContactBook[0].TourStatus &&
|
contractContactBook[0].TourStatus &&
|
||||||
contractContactBook[0].TourStatus;
|
contractContactBook[0].TourStatus;
|
||||||
if (tourstatuss && tourstatuss.length > 0) {
|
|
||||||
|
if (tourstatuss && tourstatuss.length > 0 && !isCompleted) {
|
||||||
setTourStatus(tourstatuss);
|
setTourStatus(tourstatuss);
|
||||||
const checkTourRecipients = tourstatuss.filter(
|
const checkTourRecipients = tourstatuss.filter(
|
||||||
(data) => data.signyourself
|
(data) => data.signyourself
|
||||||
@@ -299,6 +301,8 @@ function SignYourSelf() {
|
|||||||
if (checkTourRecipients && checkTourRecipients.length > 0) {
|
if (checkTourRecipients && checkTourRecipients.length > 0) {
|
||||||
setCheckTourStatus(checkTourRecipients[0].signyourself);
|
setCheckTourStatus(checkTourRecipients[0].signyourself);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
setCheckTourStatus(true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setHandleError("No Data Found!");
|
setHandleError("No Data Found!");
|
||||||
@@ -704,7 +708,7 @@ function SignYourSelf() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//function for save button to save signature or image url
|
//function for save button to save signature or image url
|
||||||
const saveSign = (isDefaultSign, width, height) => {
|
const saveSign = (type, isDefaultSign, width, height) => {
|
||||||
const isTypeText = width && height ? true : false;
|
const isTypeText = width && height ? true : false;
|
||||||
const signatureImg = isDefaultSign
|
const signatureImg = isDefaultSign
|
||||||
? isDefaultSign === "initials"
|
? isDefaultSign === "initials"
|
||||||
@@ -727,6 +731,7 @@ function SignYourSelf() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const getUpdatePosition = onSaveSign(
|
const getUpdatePosition = onSaveSign(
|
||||||
|
type,
|
||||||
xyPostion,
|
xyPostion,
|
||||||
index,
|
index,
|
||||||
signKey,
|
signKey,
|
||||||
@@ -763,6 +768,7 @@ function SignYourSelf() {
|
|||||||
|
|
||||||
//function for delete signature block
|
//function for delete signature block
|
||||||
const handleDeleteSign = (key) => {
|
const handleDeleteSign = (key) => {
|
||||||
|
setCurrWidgetsDetails({});
|
||||||
const updateResizeData = [];
|
const updateResizeData = [];
|
||||||
|
|
||||||
let filterData = xyPostion[index].pos.filter((data) => data.key !== key);
|
let filterData = xyPostion[index].pos.filter((data) => data.key !== key);
|
||||||
@@ -1101,6 +1107,8 @@ function SignYourSelf() {
|
|||||||
setIsInitial={setIsInitial}
|
setIsInitial={setIsInitial}
|
||||||
setIsStamp={setIsStamp}
|
setIsStamp={setIsStamp}
|
||||||
widgetType={widgetType}
|
widgetType={widgetType}
|
||||||
|
currWidgetsDetails={currWidgetsDetails}
|
||||||
|
setCurrWidgetsDetails={setCurrWidgetsDetails}
|
||||||
/>
|
/>
|
||||||
{/*render email component to send email after finish signature on document */}
|
{/*render email component to send email after finish signature on document */}
|
||||||
<EmailComponent
|
<EmailComponent
|
||||||
|
|||||||
@@ -1464,6 +1464,7 @@ const TemplatePlaceholder = () => {
|
|||||||
className="autoSignScroll"
|
className="autoSignScroll"
|
||||||
>
|
>
|
||||||
<SignerListPlace
|
<SignerListPlace
|
||||||
|
isMailSend={isMailSend}
|
||||||
signerPos={signerPos}
|
signerPos={signerPos}
|
||||||
signersdata={signersdata}
|
signersdata={signersdata}
|
||||||
isSelectListId={isSelectListId}
|
isSelectListId={isSelectListId}
|
||||||
@@ -1484,7 +1485,7 @@ const TemplatePlaceholder = () => {
|
|||||||
/>
|
/>
|
||||||
<div data-tut="reactourSecond">
|
<div data-tut="reactourSecond">
|
||||||
<WidgetComponent
|
<WidgetComponent
|
||||||
pdfUrl={isMailSend}
|
isMailSend={isMailSend}
|
||||||
dragSignature={dragSignature}
|
dragSignature={dragSignature}
|
||||||
signRef={signRef}
|
signRef={signRef}
|
||||||
handleDivClick={handleDivClick}
|
handleDivClick={handleDivClick}
|
||||||
|
|||||||
@@ -1,14 +1,21 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Tooltip as ReactTooltip } from "react-tooltip";
|
import { Tooltip as ReactTooltip } from "react-tooltip";
|
||||||
import { openInNewTab } from "../constant/Utils";
|
import { openInNewTab } from "../constant/Utils";
|
||||||
const Tooltip = ({ children, id, message, url, iconColor }) =>
|
const Tooltip = ({ id, message, url, iconColor }) =>
|
||||||
url ? (
|
url ? (
|
||||||
<button onClick={() => openInNewTab(url)} className="text-center">
|
<button onClick={() => openInNewTab(url)} className="text-center">
|
||||||
{children ? (
|
<sup>
|
||||||
children
|
<i
|
||||||
) : (
|
className="fa-solid fa-question rounded-full"
|
||||||
<i className="fa-solid fa-question text-xs border-[1.5px] px-1 rounded-full border-[#33bbff] text-[#33bbff]"></i>
|
style={{
|
||||||
)}
|
borderColor: iconColor ? iconColor : "#33bbff",
|
||||||
|
color: iconColor ? iconColor : "#33bbff",
|
||||||
|
fontSize: 13,
|
||||||
|
borderWidth: 1.5,
|
||||||
|
padding: "1.5px 4px"
|
||||||
|
}}
|
||||||
|
></i>
|
||||||
|
</sup>
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
@@ -17,17 +24,18 @@ const Tooltip = ({ children, id, message, url, iconColor }) =>
|
|||||||
data-tooltip-content={message}
|
data-tooltip-content={message}
|
||||||
className="z-50"
|
className="z-50"
|
||||||
>
|
>
|
||||||
{children ? (
|
<sup>
|
||||||
children
|
|
||||||
) : (
|
|
||||||
<i
|
<i
|
||||||
className="fa-solid fa-question text-xs border-[1.5px] px-1 rounded-full border-[#33bbff] text-[#33bbff]"
|
className="fa-solid fa-question rounded-full"
|
||||||
style={{
|
style={{
|
||||||
borderColor: iconColor ? iconColor : "#33bbff",
|
borderColor: iconColor ? iconColor : "#33bbff",
|
||||||
color: iconColor ? iconColor : "#33bbff"
|
color: iconColor ? iconColor : "#33bbff",
|
||||||
|
fontSize: 13,
|
||||||
|
borderWidth: 1.5,
|
||||||
|
padding: "1.5px 4px"
|
||||||
}}
|
}}
|
||||||
></i>
|
></i>
|
||||||
)}
|
</sup>
|
||||||
</a>
|
</a>
|
||||||
<ReactTooltip id={id ? id : "my-tooltip"} className="max-w-[200px]" />
|
<ReactTooltip id={id ? id : "my-tooltip"} className="max-w-[200px]" />
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -496,7 +496,11 @@
|
|||||||
overflow: hidden !important;
|
overflow: hidden !important;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
.disabled {
|
||||||
|
opacity: 0.5; /* Example: reduce opacity to visually indicate disabled state */
|
||||||
|
pointer-events: none; /* Prevents mouse clicks and other events */
|
||||||
|
/* background-color: #888; */
|
||||||
|
}
|
||||||
.useEmail {
|
.useEmail {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
color: #424242;
|
color: #424242;
|
||||||
|
|||||||
Reference in New Issue
Block a user