mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-09-05 01:07:39 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
879279a382 | ||
|
|
74df84e449 | ||
|
|
2862ae3302 | ||
|
|
7d0dfe480c | ||
|
|
c47748ed4d | ||
|
|
396504138c | ||
|
|
6e067a160c | ||
|
|
63b2693fe0 | ||
|
|
76a69d8f3b | ||
|
|
5cd0f55cb2 | ||
|
|
db640b04a6 | ||
|
|
0665bcf30a | ||
|
|
7e8ed42f46 | ||
|
|
8d7b1a5b9b | ||
|
|
c6829a7d5e | ||
|
|
bef8fbf183 | ||
|
|
fca95f09cc | ||
|
|
4d6cdf8823 | ||
|
|
e34f52dcc5 | ||
|
|
91cc4e6f3d | ||
|
|
429b7dcb0e | ||
|
|
5ffa681a80 | ||
|
|
91364db608 | ||
|
|
2433c68f27 | ||
|
|
6ea254d9ac | ||
|
|
a4d1df8324 | ||
|
|
ba15611903 | ||
|
|
eda6113792 | ||
|
|
4f1509c836 | ||
|
|
dfcf32ef3e | ||
|
|
4a95257ee2 | ||
|
|
ee1e13ef61 | ||
|
|
c9c099ffc5 | ||
|
|
a80f4fb3c9 | ||
|
|
941f3ac47f | ||
|
|
80d3200d57 | ||
|
|
55926e25d2 | ||
|
|
a31f3ebad7 | ||
|
|
dc9c32c6ee | ||
|
|
dac3aac2a1 | ||
|
|
40196e823c | ||
|
|
7708b7e938 | ||
|
|
8bbc5a9bc6 | ||
|
|
4dbdfb1b77 | ||
|
|
05c51edce3 | ||
|
|
379e8cd95e | ||
|
|
9fd00d4427 | ||
|
|
ca114cf124 | ||
|
|
75128784db | ||
|
|
722f0e277e | ||
|
|
7089998966 | ||
|
|
52211ddfa4 | ||
|
|
2b8b762d35 | ||
|
|
a9c08c8a9f | ||
|
|
9406c4f718 | ||
|
|
531ef4d0b2 | ||
|
|
4c6dbb6690 | ||
|
|
0beb60d1b5 | ||
|
|
893c9d7c42 | ||
|
|
c442689573 | ||
|
|
88919f2634 | ||
|
|
50557d8bc5 | ||
|
|
0f1ef0406e | ||
|
|
9852c87be7 | ||
|
|
1268f65516 | ||
|
|
6551b2537a | ||
|
|
b138ccf625 | ||
|
|
27ff7baa6d | ||
|
|
3fc41f4255 | ||
|
|
b20aa33a04 | ||
|
|
a64da4cd85 | ||
|
|
e80bcfc586 | ||
|
|
de5b8160a2 | ||
|
|
83df969751 | ||
|
|
f04fd16c9e |
Generated
+1252
-846
File diff suppressed because it is too large
Load Diff
+22
-21
@@ -4,14 +4,14 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@formkit/auto-animate": "^0.8.2",
|
"@formkit/auto-animate": "^0.8.2",
|
||||||
"@lottiefiles/dotlottie-react": "^0.8.9",
|
"@lottiefiles/dotlottie-react": "^0.9.0",
|
||||||
"@pdf-lib/fontkit": "^1.1.1",
|
"@pdf-lib/fontkit": "^1.1.1",
|
||||||
"@radix-ui/themes": "^3.1.3",
|
"@radix-ui/themes": "^3.1.3",
|
||||||
"@react-pdf/renderer": "^3.4.4",
|
"@react-pdf/renderer": "^4.0.0",
|
||||||
"@reduxjs/toolkit": "^2.2.7",
|
"@reduxjs/toolkit": "^2.2.7",
|
||||||
"axios": "^1.7.5",
|
"axios": "^1.7.7",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"i18next": "^23.14.0",
|
"i18next": "^23.15.1",
|
||||||
"i18next-browser-languagedetector": "^8.0.0",
|
"i18next-browser-languagedetector": "^8.0.0",
|
||||||
"i18next-http-backend": "^2.6.1",
|
"i18next-http-backend": "^2.6.1",
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
@@ -23,10 +23,10 @@
|
|||||||
"print-js": "^1.6.0",
|
"print-js": "^1.6.0",
|
||||||
"radix-ui": "^1.0.1",
|
"radix-ui": "^1.0.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-bootstrap": "^2.10.4",
|
"react-bootstrap": "^2.10.5",
|
||||||
"react-confetti": "^6.1.0",
|
"react-confetti": "^6.1.0",
|
||||||
"react-cookie": "^7.2.0",
|
"react-cookie": "^7.2.0",
|
||||||
"react-datepicker": "^7.3.0",
|
"react-datepicker": "^7.4.0",
|
||||||
"react-dnd": "^16.0.1",
|
"react-dnd": "^16.0.1",
|
||||||
"react-dnd-html5-backend": "^16.0.1",
|
"react-dnd-html5-backend": "^16.0.1",
|
||||||
"react-dnd-multi-backend": "^8.0.3",
|
"react-dnd-multi-backend": "^8.0.3",
|
||||||
@@ -34,17 +34,18 @@
|
|||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-gtm-module": "^2.0.11",
|
"react-gtm-module": "^2.0.11",
|
||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
"react-i18next": "^15.0.1",
|
"react-i18next": "^15.0.2",
|
||||||
"react-konva": "^18.2.10",
|
"react-konva": "^18.2.10",
|
||||||
"react-pdf": "^9.1.0",
|
"react-pdf": "^9.1.1",
|
||||||
"react-quill-new": "^3.3.0",
|
"react-quill-new": "^3.3.2",
|
||||||
"react-redux": "^9.1.2",
|
"react-redux": "^9.1.2",
|
||||||
"react-rnd": "^10.4.11",
|
"react-rnd": "^10.4.13",
|
||||||
"react-router-dom": "^6.26.1",
|
"react-router-dom": "^6.26.2",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"react-scrollbars-custom": "^4.1.1",
|
"react-scrollbars-custom": "^4.1.1",
|
||||||
"react-select": "^5.8.0",
|
"react-select": "^5.8.1",
|
||||||
"react-signature-canvas": "^1.0.6",
|
"react-signature-canvas": "^1.0.6",
|
||||||
|
"react-syntax-highlighter": "^15.5.0",
|
||||||
"react-tooltip": "^5.28.0",
|
"react-tooltip": "^5.28.0",
|
||||||
"react-web-share": "^2.0.2",
|
"react-web-share": "^2.0.2",
|
||||||
"reactour": "^1.19.4",
|
"reactour": "^1.19.4",
|
||||||
@@ -60,7 +61,7 @@
|
|||||||
"build-webpack": "webpack --config webpack.config.js",
|
"build-webpack": "webpack --config webpack.config.js",
|
||||||
"build": "npm run version && npm run build-webpack && react-scripts build",
|
"build": "npm run version && npm run build-webpack && react-scripts build",
|
||||||
"build-watch": "webpack --config webpack.config.js --watch",
|
"build-watch": "webpack --config webpack.config.js --watch",
|
||||||
"start-dev": "concurrently \"npm run build-watch\" \"react-scripts start\"",
|
"start-dev": "react-scripts start",
|
||||||
"start": "serve -s build",
|
"start": "serve -s build",
|
||||||
"version": "curl -s https://api.github.com/repos/opensignlabs/opensign/releases/latest | grep '\"tag_name\":' | awk -F '\"' '{print $4}' > ./public/version.txt",
|
"version": "curl -s https://api.github.com/repos/opensignlabs/opensign/releases/latest | grep '\"tag_name\":' | awk -F '\"' '{print $4}' > ./public/version.txt",
|
||||||
"version-win": "powershell -Command \"Invoke-RestMethod -Uri 'https://api.github.com/repos/opensignlabs/opensign/releases/latest' | Select-Object -ExpandProperty tag_name | Out-File -FilePath ./public/version.txt\"",
|
"version-win": "powershell -Command \"Invoke-RestMethod -Uri 'https://api.github.com/repos/opensignlabs/opensign/releases/latest' | Select-Object -ExpandProperty tag_name | Out-File -FilePath ./public/version.txt\"",
|
||||||
@@ -97,25 +98,25 @@
|
|||||||
"@babel/core": "^7.25.2",
|
"@babel/core": "^7.25.2",
|
||||||
"@babel/preset-env": "^7.25.4",
|
"@babel/preset-env": "^7.25.4",
|
||||||
"@babel/preset-react": "^7.24.7",
|
"@babel/preset-react": "^7.24.7",
|
||||||
"@babel/runtime-corejs2": "^7.25.4",
|
"@babel/runtime-corejs2": "^7.25.6",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"babel-loader": "^9.1.3",
|
"babel-loader": "^9.2.1",
|
||||||
"clean-webpack-plugin": "^4.0.0",
|
"clean-webpack-plugin": "^4.0.0",
|
||||||
"commitizen": "^4.3.0",
|
"commitizen": "^4.3.1",
|
||||||
"concurrently": "^8.2.2",
|
"concurrently": "^9.0.1",
|
||||||
"css-loader": "^7.1.2",
|
"css-loader": "^7.1.2",
|
||||||
"daisyui": "^4.12.10",
|
"daisyui": "^4.12.10",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
"dotenv-webpack": "^8.1.0",
|
"dotenv-webpack": "^8.1.0",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^9.11.1",
|
||||||
"eslint-plugin-prettier": "^5.2.1",
|
"eslint-plugin-prettier": "^5.2.1",
|
||||||
"eslint-plugin-react": "^7.34.3",
|
"eslint-plugin-react": "^7.37.0",
|
||||||
"lint-staged": "^15.2.10",
|
"lint-staged": "^15.2.10",
|
||||||
"mini-css-extract-plugin": "^2.9.1",
|
"mini-css-extract-plugin": "^2.9.1",
|
||||||
"postcss": "^8.4.45",
|
"postcss": "^8.4.47",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3",
|
||||||
"pretty-quick": "^4.0.0",
|
"pretty-quick": "^4.0.0",
|
||||||
"tailwindcss": "^3.4.10",
|
"tailwindcss": "^3.4.13",
|
||||||
"terser-webpack-plugin": "^5.3.10",
|
"terser-webpack-plugin": "^5.3.10",
|
||||||
"webpack-cli": "^5.1.4"
|
"webpack-cli": "^5.1.4"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -131,7 +131,9 @@
|
|||||||
"Share": "Share",
|
"Share": "Share",
|
||||||
"View": "View",
|
"View": "View",
|
||||||
"option": "Option",
|
"option": "Option",
|
||||||
"Embed": "Embed"
|
"Embed": "Embed",
|
||||||
|
"Copy TemplateId":"Copy TemplateId",
|
||||||
|
"Copy Public URL":"Copy Public URL"
|
||||||
},
|
},
|
||||||
"report-heading": {
|
"report-heading": {
|
||||||
"Sr.No": "Sr.No",
|
"Sr.No": "Sr.No",
|
||||||
@@ -264,7 +266,8 @@
|
|||||||
"make-template-private-alert": "Are you sure you want to make this template private? This will remove it from your public profile.",
|
"make-template-private-alert": "Are you sure you want to make this template private? This will remove it from your public profile.",
|
||||||
"public-role": "Public role",
|
"public-role": "Public role",
|
||||||
"public-url": "Public URL",
|
"public-url": "Public URL",
|
||||||
"public-url-copy-mssg": " Here’s your public URL: Copy it or share it with the signer, and you will be able to see all your publicly set templates.",
|
"public-url-copy": "Here’s your public URL: ",
|
||||||
|
"public-url-copy-mssg":"Copy it or share it with the signer, and you will be able to see all your publicly set templates.",
|
||||||
"add-public-url-alert": "Please add your public URL, and you will be able to make a public template.",
|
"add-public-url-alert": "Please add your public URL, and you will be able to make a public template.",
|
||||||
"share-with-alert": "You cannot share a template if any roles already have contacts assigned. Please remove all contact assignments from the roles before sharing the template.",
|
"share-with-alert": "You cannot share a template if any roles already have contacts assigned. Please remove all contact assignments from the roles before sharing the template.",
|
||||||
"share-with": "Share with",
|
"share-with": "Share with",
|
||||||
@@ -632,6 +635,19 @@
|
|||||||
"reason":"Reason",
|
"reason":"Reason",
|
||||||
"decline-by":"Declined/revoked by",
|
"decline-by":"Declined/revoked by",
|
||||||
"document-declined": "Document declined",
|
"document-declined": "Document declined",
|
||||||
|
"public-template-mssg-1":"To integrate OpenSign into your React or Next.js project, simply run the following command:",
|
||||||
|
"public-template-mssg-2" :"Ensure you have npm or yarn set up in your project. If you’re using Yarn, you can replace npm install with yarn add @opensign/react.",
|
||||||
|
"public-template-mssg-3" :"Need more details or examples?",
|
||||||
|
"public-template-mssg-4": "Visit the",
|
||||||
|
"public-template-mssg-5": " npm for the latest updates, detailed documentation, and version history.",
|
||||||
|
"public-template-mssg-6" :"Before you can use this code snippet, you must make this template public.",
|
||||||
|
"copy-code":"COPY",
|
||||||
|
"copied-code":"COPIED",
|
||||||
|
"Installation":"Installation",
|
||||||
|
"Usage" :"Usage",
|
||||||
|
"insufficient-credits":"Insufficient Signing Credits",
|
||||||
|
"insufficient-credits-mssg":"The owner of this document currently lacks the necessary OpenSign credits for you to sign. Please reach out to the owner if you require further details.",
|
||||||
|
"angular-npm-mssg-1": "To integrate OpenSign into your Angular project, simply run the following command:",
|
||||||
"quota-mail-info-head":"Monthly request signatures email limit",
|
"quota-mail-info-head":"Monthly request signatures email limit",
|
||||||
"quota-mail-info": "You can send upto 15 signature request emails every month. Upgrade now to send unlimited signing requests directly.",
|
"quota-mail-info": "You can send upto 15 signature request emails every month. Upgrade now to send unlimited signing requests directly.",
|
||||||
"quota-mail": "You've reached your limit of 15 signature request emails for this month. Upgrade now to continue sending emails directly.",
|
"quota-mail": "You've reached your limit of 15 signature request emails for this month. Upgrade now to continue sending emails directly.",
|
||||||
@@ -653,6 +669,9 @@
|
|||||||
"download-files":"Download files",
|
"download-files":"Download files",
|
||||||
"download-pdf":"Download Pdf",
|
"download-pdf":"Download Pdf",
|
||||||
"pdf-certificate":"Download Pdf + Certificate",
|
"pdf-certificate":"Download Pdf + Certificate",
|
||||||
"document-logs":"Document logs"
|
"document-logs":"Document logs",
|
||||||
|
"server-down": "Unable to connect to the OpenSign server. If you are self-hosting OpenSign, please ensure that all the steps in the documentation have been followed correctly. If you're running OpenSign locally, you might be accessing it through an incorrect port number.",
|
||||||
|
"admin-exists": "Admin already exists. Please login to the application using admin credentials in order to manage users.",
|
||||||
|
"public-tour-message":"Please make template public to copy public URL"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,7 +151,9 @@
|
|||||||
"Share": "Partager",
|
"Share": "Partager",
|
||||||
"View": "Voir",
|
"View": "Voir",
|
||||||
"option": "Option",
|
"option": "Option",
|
||||||
"Embed": "Intégrer"
|
"Embed": "Intégrer",
|
||||||
|
"Copy TemplateId": "Copier l'ID du modèle",
|
||||||
|
"Copy Public URL":"Copier l'URL publique"
|
||||||
},
|
},
|
||||||
"report-help": {
|
"report-help": {
|
||||||
"Draft Documents": "Il s'agit de documents que vous avez commencés mais que vous n'avez pas finalisés pour envoi.",
|
"Draft Documents": "Il s'agit de documents que vous avez commencés mais que vous n'avez pas finalisés pour envoi.",
|
||||||
@@ -263,7 +265,8 @@
|
|||||||
"make-template-private-alert": "Êtes-vous sûr de vouloir rendre ce modèle privé ? Cela le supprimera de votre profil public.",
|
"make-template-private-alert": "Êtes-vous sûr de vouloir rendre ce modèle privé ? Cela le supprimera de votre profil public.",
|
||||||
"public-role": "Rôle public",
|
"public-role": "Rôle public",
|
||||||
"public-url": "URL publique",
|
"public-url": "URL publique",
|
||||||
"public-url-copy-mssg": "Voici votre URL publique : copiez-la ou partagez-le avec le signataire et vous pouvoir voir tous vos paramètres publics modèles.",
|
"public-url-copy": "Voici votre URL publique : ",
|
||||||
|
"public-url-copy-mssg": "copiez-la ou partagez-le avec le signataire et vous pouvoir voir tous vos paramètres publics modèles.",
|
||||||
"add-public-url-alert": "Veuillez ajouter votre URL publique et vous pourra rendre public modèle.",
|
"add-public-url-alert": "Veuillez ajouter votre URL publique et vous pourra rendre public modèle.",
|
||||||
"share-with-alert": "Vous ne pouvez pas partager un modèle si des contacts sont déjà attribués à des rôles. Veuillez supprimer toutes les attributions de contacts des rôles avant de partager le modèle.",
|
"share-with-alert": "Vous ne pouvez pas partager un modèle si des contacts sont déjà attribués à des rôles. Veuillez supprimer toutes les attributions de contacts des rôles avant de partager le modèle.",
|
||||||
"share-with": "Partager avec",
|
"share-with": "Partager avec",
|
||||||
@@ -631,6 +634,19 @@
|
|||||||
"reason" :"Raison",
|
"reason" :"Raison",
|
||||||
"decline-by" :"Refusé/révoqué par",
|
"decline-by" :"Refusé/révoqué par",
|
||||||
"document-declined":"document refusé",
|
"document-declined":"document refusé",
|
||||||
|
"public-template-mssg-1" :"Pour intégrer OpenSign dans votre projet React ou Next.js, exécutez simplement la commande suivante :",
|
||||||
|
"public-template-mssg-2" :"Assurez-vous que npm ou Yarn est configuré dans votre projet. Si vous utilisez Yarn, vous pouvez remplacer npm install par Yarn Add @opensign/react.",
|
||||||
|
"public-template-mssg-3" :"Besoin de plus de détails ou d'exemples ?",
|
||||||
|
"public-template-mssg-4": "Visitez le",
|
||||||
|
"public-template-mssg-5": "npm pour les dernières mises à jour, une documentation détaillée et l'historique des versions.",
|
||||||
|
"public-template-mssg-6":"Avant de pouvoir utiliser cet extrait de code, vous devez rendre ce modèle public.",
|
||||||
|
"copy-code":"COPIE",
|
||||||
|
"copied-code":"COPIÉ",
|
||||||
|
"Installation":"Installation",
|
||||||
|
"Usage" :"Usage",
|
||||||
|
"insufficient-credits":"Crédits de signature insuffisants",
|
||||||
|
"insufficient-credits-mssg" :"Le propriétaire de ce document ne dispose actuellement pas des crédits OpenSign nécessaires pour que vous puissiez le signer. Veuillez contacter le propriétaire si vous avez besoin de plus de détails.",
|
||||||
|
"angular-npm-mssg-1" :"Pour intégrer OpenSign dans votre projet Angular, exécutez simplement la commande suivante :",
|
||||||
"quota-mail-info-head":"Limite mensuelle d'e-mails de signatures de demandes",
|
"quota-mail-info-head":"Limite mensuelle d'e-mails de signatures de demandes",
|
||||||
"quota-mail-info": "Vous pouvez envoyer jusqu'à 15 e-mails de demande de signature chaque mois. Mettez à niveau maintenant pour envoyer directement des demandes de signature illimitées.",
|
"quota-mail-info": "Vous pouvez envoyer jusqu'à 15 e-mails de demande de signature chaque mois. Mettez à niveau maintenant pour envoyer directement des demandes de signature illimitées.",
|
||||||
"quota-mail": "Vous avez atteint votre limite de 15 e-mails de demande de signature pour ce mois. Mettez à niveau maintenant pour continuer à envoyer des e-mails directement.",
|
"quota-mail": "Vous avez atteint votre limite de 15 e-mails de demande de signature pour ce mois. Mettez à niveau maintenant pour continuer à envoyer des e-mails directement.",
|
||||||
@@ -652,6 +668,10 @@
|
|||||||
"download-files" :"Télécharger des fichiers",
|
"download-files" :"Télécharger des fichiers",
|
||||||
"download-pdf" :"Télécharger le PDF",
|
"download-pdf" :"Télécharger le PDF",
|
||||||
"pdf-certificate" :"Télécharger Pdf + Certificat",
|
"pdf-certificate" :"Télécharger Pdf + Certificat",
|
||||||
"document-logs":"Journaux de documents"
|
"document-logs":"Journaux de documents",
|
||||||
|
"server-down": "Impossible de se connecter au serveur OpenSign. Si vous hébergez vous-même OpenSign, veuillez vous assurer que toutes les étapes de la documentation ont été correctement suivies. Si vous exécutez OpenSign localement, vous y accédez peut-être via un numéro de port incorrect.",
|
||||||
|
"admin-exists": "L'administrateur existe déjà. Veuillez vous connecter à l'application en utilisant les informations d'identification de l'administrateur afin de gérer les utilisateurs.",
|
||||||
|
"public-tour-message":"Veuillez rendre le modèle public pour copier l'URL publique"
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -2,13 +2,13 @@ import React, { useState, useEffect, useRef } from "react";
|
|||||||
import "../../styles/opensigndrive.css";
|
import "../../styles/opensigndrive.css";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import * as ContextMenu from "@radix-ui/react-context-menu";
|
import * as ContextMenu from "@radix-ui/react-context-menu";
|
||||||
import { saveAs } from "file-saver";
|
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import Table from "react-bootstrap/Table";
|
import Table from "react-bootstrap/Table";
|
||||||
import * as HoverCard from "@radix-ui/react-hover-card";
|
import * as HoverCard from "@radix-ui/react-hover-card";
|
||||||
import ModalUi from "../../primitives/ModalUi";
|
import ModalUi from "../../primitives/ModalUi";
|
||||||
import FolderModal from "../shared/fields/FolderModal";
|
import FolderModal from "../shared/fields/FolderModal";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { handleDownloadPdf } from "../../constant/Utils";
|
||||||
|
|
||||||
function DriveBody(props) {
|
function DriveBody(props) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -100,16 +100,17 @@ function DriveBody(props) {
|
|||||||
|
|
||||||
//function for navigate user to microapp-signature component
|
//function for navigate user to microapp-signature component
|
||||||
const checkPdfStatus = async (data) => {
|
const checkPdfStatus = async (data) => {
|
||||||
const signerExist = data.Signers && data.Signers;
|
const signerExist = data?.Signers;
|
||||||
const isDecline = data.IsDeclined && data.IsDeclined;
|
const isDecline = data?.IsDeclined;
|
||||||
const isPlaceholder = data.Placeholders && data.Placeholders;
|
const isPlaceholder = data?.Placeholders;
|
||||||
const signedUrl = data.SignedUrl;
|
const signedUrl = data?.SignedUrl;
|
||||||
|
const isSignYourself = data?.IsSignyourself;
|
||||||
//checking if document has completed and request signature flow
|
//checking if document has completed and request signature flow
|
||||||
if (data?.IsCompleted && signerExist?.length > 0) {
|
if (data?.IsCompleted && signerExist?.length > 0) {
|
||||||
navigate(`/recipientSignPdf/${data.objectId}`);
|
navigate(`/recipientSignPdf/${data.objectId}`);
|
||||||
}
|
}
|
||||||
//checking if document has completed and signyour-self flow
|
//checking if document has completed and signyour-self flow
|
||||||
else if (!signerExist && !isPlaceholder) {
|
else if ((!signerExist && !isPlaceholder) || isSignYourself) {
|
||||||
navigate(`/signaturePdf/${data.objectId}`);
|
navigate(`/signaturePdf/${data.objectId}`);
|
||||||
}
|
}
|
||||||
//checking if document has declined by someone
|
//checking if document has declined by someone
|
||||||
@@ -136,12 +137,10 @@ function DriveBody(props) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMenuItemClick = (selectType, data) => {
|
const handleMenuItemClick = async (selectType, data) => {
|
||||||
switch (selectType) {
|
switch (selectType) {
|
||||||
case "Download": {
|
case "Download": {
|
||||||
const pdfName = data && data.Name;
|
await handleDownloadPdf([data]);
|
||||||
const pdfUrl = data && data.SignedUrl ? data.SignedUrl : data.URL;
|
|
||||||
saveAs(pdfUrl, `${sanitizeFileName(pdfName)}_signed_by_OpenSign™.pdf`);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "Rename": {
|
case "Rename": {
|
||||||
@@ -264,12 +263,6 @@ function DriveBody(props) {
|
|||||||
setIsOpenMoveModal(false);
|
setIsOpenMoveModal(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const sanitizeFileName = (pdfName) => {
|
|
||||||
// Replace spaces with underscore
|
|
||||||
return pdfName.replace(/ /g, "_");
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleEnterPress = (e, data) => {
|
const handleEnterPress = (e, data) => {
|
||||||
if (e.key === "Enter") {
|
if (e.key === "Enter") {
|
||||||
handledRenameDoc(data);
|
handledRenameDoc(data);
|
||||||
|
|||||||
@@ -30,6 +30,28 @@ function EmailComponent({
|
|||||||
const pdfName = pdfDetails[0]?.Name;
|
const pdfName = pdfDetails[0]?.Name;
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
let sendMail;
|
let sendMail;
|
||||||
|
|
||||||
|
const docId = !pdfDetails?.[0]?.IsEnableOTP
|
||||||
|
? pdfDetails?.[0]?.objectId
|
||||||
|
: "";
|
||||||
|
let presignedUrl = pdfUrl;
|
||||||
|
try {
|
||||||
|
// const url = await Parse.Cloud.run("getsignedurl", { url: pdfUrl });
|
||||||
|
const axiosRes = await axios.post(
|
||||||
|
`${localStorage.getItem("baseUrl")}/functions/getsignedurl`,
|
||||||
|
{ url: pdfUrl, docId: docId },
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"content-type": "Application/json",
|
||||||
|
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||||
|
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
presignedUrl = axiosRes.data.result;
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err in getsignedurl", err);
|
||||||
|
}
|
||||||
for (let i = 0; i < emailList.length; i++) {
|
for (let i = 0; i < emailList.length; i++) {
|
||||||
try {
|
try {
|
||||||
const imgPng =
|
const imgPng =
|
||||||
@@ -47,7 +69,7 @@ function EmailComponent({
|
|||||||
mailProvider: activeMailAdapter,
|
mailProvider: activeMailAdapter,
|
||||||
extUserId: extUserId,
|
extUserId: extUserId,
|
||||||
pdfName: pdfName,
|
pdfName: pdfName,
|
||||||
url: pdfUrl,
|
url: presignedUrl,
|
||||||
recipient: emailList[i],
|
recipient: emailList[i],
|
||||||
subject: `${sender.name} has signed the doc - ${pdfName}`,
|
subject: `${sender.name} has signed the doc - ${pdfName}`,
|
||||||
from: sender.email,
|
from: sender.email,
|
||||||
|
|||||||
@@ -0,0 +1,269 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
||||||
|
import { tomorrow } from "react-syntax-highlighter/dist/esm/styles/prism";
|
||||||
|
import { copytoData } from "../../constant/Utils";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
function EmbedTab(props) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const tabName = [
|
||||||
|
{ title: "React/Next.js", icon: "fa-brands fa-react", color: "#61dafb" },
|
||||||
|
{ title: "JavaScript", icon: "fa-brands fa-js", color: "#ffd43b" },
|
||||||
|
{ title: "Angular", icon: "fa-brands fa-angular", color: "#ff5733" }
|
||||||
|
];
|
||||||
|
const [activeTab, setActiveTab] = useState(0);
|
||||||
|
// State to track if the code has been copied
|
||||||
|
const [isCopied, setIsCopied] = useState(false);
|
||||||
|
const reactCode = [
|
||||||
|
{
|
||||||
|
id: 0,
|
||||||
|
title: "Installation",
|
||||||
|
codeString: `
|
||||||
|
npm install @opensign/react`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title: "Usage",
|
||||||
|
codeString: `
|
||||||
|
import React from "react";
|
||||||
|
import Opensign from "@opensign/react";
|
||||||
|
|
||||||
|
export function App() {
|
||||||
|
return (
|
||||||
|
<div className="app">
|
||||||
|
<Opensign
|
||||||
|
onLoad={() => console.log("success")}
|
||||||
|
onLoadError={(error) => console.log(error)}
|
||||||
|
templateId= "${props.templateId}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
`
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const angularCode = [
|
||||||
|
{
|
||||||
|
id: 0,
|
||||||
|
title: "Installation",
|
||||||
|
codeString: `
|
||||||
|
npm install @opensign/angular`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title: "Usage",
|
||||||
|
codeString: `
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
import {OpensignComponent} from "@opensign/angular"
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector:'app-root',
|
||||||
|
standalone: true,
|
||||||
|
imports: [OpensignComponent],
|
||||||
|
template:\`<opensign templateId="${props.templateId}"
|
||||||
|
(onLoad)="handleLoad()"
|
||||||
|
(onLoadError)="handleError($event)"
|
||||||
|
></opensign>\`,
|
||||||
|
})
|
||||||
|
export class AppComponent{
|
||||||
|
handleLoad() {
|
||||||
|
console.log("success");
|
||||||
|
}
|
||||||
|
handleError(error: string) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
`
|
||||||
|
}
|
||||||
|
];
|
||||||
|
const jsCodeString = `
|
||||||
|
<script
|
||||||
|
src= "https://app.opensignlabs.com/static/js/public-template.bundle.js"
|
||||||
|
id="opensign-script"
|
||||||
|
templateId=${props.templateId}
|
||||||
|
></script>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const handleCopy = (code, ind) => {
|
||||||
|
copytoData(code);
|
||||||
|
setIsCopied({ ...isCopied, [ind]: true });
|
||||||
|
setTimeout(() => setIsCopied(false), 3000);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="mt-4 border-t-[1px]">
|
||||||
|
<div className="flex justify-center items-center mt-2">
|
||||||
|
<div role="tablist" className="op-tabs op-tabs-bordered">
|
||||||
|
{tabName.map((tabData, ind) => (
|
||||||
|
<div
|
||||||
|
onClick={() => setActiveTab(ind)}
|
||||||
|
key={ind}
|
||||||
|
role="tab"
|
||||||
|
className={`${
|
||||||
|
activeTab === ind ? "op-tab-active" : ""
|
||||||
|
} op-tab flex items-center`}
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
className={`${tabData.icon}`}
|
||||||
|
style={{ color: tabData.color }}
|
||||||
|
></i>
|
||||||
|
<span className="ml-1 text-[10px] font-medium md:font-normal md:text-[15px]">
|
||||||
|
{tabData.title}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{activeTab === 0 ? (
|
||||||
|
<div className="mt-4">
|
||||||
|
{reactCode.map((data, ind) => {
|
||||||
|
return (
|
||||||
|
<div key={ind}>
|
||||||
|
<p className="font-medium text-[18px]">
|
||||||
|
{t(`${data.title}`)}
|
||||||
|
</p>
|
||||||
|
{ind === 0 && (
|
||||||
|
<p className="text-[13px] mt-2">
|
||||||
|
{t("public-template-mssg-1")}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
<div className="relative p-1">
|
||||||
|
<div
|
||||||
|
onClick={() => handleCopy(data.codeString, ind)}
|
||||||
|
className="absolute top-[20px] right-[20px] cursor-pointer"
|
||||||
|
>
|
||||||
|
<i className="fa-light fa-copy text-white mr-[2px]" />
|
||||||
|
<span className=" text-white">
|
||||||
|
{isCopied[ind] ? t("copied-code") : t("copy-code")}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<SyntaxHighlighter
|
||||||
|
customStyle={{
|
||||||
|
borderRadius: "15px"
|
||||||
|
}}
|
||||||
|
language="javascript"
|
||||||
|
style={tomorrow}
|
||||||
|
>
|
||||||
|
{data.codeString}
|
||||||
|
</SyntaxHighlighter>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
|
<p className="font-medium text-[15px]">
|
||||||
|
{t("public-template-mssg-3")}
|
||||||
|
</p>
|
||||||
|
<p className="my-[6px]">
|
||||||
|
{" "}
|
||||||
|
{t("public-template-mssg-4")}
|
||||||
|
<a
|
||||||
|
href="https://www.npmjs.com/package/@opensign/react"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
className="cursor-pointer text-blue-700 "
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
OpenSign React package{" "}
|
||||||
|
</a>
|
||||||
|
{t("public-template-mssg-5")}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
) : activeTab === 1 ? (
|
||||||
|
<div className="mt-4">
|
||||||
|
<div>
|
||||||
|
{/* <p className="font-medium text-[18px]">{t(`${data.title}`)}</p> */}
|
||||||
|
|
||||||
|
<div className="relative p-1">
|
||||||
|
<div
|
||||||
|
onClick={() => handleCopy(jsCodeString, 0)}
|
||||||
|
className="absolute top-[20px] right-[20px] cursor-pointer"
|
||||||
|
>
|
||||||
|
<i className="fa-light fa-copy text-white mr-[2px]" />
|
||||||
|
<span className=" text-white">
|
||||||
|
{isCopied[0] ? t("copied-code") : t("copy-code")}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<SyntaxHighlighter
|
||||||
|
customStyle={{
|
||||||
|
borderRadius: "15px"
|
||||||
|
}}
|
||||||
|
language="javascript"
|
||||||
|
style={tomorrow}
|
||||||
|
>
|
||||||
|
{jsCodeString}
|
||||||
|
</SyntaxHighlighter>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
activeTab === 2 && (
|
||||||
|
<div className="mt-4">
|
||||||
|
{angularCode.map((data, ind) => {
|
||||||
|
return (
|
||||||
|
<div key={ind}>
|
||||||
|
<p className="font-medium text-[18px]">
|
||||||
|
{t(`${data.title}`)}
|
||||||
|
</p>
|
||||||
|
{ind === 0 && (
|
||||||
|
<p className="text-[13px] mt-2">
|
||||||
|
{t("angular-npm-mssg-1")}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
<div className="relative p-1">
|
||||||
|
<div
|
||||||
|
onClick={() => handleCopy(data.codeString, ind)}
|
||||||
|
className="absolute top-[20px] right-[20px] cursor-pointer"
|
||||||
|
>
|
||||||
|
<i className="fa-light fa-copy text-white mr-[2px]" />
|
||||||
|
<span className=" text-white">
|
||||||
|
{isCopied[ind] ? t("copied-code") : t("copy-code")}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<SyntaxHighlighter
|
||||||
|
customStyle={{
|
||||||
|
borderRadius: "15px"
|
||||||
|
}}
|
||||||
|
language="javascript"
|
||||||
|
style={tomorrow}
|
||||||
|
>
|
||||||
|
{data.codeString}
|
||||||
|
</SyntaxHighlighter>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
|
<p className="font-medium text-[15px]">
|
||||||
|
{t("public-template-mssg-3")}
|
||||||
|
</p>
|
||||||
|
<p className="my-[6px]">
|
||||||
|
{" "}
|
||||||
|
{t("public-template-mssg-4")}
|
||||||
|
<a
|
||||||
|
href="https://www.npmjs.com/package/@opensign/angular"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
className="cursor-pointer text-blue-700 "
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
OpenSign Angular package{" "}
|
||||||
|
</a>
|
||||||
|
{t("public-template-mssg-5")}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EmbedTab;
|
||||||
@@ -725,7 +725,9 @@ function Placeholder(props) {
|
|||||||
: props?.pos?.zIndex
|
: props?.pos?.zIndex
|
||||||
? props.pos.zIndex
|
? props.pos.zIndex
|
||||||
: "5",
|
: "5",
|
||||||
background: props.data ? props.data.blockColor : "rgb(203 233 237)"
|
background: props.data
|
||||||
|
? props.data?.blockColor + "b0"
|
||||||
|
: "rgba(203, 233, 237, 0.69)"
|
||||||
}}
|
}}
|
||||||
onDrag={() => {
|
onDrag={() => {
|
||||||
setDraggingEnabled(true);
|
setDraggingEnabled(true);
|
||||||
|
|||||||
@@ -596,7 +596,7 @@ function SignPad({
|
|||||||
borderRadius: "2px"
|
borderRadius: "2px"
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
backgroundColor="rgb(255, 255, 255)"
|
// backgroundColor="rgb(255, 255, 255)"
|
||||||
onEnd={() =>
|
onEnd={() =>
|
||||||
handleSignatureChange(canvasRef.current?.toDataURL())
|
handleSignatureChange(canvasRef.current?.toDataURL())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,14 +33,15 @@ export const openInNewTab = (url, target) => {
|
|||||||
export async function fetchSubscription(
|
export async function fetchSubscription(
|
||||||
extUserId,
|
extUserId,
|
||||||
contactObjId,
|
contactObjId,
|
||||||
isGuestSign = false
|
isGuestSign = false,
|
||||||
|
isPublic = false
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const Extand_Class = localStorage.getItem("Extand_Class");
|
const Extand_Class = localStorage.getItem("Extand_Class");
|
||||||
const extClass = Extand_Class && JSON.parse(Extand_Class);
|
const extClass = Extand_Class && JSON.parse(Extand_Class);
|
||||||
// console.log("extClass ", extClass);
|
// console.log("extClass ", extClass);
|
||||||
let extUser;
|
let extUser;
|
||||||
if (extClass && extClass.length > 0) {
|
if (extClass && extClass.length > 0 && !isPublic) {
|
||||||
extUser = extClass[0].objectId;
|
extUser = extClass[0].objectId;
|
||||||
} else {
|
} else {
|
||||||
extUser = extUserId;
|
extUser = extUserId;
|
||||||
@@ -54,7 +55,7 @@ export async function fetchSubscription(
|
|||||||
};
|
};
|
||||||
const params = isGuestSign
|
const params = isGuestSign
|
||||||
? { contactId: contactObjId }
|
? { contactId: contactObjId }
|
||||||
: { extUserId: extUser };
|
: { extUserId: extUser, ispublic: isPublic };
|
||||||
const tenatRes = await axios.post(url, params, { headers: headers });
|
const tenatRes = await axios.post(url, params, { headers: headers });
|
||||||
let plan, status, billingDate, adminId;
|
let plan, status, billingDate, adminId;
|
||||||
if (isGuestSign) {
|
if (isGuestSign) {
|
||||||
@@ -1349,11 +1350,6 @@ export const multiSignEmbed = async (
|
|||||||
widgetsPositionArr.map(async (url) => {
|
widgetsPositionArr.map(async (url) => {
|
||||||
let signUrl = url.SignUrl && url.SignUrl;
|
let signUrl = url.SignUrl && url.SignUrl;
|
||||||
if (signUrl) {
|
if (signUrl) {
|
||||||
if (url.ImageType === "image/png") {
|
|
||||||
//function for convert signature png base64 url to jpeg base64
|
|
||||||
const newUrl = await convertPNGtoJPEG(signUrl);
|
|
||||||
signUrl = newUrl;
|
|
||||||
}
|
|
||||||
const res = await fetch(signUrl);
|
const res = await fetch(signUrl);
|
||||||
return res.arrayBuffer();
|
return res.arrayBuffer();
|
||||||
}
|
}
|
||||||
@@ -1363,19 +1359,14 @@ export const multiSignEmbed = async (
|
|||||||
widgetsPositionArr.forEach(async (position, id) => {
|
widgetsPositionArr.forEach(async (position, id) => {
|
||||||
let img;
|
let img;
|
||||||
if (["signature", "stamp", "initials", "image"].includes(position.type)) {
|
if (["signature", "stamp", "initials", "image"].includes(position.type)) {
|
||||||
if (
|
if (position.ImageType && position.ImageType === "image/jpeg") {
|
||||||
(position.ImageType && position.ImageType === "image/png") ||
|
|
||||||
position.ImageType === "image/jpeg"
|
|
||||||
) {
|
|
||||||
img = await pdfDoc.embedJpg(images[id]);
|
img = await pdfDoc.embedJpg(images[id]);
|
||||||
} else {
|
} else {
|
||||||
img = await pdfDoc.embedPng(images[id]);
|
img = await pdfDoc.embedPng(images[id]);
|
||||||
}
|
}
|
||||||
} else if (!position.type) {
|
} else if (!position.type) {
|
||||||
if (
|
// to handle old widget when only stamp and signature are exists
|
||||||
(position.ImageType && position.ImageType === "image/png") ||
|
if (position.ImageType && position.ImageType === "image/jpeg") {
|
||||||
position.ImageType === "image/jpeg"
|
|
||||||
) {
|
|
||||||
img = await pdfDoc.embedJpg(images[id]);
|
img = await pdfDoc.embedJpg(images[id]);
|
||||||
} else {
|
} else {
|
||||||
img = await pdfDoc.embedPng(images[id]);
|
img = await pdfDoc.embedPng(images[id]);
|
||||||
@@ -1935,7 +1926,11 @@ export const getAppLogo = async () => {
|
|||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("err in getlogo ", err);
|
console.log("err in getlogo ", err);
|
||||||
return { logo: appInfo.applogo, user: "exist" };
|
if (err?.message?.includes("valid JSON")) {
|
||||||
|
return { logo: appInfo.applogo, user: "exist", error: "invalid_json" };
|
||||||
|
} else {
|
||||||
|
return { logo: appInfo.applogo, user: "exist" };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -2058,12 +2053,12 @@ export const getSignedUrl = async (pdfUrl, docId) => {
|
|||||||
export const handleDownloadPdf = async (pdfDetails, setIsDownloading) => {
|
export const handleDownloadPdf = async (pdfDetails, setIsDownloading) => {
|
||||||
const pdfName = pdfDetails[0] && pdfDetails[0]?.Name;
|
const pdfName = pdfDetails[0] && pdfDetails[0]?.Name;
|
||||||
const pdfUrl = pdfDetails?.[0]?.SignedUrl || pdfDetails?.[0]?.URL;
|
const pdfUrl = pdfDetails?.[0]?.SignedUrl || pdfDetails?.[0]?.URL;
|
||||||
setIsDownloading("pdf");
|
setIsDownloading && setIsDownloading("pdf");
|
||||||
const docId = !pdfDetails?.[0]?.IsEnableOTP ? pdfDetails?.[0]?.objectId : "";
|
const docId = !pdfDetails?.[0]?.IsEnableOTP ? pdfDetails?.[0]?.objectId : "";
|
||||||
try {
|
try {
|
||||||
const url = await getSignedUrl(pdfUrl, docId);
|
const url = await getSignedUrl(pdfUrl, docId);
|
||||||
await fetchUrl(url, pdfName);
|
await fetchUrl(url, pdfName);
|
||||||
setIsDownloading("");
|
setIsDownloading && setIsDownloading("");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("err in getsignedurl", err);
|
console.log("err in getsignedurl", err);
|
||||||
setIsDownloading("");
|
setIsDownloading("");
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { isEnableSubscription } from "../constant/const";
|
||||||
|
|
||||||
export default function reportJson(id) {
|
export default function reportJson(id) {
|
||||||
// console.log("json ", json);
|
// console.log("json ", json);
|
||||||
const head = ["Sr.No", "Title", "Note", "Folder", "File", "Owner", "Signers"];
|
const head = ["Sr.No", "Title", "Note", "Folder", "File", "Owner", "Signers"];
|
||||||
@@ -22,6 +24,31 @@ export default function reportJson(id) {
|
|||||||
const contactbook = ["Sr.No", "Name", "Email", "Phone"];
|
const contactbook = ["Sr.No", "Name", "Email", "Phone"];
|
||||||
const dashboardReportHead = ["Title", "File", "Owner", "Signers"];
|
const dashboardReportHead = ["Title", "File", "Owner", "Signers"];
|
||||||
const templateReport = ["Sr.No", "Title", "File", "Owner", "Signers"];
|
const templateReport = ["Sr.No", "Title", "File", "Owner", "Signers"];
|
||||||
|
const templateSubAction = isEnableSubscription
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
btnId: "2434",
|
||||||
|
btnLabel: "Embed",
|
||||||
|
hoverLabel: "Embed",
|
||||||
|
btnIcon: "fa-light fa-code",
|
||||||
|
action: "Embed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
btnId: "2434",
|
||||||
|
btnLabel: "Copy TemplateId",
|
||||||
|
hoverLabel: "Copy TemplateId",
|
||||||
|
btnIcon: "fa-light fa-copy",
|
||||||
|
action: "CopyTemplateId"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
btnId: "2434",
|
||||||
|
btnLabel: "Copy Public URL",
|
||||||
|
hoverLabel: "Copy Public URL",
|
||||||
|
btnIcon: "fa-light fa-copy",
|
||||||
|
action: "CopyPublicURL"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
: [];
|
||||||
switch (id) {
|
switch (id) {
|
||||||
// draft documents report
|
// draft documents report
|
||||||
case "ByHuevtCFY":
|
case "ByHuevtCFY":
|
||||||
@@ -363,13 +390,7 @@ export default function reportJson(id) {
|
|||||||
redirectUrl: "template",
|
redirectUrl: "template",
|
||||||
action: "redirect"
|
action: "redirect"
|
||||||
},
|
},
|
||||||
{
|
...templateSubAction,
|
||||||
btnId: "2434",
|
|
||||||
btnLabel: "Embed",
|
|
||||||
hoverLabel: "Embed",
|
|
||||||
btnIcon: "fa-light fa-code",
|
|
||||||
action: "Embed"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
btnId: "1834",
|
btnId: "1834",
|
||||||
btnLabel: "Delete",
|
btnLabel: "Delete",
|
||||||
@@ -391,18 +412,15 @@ export default function reportJson(id) {
|
|||||||
if (item.action === "option") {
|
if (item.action === "option") {
|
||||||
// Make a shallow copy of the item
|
// Make a shallow copy of the item
|
||||||
const newItem = { ...item };
|
const newItem = { ...item };
|
||||||
newItem.subaction = [
|
//splice method used to add `Share with team` option on second index of list
|
||||||
{
|
newItem.subaction.splice(1, 0, {
|
||||||
btnId: "1873",
|
btnId: "1873",
|
||||||
btnLabel: "Share with team",
|
btnLabel: "Share with team",
|
||||||
hoverLabel: "Share with team",
|
hoverLabel: "Share with team",
|
||||||
btnIcon: "fa-light fa-share-nodes",
|
btnIcon: "fa-light fa-share-nodes",
|
||||||
redirectUrl: "",
|
redirectUrl: "",
|
||||||
action: "sharewith"
|
action: "sharewith"
|
||||||
},
|
});
|
||||||
...newItem.subaction
|
|
||||||
];
|
|
||||||
|
|
||||||
return newItem;
|
return newItem;
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ const AddAdmin = () => {
|
|||||||
try {
|
try {
|
||||||
const app = await getAppLogo();
|
const app = await getAppLogo();
|
||||||
if (app?.user === "exist") {
|
if (app?.user === "exist") {
|
||||||
setErrMsg(t("admin-already-exist"));
|
setErrMsg(t("admin-exists"));
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setErrMsg(t("something-went-wrong-mssg"));
|
setErrMsg(t("something-went-wrong-mssg"));
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ function Login() {
|
|||||||
const [isModal, setIsModal] = useState(false);
|
const [isModal, setIsModal] = useState(false);
|
||||||
const [image, setImage] = useState();
|
const [image, setImage] = useState();
|
||||||
const [isLoginSSO, setIsLoginSSO] = useState(false);
|
const [isLoginSSO, setIsLoginSSO] = useState(false);
|
||||||
|
const [errMsg, setErrMsg] = useState();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
checkUserExt();
|
checkUserExt();
|
||||||
@@ -59,7 +60,9 @@ function Login() {
|
|||||||
|
|
||||||
const checkUserExt = async () => {
|
const checkUserExt = async () => {
|
||||||
const app = await getAppLogo();
|
const app = await getAppLogo();
|
||||||
if (!isEnableSubscription && app?.user === "not_exist") {
|
if (app?.error === "invalid_json") {
|
||||||
|
setErrMsg(t("server-down"));
|
||||||
|
} else if (!isEnableSubscription && app?.user === "not_exist") {
|
||||||
navigate("/addadmin");
|
navigate("/addadmin");
|
||||||
}
|
}
|
||||||
if (app?.logo) {
|
if (app?.logo) {
|
||||||
@@ -620,7 +623,11 @@ function Login() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return errMsg ? (
|
||||||
|
<div className="h-screen flex justify-center text-center items-center p-4 text-gray-500 text-base">
|
||||||
|
{errMsg}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
<div>
|
<div>
|
||||||
<Title title={"Login Page"} />
|
<Title title={"Login Page"} />
|
||||||
{state.loading && (
|
{state.loading && (
|
||||||
|
|||||||
@@ -2,12 +2,13 @@ import React, { useState, useRef, useEffect } from "react";
|
|||||||
import SignatureCanvas from "react-signature-canvas";
|
import SignatureCanvas from "react-signature-canvas";
|
||||||
import "../styles/managesign.css";
|
import "../styles/managesign.css";
|
||||||
import "../styles/signature.css";
|
import "../styles/signature.css";
|
||||||
import { toDataUrl } from "../constant/Utils";
|
import { generateTitleFromFilename, toDataUrl } from "../constant/Utils";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import { SaveFileSize } from "../constant/saveFileSize";
|
import { SaveFileSize } from "../constant/saveFileSize";
|
||||||
import Alert from "../primitives/Alert";
|
import Alert from "../primitives/Alert";
|
||||||
import Loader from "../primitives/Loader";
|
import Loader from "../primitives/Loader";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import sanitizeFileName from "../primitives/sanitizeFileName";
|
||||||
const ManageSign = () => {
|
const ManageSign = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [penColor, setPenColor] = useState("blue");
|
const [penColor, setPenColor] = useState("blue");
|
||||||
@@ -23,9 +24,11 @@ const ManageSign = () => {
|
|||||||
const [Initials, setInitials] = useState("");
|
const [Initials, setInitials] = useState("");
|
||||||
const [isInitials, setIsInitials] = useState(false);
|
const [isInitials, setIsInitials] = useState(false);
|
||||||
const [id, setId] = useState("");
|
const [id, setId] = useState("");
|
||||||
|
const [imgInitials, setImgInitials] = useState("");
|
||||||
const canvasRef = useRef(null);
|
const canvasRef = useRef(null);
|
||||||
const imageRef = useRef(null);
|
const imageRef = useRef(null);
|
||||||
const initailsRef = useRef(null);
|
const initailsRef = useRef(null);
|
||||||
|
const imgInitialsRef = useRef(null);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchUserSign();
|
fetchUserSign();
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
@@ -46,14 +49,23 @@ const ManageSign = () => {
|
|||||||
if (signRes) {
|
if (signRes) {
|
||||||
const res = signRes.toJSON();
|
const res = signRes.toJSON();
|
||||||
setId(res.objectId);
|
setId(res.objectId);
|
||||||
setSignName(res?.SignatureName);
|
if (res?.SignatureName) {
|
||||||
setImage(res.ImageURL);
|
const sanitizename = generateTitleFromFilename(res?.SignatureName);
|
||||||
|
const replaceSpace = sanitizeFileName(sanitizename);
|
||||||
|
setSignName(replaceSpace);
|
||||||
|
}
|
||||||
|
setImage(res?.ImageURL);
|
||||||
if (res && res.Initials) {
|
if (res && res.Initials) {
|
||||||
setInitials(res.Initials);
|
// setInitials(res.Initials);
|
||||||
setIsInitials(true);
|
setIsInitials(true);
|
||||||
|
setImgInitials(res?.Initials);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setSignName(User?.get("name") || "");
|
if (User?.get("name")) {
|
||||||
|
const sanitizename = generateTitleFromFilename(User?.get("name"));
|
||||||
|
const replaceSpace = sanitizeFileName(sanitizename);
|
||||||
|
setSignName(replaceSpace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -86,8 +98,14 @@ const ManageSign = () => {
|
|||||||
if (initailsRef.current) {
|
if (initailsRef.current) {
|
||||||
initailsRef.current.clear();
|
initailsRef.current.clear();
|
||||||
}
|
}
|
||||||
|
if (imgInitialsRef.current) {
|
||||||
|
imgInitialsRef.current.value = "";
|
||||||
|
}
|
||||||
|
setImgInitials("");
|
||||||
setInitials("");
|
setInitials("");
|
||||||
setIsValue(true);
|
if (image) {
|
||||||
|
setIsValue(true);
|
||||||
|
}
|
||||||
setIsInitials(false);
|
setIsInitials(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -101,40 +119,54 @@ const ManageSign = () => {
|
|||||||
const base64Img = await toDataUrl(file);
|
const base64Img = await toDataUrl(file);
|
||||||
setImage(base64Img);
|
setImage(base64Img);
|
||||||
setIsValue(true);
|
setIsValue(true);
|
||||||
|
} else {
|
||||||
|
setImage("");
|
||||||
|
setIsValue(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const handleSubmit = async (e) => {
|
const handleSubmit = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const isUrl = image.includes("https");
|
const isUrl = image?.includes("https") || image?.includes("http");
|
||||||
|
|
||||||
if (!isvalue) {
|
if (!isvalue) {
|
||||||
setWarning(true);
|
setWarning(true);
|
||||||
setTimeout(() => setWarning(false), 1000);
|
setTimeout(() => setWarning(false), 1000);
|
||||||
} else {
|
} else {
|
||||||
setIsLoader(true);
|
setIsLoader(true);
|
||||||
const replaceSpace = signName.replace(/ /g, "_");
|
const sanitizename = generateTitleFromFilename(signName);
|
||||||
|
const replaceSpace = sanitizeFileName(sanitizename);
|
||||||
let file;
|
let file;
|
||||||
if (signature) {
|
if (signature) {
|
||||||
file = base64StringtoFile(signature, `${replaceSpace}_sign.png`);
|
file = base64StringtoFile(signature, `${replaceSpace}_sign.png`);
|
||||||
} else {
|
} else {
|
||||||
if (!isUrl) {
|
if (image && !isUrl) {
|
||||||
file = base64StringtoFile(image, `${replaceSpace}__sign.png`);
|
file = base64StringtoFile(image, `${replaceSpace}__sign.png`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let imgUrl;
|
let imgUrl;
|
||||||
if (!isUrl) {
|
if (file && !isUrl) {
|
||||||
imgUrl = await uploadFile(file);
|
imgUrl = await uploadFile(file);
|
||||||
} else {
|
} else {
|
||||||
imgUrl = image;
|
imgUrl = image;
|
||||||
}
|
}
|
||||||
let initialsUrl = "";
|
const isInitialsUrl =
|
||||||
const isInitialsUrl = Initials.includes("https");
|
imgInitials?.includes("https") || imgInitials?.includes("http");
|
||||||
if (!isInitialsUrl && Initials) {
|
|
||||||
const initialsImg = base64StringtoFile(
|
let initialFile;
|
||||||
Initials,
|
if (Initials) {
|
||||||
`${replaceSpace}_initials.png`
|
initialFile = base64StringtoFile(Initials, `${replaceSpace}_sign.png`);
|
||||||
);
|
} else {
|
||||||
initialsUrl = await uploadFile(initialsImg);
|
if (imgInitials && !isInitialsUrl) {
|
||||||
|
initialFile = base64StringtoFile(
|
||||||
|
imgInitials,
|
||||||
|
`${replaceSpace}__sign.png`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let initialsUrl;
|
||||||
|
if (initialFile && !isInitialsUrl) {
|
||||||
|
initialsUrl = await uploadFile(initialFile);
|
||||||
|
} else {
|
||||||
|
initialsUrl = imgInitials;
|
||||||
}
|
}
|
||||||
if (imgUrl) {
|
if (imgUrl) {
|
||||||
await saveEntry({
|
await saveEntry({
|
||||||
@@ -146,7 +178,7 @@ const ManageSign = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
function base64StringtoFile(base64String, filename) {
|
function base64StringtoFile(base64String, filename) {
|
||||||
var arr = base64String.split(","),
|
let arr = base64String.split(","),
|
||||||
mime = arr[0].match(/:(.*?);/)[1],
|
mime = arr[0].match(/:(.*?);/)[1],
|
||||||
bstr = atob(arr[1]),
|
bstr = atob(arr[1]),
|
||||||
n = bstr.length,
|
n = bstr.length,
|
||||||
@@ -175,31 +207,24 @@ const ManageSign = () => {
|
|||||||
|
|
||||||
const saveEntry = async (obj) => {
|
const saveEntry = async (obj) => {
|
||||||
const signCls = "contracts_Signature";
|
const signCls = "contracts_Signature";
|
||||||
const User = Parse.User.current().id;
|
const User = Parse?.User?.current()?.id;
|
||||||
const userId = { __type: "Pointer", className: "_User", objectId: User };
|
const userId = { __type: "Pointer", className: "_User", objectId: User };
|
||||||
if (id) {
|
if (id) {
|
||||||
try {
|
try {
|
||||||
const updateSign = new Parse.Object(signCls);
|
const updateSign = new Parse.Object(signCls);
|
||||||
updateSign.id = id;
|
updateSign.id = id;
|
||||||
updateSign.set("Initials", obj.initialsUrl ? obj.initialsUrl : "");
|
updateSign.set("Initials", obj.initialsUrl ? obj.initialsUrl : "");
|
||||||
updateSign.set("ImageURL", obj.url);
|
updateSign.set("ImageURL", obj.url ? obj.url : "");
|
||||||
updateSign.set("SignatureName", obj.name);
|
updateSign.set("SignatureName", obj.name);
|
||||||
updateSign.set("UserId", userId);
|
updateSign.set("UserId", userId);
|
||||||
const res = await updateSign.save();
|
const res = await updateSign.save();
|
||||||
setIsLoader(false);
|
setIsAlert({ type: "success", message: t("signature-saved-alert") });
|
||||||
setIsAlert({
|
|
||||||
type: "success",
|
|
||||||
message: t("signature-saved-alert")
|
|
||||||
});
|
|
||||||
setTimeout(() => setIsAlert({}), 2000);
|
|
||||||
return res;
|
return res;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
setIsAlert({ type: "danger", message: `${err.message}` });
|
||||||
|
} finally {
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
setIsAlert({
|
|
||||||
type: "danger",
|
|
||||||
message: `${err.message}`
|
|
||||||
});
|
|
||||||
setTimeout(() => setIsAlert({}), 2000);
|
setTimeout(() => setIsAlert({}), 2000);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -210,20 +235,13 @@ const ManageSign = () => {
|
|||||||
updateSign.set("SignatureName", obj.name);
|
updateSign.set("SignatureName", obj.name);
|
||||||
updateSign.set("UserId", userId);
|
updateSign.set("UserId", userId);
|
||||||
const res = await updateSign.save();
|
const res = await updateSign.save();
|
||||||
setIsLoader(false);
|
setIsAlert({ type: "success", message: t("signature-saved-alert") });
|
||||||
setIsAlert({
|
|
||||||
type: "success",
|
|
||||||
message: t("signature-saved-alert")
|
|
||||||
});
|
|
||||||
setTimeout(() => setIsAlert({}), 2000);
|
|
||||||
return res;
|
return res;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
setIsAlert({ type: "success", message: `${err.message}` });
|
||||||
|
} finally {
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
setIsAlert({
|
|
||||||
type: "success",
|
|
||||||
message: `${err.message}`
|
|
||||||
});
|
|
||||||
setTimeout(() => setIsAlert({}), 2000);
|
setTimeout(() => setIsAlert({}), 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -234,7 +252,29 @@ const ManageSign = () => {
|
|||||||
};
|
};
|
||||||
const handleInitialsChange = () => {
|
const handleInitialsChange = () => {
|
||||||
setInitials(initailsRef.current.toDataURL());
|
setInitials(initailsRef.current.toDataURL());
|
||||||
setIsValue(true);
|
if (image || signature) {
|
||||||
|
setIsValue(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleUploadInitials = () => {
|
||||||
|
imgInitialsRef.current.click();
|
||||||
|
};
|
||||||
|
const onImgInitialsChange = async (event) => {
|
||||||
|
if (initailsRef.current) {
|
||||||
|
initailsRef.current.clear();
|
||||||
|
}
|
||||||
|
setInitials("");
|
||||||
|
if (event.target.files && event.target.files[0]) {
|
||||||
|
const file = event.target.files[0];
|
||||||
|
const base64Img = await toDataUrl(file);
|
||||||
|
setImgInitials(base64Img);
|
||||||
|
if (image || signature) {
|
||||||
|
setIsValue(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setImgInitials("");
|
||||||
|
setIsValue(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div className="relative h-full bg-base-100 text-base-content flex shadow-md rounded-box overflow-auto">
|
<div className="relative h-full bg-base-100 text-base-content flex shadow-md rounded-box overflow-auto">
|
||||||
@@ -281,7 +321,7 @@ const ManageSign = () => {
|
|||||||
height: "180px",
|
height: "180px",
|
||||||
className: "signatureCanvas rounded-box"
|
className: "signatureCanvas rounded-box"
|
||||||
}}
|
}}
|
||||||
backgroundColor="rgb(255, 255, 255)"
|
// backgroundColor="rgb(255, 255, 255)"
|
||||||
onEnd={() =>
|
onEnd={() =>
|
||||||
handleSignatureChange(canvasRef.current.toDataURL())
|
handleSignatureChange(canvasRef.current.toDataURL())
|
||||||
}
|
}
|
||||||
@@ -332,7 +372,7 @@ const ManageSign = () => {
|
|||||||
className="op-link"
|
className="op-link"
|
||||||
onClick={() => handleUploadBtn()}
|
onClick={() => handleUploadBtn()}
|
||||||
>
|
>
|
||||||
{t("upload-image")}
|
{t("upload")}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
type="button"
|
type="button"
|
||||||
@@ -356,17 +396,21 @@ const ManageSign = () => {
|
|||||||
<span className="font-medium select-none flex mb-[10px] pl-[10px]">
|
<span className="font-medium select-none flex mb-[10px] pl-[10px]">
|
||||||
{t("initials")}
|
{t("initials")}
|
||||||
</span>
|
</span>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
onChange={onImgInitialsChange}
|
||||||
|
className="filetype"
|
||||||
|
accept="image/*"
|
||||||
|
ref={imgInitialsRef}
|
||||||
|
hidden
|
||||||
|
/>
|
||||||
<div>
|
<div>
|
||||||
{isInitials ? (
|
{imgInitials ? (
|
||||||
<div className="intialSignature relative border-[1px] border-[#888] rounded-box overflow-hidden">
|
<div className="intialSignature relative border-[1px] border-[#888] rounded-box overflow-hidden">
|
||||||
<img
|
<img
|
||||||
alt="inititals"
|
alt="inititals"
|
||||||
src={Initials}
|
src={imgInitials}
|
||||||
style={{
|
className="w-[100%] h-[100%] object-contain"
|
||||||
width: "100%",
|
|
||||||
height: "100%",
|
|
||||||
objectFit: "contain"
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
@@ -376,10 +420,8 @@ const ManageSign = () => {
|
|||||||
canvasProps={{
|
canvasProps={{
|
||||||
className: "intialSignature rounded-box"
|
className: "intialSignature rounded-box"
|
||||||
}}
|
}}
|
||||||
backgroundColor="rgb(255, 255, 255)"
|
// backgroundColor="rgb(255, 255, 255)"
|
||||||
onEnd={() =>
|
onEnd={() => handleInitialsChange()}
|
||||||
handleInitialsChange(initailsRef.current.toDataURL())
|
|
||||||
}
|
|
||||||
dotSize={1}
|
dotSize={1}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@@ -402,6 +444,7 @@ const ManageSign = () => {
|
|||||||
? "2px solid black"
|
? "2px solid black"
|
||||||
: "2px solid white"
|
: "2px solid white"
|
||||||
}}
|
}}
|
||||||
|
className="fa-light fa-pen-nib"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (key === 0) {
|
if (key === 0) {
|
||||||
setInitialPen("blue");
|
setInitialPen("blue");
|
||||||
@@ -412,7 +455,6 @@ const ManageSign = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
key={key}
|
key={key}
|
||||||
className="fa-light fa-pen-nib"
|
|
||||||
width={20}
|
width={20}
|
||||||
height={20}
|
height={20}
|
||||||
></i>
|
></i>
|
||||||
@@ -421,13 +463,22 @@ const ManageSign = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div className="flex flex-row gap-1">
|
||||||
<div
|
<div
|
||||||
type="button"
|
type="button"
|
||||||
className="op-link text-sm md:text-base mr-1"
|
className="op-link text-sm md:text-base mr-1"
|
||||||
onClick={() => handleClearInitials()}
|
onClick={() => handleUploadInitials()}
|
||||||
>
|
>
|
||||||
{t("clear")}
|
{t("upload")}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
type="button"
|
||||||
|
className="op-link text-sm md:text-base mr-1"
|
||||||
|
onClick={() => handleClearInitials()}
|
||||||
|
>
|
||||||
|
{t("clear")}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -244,7 +244,13 @@ function PdfRequestFiles(props) {
|
|||||||
};
|
};
|
||||||
async function checkIsSubscribed(extUserId, contactId) {
|
async function checkIsSubscribed(extUserId, contactId) {
|
||||||
const isGuestSign = isGuestSignFlow || false;
|
const isGuestSign = isGuestSignFlow || false;
|
||||||
const res = await fetchSubscription(extUserId, contactId, isGuestSign);
|
const isPublic = props.templateId ? true : false;
|
||||||
|
const res = await fetchSubscription(
|
||||||
|
extUserId,
|
||||||
|
contactId,
|
||||||
|
isGuestSign,
|
||||||
|
isPublic
|
||||||
|
);
|
||||||
const plan = res.plan;
|
const plan = res.plan;
|
||||||
const billingDate = res?.billingDate;
|
const billingDate = res?.billingDate;
|
||||||
const status = res?.status;
|
const status = res?.status;
|
||||||
@@ -278,6 +284,7 @@ function PdfRequestFiles(props) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//function for get document details for perticular signer with signer'object id
|
//function for get document details for perticular signer with signer'object id
|
||||||
|
//whenever change anything in this function check react/angular packages also in plan js
|
||||||
const getTemplateDetails = async () => {
|
const getTemplateDetails = async () => {
|
||||||
try {
|
try {
|
||||||
const params = { templateId: props.templateId, ispublic: true };
|
const params = { templateId: props.templateId, ispublic: true };
|
||||||
@@ -292,19 +299,22 @@ function PdfRequestFiles(props) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const documentData =
|
const documentData = templateDeatils?.data?.result
|
||||||
templateDeatils.data && templateDeatils.data.result
|
? [templateDeatils?.data?.result]
|
||||||
? [templateDeatils.data.result]
|
: [];
|
||||||
: [];
|
|
||||||
if (documentData && documentData[0]?.error) {
|
if (documentData && documentData[0]?.error) {
|
||||||
props?.setTemplateStatus({
|
props?.setTemplateStatus &&
|
||||||
status: "Invalid"
|
props?.setTemplateStatus({
|
||||||
});
|
status: "Invalid"
|
||||||
|
});
|
||||||
|
throw new Error("error: Invalid TemplateId");
|
||||||
} else if (documentData && documentData.length > 0) {
|
} else if (documentData && documentData.length > 0) {
|
||||||
if (documentData[0]?.IsPublic) {
|
if (documentData[0]?.IsPublic) {
|
||||||
props?.setTemplateStatus({
|
//handle condition when someone use plan js then setTemplateStatus is not supporting
|
||||||
status: "Success"
|
props?.setTemplateStatus &&
|
||||||
});
|
props?.setTemplateStatus({
|
||||||
|
status: "Success"
|
||||||
|
});
|
||||||
const url =
|
const url =
|
||||||
documentData[0] &&
|
documentData[0] &&
|
||||||
(documentData[0]?.SignedUrl || documentData[0]?.URL);
|
(documentData[0]?.SignedUrl || documentData[0]?.URL);
|
||||||
@@ -348,22 +358,34 @@ function PdfRequestFiles(props) {
|
|||||||
isLoad: false
|
isLoad: false
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
props?.setTemplateStatus({
|
props?.setTemplateStatus &&
|
||||||
status: "Private"
|
props?.setTemplateStatus({
|
||||||
});
|
status: "Private"
|
||||||
|
});
|
||||||
|
setIsLoading(false);
|
||||||
|
setHandleError(t("something-went-wrong-mssg"));
|
||||||
|
console.error("error: TemplateId is not public");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
props?.setTemplateStatus({
|
props?.setTemplateStatus &&
|
||||||
status: "Invalid"
|
props?.setTemplateStatus({
|
||||||
});
|
status: "Invalid"
|
||||||
|
});
|
||||||
|
setIsLoading(false);
|
||||||
|
setHandleError(t("something-went-wrong-mssg"));
|
||||||
|
console.error("error: Invalid TemplateId");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("err in get template details ", err);
|
setIsLoading(false);
|
||||||
if (err?.response?.data?.code === 101) {
|
if (err?.response?.data?.code === 101) {
|
||||||
setHandleError(t("error-template"));
|
setHandleError(t("error-template"));
|
||||||
} else {
|
} else {
|
||||||
setHandleError(t("something-went-wrong-mssg"));
|
setHandleError(t("something-went-wrong-mssg"));
|
||||||
}
|
}
|
||||||
|
console.error("error: Invalid TemplateId");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//function for get document details for perticular signer with signer'object id
|
//function for get document details for perticular signer with signer'object id
|
||||||
@@ -1287,7 +1309,11 @@ function PdfRequestFiles(props) {
|
|||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log("error updating field is decline ", err);
|
console.log("error updating field is decline ", err);
|
||||||
setIsUiLoading(false);
|
setIsUiLoading(false);
|
||||||
alert(t("something-went-wrong-mssg"));
|
setIsAlert({
|
||||||
|
title: "Error",
|
||||||
|
isShow: true,
|
||||||
|
alertMessage: t("something-went-wrong-mssg")
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
//function to add default signature for all requested placeholder of sign
|
//function to add default signature for all requested placeholder of sign
|
||||||
@@ -1488,11 +1514,32 @@ function PdfRequestFiles(props) {
|
|||||||
await SendOtp();
|
await SendOtp();
|
||||||
} else {
|
} else {
|
||||||
console.log("error in public-sign to create user details");
|
console.log("error in public-sign to create user details");
|
||||||
alert(t("something-went-wrong-mssg"));
|
setIsAlert({
|
||||||
|
title: "Error",
|
||||||
|
isShow: true,
|
||||||
|
alertMessage: t("something-went-wrong-mssg")
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("e", e);
|
console.log("e", e);
|
||||||
// setIsLoader(false);
|
if (
|
||||||
|
e?.response?.data?.error === "Insufficient Credit" ||
|
||||||
|
e?.response?.data?.error === "Plan expired"
|
||||||
|
) {
|
||||||
|
handleCloseOtp();
|
||||||
|
setIsAlert({
|
||||||
|
title: t("insufficient-credits"),
|
||||||
|
isShow: true,
|
||||||
|
alertMessage: t("insufficient-credits-mssg")
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
handleCloseOtp();
|
||||||
|
setIsAlert({
|
||||||
|
title: "Error",
|
||||||
|
isShow: true,
|
||||||
|
alertMessage: t("something-went-wrong-mssg")
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1524,7 +1571,11 @@ function PdfRequestFiles(props) {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("error in verify otp in public-sign", error);
|
console.log("error in verify otp in public-sign", error);
|
||||||
alert(t("something-went-wrong-mssg"));
|
setIsAlert({
|
||||||
|
title: "Error",
|
||||||
|
isShow: true,
|
||||||
|
alertMessage: t("something-went-wrong-mssg")
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1680,27 +1731,6 @@ function PdfRequestFiles(props) {
|
|||||||
{!requestSignTour &&
|
{!requestSignTour &&
|
||||||
signerObjectId &&
|
signerObjectId &&
|
||||||
requestSignTourFunction()}
|
requestSignTourFunction()}
|
||||||
<ModalUi
|
|
||||||
isOpen={isAlert.isShow}
|
|
||||||
title={t("alert-message")}
|
|
||||||
handleClose={() =>
|
|
||||||
setIsAlert({ isShow: false, alertMessage: "" })
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<div className="h-full p-[20px]">
|
|
||||||
<p>{isAlert.alertMessage}</p>
|
|
||||||
<button
|
|
||||||
onClick={() =>
|
|
||||||
setIsAlert({ isShow: false, alertMessage: "" })
|
|
||||||
}
|
|
||||||
type="button"
|
|
||||||
className="op-btn op-btn-primary mt-3 px-4"
|
|
||||||
>
|
|
||||||
{t("ok")}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</ModalUi>
|
|
||||||
|
|
||||||
<Tour
|
<Tour
|
||||||
showNumber={false}
|
showNumber={false}
|
||||||
showNavigation={false}
|
showNavigation={false}
|
||||||
@@ -2216,6 +2246,22 @@ function PdfRequestFiles(props) {
|
|||||||
pdfDetails={pdfDetails}
|
pdfDetails={pdfDetails}
|
||||||
isDocId={true}
|
isDocId={true}
|
||||||
/>
|
/>
|
||||||
|
<ModalUi
|
||||||
|
isOpen={isAlert.isShow}
|
||||||
|
title={isAlert?.title || t("alert-message")}
|
||||||
|
handleClose={() => setIsAlert({ isShow: false, alertMessage: "" })}
|
||||||
|
>
|
||||||
|
<div className="h-full p-[20px]">
|
||||||
|
<p>{isAlert.alertMessage}</p>
|
||||||
|
<button
|
||||||
|
onClick={() => setIsAlert({ isShow: false, alertMessage: "" })}
|
||||||
|
type="button"
|
||||||
|
className="op-btn op-btn-primary mt-3 px-4"
|
||||||
|
>
|
||||||
|
{t("close")}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</DndProvider>
|
</DndProvider>
|
||||||
|
|||||||
@@ -1047,7 +1047,7 @@ function PlaceHolderSign() {
|
|||||||
type="button"
|
type="button"
|
||||||
className="flex flex-row items-center op-link op-link-primary"
|
className="flex flex-row items-center op-link op-link-primary"
|
||||||
>
|
>
|
||||||
<i className="fa-light fa-link" aria-hidden="true"></i>
|
<i className="fa-light fa-copy" />
|
||||||
<span className=" hidden md:block ml-1 ">{t("copy-link")}</span>
|
<span className=" hidden md:block ml-1 ">{t("copy-link")}</span>
|
||||||
</button>
|
</button>
|
||||||
<RWebShare data={{ url: data.url, title: t("sign-url") }}>
|
<RWebShare data={{ url: data.url, title: t("sign-url") }}>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ const UpdateExistUserAdmin = () => {
|
|||||||
const [isAlert, setIsAlert] = useState({ type: "danger", msg: "" });
|
const [isAlert, setIsAlert] = useState({ type: "danger", msg: "" });
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
checkIsAdminExist();
|
checkIsAdminExist();
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const checkIsAdminExist = async () => {
|
const checkIsAdminExist = async () => {
|
||||||
@@ -22,7 +23,7 @@ const UpdateExistUserAdmin = () => {
|
|||||||
const isAdminExist = await Parse.Cloud.run("checkadminexist");
|
const isAdminExist = await Parse.Cloud.run("checkadminexist");
|
||||||
if (isAdminExist !== "not_exist") {
|
if (isAdminExist !== "not_exist") {
|
||||||
// console.log("isAdminExist ", isAdminExist);
|
// console.log("isAdminExist ", isAdminExist);
|
||||||
setErrMsg("Admin already exists.");
|
setErrMsg(t("admin-exists"));
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("Err in checkadminexist", err);
|
console.log("Err in checkadminexist", err);
|
||||||
@@ -52,7 +53,7 @@ const UpdateExistUserAdmin = () => {
|
|||||||
} else if (err.code === 101) {
|
} else if (err.code === 101) {
|
||||||
setIsAlert((prev) => ({ ...prev, msg: t("user-not-found") }));
|
setIsAlert((prev) => ({ ...prev, msg: t("user-not-found") }));
|
||||||
} else if (err.code === 137) {
|
} else if (err.code === 137) {
|
||||||
setIsAlert((prev) => ({ ...prev, msg: t("admin-already-exist") }));
|
setIsAlert((prev) => ({ ...prev, msg: t("admin-exists") }));
|
||||||
} else {
|
} else {
|
||||||
setErrMsg(t("something-went-wrong-mssg"));
|
setErrMsg(t("something-went-wrong-mssg"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -596,7 +596,7 @@ function UserProfile() {
|
|||||||
className="op-btn op-btn-primary op-btn-outline op-btn-xs md:op-btn-sm"
|
className="op-btn op-btn-primary op-btn-outline op-btn-xs md:op-btn-sm"
|
||||||
onClick={() => copytoclipboard()}
|
onClick={() => copytoclipboard()}
|
||||||
>
|
>
|
||||||
<i className="fa-light fa-link"></i>{" "}
|
<i className="fa-light fa-copy" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ const Alert = ({ children, type, className }) => {
|
|||||||
: "z-[1000] fixed top-20 left-1/2 transform -translate-x-1/2 text-sm"
|
: "z-[1000] fixed top-20 left-1/2 transform -translate-x-1/2 text-sm"
|
||||||
} `}
|
} `}
|
||||||
>
|
>
|
||||||
<div className={`op-alert ${textcolor}`}>
|
<div className={`op-alert ${textcolor} flex justify-center`}>
|
||||||
<span className="ml-3">{children}</span>
|
<span className="px-1">{children}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import { validplan } from "../json/plansArr";
|
|||||||
import { serverUrl_fn } from "../constant/appinfo";
|
import { serverUrl_fn } from "../constant/appinfo";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import DownloadPdfZip from "./DownloadPdfZip";
|
import DownloadPdfZip from "./DownloadPdfZip";
|
||||||
|
import EmbedTab from "../components/pdf/EmbedTab";
|
||||||
|
|
||||||
const ReportTable = (props) => {
|
const ReportTable = (props) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -74,6 +75,8 @@ const ReportTable = (props) => {
|
|||||||
const [isModal, setIsModal] = useState({});
|
const [isModal, setIsModal] = useState({});
|
||||||
const [reason, setReason] = useState("");
|
const [reason, setReason] = useState("");
|
||||||
const [isDownloadModal, setIsDownloadModal] = useState(false);
|
const [isDownloadModal, setIsDownloadModal] = useState(false);
|
||||||
|
const [isEmbed, setIsEmbed] = useState(false);
|
||||||
|
const [isPublicTour, setIsPublicTour] = useState();
|
||||||
const Extand_Class = localStorage.getItem("Extand_Class");
|
const Extand_Class = localStorage.getItem("Extand_Class");
|
||||||
const extClass = Extand_Class && JSON.parse(Extand_Class);
|
const extClass = Extand_Class && JSON.parse(Extand_Class);
|
||||||
const startIndex = (currentPage - 1) * props.docPerPage;
|
const startIndex = (currentPage - 1) * props.docPerPage;
|
||||||
@@ -369,6 +372,21 @@ const ReportTable = (props) => {
|
|||||||
setIsShareWith({ [item.objectId]: true });
|
setIsShareWith({ [item.objectId]: true });
|
||||||
} else if (act.action === "Embed") {
|
} else if (act.action === "Embed") {
|
||||||
handleEmbedFunction(item);
|
handleEmbedFunction(item);
|
||||||
|
} else if (act.action === "CopyTemplateId") {
|
||||||
|
copyTemplateId(item.objectId);
|
||||||
|
} else if (act.action === "CopyPublicURL") {
|
||||||
|
const isPublic = item?.IsPublic;
|
||||||
|
if (isPublic) {
|
||||||
|
let publicUrl = "";
|
||||||
|
if (isStaging) {
|
||||||
|
publicUrl = `https://staging.opensign.me/publicsign?templateid=${item.objectId}`;
|
||||||
|
} else {
|
||||||
|
publicUrl = `https://opensign.me/publicsign?templateid=${item.objectId}`;
|
||||||
|
}
|
||||||
|
copyTemplateId(publicUrl);
|
||||||
|
} else {
|
||||||
|
setIsPublicTour({ [item.objectId]: true });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// Get current list
|
// Get current list
|
||||||
@@ -1121,12 +1139,25 @@ const ReportTable = (props) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const handleEmbedFunction = async (item) => {
|
const handleEmbedFunction = async (item) => {
|
||||||
|
setIsEmbed(true);
|
||||||
setIsPublicProfile({
|
setIsPublicProfile({
|
||||||
[item.objectId]: props.isPublic[item.objectId]
|
[item.objectId]: true
|
||||||
});
|
});
|
||||||
let extendUser = JSON.parse(localStorage.getItem("Extand_Class"));
|
let extendUser = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||||
setIsPublicUserName(extendUser[0]?.UserName || "");
|
setIsPublicUserName(extendUser[0]?.UserName || "");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const publicTourConfig = [
|
||||||
|
{
|
||||||
|
selector: '[data-tut="IsPublic"]',
|
||||||
|
content: t("public-tour-message"),
|
||||||
|
position: "top",
|
||||||
|
style: { fontSize: "13px" }
|
||||||
|
}
|
||||||
|
];
|
||||||
|
const closePublicTour = () => {
|
||||||
|
setIsPublicTour();
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
{Object.keys(actLoader)?.length > 0 && (
|
{Object.keys(actLoader)?.length > 0 && (
|
||||||
@@ -1147,13 +1178,27 @@ const ReportTable = (props) => {
|
|||||||
)}
|
)}
|
||||||
{isAlert && <Alert type={alertMsg.type}>{alertMsg.message}</Alert>}
|
{isAlert && <Alert type={alertMsg.type}>{alertMsg.message}</Alert>}
|
||||||
{props.tourData && props.ReportName === "Templates" && (
|
{props.tourData && props.ReportName === "Templates" && (
|
||||||
<Tour
|
<>
|
||||||
onRequestClose={closeTour}
|
<Tour
|
||||||
steps={props.tourData}
|
onRequestClose={closeTour}
|
||||||
isOpen={isTour}
|
steps={props.tourData}
|
||||||
// rounded={5}
|
isOpen={isTour}
|
||||||
closeWithMask={false}
|
// rounded={5}
|
||||||
/>
|
closeWithMask={false}
|
||||||
|
/>
|
||||||
|
{isPublicTour && (
|
||||||
|
<Tour
|
||||||
|
showNumber={false}
|
||||||
|
showNavigation={false}
|
||||||
|
showNavigationNumber={false}
|
||||||
|
onRequestClose={closePublicTour}
|
||||||
|
steps={publicTourConfig}
|
||||||
|
isOpen={true}
|
||||||
|
rounded={5}
|
||||||
|
closeWithMask={false}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
<div className="flex flex-row items-center justify-between my-2 mx-3 text-[20px] md:text-[23px]">
|
<div className="flex flex-row items-center justify-between my-2 mx-3 text-[20px] md:text-[23px]">
|
||||||
<div className="font-light">
|
<div className="font-light">
|
||||||
@@ -1369,13 +1414,17 @@ const ReportTable = (props) => {
|
|||||||
isEnableSubscription && (
|
isEnableSubscription && (
|
||||||
<td className=" pl-[20px] py-2">
|
<td className=" pl-[20px] py-2">
|
||||||
{props.ReportName === "Templates" && (
|
{props.ReportName === "Templates" && (
|
||||||
<div className="flex flex-row">
|
<div
|
||||||
|
className="flex flex-row "
|
||||||
|
data-tut="IsPublic"
|
||||||
|
>
|
||||||
<label className="cursor-pointer relative inline-flex items-center mb-0">
|
<label className="cursor-pointer relative inline-flex items-center mb-0">
|
||||||
<input
|
<input
|
||||||
checked={props.isPublic?.[item.objectId]}
|
checked={props.isPublic?.[item.objectId]}
|
||||||
onChange={(e) =>
|
onChange={(e) => {
|
||||||
handlePublicChange(e, item)
|
setIsPublicTour();
|
||||||
}
|
handlePublicChange(e, item);
|
||||||
|
}}
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
value=""
|
value=""
|
||||||
className="sr-only peer"
|
className="sr-only peer"
|
||||||
@@ -1446,22 +1495,27 @@ const ReportTable = (props) => {
|
|||||||
<ModalUi
|
<ModalUi
|
||||||
isOpen
|
isOpen
|
||||||
title={t("public-url")}
|
title={t("public-url")}
|
||||||
handleClose={() => setIsPublicProfile({})}
|
handleClose={() => {
|
||||||
|
setIsPublicProfile({});
|
||||||
|
setIsEmbed(false);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div className="m-[20px]">
|
<div className="m-[20px]">
|
||||||
{publicUserName ? (
|
{isEmbed && !item?.IsPublic ? (
|
||||||
|
<>
|
||||||
|
<p>{t("public-template-mssg-6")}</p>
|
||||||
|
<EmbedTab templateId={item.objectId} />
|
||||||
|
</>
|
||||||
|
) : publicUserName ? (
|
||||||
<div className="font-normal text-black">
|
<div className="font-normal text-black">
|
||||||
<p>{t("public-url-copy-mssg")}</p>
|
<span>{t("public-url-copy")}</span>
|
||||||
<div className=" flex items-center justify-between gap-3 mt-2 p-[2px] ">
|
<div className=" flex items-center justify-between gap-3 p-[2px] ">
|
||||||
<div className="w-[280px] whitespace-nowrap overflow-hidden text-ellipsis">
|
<div className="w-[280px] whitespace-nowrap overflow-hidden text-ellipsis">
|
||||||
<span className="font-bold">
|
|
||||||
{t("public-url")} :
|
|
||||||
</span>
|
|
||||||
<span
|
<span
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
copytoProfileLink()
|
copytoProfileLink()
|
||||||
}
|
}
|
||||||
className="ml-[2px] underline underline-offset-2 cursor-pointer"
|
className="ml-[2px] underline underline-offset-2 cursor-pointer text-blue-800"
|
||||||
>
|
>
|
||||||
{publicUrl()}
|
{publicUrl()}
|
||||||
</span>
|
</span>
|
||||||
@@ -1486,7 +1540,7 @@ const ReportTable = (props) => {
|
|||||||
copytoProfileLink()
|
copytoProfileLink()
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<i className="fa-light fa-link"></i>{" "}
|
<i className="fa-light fa-copy" />
|
||||||
<span className="hidden md:inline-block">
|
<span className="hidden md:inline-block">
|
||||||
{copied["publicprofile"]
|
{copied["publicprofile"]
|
||||||
? t("copied")
|
? t("copied")
|
||||||
@@ -1495,36 +1549,10 @@ const ReportTable = (props) => {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className=" flex items-center justify-between gap-3 mt-2 p-[2px] ">
|
<p className="text-[13px] mt-[5px]">
|
||||||
<div>
|
{t("public-url-copy-mssg")}
|
||||||
<span className="font-bold">
|
</p>
|
||||||
{t("templateid")} :
|
<EmbedTab templateId={item.objectId} />
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
onClick={() =>
|
|
||||||
copyTemplateId(item.objectId)
|
|
||||||
}
|
|
||||||
className="underline ml-[2px] underline-offset-2 w-[150px] md:w-[350px] whitespace-nowrap overflow-hidden text-ellipsis cursor-pointer"
|
|
||||||
>
|
|
||||||
{item.objectId}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<button
|
|
||||||
className="op-btn op-btn-primary op-btn-outline op-btn-xs md:op-btn-sm"
|
|
||||||
onClick={() =>
|
|
||||||
copyTemplateId(item.objectId)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<i className="fa-light fa-link"></i>{" "}
|
|
||||||
<span className="hidden md:inline-block">
|
|
||||||
{copied["templateid"]
|
|
||||||
? t("copied")
|
|
||||||
: t("copy")}
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="font-normal text-black">
|
<div className="font-normal text-black">
|
||||||
@@ -1584,65 +1612,33 @@ const ReportTable = (props) => {
|
|||||||
{isOption[item.objectId] &&
|
{isOption[item.objectId] &&
|
||||||
act.action === "option" && (
|
act.action === "option" && (
|
||||||
<ul className="absolute -right-1 top-auto z-[70] w-max op-dropdown-content op-menu shadow bg-base-100 text-base-content rounded-box">
|
<ul className="absolute -right-1 top-auto z-[70] w-max op-dropdown-content op-menu shadow bg-base-100 text-base-content rounded-box">
|
||||||
{act.subaction?.map((subact) =>
|
{act.subaction?.map((subact) => (
|
||||||
props.isPublic[
|
<li
|
||||||
item.objectId
|
key={subact.btnId}
|
||||||
] ? (
|
onClick={() =>
|
||||||
<li
|
handleActionBtn(
|
||||||
key={subact.btnId}
|
subact,
|
||||||
onClick={() =>
|
item
|
||||||
handleActionBtn(
|
)
|
||||||
subact,
|
}
|
||||||
item
|
title={t(
|
||||||
)
|
`btnLabel.${subact.btnLabel}`
|
||||||
}
|
)}
|
||||||
title={t(
|
>
|
||||||
`btnLabel.${subact.btnLabel}`
|
<span>
|
||||||
)}
|
<i
|
||||||
>
|
className={`${subact.btnIcon} mr-1.5`}
|
||||||
<span>
|
></i>
|
||||||
<i
|
{subact.btnLabel && (
|
||||||
className={`${subact.btnIcon} mr-1.5`}
|
<span className="text-[13px] capitalize font-medium">
|
||||||
></i>
|
{t(
|
||||||
{subact.btnLabel && (
|
`btnLabel.${subact.btnLabel}`
|
||||||
<span className="text-[13px] capitalize font-medium">
|
|
||||||
{t(
|
|
||||||
`btnLabel.${subact.btnLabel}`
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
) : (
|
|
||||||
subact.action !== "Embed" && (
|
|
||||||
<li
|
|
||||||
key={subact.btnId}
|
|
||||||
onClick={() =>
|
|
||||||
handleActionBtn(
|
|
||||||
subact,
|
|
||||||
item
|
|
||||||
)
|
|
||||||
}
|
|
||||||
title={t(
|
|
||||||
`btnLabel.${subact.btnLabel}`
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
<i
|
|
||||||
className={`${subact.btnIcon} mr-1.5`}
|
|
||||||
></i>
|
|
||||||
{subact.btnLabel && (
|
|
||||||
<span className="text-[13px] capitalize font-medium">
|
|
||||||
{t(
|
|
||||||
`btnLabel.${subact.btnLabel}`
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</li>
|
)}
|
||||||
)
|
</span>
|
||||||
)
|
</li>
|
||||||
)}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -1963,7 +1959,7 @@ const ReportTable = (props) => {
|
|||||||
className="op-btn op-btn-primary op-btn-outline op-btn-xs md:op-btn-sm"
|
className="op-btn op-btn-primary op-btn-outline op-btn-xs md:op-btn-sm"
|
||||||
onClick={() => copytoclipboard(share)}
|
onClick={() => copytoclipboard(share)}
|
||||||
>
|
>
|
||||||
<i className="fa-light fa-link"></i>{" "}
|
<i className="fa-light fa-copy" />
|
||||||
{copied[share.email]
|
{copied[share.email]
|
||||||
? t("copied")
|
? t("copied")
|
||||||
: t("copy")}
|
: t("copy")}
|
||||||
|
|||||||
@@ -11,28 +11,37 @@ import { isPublicStaging } from "../constant/const";
|
|||||||
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.min.mjs`;
|
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.min.mjs`;
|
||||||
|
|
||||||
// Wrapper component to manage props
|
// Wrapper component to manage props
|
||||||
const PublicScriptFileWrapper = ({ initialProps }) => {
|
const PublicScriptFileWrapper = () => {
|
||||||
const [props, setProps] = useState(initialProps);
|
const [props, setProps] = useState("");
|
||||||
|
|
||||||
// Make the setProps function globally accessible
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// Assigns the function 'setProps' to the global 'window' object as 'updatePublicTemplateProps'.
|
||||||
|
// This allows 'setProps' to be accessed and called globally across different scripts or components,
|
||||||
|
// enabling dynamic updates to the public template's properties.
|
||||||
window.updatePublicTemplateProps = setProps;
|
window.updatePublicTemplateProps = setProps;
|
||||||
|
const publicScript = document.getElementById("opensign-script");
|
||||||
|
// condition for using plan js load opensign-script then get templateId
|
||||||
|
if (publicScript) {
|
||||||
|
// Get the custom templateId attribute
|
||||||
|
const templateId = publicScript.getAttribute("templateId");
|
||||||
|
if (templateId) {
|
||||||
|
setProps({ templateId: templateId });
|
||||||
|
} else {
|
||||||
|
const error = "error: TemplateId is missing";
|
||||||
|
throw new Error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
return () => {
|
return () => {
|
||||||
window.updatePublicTemplateProps = undefined;
|
window.updatePublicTemplateProps = undefined;
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return <PdfRequestFiles {...props} />;
|
return <PdfRequestFiles {...props} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
const appId = isPublicStaging ? "opensign" : "legadranaxn";
|
const appId = isPublicStaging ? "opensign" : "legadranaxn";
|
||||||
//"opensign"
|
|
||||||
|
|
||||||
const serverUrl = isPublicStaging
|
const serverUrl = isPublicStaging
|
||||||
? "https://staging-app.opensignlabs.com/api/app"
|
? "https://staging-app.opensignlabs.com/api/app"
|
||||||
: "https://app.opensignlabs.com/api/app";
|
: "https://app.opensignlabs.com/api/app";
|
||||||
// "https://staging-app.opensignlabs.com/api/app"
|
|
||||||
|
|
||||||
localStorage.setItem("baseUrl", `${serverUrl}/`);
|
localStorage.setItem("baseUrl", `${serverUrl}/`);
|
||||||
localStorage.setItem("parseAppId", appId);
|
localStorage.setItem("parseAppId", appId);
|
||||||
@@ -58,7 +67,7 @@ const root = ReactDOM.createRoot(document.getElementById("script-component"));
|
|||||||
root.render(
|
root.render(
|
||||||
<div data-theme="opensigncss">
|
<div data-theme="opensigncss">
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<PublicScriptFileWrapper initialProps={{ text: "templateId" }} />
|
<PublicScriptFileWrapper />
|
||||||
</Provider>
|
</Provider>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -131,7 +131,9 @@
|
|||||||
"Share": "Share",
|
"Share": "Share",
|
||||||
"View": "View",
|
"View": "View",
|
||||||
"option": "Option",
|
"option": "Option",
|
||||||
"Embed": "Embed"
|
"Embed": "Embed",
|
||||||
|
"Copy TemplateId": "Copy TemplateId",
|
||||||
|
"Copy Public URL": "Copy Public URL"
|
||||||
},
|
},
|
||||||
"report-heading": {
|
"report-heading": {
|
||||||
"Sr.No": "Sr.No",
|
"Sr.No": "Sr.No",
|
||||||
@@ -264,7 +266,8 @@
|
|||||||
"make-template-private-alert": "Are you sure you want to make this template private? This will remove it from your public profile.",
|
"make-template-private-alert": "Are you sure you want to make this template private? This will remove it from your public profile.",
|
||||||
"public-role": "Public role",
|
"public-role": "Public role",
|
||||||
"public-url": "Public URL",
|
"public-url": "Public URL",
|
||||||
"public-url-copy-mssg": " Here’s your public URL: Copy it or share it with the signer, and you will be able to see all your publicly set templates.",
|
"public-url-copy": "Here’s your public URL: ",
|
||||||
|
"public-url-copy-mssg": "Copy it or share it with the signer, and you will be able to see all your publicly set templates.",
|
||||||
"add-public-url-alert": "Please add your public URL, and you will be able to make a public template.",
|
"add-public-url-alert": "Please add your public URL, and you will be able to make a public template.",
|
||||||
"share-with-alert": "You cannot share a template if any roles already have contacts assigned. Please remove all contact assignments from the roles before sharing the template.",
|
"share-with-alert": "You cannot share a template if any roles already have contacts assigned. Please remove all contact assignments from the roles before sharing the template.",
|
||||||
"share-with": "Share with",
|
"share-with": "Share with",
|
||||||
@@ -632,6 +635,19 @@
|
|||||||
"reason": "Reason",
|
"reason": "Reason",
|
||||||
"decline-by": "Declined/revoked by",
|
"decline-by": "Declined/revoked by",
|
||||||
"document-declined": "Document declined",
|
"document-declined": "Document declined",
|
||||||
|
"public-template-mssg-1": "To integrate OpenSign into your React or Next.js project, simply run the following command:",
|
||||||
|
"public-template-mssg-2": "Ensure you have npm or yarn set up in your project. If you’re using Yarn, you can replace npm install with yarn add @opensign/react.",
|
||||||
|
"public-template-mssg-3": "Need more details or examples?",
|
||||||
|
"public-template-mssg-4": "Visit the",
|
||||||
|
"public-template-mssg-5": " npm for the latest updates, detailed documentation, and version history.",
|
||||||
|
"public-template-mssg-6": "Before you can use this code snippet, you must make this template public.",
|
||||||
|
"copy-code": "COPY",
|
||||||
|
"copied-code": "COPIED",
|
||||||
|
"Installation": "Installation",
|
||||||
|
"Usage": "Usage",
|
||||||
|
"insufficient-credits": "Insufficient Signing Credits",
|
||||||
|
"insufficient-credits-mssg": "The owner of this document currently lacks the necessary OpenSign credits for you to sign. Please reach out to the owner if you require further details.",
|
||||||
|
"angular-npm-mssg-1": "To integrate OpenSign into your Angular project, simply run the following command:",
|
||||||
"quota-mail-info-head": "Monthly request signatures email limit",
|
"quota-mail-info-head": "Monthly request signatures email limit",
|
||||||
"quota-mail-info": "You can send upto 15 signature request emails every month. Upgrade now to send unlimited signing requests directly.",
|
"quota-mail-info": "You can send upto 15 signature request emails every month. Upgrade now to send unlimited signing requests directly.",
|
||||||
"quota-mail": "You've reached your limit of 15 signature request emails for this month. Upgrade now to continue sending emails directly.",
|
"quota-mail": "You've reached your limit of 15 signature request emails for this month. Upgrade now to continue sending emails directly.",
|
||||||
@@ -653,5 +669,8 @@
|
|||||||
"download-files": "Download files",
|
"download-files": "Download files",
|
||||||
"download-pdf": "Download Pdf",
|
"download-pdf": "Download Pdf",
|
||||||
"pdf-certificate": "Download Pdf + Certificate",
|
"pdf-certificate": "Download Pdf + Certificate",
|
||||||
"document-logs": "Document logs"
|
"document-logs": "Document logs",
|
||||||
|
"server-down": "Unable to connect to the OpenSign server. If you are self-hosting OpenSign, please ensure that all the steps in the documentation have been followed correctly. If you're running OpenSign locally, you might be accessing it through an incorrect port number.",
|
||||||
|
"admin-exists": "Admin already exists. Please login to the application using admin credentials in order to manage users.",
|
||||||
|
"public-tour-message": "Please make template public to copy public URL"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,7 +151,9 @@
|
|||||||
"Share": "Partager",
|
"Share": "Partager",
|
||||||
"View": "Voir",
|
"View": "Voir",
|
||||||
"option": "Option",
|
"option": "Option",
|
||||||
"Embed": "Intégrer"
|
"Embed": "Intégrer",
|
||||||
|
"Copy TemplateId": "Copier l'ID du modèle",
|
||||||
|
"Copy Public URL": "Copier l'URL publique"
|
||||||
},
|
},
|
||||||
"report-help": {
|
"report-help": {
|
||||||
"Draft Documents": "Il s'agit de documents que vous avez commencés mais que vous n'avez pas finalisés pour envoi.",
|
"Draft Documents": "Il s'agit de documents que vous avez commencés mais que vous n'avez pas finalisés pour envoi.",
|
||||||
@@ -263,7 +265,8 @@
|
|||||||
"make-template-private-alert": "Êtes-vous sûr de vouloir rendre ce modèle privé ? Cela le supprimera de votre profil public.",
|
"make-template-private-alert": "Êtes-vous sûr de vouloir rendre ce modèle privé ? Cela le supprimera de votre profil public.",
|
||||||
"public-role": "Rôle public",
|
"public-role": "Rôle public",
|
||||||
"public-url": "URL publique",
|
"public-url": "URL publique",
|
||||||
"public-url-copy-mssg": "Voici votre URL publique : copiez-la ou partagez-le avec le signataire et vous pouvoir voir tous vos paramètres publics modèles.",
|
"public-url-copy": "Voici votre URL publique : ",
|
||||||
|
"public-url-copy-mssg": "copiez-la ou partagez-le avec le signataire et vous pouvoir voir tous vos paramètres publics modèles.",
|
||||||
"add-public-url-alert": "Veuillez ajouter votre URL publique et vous pourra rendre public modèle.",
|
"add-public-url-alert": "Veuillez ajouter votre URL publique et vous pourra rendre public modèle.",
|
||||||
"share-with-alert": "Vous ne pouvez pas partager un modèle si des contacts sont déjà attribués à des rôles. Veuillez supprimer toutes les attributions de contacts des rôles avant de partager le modèle.",
|
"share-with-alert": "Vous ne pouvez pas partager un modèle si des contacts sont déjà attribués à des rôles. Veuillez supprimer toutes les attributions de contacts des rôles avant de partager le modèle.",
|
||||||
"share-with": "Partager avec",
|
"share-with": "Partager avec",
|
||||||
@@ -631,6 +634,19 @@
|
|||||||
"reason": "Raison",
|
"reason": "Raison",
|
||||||
"decline-by": "Refusé/révoqué par",
|
"decline-by": "Refusé/révoqué par",
|
||||||
"document-declined": "document refusé",
|
"document-declined": "document refusé",
|
||||||
|
"public-template-mssg-1": "Pour intégrer OpenSign dans votre projet React ou Next.js, exécutez simplement la commande suivante :",
|
||||||
|
"public-template-mssg-2": "Assurez-vous que npm ou Yarn est configuré dans votre projet. Si vous utilisez Yarn, vous pouvez remplacer npm install par Yarn Add @opensign/react.",
|
||||||
|
"public-template-mssg-3": "Besoin de plus de détails ou d'exemples ?",
|
||||||
|
"public-template-mssg-4": "Visitez le",
|
||||||
|
"public-template-mssg-5": "npm pour les dernières mises à jour, une documentation détaillée et l'historique des versions.",
|
||||||
|
"public-template-mssg-6": "Avant de pouvoir utiliser cet extrait de code, vous devez rendre ce modèle public.",
|
||||||
|
"copy-code": "COPIE",
|
||||||
|
"copied-code": "COPIÉ",
|
||||||
|
"Installation": "Installation",
|
||||||
|
"Usage": "Usage",
|
||||||
|
"insufficient-credits": "Crédits de signature insuffisants",
|
||||||
|
"insufficient-credits-mssg": "Le propriétaire de ce document ne dispose actuellement pas des crédits OpenSign nécessaires pour que vous puissiez le signer. Veuillez contacter le propriétaire si vous avez besoin de plus de détails.",
|
||||||
|
"angular-npm-mssg-1": "Pour intégrer OpenSign dans votre projet Angular, exécutez simplement la commande suivante :",
|
||||||
"quota-mail-info-head": "Limite mensuelle d'e-mails de signatures de demandes",
|
"quota-mail-info-head": "Limite mensuelle d'e-mails de signatures de demandes",
|
||||||
"quota-mail-info": "Vous pouvez envoyer jusqu'à 15 e-mails de demande de signature chaque mois. Mettez à niveau maintenant pour envoyer directement des demandes de signature illimitées.",
|
"quota-mail-info": "Vous pouvez envoyer jusqu'à 15 e-mails de demande de signature chaque mois. Mettez à niveau maintenant pour envoyer directement des demandes de signature illimitées.",
|
||||||
"quota-mail": "Vous avez atteint votre limite de 15 e-mails de demande de signature pour ce mois. Mettez à niveau maintenant pour continuer à envoyer des e-mails directement.",
|
"quota-mail": "Vous avez atteint votre limite de 15 e-mails de demande de signature pour ce mois. Mettez à niveau maintenant pour continuer à envoyer des e-mails directement.",
|
||||||
@@ -652,5 +668,8 @@
|
|||||||
"download-files": "Télécharger des fichiers",
|
"download-files": "Télécharger des fichiers",
|
||||||
"download-pdf": "Télécharger le PDF",
|
"download-pdf": "Télécharger le PDF",
|
||||||
"pdf-certificate": "Télécharger Pdf + Certificat",
|
"pdf-certificate": "Télécharger Pdf + Certificat",
|
||||||
"document-logs": "Journaux de documents"
|
"document-logs": "Journaux de documents",
|
||||||
|
"server-down": "Impossible de se connecter au serveur OpenSign. Si vous hébergez vous-même OpenSign, veuillez vous assurer que toutes les étapes de la documentation ont été correctement suivies. Si vous exécutez OpenSign localement, vous y accédez peut-être via un numéro de port incorrect.",
|
||||||
|
"admin-exists": "L'administrateur existe déjà. Veuillez vous connecter à l'application en utilisant les informations d'identification de l'administrateur afin de gérer les utilisateurs.",
|
||||||
|
"public-tour-message": "Veuillez rendre le modèle public pour copier l'URL publique"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
animation: inAnimation 2s ease-in-out;
|
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -196,8 +196,9 @@ export default async function createDocumentWithTemplate(request, response) {
|
|||||||
if (TimeToCompleteDays) {
|
if (TimeToCompleteDays) {
|
||||||
object.set('TimeToCompleteDays', TimeToCompleteDays);
|
object.set('TimeToCompleteDays', TimeToCompleteDays);
|
||||||
}
|
}
|
||||||
const enableOTP = request.body?.enableOTP === true ? true : false;
|
const enableOTP = request.body?.enableOTP;
|
||||||
const IsEnableOTP = enableOTP || template?.IsEnableOTP || false;
|
const IsEnableOTP =
|
||||||
|
enableOTP !== undefined ? enableOTP : template?.IsEnableOTP || false;
|
||||||
object.set('IsEnableOTP', IsEnableOTP);
|
object.set('IsEnableOTP', IsEnableOTP);
|
||||||
object.set('CreatedBy', template.CreatedBy);
|
object.set('CreatedBy', template.CreatedBy);
|
||||||
object.set('ExtUserPtr', {
|
object.set('ExtUserPtr', {
|
||||||
|
|||||||
@@ -48,10 +48,10 @@ export default async function updateDocument(request, response) {
|
|||||||
objectId: request?.body?.folderId,
|
objectId: request?.body?.folderId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (request.body?.enableOTP !== undefined) {
|
||||||
if (request.body?.enableOTP) {
|
|
||||||
updateQuery.set('IsEnableOTP', request.body?.enableOTP);
|
updateQuery.set('IsEnableOTP', request.body?.enableOTP);
|
||||||
}
|
}
|
||||||
|
|
||||||
const updatedRes = await updateQuery.save(null, { useMasterKey: true });
|
const updatedRes = await updateQuery.save(null, { useMasterKey: true });
|
||||||
if (updatedRes) {
|
if (updatedRes) {
|
||||||
if (request.posthog) {
|
if (request.posthog) {
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export default async function updateTemplate(request, response) {
|
|||||||
objectId: request?.body?.folderId,
|
objectId: request?.body?.folderId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (request.body?.enableOTP) {
|
if (request.body?.enableOTP !== undefined) {
|
||||||
updateQuery.set('IsEnableOTP', request.body?.enableOTP);
|
updateQuery.set('IsEnableOTP', request.body?.enableOTP);
|
||||||
}
|
}
|
||||||
const updatedRes = await updateQuery.save(null, { useMasterKey: true });
|
const updatedRes = await updateQuery.save(null, { useMasterKey: true });
|
||||||
|
|||||||
@@ -222,6 +222,25 @@ const sendMailToAllSigners = async docId => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const deductcount = async _resSub => {
|
||||||
|
try {
|
||||||
|
const subscriptionCls = new Parse.Object('contracts_Subscriptions');
|
||||||
|
subscriptionCls.id = _resSub.objectId;
|
||||||
|
const allowedCredits = _resSub?.AllowedCredits || 0;
|
||||||
|
const addonCredits = _resSub?.AddonCredits || 0;
|
||||||
|
if (allowedCredits > 0) {
|
||||||
|
const updateAllowedcredits = allowedCredits - 1 || 0;
|
||||||
|
subscriptionCls.set('AllowedCredits', updateAllowedcredits);
|
||||||
|
} else {
|
||||||
|
const updateAddonCredits = addonCredits > 0 ? addonCredits - 1 : 0;
|
||||||
|
subscriptionCls.set('AddonCredits', updateAddonCredits);
|
||||||
|
}
|
||||||
|
await subscriptionCls.save(null, { useMasterKey: true });
|
||||||
|
} catch (err) {
|
||||||
|
console.log('Err in deductcount in PublicUserLinkContacttoDoc cloud function', err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// `PublicUserLinkContactToDoc` cloud function is used to create contact, add this contact in contracts_Guest role and
|
// `PublicUserLinkContactToDoc` cloud function is used to create contact, add this contact in contracts_Guest role and
|
||||||
// create new document from template and save contact pointer in placeholder, signers and ACL of Document
|
// create new document from template and save contact pointer in placeholder, signers and ACL of Document
|
||||||
export default async function PublicUserLinkContactToDoc(req) {
|
export default async function PublicUserLinkContactToDoc(req) {
|
||||||
@@ -241,126 +260,163 @@ export default async function PublicUserLinkContactToDoc(req) {
|
|||||||
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Template not found.');
|
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Template not found.');
|
||||||
}
|
}
|
||||||
const _tempRes = JSON.parse(JSON.stringify(tempRes));
|
const _tempRes = JSON.parse(JSON.stringify(tempRes));
|
||||||
const Placeholders = _tempRes?.Placeholders || [];
|
const subscription = new Parse.Query('contracts_Subscriptions');
|
||||||
let index;
|
subscription.equalTo('TenantId', {
|
||||||
if (role) {
|
__type: 'Pointer',
|
||||||
index = Placeholders?.findIndex(x => x.Role && x.Role === role);
|
className: 'partners_Tenant',
|
||||||
} else {
|
objectId: _tempRes?.ExtUserPtr?.TenantId?.objectId,
|
||||||
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, '');
|
});
|
||||||
}
|
subscription.include('ExtUserPtr');
|
||||||
if (index !== -1) {
|
const date = new Date();
|
||||||
// Execute the query to check if a contact already exists in the 'contracts_Contactbook' class
|
subscription.greaterThanOrEqualTo('Next_billing_date', date);
|
||||||
const contactCls = new Parse.Query('contracts_Contactbook');
|
const resSub = await subscription.first({ useMasterKey: true });
|
||||||
contactCls.equalTo('Email', email);
|
if (resSub) {
|
||||||
contactCls.equalTo('CreatedBy', _tempRes.CreatedBy);
|
const _resSub = JSON.parse(JSON.stringify(resSub));
|
||||||
contactCls.notEqualTo('IsDeleted', true);
|
const allowedCredits = _resSub?.AllowedCredits || 0;
|
||||||
const existContact = await contactCls.first({ useMasterKey: true });
|
const addonCredits = _resSub?.AddonCredits || 0;
|
||||||
if (existContact) {
|
const totalcredits = allowedCredits + addonCredits;
|
||||||
const template_json = JSON.parse(JSON.stringify(tempRes));
|
if (totalcredits > 0) {
|
||||||
//update contact in placeholder, signers and update ACl in provide document
|
const Placeholders = _tempRes?.Placeholders || [];
|
||||||
const docRes = await createDocumentFromTemplate(template_json, existContact, index);
|
let index;
|
||||||
if (docRes) {
|
if (role) {
|
||||||
//condition will execute only if sendInOrder will be false for send email to all signers at a time.
|
index = Placeholders?.findIndex(x => x.Role && x.Role === role);
|
||||||
if (!template_json?.SendinOrder) {
|
} else {
|
||||||
await sendMailToAllSigners(docRes.id);
|
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, '');
|
||||||
}
|
|
||||||
return { contactId: existContact.id, docId: docRes.id };
|
|
||||||
}
|
}
|
||||||
} else {
|
if (index !== -1) {
|
||||||
// Execute the query to check if a user already exists in the 'contracts_Users' class
|
// Execute the query to check if a contact already exists in the 'contracts_Contactbook' class
|
||||||
const extUserQuery = new Parse.Query('contracts_Users');
|
const contactCls = new Parse.Query('contracts_Contactbook');
|
||||||
extUserQuery.equalTo('Email', email);
|
contactCls.equalTo('Email', email);
|
||||||
const extUser = await extUserQuery.first({ useMasterKey: true });
|
contactCls.equalTo('CreatedBy', _tempRes.CreatedBy);
|
||||||
if (extUser) {
|
contactCls.notEqualTo('IsDeleted', true);
|
||||||
const _extUser = JSON.parse(JSON.stringify(extUser));
|
const existContact = await contactCls.first({ useMasterKey: true });
|
||||||
const contact = {
|
if (existContact) {
|
||||||
UserId: _extUser.UserId,
|
const template_json = JSON.parse(JSON.stringify(tempRes));
|
||||||
Name: _extUser.Name,
|
//update contact in placeholder, signers and update ACl in provide document
|
||||||
Email: email,
|
const docRes = await createDocumentFromTemplate(template_json, existContact, index);
|
||||||
Phone: _extUser?.Phone ? _extUser.Phone : '',
|
if (docRes) {
|
||||||
CreatedBy: _tempRes.CreatedBy,
|
await deductcount(_resSub);
|
||||||
TenantId: _tempRes.ExtUserPtr.TenantId,
|
//condition will execute only if sendInOrder will be false for send email to all signers at a time.
|
||||||
};
|
if (!template_json?.SendinOrder) {
|
||||||
const template_json = JSON.parse(JSON.stringify(tempRes));
|
await sendMailToAllSigners(docRes.id);
|
||||||
// if user present on platform create contact on the basis of extended user details
|
}
|
||||||
const contactRes = await saveRoleContact(contact);
|
return { contactId: existContact.id, docId: docRes.id };
|
||||||
const docRes = await createDocumentFromTemplate(template_json, contactRes, index);
|
|
||||||
if (docRes) {
|
|
||||||
//condition will execute only if sendInOrder will be false for send email to all signers at a time.
|
|
||||||
if (!template_json?.SendinOrder) {
|
|
||||||
await sendMailToAllSigners(docRes.id);
|
|
||||||
}
|
}
|
||||||
return { contactId: contactRes.id, docId: docRes.id };
|
} else {
|
||||||
}
|
// Execute the query to check if a user already exists in the 'contracts_Users' class
|
||||||
} else if (name) {
|
const extUserQuery = new Parse.Query('contracts_Users');
|
||||||
try {
|
extUserQuery.equalTo('Email', email);
|
||||||
// Execute the query to check if a user already exists in the '_User' class
|
const extUser = await extUserQuery.first({ useMasterKey: true });
|
||||||
const userQuery = new Parse.Query(Parse.User);
|
if (extUser) {
|
||||||
userQuery.equalTo('email', email);
|
const _extUser = JSON.parse(JSON.stringify(extUser));
|
||||||
const userRes = await userQuery.first({ useMasterKey: true });
|
|
||||||
if (userRes) {
|
|
||||||
const contact = {
|
const contact = {
|
||||||
UserId: { __type: 'Pointer', className: '_User', objectId: userRes.id },
|
UserId: _extUser.UserId,
|
||||||
Name: name,
|
Name: _extUser.Name,
|
||||||
Email: email,
|
Email: email,
|
||||||
Phone: phone,
|
Phone: _extUser?.Phone ? _extUser.Phone : '',
|
||||||
CreatedBy: _tempRes.CreatedBy,
|
CreatedBy: _tempRes.CreatedBy,
|
||||||
TenantId: _tempRes.ExtUserPtr.TenantId,
|
TenantId: _tempRes.ExtUserPtr.TenantId,
|
||||||
};
|
};
|
||||||
const template_json = JSON.parse(JSON.stringify(tempRes));
|
const template_json = JSON.parse(JSON.stringify(tempRes));
|
||||||
// Create new contract on the basis provided contact details by user and userId from _User class
|
// if user present on platform create contact on the basis of extended user details
|
||||||
const contactRes = await saveRoleContact(contact);
|
const contactRes = await saveRoleContact(contact);
|
||||||
//update contact in placeholder, signers and update ACl in provide document
|
|
||||||
const docRes = await createDocumentFromTemplate(template_json, contactRes, index);
|
const docRes = await createDocumentFromTemplate(template_json, contactRes, index);
|
||||||
if (docRes) {
|
if (docRes) {
|
||||||
|
await deductcount(_resSub);
|
||||||
//condition will execute only if sendInOrder will be false for send email to all signers at a time.
|
//condition will execute only if sendInOrder will be false for send email to all signers at a time.
|
||||||
if (!template_json?.SendinOrder) {
|
if (!template_json?.SendinOrder) {
|
||||||
await sendMailToAllSigners(docRes.id);
|
await sendMailToAllSigners(docRes.id);
|
||||||
}
|
}
|
||||||
return { contactId: contactRes.id, docId: docRes.id };
|
return { contactId: contactRes.id, docId: docRes.id };
|
||||||
}
|
}
|
||||||
|
} else if (name) {
|
||||||
|
try {
|
||||||
|
// Execute the query to check if a user already exists in the '_User' class
|
||||||
|
const userQuery = new Parse.Query(Parse.User);
|
||||||
|
userQuery.equalTo('email', email);
|
||||||
|
const userRes = await userQuery.first({ useMasterKey: true });
|
||||||
|
if (userRes) {
|
||||||
|
const contact = {
|
||||||
|
UserId: { __type: 'Pointer', className: '_User', objectId: userRes.id },
|
||||||
|
Name: name,
|
||||||
|
Email: email,
|
||||||
|
Phone: phone,
|
||||||
|
CreatedBy: _tempRes.CreatedBy,
|
||||||
|
TenantId: _tempRes.ExtUserPtr.TenantId,
|
||||||
|
};
|
||||||
|
const template_json = JSON.parse(JSON.stringify(tempRes));
|
||||||
|
// Create new contract on the basis provided contact details by user and userId from _User class
|
||||||
|
const contactRes = await saveRoleContact(contact);
|
||||||
|
//update contact in placeholder, signers and update ACl in provide document
|
||||||
|
const docRes = await createDocumentFromTemplate(
|
||||||
|
template_json,
|
||||||
|
contactRes,
|
||||||
|
index
|
||||||
|
);
|
||||||
|
if (docRes) {
|
||||||
|
await deductcount(_resSub);
|
||||||
|
//condition will execute only if sendInOrder will be false for send email to all signers at a time.
|
||||||
|
if (!template_json?.SendinOrder) {
|
||||||
|
await sendMailToAllSigners(docRes.id);
|
||||||
|
}
|
||||||
|
return { contactId: contactRes.id, docId: docRes.id };
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// create new user in _User class on the basis of details provide by user
|
||||||
|
const _users = Parse.Object.extend('User');
|
||||||
|
const _user = new _users();
|
||||||
|
_user.set('name', name);
|
||||||
|
_user.set('username', email);
|
||||||
|
_user.set('email', email);
|
||||||
|
_user.set('password', email);
|
||||||
|
if (phone) {
|
||||||
|
_user.set('phone', phone);
|
||||||
|
}
|
||||||
|
const newUserRes = await _user.save();
|
||||||
|
const contact = {
|
||||||
|
UserId: { __type: 'Pointer', className: '_User', objectId: newUserRes.id },
|
||||||
|
Name: name,
|
||||||
|
Email: email,
|
||||||
|
Phone: phone,
|
||||||
|
CreatedBy: _tempRes.CreatedBy,
|
||||||
|
TenantId: _tempRes.ExtUserPtr.TenantId,
|
||||||
|
};
|
||||||
|
const template_json = JSON.parse(JSON.stringify(tempRes));
|
||||||
|
// Create new contract on the basis provided contact details by user and userId from _User class
|
||||||
|
const contactRes = await saveRoleContact(contact);
|
||||||
|
//update contact in placeholder, signers and update ACl in provide document
|
||||||
|
const docRes = await createDocumentFromTemplate(
|
||||||
|
template_json,
|
||||||
|
contactRes,
|
||||||
|
index
|
||||||
|
);
|
||||||
|
if (docRes) {
|
||||||
|
await deductcount(_resSub);
|
||||||
|
//condition will execute only if sendInOrder will be false for send email to all signers at a time.
|
||||||
|
if (!template_json?.SendinOrder) {
|
||||||
|
await sendMailToAllSigners(docRes.id);
|
||||||
|
}
|
||||||
|
return { contactId: contactRes.id, docId: docRes.id };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('Err', err);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// create new user in _User class on the basis of details provide by user
|
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'User not found.');
|
||||||
const _users = Parse.Object.extend('User');
|
|
||||||
const _user = new _users();
|
|
||||||
_user.set('name', name);
|
|
||||||
_user.set('username', email);
|
|
||||||
_user.set('email', email);
|
|
||||||
_user.set('password', email);
|
|
||||||
if (phone) {
|
|
||||||
_user.set('phone', phone);
|
|
||||||
}
|
|
||||||
const newUserRes = await _user.save();
|
|
||||||
const contact = {
|
|
||||||
UserId: { __type: 'Pointer', className: '_User', objectId: newUserRes.id },
|
|
||||||
Name: name,
|
|
||||||
Email: email,
|
|
||||||
Phone: phone,
|
|
||||||
CreatedBy: _tempRes.CreatedBy,
|
|
||||||
TenantId: _tempRes.ExtUserPtr.TenantId,
|
|
||||||
};
|
|
||||||
const template_json = JSON.parse(JSON.stringify(tempRes));
|
|
||||||
// Create new contract on the basis provided contact details by user and userId from _User class
|
|
||||||
const contactRes = await saveRoleContact(contact);
|
|
||||||
//update contact in placeholder, signers and update ACl in provide document
|
|
||||||
const docRes = await createDocumentFromTemplate(template_json, contactRes, index);
|
|
||||||
if (docRes) {
|
|
||||||
//condition will execute only if sendInOrder will be false for send email to all signers at a time.
|
|
||||||
if (!template_json?.SendinOrder) {
|
|
||||||
await sendMailToAllSigners(docRes.id);
|
|
||||||
}
|
|
||||||
return { contactId: contactRes.id, docId: docRes.id };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
|
||||||
console.log('Err', err);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'User not found.');
|
throw new Parse.Error(
|
||||||
|
Parse.Error.OBJECT_NOT_FOUND,
|
||||||
|
'Please provide required parameters!'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
throw new Parse.Error(Parse.Error.REQUEST_LIMIT_EXCEEDED, 'Insufficient Credit');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Please provide required parameters!');
|
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Plan expired');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Template not found.');
|
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Template not found.');
|
||||||
|
|||||||
@@ -51,7 +51,10 @@ export default async function UpdateExistUserAsAdmin(request) {
|
|||||||
extClsQuery.notEqualTo('IsDisabled', true);
|
extClsQuery.notEqualTo('IsDisabled', true);
|
||||||
const extAdminRes = await extClsQuery.find({ useMasterKey: true });
|
const extAdminRes = await extClsQuery.find({ useMasterKey: true });
|
||||||
if (extAdminRes && extAdminRes.length === 1 && extAdminRes?.[0]?.get('OrganizationId')) {
|
if (extAdminRes && extAdminRes.length === 1 && extAdminRes?.[0]?.get('OrganizationId')) {
|
||||||
throw new Parse.Error(Parse.Error.DUPLICATE_VALUE, 'Admin already exist.');
|
throw new Parse.Error(
|
||||||
|
Parse.Error.DUPLICATE_VALUE,
|
||||||
|
'Admin already exists. Please login to the application using admin credentials in order to manage users.'
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
const extCls = new Parse.Query('contracts_Users');
|
const extCls = new Parse.Query('contracts_Users');
|
||||||
extCls.equalTo('Email', email);
|
extCls.equalTo('Email', email);
|
||||||
|
|||||||
@@ -68,28 +68,26 @@ const makeEmail = async (to, from, subject, html, url, pdfName) => {
|
|||||||
type: 'application/pdf',
|
type: 'application/pdf',
|
||||||
path: './exports/certificate.pdf',
|
path: './exports/certificate.pdf',
|
||||||
};
|
};
|
||||||
attachments = [file, certificate];
|
if (fs.existsSync(certificate.path)) {
|
||||||
|
attachments = [file, certificate];
|
||||||
|
} else {
|
||||||
|
attachments = [file];
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
attachments = [file];
|
attachments = [file];
|
||||||
console.log('Err in read certificate sendmailv3', err);
|
console.log('Err in read certificate sendmailv3', err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const attachmentParts = attachments.map(attachment => {
|
const attachmentParts = attachments.map(attachment => {
|
||||||
if (fs.existsSync(attachment.path)) {
|
const content = fs.readFileSync(attachment.path);
|
||||||
try {
|
const encodedContent = content.toString('base64');
|
||||||
const content = fs.readFileSync(attachment.path);
|
return [
|
||||||
const encodedContent = content.toString('base64');
|
`Content-Type: ${attachment.type}\n`,
|
||||||
return [
|
'MIME-Version: 1.0\n',
|
||||||
`Content-Type: ${attachment.type}\n`,
|
`Content-Disposition: attachment; filename="${attachment.filename}"\n`,
|
||||||
'MIME-Version: 1.0\n',
|
`Content-Transfer-Encoding: base64\n\n`,
|
||||||
`Content-Disposition: attachment; filename="${attachment.filename}"\n`,
|
`${encodedContent}\n`,
|
||||||
`Content-Transfer-Encoding: base64\n\n`,
|
].join('');
|
||||||
`${encodedContent}\n`,
|
|
||||||
].join('');
|
|
||||||
} catch (err) {
|
|
||||||
console.log('Err in read attachments sendmailv3', attachment.path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const attachmentBody = attachmentParts.join(`\n--${boundary}\n`);
|
const attachmentBody = attachmentParts.join(`\n--${boundary}\n`);
|
||||||
@@ -149,6 +147,14 @@ export default async function sendMailGmailProvider(_extRes, template) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
console.log('gmail provider res: ', response?.status);
|
console.log('gmail provider res: ', response?.status);
|
||||||
|
const certificatePath = './exports/certificate.pdf';
|
||||||
|
if (fs.existsSync(certificatePath)) {
|
||||||
|
try {
|
||||||
|
fs.unlinkSync(certificatePath);
|
||||||
|
} catch (err) {
|
||||||
|
console.log('Err in unlink certificate sendmailgmail provider');
|
||||||
|
}
|
||||||
|
}
|
||||||
return { code: 200, message: 'Email sent successfully' };
|
return { code: 200, message: 'Email sent successfully' };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error sending email:', error);
|
console.error('Error sending email:', error);
|
||||||
|
|||||||
Generated
+188
-700
File diff suppressed because it is too large
Load Diff
@@ -24,24 +24,24 @@
|
|||||||
"@signpdf/placeholder-pdf-lib": "^3.2.4",
|
"@signpdf/placeholder-pdf-lib": "^3.2.4",
|
||||||
"@signpdf/signer-p12": "^3.2.4",
|
"@signpdf/signer-p12": "^3.2.4",
|
||||||
"@signpdf/signpdf": "^3.2.4",
|
"@signpdf/signpdf": "^3.2.4",
|
||||||
"aws-sdk": "^2.1687.0",
|
"aws-sdk": "^2.1691.0",
|
||||||
"axios": "^1.7.7",
|
"axios": "^1.7.7",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
"express": "^4.21.0",
|
"express": "^4.21.0",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
"generate-api-key": "^1.0.2",
|
"generate-api-key": "^1.0.2",
|
||||||
"googleapis": "^140.0.1",
|
"googleapis": "^144.0.0",
|
||||||
"jsonschema": "^1.4.1",
|
"jsonschema": "^1.4.1",
|
||||||
"mailgun.js": "^10.2.3",
|
"mailgun.js": "^10.2.3",
|
||||||
"mongoose": "^8.6.1",
|
"mongoose": "^8.7.0",
|
||||||
"multer": "^1.4.5-lts.1",
|
"multer": "^1.4.5-lts.1",
|
||||||
"multer-s3": "^3.0.1",
|
"multer-s3": "^3.0.1",
|
||||||
"node-forge": "^1.3.1",
|
"node-forge": "^1.3.1",
|
||||||
"nodemailer": "^6.9.15",
|
"nodemailer": "^6.9.15",
|
||||||
"parse": "^5.3.0",
|
"parse": "^5.3.0",
|
||||||
"parse-dbtool": "^1.2.0",
|
"parse-dbtool": "^1.2.0",
|
||||||
"parse-server": "^7.2.0",
|
"parse-server": "^7.3.0-alpha.8",
|
||||||
"parse-server-api-mail-adapter": "^4.0.0",
|
"parse-server-api-mail-adapter": "^4.0.0",
|
||||||
"pdf-lib": "^1.17.1",
|
"pdf-lib": "^1.17.1",
|
||||||
"posthog-node": "^4.2.0",
|
"posthog-node": "^4.2.0",
|
||||||
@@ -50,11 +50,11 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/eslint-parser": "^7.25.1",
|
"@babel/eslint-parser": "^7.25.1",
|
||||||
"eslint": "^9.9.1",
|
"eslint": "^9.11.1",
|
||||||
"jasmine": "^5.3.0",
|
"jasmine": "^5.3.0",
|
||||||
"mongodb-runner": "^5.6.6",
|
"mongodb-runner": "^5.6.6",
|
||||||
"nodemon": "^3.1.4",
|
"nodemon": "^3.1.7",
|
||||||
"nyc": "^17.0.0",
|
"nyc": "^17.1.0",
|
||||||
"prettier": "^3.3.3"
|
"prettier": "^3.3.3"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ services:
|
|||||||
server:
|
server:
|
||||||
image: opensign/opensignserver:main
|
image: opensign/opensignserver:main
|
||||||
container_name: OpenSignServer-container
|
container_name: OpenSignServer-container
|
||||||
|
volumes:
|
||||||
|
- opensign-files:/usr/src/app/files
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "8080:8080"
|
||||||
depends_on:
|
depends_on:
|
||||||
@@ -56,3 +58,4 @@ volumes:
|
|||||||
web-root:
|
web-root:
|
||||||
caddy_data:
|
caddy_data:
|
||||||
caddy_config:
|
caddy_config:
|
||||||
|
opensign-files:
|
||||||
|
|||||||
Reference in New Issue
Block a user