mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-09-04 16:58:05 +02:00
Compare commits
228
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03750e3145 | ||
|
|
ff4879a984 | ||
|
|
7a6a543df5 | ||
|
|
edda20940b | ||
|
|
35d20bd42c | ||
|
|
97983c423f | ||
|
|
68050e3a35 | ||
|
|
4f2801d901 | ||
|
|
aaa3dfc304 | ||
|
|
7a9bebe035 | ||
|
|
9d15b035c5 | ||
|
|
22de053cd3 | ||
|
|
13845adbd5 | ||
|
|
ef68f2da16 | ||
|
|
9114908521 | ||
|
|
f565edc655 | ||
|
|
b0e26b8ae2 | ||
|
|
9e185fa33c | ||
|
|
5142a8c62d | ||
|
|
042ad8465e | ||
|
|
ebfd9d3af7 | ||
|
|
861a065849 | ||
|
|
3884909965 | ||
|
|
bd60f91734 | ||
|
|
b58c3fd467 | ||
|
|
9d431af0b9 | ||
|
|
cb1ebc6a72 | ||
|
|
a198bce3e2 | ||
|
|
e5c50a0dbb | ||
|
|
caa1dfaf34 | ||
|
|
eb01a0b17d | ||
|
|
1add575d26 | ||
|
|
1a774bfcfa | ||
|
|
db9ec6bfd5 | ||
|
|
cbcfb8c063 | ||
|
|
da846dcbbb | ||
|
|
e7280bf017 | ||
|
|
9692f57663 | ||
|
|
f0655893eb | ||
|
|
f9e59905b7 | ||
|
|
c115c7c757 | ||
|
|
4edcf807ad | ||
|
|
416d8c823c | ||
|
|
bea158b8f2 | ||
|
|
39c6560a2d | ||
|
|
509b004014 | ||
|
|
f1b7e1164b | ||
|
|
3a2f626cb9 | ||
|
|
7cde6fd73c | ||
|
|
06d6eecaf0 | ||
|
|
c9ed29261d | ||
|
|
f74819f50a | ||
|
|
98c8af5b9c | ||
|
|
74e2582ff9 | ||
|
|
8bbbf9b3d8 | ||
|
|
0a6622159f | ||
|
|
7a5cdefcfa | ||
|
|
fa405752da | ||
|
|
2d7571af5a | ||
|
|
01b7b1cab8 | ||
|
|
fee3d8f672 | ||
|
|
f1628e46fa | ||
|
|
17cb4479cb | ||
|
|
b52511113b | ||
|
|
95cc15ec4c | ||
|
|
1a4b4655c8 | ||
|
|
9fc69ba7e6 | ||
|
|
8ce31d3d80 | ||
|
|
d097f9a741 | ||
|
|
8686a35405 | ||
|
|
a92d90db4a | ||
|
|
bfa0e0e144 | ||
|
|
d3b2e1f24b | ||
|
|
61afc35ac8 | ||
|
|
00e9396590 | ||
|
|
bbedb13f3e | ||
|
|
55cfbae8a7 | ||
|
|
bfa19eec0c | ||
|
|
07851ccde2 | ||
|
|
a13478fa64 | ||
|
|
85a1c10d26 | ||
|
|
6918282e31 | ||
|
|
fd778c25e6 | ||
|
|
af344c8ae2 | ||
|
|
c505f8cf86 | ||
|
|
52320e0cd9 | ||
|
|
214db474c2 | ||
|
|
1bffabc94d | ||
|
|
7c8a5e02f2 | ||
|
|
a49c76c188 | ||
|
|
34fc3afb1e | ||
|
|
67479a9c1e | ||
|
|
2a8cedca58 | ||
|
|
57fc4aa06b | ||
|
|
39f3f73896 | ||
|
|
3dc109c3dd | ||
|
|
83df89c115 | ||
|
|
4070409a59 | ||
|
|
70963c06b8 | ||
|
|
a1a84b6928 | ||
|
|
eefaf5fe50 | ||
|
|
9500b2d678 | ||
|
|
e52c7c97cf | ||
|
|
ebdc5ef566 | ||
|
|
2afb868edc | ||
|
|
a5fe4a345b | ||
|
|
629bf7f51f | ||
|
|
350854ab6b | ||
|
|
cc980758fd | ||
|
|
0f1ce43cc5 | ||
|
|
5e1a9cdc20 | ||
|
|
550ce10c92 | ||
|
|
6080c59bd7 | ||
|
|
273a35d42f | ||
|
|
2f195fe02e | ||
|
|
0715ca9d85 | ||
|
|
a8d564d74d | ||
|
|
89ba3e0fa4 | ||
|
|
eebcfe94d9 | ||
|
|
ea9b0370c4 | ||
|
|
e264511a6e | ||
|
|
1ec10fbcfc | ||
|
|
274620d17b | ||
|
|
06db7d2360 | ||
|
|
2b3549e4df | ||
|
|
d16478792c | ||
|
|
7ba2ef6420 | ||
|
|
b5d98796b7 | ||
|
|
97c17cfe84 | ||
|
|
4b4e200090 | ||
|
|
232d38440d | ||
|
|
341bd9bef0 | ||
|
|
2f4d04c722 | ||
|
|
148ae40e1a | ||
|
|
9cb0ced4f6 | ||
|
|
9a3b70de43 | ||
|
|
742b8f7eae | ||
|
|
abc58941e3 | ||
|
|
aac200bfd3 | ||
|
|
27d3297d61 | ||
|
|
72431b2c82 | ||
|
|
3ca48e5848 | ||
|
|
14784ec80f | ||
|
|
127741eb27 | ||
|
|
2ed987fe10 | ||
|
|
7aaa1876c8 | ||
|
|
390ffb83a2 | ||
|
|
d63e51b8cb | ||
|
|
7bd8d64649 | ||
|
|
f9e6f49ede | ||
|
|
b701d2863f | ||
|
|
cf47093227 | ||
|
|
81d0aea66c | ||
|
|
506ca35be8 | ||
|
|
1cd6718489 | ||
|
|
153c5db4b5 | ||
|
|
ac9367a715 | ||
|
|
081dae0b90 | ||
|
|
e286390aec | ||
|
|
cf88eb2124 | ||
|
|
3226e4fd85 | ||
|
|
cab94eb63d | ||
|
|
bbd5d6805e | ||
|
|
2904ba3085 | ||
|
|
ee609061ed | ||
|
|
6c98a4e899 | ||
|
|
eef9ee7f3c | ||
|
|
2cb4575db1 | ||
|
|
e7bcad80cc | ||
|
|
353839a1dc | ||
|
|
e6d30744ba | ||
|
|
b67932f448 | ||
|
|
c185c42b80 | ||
|
|
4648ace84e | ||
|
|
ccdf50dbe0 | ||
|
|
852a3dc8bb | ||
|
|
d49b7bd201 | ||
|
|
07f2ceed6e | ||
|
|
751c7b5787 | ||
|
|
e82384dff8 | ||
|
|
92d3a85147 | ||
|
|
c5762a0baf | ||
|
|
dc40b04a18 | ||
|
|
1cca5a3085 | ||
|
|
4fe4ca638c | ||
|
|
b8c7110c63 | ||
|
|
711ab6a556 | ||
|
|
7a12f54587 | ||
|
|
056f4b3e80 | ||
|
|
730a7a4e15 | ||
|
|
a4b4dc885c | ||
|
|
8562a4bb46 | ||
|
|
d3b56432e0 | ||
|
|
527c5be42c | ||
|
|
6c1d0c712a | ||
|
|
fd0ec5fd31 | ||
|
|
f5f19c9b52 | ||
|
|
642ef4f5b7 | ||
|
|
66b65e600b | ||
|
|
01a130ef8c | ||
|
|
c3bccb5412 | ||
|
|
b32e6e71f8 | ||
|
|
3b5875e283 | ||
|
|
da42fe97ae | ||
|
|
56bb7d36eb | ||
|
|
d86b7345d7 | ||
|
|
c1c17160ff | ||
|
|
d400c843e4 | ||
|
|
4e67ab50fe | ||
|
|
74c9e21d55 | ||
|
|
fefcdf6ffc | ||
|
|
0c14d71fa8 | ||
|
|
5170e4eee2 | ||
|
|
8ebfd781c3 | ||
|
|
4e8988bf57 | ||
|
|
c26734751f | ||
|
|
ca6b4e7d82 | ||
|
|
cb4a94d036 | ||
|
|
300ddb810f | ||
|
|
0b687310fd | ||
|
|
3e741ac2f9 | ||
|
|
f65b23ca26 | ||
|
|
db9b8d2ba1 | ||
|
|
4866447f33 | ||
|
|
2b345ff840 | ||
|
|
b47bf437a9 | ||
|
|
c44149050c | ||
|
|
0576123a77 |
+5
-5
@@ -45,14 +45,14 @@ DO_REGION=us-west
|
|||||||
USE_LOCAL=TRUE
|
USE_LOCAL=TRUE
|
||||||
|
|
||||||
# Email mailgun or set SMTP_ENABLE true to use SMTP config (The app will not initialize if any of these 3 variables are not set) *********************************************************************************************************************
|
# Email mailgun or set SMTP_ENABLE true to use SMTP config (The app will not initialize if any of these 3 variables are not set) *********************************************************************************************************************
|
||||||
MAILGUN_API_KEY=XXXXX
|
MAILGUN_API_KEY=
|
||||||
MAILGUN_DOMAIN=mail.yourdomain.com
|
MAILGUN_DOMAIN=mail.yourdomain.com
|
||||||
MAILGUN_SENDER=postmaster@mail.yourdomain.com
|
MAILGUN_SENDER=postmaster@mail.yourdomain.com
|
||||||
SMTP_ENABLE=
|
SMTP_ENABLE=
|
||||||
SMTP_HOST=
|
SMTP_HOST=smtp.yourhost.com
|
||||||
SMTP_PORT=
|
SMTP_PORT=443
|
||||||
SMTP_USER_EMAIL=
|
SMTP_USER_EMAIL=mailer@yourdomain.com
|
||||||
SMTP_PASS=
|
SMTP_PASS=password
|
||||||
|
|
||||||
|
|
||||||
# Base64 encoded PFX or p12 document signing certificate file *********************************************************************************************************************
|
# Base64 encoded PFX or p12 document signing certificate file *********************************************************************************************************************
|
||||||
|
|||||||
@@ -38,10 +38,11 @@
|
|||||||
7. [Acknowledgments](#acknowledgments)
|
7. [Acknowledgments](#acknowledgments)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
Please star ⭐ the repo to support us! 😀
|
||||||
|
|
||||||
### Introduction
|
### Introduction
|
||||||
|
|
||||||
Welcome to OpenSign, an open-source document e-signing solution designed to provide a secure, reliable, and free alternative to commercial platforms like DocuSign, PandaDoc, SignNow, Adobe Sign, Smartwaiver, SignRequest, HelloSign & Zoho sign. Developed under the OpenSignLabs organization, our mission is to democratize the e-signing process, making it accessible and straightforward for everyone.
|
Welcome to OpenSign, the premier open-source docusign alternative - document e-signing solution designed to provide a secure, reliable, and free alternative to commercial platforms like DocuSign, PandaDoc, SignNow, Adobe Sign, Smartwaiver, SignRequest, HelloSign & Zoho sign. Developed under the OpenSignLabs organization, our mission is to democratize the e-signing process, making it accessible and straightforward for everyone.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -20,10 +20,6 @@ module.exports = {
|
|||||||
"react-router-dom": {
|
"react-router-dom": {
|
||||||
singleton: true,
|
singleton: true,
|
||||||
requiredVersion: dependencies["react-router-dom"]
|
requiredVersion: dependencies["react-router-dom"]
|
||||||
},
|
|
||||||
"rjsf-conditionals": {
|
|
||||||
singleton: true,
|
|
||||||
requiredVersion: dependencies["rjsf-conditionals"]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Generated
-206
@@ -9,9 +9,6 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@reduxjs/toolkit": "^1.9.7",
|
"@reduxjs/toolkit": "^1.9.7",
|
||||||
"@rjsf/core": "^5.13.0",
|
|
||||||
"@rjsf/utils": "^5.13.0",
|
|
||||||
"@rjsf/validator-ajv8": "^5.13.0",
|
|
||||||
"axios": "^1.5.1",
|
"axios": "^1.5.1",
|
||||||
"daisyui": "^3.9.2",
|
"daisyui": "^3.9.2",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
@@ -39,7 +36,6 @@
|
|||||||
"reactour": "^1.19.2",
|
"reactour": "^1.19.2",
|
||||||
"redux": "^4.2.1",
|
"redux": "^4.2.1",
|
||||||
"redux-thunk": "^2.4.2",
|
"redux-thunk": "^2.4.2",
|
||||||
"rjsf-conditionals": "github:prafullnavkar-nxg/rjsf-conditionals",
|
|
||||||
"serve": "^14.2.1",
|
"serve": "^14.2.1",
|
||||||
"styled-components": "^4.4.1",
|
"styled-components": "^4.4.1",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
@@ -3921,85 +3917,6 @@
|
|||||||
"react": ">=16.14.0"
|
"react": ">=16.14.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rjsf/core": {
|
|
||||||
"version": "5.13.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@rjsf/core/-/core-5.13.0.tgz",
|
|
||||||
"integrity": "sha512-rCpJGR0yPP/ip9LKcr3SmDMkbLx4QIaRA+ag0rcalSw1XLXBSzh53SpfgaB2HN++1xhUvWtIUERRHpWjQp1E7w==",
|
|
||||||
"dependencies": {
|
|
||||||
"lodash": "^4.17.21",
|
|
||||||
"lodash-es": "^4.17.21",
|
|
||||||
"markdown-to-jsx": "^7.3.2",
|
|
||||||
"nanoid": "^3.3.6",
|
|
||||||
"prop-types": "^15.8.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@rjsf/utils": "^5.12.x",
|
|
||||||
"react": "^16.14.0 || >=17"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@rjsf/utils": {
|
|
||||||
"version": "5.13.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@rjsf/utils/-/utils-5.13.0.tgz",
|
|
||||||
"integrity": "sha512-tG2OuOJUJZ0W7VMZceD0I2SOjfMRRT1tRtG+SKbdNqhtH/gpg40aOMUj9cWgSQnYISEkNZjZq/z7NWln5RxW6A==",
|
|
||||||
"dependencies": {
|
|
||||||
"json-schema-merge-allof": "^0.8.1",
|
|
||||||
"jsonpointer": "^5.0.1",
|
|
||||||
"lodash": "^4.17.21",
|
|
||||||
"lodash-es": "^4.17.21",
|
|
||||||
"react-is": "^18.2.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": "^16.14.0 || >=17"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@rjsf/utils/node_modules/react-is": {
|
|
||||||
"version": "18.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
|
||||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
|
||||||
},
|
|
||||||
"node_modules/@rjsf/validator-ajv8": {
|
|
||||||
"version": "5.13.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@rjsf/validator-ajv8/-/validator-ajv8-5.13.0.tgz",
|
|
||||||
"integrity": "sha512-8j0xLsxJA/k1UADeDYZ2aMVrswvOCEYNC++YchoAgWRHqDiaGAUyRbbk7oxMi6QUXnhnlCIepzNeTclHnSfPXQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"ajv": "^8.12.0",
|
|
||||||
"ajv-formats": "^2.1.1",
|
|
||||||
"lodash": "^4.17.21",
|
|
||||||
"lodash-es": "^4.17.21"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@rjsf/utils": "^5.12.x"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@rjsf/validator-ajv8/node_modules/ajv": {
|
|
||||||
"version": "8.12.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
|
|
||||||
"integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
|
|
||||||
"dependencies": {
|
|
||||||
"fast-deep-equal": "^3.1.1",
|
|
||||||
"json-schema-traverse": "^1.0.0",
|
|
||||||
"require-from-string": "^2.0.2",
|
|
||||||
"uri-js": "^4.2.2"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/epoberezkin"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@rjsf/validator-ajv8/node_modules/json-schema-traverse": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
|
|
||||||
},
|
|
||||||
"node_modules/@rollup/plugin-babel": {
|
"node_modules/@rollup/plugin-babel": {
|
||||||
"version": "5.3.1",
|
"version": "5.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
|
||||||
@@ -6965,27 +6882,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
},
|
},
|
||||||
"node_modules/compute-gcd": {
|
|
||||||
"version": "1.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/compute-gcd/-/compute-gcd-1.2.1.tgz",
|
|
||||||
"integrity": "sha512-TwMbxBNz0l71+8Sc4czv13h4kEqnchV9igQZBi6QUaz09dnz13juGnnaWWJTRsP3brxOoxeB4SA2WELLw1hCtg==",
|
|
||||||
"dependencies": {
|
|
||||||
"validate.io-array": "^1.0.3",
|
|
||||||
"validate.io-function": "^1.0.2",
|
|
||||||
"validate.io-integer-array": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/compute-lcm": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/compute-lcm/-/compute-lcm-1.1.2.tgz",
|
|
||||||
"integrity": "sha512-OFNPdQAXnQhDSKioX8/XYT6sdUlXwpeMjfd6ApxMJfyZ4GxmLR1xvMERctlYhlHwIiz6CSpBc2+qYKjHGZw4TQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"compute-gcd": "^1.2.1",
|
|
||||||
"validate.io-array": "^1.0.3",
|
|
||||||
"validate.io-function": "^1.0.2",
|
|
||||||
"validate.io-integer-array": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/concat-map": {
|
"node_modules/concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
@@ -7676,14 +7572,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
||||||
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
|
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
|
||||||
},
|
},
|
||||||
"node_modules/deepcopy": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/deepcopy/-/deepcopy-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-8cZeTb1ZKC3bdSCP6XOM1IsTczIO73fdqtwa2B0N15eAz7gmyhQo+mc5gnFuulsgN3vIQYmTgbmQVKalH1dKvQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"type-detect": "^4.0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/deepmerge": {
|
"node_modules/deepmerge": {
|
||||||
"version": "4.3.1",
|
"version": "4.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
|
||||||
@@ -13418,27 +13306,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
|
||||||
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
|
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
|
||||||
},
|
},
|
||||||
"node_modules/json-schema-compare": {
|
|
||||||
"version": "0.2.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/json-schema-compare/-/json-schema-compare-0.2.2.tgz",
|
|
||||||
"integrity": "sha512-c4WYmDKyJXhs7WWvAWm3uIYnfyWFoIp+JEoX34rctVvEkMYCPGhXtvmFFXiffBbxfZsvQ0RNnV5H7GvDF5HCqQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"lodash": "^4.17.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/json-schema-merge-allof": {
|
|
||||||
"version": "0.8.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.8.1.tgz",
|
|
||||||
"integrity": "sha512-CTUKmIlPJbsWfzRRnOXz+0MjIqvnleIXwFTzz+t9T86HnYX/Rozria6ZVGLktAU9e+NygNljveP+yxqtQp/Q4w==",
|
|
||||||
"dependencies": {
|
|
||||||
"compute-lcm": "^1.1.2",
|
|
||||||
"json-schema-compare": "^0.2.2",
|
|
||||||
"lodash": "^4.17.20"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/json-schema-traverse": {
|
"node_modules/json-schema-traverse": {
|
||||||
"version": "0.4.1",
|
"version": "0.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||||
@@ -13934,21 +13801,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||||
},
|
},
|
||||||
"node_modules/lodash-es": {
|
|
||||||
"version": "4.17.21",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
|
||||||
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
|
|
||||||
},
|
|
||||||
"node_modules/lodash.debounce": {
|
"node_modules/lodash.debounce": {
|
||||||
"version": "4.0.8",
|
"version": "4.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
|
||||||
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
|
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
|
||||||
},
|
},
|
||||||
"node_modules/lodash.isequalwith": {
|
|
||||||
"version": "4.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash.isequalwith/-/lodash.isequalwith-4.4.0.tgz",
|
|
||||||
"integrity": "sha512-dcZON0IalGBpRmJBmMkaoV7d3I80R2O+FrzsZyHdNSFrANq/cgDqKQNmAHE8UEj4+QYWwwhkQOVdLHiAopzlsQ=="
|
|
||||||
},
|
|
||||||
"node_modules/lodash.isplainobject": {
|
"node_modules/lodash.isplainobject": {
|
||||||
"version": "4.0.6",
|
"version": "4.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
||||||
@@ -14310,17 +14167,6 @@
|
|||||||
"tmpl": "1.0.5"
|
"tmpl": "1.0.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/markdown-to-jsx": {
|
|
||||||
"version": "7.3.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.3.2.tgz",
|
|
||||||
"integrity": "sha512-B+28F5ucp83aQm+OxNrPkS8z0tMKaeHiy0lHJs3LqCyDQFtWuenaIrkaVTgAm1pf1AU85LXltva86hlaT17i8Q==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": ">= 0.14.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mdn-data": {
|
"node_modules/mdn-data": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz",
|
||||||
@@ -18202,26 +18048,6 @@
|
|||||||
"url": "https://github.com/sponsors/isaacs"
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/rjsf-conditionals": {
|
|
||||||
"version": "1.5.0",
|
|
||||||
"resolved": "git+ssh://git@github.com/prafullnavkar-nxg/rjsf-conditionals.git#439aa44e3ece077b1c8098278f86f454ad7185cf",
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"dependencies": {
|
|
||||||
"@rjsf/validator-ajv8": "^5.13.0",
|
|
||||||
"deepcopy": "^2.0.0",
|
|
||||||
"lodash.isequalwith": "^4.4.0",
|
|
||||||
"selectn": "^1.1.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@rjsf/core": ">=2.0.0",
|
|
||||||
"core-js": "^2.5.7",
|
|
||||||
"prop-types": "^15.7.2",
|
|
||||||
"react": "^18.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/rollup": {
|
"node_modules/rollup": {
|
||||||
"version": "2.79.1",
|
"version": "2.79.1",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
|
||||||
@@ -20423,38 +20249,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
|
||||||
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="
|
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="
|
||||||
},
|
},
|
||||||
"node_modules/validate.io-array": {
|
|
||||||
"version": "1.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/validate.io-array/-/validate.io-array-1.0.6.tgz",
|
|
||||||
"integrity": "sha512-DeOy7CnPEziggrOO5CZhVKJw6S3Yi7e9e65R1Nl/RTN1vTQKnzjfvks0/8kQ40FP/dsjRAOd4hxmJ7uLa6vxkg=="
|
|
||||||
},
|
|
||||||
"node_modules/validate.io-function": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/validate.io-function/-/validate.io-function-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-LlFybRJEriSuBnUhQyG5bwglhh50EpTL2ul23MPIuR1odjO7XaMLFV8vHGwp7AZciFxtYOeiSCT5st+XSPONiQ=="
|
|
||||||
},
|
|
||||||
"node_modules/validate.io-integer": {
|
|
||||||
"version": "1.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/validate.io-integer/-/validate.io-integer-1.0.5.tgz",
|
|
||||||
"integrity": "sha512-22izsYSLojN/P6bppBqhgUDjCkr5RY2jd+N2a3DCAUey8ydvrZ/OkGvFPR7qfOpwR2LC5p4Ngzxz36g5Vgr/hQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"validate.io-number": "^1.0.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/validate.io-integer-array": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/validate.io-integer-array/-/validate.io-integer-array-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-mTrMk/1ytQHtCY0oNO3dztafHYyGU88KL+jRxWuzfOmQb+4qqnWmI+gykvGp8usKZOM0H7keJHEbRaFiYA0VrA==",
|
|
||||||
"dependencies": {
|
|
||||||
"validate.io-array": "^1.0.3",
|
|
||||||
"validate.io-integer": "^1.0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/validate.io-number": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/validate.io-number/-/validate.io-number-1.0.3.tgz",
|
|
||||||
"integrity": "sha512-kRAyotcbNaSYoDnXvb4MHg/0a1egJdLwS6oJ38TJY7aw9n93Fl/3blIXdyYvPOp55CNxywooG/3BcrwNrBpcSg=="
|
|
||||||
},
|
|
||||||
"node_modules/vary": {
|
"node_modules/vary": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
|||||||
@@ -4,9 +4,6 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@reduxjs/toolkit": "^1.9.7",
|
"@reduxjs/toolkit": "^1.9.7",
|
||||||
"@rjsf/core": "^5.13.0",
|
|
||||||
"@rjsf/utils": "^5.13.0",
|
|
||||||
"@rjsf/validator-ajv8": "^5.13.0",
|
|
||||||
"axios": "^1.5.1",
|
"axios": "^1.5.1",
|
||||||
"daisyui": "^3.9.2",
|
"daisyui": "^3.9.2",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
@@ -34,7 +31,6 @@
|
|||||||
"reactour": "^1.19.2",
|
"reactour": "^1.19.2",
|
||||||
"redux": "^4.2.1",
|
"redux": "^4.2.1",
|
||||||
"redux-thunk": "^2.4.2",
|
"redux-thunk": "^2.4.2",
|
||||||
"rjsf-conditionals": "github:prafullnavkar-nxg/rjsf-conditionals",
|
|
||||||
"serve": "^14.2.1",
|
"serve": "^14.2.1",
|
||||||
"styled-components": "^4.4.1",
|
"styled-components": "^4.4.1",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
v1.0.5-beta
|
v1.1.1-beta
|
||||||
|
|||||||
+25
-75
@@ -7,7 +7,7 @@ import Signup from "./routes/Signup";
|
|||||||
import Form from "./routes/Form";
|
import Form from "./routes/Form";
|
||||||
import Report from "./routes/Report";
|
import Report from "./routes/Report";
|
||||||
import Dashboard from "./routes/Dashboard";
|
import Dashboard from "./routes/Dashboard";
|
||||||
import PlanSubscriptions from "./routes/PlanSubscriptions";
|
import Subscriptions from "./routes/PlanSubscriptions";
|
||||||
import HomeLayout from "./layout/HomeLayout";
|
import HomeLayout from "./layout/HomeLayout";
|
||||||
import UserProfile from "./routes/UserProfile";
|
import UserProfile from "./routes/UserProfile";
|
||||||
import PageNotFound from "./routes/PageNotFound";
|
import PageNotFound from "./routes/PageNotFound";
|
||||||
@@ -15,6 +15,10 @@ import ForgetPassword from "./routes/ForgetPassword";
|
|||||||
import ChangePassword from "./routes/ChangePassword";
|
import ChangePassword from "./routes/ChangePassword";
|
||||||
import ReportMicroapp from "./components/ReportMicroapp";
|
import ReportMicroapp from "./components/ReportMicroapp";
|
||||||
import LoadMf from "./routes/LoadMf";
|
import LoadMf from "./routes/LoadMf";
|
||||||
|
import GenerateToken from "./routes/GenerateToken";
|
||||||
|
import ValidateRoute from "./primitives/ValidateRoute";
|
||||||
|
import Webhook from "./routes/Webhook";
|
||||||
|
import Validate from "./primitives/Validate";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [isloading, setIsLoading] = useState(true);
|
const [isloading, setIsLoading] = useState(true);
|
||||||
@@ -58,88 +62,34 @@ function App() {
|
|||||||
) : (
|
) : (
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route exact path="/" element={<Login />} />
|
<Route element={<ValidateRoute />}>
|
||||||
<Route exact path="/signup" element={<Signup />} />
|
<Route exact path="/" element={<Login />} />
|
||||||
|
<Route exact path="/signup" element={<Signup />} />
|
||||||
|
</Route>
|
||||||
|
<Route element={<Validate />}>
|
||||||
|
<Route exact path="/load/:remoteApp/*" element={<LoadMf />} />
|
||||||
|
</Route>
|
||||||
<Route exact path="/loadmf/:remoteApp/*" element={<LoadMf />} />
|
<Route exact path="/loadmf/:remoteApp/*" element={<LoadMf />} />
|
||||||
<Route exact path="/forgetpassword" element={<ForgetPassword />} />
|
<Route exact path="/forgetpassword" element={<ForgetPassword />} />
|
||||||
{process.env.REACT_APP_ENABLE_SUBSCRIPTION && (
|
{process.env.REACT_APP_ENABLE_SUBSCRIPTION && (
|
||||||
<>
|
<>
|
||||||
<Route exact path="/pgsignup" element={<Pgsignup />} />
|
<Route exact path="/pgsignup" element={<Pgsignup />} />
|
||||||
<Route
|
<Route exact path="/subscription" element={<Subscriptions />} />
|
||||||
exact
|
|
||||||
path="/subscription"
|
|
||||||
element={<PlanSubscriptions />}
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<Route
|
<Route element={<HomeLayout />}>
|
||||||
exact
|
<Route path="/changepassword" element={<ChangePassword />} />
|
||||||
path="/changepassword"
|
<Route path="/mf/:remoteApp/*" element={<Microapp />} />
|
||||||
element={
|
<Route path="/asmf/:remoteApp/*" element={<Microapp />} />
|
||||||
<HomeLayout>
|
<Route path="/rpmf/:remoteApp/*" element={<ReportMicroapp />} />
|
||||||
<ChangePassword />
|
<Route path="/form/:id" element={<Form />} />
|
||||||
</HomeLayout>
|
<Route path="/report/:id" element={<Report />} />
|
||||||
}
|
<Route path="/dashboard/:id" element={<Dashboard />} />
|
||||||
/>
|
<Route path="/profile" element={<UserProfile />} />
|
||||||
<Route
|
<Route path="/generatetoken" element={<GenerateToken />} />
|
||||||
path="/mf/:remoteApp/*"
|
<Route path="/webhook" element={<Webhook />} />
|
||||||
element={
|
</Route>
|
||||||
<HomeLayout>
|
|
||||||
<Microapp />
|
|
||||||
</HomeLayout>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/asmf/:remoteApp/*"
|
|
||||||
element={
|
|
||||||
<HomeLayout>
|
|
||||||
<Microapp />
|
|
||||||
</HomeLayout>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/rpmf/:remoteApp/*"
|
|
||||||
element={
|
|
||||||
<HomeLayout>
|
|
||||||
<ReportMicroapp />
|
|
||||||
</HomeLayout>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/form/:id"
|
|
||||||
element={
|
|
||||||
<HomeLayout>
|
|
||||||
<Form />
|
|
||||||
</HomeLayout>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/report/:id"
|
|
||||||
element={
|
|
||||||
<HomeLayout>
|
|
||||||
<Report />
|
|
||||||
</HomeLayout>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="/dashboard/:id"
|
|
||||||
element={
|
|
||||||
<HomeLayout>
|
|
||||||
<Dashboard />
|
|
||||||
</HomeLayout>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Route
|
|
||||||
path="/profile"
|
|
||||||
element={
|
|
||||||
<HomeLayout>
|
|
||||||
<UserProfile />
|
|
||||||
</HomeLayout>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Route path="*" element={<PageNotFound />} />
|
<Route path="*" element={<PageNotFound />} />
|
||||||
{/* <Route exact path="/ForgotPassword" element={<ForgotPassword />} /> */}
|
|
||||||
</Routes>
|
</Routes>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -0,0 +1,283 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import Parse from "parse";
|
||||||
|
import axios from "axios";
|
||||||
|
import Title from "./Title";
|
||||||
|
import Alert from "../primitives/Alert";
|
||||||
|
|
||||||
|
const AddUser = (props) => {
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
const [phone, setPhone] = useState("");
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
const [isLoader, setIsLoader] = useState(false);
|
||||||
|
const [isUserExist, setIsUserExist] = useState(false);
|
||||||
|
const parseBaseUrl = localStorage.getItem("baseUrl");
|
||||||
|
const parseAppId = localStorage.getItem("parseAppId");
|
||||||
|
Parse.serverURL = parseBaseUrl;
|
||||||
|
Parse.initialize(parseAppId);
|
||||||
|
|
||||||
|
const checkUserExist = async () => {
|
||||||
|
try {
|
||||||
|
const res = await Parse.Cloud.run("getUserDetails", {
|
||||||
|
email: email,
|
||||||
|
userId: Parse.User.current().id
|
||||||
|
});
|
||||||
|
if (res) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Define a function to handle form submission
|
||||||
|
const handleSubmit = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
setIsLoader(true);
|
||||||
|
const res = await checkUserExist();
|
||||||
|
if (res) {
|
||||||
|
setIsUserExist(true);
|
||||||
|
setIsLoader(false);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsUserExist(false);
|
||||||
|
}, 1000);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
const contactQuery = new Parse.Object("contracts_Users");
|
||||||
|
contactQuery.set("Name", name);
|
||||||
|
contactQuery.set("Phone", phone);
|
||||||
|
contactQuery.set("Email", email);
|
||||||
|
contactQuery.set("UserRole", "contracts_User");
|
||||||
|
|
||||||
|
if (localStorage.getItem("TenetId")) {
|
||||||
|
contactQuery.set("TenantId", {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "partners_Tenant",
|
||||||
|
objectId: localStorage.getItem("TenetId")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const _users = Parse.Object.extend("User");
|
||||||
|
const _user = new _users();
|
||||||
|
_user.set("name", name);
|
||||||
|
_user.set("username", email);
|
||||||
|
_user.set("email", email);
|
||||||
|
_user.set("phone", phone);
|
||||||
|
_user.set("password", phone);
|
||||||
|
|
||||||
|
const user = await _user.save();
|
||||||
|
if (user) {
|
||||||
|
const roleurl = `${parseBaseUrl}functions/AddUserToRole`;
|
||||||
|
const headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": parseAppId,
|
||||||
|
sessionToken: localStorage.getItem("accesstoken")
|
||||||
|
};
|
||||||
|
const body = {
|
||||||
|
appName: localStorage.getItem("_appName"),
|
||||||
|
roleName: "contracts_User",
|
||||||
|
userId: user.id
|
||||||
|
};
|
||||||
|
await axios.post(roleurl, body, { headers: headers });
|
||||||
|
const currentUser = Parse.User.current();
|
||||||
|
contactQuery.set(
|
||||||
|
"CreatedBy",
|
||||||
|
Parse.User.createWithoutData(currentUser.id)
|
||||||
|
);
|
||||||
|
|
||||||
|
contactQuery.set("UserId", user);
|
||||||
|
const acl = new Parse.ACL();
|
||||||
|
acl.setPublicReadAccess(true);
|
||||||
|
acl.setPublicWriteAccess(true);
|
||||||
|
acl.setReadAccess(currentUser.id, true);
|
||||||
|
acl.setWriteAccess(currentUser.id, true);
|
||||||
|
|
||||||
|
contactQuery.setACL(acl);
|
||||||
|
|
||||||
|
const res = await contactQuery.save();
|
||||||
|
|
||||||
|
const parseData = JSON.parse(JSON.stringify(res));
|
||||||
|
if (props.details) {
|
||||||
|
props.details({
|
||||||
|
value: parseData[props.valueKey],
|
||||||
|
label: parseData[props.displayKey]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (props.closePopup) {
|
||||||
|
props.closePopup();
|
||||||
|
}
|
||||||
|
if (props.handleUserData) {
|
||||||
|
props.handleUserData(parseData);
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsLoader(false);
|
||||||
|
|
||||||
|
setName("");
|
||||||
|
setPhone("");
|
||||||
|
setEmail("");
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err ", err);
|
||||||
|
if (err.code === 202) {
|
||||||
|
const params = { email: email };
|
||||||
|
const userRes = await Parse.Cloud.run("getUserId", params);
|
||||||
|
const roleurl = `${parseBaseUrl}functions/AddUserToRole`;
|
||||||
|
const headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": parseAppId,
|
||||||
|
sessionToken: localStorage.getItem("accesstoken")
|
||||||
|
};
|
||||||
|
const body = {
|
||||||
|
appName: localStorage.getItem("_appName"),
|
||||||
|
roleName: "contracts_User",
|
||||||
|
userId: userRes.id
|
||||||
|
};
|
||||||
|
await axios.post(roleurl, body, { headers: headers });
|
||||||
|
const currentUser = Parse.User.current();
|
||||||
|
contactQuery.set(
|
||||||
|
"CreatedBy",
|
||||||
|
Parse.User.createWithoutData(currentUser.id)
|
||||||
|
);
|
||||||
|
|
||||||
|
contactQuery.set("UserId", {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "_User",
|
||||||
|
objectId: userRes.id
|
||||||
|
});
|
||||||
|
const acl = new Parse.ACL();
|
||||||
|
acl.setPublicReadAccess(true);
|
||||||
|
acl.setPublicWriteAccess(true);
|
||||||
|
acl.setReadAccess(currentUser.id, true);
|
||||||
|
acl.setWriteAccess(currentUser.id, true);
|
||||||
|
|
||||||
|
contactQuery.setACL(acl);
|
||||||
|
const res = await contactQuery.save();
|
||||||
|
|
||||||
|
const parseData = JSON.parse(JSON.stringify(res));
|
||||||
|
if (props.details) {
|
||||||
|
props.details({
|
||||||
|
value: parseData[props.valueKey],
|
||||||
|
label: parseData[props.displayKey]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (props.closePopup) {
|
||||||
|
props.closePopup();
|
||||||
|
}
|
||||||
|
if (props.handleUserData) {
|
||||||
|
props.handleUserData(parseData);
|
||||||
|
}
|
||||||
|
setIsLoader(false);
|
||||||
|
setName("");
|
||||||
|
setPhone("");
|
||||||
|
setEmail("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// console.log("err", err);
|
||||||
|
setIsLoader(false);
|
||||||
|
alert("something went wrong!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Define a function to handle the "add yourself" checkbox
|
||||||
|
const handleReset = () => {
|
||||||
|
setName("");
|
||||||
|
setPhone("");
|
||||||
|
setEmail("");
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="shadow-md rounded my-2 p-3 bg-[#ffffff] md:border-[1px] md:border-gray-600/50">
|
||||||
|
<Title title={"Add User"} />
|
||||||
|
{isUserExist && <Alert type="danger">User already exists!</Alert>}
|
||||||
|
{isLoader && (
|
||||||
|
<div className="fixed inset-0 flex justify-center items-center bg-black bg-opacity-30 z-50">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: "45px",
|
||||||
|
color: "#3dd3e0"
|
||||||
|
}}
|
||||||
|
className="loader-37"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="w-full mx-auto">
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<h1 className="text-[20px] font-semibold mb-4">Add User</h1>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label
|
||||||
|
htmlFor="name"
|
||||||
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
|
>
|
||||||
|
Name
|
||||||
|
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="name"
|
||||||
|
value={name}
|
||||||
|
onChange={(e) => setName(e.target.value)}
|
||||||
|
required
|
||||||
|
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label
|
||||||
|
htmlFor="email"
|
||||||
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
|
>
|
||||||
|
Email
|
||||||
|
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
id="email"
|
||||||
|
value={email}
|
||||||
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
|
required
|
||||||
|
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label
|
||||||
|
htmlFor="phone"
|
||||||
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
|
>
|
||||||
|
Phone
|
||||||
|
<span style={{ color: "red", fontSize: 13 }}> *</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="phone"
|
||||||
|
value={phone}
|
||||||
|
onChange={(e) => setPhone(e.target.value)}
|
||||||
|
required
|
||||||
|
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center mt-3 gap-2 text-white">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="bg-[#1ab6ce] rounded-sm shadow-md text-[13px] font-semibold uppercase text-white py-1.5 px-2.5 focus:outline-none"
|
||||||
|
>
|
||||||
|
Submit
|
||||||
|
</button>
|
||||||
|
<div
|
||||||
|
type="button"
|
||||||
|
onClick={() => handleReset()}
|
||||||
|
className="bg-[#188ae2] rounded-sm shadow-md text-[13px] font-semibold uppercase text-white py-1.5 px-2.5 text-center ml-[2px] focus:outline-none"
|
||||||
|
>
|
||||||
|
Reset
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddUser;
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import { modalCancelBtnColor, modalSubmitBtnColor } from "../constant/const";
|
||||||
|
|
||||||
const AppendFormInForm = (props) => {
|
const AppendFormInForm = (props) => {
|
||||||
const [name, setName] = useState("");
|
const [name, setName] = useState("");
|
||||||
@@ -46,6 +47,7 @@ const AppendFormInForm = (props) => {
|
|||||||
// Define a function to handle form submission
|
// Define a function to handle form submission
|
||||||
const handleSubmit = async (e) => {
|
const handleSubmit = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
setIsLoader(true);
|
setIsLoader(true);
|
||||||
Parse.serverURL = parseBaseUrl;
|
Parse.serverURL = parseBaseUrl;
|
||||||
Parse.initialize(parseAppId);
|
Parse.initialize(parseAppId);
|
||||||
@@ -105,13 +107,18 @@ const AppendFormInForm = (props) => {
|
|||||||
const res = await contactQuery.save();
|
const res = await contactQuery.save();
|
||||||
|
|
||||||
const parseData = JSON.parse(JSON.stringify(res));
|
const parseData = JSON.parse(JSON.stringify(res));
|
||||||
props.details({
|
if (props.details) {
|
||||||
value: parseData[props.valueKey],
|
props.details({
|
||||||
label: parseData[props.displayKey]
|
value: parseData[props.valueKey],
|
||||||
});
|
label: parseData[props.displayKey]
|
||||||
|
});
|
||||||
|
}
|
||||||
if (props.closePopup) {
|
if (props.closePopup) {
|
||||||
props.closePopup();
|
props.closePopup();
|
||||||
}
|
}
|
||||||
|
if (props.handleUserData) {
|
||||||
|
props.handleUserData(parseData);
|
||||||
|
}
|
||||||
|
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
// Reset the form fields
|
// Reset the form fields
|
||||||
@@ -158,13 +165,18 @@ const AppendFormInForm = (props) => {
|
|||||||
const res = await contactQuery.save();
|
const res = await contactQuery.save();
|
||||||
|
|
||||||
const parseData = JSON.parse(JSON.stringify(res));
|
const parseData = JSON.parse(JSON.stringify(res));
|
||||||
props.details({
|
if (props.details) {
|
||||||
value: parseData[props.valueKey],
|
props.details({
|
||||||
label: parseData[props.displayKey]
|
value: parseData[props.valueKey],
|
||||||
});
|
label: parseData[props.displayKey]
|
||||||
|
});
|
||||||
|
}
|
||||||
if (props.closePopup) {
|
if (props.closePopup) {
|
||||||
props.closePopup();
|
props.closePopup();
|
||||||
}
|
}
|
||||||
|
if (props.handleUserData) {
|
||||||
|
props.handleUserData(parseData);
|
||||||
|
}
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
// Reset the form fields
|
// Reset the form fields
|
||||||
setAddYourself(false);
|
setAddYourself(false);
|
||||||
@@ -282,14 +294,16 @@ const AppendFormInForm = (props) => {
|
|||||||
<div className="mt-4 flex justify-start">
|
<div className="mt-4 flex justify-start">
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="bg-[#1ab6ce] text-sm text-white px-4 py-2 rounded shadow focus:outline-none"
|
style={{ backgroundColor: modalSubmitBtnColor }}
|
||||||
|
className="mr-2 px-[20px] py-1.5 text-white rounded shadow-md text-center focus:outline-none "
|
||||||
>
|
>
|
||||||
Submit
|
Submit
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => handleReset()}
|
onClick={() => handleReset()}
|
||||||
className="bg-[#188ae2] text-sm text-white px-4 py-2 rounded ml-2 shadow focus:outline-none"
|
style={{ backgroundColor: modalCancelBtnColor }}
|
||||||
|
className="px-4 py-1.5 text-black border-[1px] border-[#ccc] shadow-md rounded focus:outline-none"
|
||||||
>
|
>
|
||||||
Reset
|
Reset
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import Package from "../../package.json";
|
import Package from "../../package.json";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import { openInNewTab } from "../constant/Utils";
|
||||||
const Footer = () => {
|
const Footer = () => {
|
||||||
const [showButton, setShowButton] = useState(false);
|
const [showButton, setShowButton] = useState(false);
|
||||||
const [version, setVersion] = useState("");
|
const [version, setVersion] = useState("");
|
||||||
@@ -37,12 +38,18 @@ const Footer = () => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const appName = "OpenSign™";
|
const appName = "OpenSign™";
|
||||||
|
const openUrl = () => {
|
||||||
|
openInNewTab(
|
||||||
|
"https://github.com/OpenSignLabs/OpenSign/releases/tag/" + version
|
||||||
|
);
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="bg-[#222c3c] text-[#98a6ba] text-center text-[13px] py-3">
|
<div className="bg-[#222c3c] text-[#98a6ba] text-center text-[13px] py-3">
|
||||||
All Rights Reserved © {new Date().getFullYear()}
|
All Rights Reserved © {new Date().getFullYear()}
|
||||||
{appName} ( version: {version ? version : `${Package.version} `})
|
<span onClick={openUrl} className="hover:underline cursor-pointer">
|
||||||
|
{appName} ( version: {version ? version : `${Package.version} `})
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
className={`${
|
className={`${
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import FullScreenButton from "./FullScreenButton";
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import { useWindowSize } from "../hook/useWindowSize";
|
import { useWindowSize } from "../hook/useWindowSize";
|
||||||
|
import { openInNewTab } from "../constant/Utils";
|
||||||
const Header = ({ showSidebar }) => {
|
const Header = ({ showSidebar }) => {
|
||||||
const navigation = useNavigate();
|
const navigation = useNavigate();
|
||||||
const { width } = useWindowSize();
|
const { width } = useWindowSize();
|
||||||
@@ -118,6 +119,12 @@ const Header = ({ showSidebar }) => {
|
|||||||
<ul>
|
<ul>
|
||||||
<li
|
<li
|
||||||
className="hover:bg-gray-100 rounded-t-lg py-1 px-2 cursor-pointer font-normal"
|
className="hover:bg-gray-100 rounded-t-lg py-1 px-2 cursor-pointer font-normal"
|
||||||
|
onClick={() => openInNewTab("https://docs.opensignlabs.com")}
|
||||||
|
>
|
||||||
|
<i className="fa-solid fa-book"></i> Docs
|
||||||
|
</li>
|
||||||
|
<li
|
||||||
|
className="hover:bg-gray-100 py-1 px-2 cursor-pointer font-normal"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
navigation("/profile");
|
navigation("/profile");
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ const LoginFacebook = ({
|
|||||||
email: userDetails.Email,
|
email: userDetails.Email,
|
||||||
// "passsword":userDetails.Phone,
|
// "passsword":userDetails.Phone,
|
||||||
phone: userDetails.Phone,
|
phone: userDetails.Phone,
|
||||||
role: "contracts_Admin",
|
role: "contracts_User",
|
||||||
company: userDetails.Company
|
company: userDetails.Company
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import React, { useState, useRef } from "react";
|
|||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import jwtDecode from "jwt-decode";
|
import jwtDecode from "jwt-decode";
|
||||||
import { useScript } from "../hook/useScript";
|
import { useScript } from "../hook/useScript";
|
||||||
|
import ModalUi from "../primitives/ModalUi";
|
||||||
|
import { modalCancelBtnColor, modalSubmitBtnColor } from "../constant/const";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* `GoogleSignInBtn`as it's name indicates it render google sign in button
|
* `GoogleSignInBtn`as it's name indicates it render google sign in button
|
||||||
@@ -148,7 +150,7 @@ const GoogleSignInBtn = ({
|
|||||||
email: userDetails.Email,
|
email: userDetails.Email,
|
||||||
// "passsword":userDetails.Phone,
|
// "passsword":userDetails.Phone,
|
||||||
phone: userDetails.Phone,
|
phone: userDetails.Phone,
|
||||||
role: "contracts_Admin",
|
role: "contracts_User",
|
||||||
company: userDetails.Company,
|
company: userDetails.Company,
|
||||||
jobTitle: userDetails.Destination
|
jobTitle: userDetails.Destination
|
||||||
}
|
}
|
||||||
@@ -231,118 +233,94 @@ const GoogleSignInBtn = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div ref={googleBtn} className="text-sm"></div>
|
<div ref={googleBtn} className="text-sm"></div>
|
||||||
|
<ModalUi showClose={false} isOpen={isModal} title="Sign up form">
|
||||||
{isModal && (
|
<form className="px-4 py-3">
|
||||||
<div
|
<div className="mb-3">
|
||||||
className="modal fade show"
|
<label
|
||||||
id="exampleModal"
|
htmlFor="Phone"
|
||||||
tabIndex="-1"
|
style={{ display: "flex" }}
|
||||||
role="dialog"
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
style={{ display: "block", zIndex: 1 }}
|
>
|
||||||
>
|
Phone <span style={{ fontSize: 13, color: "red" }}>*</span>
|
||||||
<div className="modal-dialog" role="document">
|
</label>
|
||||||
<div className="modal-content">
|
<input
|
||||||
<div className="modal-header">
|
type="tel"
|
||||||
<h5 className="modal-title">Sign up form</h5>
|
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||||
<span>
|
id="Phone"
|
||||||
<span></span>
|
value={userDetails.Phone}
|
||||||
</span>
|
onChange={(e) =>
|
||||||
</div>
|
setUserDetails({
|
||||||
<div className="modal-body">
|
...userDetails,
|
||||||
<form>
|
Phone: e.target.value
|
||||||
<div className="form-group">
|
})
|
||||||
<label
|
}
|
||||||
htmlFor="Phone"
|
required
|
||||||
style={{ display: "flex" }}
|
/>
|
||||||
className="col-form-label"
|
|
||||||
>
|
|
||||||
Phone{" "}
|
|
||||||
<span style={{ fontSize: 13, color: "red" }}>*</span>
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="tel"
|
|
||||||
className="form-control"
|
|
||||||
id="Phone"
|
|
||||||
value={userDetails.Phone}
|
|
||||||
onChange={(e) =>
|
|
||||||
setUserDetails({
|
|
||||||
...userDetails,
|
|
||||||
Phone: e.target.value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="form-group">
|
|
||||||
<label
|
|
||||||
htmlFor="Company"
|
|
||||||
style={{ display: "flex" }}
|
|
||||||
className="col-form-label"
|
|
||||||
>
|
|
||||||
Company{" "}
|
|
||||||
<span style={{ fontSize: 13, color: "red" }}>*</span>
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="form-control"
|
|
||||||
id="Company"
|
|
||||||
value={userDetails.Company}
|
|
||||||
onChange={(e) =>
|
|
||||||
setUserDetails({
|
|
||||||
...userDetails,
|
|
||||||
Company: e.target.value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="form-group">
|
|
||||||
<label
|
|
||||||
htmlFor="JobTitle"
|
|
||||||
style={{ display: "flex" }}
|
|
||||||
className="col-form-label"
|
|
||||||
>
|
|
||||||
Job Title{" "}
|
|
||||||
<span style={{ fontSize: 13, color: "red" }}>*</span>
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="form-control"
|
|
||||||
id="JobTitle"
|
|
||||||
value={userDetails.Destination}
|
|
||||||
onChange={(e) =>
|
|
||||||
setUserDetails({
|
|
||||||
...userDetails,
|
|
||||||
Destination: e.target.value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="bg-[#17a2b8] p-2 text-white rounded"
|
|
||||||
onClick={() => handleSubmitbtn()}
|
|
||||||
style={{ marginRight: 10 }}
|
|
||||||
>
|
|
||||||
Sign up
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="bg-[#6c757d] p-2 text-white rounded"
|
|
||||||
onClick={handleCloseModal}
|
|
||||||
style={{ width: 90 }}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className="mb-3">
|
||||||
)}
|
<label
|
||||||
|
htmlFor="Company"
|
||||||
|
style={{ display: "flex" }}
|
||||||
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
|
>
|
||||||
|
Company <span style={{ fontSize: 13, color: "red" }}>*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||||
|
id="Company"
|
||||||
|
value={userDetails.Company}
|
||||||
|
onChange={(e) =>
|
||||||
|
setUserDetails({
|
||||||
|
...userDetails,
|
||||||
|
Company: e.target.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label
|
||||||
|
htmlFor="JobTitle"
|
||||||
|
style={{ display: "flex" }}
|
||||||
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
|
>
|
||||||
|
Job Title <span style={{ fontSize: 13, color: "red" }}>*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||||
|
id="JobTitle"
|
||||||
|
value={userDetails.Destination}
|
||||||
|
onChange={(e) =>
|
||||||
|
setUserDetails({
|
||||||
|
...userDetails,
|
||||||
|
Destination: e.target.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="px-3 py-1.5 text-white rounded shadow-md text-center focus:outline-none "
|
||||||
|
onClick={() => handleSubmitbtn()}
|
||||||
|
style={{ marginRight: 10, backgroundColor: modalSubmitBtnColor }}
|
||||||
|
>
|
||||||
|
Sign up
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="p-1.5 text-black border-[1px] border-[#ccc] shadow-md rounded focus:outline-none"
|
||||||
|
onClick={handleCloseModal}
|
||||||
|
style={{ width: 90, backgroundColor: modalCancelBtnColor }}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</ModalUi>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,391 +0,0 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
|
||||||
import Form from "@rjsf/core";
|
|
||||||
import validator from "@rjsf/validator-ajv8";
|
|
||||||
import Parse from "parse";
|
|
||||||
import "../styles/loader.css";
|
|
||||||
import LayoutField from "./fields/Rjsf-layout";
|
|
||||||
import TimeWidget from "./fields/TimeWidget";
|
|
||||||
import Level1Dropdown from "./fields/Level1Dropdown";
|
|
||||||
import HiddenField from "./fields/HiddenField";
|
|
||||||
import MultiSelectField from "./fields/MultiSelectField";
|
|
||||||
import TreeWidget from "../components/TreeWidget";
|
|
||||||
import { formJson } from "../json/FormJson";
|
|
||||||
const TreeEditForm = (props) => {
|
|
||||||
const widget = {
|
|
||||||
TimeWidget: TimeWidget
|
|
||||||
};
|
|
||||||
const fields = {
|
|
||||||
layout: LayoutField,
|
|
||||||
Level1Dropdown: Level1Dropdown,
|
|
||||||
HiddenField: HiddenField,
|
|
||||||
MultiSelectField: MultiSelectField,
|
|
||||||
FolderComponent: TreeWidget
|
|
||||||
};
|
|
||||||
|
|
||||||
const [schema, setschema] = useState({});
|
|
||||||
const [ui_schema, setui_schema] = useState({});
|
|
||||||
const [title, settitle] = useState("");
|
|
||||||
const [schemaState, setschemaState] = useState({});
|
|
||||||
const [formData, setformData] = useState({});
|
|
||||||
const [active, setactive] = useState(true);
|
|
||||||
const [loading, setloading] = useState(false);
|
|
||||||
const [_validate, set_validate] = useState(null);
|
|
||||||
const [noValidate, setnoValidate] = useState(false);
|
|
||||||
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
|
||||||
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
|
||||||
|
|
||||||
const getForm = async (id) => {
|
|
||||||
setloading(true);
|
|
||||||
try {
|
|
||||||
//get json form data (schema ,uischema)
|
|
||||||
const results = formJson(id);
|
|
||||||
try {
|
|
||||||
let _record = Parse.Object.extend(results.class);
|
|
||||||
var query1 = new Parse.Query(_record);
|
|
||||||
await query1.get(props.objectId).then(
|
|
||||||
(x) => {
|
|
||||||
try {
|
|
||||||
if (x) {
|
|
||||||
let result = x.toJSON();
|
|
||||||
let new_result = result;
|
|
||||||
for (let [key, value] of Object.entries(result)) {
|
|
||||||
if (value["__type"] === "Date") {
|
|
||||||
let todayTime1 = new Date(value.iso);
|
|
||||||
var month = String(todayTime1.getMonth() + 1);
|
|
||||||
var day = String(todayTime1.getDate());
|
|
||||||
var year = String(todayTime1.getFullYear());
|
|
||||||
if (month.length < 2) month = "0" + month;
|
|
||||||
if (day.length < 2) day = "0" + day;
|
|
||||||
let date1 = year + "-" + month + "-" + day;
|
|
||||||
let bindVar = date1;
|
|
||||||
if (!results.jsonSchema.properties[key].format) {
|
|
||||||
bindVar = todayTime1.toISOString();
|
|
||||||
}
|
|
||||||
new_result[key] = bindVar;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setschemaState(results.jsonSchema);
|
|
||||||
setformData(new_result);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
//alert(error.message);
|
|
||||||
|
|
||||||
setloading(false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
console.log("err", error);
|
|
||||||
setloading(false);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
setschema(results.jsonSchema);
|
|
||||||
setui_schema(results.uiSchema);
|
|
||||||
set_validate(results.validFunction);
|
|
||||||
setnoValidate(results.noValidate);
|
|
||||||
settitle(results.class);
|
|
||||||
setloading(false);
|
|
||||||
setactive(true);
|
|
||||||
} catch (error) {
|
|
||||||
setloading(false);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
setloading(false);
|
|
||||||
console.error("Problem", e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const wrap = (s) => "{ return " + s + " };";
|
|
||||||
|
|
||||||
const dynamicValidate = (formData, errors) => {
|
|
||||||
try {
|
|
||||||
let body = atob(_validate);
|
|
||||||
let res = new Function(wrap(body))
|
|
||||||
.call(null)
|
|
||||||
.call(null, formData, errors);
|
|
||||||
return res;
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSubmit = async ({ formData }) => {
|
|
||||||
setactive(false);
|
|
||||||
setloading(true);
|
|
||||||
let RowData = formData;
|
|
||||||
RowData &&
|
|
||||||
Object.entries(RowData).forEach(([key, value]) => {
|
|
||||||
if (typeof value === "string") {
|
|
||||||
RowData[key] = value.trim();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let _scanData = schemaState;
|
|
||||||
if (_scanData.dependencies) {
|
|
||||||
Object.keys(_scanData.dependencies).forEach((key) => {
|
|
||||||
if (_scanData.dependencies[key].oneOf) {
|
|
||||||
_scanData.dependencies[key].oneOf.forEach((val) => {
|
|
||||||
Object.keys(val.properties).forEach((k) => {
|
|
||||||
if (typeof val.properties[k] === "object") {
|
|
||||||
if (val.properties[k].format === "date") {
|
|
||||||
if (RowData[k]) {
|
|
||||||
let newdate = new Date(RowData[k]);
|
|
||||||
RowData[k] = newdate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (val.properties[k].component === "HtmlEditor") {
|
|
||||||
if (RowData[k]) {
|
|
||||||
let newHtml = RowData[k]
|
|
||||||
.replace(/<p[^>]*>/g, "")
|
|
||||||
.replace(/<\/p>/g, " ");
|
|
||||||
RowData[k] = newHtml;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (val.properties[k].component === "DateTime") {
|
|
||||||
if (RowData[k]) {
|
|
||||||
let newDate11 = new Date(RowData[k]);
|
|
||||||
RowData[k] = newDate11;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (val.properties[k].component === "CurrencyInput") {
|
|
||||||
if (val.properties[k].currencyColumn) {
|
|
||||||
RowData[`${val.properties[k].currencyColumn}`] =
|
|
||||||
val.properties[k].defaultcurrency;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (val.properties[k].type === "string") {
|
|
||||||
if (typeof RowData[k] === "string")
|
|
||||||
RowData[k] = RowData[k].trim();
|
|
||||||
}
|
|
||||||
if (val.properties[k].data !== undefined) {
|
|
||||||
if (val.properties[k].data.isPointer) {
|
|
||||||
let pointer = undefined;
|
|
||||||
if (val.properties[k].data.class) {
|
|
||||||
if (RowData[k]) {
|
|
||||||
pointer = {
|
|
||||||
__type: "Pointer",
|
|
||||||
className: val.properties[k].data.class,
|
|
||||||
objectId: RowData[k]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (RowData[k]) {
|
|
||||||
pointer = {
|
|
||||||
__type: "Pointer",
|
|
||||||
className: localStorage.getItem("extended_class"),
|
|
||||||
objectId: RowData[k]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RowData[k] = pointer;
|
|
||||||
}
|
|
||||||
if (val.properties[k].data.FolderTypeValue) {
|
|
||||||
if (RowData[k]) {
|
|
||||||
let obj = {
|
|
||||||
__type: "Pointer",
|
|
||||||
className: val.properties[k].data.ClassName,
|
|
||||||
objectId: RowData[k]
|
|
||||||
};
|
|
||||||
RowData[k] = obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let temp = [];
|
|
||||||
|
|
||||||
let _dd = _scanData.properties;
|
|
||||||
let allowed = [];
|
|
||||||
if (_dd) {
|
|
||||||
Object.keys(_dd).forEach(function (k) {
|
|
||||||
allowed.push(k);
|
|
||||||
if (RowData[k]) {
|
|
||||||
let pointer = {
|
|
||||||
__type: "Pointer",
|
|
||||||
className: _dd[k].class,
|
|
||||||
objectId: RowData[k]
|
|
||||||
};
|
|
||||||
RowData[k] = pointer;
|
|
||||||
}
|
|
||||||
if (_dd[k].format === "date") {
|
|
||||||
if (RowData[k]) {
|
|
||||||
let newdate = new Date(RowData[k]);
|
|
||||||
if (!isNaN(newdate.getTime())) {
|
|
||||||
RowData[k] = newdate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_dd[k].component === "HtmlEditor") {
|
|
||||||
if (RowData[k]) {
|
|
||||||
let newHtml = RowData[k]
|
|
||||||
.replace(/<p[^>]*>/g, "")
|
|
||||||
.replace(/<\/p>/g, " ");
|
|
||||||
RowData[k] = newHtml;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_dd[k].component === "DateTime") {
|
|
||||||
if (RowData[k]) {
|
|
||||||
let newdate = new Date(RowData[k]);
|
|
||||||
if (!isNaN(newdate.getTime())) {
|
|
||||||
RowData[k] = newdate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_dd[k].format === "date-time") {
|
|
||||||
let newdate = new Date(RowData[k]);
|
|
||||||
RowData[k] = newdate;
|
|
||||||
}
|
|
||||||
if (_dd[k].component === "CurrencyInput") {
|
|
||||||
if (_dd[k].currencyColumn) {
|
|
||||||
RowData[`${_dd[k].currencyColumn}`] = _dd[k].defaultcurrency;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_dd[k].data !== undefined) {
|
|
||||||
if (_dd[k].data.isPointer) {
|
|
||||||
let pointer = undefined;
|
|
||||||
if (typeof RowData[k] === "object") {
|
|
||||||
if (RowData[k]) {
|
|
||||||
if (RowData[k].objectId !== "Select") {
|
|
||||||
let obj = {
|
|
||||||
__type: "Pointer",
|
|
||||||
className: RowData[k].className,
|
|
||||||
objectId: RowData[k].objectId
|
|
||||||
};
|
|
||||||
pointer = obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (_dd[k].data.class) {
|
|
||||||
if (RowData[k]) {
|
|
||||||
pointer = {
|
|
||||||
__type: "Pointer",
|
|
||||||
className: _dd[k].data.class,
|
|
||||||
objectId: RowData[k]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (RowData[k]) {
|
|
||||||
pointer = {
|
|
||||||
__type: "Pointer",
|
|
||||||
className: localStorage.getItem("extended_class"),
|
|
||||||
objectId: RowData[k]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowData[k] = pointer;
|
|
||||||
}
|
|
||||||
if (_dd[k].data.FolderTypeValue) {
|
|
||||||
if (RowData[k]) {
|
|
||||||
let obj = {
|
|
||||||
__type: "Pointer",
|
|
||||||
className: _dd[k].data.ClassName,
|
|
||||||
objectId: RowData[k]
|
|
||||||
};
|
|
||||||
RowData[k] = obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_dd[k].type === "string") {
|
|
||||||
if (typeof RowData[k] === "string") RowData[k] = RowData[k].trim();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const filtered = Object.keys(RowData)
|
|
||||||
.filter((key) => allowed.includes(key))
|
|
||||||
.reduce((obj, key) => {
|
|
||||||
obj[key] = RowData[key];
|
|
||||||
return obj;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
try {
|
|
||||||
Parse.serverURL = parseBaseUrl;
|
|
||||||
Parse.initialize(parseAppId);
|
|
||||||
const currentUser = Parse.User.current();
|
|
||||||
if (temp.length !== 0) {
|
|
||||||
let userPointer = {
|
|
||||||
__type: "Pointer",
|
|
||||||
className: "_User",
|
|
||||||
objectId: currentUser.id
|
|
||||||
};
|
|
||||||
filtered[[temp[0]]] = userPointer;
|
|
||||||
}
|
|
||||||
var data = Parse.Object.extend(title);
|
|
||||||
var query = new Parse.Query(data);
|
|
||||||
query.get(props.objectId).then(async (object) => {
|
|
||||||
object.save(filtered).then(
|
|
||||||
() => {
|
|
||||||
try {
|
|
||||||
alert("Record updated successfully");
|
|
||||||
props.HideView(false);
|
|
||||||
setloading(false);
|
|
||||||
setactive(true);
|
|
||||||
} catch (error) {
|
|
||||||
console.log("err", error);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
console.log("err", error);
|
|
||||||
setloading(false);
|
|
||||||
setactive(true);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.log("err", error);
|
|
||||||
|
|
||||||
alert(error.message);
|
|
||||||
setloading(false);
|
|
||||||
setactive(true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (props.FormId) {
|
|
||||||
getForm(props.FormId);
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line
|
|
||||||
}, [props.FormId]);
|
|
||||||
|
|
||||||
if (loading) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className="loader-01"
|
|
||||||
style={{
|
|
||||||
marginTop: "50px",
|
|
||||||
marginLeft: "50%",
|
|
||||||
color: "rgb(0,28,28)",
|
|
||||||
fontSize: "35px"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<Form
|
|
||||||
schema={schema}
|
|
||||||
uiSchema={ui_schema}
|
|
||||||
formData={formData}
|
|
||||||
showErrorList={false}
|
|
||||||
widgets={widget}
|
|
||||||
fields={fields}
|
|
||||||
validate={noValidate && dynamicValidate}
|
|
||||||
onSubmit={handleSubmit}
|
|
||||||
validator={validator}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
{active ? (
|
|
||||||
<button className="bg-[#1ab6ce] px-3 py-2 rounded text-white text-sm" type="submit">
|
|
||||||
Update
|
|
||||||
</button>
|
|
||||||
) : (
|
|
||||||
<button className="bg-[#1ab6ce] px-3 py-2 rounded text-white text-sm" type="submit" disabled>
|
|
||||||
Update
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Form>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default TreeEditForm;
|
|
||||||
@@ -1,237 +0,0 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import Form from "@rjsf/core";
|
|
||||||
import validator from "@rjsf/validator-ajv8";
|
|
||||||
import LayoutField from "./fields/Rjsf-layout";
|
|
||||||
import Level1Dropdown from "./fields/Level1Dropdown";
|
|
||||||
import HiddenField from "./fields/HiddenField";
|
|
||||||
import MultiSelectField from "./fields/MultiSelectField";
|
|
||||||
import "../styles/loader.css";
|
|
||||||
import "../styles/form.css";
|
|
||||||
import FileUpload from "./fields/FileUpload";
|
|
||||||
import parse from "html-react-parser";
|
|
||||||
import TimeWidget from "./fields/TimeWidget";
|
|
||||||
import { formJson } from "../json/FormJson";
|
|
||||||
function TreeFormComponent(props) {
|
|
||||||
const widget = {
|
|
||||||
TimeWidget: TimeWidget
|
|
||||||
};
|
|
||||||
|
|
||||||
const fields = {
|
|
||||||
layout: LayoutField,
|
|
||||||
FileUpload: FileUpload,
|
|
||||||
Level1Dropdown: Level1Dropdown,
|
|
||||||
HiddenField: HiddenField,
|
|
||||||
MultiSelectField: MultiSelectField
|
|
||||||
};
|
|
||||||
|
|
||||||
const [link, setLink] = useState("");
|
|
||||||
const [help, setHelp] = useState("");
|
|
||||||
const toastDescription = "";
|
|
||||||
const toastColor = "#5cb85c";
|
|
||||||
const [loading, setLoding] = useState(true);
|
|
||||||
const [schemaState, setSchemaState] = useState({});
|
|
||||||
const [formData, setFormData] = useState({});
|
|
||||||
const [ui_schema, setUi_schema] = useState({});
|
|
||||||
const active = true;
|
|
||||||
|
|
||||||
console.log("new form", props);
|
|
||||||
|
|
||||||
const getForm = async (id) => {
|
|
||||||
setLoding(true);
|
|
||||||
try {
|
|
||||||
// get json from data(jsonschema, uischema)
|
|
||||||
const results = formJson(id);
|
|
||||||
// console.log("result", results);
|
|
||||||
if (results) {
|
|
||||||
let parentObject = {},
|
|
||||||
childObject = {};
|
|
||||||
const resultjson = results;
|
|
||||||
for (let [key, value] of Object.entries(
|
|
||||||
resultjson.jsonSchema.properties
|
|
||||||
)) {
|
|
||||||
if (key === props.ParentField) {
|
|
||||||
if (props.ParentValue[key]) {
|
|
||||||
parentObject = { [key]: props.ParentValue[key] };
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (props.ParentValue && typeof props.ParentValue === "object") {
|
|
||||||
Object.entries(props.ParentValue).forEach(([k, value]) => {
|
|
||||||
if (k === key) {
|
|
||||||
let newO = { [k]: value };
|
|
||||||
parentObject = { ...parentObject, ...newO };
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (props.ChildField) {
|
|
||||||
Object.entries(props.ChildField).forEach(([k, value]) => {
|
|
||||||
if (k === key) {
|
|
||||||
let newO = { [k]: value };
|
|
||||||
childObject = { ...childObject, ...newO };
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof value === "object") {
|
|
||||||
for (let [k, v] of Object.entries(value)) {
|
|
||||||
if (k === "format" && v === "date") {
|
|
||||||
let today = new Date();
|
|
||||||
let date =
|
|
||||||
today.getFullYear() +
|
|
||||||
"-" +
|
|
||||||
("0" + (today.getMonth() + 1)).slice(-2) +
|
|
||||||
"-" +
|
|
||||||
("0" + today.getDate()).slice(-2);
|
|
||||||
value.default = date;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (props.ParentField) {
|
|
||||||
setFormData({ ...parentObject, ...childObject });
|
|
||||||
}
|
|
||||||
|
|
||||||
let txt, link;
|
|
||||||
if (resultjson.help) {
|
|
||||||
if (resultjson.help.htmlbody) {
|
|
||||||
txt = resultjson.help.htmlbody;
|
|
||||||
}
|
|
||||||
if (resultjson.help.link) {
|
|
||||||
link = resultjson.help.link;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setHelp(txt);
|
|
||||||
setLink(link);
|
|
||||||
|
|
||||||
props.ClassName(resultjson.class);
|
|
||||||
props.SchemaState(resultjson.jsonSchema);
|
|
||||||
setSchemaState(resultjson.jsonSchema);
|
|
||||||
setUi_schema(resultjson.uiSchema);
|
|
||||||
setLoding(false);
|
|
||||||
} else {
|
|
||||||
alert("form not found");
|
|
||||||
setLoding(false);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Problem", e);
|
|
||||||
setLoding(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!props.IsEdit) {
|
|
||||||
getForm(props.Id);
|
|
||||||
}
|
|
||||||
// console.log("props tree", props);
|
|
||||||
// eslint-disable-next-line
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
let formView = (
|
|
||||||
<React.Fragment>
|
|
||||||
<Form
|
|
||||||
schema={schemaState}
|
|
||||||
uiSchema={ui_schema}
|
|
||||||
showErrorList={false}
|
|
||||||
widgets={widget}
|
|
||||||
fields={fields}
|
|
||||||
formData={formData}
|
|
||||||
onSubmit={props.handleSubmit}
|
|
||||||
validator={validator}
|
|
||||||
>
|
|
||||||
{active ? (
|
|
||||||
<button className="btn btn-info submiBtn" type="submit">
|
|
||||||
{props.IsEdit ? "update folder" : "create folder"}
|
|
||||||
</button>
|
|
||||||
) : (
|
|
||||||
<button className="btn btn-info submiBtn " type="submit" disabled>
|
|
||||||
submitting...
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</Form>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
|
|
||||||
if (loading) {
|
|
||||||
formView = (
|
|
||||||
<div style={{ height: "300px" }}>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
marginLeft: "45%",
|
|
||||||
marginTop: "150px",
|
|
||||||
fontSize: "45px",
|
|
||||||
color: "#3dd3e0"
|
|
||||||
}}
|
|
||||||
className="loader-37"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-12">
|
|
||||||
<div className="card">
|
|
||||||
<div className="card-body no-padding height-9">
|
|
||||||
{help ? (
|
|
||||||
<div className="dropdown" style={{ marginTop: "-30px" }}>
|
|
||||||
<i
|
|
||||||
className="far fa-question-circle dropdown-toggle hovereffect"
|
|
||||||
aria-hidden="true"
|
|
||||||
id="dropdownMenuButton"
|
|
||||||
data-toggle="dropdown"
|
|
||||||
aria-haspopup="true"
|
|
||||||
aria-expanded="false"
|
|
||||||
style={{
|
|
||||||
fontSize: "18px",
|
|
||||||
color: "purple",
|
|
||||||
cursor: "pointer !important",
|
|
||||||
position: "relative",
|
|
||||||
top: "40px",
|
|
||||||
left: "98%"
|
|
||||||
}}
|
|
||||||
></i>
|
|
||||||
<div
|
|
||||||
className="dropdown-menu"
|
|
||||||
aria-labelledby="dropdownMenuButton"
|
|
||||||
style={{
|
|
||||||
marginleft: "-121px",
|
|
||||||
margintop: "-14px",
|
|
||||||
position: "absolute",
|
|
||||||
padding: "10px",
|
|
||||||
width: "300px",
|
|
||||||
top: "102px!important"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{parse(`
|
|
||||||
${help}
|
|
||||||
`)}
|
|
||||||
<br />
|
|
||||||
{link ? (
|
|
||||||
<a
|
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
window.location.href = link;
|
|
||||||
}}
|
|
||||||
target="_blank"
|
|
||||||
className="btn btn-xs btn-primary"
|
|
||||||
>
|
|
||||||
Read more..
|
|
||||||
</a>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
<div style={{ fontSize: "13px" }}>{formView}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="snackbar" style={{ backgroundColor: toastColor }}>
|
|
||||||
{toastDescription}
|
|
||||||
</div>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default TreeFormComponent;
|
|
||||||
@@ -1,895 +0,0 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
|
||||||
import { connect } from "react-redux";
|
|
||||||
import LabelField from "./fields/LabelField";
|
|
||||||
import Parse from "parse";
|
|
||||||
import axios from "axios";
|
|
||||||
import "../styles/spinner.css";
|
|
||||||
import TreeFormComponent from "./TreeFormComponent";
|
|
||||||
import TreeEditForm from "./TreeEditForm";
|
|
||||||
import "../styles/modal.css";
|
|
||||||
import Modal from "react-modal";
|
|
||||||
|
|
||||||
const TreeWidget = (props) => {
|
|
||||||
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
|
||||||
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
|
||||||
const [isAddField, setIsAddField] = useState(false);
|
|
||||||
const [folderList, setFolderList] = useState([]);
|
|
||||||
const [tabList, setTabList] = useState([]);
|
|
||||||
const [appId, setAppId] = useState(undefined);
|
|
||||||
const [selectedFolder, setSelectedFolder] = useState(undefined);
|
|
||||||
const [loader, setLoader] = useState(false);
|
|
||||||
const [className, setClassName] = useState("");
|
|
||||||
const [schemaState, setSchemaState] = useState({});
|
|
||||||
const [TabURL, setTabURL] = useState("");
|
|
||||||
const [editable, setEditable] = useState(false);
|
|
||||||
const [editId, setEditId] = useState("");
|
|
||||||
const [defaultState, setDefaultState] = useState(false);
|
|
||||||
const [isShowModal, setIsShowModal] = useState(false);
|
|
||||||
const selectFolderHandle = async () => {
|
|
||||||
setIsShowModal(true);
|
|
||||||
setIsAddField(false);
|
|
||||||
setDefaultState(false);
|
|
||||||
setFolderList([]);
|
|
||||||
setLoader(true);
|
|
||||||
|
|
||||||
if (tabList.length > 0) {
|
|
||||||
let len = tabList.length - 1;
|
|
||||||
selectedItemList(tabList[len]);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
var test;
|
|
||||||
if (props.schema.parent) {
|
|
||||||
try {
|
|
||||||
if (props.parent[props.schema.parent]) {
|
|
||||||
Parse.serverURL = parseBaseUrl;
|
|
||||||
Parse.initialize(parseAppId);
|
|
||||||
const currentUser = Parse.User.current();
|
|
||||||
let res;
|
|
||||||
if (localStorage.getItem("Extand_Class")) {
|
|
||||||
let data = JSON.parse(localStorage.getItem("Extand_Class"));
|
|
||||||
res = data[0];
|
|
||||||
} else {
|
|
||||||
res = await Parse.Cloud.run("getUserDetails", {
|
|
||||||
email: currentUser.get("email")
|
|
||||||
});
|
|
||||||
if (res) res = res.toJSON();
|
|
||||||
}
|
|
||||||
if (res) {
|
|
||||||
let json = res;
|
|
||||||
setAppId(json.AppId);
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line
|
|
||||||
let reg = /(\#.*?\#)/gi;
|
|
||||||
let str = props.schema.data.Query;
|
|
||||||
if (str.includes("#")) {
|
|
||||||
test = str.replace(reg, props.parent[props.schema.parent]);
|
|
||||||
} else {
|
|
||||||
test = str;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (props.child[props.schema.parent]) {
|
|
||||||
Parse.serverURL = parseBaseUrl;
|
|
||||||
Parse.initialize(parseAppId);
|
|
||||||
const currentUser = Parse.User.current();
|
|
||||||
let res;
|
|
||||||
if (localStorage.getItem("Extand_Class")) {
|
|
||||||
let data = JSON.parse(localStorage.getItem("Extand_Class"));
|
|
||||||
res = data[0];
|
|
||||||
} else {
|
|
||||||
res = await Parse.Cloud.run("getUserDetails", {
|
|
||||||
email: currentUser.get("email")
|
|
||||||
});
|
|
||||||
if (res) res = res.toJSON();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res) {
|
|
||||||
let json = res;
|
|
||||||
setAppId(json.AppId);
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line
|
|
||||||
let reg = /(\#.*?\#)/gi;
|
|
||||||
let str = props.schema.data.Query;
|
|
||||||
if (str.includes("#")) {
|
|
||||||
test = str.replace(reg, props.child[props.schema.parent]);
|
|
||||||
} else {
|
|
||||||
test = str;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
alert(`Please select ${props.schema.parent}`);
|
|
||||||
setLoader(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log("error ", error);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Parse.serverURL = parseBaseUrl;
|
|
||||||
Parse.initialize(parseAppId);
|
|
||||||
const currentUser = Parse.User.current();
|
|
||||||
// eslint-disable-next-line
|
|
||||||
let reg = /(\#.*?\#)/gi;
|
|
||||||
let str = props.schema.data.Query;
|
|
||||||
let res;
|
|
||||||
if (localStorage.getItem("Extand_Class")) {
|
|
||||||
let data = JSON.parse(localStorage.getItem("Extand_Class"));
|
|
||||||
res = data[0];
|
|
||||||
} else {
|
|
||||||
// emp = Parse.Object.extend(localStorage.getItem("extended_class"));
|
|
||||||
// q = new Parse.Query(emp);
|
|
||||||
// q.equalTo("UserId", currentUser);
|
|
||||||
// res = await q.first();
|
|
||||||
// if (res) res = res.toJSON();
|
|
||||||
const currentUser = Parse.User.current();
|
|
||||||
res = await Parse.Cloud.run("getUserDetails", {
|
|
||||||
email: currentUser.get("email")
|
|
||||||
});
|
|
||||||
if (res) res = res.toJSON();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res) {
|
|
||||||
let json = res;
|
|
||||||
setAppId(json.AppId);
|
|
||||||
}
|
|
||||||
if (str.includes("#")) {
|
|
||||||
if (res) {
|
|
||||||
let json = res.toJSON();
|
|
||||||
let output = str.match(reg);
|
|
||||||
if (output.length === 1) {
|
|
||||||
output = output.join();
|
|
||||||
output = output.substring(1, output.length - 1);
|
|
||||||
output = output.split(".");
|
|
||||||
if (output.length === 1) {
|
|
||||||
let out = output[0];
|
|
||||||
if (json[out]) {
|
|
||||||
if (typeof json[out] === "object") {
|
|
||||||
test = str.replace(reg, JSON.stringify(json[out]));
|
|
||||||
} else {
|
|
||||||
test = str.replace(reg, json[out]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
test = str.replace(reg, currentUser.id);
|
|
||||||
}
|
|
||||||
} else if (output.length === 2) {
|
|
||||||
let out1 = json[output[0]][output[1]];
|
|
||||||
if (out1) {
|
|
||||||
test = str.replace(reg, out1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
test = str;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let url = `${parseBaseUrl}classes/${props.schema.data.ClassName}?${test}`;
|
|
||||||
const headers = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": parseAppId,
|
|
||||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
|
||||||
};
|
|
||||||
await axios
|
|
||||||
.get(url, { headers: headers })
|
|
||||||
.then((res) => {
|
|
||||||
if (res) {
|
|
||||||
setFolderList(res.data.results);
|
|
||||||
setLoader(false);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
setLoader(false);
|
|
||||||
console.log(err);
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
setLoader(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const selectedItemList = async (folder) => {
|
|
||||||
setLoader(true);
|
|
||||||
setFolderList([]);
|
|
||||||
try {
|
|
||||||
let url = `${parseBaseUrl}classes/${props.schema.data.ClassName}?where={"${props.schema.data.ParentFolderField}":{"__type":"Pointer","className":"${props.schema.data.ClassName}","objectId":"${folder.objectId}"}}`;
|
|
||||||
const headers = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": parseAppId,
|
|
||||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
|
||||||
};
|
|
||||||
await axios.get(url, { headers: headers }).then((result) => {
|
|
||||||
if (result) {
|
|
||||||
setFolderList(result.data.results);
|
|
||||||
setLoader(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
setLoader(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const removeTabListItem = async (e, i) => {
|
|
||||||
e.preventDefault();
|
|
||||||
setEditable(false);
|
|
||||||
setLoader(true);
|
|
||||||
setFolderList([]);
|
|
||||||
let list = tabList.filter((itm, j) => {
|
|
||||||
if (j <= i) {
|
|
||||||
return itm;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
setTabList(list);
|
|
||||||
setIsAddField(false);
|
|
||||||
try {
|
|
||||||
let _len = list.length - 1;
|
|
||||||
let url = `${parseBaseUrl}classes/${props.schema.data.ClassName}?where={"${props.schema.data.ParentFolderField}":{"__type":"Pointer","className":"${props.schema.data.ClassName}","objectId":"${list[_len].objectId}"}}`;
|
|
||||||
const headers = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": parseAppId,
|
|
||||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
|
||||||
};
|
|
||||||
await axios.get(url, { headers: headers }).then((result) => {
|
|
||||||
if (result) {
|
|
||||||
setFolderList(result.data.results);
|
|
||||||
setLoader(false);
|
|
||||||
}
|
|
||||||
setLoader(false);
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
setLoader(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onDeleteFolder = async (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
if (folderList.length > 0) {
|
|
||||||
alert(
|
|
||||||
"Folder should not delete. To delete first delete sub items in it."
|
|
||||||
);
|
|
||||||
} else if (window.confirm(`Are you sure you want to delete this record`)) {
|
|
||||||
try {
|
|
||||||
setLoader(true);
|
|
||||||
let len = tabList.length - 1;
|
|
||||||
|
|
||||||
Parse.serverURL = parseBaseUrl;
|
|
||||||
Parse.initialize(parseAppId);
|
|
||||||
var deleted = Parse.Object.extend(props.schema.data.ClassName);
|
|
||||||
var query = new Parse.Query(deleted);
|
|
||||||
await query.get(tabList[len].objectId).then(
|
|
||||||
(del) => {
|
|
||||||
del.destroy().then(
|
|
||||||
(y) => {
|
|
||||||
if (y) {
|
|
||||||
setLoader(false);
|
|
||||||
let list = tabList.filter((itm, j) => {
|
|
||||||
if (j !== len) return itm;
|
|
||||||
});
|
|
||||||
setTabList(list);
|
|
||||||
if (list.length > 0) {
|
|
||||||
let len = list.length - 1;
|
|
||||||
selectedItemList(list[len]);
|
|
||||||
} else {
|
|
||||||
selectFolderHandle();
|
|
||||||
}
|
|
||||||
alert("Folder deleted successfully.");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
alert(error.message);
|
|
||||||
setLoader(false);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
console.log("error ", error);
|
|
||||||
// The object was not retrieved successfully.
|
|
||||||
setLoader(false);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
setLoader(false);
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSubmitResult = async (e) => {
|
|
||||||
setIsShowModal(false);
|
|
||||||
e.preventDefault();
|
|
||||||
//console.log("tabList ", tabList);
|
|
||||||
if (tabList.length > 0) {
|
|
||||||
try {
|
|
||||||
let len = tabList.length - 1;
|
|
||||||
setSelectedFolder({
|
|
||||||
Topic: tabList[len][`${props.schema.data.FolderNameField}`],
|
|
||||||
description: tabList[len][`${props.schema.data.FolderDescription}`]
|
|
||||||
});
|
|
||||||
props.onChange(tabList[len]["objectId"]);
|
|
||||||
let url = "Folders";
|
|
||||||
tabList.forEach((t) => {
|
|
||||||
url = url + " / " + t[`${props.schema.data.FolderNameField}`];
|
|
||||||
});
|
|
||||||
setTabURL(url);
|
|
||||||
setIsAddField(false);
|
|
||||||
if (!props.formData) {
|
|
||||||
setTabList([]);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
setIsAddField(false);
|
|
||||||
alert(error.message);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setIsAddField(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const editFolderDisplay = async (formData) => {
|
|
||||||
try {
|
|
||||||
let objectId = formData.objectId;
|
|
||||||
let className = formData.className;
|
|
||||||
Parse.serverURL = parseBaseUrl;
|
|
||||||
Parse.initialize(parseAppId);
|
|
||||||
const fldr = Parse.Object.extend(className);
|
|
||||||
let query = new Parse.Query(fldr);
|
|
||||||
query.equalTo("objectId", objectId);
|
|
||||||
const result = await query.first();
|
|
||||||
let resultJson = result.toJSON();
|
|
||||||
let CustomTabList = [];
|
|
||||||
if (resultJson) {
|
|
||||||
CustomTabList.push(resultJson);
|
|
||||||
if (resultJson[`${props.schema.data.ParentFolderField}`]) {
|
|
||||||
let tabsRes = resultJson[`${props.schema.data.ParentFolderField}`];
|
|
||||||
let looping = false;
|
|
||||||
do {
|
|
||||||
let fldttr = Parse.Object.extend(tabsRes.className);
|
|
||||||
let query2 = new Parse.Query(fldttr);
|
|
||||||
query2.equalTo("objectId", tabsRes.objectId);
|
|
||||||
let custome_res = await query2.first();
|
|
||||||
if (custome_res) {
|
|
||||||
let tabsData = custome_res.toJSON();
|
|
||||||
CustomTabList.push(tabsData);
|
|
||||||
if (tabsData[`${props.schema.data.ParentFolderField}`]) {
|
|
||||||
tabsRes = tabsData[`${props.schema.data.ParentFolderField}`];
|
|
||||||
looping = true;
|
|
||||||
} else {
|
|
||||||
looping = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (looping);
|
|
||||||
}
|
|
||||||
let url = "Folders";
|
|
||||||
CustomTabList.length > 0 &&
|
|
||||||
CustomTabList.reverse().forEach(
|
|
||||||
(t) => (url = url + " / " + t[props.schema.data.FolderNameField])
|
|
||||||
);
|
|
||||||
setTabURL(url);
|
|
||||||
setSelectedFolder({
|
|
||||||
Topic: resultJson[`${props.schema.data.FolderNameField}`],
|
|
||||||
description: resultJson[`${props.schema.data.FolderDescription}`]
|
|
||||||
});
|
|
||||||
setTabList(CustomTabList);
|
|
||||||
props.onChange(resultJson.objectId);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSubmit = async ({ formData }) => {
|
|
||||||
setLoader(true);
|
|
||||||
|
|
||||||
try {
|
|
||||||
let RowData = formData;
|
|
||||||
let _scanData = schemaState;
|
|
||||||
Object.keys(_scanData).forEach(function (key) {
|
|
||||||
let _dd = _scanData[key];
|
|
||||||
Object.keys(_dd).forEach(function (k) {
|
|
||||||
if (_dd[k].component === "AutoSuggest" && _dd[k].isPointer) {
|
|
||||||
let pointer = {
|
|
||||||
__type: "Pointer",
|
|
||||||
className: _dd[k].class,
|
|
||||||
objectId: RowData[k]
|
|
||||||
};
|
|
||||||
RowData[k] = pointer;
|
|
||||||
}
|
|
||||||
if (_dd[k].format === "date") {
|
|
||||||
let newdate = new Date(RowData[k]);
|
|
||||||
RowData[k] = newdate;
|
|
||||||
}
|
|
||||||
if (_dd[k].component === "DateTime") {
|
|
||||||
let newDate11;
|
|
||||||
if (!RowData[k]) {
|
|
||||||
newDate11 = new Date();
|
|
||||||
} else {
|
|
||||||
newDate11 = new Date(RowData[k]);
|
|
||||||
}
|
|
||||||
RowData[k] = newDate11;
|
|
||||||
}
|
|
||||||
if (_dd[k].component === "CurrencyInput") {
|
|
||||||
if (_dd[k].currencyColumn) {
|
|
||||||
RowData[`${_dd[k].currencyColumn}`] = _dd[k].defaultcurrency;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_dd[k].data !== undefined) {
|
|
||||||
if (_dd[k].data.isPointer) {
|
|
||||||
let pointer = {};
|
|
||||||
if (RowData[k] && RowData[k] !== "Select") {
|
|
||||||
if (_dd[k].data.class) {
|
|
||||||
if (RowData[k]) {
|
|
||||||
pointer = {
|
|
||||||
__type: "Pointer",
|
|
||||||
className: _dd[k].data.class,
|
|
||||||
objectId: RowData[k]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pointer = {
|
|
||||||
__type: "Pointer",
|
|
||||||
className: localStorage.getItem("extended_class"),
|
|
||||||
objectId: RowData[k]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
RowData[k] = pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_dd[k].data.FolderTypeValue) {
|
|
||||||
let obj = {
|
|
||||||
__type: "Pointer",
|
|
||||||
className: _dd[k].data.ClassName,
|
|
||||||
objectId: RowData[k]
|
|
||||||
};
|
|
||||||
RowData[k] = obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_dd[k].type === "string") {
|
|
||||||
let d = RowData[k];
|
|
||||||
if (typeof d === "string") {
|
|
||||||
RowData[k] = d.trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
Parse.serverURL = parseBaseUrl;
|
|
||||||
Parse.initialize(parseAppId);
|
|
||||||
|
|
||||||
var forms = Parse.Object.extend(className);
|
|
||||||
var folder = new forms();
|
|
||||||
folder.set(
|
|
||||||
props.schema.data.FolderNameField,
|
|
||||||
formData[props.schema.data.FolderNameField]
|
|
||||||
);
|
|
||||||
if (props.schema.data.FolderDescription) {
|
|
||||||
folder.set(
|
|
||||||
props.schema.data.FolderDescription,
|
|
||||||
formData[props.schema.data.FolderDescription]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
folder.set("AppId", appId);
|
|
||||||
folder.set(
|
|
||||||
props.schema.data.FolderTypeField,
|
|
||||||
props.schema.data.FolderTypeValue
|
|
||||||
);
|
|
||||||
const currentUser = Parse.User.current();
|
|
||||||
folder.set("CreatedBy", Parse.User.createWithoutData(currentUser.id));
|
|
||||||
if (tabList.length > 0) {
|
|
||||||
let len = tabList.length - 1;
|
|
||||||
folder.set(props.schema.data.ParentFolderField, {
|
|
||||||
__type: "Pointer",
|
|
||||||
className: props.schema.data.ClassName,
|
|
||||||
objectId: tabList[len]["objectId"]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
folder.save(RowData).then(
|
|
||||||
(result) => {
|
|
||||||
RowData = {};
|
|
||||||
if (result) {
|
|
||||||
setIsAddField(false);
|
|
||||||
setLoader(false);
|
|
||||||
if (tabList.length > 0) {
|
|
||||||
let len = tabList.length - 1;
|
|
||||||
selectedItemList(tabList[len]);
|
|
||||||
} else {
|
|
||||||
selectFolderHandle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
console.log("error ", error);
|
|
||||||
setLoader(false);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
setLoader(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (props.formData) {
|
|
||||||
editFolderDisplay(props.formData);
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line
|
|
||||||
}, [props.formData]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (defaultState) {
|
|
||||||
selectFolderHandle();
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line
|
|
||||||
}, [defaultState]);
|
|
||||||
const customStyles = {
|
|
||||||
content: {
|
|
||||||
top: "50%",
|
|
||||||
left: "50%",
|
|
||||||
right: "auto",
|
|
||||||
bottom: "auto",
|
|
||||||
marginRight: "-50%",
|
|
||||||
transform: "translate(-50%, -50%)",
|
|
||||||
backgroundColor: "white",
|
|
||||||
padding: 0
|
|
||||||
},
|
|
||||||
overlay: {
|
|
||||||
width: "100%",
|
|
||||||
backgroundColor: "rgba(0, 0, 0, 0.75)",
|
|
||||||
zIndex: 50
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<LabelField
|
|
||||||
Title={props.schema.title}
|
|
||||||
Name={props.name}
|
|
||||||
Required={props.required}
|
|
||||||
HelpBody={props.schema.helpbody}
|
|
||||||
HelpLink={props.schema.helplink}
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
<div className="block max-w-sm bg-white border border-gray-200 shadow hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700">
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
color: "black",
|
|
||||||
fontWeight: "bold",
|
|
||||||
fontSize: "13px",
|
|
||||||
padding: "2%",
|
|
||||||
alignItems: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div style={{ width: "20%" }}>
|
|
||||||
<div
|
|
||||||
className="pull-left"
|
|
||||||
title="Select Folder"
|
|
||||||
style={{
|
|
||||||
color: "#33bbff",
|
|
||||||
margin: "auto",
|
|
||||||
padding: "10px 10px",
|
|
||||||
textAlign: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="far fa-folder-open"
|
|
||||||
style={{ fontSize: "40px" }}
|
|
||||||
aria-hidden="true"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style={{ margin: "0px 10px 0 20px", width: "80%" }}>
|
|
||||||
<div>
|
|
||||||
{selectedFolder && selectedFolder.Topic
|
|
||||||
? selectedFolder.Topic
|
|
||||||
: "Root"}
|
|
||||||
<i
|
|
||||||
className="fa fa-pencil"
|
|
||||||
title="Select Folder"
|
|
||||||
style={{ fontSize: 17, cursor: "pointer", marginLeft: 12 }}
|
|
||||||
onClick={selectFolderHandle}
|
|
||||||
></i>
|
|
||||||
{selectedFolder && (
|
|
||||||
<a
|
|
||||||
className="pull-right"
|
|
||||||
onClick={() => {
|
|
||||||
setSelectedFolder(undefined);
|
|
||||||
setTabURL(undefined);
|
|
||||||
props.onChange(undefined);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-times-circle-o"
|
|
||||||
aria-hidden="true"
|
|
||||||
style={{ fontSize: 17 }}
|
|
||||||
></i>
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{TabURL && (
|
|
||||||
<div
|
|
||||||
style={{ fontSize: "10px", color: "gray", fontWeight: "bold" }}
|
|
||||||
>
|
|
||||||
({TabURL})
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/* save document in folder and add new folder modal */}
|
|
||||||
<Modal
|
|
||||||
isOpen={isShowModal}
|
|
||||||
onRequestClose={() => setIsShowModal(false)}
|
|
||||||
shouldCloseOnOverlayClick={false}
|
|
||||||
contentLabel="Modal"
|
|
||||||
style={customStyles}
|
|
||||||
>
|
|
||||||
<div className="w-full min-w-[300px] md:min-w-[500px]">
|
|
||||||
{/* header */}
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
alignItems: "center",
|
|
||||||
backgroundColor: "rgba(203, 200, 200, 0.09)"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div style={{ padding: "10px" }}>
|
|
||||||
<h4 className=" text-black">Select Folder</h4>
|
|
||||||
</div>
|
|
||||||
<div style={{ padding: "10px" }}>
|
|
||||||
<button
|
|
||||||
className="btn btn-sm pull-right"
|
|
||||||
data-dismiss="modal"
|
|
||||||
title="Select Folder"
|
|
||||||
style={{
|
|
||||||
width: "auto",
|
|
||||||
backgroundColor: "white",
|
|
||||||
border: "1px solid gray",
|
|
||||||
boxshadow: "rgba(100, 100, 111, 0.2) 0px 7px 29px 0px"
|
|
||||||
}}
|
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
setIsAddField(false);
|
|
||||||
setFolderList([]);
|
|
||||||
setEditable(false);
|
|
||||||
if (!props.formData) {
|
|
||||||
setTabList([]);
|
|
||||||
}
|
|
||||||
setIsShowModal(false);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr />
|
|
||||||
{/* body */}
|
|
||||||
<div className="p-3 space-y-6">
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
color: "#ac4848",
|
|
||||||
cursor: "pointer",
|
|
||||||
fontSize: "14px",
|
|
||||||
fontWeight: "500"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
onClick={() => {
|
|
||||||
setTabList([]);
|
|
||||||
setIsAddField(false);
|
|
||||||
setDefaultState(true);
|
|
||||||
setEditable(false);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Folders
|
|
||||||
</a>
|
|
||||||
{" / "}
|
|
||||||
|
|
||||||
{tabList &&
|
|
||||||
tabList.map((tab, i) => (
|
|
||||||
<React.Fragment key={`${tab.objectId}-${i}`}>
|
|
||||||
<a
|
|
||||||
title={tab[`${props.schema.data.FolderNameField}`]}
|
|
||||||
onClick={(e) => removeTabListItem(e, i)}
|
|
||||||
>
|
|
||||||
{tab[`${props.schema.data.FolderNameField}`]}
|
|
||||||
</a>
|
|
||||||
{" / "}
|
|
||||||
</React.Fragment>
|
|
||||||
))}
|
|
||||||
<hr />
|
|
||||||
</div>
|
|
||||||
{/* {editable && (
|
|
||||||
<TreeEditForm
|
|
||||||
FormId={props.schema.data.FormId}
|
|
||||||
objectId={editId}
|
|
||||||
HideView={(cl) => {
|
|
||||||
setEditable(cl);
|
|
||||||
selectFolderHandle();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)} */}
|
|
||||||
{isAddField && !loader && !editable && (
|
|
||||||
<TreeFormComponent
|
|
||||||
Id={props.schema.data.FormId}
|
|
||||||
handleSubmit={handleSubmit}
|
|
||||||
ParentField={props.schema.parent && props.schema.parent}
|
|
||||||
ParentValue={props.schema.parent && props.parent}
|
|
||||||
ChildField={props.child && props.child}
|
|
||||||
ClassName={(cls) => setClassName(cls)}
|
|
||||||
SchemaState={(cls) => setSchemaState(cls)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{loader && (
|
|
||||||
<div
|
|
||||||
className="loader-01"
|
|
||||||
style={{
|
|
||||||
marginTop: "50px",
|
|
||||||
marginLeft: "50%",
|
|
||||||
color: "rgb(0,28,28)",
|
|
||||||
fontSize: "35px"
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{!isAddField && !editable && (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
maxHeight: "280px",
|
|
||||||
overflowY: "auto",
|
|
||||||
marginTop: "5px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ul>
|
|
||||||
{folderList &&
|
|
||||||
folderList.map(
|
|
||||||
(fldr) =>
|
|
||||||
fldr[props.schema.data.FolderTypeField] ===
|
|
||||||
props.schema.data.FolderTypeValue && (
|
|
||||||
<li
|
|
||||||
key={`${fldr.objectId}`}
|
|
||||||
style={{
|
|
||||||
listStyle: "none",
|
|
||||||
padding: "10px 20px",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
fontWeight: 300,
|
|
||||||
border: "1px solid gray",
|
|
||||||
borderRadius: "1px",
|
|
||||||
marginTop: "8px",
|
|
||||||
transition: "all 0.75s ease",
|
|
||||||
WebkitTransition: "all 0.5s ease",
|
|
||||||
MozTransition: "all 0.5s ease",
|
|
||||||
MsTransition: "all 0.5s ease",
|
|
||||||
OTransition: "all 0.5 ease",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "space-between"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className={"fa fa-folder"}
|
|
||||||
style={{
|
|
||||||
fontSize: "1.4rem",
|
|
||||||
color: "skyblue"
|
|
||||||
}}
|
|
||||||
aria-hidden="true"
|
|
||||||
></i>
|
|
||||||
<a
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
fontSize: "12px",
|
|
||||||
marginLeft: "4px",
|
|
||||||
cursor: "pointer"
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
setTabList((tabs) => tabs.concat(fldr));
|
|
||||||
selectedItemList(fldr);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{fldr[`${props.schema.data.FolderNameField}`]}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* {fldr[props.schema.data.FolderTypeField] ===
|
|
||||||
props.schema.data.FolderTypeValue && (
|
|
||||||
<a
|
|
||||||
className="float-right"
|
|
||||||
onClick={() => {
|
|
||||||
setEditable(true);
|
|
||||||
setEditId(fldr.objectId);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className={"fa fa-pencil"}
|
|
||||||
title={"Edit Folder"}
|
|
||||||
style={{
|
|
||||||
fontSize: "0.9rem",
|
|
||||||
color: "purple",
|
|
||||||
cursor: "pointer"
|
|
||||||
}}
|
|
||||||
aria-hidden="true"
|
|
||||||
></i>
|
|
||||||
</a>
|
|
||||||
)} */}
|
|
||||||
</li>
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{/* footer */}
|
|
||||||
|
|
||||||
<div className="flex items-center p-3 space-x-2 border-t border-gray-200 rounded-b dark:border-gray-600 justify-between">
|
|
||||||
<button
|
|
||||||
className="btn btn-sm float-left createFolder"
|
|
||||||
title="Create New Folder"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
setIsAddField(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
<i
|
|
||||||
className="fa fa-plus"
|
|
||||||
style={{ fontSize: "1.5rem" }}
|
|
||||||
aria-hidden="true"
|
|
||||||
></i>
|
|
||||||
</button>
|
|
||||||
{!isAddField && !editable && (
|
|
||||||
<div className="flex">
|
|
||||||
{tabList.length > 0 && (
|
|
||||||
<button
|
|
||||||
className="btn btn-sm float-right deleteFolder"
|
|
||||||
title="Delete Folder"
|
|
||||||
onClick={onDeleteFolder}
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
<i
|
|
||||||
className="fa fa-trash"
|
|
||||||
style={{ fontSize: "1rem" }}
|
|
||||||
aria-hidden="true"
|
|
||||||
></i>
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
<button
|
|
||||||
className="btn btn-sm float-right saveFolder"
|
|
||||||
title="Save Here"
|
|
||||||
onClick={onSubmitResult}
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
{/* <i
|
|
||||||
className="fa fa-floppy-o"
|
|
||||||
style={{ fontSize: "2rem" }}
|
|
||||||
aria-hidden="true"
|
|
||||||
></i> */}
|
|
||||||
<i
|
|
||||||
className="fas fa-save"
|
|
||||||
aria-hidden="true"
|
|
||||||
style={{ fontSize: "20px" }}
|
|
||||||
></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapStateToProps = (state) => {
|
|
||||||
return {
|
|
||||||
parent: state.Level1_Dropdown,
|
|
||||||
child: state.Level2_Dropdown
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default connect(mapStateToProps)(TreeWidget);
|
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import Parse from "parse";
|
||||||
|
import Alert from "../../primitives/Alert";
|
||||||
|
|
||||||
|
const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => {
|
||||||
|
const folderPtr = {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: folderCls,
|
||||||
|
objectId: parentFolderId
|
||||||
|
};
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
const [folderList, setFolderList] = useState([]);
|
||||||
|
const [isAlert, setIsAlert] = useState(false);
|
||||||
|
const [selectedParent, setSelectedParent] = useState();
|
||||||
|
const [alert, setAlert] = useState({ type: "info", message: "" });
|
||||||
|
useEffect(() => {
|
||||||
|
fetchFolder();
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const fetchFolder = async () => {
|
||||||
|
try {
|
||||||
|
const FolderQuery = new Parse.Query(folderCls);
|
||||||
|
if (parentFolderId) {
|
||||||
|
FolderQuery.equalTo("Folder", folderPtr);
|
||||||
|
FolderQuery.equalTo("Type", "Folder");
|
||||||
|
} else {
|
||||||
|
FolderQuery.doesNotExist("Folder");
|
||||||
|
FolderQuery.equalTo("Type", "Folder");
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await FolderQuery.find();
|
||||||
|
if (res) {
|
||||||
|
const result = JSON.parse(JSON.stringify(res));
|
||||||
|
if (result) {
|
||||||
|
setFolderList(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Err ", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleCreateFolder = async (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
if (name) {
|
||||||
|
const currentUser = Parse.User.current();
|
||||||
|
const exsitQuery = new Parse.Query(folderCls);
|
||||||
|
exsitQuery.equalTo("Name", name);
|
||||||
|
exsitQuery.equalTo("Type", "Folder");
|
||||||
|
if (parentFolderId) {
|
||||||
|
exsitQuery.equalTo("Folder", folderPtr);
|
||||||
|
}
|
||||||
|
const templExist = await exsitQuery.first();
|
||||||
|
if (templExist) {
|
||||||
|
setAlert({ type: "dange", message: "Folder already exist!" });
|
||||||
|
setIsAlert(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsAlert(false);
|
||||||
|
}, 1000);
|
||||||
|
} else {
|
||||||
|
const template = new Parse.Object(folderCls);
|
||||||
|
template.set("Name", name);
|
||||||
|
template.set("Type", "Folder");
|
||||||
|
|
||||||
|
if (selectedParent) {
|
||||||
|
template.set("Folder", {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: folderCls,
|
||||||
|
objectId: selectedParent
|
||||||
|
});
|
||||||
|
} else if (parentFolderId) {
|
||||||
|
template.set("Folder", folderPtr);
|
||||||
|
}
|
||||||
|
template.set("CreatedBy", Parse.User.createWithoutData(currentUser.id));
|
||||||
|
const res = await template.save();
|
||||||
|
if (res) {
|
||||||
|
setAlert({
|
||||||
|
type: "success",
|
||||||
|
message: "Folder created successfully!"
|
||||||
|
});
|
||||||
|
setIsAlert(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsAlert(false);
|
||||||
|
}, 1000);
|
||||||
|
if (onSuccess) {
|
||||||
|
onSuccess(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setAlert({ type: "info", message: "Please fill folder name" });
|
||||||
|
setIsAlert(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsAlert(false);
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleOptions = (e) => {
|
||||||
|
setSelectedParent(e.target.value);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{isAlert && <Alert type={alert.type}>{alert.message}</Alert>}
|
||||||
|
<div id="createFolder">
|
||||||
|
<h1 className="text-base font-semibold">Create Folder</h1>
|
||||||
|
<div className="text-xs mt-2">
|
||||||
|
<label className="block">
|
||||||
|
Name<span className="text-red-500 text-[13px]">*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||||
|
value={name}
|
||||||
|
onChange={(e) => setName(e.target.value)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="text-xs mt-2">
|
||||||
|
<label className="block">Parent Folder</label>
|
||||||
|
<select
|
||||||
|
value={selectedParent}
|
||||||
|
onChange={handleOptions}
|
||||||
|
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||||
|
>
|
||||||
|
<option>select</option>
|
||||||
|
{folderList.length > 0 &&
|
||||||
|
folderList.map((x) => (
|
||||||
|
<option key={x.objectId} value={x.objectId}>
|
||||||
|
{x.Name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
onClick={handleCreateFolder}
|
||||||
|
className="flex items-center rounded p-2 bg-[#32a3ac] text-white mt-3"
|
||||||
|
>
|
||||||
|
<i className="fa-solid fa-plus mr-1"></i>
|
||||||
|
<span>Create</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CreateFolder;
|
||||||
@@ -41,7 +41,8 @@ export default function DropboxChooser({ children, onSuccess, onCancel }) {
|
|||||||
[onSuccess, onCancel]
|
[onSuccess, onCancel]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleChoose = useCallback(() => {
|
const handleChoose = useCallback((e) => {
|
||||||
|
e.preventDefault()
|
||||||
if (window.Dropbox) {
|
if (window.Dropbox) {
|
||||||
window.Dropbox.choose(options);
|
window.Dropbox.choose(options);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,308 +0,0 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
|
||||||
import { SaveFileSize } from "../../constant/saveFileSize";
|
|
||||||
import Parse from "parse";
|
|
||||||
import sanitizeFileName from "../../primitives/sanitizeFileName";
|
|
||||||
import DropboxChooser from "./DropboxChoose";
|
|
||||||
const FileUpload = (props) => {
|
|
||||||
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
|
||||||
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
|
||||||
const [_fileupload, setFileUpload] = useState("");
|
|
||||||
const [fileload, setfileload] = useState(false);
|
|
||||||
const [Message] = useState(false);
|
|
||||||
const [percentage, setpercentage] = useState(0);
|
|
||||||
|
|
||||||
const REQUIRED_FIELD_SYMBOL = "*";
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!props.formData) {
|
|
||||||
setFileUpload([]);
|
|
||||||
props.onChange(undefined);
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line
|
|
||||||
}, [props.formData]);
|
|
||||||
const onChange = (e) => {
|
|
||||||
try {
|
|
||||||
let files = e.target.files;
|
|
||||||
if (typeof files[0] !== "undefined") {
|
|
||||||
if (props.schema.filetypes && props.schema.filetypes.length > 0) {
|
|
||||||
var fileName = files[0].name;
|
|
||||||
var fileNameExt = fileName
|
|
||||||
.substr(fileName.lastIndexOf(".") + 1)
|
|
||||||
.toLowerCase();
|
|
||||||
let Extensions = props.schema.filetypes.map((x) => x.toLowerCase());
|
|
||||||
let arr = Extensions.filter((x) => x === fileNameExt);
|
|
||||||
if (arr.length > 0) {
|
|
||||||
console.log("multiple type");
|
|
||||||
} else {
|
|
||||||
alert(
|
|
||||||
"Only these file types are accepted : " + Extensions.join(", ")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (props.schema.maxfilesizeKB && props.schema.maxfilesizeKB !== "") {
|
|
||||||
// console.log(Math.round(files[0].size / 1024));
|
|
||||||
if (
|
|
||||||
Math.round(Number(files[0].size) / 1024) >=
|
|
||||||
props.schema.maxfilesizeKB
|
|
||||||
) {
|
|
||||||
alert(
|
|
||||||
`The selected file size is too large. Please select a file less than ${Math.round(
|
|
||||||
props.schema.maxfilesizeKB / 1024
|
|
||||||
)} MB`
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
handleFileUpload(files[0]);
|
|
||||||
} else {
|
|
||||||
alert("Please select file.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
alert(error.message);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleFileUpload = async (file) => {
|
|
||||||
Parse.serverURL = parseBaseUrl;
|
|
||||||
Parse.initialize(parseAppId);
|
|
||||||
setfileload(true);
|
|
||||||
const size = file.size;
|
|
||||||
const fileName = file.name;
|
|
||||||
const name = sanitizeFileName(fileName);
|
|
||||||
const pdfFile = file;
|
|
||||||
const parseFile = new Parse.File(name, pdfFile);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await parseFile.save({
|
|
||||||
progress: (progressValue, loaded, total, { type }) => {
|
|
||||||
if (type === "upload" && progressValue !== null) {
|
|
||||||
const percentCompleted = Math.round((loaded * 100) / total);
|
|
||||||
// console.log("percentCompleted ", percentCompleted);
|
|
||||||
setpercentage(percentCompleted);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
setFileUpload(response.url());
|
|
||||||
props.onChange(response.url());
|
|
||||||
setfileload(false);
|
|
||||||
// The response object will contain information about the uploaded file
|
|
||||||
// console.log("File uploaded:", response);
|
|
||||||
|
|
||||||
// You can access the URL of the uploaded file using response.url()
|
|
||||||
// console.log("File URL:", response.url());
|
|
||||||
if (response.url()) {
|
|
||||||
SaveFileSize(size, response.url());
|
|
||||||
return response.url();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
setfileload(false);
|
|
||||||
setpercentage(0);
|
|
||||||
console.error("Error uploading file:", error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const dropboxSuccess = async (files) => {
|
|
||||||
// console.log("file ", files);
|
|
||||||
setfileload(true);
|
|
||||||
const file = files[0];
|
|
||||||
const url = file.link;
|
|
||||||
const size = file.bytes;
|
|
||||||
const mb = Math.round(file.bytes / Math.pow(1024, 2));
|
|
||||||
|
|
||||||
if (mb > 10) {
|
|
||||||
setTimeout(() => {
|
|
||||||
alert(
|
|
||||||
`The selected file size is too large. Please select a file less than 10 MB`
|
|
||||||
);
|
|
||||||
}, 500);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
const name = sanitizeFileName(file.name);
|
|
||||||
|
|
||||||
const parseFile = new Parse.File(name, { uri: url });
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await parseFile.save({
|
|
||||||
progress: (progressValue, loaded, total, { type }) => {
|
|
||||||
if (type === "upload" && progressValue !== null) {
|
|
||||||
const percentCompleted = Math.round((loaded * 100) / total);
|
|
||||||
// console.log("percentCompleted ", percentCompleted);
|
|
||||||
setpercentage(percentCompleted);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// console.log("response.url() ", response.url());
|
|
||||||
setFileUpload(response.url());
|
|
||||||
props.onChange(response.url());
|
|
||||||
setfileload(false);
|
|
||||||
|
|
||||||
if (response.url()) {
|
|
||||||
SaveFileSize(size, response.url());
|
|
||||||
return response.url();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
setfileload(false);
|
|
||||||
setpercentage(0);
|
|
||||||
console.error("Error uploading file:", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const dropboxCancel = async () => {
|
|
||||||
console.log("cancel clicked ");
|
|
||||||
};
|
|
||||||
let fileView =
|
|
||||||
props.formData &&
|
|
||||||
props.schema.uploadtype === "s3viajw" ? null : props.formData &&
|
|
||||||
props.formData ? (
|
|
||||||
<React.Fragment>
|
|
||||||
<a
|
|
||||||
href={props.formData}
|
|
||||||
title={props.formData}
|
|
||||||
style={{ paddingBottom: "10px", color: "blue" }}
|
|
||||||
>
|
|
||||||
Download
|
|
||||||
</a>
|
|
||||||
</React.Fragment>
|
|
||||||
) : fileload === false ? null : (
|
|
||||||
<React.Fragment>
|
|
||||||
<a
|
|
||||||
href={_fileupload}
|
|
||||||
title={_fileupload}
|
|
||||||
style={{ paddingBottom: "10px" }}
|
|
||||||
>
|
|
||||||
Download
|
|
||||||
</a>
|
|
||||||
<br />
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<div style={{ display: "inline-block" }}>
|
|
||||||
<label htmlFor={props.name}>
|
|
||||||
{props.schema.title}
|
|
||||||
{props.required && (
|
|
||||||
<span className="required">{REQUIRED_FIELD_SYMBOL}</span>
|
|
||||||
)}
|
|
||||||
{fileload ? (
|
|
||||||
<div className="flex items-center gap-x-2">
|
|
||||||
<div className="h-2 rounded-full w-[200px] md:w-[400px] bg-gray-200">
|
|
||||||
<div
|
|
||||||
className="h-2 rounded-full bg-blue-500"
|
|
||||||
style={{ width: `${percentage}%` }}
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
<span className="text-black text-sm">{percentage}%</span>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
Message && (
|
|
||||||
<span style={{ fontSize: "9px", marginLeft: "4px" }}>
|
|
||||||
Processing will take 5-10 mins....
|
|
||||||
</span>
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
{props.schema.helpbody ? (
|
|
||||||
<div className="dropdown pull-right">
|
|
||||||
<i
|
|
||||||
className="far fa-question-circle dropdown-toggle hovereffect"
|
|
||||||
aria-hidden="true"
|
|
||||||
id="dropdownMenuButton"
|
|
||||||
data-toggle="dropdown"
|
|
||||||
aria-haspopup="true"
|
|
||||||
aria-expanded="false"
|
|
||||||
style={{
|
|
||||||
fontSize: "12px",
|
|
||||||
color: "purple",
|
|
||||||
cursor: "pointer !important",
|
|
||||||
position: "relative",
|
|
||||||
bottom: "0px",
|
|
||||||
left: "0px",
|
|
||||||
paddingBottom: "4px",
|
|
||||||
paddingLeft: "4px"
|
|
||||||
}}
|
|
||||||
></i>
|
|
||||||
<div
|
|
||||||
className="dropdown-menu"
|
|
||||||
aria-labelledby="dropdownMenuButton"
|
|
||||||
style={{
|
|
||||||
marginleft: "-121px",
|
|
||||||
margintop: "-14px",
|
|
||||||
position: "absolute",
|
|
||||||
padding: "10px",
|
|
||||||
top: "102px!important"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<br />
|
|
||||||
{props.schema.helplink ? (
|
|
||||||
<a
|
|
||||||
href={props.schema.helplink}
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
className="btn btn-xs btn-primary"
|
|
||||||
>
|
|
||||||
Read more..
|
|
||||||
</a>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
<span style={{ marginLeft: "10px" }}>{fileView}</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<>
|
|
||||||
{props.formData ? (
|
|
||||||
<div className="flex gap-2 justify-center items-center">
|
|
||||||
<div className="flex justify-between items-center px-2 py-[3px] w-full font-bold rounded border-[1px] border-[#ccc] text-gray-500 bg-white text-[13px]">
|
|
||||||
<div className="break-all">
|
|
||||||
file selected : {props.formData.split("/")[3]}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
onClick={() => {
|
|
||||||
console.log("clicked");
|
|
||||||
setFileUpload([]);
|
|
||||||
props.onChange(undefined);
|
|
||||||
}}
|
|
||||||
className="cursor-pointer px-[10px] text-[20px] font-bold bg-white text-red-500"
|
|
||||||
>
|
|
||||||
<i className="fa-solid fa-xmark"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<DropboxChooser
|
|
||||||
onSuccess={dropboxSuccess}
|
|
||||||
onCancel={dropboxCancel}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="flex gap-2 justify-center items-center">
|
|
||||||
<input
|
|
||||||
type="file"
|
|
||||||
id="hashfile"
|
|
||||||
style={{
|
|
||||||
border: "1px solid #ccc",
|
|
||||||
color: "gray",
|
|
||||||
backgroundColor: "white",
|
|
||||||
padding: "5px 10px",
|
|
||||||
borderRadius: "4px",
|
|
||||||
fontSize: "13px",
|
|
||||||
width: "100%",
|
|
||||||
fontWeight: "bold"
|
|
||||||
}}
|
|
||||||
accept="application/pdf,application/vnd.ms-excel"
|
|
||||||
onChange={onChange}
|
|
||||||
/>
|
|
||||||
<DropboxChooser
|
|
||||||
onSuccess={dropboxSuccess}
|
|
||||||
onCancel={dropboxCancel}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default FileUpload;
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
import React, { Component } from "react";
|
|
||||||
import Parse from "parse";
|
|
||||||
// import axios from "axios";
|
|
||||||
|
|
||||||
export class HiddenField extends Component {
|
|
||||||
state = {
|
|
||||||
baseUrl: localStorage.getItem("baseUrl"),
|
|
||||||
parseAppId: localStorage.getItem("parseAppId"),
|
|
||||||
_fields: ""
|
|
||||||
};
|
|
||||||
loadData = async () => {
|
|
||||||
if (this.props.schema.default) {
|
|
||||||
this.setState({ _fields: this.props.schema.default });
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
Parse.serverURL = this.state.baseUrl;
|
|
||||||
Parse.initialize(this.state.parseAppId);
|
|
||||||
let currentUser = await Parse.User.current();
|
|
||||||
if (localStorage.getItem("Extand_Class")) {
|
|
||||||
let _rdata = JSON.parse(localStorage.getItem("Extand_Class"));
|
|
||||||
let custome_Filed = "";
|
|
||||||
let splitArray = this.props.schema.data.valueKey.split(".");
|
|
||||||
if (splitArray.length > 1) {
|
|
||||||
custome_Filed = _rdata[0][splitArray[0]][splitArray[1]];
|
|
||||||
} else {
|
|
||||||
let _Filed = _rdata[0][splitArray[0]];
|
|
||||||
if (typeof _Filed === "object") {
|
|
||||||
custome_Filed = {
|
|
||||||
__type: "Pointer",
|
|
||||||
className: _Filed["className"],
|
|
||||||
objectId: _Filed["objectId"]
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
custome_Filed = _rdata[0][splitArray[0]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.setState({ _fields: custome_Filed });
|
|
||||||
} else {
|
|
||||||
if (currentUser) {
|
|
||||||
// let url = `${this.state.baseUrl}classes/${localStorage.getItem(
|
|
||||||
// "extended_class"
|
|
||||||
// )}?where={"UserId":{"__type":"Pointer","className":"_User","objectId":"${
|
|
||||||
// currentUser.id
|
|
||||||
// }"}}&keys=${this.props.schema.data.valueKey}`;
|
|
||||||
// const headers = {
|
|
||||||
// "Content-Type": "application/json",
|
|
||||||
// "X-Parse-Application-Id": this.state.parseAppId
|
|
||||||
// };
|
|
||||||
// await axios.get(url, { headers: headers }).then((res) => {
|
|
||||||
// let custome_Filed = "";
|
|
||||||
// let _rdata = res.data.results;
|
|
||||||
// let splitArray = this.props.schema.data.valueKey.split(".");
|
|
||||||
// if (splitArray.length > 1) {
|
|
||||||
// custome_Filed = _rdata[0][splitArray[0]][splitArray[1]];
|
|
||||||
// } else {
|
|
||||||
// console.log(_rdata[0][splitArray[0]]);
|
|
||||||
// custome_Filed = _rdata[0][splitArray[0]];
|
|
||||||
// }
|
|
||||||
// this.setState({ _fields: custome_Filed });
|
|
||||||
// });
|
|
||||||
|
|
||||||
const res = await Parse.Cloud.run("getUserDetails", {
|
|
||||||
email: currentUser.get("email")
|
|
||||||
});
|
|
||||||
let custome_Filed = "";
|
|
||||||
const result = res.toJSON();
|
|
||||||
let _rdata = [result];
|
|
||||||
let splitArray = this.props.schema.data.valueKey.split(".");
|
|
||||||
if (splitArray.length > 1) {
|
|
||||||
custome_Filed = _rdata[0][splitArray[0]][splitArray[1]];
|
|
||||||
} else {
|
|
||||||
console.log(_rdata[0][splitArray[0]]);
|
|
||||||
custome_Filed = _rdata[0][splitArray[0]];
|
|
||||||
}
|
|
||||||
this.setState({ _fields: custome_Filed });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log("err", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
componentDidMount() {
|
|
||||||
this.loadData();
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<input
|
|
||||||
type="hidden"
|
|
||||||
value={this.state._fields}
|
|
||||||
onChange={this.props.onChange(this.state._fields)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default HiddenField;
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import parse from "html-react-parser";
|
|
||||||
import PropTypes from "prop-types";
|
|
||||||
|
|
||||||
const LabelField = (props) => {
|
|
||||||
const { Title, Name, Required, HelpBody, HelpLink } = props;
|
|
||||||
const REQUIRED_FIELD_SYMBOL = "*";
|
|
||||||
return (
|
|
||||||
<div style={{ display: "inline-block" }}>
|
|
||||||
<label htmlFor={Name}>
|
|
||||||
{Title}
|
|
||||||
{Required && <span className="required">{REQUIRED_FIELD_SYMBOL}</span>}
|
|
||||||
{HelpBody ? (
|
|
||||||
<div className="dropdown pull-right">
|
|
||||||
<i
|
|
||||||
className="far fa-question-circle dropdown-toggle hovereffect pull-right"
|
|
||||||
aria-hidden="true"
|
|
||||||
id="dropdownMenuButton"
|
|
||||||
data-toggle="dropdown"
|
|
||||||
aria-haspopup="true"
|
|
||||||
aria-expanded="false"
|
|
||||||
style={{
|
|
||||||
fontSize: "12px",
|
|
||||||
color: "purple",
|
|
||||||
cursor: "pointer !important",
|
|
||||||
position: "relative",
|
|
||||||
bottom: "0px",
|
|
||||||
left: "0px",
|
|
||||||
paddingBottom: "4px",
|
|
||||||
paddingLeft: "4px"
|
|
||||||
}}
|
|
||||||
></i>
|
|
||||||
<div
|
|
||||||
className="dropdown-menu"
|
|
||||||
aria-labelledby="dropdownMenuButton"
|
|
||||||
style={{
|
|
||||||
marginleft: "-121px",
|
|
||||||
margintop: "-14px",
|
|
||||||
position: "absolute",
|
|
||||||
padding: "10px",
|
|
||||||
top: "102px!important"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{parse(`
|
|
||||||
${HelpBody}
|
|
||||||
`)}
|
|
||||||
<br />
|
|
||||||
{HelpLink ? (
|
|
||||||
<a
|
|
||||||
href={HelpLink}
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
className="btn btn-xs btn-primary"
|
|
||||||
>
|
|
||||||
Read more..
|
|
||||||
</a>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
LabelField.propTypes = {
|
|
||||||
Name: PropTypes.string.isRequired,
|
|
||||||
Title: PropTypes.string.isRequired
|
|
||||||
};
|
|
||||||
export default LabelField;
|
|
||||||
@@ -1,482 +0,0 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { connect } from "react-redux";
|
|
||||||
import { onChangeLevel1Dropdown } from "../../redux/actions/index";
|
|
||||||
import axios from "axios";
|
|
||||||
import Parse from "parse";
|
|
||||||
import parse from "html-react-parser";
|
|
||||||
|
|
||||||
const Level1Dropdown = (props) => {
|
|
||||||
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
|
||||||
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
|
||||||
const [Level1_DD, setLevel1_DD] = useState([]);
|
|
||||||
const [toastColor] = useState("#d9534f");
|
|
||||||
const [toastDescription, setToastDescription] = useState("");
|
|
||||||
const [active, setActive] = useState(false);
|
|
||||||
|
|
||||||
const getParams = (offset) => {
|
|
||||||
const params = {
|
|
||||||
skip: offset
|
|
||||||
};
|
|
||||||
return params;
|
|
||||||
};
|
|
||||||
|
|
||||||
const Level1DropdownData = async () => {
|
|
||||||
try {
|
|
||||||
if (
|
|
||||||
props.formData &&
|
|
||||||
props.uiSchema["ui:disabled"] &&
|
|
||||||
props.formData !== "Select"
|
|
||||||
) {
|
|
||||||
let url = `${parseBaseUrl}classes/${props.schema.data.class}/${props.formData}`;
|
|
||||||
if (typeof props.formData === "object") {
|
|
||||||
url = `${parseBaseUrl}classes/${props.schema.data.class}/${props.formData.objectId}`;
|
|
||||||
}
|
|
||||||
let headers1 = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": parseAppId,
|
|
||||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
|
||||||
};
|
|
||||||
let data = [];
|
|
||||||
let response = [];
|
|
||||||
await axios.get(url, { headers: headers1 }).then((res) => {
|
|
||||||
if (res) {
|
|
||||||
data.push(res.data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (data.length > 0) {
|
|
||||||
let temp = [];
|
|
||||||
data.forEach((x) => {
|
|
||||||
let opt = "";
|
|
||||||
if (Array.isArray(x[props.schema.data.valueKey])) {
|
|
||||||
x[props.schema.data.valueKey].forEach((tt) => {
|
|
||||||
if (typeof tt === "object") {
|
|
||||||
opt = {
|
|
||||||
objectId: tt[props.schema.data.displayKey],
|
|
||||||
option: tt[props.schema.data.displayKey]
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
opt = {
|
|
||||||
objectId: tt,
|
|
||||||
option: tt
|
|
||||||
};
|
|
||||||
}
|
|
||||||
temp.push(opt);
|
|
||||||
});
|
|
||||||
} else if (props.schema.data.isPointer) {
|
|
||||||
if (props.schema.data.valueKey.includes(".")) {
|
|
||||||
let newArr = props.schema.data.valueKey.split(".");
|
|
||||||
if (newArr.length === 2) {
|
|
||||||
opt = {
|
|
||||||
objectId: x[newArr[0]][newArr[1]],
|
|
||||||
option: x[props.schema.data.displayKey]
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
opt = {
|
|
||||||
objectId: x[newArr[0]],
|
|
||||||
option: x[props.schema.data.displayKey]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
opt = {
|
|
||||||
objectId: x[props.schema.data.valueKey],
|
|
||||||
option: x[props.schema.data.displayKey]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
temp.push(opt);
|
|
||||||
} else {
|
|
||||||
opt = {
|
|
||||||
objectId: x[props.schema.data.valueKey],
|
|
||||||
option: x[props.schema.data.displayKey]
|
|
||||||
};
|
|
||||||
temp.push(opt);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
response = temp;
|
|
||||||
setLevel1_DD(response);
|
|
||||||
setActive(false);
|
|
||||||
if (response.length === 1) {
|
|
||||||
props.onChangeLevel1Dropdown(response[0].objectId, props.name);
|
|
||||||
props.onChange(response[0].objectId);
|
|
||||||
} else if (response.length === 0) {
|
|
||||||
props.onChangeLevel1Dropdown("", props.name);
|
|
||||||
props.onChange("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let response = [];
|
|
||||||
setActive(true);
|
|
||||||
Parse.serverURL = parseBaseUrl;
|
|
||||||
Parse.initialize(parseAppId);
|
|
||||||
const currentUser = Parse.User.current();
|
|
||||||
|
|
||||||
// eslint-disable-next-line
|
|
||||||
var reg = /(\#.*?\#)/gi;
|
|
||||||
let str = props.schema.data.query;
|
|
||||||
var test;
|
|
||||||
if (str.includes("#")) {
|
|
||||||
let res;
|
|
||||||
if (localStorage.getItem("Extand_Class")) {
|
|
||||||
let data = JSON.parse(localStorage.getItem("Extand_Class"));
|
|
||||||
res = data[0];
|
|
||||||
} else {
|
|
||||||
const currentUser = Parse.User.current();
|
|
||||||
res = await Parse.Cloud.run("getUserDetails", {
|
|
||||||
email: currentUser.get("email")
|
|
||||||
});
|
|
||||||
if (res) res = res.toJSON();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res) {
|
|
||||||
let json = res;
|
|
||||||
let output = str.match(reg);
|
|
||||||
if (output.length === 1) {
|
|
||||||
output = output.join();
|
|
||||||
output = output.substring(1, output.length - 1);
|
|
||||||
output = output.split(".");
|
|
||||||
if (output.length === 1) {
|
|
||||||
let out = output[0];
|
|
||||||
if (json[out]) {
|
|
||||||
if (typeof json[out] === "object") {
|
|
||||||
test = str.replace(reg, JSON.stringify(json[out]));
|
|
||||||
} else {
|
|
||||||
test = str.replace(reg, json[out]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
test = str.replace(reg, currentUser.id);
|
|
||||||
}
|
|
||||||
} else if (output.length === 2) {
|
|
||||||
let out1 = json[output[0]][output[1]];
|
|
||||||
if (out1) {
|
|
||||||
test = str.replace(reg, out1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (output.length === 2) {
|
|
||||||
let output1 = output[0];
|
|
||||||
output1 = output1.substring(1, output1.length - 1);
|
|
||||||
output1 = output1.split(".");
|
|
||||||
if (output1.length === 1) {
|
|
||||||
let out = output1[0];
|
|
||||||
if (json[out]) {
|
|
||||||
if (typeof json[out] === "object") {
|
|
||||||
str = str.replace(output[0], JSON.stringify(json[out]));
|
|
||||||
} else {
|
|
||||||
str = str.replace(output[0], json[out]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
str = str.replace(output[0], currentUser.id);
|
|
||||||
}
|
|
||||||
} else if (output1.length === 2) {
|
|
||||||
let out1 = json[output1[0]][output1[1]];
|
|
||||||
if (out1) {
|
|
||||||
str = str.replace(output[0], out1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let output2 = output[1];
|
|
||||||
output2 = output2.substring(1, output2.length - 1);
|
|
||||||
output2 = output2.split(".");
|
|
||||||
if (output2.length === 1) {
|
|
||||||
let out = output2[0];
|
|
||||||
if (json[out]) {
|
|
||||||
if (typeof json[out] === "object") {
|
|
||||||
str = str.replace(output[1], JSON.stringify(json[out]));
|
|
||||||
} else {
|
|
||||||
str = str.replace(output[1], json[out]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
str = str.replace(output[1], currentUser.id);
|
|
||||||
}
|
|
||||||
} else if (output2.length === 2) {
|
|
||||||
let out1 = json[output2[0]][output2[1]];
|
|
||||||
if (out1) {
|
|
||||||
str = str.replace(output[1], out1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
test = str;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setToastDescription(
|
|
||||||
`User not found in ${localStorage.getItem("extended_class")}`
|
|
||||||
);
|
|
||||||
setActive(false);
|
|
||||||
var x = document.getElementById("Level_1");
|
|
||||||
x.className = "show";
|
|
||||||
setTimeout(function () {
|
|
||||||
x.className = x.className.replace("show", "");
|
|
||||||
}, 5000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
test = str;
|
|
||||||
}
|
|
||||||
let url = `${parseBaseUrl}classes/${props.schema.data.class}?${test}`;
|
|
||||||
const headers = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": parseAppId,
|
|
||||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
|
||||||
};
|
|
||||||
let fetchCount = 0;
|
|
||||||
let offset = 0;
|
|
||||||
let data = [];
|
|
||||||
/* eslint-disable no-constant-condition */
|
|
||||||
while (true) {
|
|
||||||
const params = getParams(offset);
|
|
||||||
await axios
|
|
||||||
.get(url, { params: params, headers: headers })
|
|
||||||
.then((response) => {
|
|
||||||
fetchCount = response.data.results.length;
|
|
||||||
offset += response.data.results.length;
|
|
||||||
|
|
||||||
if (fetchCount > 0) {
|
|
||||||
response.data.results.forEach((x) => {
|
|
||||||
data.push(x);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error("Problem", err.response);
|
|
||||||
setToastDescription(err.response.data.message);
|
|
||||||
setActive(false);
|
|
||||||
var x = document.getElementById("Level_1");
|
|
||||||
x.className = "show";
|
|
||||||
setTimeout(function () {
|
|
||||||
x.className = x.className.replace("show", "");
|
|
||||||
}, 5000);
|
|
||||||
});
|
|
||||||
if (fetchCount === 0 || fetchCount < 100) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data.length > 0) {
|
|
||||||
let temp = [];
|
|
||||||
data.forEach((x) => {
|
|
||||||
let opt = "";
|
|
||||||
if (Array.isArray(x[props.schema.data.valueKey])) {
|
|
||||||
x[props.schema.data.valueKey].forEach((tt) => {
|
|
||||||
if (typeof tt === "object") {
|
|
||||||
if (props.schema.data.isPointer) {
|
|
||||||
opt = {
|
|
||||||
objectId: tt["objectId"],
|
|
||||||
option: tt[props.schema.data.displayKey]
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
opt = {
|
|
||||||
objectId: tt[props.schema.data.displayKey],
|
|
||||||
option: tt[props.schema.data.displayKey]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
opt = {
|
|
||||||
objectId: tt,
|
|
||||||
option: tt
|
|
||||||
};
|
|
||||||
}
|
|
||||||
temp.push(opt);
|
|
||||||
});
|
|
||||||
} else if (props.schema.data.isPointer) {
|
|
||||||
if (props.schema.data.valueKey.includes(".")) {
|
|
||||||
let newArr = props.schema.data.valueKey.split(".");
|
|
||||||
if (newArr.length === 2) {
|
|
||||||
let _dis = props.schema.data.displayKey.split(".");
|
|
||||||
if (_dis.length === 2) {
|
|
||||||
opt = {
|
|
||||||
objectId: x[newArr[0]][newArr[1]],
|
|
||||||
option: x[_dis[0]][_dis[1]]
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
opt = {
|
|
||||||
objectId: x[newArr[0]][newArr[1]],
|
|
||||||
option: x[props.schema.data.displayKey]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
opt = {
|
|
||||||
objectId: x[newArr[0]],
|
|
||||||
option: x[props.schema.data.displayKey]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
opt = {
|
|
||||||
objectId: x[props.schema.data.valueKey],
|
|
||||||
option: x[props.schema.data.displayKey]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
temp.push(opt);
|
|
||||||
} else {
|
|
||||||
opt = {
|
|
||||||
objectId: x[props.schema.data.valueKey],
|
|
||||||
option: x[props.schema.data.displayKey]
|
|
||||||
};
|
|
||||||
temp.push(opt);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
response = temp;
|
|
||||||
setLevel1_DD(response);
|
|
||||||
setActive(false);
|
|
||||||
if (!props.formData) {
|
|
||||||
props.onChangeLevel1Dropdown("", props.name);
|
|
||||||
}
|
|
||||||
if (response.length === 1) {
|
|
||||||
props.onChangeLevel1Dropdown(response[0].objectId, props.name);
|
|
||||||
props.onChange(response[0].objectId);
|
|
||||||
} else if (response.length === 0) {
|
|
||||||
props.onChangeLevel1Dropdown("", props.name);
|
|
||||||
props.onChange("");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setActive(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
try {
|
|
||||||
setToastDescription(e.message);
|
|
||||||
setActive(false);
|
|
||||||
x = document.getElementById("Level_1");
|
|
||||||
x.className = "show";
|
|
||||||
setTimeout(function () {
|
|
||||||
x.className = x.className.replace("show", "");
|
|
||||||
}, 5000);
|
|
||||||
} catch (error) {
|
|
||||||
console.log("Err", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
Level1DropdownData();
|
|
||||||
// eslint-disable-next-line
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (props.formData && props.formData[`objectId`]) {
|
|
||||||
props.onChangeLevel1Dropdown(props.formData.objectId, props.name);
|
|
||||||
} else if (props.formData) {
|
|
||||||
props.onChangeLevel1Dropdown(props.formData, props.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line
|
|
||||||
}, [props.formData]);
|
|
||||||
|
|
||||||
const selectDefault = () => {
|
|
||||||
props.onChange(Level1_DD[0].objectId);
|
|
||||||
props.onChangeLevel1Dropdown(Level1_DD[0].objectId, props.name);
|
|
||||||
};
|
|
||||||
|
|
||||||
const REQUIRED_FIELD_SYMBOL = "*";
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<div style={{ display: "inline-block" }}>
|
|
||||||
<label htmlFor={props.name}>
|
|
||||||
{props.schema.title}
|
|
||||||
{props.required && (
|
|
||||||
<span className="required">{REQUIRED_FIELD_SYMBOL}</span>
|
|
||||||
)}
|
|
||||||
{props.schema.data.helpbody ? (
|
|
||||||
<div className="dropdown pull-right">
|
|
||||||
<i
|
|
||||||
className="far fa-question-circle dropdown-toggle hovereffect pull-right"
|
|
||||||
aria-hidden="true"
|
|
||||||
id="dropdownMenuButton"
|
|
||||||
data-toggle="dropdown"
|
|
||||||
aria-haspopup="true"
|
|
||||||
aria-expanded="false"
|
|
||||||
style={{
|
|
||||||
fontSize: "12px",
|
|
||||||
color: "purple",
|
|
||||||
cursor: "pointer !important",
|
|
||||||
position: "relative",
|
|
||||||
bottom: "0px",
|
|
||||||
left: "0px",
|
|
||||||
paddingBottom: "4px",
|
|
||||||
paddingLeft: "4px"
|
|
||||||
}}
|
|
||||||
></i>
|
|
||||||
<div
|
|
||||||
className="dropdown-menu"
|
|
||||||
aria-labelledby="dropdownMenuButton"
|
|
||||||
style={{
|
|
||||||
marginleft: "-121px",
|
|
||||||
margintop: "-14px",
|
|
||||||
position: "absolute",
|
|
||||||
padding: "10px",
|
|
||||||
top: "102px!important"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{parse(`
|
|
||||||
${props.schema.data.helpbody}
|
|
||||||
`)}
|
|
||||||
<br />
|
|
||||||
{props.schema.data.helplink ? (
|
|
||||||
<a
|
|
||||||
href={props.schema.data.helplink}
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
className="btn btn-xs btn-primary"
|
|
||||||
>
|
|
||||||
Read more..
|
|
||||||
</a>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{Level1_DD && (
|
|
||||||
<select
|
|
||||||
className="form-control"
|
|
||||||
name={props.name}
|
|
||||||
value={props.value}
|
|
||||||
required={props.required}
|
|
||||||
disabled={props.uiSchema["ui:disabled"]}
|
|
||||||
onChange={(e) => {
|
|
||||||
if (!e.target.value) {
|
|
||||||
if (props.schema.data.isPointer) {
|
|
||||||
localStorage.setItem("Level1", undefined);
|
|
||||||
props.onChangeLevel1Dropdown(undefined, props.name);
|
|
||||||
return props.onChange(undefined);
|
|
||||||
} else {
|
|
||||||
localStorage.setItem("Level1", e.target.value);
|
|
||||||
props.onChangeLevel1Dropdown(e.target.value, props.name);
|
|
||||||
return props.onChange(e.target.value);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
localStorage.setItem("Level1", e.target.value);
|
|
||||||
props.onChangeLevel1Dropdown(e.target.value, props.name);
|
|
||||||
return props.onChange(e.target.value);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
readOnly={props.uiSchema["ui:disabled"] ? true : false}
|
|
||||||
defaultValue={Level1_DD.length === 1 && selectDefault}
|
|
||||||
>
|
|
||||||
<option value="">{!active ? "Select" : "loading..."}</option>
|
|
||||||
{Level1_DD &&
|
|
||||||
Level1_DD.map((x, i) => (
|
|
||||||
<React.Fragment key={i}>
|
|
||||||
{props.formData && props.formData.objectId ? (
|
|
||||||
props.formData.objectId === x.objectId ? (
|
|
||||||
<option value={x.objectId} selected>
|
|
||||||
{x.option}
|
|
||||||
</option>
|
|
||||||
) : (
|
|
||||||
<option value={x.objectId}>{x.option}</option>
|
|
||||||
)
|
|
||||||
) : props.formData && props.formData === x.objectId ? (
|
|
||||||
<option value={x.objectId} selected>
|
|
||||||
{x.option}
|
|
||||||
</option>
|
|
||||||
) : (
|
|
||||||
<option value={x.objectId}>{x.option}</option>
|
|
||||||
)}
|
|
||||||
</React.Fragment>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
)}
|
|
||||||
<div id="Level_1" style={{ backgroundColor: toastColor }}>
|
|
||||||
{toastDescription}
|
|
||||||
</div>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default connect(null, { onChangeLevel1Dropdown })(Level1Dropdown);
|
|
||||||
@@ -1,709 +0,0 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
|
||||||
import { connect } from "react-redux";
|
|
||||||
import Select from "react-select";
|
|
||||||
import axios from "axios";
|
|
||||||
import LabelField from "./LabelField";
|
|
||||||
import ReactDragListView from "react-drag-listview";
|
|
||||||
import AppendFormInForm from "../AppendFormInForm";
|
|
||||||
import Modal from "react-modal";
|
|
||||||
function arrayMove(array, from, to) {
|
|
||||||
array = array.slice();
|
|
||||||
array.splice(to < 0 ? array.length + to : to, 0, array.splice(from, 1)[0]);
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* react-sortable-hoc is depcreated not usable from react 18.x.x
|
|
||||||
* need to replace it with @dnd-kit
|
|
||||||
* code changes required
|
|
||||||
*/
|
|
||||||
|
|
||||||
const MultiSelectField = (props) => {
|
|
||||||
Modal.setAppElement("body");
|
|
||||||
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
|
||||||
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
|
||||||
const [state, setState] = useState(undefined);
|
|
||||||
// const [editFormData, setEditFormData] = useState([]);
|
|
||||||
const [selected, setSelected] = React.useState([]);
|
|
||||||
const [isModal, setIsModel] = useState(false);
|
|
||||||
const onChange = (selectedOptions) => setSelected(selectedOptions);
|
|
||||||
const [modalIsOpen, setModalIsOpen] = useState(false);
|
|
||||||
|
|
||||||
const onSortEnd = ({ oldIndex, newIndex }) => {
|
|
||||||
const newValue = arrayMove(selected, oldIndex, newIndex);
|
|
||||||
setSelected(newValue);
|
|
||||||
};
|
|
||||||
// console.log("props",props)
|
|
||||||
const GetSelectListData = async () => {
|
|
||||||
try {
|
|
||||||
let response = [];
|
|
||||||
let str = props.schema.data.query;
|
|
||||||
let _query;
|
|
||||||
/* eslint-disable no-useless-escape */
|
|
||||||
let reg = /(\#.*?\#)/gi;
|
|
||||||
let extclass =
|
|
||||||
localStorage.getItem("Extand_Class") &&
|
|
||||||
JSON.parse(localStorage.getItem("Extand_Class"));
|
|
||||||
let extRow = extclass.length && extclass[0];
|
|
||||||
if (str.includes("#")) {
|
|
||||||
let output = str.match(reg);
|
|
||||||
output = output.join();
|
|
||||||
output = output.substring(1, output.length - 1);
|
|
||||||
output = output.split(".");
|
|
||||||
|
|
||||||
if (output.length === 2) {
|
|
||||||
let out1 = extRow[output[0]][output[1]];
|
|
||||||
_query = str.replace(reg, out1 && out1);
|
|
||||||
} else {
|
|
||||||
let out1 = extRow[output[0]];
|
|
||||||
_query = str.replace(reg, out1 && out1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_query = str;
|
|
||||||
}
|
|
||||||
let url = `${parseBaseUrl}classes/${props.schema.data.class}?${_query}`;
|
|
||||||
const headers = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": parseAppId,
|
|
||||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
|
||||||
};
|
|
||||||
await axios.get(url, { headers: headers }).then((res) => {
|
|
||||||
let temp = [];
|
|
||||||
let formArray = [];
|
|
||||||
let _selected = [];
|
|
||||||
if (props.schema.uiLayout === "MultiDropdownList") {
|
|
||||||
if (props.formData) {
|
|
||||||
props.formData.forEach((x) => {
|
|
||||||
if (typeof x === "object") {
|
|
||||||
formArray.push(x.objectId);
|
|
||||||
} else {
|
|
||||||
formArray.push(x);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
res.data.results.forEach((x) => {
|
|
||||||
let obj = {};
|
|
||||||
if (formArray.includes(x[props.schema.data.valueKey])) {
|
|
||||||
obj = {
|
|
||||||
name: x[props.schema.data.displayKey],
|
|
||||||
value: x[props.schema.data.valueKey],
|
|
||||||
isChecked: true
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
if (props.schema.selectAll) {
|
|
||||||
obj = {
|
|
||||||
name: x[props.schema.data.displayKey],
|
|
||||||
value: x[props.schema.data.valueKey],
|
|
||||||
isChecked: true
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
obj = {
|
|
||||||
name: x[props.schema.data.displayKey],
|
|
||||||
value: x[props.schema.data.valueKey],
|
|
||||||
isChecked: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
temp.push(obj);
|
|
||||||
});
|
|
||||||
response = temp;
|
|
||||||
if (props.formData) {
|
|
||||||
let checkData = [];
|
|
||||||
response.forEach((x) => {
|
|
||||||
if (x.isChecked) {
|
|
||||||
checkData.push(x.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
setSelected(checkData);
|
|
||||||
}
|
|
||||||
setState({ [`${props.name}_DD`]: response });
|
|
||||||
} else {
|
|
||||||
res.data.results.forEach((x) => {
|
|
||||||
let obj = {};
|
|
||||||
if (props.formData) {
|
|
||||||
props.formData.forEach((x) => {
|
|
||||||
if (typeof x === "object") {
|
|
||||||
formArray.push(x.objectId);
|
|
||||||
} else {
|
|
||||||
formArray.push(x);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
obj = {
|
|
||||||
label: x[props.schema.data.displayKey],
|
|
||||||
value: x[props.schema.data.valueKey]
|
|
||||||
};
|
|
||||||
if (formArray.includes(x[props.schema.data.valueKey])) {
|
|
||||||
_selected.push(obj);
|
|
||||||
}
|
|
||||||
if (props.schema.selectAll) {
|
|
||||||
_selected.push(obj);
|
|
||||||
}
|
|
||||||
temp.push(obj);
|
|
||||||
});
|
|
||||||
response = temp;
|
|
||||||
setState({ [`${props.name}_DD`]: response });
|
|
||||||
setSelected(_selected);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.log("err", error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCheckChieldElement = (event) => {
|
|
||||||
let SelectLists = state[`${props.name}_DD`];
|
|
||||||
let List = [];
|
|
||||||
SelectLists.forEach((select) => {
|
|
||||||
if (select.value === event.target.value) {
|
|
||||||
select.isChecked = event.target.checked;
|
|
||||||
}
|
|
||||||
if (select.isChecked) {
|
|
||||||
List.push(select.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
setSelected(List);
|
|
||||||
setState({ [`${props.name}_DD`]: SelectLists });
|
|
||||||
};
|
|
||||||
|
|
||||||
// const Level1CheckList = async (id) => {
|
|
||||||
// try {
|
|
||||||
// let response = [];
|
|
||||||
// // eslint-disable-next-line
|
|
||||||
// let reg = /(\#.*?\#)/gi;
|
|
||||||
// let _query = props.schema.data.query;
|
|
||||||
// let output = _query.match(reg);
|
|
||||||
// if (output.length === 2) {
|
|
||||||
// let res;
|
|
||||||
// if (localStorage.getItem("Extand_Class")) {
|
|
||||||
// let data = JSON.parse(localStorage.getItem("Extand_Class"));
|
|
||||||
// res = data[0];
|
|
||||||
// }
|
|
||||||
// output = output.filter((x) => x !== "#queryString#");
|
|
||||||
// if (output.length === 1) {
|
|
||||||
// _query = _query.replace("#queryString#", id);
|
|
||||||
// output = output.join();
|
|
||||||
// output = output.substring(1, output.length - 1);
|
|
||||||
// output = output.split(".");
|
|
||||||
// if (output.length > 0) {
|
|
||||||
// _query = _query.replace(reg, res[output[0]][output[1]]);
|
|
||||||
// } else {
|
|
||||||
// _query = _query.replace(reg, res[output[0]]);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// _query = props.schema.data.query.replace(reg, id);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let url = `${parseBaseUrl}classes/${props.schema.data.class}?${_query}`;
|
|
||||||
// const headers = {
|
|
||||||
// "Content-Type": "application/json",
|
|
||||||
// "X-Parse-Application-Id": parseAppId,
|
|
||||||
// "X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
|
||||||
// };
|
|
||||||
// await axios.get(url, { headers: headers }).then(async (res) => {
|
|
||||||
// let temp = [];
|
|
||||||
// let formArray = [];
|
|
||||||
// let _selected = [];
|
|
||||||
// if (editFormData.length > 0) {
|
|
||||||
// editFormData.forEach((x) => {
|
|
||||||
// if (typeof x === "object") {
|
|
||||||
// formArray.push(x.objectId);
|
|
||||||
// } else {
|
|
||||||
// formArray.push(x);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// } else if (
|
|
||||||
// props.schema.selectedData &&
|
|
||||||
// Object.keys(props.schema.selectedData).length !== 0 &&
|
|
||||||
// props.schema.selectedData.constructor === Object
|
|
||||||
// ) {
|
|
||||||
// try {
|
|
||||||
// let selectedDataQuery = props.schema.selectedData.query.replace(
|
|
||||||
// reg,
|
|
||||||
// id
|
|
||||||
// );
|
|
||||||
// let selectedDataUrl = `${parseBaseUrl}classes/${props.schema.selectedData.class}?${selectedDataQuery}`;
|
|
||||||
|
|
||||||
// await axios.get(selectedDataUrl, { headers }).then((sltres) => {
|
|
||||||
// let sltData = sltres.data.results;
|
|
||||||
// sltData.forEach((x) => {
|
|
||||||
// if (props.schema.selectedData.valueKey.includes(".")) {
|
|
||||||
// let sltArr = props.schema.selectedData.valueKey.split(".");
|
|
||||||
|
|
||||||
// if (Array.isArray(x[sltArr[0]])) {
|
|
||||||
// x[sltArr[0]].forEach((l) => {
|
|
||||||
// formArray.push(l[sltArr[1]]);
|
|
||||||
// });
|
|
||||||
// } else {
|
|
||||||
// formArray.push(x[sltArr[0][sltArr[1]]]);
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// formArray.push(x[props.schema.selectedData.valueKey]);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// } catch (error) {}
|
|
||||||
// }
|
|
||||||
// res.data.results.forEach((x) => {
|
|
||||||
// let obj = {};
|
|
||||||
// if (props.schema.data.valueKey.includes(".")) {
|
|
||||||
// let newArr = props.schema.data.valueKey.split(".");
|
|
||||||
// if (Array.isArray(x[newArr[0]])) {
|
|
||||||
// if (props.schema.data.displayKey.includes(".")) {
|
|
||||||
// let _dis = props.schema.data.displayKey.split(".");
|
|
||||||
// x[newArr[0]].forEach((l) => {
|
|
||||||
// if (formArray.includes(l[newArr[1]])) {
|
|
||||||
// obj = {
|
|
||||||
// label: l[_dis[1]],
|
|
||||||
// value: l[newArr[1]],
|
|
||||||
// isChecked: true
|
|
||||||
// };
|
|
||||||
// _selected.push(obj);
|
|
||||||
// } else {
|
|
||||||
// if (props.schema.selectAll) {
|
|
||||||
// obj = {
|
|
||||||
// label: l[_dis[1]],
|
|
||||||
// value: l[newArr[1]],
|
|
||||||
// isChecked: true
|
|
||||||
// };
|
|
||||||
// _selected.push(obj);
|
|
||||||
// } else {
|
|
||||||
// obj = {
|
|
||||||
// label: l[_dis[1]],
|
|
||||||
// value: l[newArr[1]],
|
|
||||||
// isChecked: false
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// temp.push(obj);
|
|
||||||
// });
|
|
||||||
// } else {
|
|
||||||
// x[newArr[0]].forEach((l) => {
|
|
||||||
// if (formArray.includes(l[newArr[1]])) {
|
|
||||||
// obj = {
|
|
||||||
// label: x[props.schema.data.displayKey],
|
|
||||||
// value: l[newArr[1]],
|
|
||||||
// isChecked: true
|
|
||||||
// };
|
|
||||||
// _selected.push(obj);
|
|
||||||
// } else {
|
|
||||||
// if (props.schema.selectAll) {
|
|
||||||
// obj = {
|
|
||||||
// label: x[props.schema.data.displayKey],
|
|
||||||
// value: l[newArr[1]],
|
|
||||||
// isChecked: true
|
|
||||||
// };
|
|
||||||
// _selected.push(obj);
|
|
||||||
// } else {
|
|
||||||
// obj = {
|
|
||||||
// label: x[props.schema.data.displayKey],
|
|
||||||
// value: l[newArr[1]],
|
|
||||||
// isChecked: false
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// temp.push(obj);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// if (props.schema.data.displayKey.includes(".")) {
|
|
||||||
// let disArr = props.schema.data.displayKey.split(".");
|
|
||||||
// if (formArray.includes(x[newArr[0]][newArr[1]])) {
|
|
||||||
// obj = {
|
|
||||||
// label: x[disArr[0]][disArr[1]],
|
|
||||||
// value: x[newArr[0]][newArr[1]],
|
|
||||||
// isChecked: true
|
|
||||||
// };
|
|
||||||
// _selected.push(obj);
|
|
||||||
// } else {
|
|
||||||
// if (props.schema.selectAll) {
|
|
||||||
// obj = {
|
|
||||||
// label: x[disArr[0]][disArr[1]],
|
|
||||||
// value: x[newArr[0]][newArr[1]],
|
|
||||||
// isChecked: true
|
|
||||||
// };
|
|
||||||
// _selected.push(obj);
|
|
||||||
// } else {
|
|
||||||
// obj = {
|
|
||||||
// label: x[disArr[0]][disArr[1]],
|
|
||||||
// value: x[newArr[0]][newArr[1]],
|
|
||||||
// isChecked: false
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// if (formArray.includes(x[newArr[0]][newArr[1]])) {
|
|
||||||
// obj = {
|
|
||||||
// label: x[props.schema.data.displayKey],
|
|
||||||
// value: x[newArr[0]][newArr[1]],
|
|
||||||
// isChecked: true
|
|
||||||
// };
|
|
||||||
// _selected.push(obj);
|
|
||||||
// } else {
|
|
||||||
// if (props.schema.selectAll) {
|
|
||||||
// obj = {
|
|
||||||
// label: x[props.schema.data.displayKey],
|
|
||||||
// value: x[newArr[0]][newArr[1]],
|
|
||||||
// isChecked: true
|
|
||||||
// };
|
|
||||||
// _selected.push(obj);
|
|
||||||
// } else {
|
|
||||||
// obj = {
|
|
||||||
// label: x[props.schema.data.displayKey],
|
|
||||||
// value: x[newArr[0]][newArr[1]],
|
|
||||||
// isChecked: false
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// if (Array.isArray(x[props.schema.data.valueKey])) {
|
|
||||||
// x[props.schema.data.valueKey].forEach((t) => {
|
|
||||||
// if (formArray.includes(t)) {
|
|
||||||
// obj = {
|
|
||||||
// label: t,
|
|
||||||
// value: t,
|
|
||||||
// isChecked: true
|
|
||||||
// };
|
|
||||||
// _selected.push(obj);
|
|
||||||
// } else {
|
|
||||||
// if (props.schema.selectAll) {
|
|
||||||
// obj = {
|
|
||||||
// label: t,
|
|
||||||
// value: t,
|
|
||||||
// isChecked: true
|
|
||||||
// };
|
|
||||||
// _selected.push(obj);
|
|
||||||
// } else {
|
|
||||||
// obj = {
|
|
||||||
// label: t,
|
|
||||||
// value: t,
|
|
||||||
// isChecked: false
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// temp.push(obj);
|
|
||||||
// });
|
|
||||||
// } else if (formArray.includes(x[props.schema.data.valueKey])) {
|
|
||||||
// obj = {
|
|
||||||
// label: x[props.schema.data.displayKey],
|
|
||||||
// value: x[props.schema.data.valueKey],
|
|
||||||
// isChecked: true
|
|
||||||
// };
|
|
||||||
// _selected.push(obj);
|
|
||||||
// } else {
|
|
||||||
// if (props.schema.selectAll) {
|
|
||||||
// obj = {
|
|
||||||
// label: x[props.schema.data.displayKey],
|
|
||||||
// value: x[props.schema.data.valueKey],
|
|
||||||
// isChecked: true
|
|
||||||
// };
|
|
||||||
// _selected.push(obj);
|
|
||||||
// } else {
|
|
||||||
// obj = {
|
|
||||||
// label: x[props.schema.data.displayKey],
|
|
||||||
// value: x[props.schema.data.valueKey],
|
|
||||||
// isChecked: false
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// temp.push(obj);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// response = temp;
|
|
||||||
// if (props.schema.uiLayout === "MultiDropdownList") {
|
|
||||||
// if (editFormData) {
|
|
||||||
// let checkData = [];
|
|
||||||
// response.forEach((x) => {
|
|
||||||
// if (x.isChecked) {
|
|
||||||
// checkData.push(x.value);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// setSelected(checkData);
|
|
||||||
// }
|
|
||||||
// setState({ [`${props.name}_DD`]: response });
|
|
||||||
// } else {
|
|
||||||
// setState({ [`${props.name}_DD`]: response });
|
|
||||||
// setSelected(_selected);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// } catch (error) {}
|
|
||||||
// };
|
|
||||||
|
|
||||||
const dragProps = {
|
|
||||||
onDragEnd(fromIndex, toIndex) {
|
|
||||||
const data = [...state[`${props.name}_DD`]];
|
|
||||||
const item = data.splice(fromIndex, 1)[0];
|
|
||||||
data.splice(toIndex, 0, item);
|
|
||||||
let NewList = [];
|
|
||||||
data.forEach((x) => {
|
|
||||||
if (x.isChecked) {
|
|
||||||
NewList.push(x.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
setState({ [`${props.name}_DD`]: data });
|
|
||||||
setSelected(NewList);
|
|
||||||
},
|
|
||||||
nodeSelector: "li",
|
|
||||||
handleSelector: "a"
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!props.schema.parent) GetSelectListData();
|
|
||||||
// eslint-disable-next-line
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (props.schema.uiLayout === "MultiDropdownList") {
|
|
||||||
props.onChange(selected);
|
|
||||||
} else {
|
|
||||||
if (selected && selected.length) {
|
|
||||||
let newData = [];
|
|
||||||
selected.forEach((x) => {
|
|
||||||
newData.push(x.value);
|
|
||||||
});
|
|
||||||
props.onChange(newData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line
|
|
||||||
}, [selected]);
|
|
||||||
|
|
||||||
// useState(() => {
|
|
||||||
// if (props.formData) {
|
|
||||||
// if (props.formData === "Select") {
|
|
||||||
// } else {
|
|
||||||
// setEditFormData(props.formData);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // eslint-disable-next-line
|
|
||||||
// }, [props.formData]);
|
|
||||||
|
|
||||||
const handleModalCloseClick = () => {
|
|
||||||
setIsModel(false);
|
|
||||||
setModalIsOpen(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const openModal = () => {
|
|
||||||
setModalIsOpen(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
// `handleNewDetails` is used to set just save from quick form to selected option in dropdown
|
|
||||||
const handleNewDetails = (data) => {
|
|
||||||
setState({ [`${props.name}_DD`]: [...state[`${props.name}_DD`], data] });
|
|
||||||
if (selected.length > 0) {
|
|
||||||
setSelected([...selected, data]);
|
|
||||||
} else {
|
|
||||||
setSelected([data]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (props.schema.uiLayout === "MultiDropdownList") {
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<LabelField
|
|
||||||
Title={props.schema.title}
|
|
||||||
Name={props.name}
|
|
||||||
Required={props.required}
|
|
||||||
HelpBody={props.schema.helpbody}
|
|
||||||
HelpLink={props.schema.helplink}
|
|
||||||
/>
|
|
||||||
<ReactDragListView {...dragProps}>
|
|
||||||
<ul
|
|
||||||
style={{
|
|
||||||
listStyleType: "square",
|
|
||||||
listStylePosition: "outside",
|
|
||||||
maxHeight: "250px",
|
|
||||||
overflow: "auto",
|
|
||||||
paddingTop: "10px",
|
|
||||||
paddingBottom: "10px",
|
|
||||||
border: "0px solid #b3b3b3",
|
|
||||||
borderRadius: "5px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{state && state[`${props.name}_DD`].length > 0 ? (
|
|
||||||
state[`${props.name}_DD`].map((x, i) => {
|
|
||||||
return (
|
|
||||||
<li key={i} className="multiSelectList">
|
|
||||||
<input
|
|
||||||
key={x.value}
|
|
||||||
onClick={handleCheckChieldElement}
|
|
||||||
type="checkbox"
|
|
||||||
checked={x.isChecked}
|
|
||||||
style={{ marginTop: "7px" }}
|
|
||||||
value={x.value}
|
|
||||||
disabled={props.disabled}
|
|
||||||
/>{" "}
|
|
||||||
<span style={{ marginTop: "7px" }}>{x.name}</span>
|
|
||||||
{props.schema.isSortable && !props.disabled && (
|
|
||||||
<a
|
|
||||||
onClick={(e) => e.preventDefault()}
|
|
||||||
className="pull-right"
|
|
||||||
title="Sort List"
|
|
||||||
style={{ textDecoration: "none" }}
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-bars"
|
|
||||||
style={{
|
|
||||||
fontSize: "30px",
|
|
||||||
color: "skyblue",
|
|
||||||
paddingTop: "11px"
|
|
||||||
}}
|
|
||||||
></i>
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
) : (
|
|
||||||
<li className="multiSelectList">No Record Found</li>
|
|
||||||
)}
|
|
||||||
</ul>
|
|
||||||
</ReactDragListView>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<LabelField
|
|
||||||
Title={props.schema.title}
|
|
||||||
Name={props.name}
|
|
||||||
Required={props.required}
|
|
||||||
HelpBody={props.schema.helpbody}
|
|
||||||
HelpLink={props.schema.helplink}
|
|
||||||
/>
|
|
||||||
<div style={{ display: "flex", gap: 5 }}>
|
|
||||||
<div style={{ flexWrap: "wrap", width: "100%" }}>
|
|
||||||
<Select
|
|
||||||
onSortEnd={onSortEnd}
|
|
||||||
distance={4}
|
|
||||||
isMulti
|
|
||||||
options={(state && state[`${props.name}_DD`]) || []}
|
|
||||||
value={selected}
|
|
||||||
onChange={onChange}
|
|
||||||
closeMenuOnSelect={false}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{props.schema.data.quickAddFormId && (
|
|
||||||
<div
|
|
||||||
onClick={() => {
|
|
||||||
setIsModel(true);
|
|
||||||
openModal();
|
|
||||||
}}
|
|
||||||
style={{
|
|
||||||
cursor: "pointer",
|
|
||||||
borderRadius: 4,
|
|
||||||
border: "1px solid #ccc",
|
|
||||||
minHeight: 38,
|
|
||||||
minWidth: 48,
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<i className="fas fa-plus"></i>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{/* {props.schema.data.quickAddFormId && (
|
|
||||||
<div
|
|
||||||
className="modal fade"
|
|
||||||
id={"multiSelectModal" + props.schema.data.quickAddFormId}
|
|
||||||
tabIndex="-1"
|
|
||||||
role="dialog"
|
|
||||||
aria-labelledby="exampleModalLabel"
|
|
||||||
aria-hidden="true"
|
|
||||||
>
|
|
||||||
<div className="modal-dialog modal-lg" role="document">
|
|
||||||
<div className="modal-content">
|
|
||||||
<div className="modal-header">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="close"
|
|
||||||
data-dismiss="modal"
|
|
||||||
aria-label="Close"
|
|
||||||
onClick={handleModalCloseClick}
|
|
||||||
>
|
|
||||||
<i className="fa fa-times-circle" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div className="modal-body">
|
|
||||||
{isModal && (
|
|
||||||
<AppendFormInForm
|
|
||||||
id={props.schema.data.quickAddFormId}
|
|
||||||
valueKey={props.schema.data.valueKey}
|
|
||||||
displayKey={props.schema.data.displayKey}
|
|
||||||
details={handleNewDetails}
|
|
||||||
closePopup={handleModalCloseClick}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)} */}
|
|
||||||
<Modal
|
|
||||||
isOpen={modalIsOpen}
|
|
||||||
onRequestClose={handleModalCloseClick}
|
|
||||||
shouldCloseOnOverlayClick={false}
|
|
||||||
contentLabel="Modal"
|
|
||||||
style={{
|
|
||||||
content: {
|
|
||||||
top: "50%",
|
|
||||||
left: "50%",
|
|
||||||
right: "auto",
|
|
||||||
bottom: "auto",
|
|
||||||
transform: "translate(-50%, -50%)",
|
|
||||||
padding: 0
|
|
||||||
},
|
|
||||||
overlay: {
|
|
||||||
width: "100%",
|
|
||||||
backgroundColor: "rgba(0, 0, 0, 0.75)",
|
|
||||||
zIndex: 50
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="min-w-full md:min-w-[500px]">
|
|
||||||
<div
|
|
||||||
type="button"
|
|
||||||
className="flex justify-between items-center p-3 border-b-[1px] border-gray-300"
|
|
||||||
>
|
|
||||||
<div className=" text-black text-xl font-semibold pl-3">
|
|
||||||
Add Signer
|
|
||||||
</div>
|
|
||||||
<button onClick={handleModalCloseClick}>
|
|
||||||
<i
|
|
||||||
style={{ fontSize: 25 }}
|
|
||||||
className="fa fa-times-circle"
|
|
||||||
aria-hidden="true"
|
|
||||||
></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{isModal && (
|
|
||||||
<AppendFormInForm
|
|
||||||
id={props.schema.data.quickAddFormId}
|
|
||||||
valueKey={props.schema.data.valueKey}
|
|
||||||
displayKey={props.schema.data.displayKey}
|
|
||||||
details={handleNewDetails}
|
|
||||||
closePopup={handleModalCloseClick}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
</div>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapStateToProps = (state) => {
|
|
||||||
return {
|
|
||||||
Level1_Dropdown: state.Level1_Dropdown,
|
|
||||||
Level2_Dropdown: state.Level2_Dropdown,
|
|
||||||
Level3_Dropdown: state.Level3_Dropdown
|
|
||||||
};
|
|
||||||
};
|
|
||||||
export default connect(mapStateToProps, null)(MultiSelectField);
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import ObjectField from "@rjsf/core/lib/components/fields/ObjectField";
|
|
||||||
import validator from "@rjsf/validator-ajv8";
|
|
||||||
import { Col } from "react-bootstrap";
|
|
||||||
import { retrieveSchema } from "@rjsf/utils";
|
|
||||||
|
|
||||||
class GridField extends ObjectField {
|
|
||||||
state = {};
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
uiSchema,
|
|
||||||
errorSchema,
|
|
||||||
idSchema,
|
|
||||||
|
|
||||||
disabled,
|
|
||||||
readonly,
|
|
||||||
onBlur,
|
|
||||||
formData
|
|
||||||
} = this.props;
|
|
||||||
const { fields, rootSchema } = this.props.registry;
|
|
||||||
|
|
||||||
const { SchemaField } = fields;
|
|
||||||
const schema = retrieveSchema(validator, this.props.schema, rootSchema);
|
|
||||||
const title = schema.title === undefined ? "" : schema.title;
|
|
||||||
const description =
|
|
||||||
schema && schema.description === undefined ? "" : schema.description;
|
|
||||||
// console.log('this.props.schema ', this.props.schema)
|
|
||||||
// console.log("schema ", schema);
|
|
||||||
const layout = uiSchema["ui:layout"];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<fieldset>
|
|
||||||
{title ? <h4>{title}</h4> : null}
|
|
||||||
{description ? <h6>{description}</h6> : null}
|
|
||||||
{layout.map((row, index) => {
|
|
||||||
return (
|
|
||||||
<div className="row" key={index}>
|
|
||||||
{Object.keys(row).map((name, index) => {
|
|
||||||
const { doShow, ...rowProps } = row[name];
|
|
||||||
let style = {};
|
|
||||||
if (doShow && !doShow({ formData })) {
|
|
||||||
style = { display: "none" };
|
|
||||||
}
|
|
||||||
if (schema.properties[name]) {
|
|
||||||
return (
|
|
||||||
<Col {...rowProps} key={index} style={style}>
|
|
||||||
<SchemaField
|
|
||||||
name={name}
|
|
||||||
required={this.isRequired(name)}
|
|
||||||
schema={schema.properties[name]}
|
|
||||||
uiSchema={uiSchema[name]}
|
|
||||||
errorSchema={errorSchema[name]}
|
|
||||||
idSchema={idSchema[name]}
|
|
||||||
formData={formData[name]}
|
|
||||||
onChange={this.onPropertyChange(name)}
|
|
||||||
onBlur={onBlur}
|
|
||||||
registry={this.props.registry}
|
|
||||||
disabled={disabled}
|
|
||||||
readonly={readonly}
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
const { render, ...rowProps } = row[name];
|
|
||||||
let UIComponent = () => null;
|
|
||||||
|
|
||||||
if (render) {
|
|
||||||
UIComponent = render;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Col {...rowProps} key={index} style={style}>
|
|
||||||
<UIComponent
|
|
||||||
name={name}
|
|
||||||
formData={formData}
|
|
||||||
errorSchema={errorSchema}
|
|
||||||
uiSchema={uiSchema}
|
|
||||||
schema={schema}
|
|
||||||
registry={this.props.registry}
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</fieldset>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export default GridField;
|
|
||||||
@@ -0,0 +1,261 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import Parse from "parse";
|
||||||
|
import CreateFolder from "./CreateFolder";
|
||||||
|
import ModalUi from "../../primitives/ModalUi";
|
||||||
|
|
||||||
|
const SelectFolder = ({ required, onSuccess, folderCls }) => {
|
||||||
|
const [isOpen, SetIsOpen] = useState(false);
|
||||||
|
const [clickFolder, setClickFolder] = useState("");
|
||||||
|
const [selectFolder, setSelectedFolder] = useState({});
|
||||||
|
const [folderList, setFolderList] = useState([]);
|
||||||
|
const [tabList, setTabList] = useState([]);
|
||||||
|
const [isLoader, setIsLoader] = useState(false);
|
||||||
|
const [folderPath, setFolderPath] = useState("");
|
||||||
|
const [isAdd, setIsAdd] = useState(false);
|
||||||
|
useEffect(() => {
|
||||||
|
if (isOpen) {
|
||||||
|
setIsAdd(false);
|
||||||
|
setClickFolder({});
|
||||||
|
setFolderList([]);
|
||||||
|
setTabList([]);
|
||||||
|
fetchFolder();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, [isOpen]);
|
||||||
|
const fetchFolder = async (folderPtr) => {
|
||||||
|
setIsLoader(true);
|
||||||
|
try {
|
||||||
|
const FolderQuery = new Parse.Query(folderCls);
|
||||||
|
if (folderPtr) {
|
||||||
|
FolderQuery.equalTo("Folder", folderPtr);
|
||||||
|
FolderQuery.equalTo("Type", "Folder");
|
||||||
|
} else {
|
||||||
|
FolderQuery.doesNotExist("Folder");
|
||||||
|
FolderQuery.equalTo("Type", "Folder");
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await FolderQuery.find();
|
||||||
|
if (res) {
|
||||||
|
const result = JSON.parse(JSON.stringify(res));
|
||||||
|
if (result) {
|
||||||
|
setFolderList(result);
|
||||||
|
setIsLoader(false);
|
||||||
|
}
|
||||||
|
setIsLoader(false);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
setIsLoader(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleSelect = (item) => {
|
||||||
|
setFolderList([]);
|
||||||
|
setClickFolder({ ObjectId: item.objectId, Name: item.Name });
|
||||||
|
if (tabList.length > 0) {
|
||||||
|
const tab = tabList.some((x) => x.objectId === item.objectId);
|
||||||
|
if (!tab) {
|
||||||
|
setTabList((tabs) => [...tabs, item]);
|
||||||
|
const folderPtr = {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: folderCls,
|
||||||
|
objectId: item.objectId
|
||||||
|
};
|
||||||
|
fetchFolder(folderPtr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setTabList((tabs) => [...tabs, item]);
|
||||||
|
const folderPtr = {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: folderCls,
|
||||||
|
objectId: item.objectId
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchFolder(folderPtr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
let url = "Root";
|
||||||
|
tabList.forEach((t) => {
|
||||||
|
url = url + " / " + t.Name;
|
||||||
|
});
|
||||||
|
setFolderPath(url);
|
||||||
|
setSelectedFolder(clickFolder);
|
||||||
|
if (onSuccess) {
|
||||||
|
onSuccess(clickFolder);
|
||||||
|
}
|
||||||
|
SetIsOpen(false);
|
||||||
|
};
|
||||||
|
const handleCancel = () => {
|
||||||
|
SetIsOpen(false);
|
||||||
|
setClickFolder({});
|
||||||
|
setFolderList([]);
|
||||||
|
setTabList([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeTabListItem = async (e, i) => {
|
||||||
|
e.preventDefault();
|
||||||
|
// setEditable(false);
|
||||||
|
if (!isAdd) {
|
||||||
|
setIsLoader(true);
|
||||||
|
let folderPtr;
|
||||||
|
if (i) {
|
||||||
|
setFolderList([]);
|
||||||
|
let list = tabList.filter((itm, j) => {
|
||||||
|
if (j <= i) {
|
||||||
|
return itm;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let _len = list.length - 1;
|
||||||
|
folderPtr = {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: folderCls,
|
||||||
|
objectId: list[_len].objectId
|
||||||
|
};
|
||||||
|
setTabList(list);
|
||||||
|
} else {
|
||||||
|
setClickFolder({});
|
||||||
|
setSelectedFolder({});
|
||||||
|
setFolderList([]);
|
||||||
|
setTabList([]);
|
||||||
|
}
|
||||||
|
fetchFolder(folderPtr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleCreate = () => {
|
||||||
|
setIsAdd(!isAdd);
|
||||||
|
};
|
||||||
|
const handleAddFolder = () => {
|
||||||
|
setFolderList([]);
|
||||||
|
if (clickFolder && clickFolder.ObjectId) {
|
||||||
|
fetchFolder({
|
||||||
|
__type: "Pointer",
|
||||||
|
className: folderCls,
|
||||||
|
objectId: clickFolder.ObjectId
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
fetchFolder();
|
||||||
|
}
|
||||||
|
handleCreate();
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="text-xs mt-2 ">
|
||||||
|
<div>
|
||||||
|
<label className="block">
|
||||||
|
Select Folder
|
||||||
|
{required && <span className="text-red-500 text-[13px]">*</span>}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className="rounded px-[20px] py-[20px] bg-white border border-gray-200 shadow flex max-w-sm gap-8 items-center">
|
||||||
|
<div>
|
||||||
|
<i
|
||||||
|
className="far fa-folder-open text-[40px] text-[#33bbff]"
|
||||||
|
style={{ fontSize: "40px" }}
|
||||||
|
aria-hidden="true"
|
||||||
|
></i>
|
||||||
|
</div>
|
||||||
|
<div className="font-semibold ">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<p>
|
||||||
|
{selectFolder && selectFolder.Name ? selectFolder.Name : "Root"}
|
||||||
|
</p>
|
||||||
|
<div className="text-black text-sm" onClick={() => SetIsOpen(true)}>
|
||||||
|
<i
|
||||||
|
className="fa fa-pencil"
|
||||||
|
title="Select Folder"
|
||||||
|
aria-hidden="true"
|
||||||
|
></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className="text-[10px] text-gray-400">
|
||||||
|
{selectFolder && selectFolder.Name ? `(${folderPath})` : ""}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ModalUi
|
||||||
|
title={"Select Folder"}
|
||||||
|
isOpen={isOpen}
|
||||||
|
handleClose={handleCancel}
|
||||||
|
>
|
||||||
|
<div className="w-full min-w-[300px] md:min-w-[500px] px-3">
|
||||||
|
<div className="py-2 text-[#ac4848] text-[14px] font-[500]">
|
||||||
|
<span
|
||||||
|
className="cursor-pointer"
|
||||||
|
title="Root"
|
||||||
|
onClick={(e) => removeTabListItem(e)}
|
||||||
|
>
|
||||||
|
Root /{" "}
|
||||||
|
</span>
|
||||||
|
{tabList &&
|
||||||
|
tabList.map((tab, i) => (
|
||||||
|
<React.Fragment key={`${tab.objectId}-${i}`}>
|
||||||
|
<span
|
||||||
|
className="cursor-pointer"
|
||||||
|
title={tab.Name}
|
||||||
|
onClick={(e) => removeTabListItem(e, i)}
|
||||||
|
>
|
||||||
|
{tab.Name}
|
||||||
|
</span>
|
||||||
|
{" / "}
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
<div className="mt-2 mb-3">
|
||||||
|
{!isAdd &&
|
||||||
|
folderList.length > 0 &&
|
||||||
|
folderList.map((folder) => (
|
||||||
|
<div
|
||||||
|
key={folder.Name}
|
||||||
|
className="border-[1px] border-[#8a8a8a] px-2 py-2 mb-2 cursor-pointer"
|
||||||
|
onClick={() => handleSelect(folder)}
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<i
|
||||||
|
className="fa fa-folder text-[#33bbff] text-[1.4rem]"
|
||||||
|
aria-hidden="true"
|
||||||
|
></i>
|
||||||
|
<span className="font-semibold">{folder.Name}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
{isAdd && (
|
||||||
|
<CreateFolder
|
||||||
|
parentFolderId={clickFolder && clickFolder.ObjectId}
|
||||||
|
folderCls={folderCls}
|
||||||
|
onSuccess={handleAddFolder}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{isLoader && (
|
||||||
|
<div className="flex justify-center">
|
||||||
|
<i className="fa-solid fa-spinner fa-spin-pulse text-[30px]"></i>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<div className="flex justify-between items-center py-[.75rem] px-[1.25rem]">
|
||||||
|
<div
|
||||||
|
className="text-[30px] cursor-pointer text-[#32a3ac]"
|
||||||
|
title="Save Here"
|
||||||
|
onClick={handleCreate}
|
||||||
|
>
|
||||||
|
{isAdd ? (
|
||||||
|
<i className="fa-solid fa-arrow-left" aria-hidden="true"></i>
|
||||||
|
) : (
|
||||||
|
<i className="fa-solid fa-square-plus" aria-hidden="true"></i>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="text-[30px] cursor-pointer"
|
||||||
|
title="Save Here"
|
||||||
|
onClick={handleSubmit}
|
||||||
|
>
|
||||||
|
<i className="fas fa-save" aria-hidden="true"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SelectFolder;
|
||||||
@@ -0,0 +1,189 @@
|
|||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import Select from "react-select";
|
||||||
|
import AppendFormInForm from "../AppendFormInForm";
|
||||||
|
import Modal from "react-modal";
|
||||||
|
import Parse from "parse";
|
||||||
|
function arrayMove(array, from, to) {
|
||||||
|
array = array.slice();
|
||||||
|
array.splice(to < 0 ? array.length + to : to, 0, array.splice(from, 1)[0]);
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* react-sortable-hoc is depcreated not usable from react 18.x.x
|
||||||
|
* need to replace it with @dnd-kit
|
||||||
|
* code changes required
|
||||||
|
*/
|
||||||
|
|
||||||
|
const SignersInput = (props) => {
|
||||||
|
Modal.setAppElement("body");
|
||||||
|
const [state, setState] = useState(undefined);
|
||||||
|
// const [editFormData, setEditFormData] = useState([]);
|
||||||
|
const [selected, setSelected] = React.useState([]);
|
||||||
|
const [isModal, setIsModel] = useState(false);
|
||||||
|
const onChange = (selectedOptions) => setSelected(selectedOptions);
|
||||||
|
const [modalIsOpen, setModalIsOpen] = useState(false);
|
||||||
|
|
||||||
|
const onSortEnd = ({ oldIndex, newIndex }) => {
|
||||||
|
const newValue = arrayMove(selected, oldIndex, newIndex);
|
||||||
|
setSelected(newValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
const GetSelectListData = async () => {
|
||||||
|
try {
|
||||||
|
const currentUser = Parse.User.current();
|
||||||
|
const contactbook = new Parse.Query("contracts_Contactbook");
|
||||||
|
contactbook.equalTo(
|
||||||
|
"CreatedBy",
|
||||||
|
Parse.User.createWithoutData(currentUser.id)
|
||||||
|
);
|
||||||
|
contactbook.notEqualTo("IsDeleted", true);
|
||||||
|
const contactRes = await contactbook.find();
|
||||||
|
if (contactRes) {
|
||||||
|
const res = JSON.parse(JSON.stringify(contactRes));
|
||||||
|
let list = [];
|
||||||
|
|
||||||
|
// let _selected = [];
|
||||||
|
res.forEach((x) => {
|
||||||
|
let obj = {
|
||||||
|
label: x.Name,
|
||||||
|
value: x.objectId,
|
||||||
|
isChecked: true
|
||||||
|
};
|
||||||
|
|
||||||
|
list.push(obj);
|
||||||
|
});
|
||||||
|
setState(list);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("err", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
GetSelectListData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (selected && selected.length) {
|
||||||
|
let newData = [];
|
||||||
|
selected.forEach((x) => {
|
||||||
|
newData.push(x.value);
|
||||||
|
});
|
||||||
|
if (props.onChange) {
|
||||||
|
props.onChange(newData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, [selected]);
|
||||||
|
|
||||||
|
const handleModalCloseClick = () => {
|
||||||
|
setIsModel(false);
|
||||||
|
setModalIsOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const openModal = () => {
|
||||||
|
setModalIsOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// `handleNewDetails` is used to set just save from quick form to selected option in dropdown
|
||||||
|
const handleNewDetails = (data) => {
|
||||||
|
setState([...state, data]);
|
||||||
|
if (selected.length > 0) {
|
||||||
|
setSelected([...selected, data]);
|
||||||
|
} else {
|
||||||
|
setSelected([data]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="text-xs mt-2 ">
|
||||||
|
<label className="block">
|
||||||
|
Signers
|
||||||
|
{props.required && <span className="text-red-500 text-[13px]">*</span>}
|
||||||
|
</label>
|
||||||
|
<div style={{ display: "flex", gap: 5 }}>
|
||||||
|
<div style={{ flexWrap: "wrap", width: "100%" }}>
|
||||||
|
<Select
|
||||||
|
onSortEnd={onSortEnd}
|
||||||
|
distance={4}
|
||||||
|
isMulti
|
||||||
|
options={state || []}
|
||||||
|
value={selected}
|
||||||
|
onChange={onChange}
|
||||||
|
closeMenuOnSelect={false}
|
||||||
|
required={props.required}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
onClick={() => {
|
||||||
|
setIsModel(true);
|
||||||
|
openModal();
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
cursor: "pointer",
|
||||||
|
borderRadius: 4,
|
||||||
|
border: "1px solid #ccc",
|
||||||
|
minHeight: 38,
|
||||||
|
minWidth: 48,
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<i className="fas fa-plus"></i>
|
||||||
|
</div>
|
||||||
|
<Modal
|
||||||
|
isOpen={modalIsOpen}
|
||||||
|
onRequestClose={handleModalCloseClick}
|
||||||
|
shouldCloseOnOverlayClick={false}
|
||||||
|
id="modal1"
|
||||||
|
contentLabel="Modal"
|
||||||
|
style={{
|
||||||
|
content: {
|
||||||
|
top: "50%",
|
||||||
|
left: "50%",
|
||||||
|
right: "auto",
|
||||||
|
bottom: "auto",
|
||||||
|
transform: "translate(-50%, -50%)",
|
||||||
|
border: "1px transparent",
|
||||||
|
padding: 0
|
||||||
|
},
|
||||||
|
overlay: {
|
||||||
|
width: "100%",
|
||||||
|
backgroundColor: "rgba(0, 0, 0, 0.75)",
|
||||||
|
zIndex: 50
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="min-w-full md:min-w-[500px]">
|
||||||
|
<div
|
||||||
|
className="flex justify-between rounded-t items-center py-[10px] px-[20px] text-white"
|
||||||
|
style={{ background: "#32a3ac" }}
|
||||||
|
>
|
||||||
|
<div className="text-[1.2rem] font-normal">Add Signer</div>
|
||||||
|
<button
|
||||||
|
onClick={handleModalCloseClick}
|
||||||
|
className="text-[1.5rem] cursor-pointer focus:outline-none"
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{isModal && (
|
||||||
|
<AppendFormInForm
|
||||||
|
valueKey={"objectId"}
|
||||||
|
displayKey={"Name"}
|
||||||
|
details={handleNewDetails}
|
||||||
|
closePopup={handleModalCloseClick}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SignersInput;
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import PropTypes from "prop-types";
|
|
||||||
|
|
||||||
function TimeWidget(props) {
|
|
||||||
const {
|
|
||||||
onChange,
|
|
||||||
registry: {
|
|
||||||
widgets: { BaseInput }
|
|
||||||
}
|
|
||||||
} = props;
|
|
||||||
return (
|
|
||||||
<BaseInput
|
|
||||||
type="time"
|
|
||||||
{...props}
|
|
||||||
onChange={(value) => onChange(value || undefined)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== "production") {
|
|
||||||
TimeWidget.propTypes = {
|
|
||||||
value: PropTypes.string
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default TimeWidget;
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export const openInNewTab = (url) => {
|
||||||
|
window.open(url, "_blank", "noopener,noreferrer");
|
||||||
|
};
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
export const contactCls = "contracts_Contactbook";
|
||||||
|
export const templateCls = "contracts_Template";
|
||||||
|
export const documentCls = "contracts_Document";
|
||||||
|
export const rejectBtn =
|
||||||
|
"bg-[#ffffff] rounded-sm shadow-md text-[12px] font-semibold uppercase text-black py-1.5 px-4 focus:outline-none text-center border-[1px] border-[#b4b4b4]";
|
||||||
|
export const submitBtn =
|
||||||
|
"bg-[#32a3ac] rounded-sm shadow-md text-[12px] font-semibold uppercase text-white py-1.5 px-4 focus:outline-none text-center";
|
||||||
|
export const modalSubmitBtnColor = "#17a2b8";
|
||||||
|
export const modalCancelBtnColor = "white";
|
||||||
@@ -4,4 +4,15 @@
|
|||||||
|
|
||||||
body{
|
body{
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Custom CSS to hide scrollbar */
|
||||||
|
.hide-scrollbar::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hide-scrollbar {
|
||||||
|
-ms-overflow-style: none; /* IE and Edge */
|
||||||
|
scrollbar-width: none; /* Firefox */
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,584 +1,26 @@
|
|||||||
import Parse from "parse";
|
import { documentCls, templateCls } from "../constant/const";
|
||||||
export const formJson = (id) => {
|
export const formJson = {
|
||||||
let formData;
|
|
||||||
//json form for signYourself
|
//json form for signYourself
|
||||||
if (id === "sHAnZphf69") {
|
sHAnZphf69: {
|
||||||
formData = {
|
title: "Sign Yourself",
|
||||||
jsonSchema: {
|
redirectRoute: "signaturePdf",
|
||||||
title: "Sign Yourself",
|
msgVar: "Document",
|
||||||
description: "",
|
Cls: documentCls
|
||||||
type: "object",
|
},
|
||||||
required: ["URL", "Name"],
|
|
||||||
properties: {
|
|
||||||
URL: {
|
|
||||||
type: "string",
|
|
||||||
title: "Select Document",
|
|
||||||
filetypes: [],
|
|
||||||
maxfilesizeKB: "10000",
|
|
||||||
uploadtype: "regular",
|
|
||||||
helpbody: "",
|
|
||||||
helplink: ""
|
|
||||||
},
|
|
||||||
Name: {
|
|
||||||
type: "string",
|
|
||||||
title: "Title",
|
|
||||||
maxLength: 50
|
|
||||||
},
|
|
||||||
Description: {
|
|
||||||
type: "string",
|
|
||||||
title: "Description",
|
|
||||||
maxLength: 500
|
|
||||||
},
|
|
||||||
Folder: {
|
|
||||||
title: "Folder",
|
|
||||||
parent: null,
|
|
||||||
data: {
|
|
||||||
ClassName: "contracts_Document",
|
|
||||||
FolderNameField: "Name",
|
|
||||||
FolderTypeField: "Type",
|
|
||||||
FolderTypeValue: "Folder",
|
|
||||||
FolderDescription: "Description",
|
|
||||||
ParentFolderField: "Folder",
|
|
||||||
FormId: "YjIB7W7Xs6",
|
|
||||||
Query: 'where={"Folder":{"$exists":false},"Type":"Folder"}'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ExtUserPtr: {
|
|
||||||
data: {
|
|
||||||
valueKey: "objectId",
|
|
||||||
isPointer: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
uiSchema: {
|
|
||||||
URL: {
|
|
||||||
"ui:field": "FileUpload"
|
|
||||||
},
|
|
||||||
Description: {
|
|
||||||
"ui:widget": "textarea",
|
|
||||||
"ui:options": {
|
|
||||||
rows: 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Note: {
|
|
||||||
"ui:widget": "textarea",
|
|
||||||
"ui:options": {
|
|
||||||
rows: 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Folder: {
|
|
||||||
"ui:field": "FolderComponent"
|
|
||||||
},
|
|
||||||
ExtUserPtr: {
|
|
||||||
"ui:field": "HiddenField"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
userSchema: {},
|
|
||||||
rules: null,
|
|
||||||
noValidate: false,
|
|
||||||
liveValidate: false,
|
|
||||||
isRegisterForm: false,
|
|
||||||
help: { htmlbody: "" },
|
|
||||||
description: "",
|
|
||||||
class: "contracts_Document",
|
|
||||||
buttons: {
|
|
||||||
add: {
|
|
||||||
resetText: "Reset",
|
|
||||||
submitText: "Submit"
|
|
||||||
},
|
|
||||||
edit: { submitText: "Update", cancelText: "Cancel" }
|
|
||||||
},
|
|
||||||
formACL: {
|
|
||||||
"#currentUser#": { read: true, write: true },
|
|
||||||
"*": { read: true, write: true }
|
|
||||||
},
|
|
||||||
redirect_id:
|
|
||||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/signaturePdf",
|
|
||||||
success_message: "Success!",
|
|
||||||
success_redirect: "Microapp",
|
|
||||||
validFunction:
|
|
||||||
"ZnVuY3Rpb24gdmFsaWRhdGUoZm9ybURhdGEsIGVycm9ycykgeyBpZiAoZm9ybURhdGEucGFzczEgIT09IGZvcm1EYXRhLnBhc3MyKSB7IGVycm9ycy5wYXNzMi5hZGRFcnJvcignUGFzc3dvcmRzIGRvbid0IG1hdGNoJyk7IH0gcmV0dXJuIGVycm9yczsgfQ=="
|
|
||||||
};
|
|
||||||
|
|
||||||
return formData;
|
//json form for request signatures
|
||||||
}
|
"8mZzFxbG1z": {
|
||||||
//json form for request signature
|
title: "Request Signatures",
|
||||||
else if (id === "8mZzFxbG1z") {
|
msgVar: "Document",
|
||||||
const user = Parse.User.current();
|
redirectRoute: "placeHolderSign",
|
||||||
const userPtr = JSON.stringify({
|
Cls: documentCls,
|
||||||
__type: "Pointer",
|
signers: true
|
||||||
className: "_User",
|
},
|
||||||
objectId: user.id
|
//json form for template
|
||||||
});
|
template: {
|
||||||
formData = {
|
title: "New Template",
|
||||||
jsonSchema: {
|
redirectRoute: "template",
|
||||||
title: "New Document",
|
msgVar: "Template",
|
||||||
description: "",
|
Cls: templateCls
|
||||||
type: "object",
|
|
||||||
required: ["URL", "Name", "Note", "TimeToCompleteDays", "Signers"],
|
|
||||||
properties: {
|
|
||||||
URL: {
|
|
||||||
type: "string",
|
|
||||||
title: "Select Document",
|
|
||||||
filetypes: [],
|
|
||||||
maxfilesizeKB: "5000",
|
|
||||||
uploadtype: "regular",
|
|
||||||
helpbody: "",
|
|
||||||
helplink: ""
|
|
||||||
},
|
|
||||||
Name: {
|
|
||||||
type: "string",
|
|
||||||
title: "Title",
|
|
||||||
maxLength: 100
|
|
||||||
},
|
|
||||||
Description: {
|
|
||||||
type: "string",
|
|
||||||
title: "Description",
|
|
||||||
maxLength: 500
|
|
||||||
},
|
|
||||||
Signers: {
|
|
||||||
type: "array",
|
|
||||||
title: "Signers",
|
|
||||||
isSortable: false,
|
|
||||||
selectAll: false,
|
|
||||||
selectedData: null,
|
|
||||||
data: {
|
|
||||||
class: "contracts_Contactbook",
|
|
||||||
displayKey: "Name",
|
|
||||||
valueKey: "objectId",
|
|
||||||
query: `where={"CreatedBy":${userPtr},"IsDeleted":{"$ne":true}}&keys=Name`,
|
|
||||||
isPointer: true,
|
|
||||||
helpbody: "",
|
|
||||||
helplink: "",
|
|
||||||
quickAddFormId: "qUGywSWd8e"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Note: {
|
|
||||||
type: "string",
|
|
||||||
title: "Note",
|
|
||||||
default: "Please review and sign this document",
|
|
||||||
maxLength: 500
|
|
||||||
},
|
|
||||||
Folder: {
|
|
||||||
title: "Folder",
|
|
||||||
data: {
|
|
||||||
ClassName: "contracts_Document",
|
|
||||||
FolderNameField: "Name",
|
|
||||||
FolderTypeField: "Type",
|
|
||||||
FolderTypeValue: "Folder",
|
|
||||||
FolderDescription: "Description",
|
|
||||||
ParentFolderField: "Folder",
|
|
||||||
FormId: "YjIB7W7Xs6",
|
|
||||||
Query: 'where={"Folder":{"$exists":false},"Type":"Folder"}'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
TimeToCompleteDays: {
|
|
||||||
type: "number",
|
|
||||||
title: "Time To Complete (Days)",
|
|
||||||
default: 15,
|
|
||||||
maxLength: 5000
|
|
||||||
},
|
|
||||||
ExtUserPtr: {
|
|
||||||
data: {
|
|
||||||
valueKey: "objectId",
|
|
||||||
isPointer: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
uiSchema: {
|
|
||||||
URL: {
|
|
||||||
"ui:field": "FileUpload"
|
|
||||||
},
|
|
||||||
Description: {
|
|
||||||
"ui:widget": "textarea",
|
|
||||||
"ui:options": {
|
|
||||||
rows: 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Note: {
|
|
||||||
"ui:widget": "textarea",
|
|
||||||
"ui:options": {
|
|
||||||
rows: 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Signers: {
|
|
||||||
"ui:field": "MultiSelectField"
|
|
||||||
},
|
|
||||||
Folder: {
|
|
||||||
"ui:field": "FolderComponent"
|
|
||||||
},
|
|
||||||
TimeToCompleteDays: {
|
|
||||||
"ui:placeholder": "No. of days",
|
|
||||||
"ui:widget": "updown"
|
|
||||||
},
|
|
||||||
ExtUserPtr: {
|
|
||||||
"ui:field": "HiddenField"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
userSchema: {},
|
|
||||||
rules: null,
|
|
||||||
noValidate: false,
|
|
||||||
liveValidate: false,
|
|
||||||
isRegisterForm: false,
|
|
||||||
help: { htmlbody: "" },
|
|
||||||
description: "",
|
|
||||||
class: "contracts_Document",
|
|
||||||
buttons: {
|
|
||||||
add: {
|
|
||||||
resetText: "Reset",
|
|
||||||
submitText: "Submit"
|
|
||||||
},
|
|
||||||
edit: { submitText: "Update", cancelText: "Cancel" }
|
|
||||||
},
|
|
||||||
formACL: {
|
|
||||||
"#currentUser#": { read: true, write: true },
|
|
||||||
"*": { read: true, write: true }
|
|
||||||
},
|
|
||||||
redirect_id:
|
|
||||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/placeHolderSign",
|
|
||||||
success_message: "Success!",
|
|
||||||
success_redirect: "Microapp",
|
|
||||||
validFunction:
|
|
||||||
"ZnVuY3Rpb24gdmFsaWRhdGUoZm9ybURhdGEsIGVycm9ycykgeyBpZiAoZm9ybURhdGEucGFzczEgIT09IGZvcm1EYXRhLnBhc3MyKSB7IGVycm9ycy5wYXNzMi5hZGRFcnJvcignUGFzc3dvcmRzIGRvbid0IG1hdGNoJyk7IH0gcmV0dXJuIGVycm9yczsgfQ=="
|
|
||||||
};
|
|
||||||
|
|
||||||
return formData;
|
|
||||||
}
|
|
||||||
//json form for create new folder
|
|
||||||
else if (id === "YjIB7W7Xs6") {
|
|
||||||
formData = {
|
|
||||||
jsonSchema: {
|
|
||||||
title: "New Folder",
|
|
||||||
description: "",
|
|
||||||
type: "object",
|
|
||||||
required: ["Name"],
|
|
||||||
properties: {
|
|
||||||
Name: {
|
|
||||||
type: "string",
|
|
||||||
title: "Name",
|
|
||||||
maxLength: 50
|
|
||||||
},
|
|
||||||
Type: {
|
|
||||||
type: "string",
|
|
||||||
data: {
|
|
||||||
valueKey: "Type",
|
|
||||||
isPointer: false
|
|
||||||
},
|
|
||||||
default: "Folder"
|
|
||||||
},
|
|
||||||
Folder: {
|
|
||||||
title: "Parent Folder",
|
|
||||||
data: {
|
|
||||||
class: "contracts_Document",
|
|
||||||
displayKey: "Name",
|
|
||||||
valueKey: "objectId",
|
|
||||||
query: 'where={"Type":"Folder"}&keys=Name',
|
|
||||||
isPointer: true,
|
|
||||||
savePointerClass: "",
|
|
||||||
helpbody: "",
|
|
||||||
helplink: ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
uiSchema: {
|
|
||||||
Type: {
|
|
||||||
"ui:field": "HiddenField"
|
|
||||||
},
|
|
||||||
Folder: {
|
|
||||||
"ui:field": "Level1Dropdown"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
userSchema: {},
|
|
||||||
rules: null,
|
|
||||||
noValidate: false,
|
|
||||||
liveValidate: false,
|
|
||||||
isRegisterForm: false,
|
|
||||||
help: { htmlbody: "" },
|
|
||||||
description: "",
|
|
||||||
class: "contracts_Document",
|
|
||||||
buttons: {
|
|
||||||
add: {
|
|
||||||
resetText: "Reset",
|
|
||||||
submitText: "Submit"
|
|
||||||
},
|
|
||||||
edit: { submitText: "Update", cancelText: "Cancel" }
|
|
||||||
},
|
|
||||||
formACL: {
|
|
||||||
"#currentUser#": { read: true, write: true },
|
|
||||||
"*": { read: true, write: true }
|
|
||||||
},
|
|
||||||
redirect_id: "",
|
|
||||||
success_message: "Success!",
|
|
||||||
success_redirect: "",
|
|
||||||
validFunction:
|
|
||||||
"ZnVuY3Rpb24gdmFsaWRhdGUoZm9ybURhdGEsIGVycm9ycykgeyBpZiAoZm9ybURhdGEucGFzczEgIT09IGZvcm1EYXRhLnBhc3MyKSB7IGVycm9ycy5wYXNzMi5hZGRFcnJvcignUGFzc3dvcmRzIGRvbid0IG1hdGNoJyk7IH0gcmV0dXJuIGVycm9yczsgfQ=="
|
|
||||||
};
|
|
||||||
return formData;
|
|
||||||
}
|
|
||||||
//json form for add signers
|
|
||||||
else if (id === "fICciRuUcB") {
|
|
||||||
formData = {
|
|
||||||
jsonSchema: {
|
|
||||||
title: "Add Signer",
|
|
||||||
description: "",
|
|
||||||
type: "object",
|
|
||||||
required: ["Name", "Email", "Phone", "Company"],
|
|
||||||
properties: {
|
|
||||||
Name: {
|
|
||||||
type: "string",
|
|
||||||
title: "Name",
|
|
||||||
maxLength: 50
|
|
||||||
},
|
|
||||||
Email: {
|
|
||||||
type: "string",
|
|
||||||
title: "Email",
|
|
||||||
maxLength: 50
|
|
||||||
},
|
|
||||||
Phone: {
|
|
||||||
type: "string",
|
|
||||||
title: "Phone",
|
|
||||||
maxLength: 50
|
|
||||||
},
|
|
||||||
Company: {
|
|
||||||
type: "string",
|
|
||||||
title: "Company",
|
|
||||||
maxLength: 50
|
|
||||||
},
|
|
||||||
JobTitle: {
|
|
||||||
type: "string",
|
|
||||||
title: "JobTitle",
|
|
||||||
maxLength: 50
|
|
||||||
},
|
|
||||||
IsContactEntry: {
|
|
||||||
type: "boolean",
|
|
||||||
data: {
|
|
||||||
valueKey: "IsContactEntry",
|
|
||||||
isPointer: false
|
|
||||||
},
|
|
||||||
default: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
uiSchema: {
|
|
||||||
Email: {
|
|
||||||
"ui:widget": "email"
|
|
||||||
},
|
|
||||||
IsContactEntry: {
|
|
||||||
"ui:field": "HiddenField"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
userSchema: {
|
|
||||||
email: "$Email",
|
|
||||||
name: "$Name",
|
|
||||||
password: "$Phone",
|
|
||||||
phone: "$Phone",
|
|
||||||
role: "contracts_User",
|
|
||||||
username: "$Email"
|
|
||||||
},
|
|
||||||
rules: null,
|
|
||||||
noValidate: false,
|
|
||||||
liveValidate: false,
|
|
||||||
isRegisterForm: true,
|
|
||||||
help: {},
|
|
||||||
description: "",
|
|
||||||
class: "contracts_Users",
|
|
||||||
buttons: {
|
|
||||||
add: {
|
|
||||||
resetText: "Reset",
|
|
||||||
submitText: "Submit"
|
|
||||||
},
|
|
||||||
edit: { submitText: "Update", cancelText: "Cancel" }
|
|
||||||
},
|
|
||||||
formACL: {
|
|
||||||
"#currentUser#": { read: true, write: true },
|
|
||||||
"*": { read: true, write: true }
|
|
||||||
},
|
|
||||||
redirect_id: "",
|
|
||||||
success_message: "Success!",
|
|
||||||
success_redirect: "",
|
|
||||||
validFunction:
|
|
||||||
"ZnVuY3Rpb24gdmFsaWRhdGUoZm9ybURhdGEsIGVycm9ycykgeyBpZiAoZm9ybURhdGEucGFzczEgIT09IGZvcm1EYXRhLnBhc3MyKSB7IGVycm9ycy5wYXNzMi5hZGRFcnJvcignUGFzc3dvcmRzIGRvbid0IG1hdGNoJyk7IH0gcmV0dXJuIGVycm9yczsgfQ=="
|
|
||||||
};
|
|
||||||
return formData;
|
|
||||||
}
|
|
||||||
//json form for add users
|
|
||||||
else if (id === "lM0xRnM3iE") {
|
|
||||||
formData = {
|
|
||||||
jsonSchema: {
|
|
||||||
title: "Add User",
|
|
||||||
description: "",
|
|
||||||
type: "object",
|
|
||||||
required: ["Name", "Email", "Phone", "JobTitle"],
|
|
||||||
properties: {
|
|
||||||
Name: {
|
|
||||||
type: "string",
|
|
||||||
title: "Name",
|
|
||||||
maxLength: 50
|
|
||||||
},
|
|
||||||
Email: {
|
|
||||||
type: "string",
|
|
||||||
title: "Email",
|
|
||||||
maxLength: 50
|
|
||||||
},
|
|
||||||
Phone: {
|
|
||||||
type: "string",
|
|
||||||
title: "Phone",
|
|
||||||
maxLength: 50
|
|
||||||
},
|
|
||||||
JobTitle: {
|
|
||||||
type: "string",
|
|
||||||
title: "Job Title",
|
|
||||||
maxLength: 50
|
|
||||||
},
|
|
||||||
Company: {
|
|
||||||
type: "string",
|
|
||||||
title: "Company",
|
|
||||||
maxLength: 50
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
uiSchema: {
|
|
||||||
Email: {
|
|
||||||
"ui:widget": "email"
|
|
||||||
},
|
|
||||||
Phone: {
|
|
||||||
"ui:options": {
|
|
||||||
inputType: "tel"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
userSchema: {
|
|
||||||
email: "$Email",
|
|
||||||
name: "$Name",
|
|
||||||
password: "$Phone",
|
|
||||||
phone: "$Phone",
|
|
||||||
role: "contracts_User",
|
|
||||||
username: "$Email"
|
|
||||||
},
|
|
||||||
rules: null,
|
|
||||||
noValidate: false,
|
|
||||||
liveValidate: false,
|
|
||||||
isRegisterForm: true,
|
|
||||||
help: {},
|
|
||||||
description: "",
|
|
||||||
class: "contracts_Users",
|
|
||||||
buttons: {
|
|
||||||
add: {
|
|
||||||
resetText: "Reset",
|
|
||||||
submitText: "Submit"
|
|
||||||
},
|
|
||||||
edit: { submitText: "Update", cancelText: "Cancel" }
|
|
||||||
},
|
|
||||||
formACL: {
|
|
||||||
"#currentUser#": { read: true, write: true },
|
|
||||||
"*": { read: true, write: true }
|
|
||||||
},
|
|
||||||
redirect_id: "",
|
|
||||||
success_message: "Success!",
|
|
||||||
success_redirect: "",
|
|
||||||
validFunction:
|
|
||||||
"ZnVuY3Rpb24gdmFsaWRhdGUoZm9ybURhdGEsIGVycm9ycykgeyBpZiAoZm9ybURhdGEucGFzczEgIT09IGZvcm1EYXRhLnBhc3MyKSB7IGVycm9ycy5wYXNzMi5hZGRFcnJvcignUGFzc3dvcmRzIGRvbid0IG1hdGNoJyk7IH0gcmV0dXJuIGVycm9yczsgfQ=="
|
|
||||||
};
|
|
||||||
return formData;
|
|
||||||
} else if (id === "qUGywSWd8e") {
|
|
||||||
formData = {
|
|
||||||
jsonSchema: {
|
|
||||||
title: "Add Contact",
|
|
||||||
description: "",
|
|
||||||
type: "object",
|
|
||||||
required: ["Name", "Email", "Phone"],
|
|
||||||
properties: {
|
|
||||||
Name: {
|
|
||||||
type: "string",
|
|
||||||
title: "Name",
|
|
||||||
maxLength: 50
|
|
||||||
},
|
|
||||||
Email: {
|
|
||||||
type: "string",
|
|
||||||
title: "Email",
|
|
||||||
maxLength: 50
|
|
||||||
},
|
|
||||||
Phone: {
|
|
||||||
type: "string",
|
|
||||||
title: "Phone",
|
|
||||||
maxLength: 50
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
uiSchema: {
|
|
||||||
Email: {
|
|
||||||
"ui:widget": "email"
|
|
||||||
},
|
|
||||||
Phone: {
|
|
||||||
"ui:options": {
|
|
||||||
inputType: "tel"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
userSchema: {
|
|
||||||
name: "$Name",
|
|
||||||
username: "$Email",
|
|
||||||
email: "$Email",
|
|
||||||
password: "$Phone",
|
|
||||||
phone: "$Phone",
|
|
||||||
role: "contracts_Guest"
|
|
||||||
},
|
|
||||||
restrict_form_entry: {
|
|
||||||
enable_captcha: false,
|
|
||||||
allow_one_entry_per_ip_address: false,
|
|
||||||
allow_one_entry_per_user: false,
|
|
||||||
enable_geo_fence: false
|
|
||||||
},
|
|
||||||
restrict_form_access: {
|
|
||||||
entryCount: ""
|
|
||||||
},
|
|
||||||
help: {},
|
|
||||||
email_template: {
|
|
||||||
from: "",
|
|
||||||
to: "",
|
|
||||||
subject: "",
|
|
||||||
message: ""
|
|
||||||
},
|
|
||||||
buttons: {
|
|
||||||
add: {
|
|
||||||
submitText: "Submit",
|
|
||||||
resetText: "Reset"
|
|
||||||
},
|
|
||||||
edit: {
|
|
||||||
submitText: "Update",
|
|
||||||
cancelText: "Cancel"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
appId: {
|
|
||||||
__type: "Pointer",
|
|
||||||
className: "w_appinfo",
|
|
||||||
objectId: "aIPmIvMzGM"
|
|
||||||
},
|
|
||||||
formACL: {
|
|
||||||
"*": {
|
|
||||||
read: true,
|
|
||||||
write: true
|
|
||||||
},
|
|
||||||
"#currentUser#": {
|
|
||||||
read: true,
|
|
||||||
write: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
class: "contracts_Contactbook",
|
|
||||||
description: "",
|
|
||||||
success_message: "Success!",
|
|
||||||
form_permission: "private",
|
|
||||||
success_redirect: "",
|
|
||||||
redirect_id: "",
|
|
||||||
isRegisterForm: true,
|
|
||||||
liveValidate: false,
|
|
||||||
noValidate: false,
|
|
||||||
validFunction:
|
|
||||||
"ZnVuY3Rpb24gdmFsaWRhdGUoZm9ybURhdGEsIGVycm9ycykgeyBpZiAoZm9ybURhdGEucGFzczEgIT09IGZvcm1EYXRhLnBhc3MyKSB7IGVycm9ycy5wYXNzMi5hZGRFcnJvcignUGFzc3dvcmRzIGRvbid0IG1hdGNoJyk7IH0gcmV0dXJuIGVycm9yczsgfQ=="
|
|
||||||
};
|
|
||||||
return formData;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
export default function reportJson(id) {
|
export default function reportJson(id) {
|
||||||
// console.log("json ", json);
|
// console.log("json ", json);
|
||||||
const head = ["Sr.No", "Name", "Note", "Folder", "File", "Owner", "Signers"];
|
const head = ["Sr.No", "Title", "Note", "Folder", "File", "Owner", "Signers"];
|
||||||
const contactbook = ["Sr.No", "Name", "Email", "Phone"];
|
const contactbook = ["Sr.No", "Title", "Email", "Phone"];
|
||||||
|
const dashboardReportHead = ["Title", "File", "Owner", "Signers"];
|
||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
// draft documents report
|
// draft documents report
|
||||||
case "ByHuevtCFY":
|
case "ByHuevtCFY":
|
||||||
@@ -103,7 +105,7 @@ export default function reportJson(id) {
|
|||||||
case "d9k3UfYHBc":
|
case "d9k3UfYHBc":
|
||||||
return {
|
return {
|
||||||
reportName: "Recently sent for signatures",
|
reportName: "Recently sent for signatures",
|
||||||
heading: head,
|
heading: dashboardReportHead,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
btnLabel: "View",
|
btnLabel: "View",
|
||||||
@@ -119,7 +121,7 @@ export default function reportJson(id) {
|
|||||||
case "5Go51Q7T8r":
|
case "5Go51Q7T8r":
|
||||||
return {
|
return {
|
||||||
reportName: "Recent signature requests",
|
reportName: "Recent signature requests",
|
||||||
heading: head,
|
heading: dashboardReportHead,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
btnLabel: "Sign",
|
btnLabel: "Sign",
|
||||||
@@ -135,7 +137,7 @@ export default function reportJson(id) {
|
|||||||
case "kC5mfynCi4":
|
case "kC5mfynCi4":
|
||||||
return {
|
return {
|
||||||
reportName: "Drafts",
|
reportName: "Drafts",
|
||||||
heading: head,
|
heading: ["Title", "Note", "Folder", "File", "Owner", "Signers"],
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
btnLabel: "sign",
|
btnLabel: "sign",
|
||||||
@@ -159,6 +161,31 @@ export default function reportJson(id) {
|
|||||||
textColor: "white",
|
textColor: "white",
|
||||||
btnIcon: "fa-solid fa-trash"
|
btnIcon: "fa-solid fa-trash"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
form: "ContactBook"
|
||||||
|
};
|
||||||
|
// template report
|
||||||
|
case "6TeaPr321t":
|
||||||
|
return {
|
||||||
|
reportName: "Templates",
|
||||||
|
heading: head,
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
btnLabel: "Use",
|
||||||
|
btnColor: "#4bd396",
|
||||||
|
textColor: "white",
|
||||||
|
btnIcon: "fa fa-plus",
|
||||||
|
redirectUrl:
|
||||||
|
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/placeHolderSign"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
btnLabel: "Edit",
|
||||||
|
btnColor: "#00c9d5",
|
||||||
|
textColor: "white",
|
||||||
|
btnIcon: "fa fa-plus",
|
||||||
|
redirectUrl:
|
||||||
|
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/template"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -27,13 +27,13 @@
|
|||||||
"planName": "THANKS PLAN",
|
"planName": "THANKS PLAN",
|
||||||
"currency": "$",
|
"currency": "$",
|
||||||
"price": "29.99",
|
"price": "29.99",
|
||||||
"subtitle": "Use code 'FREEBETA' to get this for free(First 1000 users)",
|
"subtitle": "Use code <span style='background-color: yellow;'>'FREEBETA'</span> to get this for free(First 1000 users)",
|
||||||
"btnText": "Subscribe",
|
"btnText": "Subscribe",
|
||||||
"url": "https://subscriptions.zoho.in/subscribe/ef798486e6a0a11ea65f2bae8f2af901dbadf3175d495584fd25b9af5d2f2b9e/thanks",
|
"url": "https://subscriptions.zoho.in/subscribe/ef798486e6a0a11ea65f2bae8f2af901dbadf3175d495584fd25b9af5d2f2b9e/thanks",
|
||||||
"target": "_self",
|
"target": "_self",
|
||||||
"benefits": [
|
"benefits": [
|
||||||
"Sign Unlimited Documents",
|
"Sign Unlimited Documents",
|
||||||
"Unlimited Secure Doc Storage with OpenSignDrive",
|
"Unlimited Secure Doc Storage with OpenSign™ Drive",
|
||||||
"Unlimited Guest Signers",
|
"Unlimited Guest Signers",
|
||||||
"Unlimited completion certificates",
|
"Unlimited completion certificates",
|
||||||
"Unique Code(OTP) verification for guest signers",
|
"Unique Code(OTP) verification for guest signers",
|
||||||
|
|||||||
@@ -7,10 +7,37 @@ import Tour from "reactour";
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
const HomeLayout = ({ children }) => {
|
import ModalUi from "../primitives/ModalUi";
|
||||||
|
import { useNavigate, useLocation, Outlet } from "react-router-dom";
|
||||||
|
|
||||||
|
const HomeLayout = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const location = useLocation();
|
||||||
const { width } = useWindowSize();
|
const { width } = useWindowSize();
|
||||||
const [isOpen, setIsOpen] = useState(true);
|
const [isOpen, setIsOpen] = useState(true);
|
||||||
const arr = useSelector((state) => state.TourSteps);
|
const arr = useSelector((state) => state.TourSteps);
|
||||||
|
const [isUserValid, setIsUserValid] = useState(true);
|
||||||
|
const [isLoader, setIsLoader] = useState(true);
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
// Use the session token to validate the user
|
||||||
|
const userQuery = new Parse.Query(Parse.User);
|
||||||
|
const user = await userQuery.get(Parse.User.current().id, {
|
||||||
|
sessionToken: localStorage.getItem("accesstoken")
|
||||||
|
});
|
||||||
|
if (user) {
|
||||||
|
setIsUserValid(true);
|
||||||
|
setIsLoader(false);
|
||||||
|
} else {
|
||||||
|
setIsUserValid(false);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Session token is invalid or there was an error
|
||||||
|
setIsUserValid(false);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}, []);
|
||||||
|
|
||||||
// reactour state
|
// reactour state
|
||||||
const [isCloseBtn, setIsCloseBtn] = useState(true);
|
const [isCloseBtn, setIsCloseBtn] = useState(true);
|
||||||
@@ -19,7 +46,7 @@ const HomeLayout = ({ children }) => {
|
|||||||
const [tourConfigs, setTourConfigs] = useState([]);
|
const [tourConfigs, setTourConfigs] = useState([]);
|
||||||
|
|
||||||
const showSidebar = () => {
|
const showSidebar = () => {
|
||||||
setIsOpen(value => !value);
|
setIsOpen((value) => !value);
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (width && width <= 768) {
|
if (width && width <= 768) {
|
||||||
@@ -28,9 +55,7 @@ const HomeLayout = ({ children }) => {
|
|||||||
}, [width]);
|
}, [width]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (localStorage.getItem("domain") === "sign" && arr && arr.length > 0) {
|
if (
|
||||||
handleDynamicSteps();
|
|
||||||
} else if (
|
|
||||||
localStorage.getItem("domain") === "contracts" &&
|
localStorage.getItem("domain") === "contracts" &&
|
||||||
arr &&
|
arr &&
|
||||||
arr.length > 0
|
arr.length > 0
|
||||||
@@ -153,32 +178,80 @@ const HomeLayout = ({ children }) => {
|
|||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleLoginBtn = () => {
|
||||||
|
try {
|
||||||
|
Parse.User.logOut();
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err ", err);
|
||||||
|
} finally {
|
||||||
|
localStorage.removeItem("accesstoken");
|
||||||
|
navigate("/", { replace: true, state: { from: location } });
|
||||||
|
}
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="sticky top-0 z-50">
|
<div className="sticky top-0 z-50">
|
||||||
<Header showSidebar={showSidebar} />
|
<Header showSidebar={showSidebar} />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex md:flex-row flex-col z-50">
|
{isUserValid ? (
|
||||||
<Sidebar isOpen={isOpen} closeSidebar={closeSidebar} />
|
<>
|
||||||
|
{isLoader ? (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: "100vh",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: "45px",
|
||||||
|
color: "#3dd3e0"
|
||||||
|
}}
|
||||||
|
className="loader-37"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div className="flex md:flex-row flex-col z-50">
|
||||||
|
<Sidebar isOpen={isOpen} closeSidebar={closeSidebar} />
|
||||||
|
|
||||||
<div className="relative h-screen flex flex-col justify-between w-full overflow-y-auto">
|
<div className="relative h-screen flex flex-col justify-between w-full overflow-y-auto">
|
||||||
<div className="bg-[#eef1f5] p-3">{children}</div>
|
<div className="bg-[#eef1f5] p-3">{<Outlet />}</div>
|
||||||
<div className="z-30">
|
<div className="z-30">
|
||||||
<Footer />
|
<Footer />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Tour
|
||||||
|
onRequestClose={closeTour}
|
||||||
|
steps={tourConfigs}
|
||||||
|
isOpen={isTour}
|
||||||
|
closeWithMask={false}
|
||||||
|
disableKeyboardNavigation={["esc"]}
|
||||||
|
// disableInteraction={true}
|
||||||
|
scrollOffset={-100}
|
||||||
|
rounded={5}
|
||||||
|
showCloseButton={isCloseBtn}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<ModalUi title={"Session Expired"} isOpen={true} showClose={false}>
|
||||||
|
<div className="flex flex-col justify-center items-center py-4 md:py-5 gap-5">
|
||||||
|
<p className="text-xl font-normal">Your session has expired.</p>
|
||||||
|
<button
|
||||||
|
onClick={handleLoginBtn}
|
||||||
|
className="text-base px-3 py-1.5 rounded shadow-md text-white bg-[#1ab6ce]"
|
||||||
|
>
|
||||||
|
Login
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</ModalUi>
|
||||||
</div>
|
)}
|
||||||
<Tour
|
|
||||||
onRequestClose={closeTour}
|
|
||||||
steps={tourConfigs}
|
|
||||||
isOpen={isTour}
|
|
||||||
closeWithMask={false}
|
|
||||||
disableKeyboardNavigation={["esc"]}
|
|
||||||
// disableInteraction={true}
|
|
||||||
scrollOffset={-100}
|
|
||||||
rounded={5}
|
|
||||||
showCloseButton={isCloseBtn}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
const Alert = ({ children, type }) => {
|
||||||
|
const textcolor = type ? theme(type) : theme();
|
||||||
|
function theme(color) {
|
||||||
|
switch (color) {
|
||||||
|
case "success":
|
||||||
|
return "border-[#c3e6cb] bg-[#d4edda] text-[#155724]";
|
||||||
|
case "info":
|
||||||
|
return "border-[#adcdeb] bg-[#c1daf0] text-[#153756]";
|
||||||
|
case "danger":
|
||||||
|
return "border-[#f0a8a8] bg-[#f4bebe] text-[#c42121]";
|
||||||
|
default:
|
||||||
|
return "border-[#d6d6d6] bg-[#d9d9d9] text-[#575757]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{children && (
|
||||||
|
<div
|
||||||
|
className={`z-40 fixed top-20 left-1/2 transform -translate-x-1/2 border-[1px] text-sm ${textcolor} rounded py-[.75rem] px-[1.25rem] `}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Alert;
|
||||||
@@ -3,6 +3,9 @@ import pad from "../assets/images/pad.svg";
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import "../styles/report.css";
|
import "../styles/report.css";
|
||||||
|
import ModalUi from "./ModalUi";
|
||||||
|
import AppendFormInForm from "../components/AppendFormInForm";
|
||||||
|
import { modalSubmitBtnColor, modalCancelBtnColor } from "../constant/const";
|
||||||
const ReportTable = ({
|
const ReportTable = ({
|
||||||
ReportName,
|
ReportName,
|
||||||
List,
|
List,
|
||||||
@@ -11,13 +14,19 @@ const ReportTable = ({
|
|||||||
heading,
|
heading,
|
||||||
setIsNextRecord,
|
setIsNextRecord,
|
||||||
isMoreDocs,
|
isMoreDocs,
|
||||||
docPerPage
|
docPerPage,
|
||||||
|
form
|
||||||
}) => {
|
}) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [actLoader, setActLoader] = useState({});
|
const [actLoader, setActLoader] = useState({});
|
||||||
const [isAlert, setIsAlert] = useState(false);
|
const [isAlert, setIsAlert] = useState(false);
|
||||||
const [isErr, setIsErr] = useState(false);
|
const [isErr, setIsErr] = useState(false);
|
||||||
|
const [isDocErr, setIsDocErr] = useState(false);
|
||||||
|
const [isContactform, setIsContactform] = useState(false);
|
||||||
|
const [isDeleteModal, setIsDeleteModal] = useState({});
|
||||||
|
const startIndex = (currentPage - 1) * docPerPage;
|
||||||
|
|
||||||
// For loop is used to calculate page numbers visible below table
|
// For loop is used to calculate page numbers visible below table
|
||||||
// Initialize pageNumbers using useMemo to avoid unnecessary re-creation
|
// Initialize pageNumbers using useMemo to avoid unnecessary re-creation
|
||||||
const pageNumbers = useMemo(() => {
|
const pageNumbers = useMemo(() => {
|
||||||
@@ -55,39 +64,128 @@ const ReportTable = ({
|
|||||||
}, [isMoreDocs, pageNumbers, currentPage, setIsNextRecord]);
|
}, [isMoreDocs, pageNumbers, currentPage, setIsNextRecord]);
|
||||||
|
|
||||||
// `handlemicroapp` is used to open microapp
|
// `handlemicroapp` is used to open microapp
|
||||||
const handlemicroapp = (item, url) => {
|
const handlemicroapp = async (item, url, btnLabel) => {
|
||||||
localStorage.removeItem("rowlevel");
|
if (ReportName === "Templates") {
|
||||||
navigate("/rpmf/" + url);
|
if (btnLabel === "Edit") {
|
||||||
localStorage.setItem("rowlevel", JSON.stringify(item));
|
navigate(`/asmf/${url}/${item.objectId}`);
|
||||||
|
} else {
|
||||||
|
setActLoader({ [`${item.objectId}_${btnLabel}`]: true });
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
templateId: item.objectId
|
||||||
|
};
|
||||||
|
const templateDeatils = await axios.post(
|
||||||
|
`${localStorage.getItem("baseUrl")}functions/getTemplate`,
|
||||||
|
params,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||||
|
sessionToken: localStorage.getItem("accesstoken")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// console.log("templateDeatils.data ", templateDeatils.data);
|
||||||
|
const templateData =
|
||||||
|
templateDeatils.data && templateDeatils.data.result;
|
||||||
|
if (!templateData.error) {
|
||||||
|
const Doc = templateData;
|
||||||
|
|
||||||
|
let signers = [];
|
||||||
|
if (Doc.Signers?.length > 0) {
|
||||||
|
Doc.Signers?.forEach((x) => {
|
||||||
|
if (x.objectId) {
|
||||||
|
const obj = {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "contracts_Contactbook",
|
||||||
|
objectId: x.objectId
|
||||||
|
};
|
||||||
|
signers.push(obj);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let placeholdersArr = [];
|
||||||
|
if (Doc.Placeholders?.length > 0) {
|
||||||
|
placeholdersArr = Doc.Placeholders;
|
||||||
|
const data = {
|
||||||
|
Name: Doc.Name,
|
||||||
|
URL: Doc.URL,
|
||||||
|
SignedUrl: Doc.SignedUrl,
|
||||||
|
Description: Doc.Description,
|
||||||
|
Note: Doc.Note,
|
||||||
|
Placeholders: placeholdersArr,
|
||||||
|
ExtUserPtr: {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "contracts_Users",
|
||||||
|
objectId: Doc.ExtUserPtr.objectId
|
||||||
|
},
|
||||||
|
CreatedBy: {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "_User",
|
||||||
|
objectId: Doc.CreatedBy.objectId
|
||||||
|
},
|
||||||
|
Signers: signers
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const res = await axios.post(
|
||||||
|
`${localStorage.getItem(
|
||||||
|
"baseUrl"
|
||||||
|
)}classes/${localStorage.getItem("_appName")}_Document`,
|
||||||
|
data,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id":
|
||||||
|
localStorage.getItem("parseAppId"),
|
||||||
|
"X-Parse-Session-Token":
|
||||||
|
localStorage.getItem("accesstoken")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// console.log("Res ", res.data);
|
||||||
|
if (res.data && res.data.objectId) {
|
||||||
|
setActLoader({});
|
||||||
|
setIsAlert(true);
|
||||||
|
navigate(`/asmf/${url}/${res.data.objectId}`, {
|
||||||
|
state: { title: "Use Template" }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Err", err);
|
||||||
|
setIsAlert(true);
|
||||||
|
setIsErr(true);
|
||||||
|
setActLoader({});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setIsDocErr(true);
|
||||||
|
setActLoader({});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setIsAlert(true);
|
||||||
|
setIsErr(true);
|
||||||
|
setActLoader({});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err", err);
|
||||||
|
setIsAlert(true);
|
||||||
|
setIsErr(true);
|
||||||
|
setActLoader({});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
localStorage.removeItem("rowlevel");
|
||||||
|
navigate("/rpmf/" + url);
|
||||||
|
localStorage.setItem("rowlevel", JSON.stringify(item));
|
||||||
|
}
|
||||||
|
|
||||||
// localStorage.setItem("rowlevelMicro");
|
// localStorage.setItem("rowlevelMicro");
|
||||||
};
|
};
|
||||||
const handlebtn = async (item) => {
|
const handlebtn = async (item) => {
|
||||||
if (ReportName === "Contactbook") {
|
if (ReportName === "Contactbook") {
|
||||||
setActLoader({ [item.objectId]: true });
|
setIsDeleteModal({ [item.objectId]: true });
|
||||||
try {
|
|
||||||
const url =
|
|
||||||
process.env.REACT_APP_SERVERURL + "/classes/contracts_Contactbook/";
|
|
||||||
const body = { IsDeleted: true };
|
|
||||||
const res = await axios.put(url + item.objectId, body, {
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": localStorage.getItem("AppID12"),
|
|
||||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// console.log("Res ", res.data);
|
|
||||||
if (res.data && res.data.updatedAt) {
|
|
||||||
setActLoader({});
|
|
||||||
setIsAlert(true);
|
|
||||||
const upldatedList = List.filter((x) => x.objectId !== item.objectId);
|
|
||||||
setList(upldatedList);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.log("err", err);
|
|
||||||
setIsAlert(true);
|
|
||||||
setIsErr(true);
|
|
||||||
setActLoader({});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -101,6 +199,44 @@ const ReportTable = ({
|
|||||||
const paginateFront = () => setCurrentPage(currentPage + 1);
|
const paginateFront = () => setCurrentPage(currentPage + 1);
|
||||||
const paginateBack = () => setCurrentPage(currentPage - 1);
|
const paginateBack = () => setCurrentPage(currentPage - 1);
|
||||||
|
|
||||||
|
const handleContactFormModal = () => {
|
||||||
|
setIsContactform(!isContactform);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleUserData = (data) => {
|
||||||
|
setList((prevData) => [data, ...prevData]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDelete = async (item) => {
|
||||||
|
setIsDeleteModal({});
|
||||||
|
setActLoader({ [item.objectId]: true });
|
||||||
|
try {
|
||||||
|
const url =
|
||||||
|
process.env.REACT_APP_SERVERURL + "/classes/contracts_Contactbook/";
|
||||||
|
const body = { IsDeleted: true };
|
||||||
|
const res = await axios.put(url + item.objectId, body, {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": localStorage.getItem("AppID12"),
|
||||||
|
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// console.log("Res ", res.data);
|
||||||
|
if (res.data && res.data.updatedAt) {
|
||||||
|
setActLoader({});
|
||||||
|
setIsAlert(true);
|
||||||
|
const upldatedList = List.filter((x) => x.objectId !== item.objectId);
|
||||||
|
setList(upldatedList);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err", err);
|
||||||
|
setIsAlert(true);
|
||||||
|
setIsErr(true);
|
||||||
|
setActLoader({});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleCloseDeleteModal = () => setIsDeleteModal({});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="p-2 overflow-x-scroll w-full bg-white rounded-md">
|
<div className="p-2 overflow-x-scroll w-full bg-white rounded-md">
|
||||||
{isAlert && (
|
{isAlert && (
|
||||||
@@ -115,7 +251,23 @@ const ReportTable = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<h2 className="text-[23px] font-light my-2">{ReportName}</h2>
|
<div className="flex flex-row items-center justify-between my-2 mx-3 text-[20px] md:text-[23px]">
|
||||||
|
<div className="font-light">{ReportName}</div>
|
||||||
|
{ReportName === "Templates" && (
|
||||||
|
<i
|
||||||
|
onClick={() => navigate("/form/template")}
|
||||||
|
className="fa-solid fa-square-plus text-sky-400 text-[25px]"
|
||||||
|
></i>
|
||||||
|
)}
|
||||||
|
{form && (
|
||||||
|
<div
|
||||||
|
className="cursor-pointer"
|
||||||
|
onClick={() => handleContactFormModal()}
|
||||||
|
>
|
||||||
|
<i className="fa-solid fa-square-plus text-sky-400 text-[25px]"></i>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<table className="table-auto w-full border-collapse">
|
<table className="table-auto w-full border-collapse">
|
||||||
<thead className="text-[14px]">
|
<thead className="text-[14px]">
|
||||||
<tr className="border-y-[1px]">
|
<tr className="border-y-[1px]">
|
||||||
@@ -135,11 +287,13 @@ const ReportTable = ({
|
|||||||
{currentLists.map((item, index) =>
|
{currentLists.map((item, index) =>
|
||||||
ReportName === "Contactbook" ? (
|
ReportName === "Contactbook" ? (
|
||||||
<tr className="border-y-[1px]" key={index}>
|
<tr className="border-y-[1px]" key={index}>
|
||||||
<td className="px-4 py-2">{index + 1}</td>
|
{heading.includes("Sr.No") && (
|
||||||
|
<td className="px-4 py-2">{startIndex + index + 1}</td>
|
||||||
|
)}
|
||||||
<td className="px-4 py-2 font-semibold">{item?.Name} </td>
|
<td className="px-4 py-2 font-semibold">{item?.Name} </td>
|
||||||
<td className="px-4 py-2">{item?.Email || "-"}</td>
|
<td className="px-4 py-2">{item?.Email || "-"}</td>
|
||||||
<td className="px-4 py-2">{item?.Phone || "-"}</td>
|
<td className="px-4 py-2">{item?.Phone || "-"}</td>
|
||||||
<td className="px-4 py-2 flex flex-col justify-center items-center gap-2 text-white">
|
<td className="px-3 py-2 text-white">
|
||||||
{actions?.length > 0 &&
|
{actions?.length > 0 &&
|
||||||
actions.map((act, index) => (
|
actions.map((act, index) => (
|
||||||
<button
|
<button
|
||||||
@@ -149,7 +303,7 @@ const ReportTable = ({
|
|||||||
? handlemicroapp(item, act.redirectUrl)
|
? handlemicroapp(item, act.redirectUrl)
|
||||||
: handlebtn(item)
|
: handlebtn(item)
|
||||||
}
|
}
|
||||||
className={`flex justify-center items-center gap-1 px-2 py-1 rounded shadow`}
|
className={`mb-1 flex justify-center items-center gap-1 px-2 py-1 rounded shadow`}
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: act.btnColor
|
backgroundColor: act.btnColor
|
||||||
? act.btnColor
|
? act.btnColor
|
||||||
@@ -175,16 +329,54 @@ const ReportTable = ({
|
|||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
|
{isDeleteModal[item.objectId] && (
|
||||||
|
<ModalUi
|
||||||
|
isOpen
|
||||||
|
title={"Delete Contact"}
|
||||||
|
handleClose={handleCloseDeleteModal}
|
||||||
|
>
|
||||||
|
<div className="m-[20px]">
|
||||||
|
<div className="text-lg font-normal text-black">
|
||||||
|
Are you sure you want to delete this contact?
|
||||||
|
</div>
|
||||||
|
<hr className="bg-[#ccc] mt-4 " />
|
||||||
|
<div className="flex items-center mt-3 gap-2 text-white">
|
||||||
|
<button
|
||||||
|
onClick={() => handleDelete(item)}
|
||||||
|
className="px-4 py-1.5 text-white rounded shadow-md text-center focus:outline-none "
|
||||||
|
style={{ backgroundColor: modalSubmitBtnColor }}
|
||||||
|
>
|
||||||
|
Yes
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={handleCloseDeleteModal}
|
||||||
|
className="px-4 py-1.5 text-black border-[1px] border-[#ccc] shadow-md rounded focus:outline-none"
|
||||||
|
style={{ backgroundColor: modalCancelBtnColor }}
|
||||||
|
>
|
||||||
|
No
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
|
)}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
) : (
|
) : (
|
||||||
<tr className="border-y-[1px]" key={index}>
|
<tr className="border-y-[1px]" key={index}>
|
||||||
<td className="px-4 py-2">{index + 1}</td>
|
{heading.includes("Sr.No") && (
|
||||||
<td className="px-4 py-2 font-semibold">{item?.Name} </td>
|
<td className="px-4 py-2">{startIndex + index + 1}</td>
|
||||||
<td className="px-4 py-2">{item?.Note || "-"}</td>
|
)}
|
||||||
<td className="px-4 py-2">
|
<td className="px-4 py-2 font-semibold w-56">
|
||||||
{item?.Folder?.Name || "OpenSignDrive"}
|
{item?.Name}{" "}
|
||||||
</td>
|
</td>
|
||||||
|
{heading.includes("Note") && (
|
||||||
|
<td className="px-4 py-2">{item?.Note || "-"}</td>
|
||||||
|
)}
|
||||||
|
{heading.includes("Folder") && (
|
||||||
|
<td className="px-4 py-2">
|
||||||
|
{item?.Folder?.Name || "OpenSign™ Drive"}
|
||||||
|
</td>
|
||||||
|
)}
|
||||||
<td className="px-4 py-2">
|
<td className="px-4 py-2">
|
||||||
<a
|
<a
|
||||||
target="_blank"
|
target="_blank"
|
||||||
@@ -202,17 +394,21 @@ const ReportTable = ({
|
|||||||
<td className="px-4 py-2">
|
<td className="px-4 py-2">
|
||||||
{item?.Signers ? formatRow(item?.Signers) : "-"}
|
{item?.Signers ? formatRow(item?.Signers) : "-"}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-2 flex flex-col justify-center items-center gap-2 text-white">
|
<td className="px-3 py-2 text-white">
|
||||||
{actions?.length > 0 &&
|
{actions?.length > 0 &&
|
||||||
actions.map((act, index) => (
|
actions.map((act, index) => (
|
||||||
<button
|
<button
|
||||||
key={index}
|
key={index}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
act?.redirectUrl
|
act?.redirectUrl
|
||||||
? handlemicroapp(item, act.redirectUrl)
|
? handlemicroapp(
|
||||||
|
item,
|
||||||
|
act.redirectUrl,
|
||||||
|
act.btnLabel
|
||||||
|
)
|
||||||
: handlebtn(item)
|
: handlebtn(item)
|
||||||
}
|
}
|
||||||
className={`flex justify-center items-center w-full gap-1 px-2 py-1 rounded shadow`}
|
className={`mb-1 flex justify-center items-center gap-1 px-2 py-1 rounded shadow`}
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: act.btnColor
|
backgroundColor: act.btnColor
|
||||||
? act.btnColor
|
? act.btnColor
|
||||||
@@ -224,7 +420,9 @@ const ReportTable = ({
|
|||||||
{act?.btnIcon && (
|
{act?.btnIcon && (
|
||||||
<i
|
<i
|
||||||
className={
|
className={
|
||||||
actLoader[item.objectId]
|
actLoader[
|
||||||
|
`${item.objectId}_${act.btnLabel}`
|
||||||
|
]
|
||||||
? "fa-solid fa-spinner fa-spin-pulse"
|
? "fa-solid fa-spinner fa-spin-pulse"
|
||||||
: act.btnIcon
|
: act.btnIcon
|
||||||
}
|
}
|
||||||
@@ -235,7 +433,6 @@ const ReportTable = ({
|
|||||||
{act?.btnLabel ? act.btnLabel : "view"}
|
{act?.btnLabel ? act.btnLabel : "view"}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
// )
|
|
||||||
))}
|
))}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -293,6 +490,26 @@ const ReportTable = ({
|
|||||||
<div className="text-sm font-semibold">No Data Available</div>
|
<div className="text-sm font-semibold">No Data Available</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
<ModalUi
|
||||||
|
title={"Add Contact"}
|
||||||
|
isOpen={isContactform}
|
||||||
|
handleClose={handleContactFormModal}
|
||||||
|
>
|
||||||
|
<AppendFormInForm
|
||||||
|
handleUserData={handleUserData}
|
||||||
|
closePopup={handleContactFormModal}
|
||||||
|
/>
|
||||||
|
</ModalUi>
|
||||||
|
<ModalUi
|
||||||
|
headColor={"#dc3545"}
|
||||||
|
isOpen={isDocErr}
|
||||||
|
title={"Receipent required"}
|
||||||
|
handleClose={() => setIsDocErr(false)}
|
||||||
|
>
|
||||||
|
<div style={{ height: "100%", padding: 20 }}>
|
||||||
|
<p>Please add receipent in template!</p>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
|
||||||
|
const Modal = ({ children, Title }) => {
|
||||||
|
const [isOpen, SetIsOpen] = useState(false);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{children && (
|
||||||
|
<div
|
||||||
|
className={`fixed top-20 left-1/2 transform -translate-x-1/2 border-[1px] text-sm bg-white rounded `}
|
||||||
|
>
|
||||||
|
<div className="flex justify-between items-center py-[.75rem] px-[1.25rem] ">
|
||||||
|
<div className="font-semibold text-xl text-black">{Title}</div>
|
||||||
|
<div
|
||||||
|
onClick={() => SetIsOpen()}
|
||||||
|
className="px-2 py-1 bg-gray-400 rounded cursor-pointer"
|
||||||
|
>
|
||||||
|
<i className="fa-solid fa-xmark"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
{isOpen && <div>{children}</div>}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Modal;
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import React from "react";
|
||||||
|
const ModalUi = ({
|
||||||
|
children,
|
||||||
|
title,
|
||||||
|
isOpen,
|
||||||
|
headColor,
|
||||||
|
handleClose,
|
||||||
|
showHeader = true,
|
||||||
|
showClose = true
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{isOpen && (
|
||||||
|
<div className="fixed z-[999] top-0 left-0 w-[100%] h-[100%] bg-black bg-opacity-[75%]">
|
||||||
|
<div className="fixed z-[1000] top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 text-sm bg-white rounded shadow-md max-h-90 min-w-[90%] md:min-w-[500px] overflow-y-auto hide-scrollbar">
|
||||||
|
{showHeader && (
|
||||||
|
<div
|
||||||
|
className="flex justify-between rounded-t items-center py-[15px] px-[20px] text-white"
|
||||||
|
style={{ background: headColor ? headColor : "#32a3ac" }}
|
||||||
|
>
|
||||||
|
<div className="text-[1.2rem] font-normal">{title}</div>
|
||||||
|
{showClose && (
|
||||||
|
<div
|
||||||
|
className="text-[1.5rem] cursor-pointer"
|
||||||
|
onClick={() => handleClose && handleClose()}
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div>{children}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ModalUi;
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import Parse from "parse";
|
||||||
|
import { Outlet, useNavigate, useLocation } from "react-router-dom";
|
||||||
|
import ModalUi from "./ModalUi";
|
||||||
|
const Validate = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const location = useLocation();
|
||||||
|
const [isUserValid, setIsUserValid] = useState(true);
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
// Use the session token to validate the user
|
||||||
|
const userQuery = new Parse.Query(Parse.User);
|
||||||
|
const user = await userQuery.get(Parse.User.current().id, {
|
||||||
|
sessionToken: localStorage.getItem("accesstoken")
|
||||||
|
});
|
||||||
|
if (user) {
|
||||||
|
setIsUserValid(true);
|
||||||
|
} else {
|
||||||
|
setIsUserValid(false);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Session token is invalid or there was an error
|
||||||
|
setIsUserValid(false);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}, []);
|
||||||
|
const handleLoginBtn = () => {
|
||||||
|
try {
|
||||||
|
Parse.User.logOut();
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err ", err);
|
||||||
|
} finally {
|
||||||
|
localStorage.removeItem("accesstoken");
|
||||||
|
navigate("/", { replace: true, state: { from: location } });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return isUserValid ? (
|
||||||
|
<div>
|
||||||
|
<Outlet />
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<ModalUi title={"Session Expired"} isOpen={true} showClose={false}>
|
||||||
|
<div className="flex flex-col justify-center items-center py-4 md:py-5 gap-5">
|
||||||
|
<p className="text-xl font-normal">Your session has expired.</p>
|
||||||
|
<button
|
||||||
|
onClick={handleLoginBtn}
|
||||||
|
className="text-base px-3 py-1.5 rounded shadow-md text-white bg-[#1ab6ce]"
|
||||||
|
>
|
||||||
|
Login
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Validate;
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import React, { useEffect } from "react";
|
||||||
|
import Parse from "parse";
|
||||||
|
import { Outlet } from "react-router-dom";
|
||||||
|
const ValidateRoute = () => {
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
// Use the session token to validate the user
|
||||||
|
const userQuery = new Parse.Query(Parse.User);
|
||||||
|
const user = await userQuery.get(Parse.User.current().id, {
|
||||||
|
sessionToken: localStorage.getItem("accesstoken")
|
||||||
|
});
|
||||||
|
if (!user) {
|
||||||
|
handlelogout();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
handlelogout();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}, []);
|
||||||
|
const handlelogout = async () => {
|
||||||
|
try {
|
||||||
|
Parse.User.logOut();
|
||||||
|
localStorage.removeItem("accesstoken");
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err ", err);
|
||||||
|
} finally {
|
||||||
|
localStorage.removeItem("accesstoken");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return <div>{<Outlet />}</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ValidateRoute;
|
||||||
@@ -124,8 +124,7 @@ export const login = (username, password) => async (dispatch) => {
|
|||||||
const currentUser = Parse.User.current();
|
const currentUser = Parse.User.current();
|
||||||
await Parse.Cloud.run("getUserDetails", {
|
await Parse.Cloud.run("getUserDetails", {
|
||||||
email: currentUser.get("email")
|
email: currentUser.get("email")
|
||||||
})
|
}).then(
|
||||||
.then(
|
|
||||||
(results) => {
|
(results) => {
|
||||||
let userinfo = results.toJSON();
|
let userinfo = results.toJSON();
|
||||||
if (userinfo.TenantId) {
|
if (userinfo.TenantId) {
|
||||||
@@ -215,95 +214,10 @@ export const fetchRoleEnum = (name) => async (dispatch) => {
|
|||||||
dispatch({ type: "FETCH_ROLE", payload: response });
|
dispatch({ type: "FETCH_ROLE", payload: response });
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setEnableCart = (val) => async (dispatch) => {
|
|
||||||
dispatch({
|
|
||||||
type: "ENABLE_CART",
|
|
||||||
payload: val
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const setCartUpdateData = (val) => async (dispatch) => {
|
|
||||||
dispatch({
|
|
||||||
type: "UPDATE_CART",
|
|
||||||
payload: val
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const addItemsToCart = (val) => async (dispatch) => {
|
|
||||||
dispatch({
|
|
||||||
type: "ADD_CART",
|
|
||||||
payload: val
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const clearCartData = () => async (dispatch) => {
|
|
||||||
dispatch({
|
|
||||||
type: "CLEAR_CART",
|
|
||||||
payload: []
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const SaveMultipleCart = (val) => async (dispatch) => {
|
|
||||||
dispatch({
|
|
||||||
type: "MULTI_CART",
|
|
||||||
payload: val
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const removeFromCart = (val) => async (dispatch) => {
|
|
||||||
dispatch({
|
|
||||||
type: "REMOVE_CART",
|
|
||||||
payload: val
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const onChangeLevel1Dropdown = (id, name) => async (dispatch) => {
|
|
||||||
localStorage.setItem(`_dd${name}`, id);
|
|
||||||
let _data = { [name]: `${id}` };
|
|
||||||
dispatch({ type: "Level1_Dropdown", payload: _data });
|
|
||||||
};
|
|
||||||
|
|
||||||
export const onChangeLevel2Dropdown = (id, name) => async (dispatch) => {
|
|
||||||
localStorage.setItem(`_dd${name}`, id);
|
|
||||||
let _data = { [name]: `${id}` };
|
|
||||||
dispatch({ type: "Level2_Dropdown", payload: _data });
|
|
||||||
};
|
|
||||||
|
|
||||||
export const onChangeLevel3Dropdown = (id, name) => async (dispatch) => {
|
|
||||||
localStorage.setItem(`_dd${name}`, id);
|
|
||||||
let _data = { [name]: `${id}` };
|
|
||||||
dispatch({ type: "Level3_Dropdown", payload: _data });
|
|
||||||
};
|
|
||||||
|
|
||||||
export const removeState = () => async (dispatch) => {
|
|
||||||
dispatch({ type: "REMOVE_STATE", payload: {} });
|
|
||||||
};
|
|
||||||
export const removeLevel2State = () => async (dispatch) => {
|
|
||||||
dispatch({ type: "removeLevel2", payload: {} });
|
|
||||||
};
|
|
||||||
|
|
||||||
export const removeLevel3State = () => async (dispatch) => {
|
|
||||||
dispatch({ type: "removeLevel3", payload: {} });
|
|
||||||
};
|
|
||||||
|
|
||||||
export const showTenantName = (name) => async (dispatch) => {
|
export const showTenantName = (name) => async (dispatch) => {
|
||||||
dispatch({ type: "SHOW_TENANT", payload: name || null });
|
dispatch({ type: "SHOW_TENANT", payload: name || null });
|
||||||
};
|
};
|
||||||
|
|
||||||
export const saveDependantDDValue = (id, value) => async (dispatch) => {
|
|
||||||
let _data = { [`${id}_dd`]: value };
|
|
||||||
dispatch({ type: "SAVE_DEPENDANTDD", payload: _data });
|
|
||||||
};
|
|
||||||
|
|
||||||
export const removeDependantDDValue = (id, value) => async (dispatch) => {
|
|
||||||
let _data = { [`${id}_dd`]: value };
|
|
||||||
dispatch({ type: "REMOVE_DEPENDANTDD", payload: _data });
|
|
||||||
};
|
|
||||||
|
|
||||||
export const remove_AlldependantDD = () => async (dispatch) => {
|
|
||||||
dispatch({ type: "REMOVE_ALLDEPENDANTDD", payload: {} });
|
|
||||||
};
|
|
||||||
|
|
||||||
export const save_tourSteps = (steps) => async (dispatch) => {
|
export const save_tourSteps = (steps) => async (dispatch) => {
|
||||||
dispatch({ type: "SAVE_TOURSTEPS", payload: steps });
|
dispatch({ type: "SAVE_TOURSTEPS", payload: steps });
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const Dashboard = (props) => {
|
|||||||
getDashboard(localStorage.getItem("PageLanding"));
|
getDashboard(localStorage.getItem("PageLanding"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
navigate("/", { replace: true });
|
navigate("/", { replace: true, state: { from: location } });
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
}, [id]);
|
}, [id]);
|
||||||
|
|||||||
+380
-1290
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,184 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import Title from "../components/Title";
|
||||||
|
import axios from "axios";
|
||||||
|
import Alert from "../primitives/Alert";
|
||||||
|
import ModalUi from "../primitives/ModalUi";
|
||||||
|
import { rejectBtn, submitBtn } from "../constant/const";
|
||||||
|
import { openInNewTab } from "../constant/Utils";
|
||||||
|
|
||||||
|
function GenerateToken() {
|
||||||
|
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
||||||
|
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
||||||
|
const [apiToken, SetApiToken] = useState("");
|
||||||
|
const [isLoader, setIsLoader] = useState(true);
|
||||||
|
const [copied, setCopied] = useState(false);
|
||||||
|
const [isGenerate, setIsGenerate] = useState(false);
|
||||||
|
const [isErr, setIsErr] = useState(false);
|
||||||
|
const [isModal, setIsModal] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchToken();
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const fetchToken = async () => {
|
||||||
|
try {
|
||||||
|
const url = parseBaseUrl + "functions/getapitoken";
|
||||||
|
const headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": parseAppId,
|
||||||
|
sessiontoken: localStorage.getItem("accesstoken")
|
||||||
|
};
|
||||||
|
const res = await axios.post(url, {}, { headers: headers });
|
||||||
|
if (res) {
|
||||||
|
SetApiToken(res.data.result.result);
|
||||||
|
}
|
||||||
|
setIsLoader(false);
|
||||||
|
} catch (err) {
|
||||||
|
SetApiToken();
|
||||||
|
setIsLoader(false);
|
||||||
|
console.log("Err", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleSubmit = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setIsLoader(true);
|
||||||
|
setIsModal(false);
|
||||||
|
try {
|
||||||
|
const url = parseBaseUrl + "functions/generateapitoken";
|
||||||
|
const headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": parseAppId,
|
||||||
|
sessiontoken: localStorage.getItem("accesstoken")
|
||||||
|
};
|
||||||
|
await axios.post(url, {}, { headers: headers }).then((res) => {
|
||||||
|
if (res) {
|
||||||
|
SetApiToken(res.data.result.token);
|
||||||
|
// localStorage.setItem("apiToken", res.data.result.token);
|
||||||
|
setIsGenerate(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsGenerate(false);
|
||||||
|
}, 1500);
|
||||||
|
setIsLoader(false);
|
||||||
|
} else {
|
||||||
|
console.error("Error while generating Token");
|
||||||
|
setIsLoader(false);
|
||||||
|
setIsErr(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsErr(false);
|
||||||
|
}, 1500);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
setIsLoader(false);
|
||||||
|
setIsErr(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsErr(false);
|
||||||
|
}, 1500);
|
||||||
|
|
||||||
|
console.log("err", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const copytoclipboard = (text) => {
|
||||||
|
navigator.clipboard.writeText(text);
|
||||||
|
setCopied(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setCopied(false);
|
||||||
|
}, 1500); // Reset copied state after 1.5 seconds
|
||||||
|
};
|
||||||
|
const handleModal = () => setIsModal(!isModal);
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<Title title={"API Token"} />
|
||||||
|
{isGenerate && (
|
||||||
|
<Alert type="success">Token generated successfully!</Alert>
|
||||||
|
)}
|
||||||
|
{copied && <Alert type="success">Copied</Alert>}
|
||||||
|
{isErr && <Alert type="danger">Something went wrong!</Alert>}
|
||||||
|
{isLoader ? (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: "100vh",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: "45px",
|
||||||
|
color: "#3dd3e0"
|
||||||
|
}}
|
||||||
|
className="loader-37"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="bg-white flex flex-col justify-center shadow rounded">
|
||||||
|
<h1 className="ml-4 mt-3 mb-2 font-semibold">API Token</h1>
|
||||||
|
<ul className="w-full flex flex-col p-2 text-sm">
|
||||||
|
<li
|
||||||
|
className={`flex justify-between items-center border-y-[1px] border-gray-300 break-all py-2`}
|
||||||
|
>
|
||||||
|
<span className="w-[40%]">Api Token:</span>{" "}
|
||||||
|
<span
|
||||||
|
id="token"
|
||||||
|
className="w-[60%] md:text-end cursor-pointer"
|
||||||
|
onClick={() => copytoclipboard(apiToken)}
|
||||||
|
>
|
||||||
|
{apiToken && apiToken}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div className="flex flex-col md:flex-row items-center justify-center gap-2 pb-4">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={apiToken ? handleModal : handleSubmit}
|
||||||
|
className="rounded hover:bg-[#15b4e9] border-[1px] border-[#15b4e9] text-[#15b4e9] hover:text-white px-4 py-2 text-xs md:text-base focus:outline-none"
|
||||||
|
>
|
||||||
|
{apiToken ? "Regenerate Token" : "Generate Token"}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() =>
|
||||||
|
openInNewTab(
|
||||||
|
"https://docs.opensignlabs.com/docs/API-docs/opensign-api-v-1"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
className="rounded hover:bg-[#15b4e9] border-[1px] border-[#15b4e9] text-[#15b4e9] hover:text-white px-11 py-2 text-xs md:text-base focus:outline-none"
|
||||||
|
>
|
||||||
|
View Docs
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ModalUi
|
||||||
|
isOpen={isModal}
|
||||||
|
title={"Regenerate Token"}
|
||||||
|
handleClose={handleModal}
|
||||||
|
>
|
||||||
|
<div className="m-[20px]">
|
||||||
|
<div className="text-lg font-normal text-black">
|
||||||
|
Are you sure you want to regenerate token it will expire old
|
||||||
|
token?
|
||||||
|
</div>
|
||||||
|
<hr className="bg-[#ccc] mt-4 " />
|
||||||
|
<div className="flex items-center mt-3 gap-2 text-white">
|
||||||
|
<button
|
||||||
|
onClick={handleSubmit}
|
||||||
|
className={submitBtn + "ml-[2px]"}
|
||||||
|
>
|
||||||
|
Yes
|
||||||
|
</button>
|
||||||
|
<button onClick={handleModal} className={rejectBtn}>
|
||||||
|
No
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GenerateToken;
|
||||||
@@ -30,9 +30,9 @@ function RemoteApp({ app }) {
|
|||||||
boxShadow: "0 1px 3px 0 rgba(0, 0, 0, 0.33)",
|
boxShadow: "0 1px 3px 0 rgba(0, 0, 0, 0.33)",
|
||||||
backgroundColor: "#ffffff",
|
backgroundColor: "#ffffff",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
overflow: "hidden",
|
|
||||||
borderRadius: 3,
|
borderRadius: 3,
|
||||||
minHeight: "70vh"
|
height: "100%",
|
||||||
|
minHeight: "100vh"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{RemoteComponent && <RemoteComponent />}
|
{RemoteComponent && <RemoteComponent />}
|
||||||
|
|||||||
@@ -8,12 +8,15 @@ import axios from "axios";
|
|||||||
import Title from "../components/Title";
|
import Title from "../components/Title";
|
||||||
import GoogleSignInBtn from "../components/LoginGoogle";
|
import GoogleSignInBtn from "../components/LoginGoogle";
|
||||||
// import LoginFacebook from "../components/LoginFacebook";
|
// import LoginFacebook from "../components/LoginFacebook";
|
||||||
import { NavLink, useNavigate } from "react-router-dom";
|
import { NavLink, useNavigate, useLocation } from "react-router-dom";
|
||||||
import login_img from "../assets/images/login_img.svg";
|
import login_img from "../assets/images/login_img.svg";
|
||||||
import { useWindowSize } from "../hook/useWindowSize";
|
import { useWindowSize } from "../hook/useWindowSize";
|
||||||
|
import ModalUi from "../primitives/ModalUi";
|
||||||
|
import { modalCancelBtnColor, modalSubmitBtnColor } from "../constant/const";
|
||||||
|
|
||||||
function Login(props) {
|
function Login(props) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const location = useLocation();
|
||||||
const { width } = useWindowSize();
|
const { width } = useWindowSize();
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
email: "",
|
email: "",
|
||||||
@@ -132,6 +135,9 @@ function Login(props) {
|
|||||||
`${localStorage.getItem("_appName")}_appeditor`
|
`${localStorage.getItem("_appName")}_appeditor`
|
||||||
) {
|
) {
|
||||||
userSettings.forEach(async (element) => {
|
userSettings.forEach(async (element) => {
|
||||||
|
const redirectUrl =
|
||||||
|
location?.state?.from ||
|
||||||
|
`/${element.pageType}/${element.pageId}`;
|
||||||
if (element.role === _currentRole) {
|
if (element.role === _currentRole) {
|
||||||
let _role = _currentRole.replace(
|
let _role = _currentRole.replace(
|
||||||
`${localStorage.getItem("_appName")}_`,
|
`${localStorage.getItem("_appName")}_`,
|
||||||
@@ -260,9 +266,8 @@ function Login(props) {
|
|||||||
localStorage.removeItem(
|
localStorage.removeItem(
|
||||||
"userDetails"
|
"userDetails"
|
||||||
);
|
);
|
||||||
navigate(
|
// Redirect to the appropriate URL after successful login
|
||||||
`/${element.pageType}/${element.pageId}`
|
navigate(redirectUrl);
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
navigate(`/subscription`, {
|
navigate(`/subscription`, {
|
||||||
replace: true
|
replace: true
|
||||||
@@ -274,9 +279,8 @@ function Login(props) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
navigate(
|
// Redirect to the appropriate URL after successful login
|
||||||
`/${element.pageType}/${element.pageId}`
|
navigate(redirectUrl);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -313,9 +317,8 @@ function Login(props) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
navigate(
|
// Redirect to the appropriate URL after successful login
|
||||||
`/${element.pageType}/${element.pageId}`
|
navigate(redirectUrl);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -462,6 +465,9 @@ function Login(props) {
|
|||||||
`${localStorage.getItem("_appName")}_appeditor`
|
`${localStorage.getItem("_appName")}_appeditor`
|
||||||
) {
|
) {
|
||||||
userSettings.forEach(async (element) => {
|
userSettings.forEach(async (element) => {
|
||||||
|
const redirectUrl =
|
||||||
|
location?.state?.from ||
|
||||||
|
`/${element.pageType}/${element.pageId}`;
|
||||||
if (element.role === _currentRole) {
|
if (element.role === _currentRole) {
|
||||||
let _role = _currentRole.replace(
|
let _role = _currentRole.replace(
|
||||||
`${localStorage.getItem("_appName")}_`,
|
`${localStorage.getItem("_appName")}_`,
|
||||||
@@ -569,9 +575,7 @@ function Login(props) {
|
|||||||
if (billingDate) {
|
if (billingDate) {
|
||||||
if (billingDate > new Date()) {
|
if (billingDate > new Date()) {
|
||||||
localStorage.removeItem("userDetails");
|
localStorage.removeItem("userDetails");
|
||||||
navigate(
|
navigate(redirectUrl);
|
||||||
`/${element.pageType}/${element.pageId}`
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
navigate(`/subscription`, {
|
navigate(`/subscription`, {
|
||||||
replace: true
|
replace: true
|
||||||
@@ -581,9 +585,7 @@ function Login(props) {
|
|||||||
navigate(`/subscription`, { replace: true });
|
navigate(`/subscription`, { replace: true });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
navigate(
|
navigate(redirectUrl);
|
||||||
`/${element.pageType}/${element.pageId}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -599,9 +601,8 @@ function Login(props) {
|
|||||||
if (billingDate) {
|
if (billingDate) {
|
||||||
if (billingDate > new Date()) {
|
if (billingDate > new Date()) {
|
||||||
localStorage.removeItem("userDetails");
|
localStorage.removeItem("userDetails");
|
||||||
navigate(
|
// Redirect to the appropriate URL after successful login
|
||||||
`/${element.pageType}/${element.pageId}`
|
navigate(redirectUrl);
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
navigate(`/subscription`, { replace: true });
|
navigate(`/subscription`, { replace: true });
|
||||||
}
|
}
|
||||||
@@ -609,9 +610,7 @@ function Login(props) {
|
|||||||
navigate(`/subscription`, { replace: true });
|
navigate(`/subscription`, { replace: true });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
navigate(
|
navigate(redirectUrl);
|
||||||
`/${element.pageType}/${element.pageId}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1134,100 +1133,76 @@ function Login(props) {
|
|||||||
{state.toastDescription}
|
{state.toastDescription}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{isModal && (
|
<ModalUi isOpen={isModal} title="Additional Info" showClose={false}>
|
||||||
<div
|
<form className="px-4 py-3">
|
||||||
className="modal fade show"
|
<div className="mb-3">
|
||||||
id="exampleModal"
|
<label
|
||||||
tabIndex="-1"
|
htmlFor="Company"
|
||||||
role="dialog"
|
style={{ display: "flex" }}
|
||||||
style={{
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
display: "block",
|
>
|
||||||
zIndex: 1,
|
Company <span style={{ fontSize: 13, color: "red" }}>*</span>
|
||||||
backgroundColor: "rgba(0,0,0,0.5)"
|
</label>
|
||||||
}}
|
<input
|
||||||
>
|
type="text"
|
||||||
<div className="modal-dialog" role="document">
|
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||||
<div className="modal-content">
|
id="Company"
|
||||||
<div className="modal-header">
|
value={userDetails.Company}
|
||||||
<h5 className="modal-title font-semibold">
|
onChange={(e) =>
|
||||||
Additional Info
|
setUserDetails({
|
||||||
</h5>
|
...userDetails,
|
||||||
<span>
|
Company: e.target.value
|
||||||
<span></span>
|
})
|
||||||
</span>
|
}
|
||||||
</div>
|
required
|
||||||
<div className="modal-body">
|
/>
|
||||||
<form className="text-sm">
|
|
||||||
<div className="form-group">
|
|
||||||
<label
|
|
||||||
htmlFor="Company"
|
|
||||||
style={{ display: "flex" }}
|
|
||||||
className="col-form-label"
|
|
||||||
>
|
|
||||||
Company{" "}
|
|
||||||
<span style={{ fontSize: 13, color: "red" }}>*</span>
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="form-control"
|
|
||||||
id="Company"
|
|
||||||
value={userDetails.Company}
|
|
||||||
onChange={(e) =>
|
|
||||||
setUserDetails({
|
|
||||||
...userDetails,
|
|
||||||
Company: e.target.value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="form-group">
|
|
||||||
<label
|
|
||||||
htmlFor="JobTitle"
|
|
||||||
style={{ display: "flex" }}
|
|
||||||
className="col-form-label"
|
|
||||||
>
|
|
||||||
Job Title
|
|
||||||
<span style={{ fontSize: 13, color: "red" }}>*</span>
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="form-control"
|
|
||||||
id="JobTitle"
|
|
||||||
value={userDetails.Destination}
|
|
||||||
onChange={(e) =>
|
|
||||||
setUserDetails({
|
|
||||||
...userDetails,
|
|
||||||
Destination: e.target.value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="mt-4">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="bg-[#17a2b8] text-sm p-2 text-white rounded uppercase"
|
|
||||||
onClick={(e) => handleSubmitbtn(e)}
|
|
||||||
style={{ marginRight: 10 }}
|
|
||||||
>
|
|
||||||
Login
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="bg-[#6c757d] text-sm p-2 text-white rounded uppercase"
|
|
||||||
onClick={handleCloseModal}
|
|
||||||
style={{ width: 90 }}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className="mb-3">
|
||||||
)}
|
<label
|
||||||
|
htmlFor="JobTitle"
|
||||||
|
style={{ display: "flex" }}
|
||||||
|
className="block text-xs text-gray-700 font-semibold"
|
||||||
|
>
|
||||||
|
Job Title
|
||||||
|
<span style={{ fontSize: 13, color: "red" }}>*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||||
|
id="JobTitle"
|
||||||
|
value={userDetails.Destination}
|
||||||
|
onChange={(e) =>
|
||||||
|
setUserDetails({
|
||||||
|
...userDetails,
|
||||||
|
Destination: e.target.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="px-3 py-1.5 text-white rounded shadow-md text-center focus:outline-none "
|
||||||
|
onClick={(e) => handleSubmitbtn(e)}
|
||||||
|
style={{
|
||||||
|
marginRight: 10,
|
||||||
|
backgroundColor: modalSubmitBtnColor
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Login
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="py-1.5 text-black border-[1px] border-[#ccc] shadow-md rounded focus:outline-none"
|
||||||
|
onClick={handleCloseModal}
|
||||||
|
style={{ width: 75, backgroundColor: modalCancelBtnColor }}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</ModalUi>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import Title from "../components/Title";
|
import Title from "../components/Title";
|
||||||
|
|
||||||
const PageNotFound = () => {
|
const PageNotFound = ({ prefix }) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-center h-screen w-full bg-white rounded">
|
<div className="flex items-center justify-center h-screen w-full bg-white rounded">
|
||||||
<Title title={"Page Not Found"} />
|
<Title title={"Page Not Found"} />
|
||||||
@@ -10,7 +10,9 @@ const PageNotFound = () => {
|
|||||||
<h1 className="text-[60px] lg:text-[120px] font-semibold text-black">
|
<h1 className="text-[60px] lg:text-[120px] font-semibold text-black">
|
||||||
404
|
404
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-[30px] lg:text-[50px] text-black">Page Not Found</p>
|
<p className="text-[30px] lg:text-[50px] text-black">
|
||||||
|
{prefix ? prefix : "Page"} Not Found
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import axios from "axios";
|
|||||||
import { fetchAppInfo, showTenantName } from "../redux/actions/index";
|
import { fetchAppInfo, showTenantName } from "../redux/actions/index";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import Title from "../components/Title";
|
import Title from "../components/Title";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate, useLocation } from "react-router-dom";
|
||||||
|
|
||||||
const appId = localStorage.getItem("AppID12");
|
const appId = localStorage.getItem("AppID12");
|
||||||
const server = localStorage.getItem("BaseUrl12");
|
const server = localStorage.getItem("BaseUrl12");
|
||||||
@@ -13,6 +13,7 @@ Parse.serverURL = server;
|
|||||||
Parse.initialize(appId);
|
Parse.initialize(appId);
|
||||||
const PgSignUp = (props) => {
|
const PgSignUp = (props) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const location = useLocation();
|
||||||
const [parseBaseUrl] = useState(localStorage.getItem("BaseUrl12"));
|
const [parseBaseUrl] = useState(localStorage.getItem("BaseUrl12"));
|
||||||
const [parseAppId] = useState(localStorage.getItem("AppID12"));
|
const [parseAppId] = useState(localStorage.getItem("AppID12"));
|
||||||
const [formData, setFormData] = useState({
|
const [formData, setFormData] = useState({
|
||||||
@@ -74,8 +75,8 @@ const PgSignUp = (props) => {
|
|||||||
const res = await Parse.Cloud.run("getUserDetails", params);
|
const res = await Parse.Cloud.run("getUserDetails", params);
|
||||||
// console.log("res", res);
|
// console.log("res", res);
|
||||||
if (res) {
|
if (res) {
|
||||||
const checkUser = new Parse.Query(extClass);
|
const updateQuery = new Parse.Object(extClass);
|
||||||
const updateQuery = await checkUser.get(res.id);
|
updateQuery.id = res.id;
|
||||||
updateQuery.set(
|
updateQuery.set(
|
||||||
"Next_billing_date",
|
"Next_billing_date",
|
||||||
new Date(zohoRes.data.result.nextBillingDate)
|
new Date(zohoRes.data.result.nextBillingDate)
|
||||||
@@ -187,7 +188,7 @@ const PgSignUp = (props) => {
|
|||||||
console.log("err ", error);
|
console.log("err ", error);
|
||||||
if (error.message === "Account already exists for this username.") {
|
if (error.message === "Account already exists for this username.") {
|
||||||
alert("Account already exists!");
|
alert("Account already exists!");
|
||||||
navigate("/");
|
navigate("/", { replace: true });
|
||||||
} else {
|
} else {
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
alert("Something went wrong, please try again later!");
|
alert("Something went wrong, please try again later!");
|
||||||
@@ -351,7 +352,7 @@ const PgSignUp = (props) => {
|
|||||||
element.pageType
|
element.pageType
|
||||||
);
|
);
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
navigate("/");
|
navigate("/", { replace: true });
|
||||||
} else {
|
} else {
|
||||||
extendedInfo.forEach((x) => {
|
extendedInfo.forEach((x) => {
|
||||||
if (x.TenantId) {
|
if (x.TenantId) {
|
||||||
@@ -389,9 +390,12 @@ const PgSignUp = (props) => {
|
|||||||
);
|
);
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
alert("Registered user successfully");
|
alert("Registered user successfully");
|
||||||
navigate(
|
const redirectUrl =
|
||||||
`/${element.pageType}/${element.pageId}`
|
location?.state?.from ||
|
||||||
);
|
`/${element.pageType}/${element.pageId}`;
|
||||||
|
|
||||||
|
// Redirect to the appropriate URL after successful login
|
||||||
|
navigate(redirectUrl);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alert("Registered user successfully");
|
alert("Registered user successfully");
|
||||||
@@ -402,7 +406,12 @@ const PgSignUp = (props) => {
|
|||||||
);
|
);
|
||||||
localStorage.setItem("pageType", element.pageType);
|
localStorage.setItem("pageType", element.pageType);
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
navigate(`/${element.pageType}/${element.pageId}`);
|
const redirectUrl =
|
||||||
|
location?.state?.from ||
|
||||||
|
`/${element.pageType}/${element.pageId}`;
|
||||||
|
|
||||||
|
// Redirect to the appropriate URL after successful login
|
||||||
|
navigate(redirectUrl);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ const PlanSubscriptions = () => {
|
|||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
setYearlyVisible(false);
|
setYearlyVisible(false);
|
||||||
} else {
|
} else {
|
||||||
navigate("/");
|
navigate("/", { replace: true });
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
}, []);
|
}, []);
|
||||||
@@ -78,31 +78,6 @@ const PlanSubscriptions = () => {
|
|||||||
id="monthlyPlans"
|
id="monthlyPlans"
|
||||||
className={`${yearlyVisible ? "none" : "block my-2"}`}
|
className={`${yearlyVisible ? "none" : "block my-2"}`}
|
||||||
>
|
>
|
||||||
{/* <div className=" my-2 w-full flex justify-center">
|
|
||||||
<ul
|
|
||||||
className="navs"
|
|
||||||
style={{
|
|
||||||
listStyle: "none",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "baseline"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<li className="nav-item">
|
|
||||||
<button className="nav-link frequency active" name="1_months">
|
|
||||||
Monthly
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
<li className="nav-item">
|
|
||||||
<button
|
|
||||||
className="nav-link frequency "
|
|
||||||
onClick={toggleFrequency}
|
|
||||||
name="1_years"
|
|
||||||
>
|
|
||||||
Yearly
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div> */}
|
|
||||||
<div className="flex justify-center w-full my-2">
|
<div className="flex justify-center w-full my-2">
|
||||||
<ul className=" flex flex-col md:flex-row h-full bg-white justify-center border-collapse border-[1px] border-gray-300">
|
<ul className=" flex flex-col md:flex-row h-full bg-white justify-center border-collapse border-[1px] border-gray-300">
|
||||||
{plansArr.map((item) => (
|
{plansArr.map((item) => (
|
||||||
@@ -129,11 +104,27 @@ const PlanSubscriptions = () => {
|
|||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
item.subtitle.length <= 32
|
item.subtitle.length <= 32
|
||||||
? "w-[150px] text-center"
|
? "w-[150px] text-center"
|
||||||
: ""
|
: ""
|
||||||
} text-sm text-center my-2`}
|
} text-sm text-center my-2`}
|
||||||
>
|
>
|
||||||
<p>{item.subtitle}</p>
|
<p
|
||||||
|
style={{
|
||||||
|
backgroundColor: item.subtitlecolor
|
||||||
|
? item.subtitlecolor
|
||||||
|
: "white"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{item.subtitle.includes("<") ? (
|
||||||
|
<div
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: item.subtitle
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<span>{item.subtitle}</span>
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import axios from "axios";
|
|||||||
import reportJson from "../json/ReportJson";
|
import reportJson from "../json/ReportJson";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import Title from "../components/Title";
|
import Title from "../components/Title";
|
||||||
|
import PageNotFound from "./PageNotFound";
|
||||||
|
|
||||||
const Report = () => {
|
const Report = () => {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
@@ -15,6 +16,7 @@ const Report = () => {
|
|||||||
const [heading, setHeading] = useState([]);
|
const [heading, setHeading] = useState([]);
|
||||||
const [isNextRecord, setIsNextRecord] = useState(false);
|
const [isNextRecord, setIsNextRecord] = useState(false);
|
||||||
const [isMoreDocs, setIsMoreDocs] = useState(true);
|
const [isMoreDocs, setIsMoreDocs] = useState(true);
|
||||||
|
const [form, setForm] = useState("");
|
||||||
const abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
const docPerPage = 10;
|
const docPerPage = 10;
|
||||||
|
|
||||||
@@ -50,6 +52,7 @@ const Report = () => {
|
|||||||
setActions(json.actions);
|
setActions(json.actions);
|
||||||
setHeading(json.heading);
|
setHeading(json.heading);
|
||||||
setReportName(json.reportName);
|
setReportName(json.reportName);
|
||||||
|
setForm(json.form);
|
||||||
Parse.serverURL = localStorage.getItem("BaseUrl12");
|
Parse.serverURL = localStorage.getItem("BaseUrl12");
|
||||||
Parse.initialize(localStorage.getItem("AppID12"));
|
Parse.initialize(localStorage.getItem("AppID12"));
|
||||||
const currentUser = Parse.User.current().id;
|
const currentUser = Parse.User.current().id;
|
||||||
@@ -154,15 +157,10 @@ const Report = () => {
|
|||||||
setIsNextRecord={setIsNextRecord}
|
setIsNextRecord={setIsNextRecord}
|
||||||
isMoreDocs={isMoreDocs}
|
isMoreDocs={isMoreDocs}
|
||||||
docPerPage={docPerPage}
|
docPerPage={docPerPage}
|
||||||
|
form={form}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex items-center justify-center h-screen w-full bg-white rounded">
|
<PageNotFound prefix={"Report"} />
|
||||||
<div className="text-center">
|
|
||||||
<p className="text-[30px] lg:text-[50px] text-black">
|
|
||||||
Report Not Found
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -0,0 +1,171 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import Title from "../components/Title";
|
||||||
|
import axios from "axios";
|
||||||
|
import Alert from "../primitives/Alert";
|
||||||
|
import ModalUi from "../primitives/ModalUi";
|
||||||
|
import { rejectBtn, submitBtn } from "../constant/const";
|
||||||
|
import { openInNewTab } from "../constant/Utils";
|
||||||
|
import Parse from "parse";
|
||||||
|
|
||||||
|
function Webhook() {
|
||||||
|
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
||||||
|
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
||||||
|
const [webhook, setWebhook] = useState();
|
||||||
|
const [isLoader, setIsLoader] = useState(true);
|
||||||
|
const [isGenerate, setIsGenerate] = useState(false);
|
||||||
|
const [isErr, setIsErr] = useState(false);
|
||||||
|
const [isModal, setIsModal] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchWebhook();
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const fetchWebhook = async () => {
|
||||||
|
const email = Parse.User.current().getEmail();
|
||||||
|
const params = { email: email };
|
||||||
|
try {
|
||||||
|
const extRes = await Parse.Cloud.run("getUserDetails", params);
|
||||||
|
if (extRes) {
|
||||||
|
setWebhook(extRes.get("Webhook"));
|
||||||
|
}
|
||||||
|
setIsLoader(false);
|
||||||
|
} catch (err) {
|
||||||
|
setWebhook();
|
||||||
|
setIsLoader(false);
|
||||||
|
console.log("Err", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleSubmit = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setIsLoader(true);
|
||||||
|
setIsModal(false);
|
||||||
|
try {
|
||||||
|
const params = { url: webhook };
|
||||||
|
const url = parseBaseUrl + "functions/savewebhook";
|
||||||
|
const headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": parseAppId,
|
||||||
|
sessiontoken: localStorage.getItem("accesstoken")
|
||||||
|
};
|
||||||
|
await axios.post(url, params, { headers: headers }).then((res) => {
|
||||||
|
if (res.data && res.data.result && res.data.result.Webhook) {
|
||||||
|
setWebhook(res.data.result.Webhook);
|
||||||
|
setIsGenerate(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsGenerate(false);
|
||||||
|
}, 1500);
|
||||||
|
setIsLoader(false);
|
||||||
|
} else {
|
||||||
|
console.error("Error while generating webhook");
|
||||||
|
setIsLoader(false);
|
||||||
|
setIsErr(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsErr(false);
|
||||||
|
}, 1500);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
setIsLoader(false);
|
||||||
|
setIsErr(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsErr(false);
|
||||||
|
}, 1500);
|
||||||
|
|
||||||
|
console.log("err", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleModal = () => setIsModal(!isModal);
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<Title title={"Webhook"} />
|
||||||
|
{isGenerate && <Alert type="success">Webhook added successfully!</Alert>}
|
||||||
|
{isErr && <Alert type="danger">Something went wrong!</Alert>}
|
||||||
|
{isLoader ? (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: "100vh",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: "45px",
|
||||||
|
color: "#3dd3e0"
|
||||||
|
}}
|
||||||
|
className="loader-37"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="bg-white flex flex-col justify-center shadow rounded">
|
||||||
|
<h1 className="ml-4 mt-3 mb-2 font-semibold">Webhook</h1>
|
||||||
|
<ul className="w-full flex flex-col p-2 text-sm">
|
||||||
|
<li
|
||||||
|
className={`flex justify-between items-center border-y-[1px] border-gray-300 break-all py-2`}
|
||||||
|
>
|
||||||
|
<span className="w-[40%]">Webhook:</span>{" "}
|
||||||
|
<span id="token" className="w-[60%] md:text-end cursor-pointer">
|
||||||
|
{webhook && webhook}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div className="flex flex-col md:flex-row items-center justify-center gap-2 pb-4">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={handleModal}
|
||||||
|
className="rounded hover:bg-[#15b4e9] border-[1px] border-[#15b4e9] text-[#15b4e9] hover:text-white px-4 py-2 text-xs md:text-base focus:outline-none"
|
||||||
|
>
|
||||||
|
{webhook ? "Update Webhook" : "Add Webhook"}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() =>
|
||||||
|
openInNewTab(
|
||||||
|
"https://docs.opensignlabs.com/docs/API-docs/opensign-api-v-1"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
className="rounded hover:bg-[#15b4e9] border-[1px] border-[#15b4e9] text-[#15b4e9] hover:text-white px-11 py-2 text-xs md:text-base focus:outline-none"
|
||||||
|
>
|
||||||
|
View Docs
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ModalUi
|
||||||
|
isOpen={isModal}
|
||||||
|
title={"Regenerate Token"}
|
||||||
|
handleClose={handleModal}
|
||||||
|
>
|
||||||
|
<div className="m-[20px]">
|
||||||
|
<div className="text-lg font-normal text-black">
|
||||||
|
<label className="text-sm ml-2">Webhook</label>
|
||||||
|
<input
|
||||||
|
value={webhook}
|
||||||
|
onChange={(e) => setWebhook(e.target.value)}
|
||||||
|
placeholder="Enter webhook url"
|
||||||
|
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<hr className="bg-[#ccc] mt-4 " />
|
||||||
|
<div className="flex items-center mt-3 gap-2 text-white">
|
||||||
|
<button
|
||||||
|
onClick={handleSubmit}
|
||||||
|
className={submitBtn + "ml-[2px]"}
|
||||||
|
>
|
||||||
|
Yes
|
||||||
|
</button>
|
||||||
|
<button onClick={handleModal} className={rejectBtn}>
|
||||||
|
No
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ModalUi>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Webhook;
|
||||||
+66
-2217
File diff suppressed because it is too large
Load Diff
@@ -1,209 +1,64 @@
|
|||||||
#snackbar {
|
#snackbar {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
min-width: 250px;
|
min-width: 250px;
|
||||||
margin-left: -125px;
|
margin-left: -125px;
|
||||||
background-color: #333;
|
background-color: #333;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 99999;
|
z-index: 99999;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
|
top: 30px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#snackbar.show {
|
||||||
|
visibility: visible;
|
||||||
|
-webkit-animation: fadein 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes fadein {
|
||||||
|
from {
|
||||||
|
top: 0;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
top: 30px;
|
top: 30px;
|
||||||
font-size: 14px;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#_editsnackbar {
|
|
||||||
visibility: hidden;
|
@keyframes fadein {
|
||||||
min-width: 250px;
|
from {
|
||||||
margin-left: -125px;
|
top: 0;
|
||||||
background-color: #333;
|
opacity: 0;
|
||||||
color: #fff;
|
}
|
||||||
text-align: center;
|
to {
|
||||||
border-radius: 2px;
|
|
||||||
padding: 16px;
|
|
||||||
position: fixed;
|
|
||||||
z-index: 99999;
|
|
||||||
left: 50%;
|
|
||||||
top: 30px;
|
top: 30px;
|
||||||
font-size: 14px;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#_editsnackbar.show {
|
|
||||||
visibility: visible;
|
@-webkit-keyframes fadeout {
|
||||||
-webkit-animation: fadein 0.5s;
|
from {
|
||||||
}
|
|
||||||
|
|
||||||
#UpdateColumnValue.show {
|
|
||||||
visibility: visible;
|
|
||||||
-webkit-animation: fadein 0.5s;
|
|
||||||
}
|
|
||||||
#DeleteUser.show {
|
|
||||||
visibility: visible;
|
|
||||||
-webkit-animation: fadein 0.5s;
|
|
||||||
}
|
|
||||||
#DeleteUser {
|
|
||||||
visibility: hidden;
|
|
||||||
min-width: 250px;
|
|
||||||
margin-left: -125px;
|
|
||||||
background-color: #333;
|
|
||||||
color: #fff;
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 2px;
|
|
||||||
padding: 16px;
|
|
||||||
position: fixed;
|
|
||||||
z-index: 99999;
|
|
||||||
left: 50%;
|
|
||||||
top: 30px;
|
top: 30px;
|
||||||
font-size: 14px;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
to {
|
||||||
#deleteObj.show {
|
top: 0;
|
||||||
visibility: visible;
|
opacity: 0;
|
||||||
-webkit-animation: fadein 0.5s;
|
|
||||||
}
|
}
|
||||||
#deleteObj {
|
}
|
||||||
visibility: hidden;
|
|
||||||
min-width: 250px;
|
@keyframes fadeout {
|
||||||
margin-left: -125px;
|
from {
|
||||||
background-color: #333;
|
|
||||||
color: #fff;
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 2px;
|
|
||||||
padding: 16px;
|
|
||||||
position: fixed;
|
|
||||||
z-index: 99999;
|
|
||||||
left: 50%;
|
|
||||||
top: 30px;
|
top: 30px;
|
||||||
font-size: 14px;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
to {
|
||||||
#UpdateColumnValue {
|
top: 0;
|
||||||
visibility: hidden;
|
opacity: 0;
|
||||||
min-width: 250px;
|
|
||||||
margin-left: -125px;
|
|
||||||
background-color: #333;
|
|
||||||
color: #fff;
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 2px;
|
|
||||||
padding: 16px;
|
|
||||||
position: fixed;
|
|
||||||
z-index: 99999;
|
|
||||||
left: 50%;
|
|
||||||
top: 30px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#snackbar.show {
|
|
||||||
visibility: visible;
|
|
||||||
-webkit-animation: fadein 0.5s;
|
|
||||||
}
|
|
||||||
|
|
||||||
#snackbar1 {
|
|
||||||
visibility: hidden;
|
|
||||||
min-width: 250px;
|
|
||||||
margin-left: -125px;
|
|
||||||
background-color: #333;
|
|
||||||
color: #fff;
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 2px;
|
|
||||||
padding: 16px;
|
|
||||||
position: fixed;
|
|
||||||
z-index: 99999;
|
|
||||||
left: 50%;
|
|
||||||
top: 30px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#snackbar1.show {
|
|
||||||
visibility: visible;
|
|
||||||
-webkit-animation: fadein 0.5s;
|
|
||||||
}
|
|
||||||
|
|
||||||
#snackbar10 {
|
|
||||||
visibility: hidden;
|
|
||||||
min-width: 250px;
|
|
||||||
margin-left: -125px;
|
|
||||||
background-color: #333;
|
|
||||||
color: #fff;
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 2px;
|
|
||||||
padding: 16px;
|
|
||||||
position: fixed;
|
|
||||||
z-index: 99999;
|
|
||||||
left: 50%;
|
|
||||||
top: 30px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#snackbar10.show {
|
|
||||||
visibility: visible;
|
|
||||||
-webkit-animation: fadein 0.5s;
|
|
||||||
}
|
|
||||||
|
|
||||||
#snackbarCol {
|
|
||||||
visibility: hidden;
|
|
||||||
min-width: 250px;
|
|
||||||
margin-left: -125px;
|
|
||||||
background-color: #333;
|
|
||||||
color: #fff;
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 2px;
|
|
||||||
padding: 16px;
|
|
||||||
position: fixed;
|
|
||||||
z-index: 99999;
|
|
||||||
left: 50%;
|
|
||||||
top: 30px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#snackbarCol.show {
|
|
||||||
visibility: visible;
|
|
||||||
-webkit-animation: fadein 0.5s;
|
|
||||||
}
|
|
||||||
|
|
||||||
@-webkit-keyframes fadein {
|
|
||||||
from {
|
|
||||||
top: 0;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
top: 30px;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fadein {
|
|
||||||
from {
|
|
||||||
top: 0;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
top: 30px;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@-webkit-keyframes fadeout {
|
|
||||||
from {
|
|
||||||
top: 30px;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
top: 0;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fadeout {
|
|
||||||
from {
|
|
||||||
top: 30px;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
top: 0;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
export function customAPIurl() {
|
||||||
|
const url = new URL(process.env.SERVER_URL);
|
||||||
|
return url.pathname === '/api/app' ? url.origin + '/api' : url.origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const color = [
|
||||||
|
'#93a3db',
|
||||||
|
'#e6c3db',
|
||||||
|
'#c0e3bc',
|
||||||
|
'#bce3db',
|
||||||
|
'#b8ccdb',
|
||||||
|
'#ceb8db',
|
||||||
|
'#ffccff',
|
||||||
|
'#99ffcc',
|
||||||
|
'#cc99ff',
|
||||||
|
'#ffcc99',
|
||||||
|
'#66ccff',
|
||||||
|
'#ffffcc',
|
||||||
|
];
|
||||||
|
|
||||||
|
export function replaceMailVaribles(subject, body, variables) {
|
||||||
|
let replacedSubject = subject;
|
||||||
|
let replacedBody = body;
|
||||||
|
|
||||||
|
for (const variable in variables) {
|
||||||
|
const regex = new RegExp(`{{${variable}}}`, 'g');
|
||||||
|
if (subject) {
|
||||||
|
replacedSubject = replacedSubject.replace(regex, variables[variable]);
|
||||||
|
}
|
||||||
|
if (body) {
|
||||||
|
replacedBody = replacedBody.replace(regex, variables[variable]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = {
|
||||||
|
subject: replacedSubject,
|
||||||
|
body: replacedBody,
|
||||||
|
};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
//--npm modules
|
||||||
|
import express from 'express';
|
||||||
|
import cors from 'cors';
|
||||||
|
export const app = express();
|
||||||
|
import dotenv from 'dotenv';
|
||||||
|
import getUser from './routes/getUser.js';
|
||||||
|
import getDocumentList from './routes/getDocumentList.js';
|
||||||
|
import getDocument from './routes/getDocument.js';
|
||||||
|
import getContact from './routes/getContact.js';
|
||||||
|
import deleteContact from './routes/deleteContact.js';
|
||||||
|
import getContactList from './routes/getContactList.js';
|
||||||
|
import draftDocument from './routes/draftDocument.js';
|
||||||
|
import createTemplate from './routes/createTemplate.js';
|
||||||
|
import getTemplate from './routes/getTemplate.js';
|
||||||
|
import deletedTemplate from './routes/deleteTemplate.js';
|
||||||
|
import getTemplatetList from './routes/getTemplateList.js';
|
||||||
|
import updateTemplate from './routes/updateTemplate.js';
|
||||||
|
import createContact from './routes/createContact.js';
|
||||||
|
import multer from 'multer';
|
||||||
|
// import fs from 'node:fs';
|
||||||
|
import updateDocument from './routes/updateDocument.js';
|
||||||
|
import deleteDocument from './routes/deleteDocument.js';
|
||||||
|
import createDocumentWithTemplate from './routes/CreateDocumentWithTemplate.js';
|
||||||
|
import saveWebhook from './routes/saveWebhook.js';
|
||||||
|
import deleteWebhook from './routes/deleteWebhook.js';
|
||||||
|
import getWebhook from './routes/getWebhook.js';
|
||||||
|
import createDocumentwithCoordinate from './routes/createDocumentwithCoordinate.js';
|
||||||
|
import createTemplatewithCoordinate from './routes/createTemplatewithCoordinate.js';
|
||||||
|
dotenv.config();
|
||||||
|
const storage = multer.memoryStorage();
|
||||||
|
const upload = multer({ storage: storage });
|
||||||
|
|
||||||
|
app.use(cors());
|
||||||
|
app.use(express.json({ limit: '50mb' }));
|
||||||
|
app.use(express.urlencoded({ limit: '50mb', extended: true }));
|
||||||
|
|
||||||
|
// get user details whose api token used
|
||||||
|
app.get('/getuser', getUser);
|
||||||
|
|
||||||
|
// get contact on the basis of id
|
||||||
|
app.post('/createcontact', createContact);
|
||||||
|
|
||||||
|
// get contact on the basis of id
|
||||||
|
app.get('/contact/:contact_id', getContact);
|
||||||
|
|
||||||
|
// soft delete contact
|
||||||
|
app.delete('/contact/:contact_id', deleteContact);
|
||||||
|
|
||||||
|
// get list of contacts
|
||||||
|
app.get('/contactlist', getContactList);
|
||||||
|
|
||||||
|
// create Document
|
||||||
|
app.post('/createdocumentwithbinary', upload.array('file', 1), createDocumentwithCoordinate);
|
||||||
|
|
||||||
|
// create Document with co-ordinate
|
||||||
|
app.post('/createdocument', createDocumentwithCoordinate);
|
||||||
|
|
||||||
|
// create Document with base64 without placeholder
|
||||||
|
app.post('/draftdocument', draftDocument);
|
||||||
|
|
||||||
|
// create Document with templateId
|
||||||
|
app.post('/createdocument/:template_id', createDocumentWithTemplate);
|
||||||
|
|
||||||
|
// get Document on the basis of id
|
||||||
|
app.get('/document/:document_id', getDocument);
|
||||||
|
|
||||||
|
// get document on the basis of id
|
||||||
|
app.put('/document/:document_id', updateDocument);
|
||||||
|
|
||||||
|
// get document on the basis of id
|
||||||
|
app.delete('/document/:document_id', deleteDocument);
|
||||||
|
|
||||||
|
// get all types of documents on the basis of doctype
|
||||||
|
app.get('/documentlist/:doctype', getDocumentList);
|
||||||
|
|
||||||
|
// create Template with co-ordinate
|
||||||
|
app.post('/createtemplate', createTemplatewithCoordinate);
|
||||||
|
|
||||||
|
// create Template
|
||||||
|
app.post('/drafttemplate', createTemplate);
|
||||||
|
|
||||||
|
// create Template with binary
|
||||||
|
app.post('/createtemplatewithbinary', upload.array('file', 1), createTemplatewithCoordinate);
|
||||||
|
|
||||||
|
// get template on the basis of id
|
||||||
|
app.get('/template/:template_id', getTemplate);
|
||||||
|
|
||||||
|
// get template on the basis of id
|
||||||
|
app.put('/template/:template_id', updateTemplate);
|
||||||
|
|
||||||
|
// get template on the basis of id
|
||||||
|
app.delete('/template/:template_id', deletedTemplate);
|
||||||
|
|
||||||
|
// get all types of documents on the basis of doctype
|
||||||
|
app.get('/templatelist', getTemplatetList);
|
||||||
|
|
||||||
|
// set and update webhook
|
||||||
|
app.get('/webhook', getWebhook);
|
||||||
|
|
||||||
|
// set and update webhook
|
||||||
|
app.post('/webhook', saveWebhook);
|
||||||
|
|
||||||
|
// set and update webhook
|
||||||
|
app.delete('/webhook', deleteWebhook);
|
||||||
@@ -0,0 +1,367 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import { customAPIurl, replaceMailVaribles } from '../../../../Utils.js';
|
||||||
|
|
||||||
|
// `sendDoctoWebhook` is used to send res data of document on webhook
|
||||||
|
async function sendDoctoWebhook(doc, WebhookUrl, userId) {
|
||||||
|
if (WebhookUrl) {
|
||||||
|
const params = {
|
||||||
|
event: 'created',
|
||||||
|
...doc,
|
||||||
|
};
|
||||||
|
await axios
|
||||||
|
.post(WebhookUrl, params, {
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
try {
|
||||||
|
// console.log('res ', res);
|
||||||
|
const webhook = new Parse.Object('contracts_Webhook');
|
||||||
|
webhook.set('Log', res?.status);
|
||||||
|
webhook.set('UserId', {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: userId,
|
||||||
|
});
|
||||||
|
webhook.save(null, { useMasterKey: true });
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err save in contracts_Webhook', err);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log('Err send data to webhook', err);
|
||||||
|
try {
|
||||||
|
const webhook = new Parse.Object('contracts_Webhook');
|
||||||
|
webhook.set('Log', err?.status);
|
||||||
|
webhook.set('UserId', {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: userId,
|
||||||
|
});
|
||||||
|
webhook.save(null, { useMasterKey: true });
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err save in contracts_Webhook', err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// console.log('res ', res.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default async function createDocumentWithTemplate(request, response) {
|
||||||
|
const signers = request.body.signers;
|
||||||
|
const folderId = request.body.folderId;
|
||||||
|
const templateId = request.params.template_id;
|
||||||
|
const protocol = customAPIurl();
|
||||||
|
const baseUrl = new URL(process.env.SERVER_URL);
|
||||||
|
const send_email = request.body.send_email;
|
||||||
|
const email_subject = request.body.email_subject;
|
||||||
|
const email_body = request.body.email_body;
|
||||||
|
const sendInOrder = request.body.sendInOrder || false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
const templateQuery = new Parse.Query('contracts_Template');
|
||||||
|
templateQuery.include('ExtUserPtr');
|
||||||
|
const templateRes = await templateQuery.get(templateId, { useMasterKey: true });
|
||||||
|
if (templateRes) {
|
||||||
|
const template = JSON.parse(JSON.stringify(templateRes));
|
||||||
|
if (template?.Placeholders?.length > 0) {
|
||||||
|
const emptyplaceholder = template?.Placeholders.filter(x => !x.signerObjId);
|
||||||
|
const isValid =
|
||||||
|
signers.length >= emptyplaceholder.length &&
|
||||||
|
signers.length <= template?.Placeholders?.length;
|
||||||
|
const placeholder =
|
||||||
|
signers.length > emptyplaceholder.length ? template.Placeholders : emptyplaceholder;
|
||||||
|
const updateSigners = placeholder.every(y => signers?.some(x => x.role === y.Role));
|
||||||
|
// console.log('isValid ', isValid);
|
||||||
|
if (isValid && updateSigners) {
|
||||||
|
const folderPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Document',
|
||||||
|
objectId: folderId,
|
||||||
|
};
|
||||||
|
const template = JSON.parse(JSON.stringify(templateRes));
|
||||||
|
const object = new Parse.Object('contracts_Document');
|
||||||
|
object.set('Name', template.Name);
|
||||||
|
if (template?.Note) {
|
||||||
|
object.set('Note', template.Note);
|
||||||
|
}
|
||||||
|
if (template?.Description) {
|
||||||
|
object.set('Description', template.Description);
|
||||||
|
}
|
||||||
|
object.set('IsSendMail', send_email);
|
||||||
|
if (sendInOrder) {
|
||||||
|
object.set('SendinOrder', sendInOrder);
|
||||||
|
} else if (template?.SendinOrder && template?.SendinOrder) {
|
||||||
|
object.set('SendinOrder', template?.SendinOrder);
|
||||||
|
}
|
||||||
|
let templateSigner = template?.Signers ? template?.Signers : [];
|
||||||
|
let contact = [];
|
||||||
|
if (signers && signers.length > 0) {
|
||||||
|
let parseSigners = [...signers];
|
||||||
|
let createContactUrl = protocol + '/v1/createcontact';
|
||||||
|
|
||||||
|
for (const obj of parseSigners) {
|
||||||
|
const body = {
|
||||||
|
name: obj?.name || '',
|
||||||
|
email: obj?.email || '',
|
||||||
|
phone: obj?.phone || '',
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const res = await axios.post(createContactUrl, body, {
|
||||||
|
headers: { 'Content-Type': 'application/json', 'x-api-token': reqToken },
|
||||||
|
});
|
||||||
|
const contactPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Contactbook',
|
||||||
|
objectId: res.data?.objectId,
|
||||||
|
};
|
||||||
|
const newObj = { ...obj, contactPtr: contactPtr };
|
||||||
|
contact.push(newObj);
|
||||||
|
} catch (err) {
|
||||||
|
// console.log('err ', err);
|
||||||
|
if (err?.response?.data?.objectId) {
|
||||||
|
const contactPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Contactbook',
|
||||||
|
objectId: err.response.data?.objectId,
|
||||||
|
};
|
||||||
|
const newObj = { ...obj, contactPtr: contactPtr };
|
||||||
|
contact.push(newObj);
|
||||||
|
} else {
|
||||||
|
console.log('err ', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const contactPtrs = contact.map(x => x.contactPtr);
|
||||||
|
object.set('Signers', [...templateSigner, ...contactPtrs]);
|
||||||
|
|
||||||
|
let updatedPlaceholder = template?.Placeholders?.map(x => {
|
||||||
|
let matchingSigner = contact.find(y => x.Role && x.Role === y.role);
|
||||||
|
|
||||||
|
if (matchingSigner) {
|
||||||
|
return {
|
||||||
|
...x,
|
||||||
|
signerObjId: matchingSigner?.contactPtr?.objectId,
|
||||||
|
signerPtr: matchingSigner?.contactPtr,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
...x,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
object.set('Placeholders', updatedPlaceholder);
|
||||||
|
} else {
|
||||||
|
object.set('Signers', templateSigner);
|
||||||
|
}
|
||||||
|
object.set('URL', template.URL);
|
||||||
|
object.set('CreatedBy', template.CreatedBy);
|
||||||
|
object.set('ExtUserPtr', {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Users',
|
||||||
|
objectId: template.ExtUserPtr.objectId,
|
||||||
|
});
|
||||||
|
if (folderId) {
|
||||||
|
object.set('Folder', folderPtr);
|
||||||
|
}
|
||||||
|
const newACL = new Parse.ACL();
|
||||||
|
newACL.setPublicReadAccess(false);
|
||||||
|
newACL.setPublicWriteAccess(false);
|
||||||
|
newACL.setReadAccess(userPtr.objectId, true);
|
||||||
|
newACL.setWriteAccess(userPtr.objectId, true);
|
||||||
|
object.setACL(newACL);
|
||||||
|
const res = await object.save(null, { useMasterKey: true });
|
||||||
|
|
||||||
|
const newDate = new Date();
|
||||||
|
newDate.setDate(newDate.getDate() + 15);
|
||||||
|
const localExpireDate = newDate.toLocaleDateString('en-US', {
|
||||||
|
day: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
year: 'numeric',
|
||||||
|
});
|
||||||
|
let sender = template.ExtUserPtr.Email;
|
||||||
|
let sendMail;
|
||||||
|
const serverUrl = process.env.SERVER_URL;
|
||||||
|
const newServer = serverUrl.replaceAll('/', '%2F');
|
||||||
|
const serverParams = `${newServer}%2F&${process.env.APP_ID}&contracts`;
|
||||||
|
if (send_email === false) {
|
||||||
|
console.log("don't send mail");
|
||||||
|
} else {
|
||||||
|
let contactMail = contact;
|
||||||
|
if (sendInOrder) {
|
||||||
|
contactMail = contact.slice();
|
||||||
|
contactMail.splice(1);
|
||||||
|
}
|
||||||
|
for (let i = 0; i < contactMail.length; i++) {
|
||||||
|
try {
|
||||||
|
const imgPng = 'https://qikinnovation.ams3.digitaloceanspaces.com/logo.png';
|
||||||
|
let url = `${process.env.SERVER_URL}/functions/sendmailv3/`;
|
||||||
|
const headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-Parse-Application-Id': process.env.APP_ID,
|
||||||
|
'X-Parse-Master-Key': process.env.MASTER_KEY,
|
||||||
|
};
|
||||||
|
|
||||||
|
const objectId = contactMail[i].contactPtr.objectId;
|
||||||
|
|
||||||
|
const hostUrl = baseUrl.origin + '/loadmf/signmicroapp';
|
||||||
|
let signPdf = `${hostUrl}/login/${res.id}/${contactMail[i].email}/${objectId}/${serverParams}`;
|
||||||
|
const openSignUrl = 'https://www.opensignlabs.com/contact-us';
|
||||||
|
const orgName = template.ExtUserPtr.Company ? template.ExtUserPtr.Company : '';
|
||||||
|
const themeBGcolor = '#47a3ad';
|
||||||
|
const email_html =
|
||||||
|
"<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /> </head> <body> <div style='background-color: #f5f5f5; padding: 20px'> <div style='box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;background: white;padding-bottom: 20px;'> <div style='padding:10px 10px 0 10px'><img src='" +
|
||||||
|
imgPng +
|
||||||
|
"' height='50' style='padding:20px; width:170px; height:40px;' /></div><div style='padding: 2px;font-family: system-ui;background-color:" +
|
||||||
|
themeBGcolor +
|
||||||
|
";'><p style='font-size: 20px;font-weight: 400;color: white;padding-left: 20px;' > Digital Signature Request</p></div><div><p style='padding: 20px;font-family: system-ui;font-size: 14px; margin-bottom: 10px;'> " +
|
||||||
|
template.ExtUserPtr.Name +
|
||||||
|
' has requested you to review and sign <strong> ' +
|
||||||
|
template.Name +
|
||||||
|
"</strong>.</p><div style='padding: 5px 0px 5px 25px;display: flex;flex-direction: row;justify-content: space-around;'><table> <tr> <td style='font-weight:bold;font-family:sans-serif;font-size:15px'>Sender</td> <td> </td> <td style='color:#626363;font-weight:bold'>" +
|
||||||
|
sender +
|
||||||
|
"</td></tr><tr><td style='font-weight:bold;font-family:sans-serif;font-size:15px'>Organization</td> <td> </td><td style='color:#626363;font-weight:bold'> " +
|
||||||
|
orgName +
|
||||||
|
"</td></tr> <tr> <td style='font-weight:bold;font-family:sans-serif;font-size:15px'>Expires on</td><td> </td> <td style='color:#626363;font-weight:bold'>" +
|
||||||
|
localExpireDate +
|
||||||
|
"</td></tr><tr> <td></td> <td> </td></tr></table> </div> <div style='margin-left:70px'><a href=" +
|
||||||
|
signPdf +
|
||||||
|
"> <button style='padding: 12px 12px 12px 12px;background-color: #d46b0f;color: white; border: 0px;box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px,rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;font-weight:bold;margin-top:30px;'>Sign here</button></a> </div> <div style='display: flex; justify-content: center;margin-top: 10px;'> </div></div></div><div><p> This is an automated email from OpenSign™. For any queries regarding this email, please contact the sender " +
|
||||||
|
sender +
|
||||||
|
' directly.If you think this email is inappropriate or spam, you may file a complaint with OpenSign™ <a href=' +
|
||||||
|
openSignUrl +
|
||||||
|
' target=_blank>here</a>.</p> </div></div></body> </html>';
|
||||||
|
|
||||||
|
let replaceVar;
|
||||||
|
const variables = {
|
||||||
|
document_title: template.Name,
|
||||||
|
sender_name: template.ExtUserPtr.Name,
|
||||||
|
sender_mail: template.ExtUserPtr.Email,
|
||||||
|
sender_phone: template.ExtUserPtr.Phone,
|
||||||
|
receiver_name: contactMail[i].name,
|
||||||
|
receiver_email: contactMail[i].email,
|
||||||
|
receiver_phone: contactMail[i].phone,
|
||||||
|
expiry_date: localExpireDate,
|
||||||
|
company_name: orgName,
|
||||||
|
signing_url: signPdf,
|
||||||
|
};
|
||||||
|
if (email_subject && email_body) {
|
||||||
|
replaceVar = replaceMailVaribles(email_subject, email_body, variables);
|
||||||
|
} else if (email_subject) {
|
||||||
|
replaceVar = replaceMailVaribles(email_subject, '', variables);
|
||||||
|
replaceVar = { subject: replaceVar.subject, body: email_html };
|
||||||
|
} else if (email_body) {
|
||||||
|
replaceVar = replaceMailVaribles(
|
||||||
|
`${template.ExtUserPtr.Name} has requested you to sign ${template.Name}`,
|
||||||
|
email_body,
|
||||||
|
variables
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
replaceVar = {
|
||||||
|
subject: `${template.ExtUserPtr.Name} has requested you to sign ${template.Name}`,
|
||||||
|
body: email_html,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const subject = replaceVar.subject;
|
||||||
|
const html = replaceVar.body;
|
||||||
|
let params = {
|
||||||
|
recipient: contactMail[i].email,
|
||||||
|
subject: subject,
|
||||||
|
from: sender,
|
||||||
|
html: html,
|
||||||
|
};
|
||||||
|
sendMail = await axios.post(url, params, { headers: headers });
|
||||||
|
} catch (error) {
|
||||||
|
console.log('error', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if (sendMail.data.result.status === 'success') {
|
||||||
|
try {
|
||||||
|
const doc = {
|
||||||
|
objectId: res.id,
|
||||||
|
file: template?.URL,
|
||||||
|
name: template?.Name,
|
||||||
|
note: template?.Note || '',
|
||||||
|
description: template?.Description || '',
|
||||||
|
signers: contact?.map(x => ({ name: x.name, email: x.email, phone: x.phone })),
|
||||||
|
createdAt: res.createdAt,
|
||||||
|
};
|
||||||
|
if (template.ExtUserPtr && template.ExtUserPtr?.Webhook) {
|
||||||
|
sendDoctoWebhook(doc, template.ExtUserPtr?.Webhook, userPtr?.objectId);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('Err', err);
|
||||||
|
}
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_create_document_with_templateid',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({
|
||||||
|
objectId: res.id,
|
||||||
|
signurl: contact.map(x => ({
|
||||||
|
email: x.email,
|
||||||
|
url: `${baseUrl.origin}/loadmf/signmicroapp/login/${res.id}/${x.email}/${x.contactPtr.objectId}/${serverParams}`,
|
||||||
|
})),
|
||||||
|
message: 'Document sent successfully!',
|
||||||
|
});
|
||||||
|
// }
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_create_document_with_templateid',
|
||||||
|
properties: { response_code: 400 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(400).json({ error: 'Please provide signers properly!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_create_document_with_templateid',
|
||||||
|
properties: { response_code: 400 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(400).json({ error: 'Please setup template properly!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_create_document_with_templateid',
|
||||||
|
properties: { response_code: 404 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(404).json({ error: 'Invalid template id!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err ', err);
|
||||||
|
if (err.code === 101) {
|
||||||
|
return response.status(404).json({ error: 'Invalid template id!' });
|
||||||
|
}
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,216 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
export default async function createContact(request, response) {
|
||||||
|
const serverUrl = process.env.SERVER_URL;
|
||||||
|
const appId = process.env.APP_ID;
|
||||||
|
const name = request.body.name;
|
||||||
|
const phone = request.body.phone;
|
||||||
|
const email = request.body.email;
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const contactbook = new Parse.Query('contracts_Contactbook');
|
||||||
|
contactbook.equalTo('Email', email);
|
||||||
|
contactbook.equalTo('CreatedBy', userPtr);
|
||||||
|
contactbook.notEqualTo('IsDeleted', true);
|
||||||
|
const userExists = await contactbook.first({ useMasterKey: true });
|
||||||
|
|
||||||
|
if (userExists) {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_create_contact',
|
||||||
|
properties: { response_code: 401 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
.status(401)
|
||||||
|
.json({ error: 'Contact already exists!', objectId: userExists.id });
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
const Tenant = new Parse.Query('partners_Tenant');
|
||||||
|
Tenant.equalTo('UserId', userPtr);
|
||||||
|
const tenantRes = await Tenant.first({ useMasterKey: true });
|
||||||
|
|
||||||
|
const contactQuery = new Parse.Object('contracts_Contactbook');
|
||||||
|
contactQuery.set('Name', name);
|
||||||
|
contactQuery.set('Phone', phone);
|
||||||
|
contactQuery.set('Email', email);
|
||||||
|
contactQuery.set('UserRole', 'contracts_Guest');
|
||||||
|
if (tenantRes && tenantRes.id) {
|
||||||
|
contactQuery.set('TenantId', {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'partners_Tenant',
|
||||||
|
objectId: tenantRes.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const _users = Parse.Object.extend('User');
|
||||||
|
const _user = new _users();
|
||||||
|
_user.set('name', name);
|
||||||
|
_user.set('username', email);
|
||||||
|
_user.set('email', email);
|
||||||
|
_user.set('phone', phone);
|
||||||
|
_user.set('password', phone);
|
||||||
|
|
||||||
|
const user = await _user.save();
|
||||||
|
if (user) {
|
||||||
|
const roleurl = `${serverUrl}/functions/AddUserToRole`;
|
||||||
|
const headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-Parse-Application-Id': appId,
|
||||||
|
// sessionToken: localStorage.getItem('accesstoken'),
|
||||||
|
};
|
||||||
|
const body = {
|
||||||
|
appName: 'contracts',
|
||||||
|
roleName: 'contracts_Guest',
|
||||||
|
userId: user.id,
|
||||||
|
};
|
||||||
|
await axios.post(roleurl, body, { headers: headers });
|
||||||
|
const currentUser = userPtr;
|
||||||
|
contactQuery.set('CreatedBy', currentUser);
|
||||||
|
contactQuery.set('UserId', user);
|
||||||
|
|
||||||
|
const acl = new Parse.ACL();
|
||||||
|
acl.setReadAccess(userPtr.objectId, true);
|
||||||
|
acl.setWriteAccess(userPtr.objectId, true);
|
||||||
|
acl.setReadAccess(user.id, true);
|
||||||
|
acl.setWriteAccess(user.id, true);
|
||||||
|
contactQuery.setACL(acl);
|
||||||
|
|
||||||
|
const contactRes = await contactQuery.save();
|
||||||
|
const parseRes = JSON.parse(JSON.stringify(contactRes));
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_create_contact',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({
|
||||||
|
objectId: parseRes.objectId,
|
||||||
|
name: parseRes.Name,
|
||||||
|
email: parseRes.Email,
|
||||||
|
phone: parseRes.Phone,
|
||||||
|
createdAt: parseRes.createdAt,
|
||||||
|
updatedAt: parseRes.updatedAt,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err in', err);
|
||||||
|
if (err.code === 202) {
|
||||||
|
const params = { email: email };
|
||||||
|
const userRes = await Parse.Cloud.run('getUserId', params);
|
||||||
|
const roleurl = `${serverUrl}/functions/AddUserToRole`;
|
||||||
|
const headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-Parse-Application-Id': appId,
|
||||||
|
// sessionToken: localStorage.getItem('accesstoken'),
|
||||||
|
};
|
||||||
|
const body = {
|
||||||
|
appName: 'contracts',
|
||||||
|
roleName: 'contracts_Guest',
|
||||||
|
userId: userRes.objectId,
|
||||||
|
};
|
||||||
|
await axios.post(roleurl, body, { headers: headers });
|
||||||
|
contactQuery.set('CreatedBy', userPtr.objectId);
|
||||||
|
contactQuery.set('UserId', {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: userRes.id,
|
||||||
|
});
|
||||||
|
const acl = new Parse.ACL();
|
||||||
|
acl.setReadAccess(userPtr.objectId, true);
|
||||||
|
acl.setWriteAccess(userPtr.objectId, true);
|
||||||
|
acl.setReadAccess(userRes.id, true);
|
||||||
|
acl.setWriteAccess(userRes.id, true);
|
||||||
|
|
||||||
|
contactQuery.setACL(acl);
|
||||||
|
const contactRes = await contactQuery.save();
|
||||||
|
if (contactRes) {
|
||||||
|
const parseRes = JSON.parse(JSON.stringify(contactRes));
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_create_contact',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({
|
||||||
|
objectId: parseRes.objectId,
|
||||||
|
name: parseRes.Name,
|
||||||
|
email: parseRes.Email,
|
||||||
|
phone: parseRes.Phone,
|
||||||
|
createdAt: parseRes.createdAt,
|
||||||
|
updatedAt: parseRes.updatedAt,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (err.code === 137) {
|
||||||
|
return response.status(401).json({ error: 'Contact already exists!' });
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
.status(400)
|
||||||
|
.json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err ', err);
|
||||||
|
if (err.code === 137) {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_create_contact',
|
||||||
|
properties: { response_code: 401 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(401).json({ error: 'Contact already exists!' });
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_create_contact',
|
||||||
|
properties: { response_code: 400 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
.status(400)
|
||||||
|
.json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_create_contact',
|
||||||
|
properties: { response_code: 400 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
.status(400)
|
||||||
|
.json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('Err ', err);
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,379 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import { color, customAPIurl, replaceMailVaribles } from '../../../../Utils.js';
|
||||||
|
|
||||||
|
// `sendDoctoWebhook` is used to send res data of document on webhook
|
||||||
|
async function sendDoctoWebhook(doc, WebhookUrl, userId) {
|
||||||
|
if (WebhookUrl) {
|
||||||
|
const params = {
|
||||||
|
event: 'created',
|
||||||
|
...doc,
|
||||||
|
};
|
||||||
|
await axios
|
||||||
|
.post(WebhookUrl, params, {
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
try {
|
||||||
|
// console.log('res ', res);
|
||||||
|
const webhook = new Parse.Object('contracts_Webhook');
|
||||||
|
webhook.set('Log', res?.status);
|
||||||
|
webhook.set('UserId', {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: userId,
|
||||||
|
});
|
||||||
|
webhook.save(null, { useMasterKey: true });
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err save in contracts_Webhook', err);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log('Err send data to webhook', err);
|
||||||
|
try {
|
||||||
|
const webhook = new Parse.Object('contracts_Webhook');
|
||||||
|
webhook.set('Log', err?.status);
|
||||||
|
webhook.set('UserId', {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: userId,
|
||||||
|
});
|
||||||
|
webhook.save(null, { useMasterKey: true });
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err save in contracts_Webhook', err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// console.log('res ', res.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const randomId = () => Math.floor(1000 + Math.random() * 9000);
|
||||||
|
export default async function createDocumentwithCoordinate(request, response) {
|
||||||
|
const name = request.body.title;
|
||||||
|
const note = request.body.note;
|
||||||
|
const description = request.body.description;
|
||||||
|
const send_email = request.body.send_email;
|
||||||
|
const signers = request.body.signers;
|
||||||
|
const folderId = request.body.folderId;
|
||||||
|
const base64File = request.body.file;
|
||||||
|
const fileData = request.files?.[0] ? request.files[0].buffer : null;
|
||||||
|
const email_subject = request.body.email_subject;
|
||||||
|
const email_body = request.body.email_body;
|
||||||
|
const sendInOrder = request.body.sendInOrder || false;
|
||||||
|
// console.log('fileData ', fileData);
|
||||||
|
const protocol = customAPIurl();
|
||||||
|
const baseUrl = new URL(process.env.SERVER_URL);
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
if (signers && signers.length > 0) {
|
||||||
|
let fileUrl;
|
||||||
|
if (request.files?.[0]) {
|
||||||
|
const file = new Parse.File(request.files?.[0]?.originalname, {
|
||||||
|
base64: fileData?.toString('base64'),
|
||||||
|
});
|
||||||
|
await file.save({ useMasterKey: true });
|
||||||
|
fileUrl = file.url();
|
||||||
|
} else {
|
||||||
|
const file = new Parse.File(`${name}.pdf`, {
|
||||||
|
base64: base64File,
|
||||||
|
});
|
||||||
|
await file.save({ useMasterKey: true });
|
||||||
|
fileUrl = file.url();
|
||||||
|
}
|
||||||
|
const contractsUser = new Parse.Query('contracts_Users');
|
||||||
|
contractsUser.equalTo('UserId', userPtr);
|
||||||
|
const extUser = await contractsUser.first({ useMasterKey: true });
|
||||||
|
const parseExtUser = JSON.parse(JSON.stringify(extUser));
|
||||||
|
|
||||||
|
const extUserPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Users',
|
||||||
|
objectId: extUser.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
const object = new Parse.Object('contracts_Document');
|
||||||
|
object.set('Name', name);
|
||||||
|
|
||||||
|
if (note) {
|
||||||
|
object.set('Note', note);
|
||||||
|
}
|
||||||
|
if (description) {
|
||||||
|
object.set('Description', description);
|
||||||
|
}
|
||||||
|
if (sendInOrder) {
|
||||||
|
object.set('SendinOrder', sendInOrder);
|
||||||
|
}
|
||||||
|
object.set('URL', fileUrl);
|
||||||
|
object.set('CreatedBy', userPtr);
|
||||||
|
object.set('ExtUserPtr', extUserPtr);
|
||||||
|
object.set('IsSendMail', send_email);
|
||||||
|
let contact = [];
|
||||||
|
if (signers && signers.length > 0) {
|
||||||
|
let parseSigners;
|
||||||
|
if (base64File) {
|
||||||
|
parseSigners = signers;
|
||||||
|
} else {
|
||||||
|
parseSigners = JSON.parse(signers);
|
||||||
|
}
|
||||||
|
let createContactUrl = protocol + '/v1/createcontact';
|
||||||
|
|
||||||
|
for (const [index, element] of parseSigners.entries()) {
|
||||||
|
const body = {
|
||||||
|
name: element?.name || '',
|
||||||
|
email: element?.email || '',
|
||||||
|
phone: element?.phone || '',
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const res = await axios.post(createContactUrl, body, {
|
||||||
|
headers: { 'Content-Type': 'application/json', 'x-api-token': reqToken },
|
||||||
|
});
|
||||||
|
// console.log('res ', res.data);
|
||||||
|
const contactPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Contactbook',
|
||||||
|
objectId: res.data?.objectId,
|
||||||
|
};
|
||||||
|
const newObj = { ...element, contactPtr: contactPtr, index: index };
|
||||||
|
contact.push(newObj);
|
||||||
|
} catch (err) {
|
||||||
|
// console.log('err ', err.response);
|
||||||
|
if (err?.response?.data?.objectId) {
|
||||||
|
const contactPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Contactbook',
|
||||||
|
objectId: err.response.data?.objectId,
|
||||||
|
};
|
||||||
|
const newObj = { ...element, contactPtr: contactPtr, index: index };
|
||||||
|
contact.push(newObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object.set(
|
||||||
|
'Signers',
|
||||||
|
contact?.map(x => x.contactPtr)
|
||||||
|
);
|
||||||
|
let updatePlaceholders = contact.map((signer, index) => {
|
||||||
|
const placeHolder = [];
|
||||||
|
|
||||||
|
for (const widget of signer.widgets) {
|
||||||
|
const pageNumber = widget.page;
|
||||||
|
const page = placeHolder.find(page => page.pageNumber === pageNumber);
|
||||||
|
|
||||||
|
const widgetData = {
|
||||||
|
xPosition: widget.x,
|
||||||
|
yPosition: widget.y,
|
||||||
|
isStamp: widget.type === 'stamp',
|
||||||
|
key: randomId(),
|
||||||
|
isDrag: false,
|
||||||
|
firstXPos: widget.x,
|
||||||
|
firstYPos: widget.y,
|
||||||
|
yBottom: 0,
|
||||||
|
scale: 1,
|
||||||
|
isMobile: false,
|
||||||
|
zIndex: 1,
|
||||||
|
type: widget.type,
|
||||||
|
widgetValue: '',
|
||||||
|
Width: widget.w,
|
||||||
|
Height: widget.h,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (page) {
|
||||||
|
page.pos.push(widgetData);
|
||||||
|
} else {
|
||||||
|
placeHolder.push({
|
||||||
|
pageNumber,
|
||||||
|
pos: [widgetData],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
signerObjId: signer?.contactPtr?.objectId,
|
||||||
|
signerPtr: signer?.contactPtr,
|
||||||
|
Role: signer.role,
|
||||||
|
Id: randomId(),
|
||||||
|
blockColor: color[signer?.index],
|
||||||
|
placeHolder,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
object.set('Placeholders', updatePlaceholders);
|
||||||
|
}
|
||||||
|
if (folderId) {
|
||||||
|
object.set('Folder', {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Document',
|
||||||
|
objectId: folderId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const newACL = new Parse.ACL();
|
||||||
|
newACL.setPublicReadAccess(false);
|
||||||
|
newACL.setPublicWriteAccess(false);
|
||||||
|
newACL.setReadAccess(userPtr.objectId, true);
|
||||||
|
newACL.setWriteAccess(userPtr.objectId, true);
|
||||||
|
object.setACL(newACL);
|
||||||
|
const res = await object.save(null, { useMasterKey: true });
|
||||||
|
const doc = {
|
||||||
|
objectId: res.id,
|
||||||
|
file: fileUrl,
|
||||||
|
name: name,
|
||||||
|
note: note || '',
|
||||||
|
description: description || '',
|
||||||
|
signers: contact?.map(x => ({ name: x.name, email: x.email, phone: x.phone })),
|
||||||
|
createdAt: res.createdAt,
|
||||||
|
};
|
||||||
|
if (parseExtUser && parseExtUser.Webhook) {
|
||||||
|
sendDoctoWebhook(doc, parseExtUser?.Webhook, userPtr?.objectId);
|
||||||
|
}
|
||||||
|
const newDate = new Date();
|
||||||
|
newDate.setDate(newDate.getDate() + 15);
|
||||||
|
const localExpireDate = newDate.toLocaleDateString('en-US', {
|
||||||
|
day: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
year: 'numeric',
|
||||||
|
});
|
||||||
|
let sender = parseExtUser.Email;
|
||||||
|
let sendMail;
|
||||||
|
const serverUrl = process.env.SERVER_URL;
|
||||||
|
const newServer = serverUrl.replaceAll('/', '%2F');
|
||||||
|
const serverParams = `${newServer}%2F&${process.env.APP_ID}&contracts`;
|
||||||
|
if (send_email === false) {
|
||||||
|
console.log("don't send mail");
|
||||||
|
} else {
|
||||||
|
let contactMail = contact;
|
||||||
|
if (sendInOrder) {
|
||||||
|
contactMail = contact.slice();
|
||||||
|
contactMail.splice(1);
|
||||||
|
}
|
||||||
|
for (let i = 0; i < contactMail.length; i++) {
|
||||||
|
try {
|
||||||
|
const imgPng = 'https://qikinnovation.ams3.digitaloceanspaces.com/logo.png';
|
||||||
|
let url = `${process.env.SERVER_URL}/functions/sendmailv3/`;
|
||||||
|
const headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-Parse-Application-Id': process.env.APP_ID,
|
||||||
|
'X-Parse-Master-Key': process.env.MASTER_KEY,
|
||||||
|
};
|
||||||
|
|
||||||
|
const objectId = contactMail[i].contactPtr.objectId;
|
||||||
|
|
||||||
|
const hostUrl = baseUrl.origin + '/loadmf/signmicroapp';
|
||||||
|
let signPdf = `${hostUrl}/login/${res.id}/${contactMail[i].email}/${objectId}/${serverParams}`;
|
||||||
|
const openSignUrl = 'https://www.opensignlabs.com/contact-us';
|
||||||
|
const orgName = parseExtUser.Company ? parseExtUser.Company : '';
|
||||||
|
const themeBGcolor = '#47a3ad';
|
||||||
|
const email_html =
|
||||||
|
"<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /> </head> <body> <div style='background-color: #f5f5f5; padding: 20px'> <div style=' box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;background: white;padding-bottom: 20px;'> <div style='padding:10px 10px 0 10px'><img src=" +
|
||||||
|
imgPng +
|
||||||
|
" height='50' style='padding:20px; width:170px; height:40px;' /></div> <div style='padding:2px; font-family: system-ui;background-color:" +
|
||||||
|
themeBGcolor +
|
||||||
|
";'><p style='font-size: 20px;font-weight: 400;color: white;padding-left: 20px;' > Digital Signature Request</p></div><div><p style='padding: 20px;font-family: system-ui;font-size: 14px; margin-bottom: 10px;'> " +
|
||||||
|
parseExtUser.Name +
|
||||||
|
' has requested you to review and sign <strong> ' +
|
||||||
|
name +
|
||||||
|
"</strong>.</p><div style='padding: 5px 0px 5px 25px;display: flex;flex-direction: row;justify-content: space-around;'><table> <tr> <td style='font-weight:bold;font-family:sans-serif;font-size:15px'>Sender</td> <td> </td> <td style='color:#626363;font-weight:bold'>" +
|
||||||
|
sender +
|
||||||
|
"</td></tr><tr><td style='font-weight:bold;font-family:sans-serif;font-size:15px'>Organization</td> <td> </td><td style='color:#626363;font-weight:bold'> " +
|
||||||
|
orgName +
|
||||||
|
"</td></tr> <tr> <td style='font-weight:bold;font-family:sans-serif;font-size:15px'>Expires on</td><td> </td> <td style='color:#626363;font-weight:bold'>" +
|
||||||
|
localExpireDate +
|
||||||
|
"</td></tr><tr> <td></td> <td> </td></tr></table> </div> <div style='margin-left:70px'><a href=" +
|
||||||
|
signPdf +
|
||||||
|
"> <button style='padding: 12px 12px 12px 12px;background-color: #d46b0f;color: white; border: 0px;box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px,rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;font-weight:bold;margin-top:30px'>Sign here</button></a> </div> <div style='display: flex; justify-content: center;margin-top: 10px;'> </div></div></div><div><p> This is an automated email from OpenSign™. For any queries regarding this email, please contact the sender " +
|
||||||
|
sender +
|
||||||
|
' directly.If you think this email is inappropriate or spam, you may file a complaint with OpenSign™ <a href=' +
|
||||||
|
openSignUrl +
|
||||||
|
' target=_blank>here</a>.</p> </div></div></body> </html>';
|
||||||
|
let replaceVar;
|
||||||
|
const variables = {
|
||||||
|
document_title: name,
|
||||||
|
sender_name: parseExtUser.Name,
|
||||||
|
sender_mail: parseExtUser.Email,
|
||||||
|
sender_phone: parseExtUser.Phone,
|
||||||
|
receiver_name: contactMail[i].name,
|
||||||
|
receiver_email: contactMail[i].email,
|
||||||
|
receiver_phone: contactMail[i].phone,
|
||||||
|
expiry_date: localExpireDate,
|
||||||
|
company_name: orgName,
|
||||||
|
signing_url: signPdf,
|
||||||
|
};
|
||||||
|
if (email_subject && email_body) {
|
||||||
|
replaceVar = replaceMailVaribles(email_subject, email_body, variables);
|
||||||
|
} else if (email_subject) {
|
||||||
|
replaceVar = replaceMailVaribles(email_subject, '', variables);
|
||||||
|
replaceVar = { subject: replaceVar.subject, body: email_html };
|
||||||
|
} else if (email_body) {
|
||||||
|
replaceVar = replaceMailVaribles(
|
||||||
|
`${parseExtUser.Name} has requested you to sign ${name}`,
|
||||||
|
email_body,
|
||||||
|
variables
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
replaceVar = {
|
||||||
|
subject: `${parseExtUser.Name} has requested you to sign ${parseExtUser.Name}`,
|
||||||
|
body: email_html,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const subject = replaceVar.subject;
|
||||||
|
const html = replaceVar.body;
|
||||||
|
|
||||||
|
let params = {
|
||||||
|
recipient: contactMail[i].email,
|
||||||
|
subject: subject,
|
||||||
|
from: sender,
|
||||||
|
html: html,
|
||||||
|
};
|
||||||
|
|
||||||
|
sendMail = await axios.post(url, params, { headers: headers });
|
||||||
|
} catch (error) {
|
||||||
|
console.log('error', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if (sendMail.data.result.status === 'success') {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_create_document',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({
|
||||||
|
objectId: res.id,
|
||||||
|
signurl: contact.map(x => ({
|
||||||
|
email: x.email,
|
||||||
|
url: `${baseUrl.origin}/loadmf/signmicroapp/login/${res.id}/${x.email}/${x.contactPtr.objectId}/${serverParams}`,
|
||||||
|
})),
|
||||||
|
message: 'Document sent successfully!',
|
||||||
|
});
|
||||||
|
// }
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_create_document',
|
||||||
|
properties: { response_code: 400 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(400).json({ error: 'Please provide signers!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err ', err);
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
import { customAPIurl } from '../../../../Utils.js';
|
||||||
|
|
||||||
|
const randomId = () => Math.floor(1000 + Math.random() * 9000);
|
||||||
|
export default async function createTemplate(request, response) {
|
||||||
|
const name = request.body?.title;
|
||||||
|
const note = request.body?.note;
|
||||||
|
const description = request.body?.description;
|
||||||
|
const signers = request.body?.signers;
|
||||||
|
const folderId = request.body?.folderId;
|
||||||
|
const base64File = request.body.file;
|
||||||
|
const SendinOrder = request.body.sendInOrder || false;
|
||||||
|
const fileData = request.files?.[0] ? request.files[0].buffer : null;
|
||||||
|
const baseUrl = new URL(process.env.SERVER_URL);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
let fileUrl;
|
||||||
|
if (base64File) {
|
||||||
|
const file = new Parse.File(`${name}.pdf`, {
|
||||||
|
base64: base64File,
|
||||||
|
});
|
||||||
|
await file.save({ useMasterKey: true });
|
||||||
|
fileUrl = file.url();
|
||||||
|
} else {
|
||||||
|
const file = new Parse.File(request.files?.[0]?.originalname, {
|
||||||
|
base64: fileData?.toString('base64'),
|
||||||
|
});
|
||||||
|
await file.save({ useMasterKey: true });
|
||||||
|
fileUrl = file.url();
|
||||||
|
}
|
||||||
|
|
||||||
|
const contractsUser = new Parse.Query('contracts_Users');
|
||||||
|
contractsUser.equalTo('UserId', userPtr);
|
||||||
|
const extUser = await contractsUser.first({ useMasterKey: true });
|
||||||
|
const extUserPtr = { __type: 'Pointer', className: 'contracts_Users', objectId: extUser.id };
|
||||||
|
|
||||||
|
const folderPtr = { __type: 'Pointer', className: 'contracts_Template', objectId: folderId };
|
||||||
|
|
||||||
|
const object = new Parse.Object('contracts_Template');
|
||||||
|
object.set('Name', name);
|
||||||
|
if (note) {
|
||||||
|
object.set('Note', note);
|
||||||
|
}
|
||||||
|
if (description) {
|
||||||
|
object.set('Description', description);
|
||||||
|
}
|
||||||
|
object.set('URL', fileUrl);
|
||||||
|
object.set('CreatedBy', userPtr);
|
||||||
|
object.set('ExtUserPtr', extUserPtr);
|
||||||
|
if (SendinOrder) {
|
||||||
|
object.set('SendinOrder', SendinOrder);
|
||||||
|
}
|
||||||
|
if (signers && signers.length > 0) {
|
||||||
|
let parseSigners;
|
||||||
|
if (base64File) {
|
||||||
|
parseSigners = signers;
|
||||||
|
} else {
|
||||||
|
parseSigners = JSON.parse(signers);
|
||||||
|
}
|
||||||
|
let createContactUrl = protocol + '/v1/createcontact';
|
||||||
|
|
||||||
|
let contact = [];
|
||||||
|
for (const obj of parseSigners) {
|
||||||
|
const body = {
|
||||||
|
name: obj?.name || '',
|
||||||
|
email: obj?.email || '',
|
||||||
|
phone: obj?.phone || '',
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const res = await axios.post(createContactUrl, body, {
|
||||||
|
headers: { 'Content-Type': 'application/json', 'x-api-token': reqToken },
|
||||||
|
});
|
||||||
|
// console.log('res ', res.data);
|
||||||
|
contact.push({
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Contactbook',
|
||||||
|
objectId: res.data?.objectId,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
// console.log('err ', err.response);
|
||||||
|
if (err?.response?.data?.objectId) {
|
||||||
|
contact.push({
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Contactbook',
|
||||||
|
objectId: err.response.data?.objectId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object.set('Signers', contact);
|
||||||
|
}
|
||||||
|
if (folderId) {
|
||||||
|
object.set('Folder', folderPtr);
|
||||||
|
}
|
||||||
|
const newACL = new Parse.ACL();
|
||||||
|
newACL.setPublicReadAccess(false);
|
||||||
|
newACL.setPublicWriteAccess(false);
|
||||||
|
newACL.setReadAccess(userPtr.objectId, true);
|
||||||
|
newACL.setWriteAccess(userPtr.objectId, true);
|
||||||
|
object.setACL(newACL);
|
||||||
|
const res = await object.save(null, { useMasterKey: true });
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_draft_template',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({
|
||||||
|
objectId: res.id,
|
||||||
|
url: baseUrl.origin + '/load/signmicroapp/template/' + res.id,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err ', err);
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,214 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import { color, customAPIurl } from '../../../../Utils.js';
|
||||||
|
|
||||||
|
const randomId = () => Math.floor(1000 + Math.random() * 9000);
|
||||||
|
export default async function createTemplatewithCoordinate(request, response) {
|
||||||
|
const name = request.body.title;
|
||||||
|
const note = request.body.note;
|
||||||
|
const description = request.body.description;
|
||||||
|
const signers = request.body.signers;
|
||||||
|
const folderId = request.body.folderId;
|
||||||
|
const base64File = request.body.file;
|
||||||
|
const fileData = request.files?.[0] ? request.files[0].buffer : null;
|
||||||
|
const SendinOrder = request.body.sendInOrder || false;
|
||||||
|
// console.log('fileData ', fileData);
|
||||||
|
const protocol = customAPIurl();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
if (signers && signers.length > 0) {
|
||||||
|
let fileUrl;
|
||||||
|
if (request.files?.[0]) {
|
||||||
|
const file = new Parse.File(request.files?.[0]?.originalname, {
|
||||||
|
base64: fileData?.toString('base64'),
|
||||||
|
});
|
||||||
|
await file.save({ useMasterKey: true });
|
||||||
|
fileUrl = file.url();
|
||||||
|
} else {
|
||||||
|
const file = new Parse.File(`${name}.pdf`, {
|
||||||
|
base64: base64File,
|
||||||
|
});
|
||||||
|
await file.save({ useMasterKey: true });
|
||||||
|
fileUrl = file.url();
|
||||||
|
}
|
||||||
|
const contractsUser = new Parse.Query('contracts_Users');
|
||||||
|
contractsUser.equalTo('UserId', userPtr);
|
||||||
|
const extUser = await contractsUser.first({ useMasterKey: true });
|
||||||
|
const extUserPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Users',
|
||||||
|
objectId: extUser.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
const object = new Parse.Object('contracts_Template');
|
||||||
|
object.set('Name', name);
|
||||||
|
|
||||||
|
if (note) {
|
||||||
|
object.set('Note', note);
|
||||||
|
}
|
||||||
|
if (description) {
|
||||||
|
object.set('Description', description);
|
||||||
|
}
|
||||||
|
if (SendinOrder) {
|
||||||
|
object.set('SendinOrder', SendinOrder);
|
||||||
|
}
|
||||||
|
object.set('URL', fileUrl);
|
||||||
|
object.set('CreatedBy', userPtr);
|
||||||
|
object.set('ExtUserPtr', extUserPtr);
|
||||||
|
let contact = [];
|
||||||
|
if (signers && signers.length > 0) {
|
||||||
|
let parseSigners;
|
||||||
|
if (base64File) {
|
||||||
|
parseSigners = signers;
|
||||||
|
} else {
|
||||||
|
parseSigners = JSON.parse(signers);
|
||||||
|
}
|
||||||
|
let createContactUrl = protocol + '/v1/createcontact';
|
||||||
|
|
||||||
|
for (const [index, element] of parseSigners.entries()) {
|
||||||
|
if (element?.name && element.phone && element?.email) {
|
||||||
|
const body = {
|
||||||
|
name: element?.name || '',
|
||||||
|
email: element?.email || '',
|
||||||
|
phone: element?.phone || '',
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const res = await axios.post(createContactUrl, body, {
|
||||||
|
headers: { 'Content-Type': 'application/json', 'x-api-token': reqToken },
|
||||||
|
});
|
||||||
|
// console.log('res ', res.data);
|
||||||
|
const contactPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Contactbook',
|
||||||
|
objectId: res.data?.objectId,
|
||||||
|
};
|
||||||
|
const newObj = { ...element, contactPtr: contactPtr, index: index };
|
||||||
|
contact.push(newObj);
|
||||||
|
} catch (err) {
|
||||||
|
// console.log('err ', err.response);
|
||||||
|
if (err?.response?.data?.objectId) {
|
||||||
|
const contactPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Contactbook',
|
||||||
|
objectId: err.response.data?.objectId,
|
||||||
|
};
|
||||||
|
const newObj = { ...element, contactPtr: contactPtr, index: index };
|
||||||
|
contact.push(newObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const newObj = { ...element, contactPtr: {}, index: index };
|
||||||
|
contact.push(newObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const updatedSigners = contact?.filter(x => x.contactPtr && x.contactPtr.objectId);
|
||||||
|
if (updatedSigners && updatedSigners.length > 0) {
|
||||||
|
object.set(
|
||||||
|
'Signers',
|
||||||
|
updatedSigners?.map(x => x.contactPtr)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let updatePlaceholders = contact.map((signer, index) => {
|
||||||
|
const placeHolder = [];
|
||||||
|
|
||||||
|
for (const widget of signer.widgets) {
|
||||||
|
const pageNumber = widget.page;
|
||||||
|
const page = placeHolder.find(page => page.pageNumber === pageNumber);
|
||||||
|
|
||||||
|
const widgetData = {
|
||||||
|
xPosition: widget.x,
|
||||||
|
yPosition: widget.y,
|
||||||
|
isStamp: widget.type === 'stamp',
|
||||||
|
key: randomId(),
|
||||||
|
isDrag: false,
|
||||||
|
firstXPos: widget.x,
|
||||||
|
firstYPos: widget.y,
|
||||||
|
yBottom: 0,
|
||||||
|
scale: 1,
|
||||||
|
isMobile: false,
|
||||||
|
zIndex: 1,
|
||||||
|
type: widget.type,
|
||||||
|
widgetValue: '',
|
||||||
|
Width: widget.w,
|
||||||
|
Height: widget.h,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (page) {
|
||||||
|
page.pos.push(widgetData);
|
||||||
|
} else {
|
||||||
|
placeHolder.push({
|
||||||
|
pageNumber,
|
||||||
|
pos: [widgetData],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
signerObjId: signer?.contactPtr?.objectId,
|
||||||
|
signerPtr: signer?.contactPtr,
|
||||||
|
Role: signer.role,
|
||||||
|
Id: randomId(),
|
||||||
|
blockColor: color[signer?.index],
|
||||||
|
placeHolder,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
object.set('Placeholders', updatePlaceholders);
|
||||||
|
}
|
||||||
|
if (folderId) {
|
||||||
|
object.set('Folder', {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Template',
|
||||||
|
objectId: folderId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const newACL = new Parse.ACL();
|
||||||
|
newACL.setPublicReadAccess(false);
|
||||||
|
newACL.setPublicWriteAccess(false);
|
||||||
|
newACL.setReadAccess(userPtr.objectId, true);
|
||||||
|
newACL.setWriteAccess(userPtr.objectId, true);
|
||||||
|
object.setACL(newACL);
|
||||||
|
const res = await object.save(null, { useMasterKey: true });
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_create_template',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({
|
||||||
|
objectId: res.id,
|
||||||
|
message: 'Template created successfully!',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_create_template',
|
||||||
|
properties: { response_code: 400 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(400).json({ error: 'Please provide signers!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err ', err);
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
export default async function deleteContact(request, response) {
|
||||||
|
try {
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Contactbook = new Parse.Query('contracts_Contactbook');
|
||||||
|
Contactbook.equalTo('objectId', request.params.contact_id);
|
||||||
|
Contactbook.equalTo('CreatedBy', userPtr);
|
||||||
|
const res = await Contactbook.first({ useMasterKey: true });
|
||||||
|
if (res) {
|
||||||
|
const isDeleted = res.get('IsDeleted');
|
||||||
|
if (isDeleted && isDeleted) {
|
||||||
|
return response.status(404).json({ error: 'Contact not found!' });
|
||||||
|
} else {
|
||||||
|
const Contactbook = Parse.Object.extend('contracts_Contactbook');
|
||||||
|
const deleteQuery = new Contactbook();
|
||||||
|
deleteQuery.id = request.params.contact_id;
|
||||||
|
deleteQuery.set('IsDeleted', true);
|
||||||
|
const deleteRes = await deleteQuery.save(null, { useMasterKey: true });
|
||||||
|
if (deleteRes) {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_delete_contact',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({
|
||||||
|
objectId: request.params.contact_id,
|
||||||
|
deletedAt: deleteRes.get('updatedAt'),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_delete_contact',
|
||||||
|
properties: { response_code: 404 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(404).json({ error: 'Contact not found!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err ', err);
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
export default async function deleteDocument(request, response) {
|
||||||
|
try {
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Document = new Parse.Query('contracts_Document');
|
||||||
|
Document.equalTo('objectId', request.params.document_id);
|
||||||
|
Document.equalTo('CreatedBy', userPtr);
|
||||||
|
const res = await Document.first({ useMasterKey: true });
|
||||||
|
if (res) {
|
||||||
|
const isArchive = res.get('IsArchive');
|
||||||
|
if (isArchive && isArchive) {
|
||||||
|
return response.status(404).json({ error: 'Document not found!' });
|
||||||
|
} else {
|
||||||
|
const Document = Parse.Object.extend('contracts_Document');
|
||||||
|
const deleteQuery = new Document();
|
||||||
|
deleteQuery.id = request.params.document_id;
|
||||||
|
deleteQuery.set('IsArchive', true);
|
||||||
|
const deleteRes = await deleteQuery.save(null, { useMasterKey: true });
|
||||||
|
if (deleteRes) {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_delete_document',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({
|
||||||
|
objectId: request.params.document_id,
|
||||||
|
deletedAt: deleteRes.get('updatedAt'),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_delete_document',
|
||||||
|
properties: { response_code: 404 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(404).json({ error: 'Document not found!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err ', err);
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
export default async function deletedTemplate(request, response) {
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
const template = new Parse.Query('contracts_Template');
|
||||||
|
template.equalTo('objectId', request.params.template_id);
|
||||||
|
template.equalTo('CreatedBy', userPtr);
|
||||||
|
const res = await template.first({ useMasterKey: true });
|
||||||
|
if (res) {
|
||||||
|
const isArchive = res.get('IsArchive');
|
||||||
|
if (isArchive && isArchive) {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_delete_template',
|
||||||
|
properties: { response_code: 404 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(404).json({ error: 'Template not found!' });
|
||||||
|
} else {
|
||||||
|
const template = Parse.Object.extend('contracts_Template');
|
||||||
|
const deleteQuery = new template();
|
||||||
|
deleteQuery.id = request.params.template_id;
|
||||||
|
deleteQuery.set('IsArchive', true);
|
||||||
|
const deleteRes = await deleteQuery.save(null, { useMasterKey: true });
|
||||||
|
if (deleteRes) {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_delete_template',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({
|
||||||
|
objectId: request.params.template_id,
|
||||||
|
deletedAt: deleteRes.get('updatedAt'),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_delete_template',
|
||||||
|
properties: { response_code: 404 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(404).json({ error: 'Template not found!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err ', err);
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
export default async function deleteWebhook(request, response) {
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
|
||||||
|
const query = new Parse.Query('contracts_Users');
|
||||||
|
query.equalTo('UserId', userPtr);
|
||||||
|
const user = await query.first({ useMasterKey: true });
|
||||||
|
if (user) {
|
||||||
|
const updateQuery = new Parse.Object('contracts_Users');
|
||||||
|
updateQuery.id = user.id;
|
||||||
|
updateQuery.unset('Webhook');
|
||||||
|
const res = await updateQuery.save(null, { useMasterKey: true });
|
||||||
|
if (res) {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_delete_webhook',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({
|
||||||
|
result: 'Webhook deleted successfully!',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_delete_webhook',
|
||||||
|
properties: { response_code: 404 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(404).json({ error: 'User not found!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err ', err);
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import { customAPIurl } from '../../../../Utils.js';
|
||||||
|
|
||||||
|
// const randomId = () => Math.floor(1000 + Math.random() * 9000);
|
||||||
|
export default async function draftDocument(request, response) {
|
||||||
|
const name = request.body.title;
|
||||||
|
const note = request.body.note;
|
||||||
|
const description = request.body.description;
|
||||||
|
const signers = request.body.signers;
|
||||||
|
const folderId = request.body.folderId;
|
||||||
|
const base64File = request.body.file;
|
||||||
|
const send_email = request.body.send_email || true;
|
||||||
|
const fileData = request.files?.[0] ? request.files[0].buffer : null;
|
||||||
|
const SendinOrder = request.body.sendInOrder || false;
|
||||||
|
// console.log('fileData ', fileData);
|
||||||
|
const protocol = customAPIurl();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
// Valid Token then proceed request
|
||||||
|
if (signers && signers.length > 0) {
|
||||||
|
let fileUrl;
|
||||||
|
if (request.files?.[0]) {
|
||||||
|
const file = new Parse.File(request.files?.[0]?.originalname, {
|
||||||
|
base64: fileData?.toString('base64'),
|
||||||
|
});
|
||||||
|
await file.save({ useMasterKey: true });
|
||||||
|
fileUrl = file.url();
|
||||||
|
} else {
|
||||||
|
const file = new Parse.File(`${name}.pdf`, {
|
||||||
|
base64: base64File,
|
||||||
|
});
|
||||||
|
await file.save({ useMasterKey: true });
|
||||||
|
fileUrl = file.url();
|
||||||
|
}
|
||||||
|
const contractsUser = new Parse.Query('contracts_Users');
|
||||||
|
contractsUser.equalTo('UserId', userPtr);
|
||||||
|
const extUser = await contractsUser.first({ useMasterKey: true });
|
||||||
|
const extUserPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Users',
|
||||||
|
objectId: extUser.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
const folderPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Document',
|
||||||
|
objectId: folderId,
|
||||||
|
};
|
||||||
|
|
||||||
|
const object = new Parse.Object('contracts_Document');
|
||||||
|
object.set('Name', name);
|
||||||
|
if (note) {
|
||||||
|
object.set('Note', note);
|
||||||
|
}
|
||||||
|
if (description) {
|
||||||
|
object.set('Description', description);
|
||||||
|
}
|
||||||
|
if (SendinOrder) {
|
||||||
|
object.set('SendinOrder', SendinOrder);
|
||||||
|
}
|
||||||
|
object.set('URL', fileUrl);
|
||||||
|
object.set('CreatedBy', userPtr);
|
||||||
|
object.set('ExtUserPtr', extUserPtr);
|
||||||
|
object.set('IsSendMail', send_email);
|
||||||
|
if (signers && signers.length > 0) {
|
||||||
|
let parseSigners;
|
||||||
|
if (base64File) {
|
||||||
|
parseSigners = signers;
|
||||||
|
} else {
|
||||||
|
parseSigners = JSON.parse(signers);
|
||||||
|
}
|
||||||
|
let createContactUrl = protocol + '/v1/createcontact';
|
||||||
|
|
||||||
|
let contact = [];
|
||||||
|
for (const obj of parseSigners) {
|
||||||
|
const body = {
|
||||||
|
name: obj?.name || '',
|
||||||
|
email: obj?.email || '',
|
||||||
|
phone: obj?.phone || '',
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const res = await axios.post(createContactUrl, body, {
|
||||||
|
headers: { 'Content-Type': 'application/json', 'x-api-token': reqToken },
|
||||||
|
});
|
||||||
|
// console.log('res ', res.data);
|
||||||
|
contact.push({
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Contactbook',
|
||||||
|
objectId: res.data?.objectId,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
// console.log('err ', err.response);
|
||||||
|
if (err?.response?.data?.objectId) {
|
||||||
|
contact.push({
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Contactbook',
|
||||||
|
objectId: err.response.data?.objectId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object.set('Signers', contact);
|
||||||
|
}
|
||||||
|
if (folderId) {
|
||||||
|
object.set('Folder', folderPtr);
|
||||||
|
}
|
||||||
|
const newACL = new Parse.ACL();
|
||||||
|
newACL.setPublicReadAccess(false);
|
||||||
|
newACL.setPublicWriteAccess(false);
|
||||||
|
newACL.setReadAccess(userPtr.objectId, true);
|
||||||
|
newACL.setWriteAccess(userPtr.objectId, true);
|
||||||
|
object.setACL(newACL);
|
||||||
|
const res = await object.save(null, { useMasterKey: true });
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_draft_document',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({
|
||||||
|
objectId: res.id,
|
||||||
|
url: protocol + '/load/signmicroapp/placeholdersign/' + res.id,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_draft_document',
|
||||||
|
properties: { response_code: 400 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(400).json({ error: 'Please provide signers!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err ', err);
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
export default async function getContact(request, response) {
|
||||||
|
try {
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Contactbook = new Parse.Query('contracts_Contactbook');
|
||||||
|
Contactbook.equalTo('objectId', request.params.contact_id);
|
||||||
|
Contactbook.equalTo('CreatedBy', userPtr);
|
||||||
|
Contactbook.notEqualTo('IsDeleted', true);
|
||||||
|
Contactbook.select('Name,Email,Phone');
|
||||||
|
|
||||||
|
const res = await Contactbook.first({ useMasterKey: true });
|
||||||
|
if (res) {
|
||||||
|
const parseRes = JSON.parse(JSON.stringify(res));
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_get_contact',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({
|
||||||
|
objectId: parseRes.objectId,
|
||||||
|
name: parseRes.Name,
|
||||||
|
email: parseRes.Email,
|
||||||
|
phone: parseRes.Phone,
|
||||||
|
createdAt: parseRes.createdAt,
|
||||||
|
updatedAt: parseRes.updatedAt,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_get_contact',
|
||||||
|
properties: { response_code: 404 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(404).json({ error: 'Contact not found!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err ', err);
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
export default async function getContactList(request, response) {
|
||||||
|
try {
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
const limit = request?.query?.limit ? parseInt(request.query.limit) : 100;
|
||||||
|
const skip = request?.query?.skip ? parseInt(request.query.skip) : 0;
|
||||||
|
const Contactbook = new Parse.Query('contracts_Contactbook');
|
||||||
|
Contactbook.equalTo('CreatedBy', userPtr);
|
||||||
|
Contactbook.notEqualTo('IsDeleted', true);
|
||||||
|
Contactbook.limit(limit);
|
||||||
|
Contactbook.skip(skip);
|
||||||
|
Contactbook.descending('createdAt');
|
||||||
|
const res = await Contactbook.find({ useMasterKey: true });
|
||||||
|
if (res && res.length > 0) {
|
||||||
|
const parseRes = JSON.parse(JSON.stringify(res));
|
||||||
|
const contactlist = parseRes.map(x => ({
|
||||||
|
objectId: x.objectId,
|
||||||
|
name: x.Name,
|
||||||
|
email: x.Email,
|
||||||
|
phone: x.Phone,
|
||||||
|
createdAt: x.createdAt,
|
||||||
|
updatedAt: x.updatedAt,
|
||||||
|
}));
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_get_contact_list',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({ result: contactlist });
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_get_contact_list',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({ result: [] });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err ', err);
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
export default async function getDocument(request, response) {
|
||||||
|
try {
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
const Document = new Parse.Query('contracts_Document');
|
||||||
|
Document.equalTo('objectId', request.params.document_id);
|
||||||
|
Document.equalTo('CreatedBy', userPtr);
|
||||||
|
Document.notEqualTo('IsArchive', true);
|
||||||
|
Document.include('Signers');
|
||||||
|
Document.include('Folder');
|
||||||
|
Document.include('ExtUserPtr');
|
||||||
|
Document.include('Placeholders.signerPtr');
|
||||||
|
const res = await Document.first({ useMasterKey: true });
|
||||||
|
if (res) {
|
||||||
|
const document = JSON.parse(JSON.stringify(res));
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_get_document',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({
|
||||||
|
objectId: document.objectId,
|
||||||
|
title: document.Name,
|
||||||
|
note: document.Note || '',
|
||||||
|
folder: { objectId: document?.Folder?.objectId, name: document?.Folder?.Name } || '',
|
||||||
|
file: document?.SignedUrl || document.URL,
|
||||||
|
owner: document?.ExtUserPtr?.Name,
|
||||||
|
signers:
|
||||||
|
document?.Placeholders?.map(y => ({
|
||||||
|
role: y.Role,
|
||||||
|
name: y?.signerPtr?.Name || '',
|
||||||
|
email: y?.signerPtr?.Email || '',
|
||||||
|
phone: y?.signerPtr?.Phone || '',
|
||||||
|
widgets: y.placeHolder?.flatMap(x =>
|
||||||
|
x?.pos.map(w => ({
|
||||||
|
type: w?.type ? w.type : w.isStamp ? 'stamp' : 'signature',
|
||||||
|
x: w.xPosition,
|
||||||
|
y: w.yPosition,
|
||||||
|
w: w?.Width || 150,
|
||||||
|
h: w?.Height || 60,
|
||||||
|
page: x?.pageNumber,
|
||||||
|
}))
|
||||||
|
),
|
||||||
|
})) ||
|
||||||
|
document?.Signers?.map(y => ({ name: y?.Name, email: y?.Email, phone: y?.Phone })) ||
|
||||||
|
[],
|
||||||
|
sendInOrder: document?.SendinOrder || false,
|
||||||
|
createdAt: document.createdAt,
|
||||||
|
updatedAt: document.updatedAt,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_get_document',
|
||||||
|
properties: { response_code: 404 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(404).json({ error: 'Document not found!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err ', err);
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import reportJson from '../../../parsefunction/reportsJson.js';
|
||||||
|
import dotenv from 'dotenv';
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
|
export default async function getDocumentList(request, response) {
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
const appId = process.env.APP_ID;
|
||||||
|
const serverUrl = process.env.SERVER_URL;
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
const docType = request.params.doctype;
|
||||||
|
const limit = request?.query?.limit ? request.query.limit : 100;
|
||||||
|
const skip = request?.query?.skip ? request.query.skip : 0;
|
||||||
|
let reportId;
|
||||||
|
switch (docType) {
|
||||||
|
case 'draft':
|
||||||
|
reportId = 'ByHuevtCFY';
|
||||||
|
break;
|
||||||
|
case 'signaturerequest':
|
||||||
|
reportId = '4Hhwbp482K';
|
||||||
|
break;
|
||||||
|
case 'inprogress':
|
||||||
|
reportId = '1MwEuxLEkF';
|
||||||
|
break;
|
||||||
|
case 'completed':
|
||||||
|
reportId = 'kQUoW4hUXz';
|
||||||
|
break;
|
||||||
|
case 'expired':
|
||||||
|
reportId = 'zNqBHXHsYH';
|
||||||
|
break;
|
||||||
|
case 'declined':
|
||||||
|
reportId = 'UPr2Fm5WY3';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
reportId = '';
|
||||||
|
}
|
||||||
|
const json = reportId && reportJson(reportId, userPtr.objectId);
|
||||||
|
const clsName = 'contracts_Document';
|
||||||
|
if (reportId && json) {
|
||||||
|
const { params, keys } = json;
|
||||||
|
const orderBy = '-updatedAt';
|
||||||
|
const strParams = JSON.stringify(params);
|
||||||
|
const strKeys = keys.join();
|
||||||
|
const headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-Parse-Application-Id': appId,
|
||||||
|
'X-Parse-Master-Key': process.env.MASTER_KEY,
|
||||||
|
};
|
||||||
|
const url = `${serverUrl}/classes/${clsName}?where=${strParams}&keys=${strKeys},Placeholders&order=${orderBy}&skip=${skip}&limit=${limit}&include=AuditTrail.UserPtr,Placeholders.signerPtr`;
|
||||||
|
try {
|
||||||
|
const res = await axios.get(url, { headers: headers });
|
||||||
|
if (res.data && res.data.results.length > 0) {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_get_document_list_by_status',
|
||||||
|
properties: { response_code: 200, doc_type: docType },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const updateRes = res.data.results.map(x => ({
|
||||||
|
objectId: x.objectId,
|
||||||
|
title: x.Name,
|
||||||
|
note: x.Note || '',
|
||||||
|
folder: { objectId: x?.Folder?.objectId, name: x?.Folder?.Name } || '',
|
||||||
|
file: x?.SignedUrl || x.URL,
|
||||||
|
owner: x?.ExtUserPtr?.Name,
|
||||||
|
signers:
|
||||||
|
x?.Placeholders?.map(y => ({
|
||||||
|
role: y.Role,
|
||||||
|
name: y?.signerPtr?.Name || '',
|
||||||
|
email: y?.signerPtr?.Email || '',
|
||||||
|
phone: y?.signerPtr?.Phone || '',
|
||||||
|
widgets: y.placeHolder?.flatMap(x =>
|
||||||
|
x?.pos.map(w => ({
|
||||||
|
type: w?.type ? w.type : w.isStamp ? 'stamp' : 'signature',
|
||||||
|
x: w.xPosition,
|
||||||
|
y: w.yPosition,
|
||||||
|
w: w?.Width || 150,
|
||||||
|
h: w?.Height || 60,
|
||||||
|
page: x?.pageNumber,
|
||||||
|
}))
|
||||||
|
),
|
||||||
|
})) ||
|
||||||
|
x?.Signers?.map(y => ({ name: y?.Name, email: y?.Email, phone: y?.Phone })) ||
|
||||||
|
[],
|
||||||
|
sendInOrder: x?.SendinOrder || false,
|
||||||
|
createdAt: x.createdAt,
|
||||||
|
updatedAt: x.updatedAt,
|
||||||
|
}));
|
||||||
|
return response.json({ result: updateRes });
|
||||||
|
} else {
|
||||||
|
return response.json({ result: [] });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err in getdocument list', err);
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_get_document_list_by_status',
|
||||||
|
properties: { response_code: 400, doc_type: docType },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
.status(400)
|
||||||
|
.json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_get_document_list_by_status',
|
||||||
|
properties: { response_code: 404, doc_type: docType },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(404).json({ error: 'Report not available!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
} catch (err) {
|
||||||
|
console.log('Err', err);
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
export default async function getTemplate(request, response) {
|
||||||
|
try {
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Template = new Parse.Query('contracts_Template');
|
||||||
|
Template.equalTo('objectId', request.params.template_id);
|
||||||
|
Template.equalTo('CreatedBy', userPtr);
|
||||||
|
Template.notEqualTo('IsArchive', true);
|
||||||
|
Template.include('Signers');
|
||||||
|
Template.include('Folder');
|
||||||
|
Template.include('ExtUserPtr');
|
||||||
|
Template.include('Placeholders.signerPtr');
|
||||||
|
const res = await Template.first({ useMasterKey: true });
|
||||||
|
if (res) {
|
||||||
|
const template = JSON.parse(JSON.stringify(res));
|
||||||
|
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_get_template',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({
|
||||||
|
objectId: template.objectId,
|
||||||
|
title: template.Name,
|
||||||
|
note: template.Note || '',
|
||||||
|
folder: { objectId: template?.Folder?.objectId, name: template?.Folder?.Name } || '',
|
||||||
|
file: template?.SignedUrl || template?.URL,
|
||||||
|
owner: template?.ExtUserPtr?.Name,
|
||||||
|
signers:
|
||||||
|
template?.Placeholders?.map(y => ({
|
||||||
|
role: y.Role,
|
||||||
|
name: y?.signerPtr?.Name || '',
|
||||||
|
email: y?.signerPtr?.Email || '',
|
||||||
|
phone: y?.signerPtr?.Phone || '',
|
||||||
|
widgets: y.placeHolder?.flatMap(x =>
|
||||||
|
x?.pos.map(w => ({
|
||||||
|
type: w?.type ? w.type : w.isStamp ? 'stamp' : 'signature',
|
||||||
|
x: w.xPosition,
|
||||||
|
y: w.yPosition,
|
||||||
|
w: w?.Width || 150,
|
||||||
|
h: w?.Height || 60,
|
||||||
|
page: x?.pageNumber,
|
||||||
|
}))
|
||||||
|
),
|
||||||
|
})) || [],
|
||||||
|
sendInOrder: template?.SendinOrder || false,
|
||||||
|
createdAt: template.createdAt,
|
||||||
|
updatedAt: template.updatedAt,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_get_template',
|
||||||
|
properties: { response_code: 404 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(404).json({ error: 'Template not found!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err ', err);
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import dotenv from 'dotenv';
|
||||||
|
dotenv.config();
|
||||||
|
export default async function getTemplatetList(request, response) {
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
const appId = process.env.APP_ID;
|
||||||
|
const serverUrl = process.env.SERVER_URL;
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
|
||||||
|
const limit = request?.query?.limit ? request.query.limit : 100;
|
||||||
|
const skip = request?.query?.skip ? request.query.skip : 0;
|
||||||
|
|
||||||
|
const clsName = 'contracts_Template';
|
||||||
|
const params = {
|
||||||
|
Type: { $ne: 'Folder' },
|
||||||
|
CreatedBy: userPtr,
|
||||||
|
IsArchive: { $ne: true },
|
||||||
|
};
|
||||||
|
const keys = [
|
||||||
|
'Name',
|
||||||
|
'Note',
|
||||||
|
'Description',
|
||||||
|
'Folder.Name',
|
||||||
|
'URL',
|
||||||
|
'SignedUrl',
|
||||||
|
'ExtUserPtr.Name',
|
||||||
|
'Signers.Name',
|
||||||
|
'Signers.Email',
|
||||||
|
'Signers.Phone',
|
||||||
|
'Placeholders',
|
||||||
|
];
|
||||||
|
const orderBy = '-updatedAt';
|
||||||
|
const strParams = JSON.stringify(params);
|
||||||
|
const strKeys = keys.join();
|
||||||
|
const headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-Parse-Application-Id': appId,
|
||||||
|
'X-Parse-Master-Key': process.env.MASTER_KEY,
|
||||||
|
};
|
||||||
|
const url = `${serverUrl}/classes/${clsName}?where=${strParams}&keys=${strKeys}&order=${orderBy}&skip=${skip}&limit=${limit}&include=AuditTrail.UserPtr,Placeholders.signerPtr`;
|
||||||
|
const res = await axios.get(url, { headers: headers });
|
||||||
|
if (res.data && res.data.results.length > 0) {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_get_template_list',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const updateRes = res.data.results.map(template => ({
|
||||||
|
objectId: template.objectId,
|
||||||
|
title: template.Name,
|
||||||
|
note: template.Note || '',
|
||||||
|
folder: { objectId: template?.Folder?.objectId, name: template?.Folder?.Name } || '',
|
||||||
|
file: template?.SignedUrl || template.URL,
|
||||||
|
owner: template?.ExtUserPtr?.Name,
|
||||||
|
signers:
|
||||||
|
template?.Placeholders?.map(y => ({
|
||||||
|
role: y.Role,
|
||||||
|
name: y?.signerPtr?.Name || '',
|
||||||
|
email: y?.signerPtr?.Email || '',
|
||||||
|
phone: y?.signerPtr?.Phone || '',
|
||||||
|
widgets: y.placeHolder?.flatMap(x =>
|
||||||
|
x?.pos.map(w => ({
|
||||||
|
type: w?.type ? w.type : w.isStamp ? 'stamp' : 'signature',
|
||||||
|
x: w.xPosition,
|
||||||
|
y: w.yPosition,
|
||||||
|
w: w?.Width || 150,
|
||||||
|
h: w?.Height || 60,
|
||||||
|
page: x?.pageNumber,
|
||||||
|
}))
|
||||||
|
),
|
||||||
|
})) || [],
|
||||||
|
sendInOrder: template?.SendinOrder || false,
|
||||||
|
createdAt: template.createdAt,
|
||||||
|
updatedAt: template.updatedAt,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return response.json({ result: updateRes });
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_get_template_list',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({ result: [] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err', err);
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
import dotenv from 'dotenv';
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
|
export default async function getUser(request, response) {
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
|
||||||
|
const query = new Parse.Query('contracts_Users');
|
||||||
|
query.equalTo('UserId', userPtr);
|
||||||
|
query.exclude('IsContactEntry,TourStatus,UserRole,TenantId,UserId,CreatedBy,Plan');
|
||||||
|
const user = await query.first({ useMasterKey: true });
|
||||||
|
if (user) {
|
||||||
|
const parseRes = JSON.parse(JSON.stringify(user));
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_get_your_account_details',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({
|
||||||
|
objectId: parseRes.objectId,
|
||||||
|
name: parseRes.Name,
|
||||||
|
email: parseRes.Email,
|
||||||
|
phone: parseRes.Phone,
|
||||||
|
jobTitle: parseRes.JobTitle,
|
||||||
|
company: parseRes.Company,
|
||||||
|
createdAt: parseRes.createdAt,
|
||||||
|
updatedAt: parseRes.updatedAt,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_get_your_account_details',
|
||||||
|
properties: { response_code: 404 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(404).json({ error: 'User not found!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
} catch (err) {
|
||||||
|
console.log('Err', err);
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
export default async function getWebhook(request, response) {
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
const query = new Parse.Query('contracts_Users');
|
||||||
|
query.equalTo('UserId', userPtr);
|
||||||
|
const user = await query.first({ useMasterKey: true });
|
||||||
|
if (user) {
|
||||||
|
const extUser = JSON.parse(JSON.stringify(user));
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_get_webhook',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (extUser && extUser.Webhook) {
|
||||||
|
return response.json({
|
||||||
|
webhook: extUser.Webhook,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return response.json({});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_get_webhook',
|
||||||
|
properties: { response_code: 404 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(404).json({ error: 'User not found!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('Err ', err);
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
export default async function saveWebhook(request, response) {
|
||||||
|
const Url = request.body.url;
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
const query = new Parse.Query('contracts_Users');
|
||||||
|
query.equalTo('UserId', userPtr);
|
||||||
|
const user = await query.first({ useMasterKey: true });
|
||||||
|
if (user) {
|
||||||
|
const extUser = JSON.parse(JSON.stringify(user));
|
||||||
|
const isUrlExist = extUser?.Webhook && extUser?.Webhook === Url;
|
||||||
|
|
||||||
|
if (!isUrlExist) {
|
||||||
|
try {
|
||||||
|
const updateQuery = new Parse.Object('contracts_Users');
|
||||||
|
updateQuery.id = user.id;
|
||||||
|
updateQuery.set('Webhook', Url);
|
||||||
|
const res = await updateQuery.save(null, { useMasterKey: true });
|
||||||
|
if (res) {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_save_webhook',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({
|
||||||
|
result: 'Webhook updated successfully!',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_save_webhook',
|
||||||
|
properties: { response_code: 400 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
console.log('Err ', err);
|
||||||
|
return response
|
||||||
|
.status(400)
|
||||||
|
.json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_save_webhook',
|
||||||
|
properties: { response_code: 401 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(401).json({ error: 'Webhook url already exists!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_save_webhook',
|
||||||
|
properties: { response_code: 404 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(404).json({ error: 'User not found!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('Err ', err);
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
export default async function updateDocument(request, response) {
|
||||||
|
try {
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const allowedKeys = ['name', 'note', 'description', 'folderId'];
|
||||||
|
const objectKeys = Object.keys(request.body);
|
||||||
|
const isValid = objectKeys.every(key => allowedKeys.includes(key)) && objectKeys.length > 0;
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
if (isValid) {
|
||||||
|
const document = new Parse.Query('contracts_Document');
|
||||||
|
document.equalTo('objectId', request.params.document_id);
|
||||||
|
document.equalTo('CreatedBy', userPtr);
|
||||||
|
const res = await document.first({ useMasterKey: true });
|
||||||
|
if (res) {
|
||||||
|
const isArchive = res.get('IsArchive');
|
||||||
|
if (isArchive && isArchive) {
|
||||||
|
return response.status(404).json({ message: 'Document not found!' });
|
||||||
|
} else {
|
||||||
|
const document = Parse.Object.extend('contracts_Document');
|
||||||
|
const updateQuery = new document();
|
||||||
|
updateQuery.id = request.params.document_id;
|
||||||
|
if (request?.body?.name) {
|
||||||
|
updateQuery.set('Name', request?.body?.name);
|
||||||
|
}
|
||||||
|
if (request?.body?.note) {
|
||||||
|
updateQuery.set('Note', request?.body?.note);
|
||||||
|
}
|
||||||
|
if (request?.body?.description) {
|
||||||
|
updateQuery.set('Description', request?.body?.description);
|
||||||
|
}
|
||||||
|
if (request?.body?.folderId) {
|
||||||
|
updateQuery.set('Folder', {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Document',
|
||||||
|
objectId: request?.body?.folderId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const updatedRes = await updateQuery.save(null, { useMasterKey: true });
|
||||||
|
if (updatedRes) {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_update_document',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({
|
||||||
|
objectId: updatedRes.id,
|
||||||
|
updatedAt: updatedRes.get('updatedAt'),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_update_document',
|
||||||
|
properties: { response_code: 404 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(404).json({ error: 'Document not found!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_update_document',
|
||||||
|
properties: { response_code: 400 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(400).json({ error: 'Please provide valid field names!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err ', err);
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
export default async function updateTemplate(request, response) {
|
||||||
|
try {
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
tokenQuery.include('userId');
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const allowedKeys = ['name', 'note', 'description', 'folderId'];
|
||||||
|
const objectKeys = Object.keys(request.body);
|
||||||
|
const isValid = objectKeys.every(key => allowedKeys.includes(key)) && objectKeys.length > 0;
|
||||||
|
const parseUser = JSON.parse(JSON.stringify(token));
|
||||||
|
const userPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: parseUser.userId.objectId,
|
||||||
|
};
|
||||||
|
if (isValid) {
|
||||||
|
const template = new Parse.Query('contracts_Template');
|
||||||
|
template.equalTo('objectId', request.params.template_id);
|
||||||
|
template.equalTo('CreatedBy', userPtr);
|
||||||
|
const res = await template.first({ useMasterKey: true });
|
||||||
|
if (res) {
|
||||||
|
const isArchive = res.get('IsArchive');
|
||||||
|
if (isArchive && isArchive) {
|
||||||
|
return response.status(404).json({ message: 'Template not found!' });
|
||||||
|
} else {
|
||||||
|
const template = Parse.Object.extend('contracts_Template');
|
||||||
|
const updateQuery = new template();
|
||||||
|
updateQuery.id = request.params.template_id;
|
||||||
|
if (request?.body?.name) {
|
||||||
|
updateQuery.set('Name', request?.body?.name);
|
||||||
|
}
|
||||||
|
if (request?.body?.note) {
|
||||||
|
updateQuery.set('Note', request?.body?.note);
|
||||||
|
}
|
||||||
|
if (request?.body?.description) {
|
||||||
|
updateQuery.set('Description', request?.body?.description);
|
||||||
|
}
|
||||||
|
if (request?.body?.folderId) {
|
||||||
|
updateQuery.set('Folder', {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Template',
|
||||||
|
objectId: request?.body?.folderId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const updatedRes = await updateQuery.save(null, { useMasterKey: true });
|
||||||
|
if (updatedRes) {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_update_template',
|
||||||
|
properties: { response_code: 200 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.json({
|
||||||
|
objectId: updatedRes.id,
|
||||||
|
updatedAt: updatedRes.get('updatedAt'),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_update_template',
|
||||||
|
properties: { response_code: 404 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(404).json({ error: 'Template not found!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (request.posthog) {
|
||||||
|
request.posthog?.capture({
|
||||||
|
distinctId: parseUser.userId.email,
|
||||||
|
event: 'api_update_template',
|
||||||
|
properties: { response_code: 400 },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response.status(400).json({ error: 'Please provide valid field names!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err ', err);
|
||||||
|
return response.status(400).json({ error: 'Something went wrong, please try again later!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,12 @@ import getUserDetails from './parsefunction/getUserDetails.js';
|
|||||||
import getDocument from './parsefunction/getDocument.js';
|
import getDocument from './parsefunction/getDocument.js';
|
||||||
import getDrive from './parsefunction/getDrive.js';
|
import getDrive from './parsefunction/getDrive.js';
|
||||||
import getReport from './parsefunction/getReport.js';
|
import getReport from './parsefunction/getReport.js';
|
||||||
|
import generateApiToken from './parsefunction/generateApiToken.js';
|
||||||
|
import getapitoken from './parsefunction/getapitoken.js';
|
||||||
|
import TemplateAfterSave from './parsefunction/TemplateAfterSave.js';
|
||||||
|
import GetTemplate from './parsefunction/GetTemplate.js';
|
||||||
|
import savewebhook from './parsefunction/saveWebhook.js';
|
||||||
|
import callWebhook from './parsefunction/callWebhook.js';
|
||||||
|
|
||||||
Parse.Cloud.define('AddUserToRole', addUserToGroups);
|
Parse.Cloud.define('AddUserToRole', addUserToGroups);
|
||||||
Parse.Cloud.define('UserGroups', getUserGroups);
|
Parse.Cloud.define('UserGroups', getUserGroups);
|
||||||
@@ -26,14 +32,20 @@ Parse.Cloud.define('googlesign', GoogleSign);
|
|||||||
Parse.Cloud.define('zohodetails', ZohoDetails);
|
Parse.Cloud.define('zohodetails', ZohoDetails);
|
||||||
Parse.Cloud.define('usersignup', usersignup);
|
Parse.Cloud.define('usersignup', usersignup);
|
||||||
Parse.Cloud.define('facebooksign', FacebookSign);
|
Parse.Cloud.define('facebooksign', FacebookSign);
|
||||||
Parse.Cloud.afterSave('contracts_Document', DocumentAftersave);
|
|
||||||
Parse.Cloud.afterSave('contracts_Contactbook', ContactbookAftersave);
|
|
||||||
Parse.Cloud.afterSave('contracts_Users', ContractUsersAftersave);
|
|
||||||
Parse.Cloud.define('SendOTPMailV1', sendMailOTPv1);
|
Parse.Cloud.define('SendOTPMailV1', sendMailOTPv1);
|
||||||
Parse.Cloud.define('sendmail', SendMailv1);
|
Parse.Cloud.define('sendmail', SendMailv1);
|
||||||
Parse.Cloud.define('AuthLoginAsMail', AuthLoginAsMail);
|
Parse.Cloud.define('AuthLoginAsMail', AuthLoginAsMail);
|
||||||
Parse.Cloud.define('getUserId', getUserId);
|
Parse.Cloud.define('getUserId', getUserId);
|
||||||
Parse.Cloud.define('getUserDetails', getUserDetails);
|
Parse.Cloud.define('getUserDetails', getUserDetails);
|
||||||
Parse.Cloud.define('getDocument', getDocument);
|
Parse.Cloud.define('getDocument', getDocument);
|
||||||
Parse.Cloud.define('getDrive', getDrive)
|
Parse.Cloud.define('getDrive', getDrive);
|
||||||
Parse.Cloud.define('getReport', getReport)
|
Parse.Cloud.define('getReport', getReport);
|
||||||
|
Parse.Cloud.define('generateapitoken', generateApiToken);
|
||||||
|
Parse.Cloud.define('getapitoken', getapitoken);
|
||||||
|
Parse.Cloud.define('getTemplate', GetTemplate);
|
||||||
|
Parse.Cloud.define('savewebhook', savewebhook);
|
||||||
|
Parse.Cloud.define('callwebhook', callWebhook);
|
||||||
|
Parse.Cloud.afterSave('contracts_Document', DocumentAftersave);
|
||||||
|
Parse.Cloud.afterSave('contracts_Contactbook', ContactbookAftersave);
|
||||||
|
Parse.Cloud.afterSave('contracts_Users', ContractUsersAftersave);
|
||||||
|
Parse.Cloud.afterSave('contracts_Template', TemplateAfterSave);
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ async function ContactbookAftersave(request) {
|
|||||||
you can check as follows */
|
you can check as follows */
|
||||||
if (!request.original) {
|
if (!request.original) {
|
||||||
const user = request.user;
|
const user = request.user;
|
||||||
const object = request.object;
|
|
||||||
|
|
||||||
// Retrieve the current ACL
|
// Retrieve the current ACL
|
||||||
const acl = new Parse.ACL();
|
const acl = new Parse.ACL();
|
||||||
|
|
||||||
// Ensure the current user has read access
|
// Ensure the current user has read access
|
||||||
if (acl) {
|
if (acl && request?.user) {
|
||||||
|
const object = request.object;
|
||||||
acl.setReadAccess(user, true);
|
acl.setReadAccess(user, true);
|
||||||
acl.setWriteAccess(user, true);
|
acl.setWriteAccess(user, true);
|
||||||
acl.setReadAccess(object.get('UserId'), true);
|
acl.setReadAccess(object.get('UserId'), true);
|
||||||
|
|||||||
@@ -4,20 +4,11 @@ async function DocumentAftersave(request) {
|
|||||||
console.log('new entry is insert in contracts_Document');
|
console.log('new entry is insert in contracts_Document');
|
||||||
const createdAt = request.object.get('createdAt');
|
const createdAt = request.object.get('createdAt');
|
||||||
const Folder = request.object.get('Type');
|
const Folder = request.object.get('Type');
|
||||||
// console.log("createdAt")
|
|
||||||
// console.log(createdAt)
|
|
||||||
// console.log("Folder")
|
|
||||||
// console.log(Folder)
|
|
||||||
// console.log("before If condition")
|
|
||||||
if (createdAt && Folder === undefined) {
|
if (createdAt && Folder === undefined) {
|
||||||
// console.log("IN If condition")
|
// console.log("IN If condition")
|
||||||
const TimeToCompleteDays = request.object.get('TimeToCompleteDays');
|
const TimeToCompleteDays = request.object.get('TimeToCompleteDays');
|
||||||
const ExpiryDate = new Date(createdAt);
|
const ExpiryDate = new Date(createdAt);
|
||||||
// console.log("ExpiryDate")
|
|
||||||
// console.log(ExpiryDate)
|
|
||||||
ExpiryDate.setDate(ExpiryDate.getDate() + TimeToCompleteDays);
|
ExpiryDate.setDate(ExpiryDate.getDate() + TimeToCompleteDays);
|
||||||
// console.log("ExpiryDate date after update")
|
|
||||||
// console.log(ExpiryDate)
|
|
||||||
const documentQuery = new Parse.Query('contracts_Document');
|
const documentQuery = new Parse.Query('contracts_Document');
|
||||||
const updateQuery = await documentQuery.get(request.object.id, { useMasterKey: true });
|
const updateQuery = await documentQuery.get(request.object.id, { useMasterKey: true });
|
||||||
updateQuery.set('ExpiryDate', ExpiryDate);
|
updateQuery.set('ExpiryDate', ExpiryDate);
|
||||||
@@ -37,21 +28,23 @@ async function DocumentAftersave(request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const signers = request.object.get('Signers');
|
const signers = request.object.get('Signers');
|
||||||
// console.log("Signers")
|
|
||||||
// console.log(signers.length)
|
|
||||||
// update acl of New Document If There are signers present in array
|
// update acl of New Document If There are signers present in array
|
||||||
if (signers && signers.length > 0) {
|
if (signers && signers.length > 0) {
|
||||||
await updateAclDoc(request.object.id);
|
await updateAclDoc(request.object.id);
|
||||||
} else {
|
} else {
|
||||||
await updateSelfDoc(request.object.id);
|
if (request?.object?.id && request.user) {
|
||||||
|
await updateSelfDoc(request.object.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (request.user) {
|
if (request?.user) {
|
||||||
const signers = request.object.get('Signers');
|
const signers = request.object.get('Signers');
|
||||||
if (signers && signers.length > 0) {
|
if (signers && signers.length > 0) {
|
||||||
await updateAclDoc(request.object.id);
|
await updateAclDoc(request.object.id);
|
||||||
} else {
|
} else {
|
||||||
await updateSelfDoc(request.object.id);
|
if (request?.object?.id) {
|
||||||
|
await updateSelfDoc(request.object.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,6 +58,7 @@ async function DocumentAftersave(request) {
|
|||||||
// console.log(objId)
|
// console.log(objId)
|
||||||
const Query = new Parse.Query('contracts_Document');
|
const Query = new Parse.Query('contracts_Document');
|
||||||
Query.include('Signers');
|
Query.include('Signers');
|
||||||
|
Query.include('CreatedBy');
|
||||||
const updateACL = await Query.get(objId, { useMasterKey: true });
|
const updateACL = await Query.get(objId, { useMasterKey: true });
|
||||||
const res = JSON.parse(JSON.stringify(updateACL));
|
const res = JSON.parse(JSON.stringify(updateACL));
|
||||||
// console.log("res");
|
// console.log("res");
|
||||||
@@ -87,9 +81,10 @@ async function DocumentAftersave(request) {
|
|||||||
const newACL = new Parse.ACL();
|
const newACL = new Parse.ACL();
|
||||||
newACL.setPublicReadAccess(false);
|
newACL.setPublicReadAccess(false);
|
||||||
newACL.setPublicWriteAccess(false);
|
newACL.setPublicWriteAccess(false);
|
||||||
newACL.setReadAccess(request.user, true);
|
if (res?.CreatedBy) {
|
||||||
newACL.setWriteAccess(request.user, true);
|
newACL.setReadAccess(res?.CreatedBy?.objectId, true);
|
||||||
|
newACL.setWriteAccess(res?.CreatedBy?.objectId, true);
|
||||||
|
}
|
||||||
UsersPtr.forEach(x => {
|
UsersPtr.forEach(x => {
|
||||||
newACL.setReadAccess(x.objectId, true);
|
newACL.setReadAccess(x.objectId, true);
|
||||||
newACL.setWriteAccess(x.objectId, true);
|
newACL.setWriteAccess(x.objectId, true);
|
||||||
@@ -100,9 +95,9 @@ async function DocumentAftersave(request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function updateSelfDoc(objId) {
|
async function updateSelfDoc(objId) {
|
||||||
// console.log("In side updateSelfDoc func")
|
|
||||||
// console.log(objId)
|
// console.log(objId)
|
||||||
const Query = new Parse.Query('contracts_Document');
|
const Query = new Parse.Query('contracts_Document');
|
||||||
|
Query.include('CreatedBy');
|
||||||
const updateACL = await Query.get(objId, { useMasterKey: true });
|
const updateACL = await Query.get(objId, { useMasterKey: true });
|
||||||
const res = JSON.parse(JSON.stringify(updateACL));
|
const res = JSON.parse(JSON.stringify(updateACL));
|
||||||
// console.log("res");
|
// console.log("res");
|
||||||
@@ -110,8 +105,10 @@ async function DocumentAftersave(request) {
|
|||||||
const newACL = new Parse.ACL();
|
const newACL = new Parse.ACL();
|
||||||
newACL.setPublicReadAccess(false);
|
newACL.setPublicReadAccess(false);
|
||||||
newACL.setPublicWriteAccess(false);
|
newACL.setPublicWriteAccess(false);
|
||||||
newACL.setReadAccess(request.user, true);
|
if (res?.CreatedBy) {
|
||||||
newACL.setWriteAccess(request.user, true);
|
newACL.setReadAccess(res?.CreatedBy?.objectId, true);
|
||||||
|
newACL.setWriteAccess(res?.CreatedBy?.objectId, true);
|
||||||
|
}
|
||||||
updateACL.setACL(newACL);
|
updateACL.setACL(newACL);
|
||||||
updateACL.save(null, { useMasterKey: true });
|
updateACL.save(null, { useMasterKey: true });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
export default async function GetTemplate(request) {
|
||||||
|
const serverUrl = process.env.SERVER_URL;
|
||||||
|
const templateId = request.params.templateId;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const userRes = await axios.get(serverUrl + '/users/me', {
|
||||||
|
headers: {
|
||||||
|
'X-Parse-Application-Id': process.env.APP_ID,
|
||||||
|
'X-Parse-Session-Token': request.headers['sessiontoken'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const userId = userRes.data && userRes.data.objectId;
|
||||||
|
// console.log("templateId ", templateId)
|
||||||
|
// console.log("userId ",userId)
|
||||||
|
if (templateId && userId) {
|
||||||
|
try {
|
||||||
|
const template = new Parse.Query('contracts_Template');
|
||||||
|
template.equalTo('objectId', templateId);
|
||||||
|
template.include('ExtUserPtr');
|
||||||
|
template.include('Signers');
|
||||||
|
template.include('CreateBy');
|
||||||
|
const res = await template.first({ useMasterKey: true });
|
||||||
|
// console.log("res ", res)
|
||||||
|
if (res) {
|
||||||
|
// console.log("res ",res)
|
||||||
|
const acl = res.getACL();
|
||||||
|
console.log("acl", acl.getReadAccess(userId))
|
||||||
|
if (acl && acl.getReadAccess(userId)) {
|
||||||
|
return res;
|
||||||
|
} else {
|
||||||
|
return { error: "You don't have access of this document!" };
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return { error: "You don't have access of this document!" };
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err', err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return { error: 'Please pass required parameters!' };
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err', err);
|
||||||
|
if (err.code == 209) {
|
||||||
|
return { error: 'Invalid session token' };
|
||||||
|
} else {
|
||||||
|
return { error: "You don't have access of this document!" };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
export default async function TemplateAfterSave(request) {
|
||||||
|
try {
|
||||||
|
if (!request.original) {
|
||||||
|
console.log('new entry is insert in contracts_Template');
|
||||||
|
// update acl of New Document If There are signers present in array
|
||||||
|
const signers = request.object.get('Signers');
|
||||||
|
|
||||||
|
if (signers && signers.length > 0) {
|
||||||
|
await updateAclDoc(request.object.id);
|
||||||
|
} else {
|
||||||
|
if (request?.object?.id && request?.user) {
|
||||||
|
await updateSelfDoc(request.object.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (request?.user) {
|
||||||
|
const signers = request.object.get('Signers');
|
||||||
|
if (signers && signers.length > 0) {
|
||||||
|
await updateAclDoc(request.object.id);
|
||||||
|
} else {
|
||||||
|
if (request?.object?.id) {
|
||||||
|
await updateSelfDoc(request.object.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err in aftersave of contracts_Template');
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateAclDoc(objId) {
|
||||||
|
// console.log("In side updateAclDoc func")
|
||||||
|
// console.log(objId)
|
||||||
|
const Query = new Parse.Query('contracts_Template');
|
||||||
|
Query.include('Signers');
|
||||||
|
Query.include('CreatedBy');
|
||||||
|
const updateACL = await Query.get(objId, { useMasterKey: true });
|
||||||
|
const res = JSON.parse(JSON.stringify(updateACL));
|
||||||
|
// console.log("res");
|
||||||
|
// console.log(JSON.stringify(res));
|
||||||
|
const UsersPtr = res.Signers.map(item => item.UserId);
|
||||||
|
|
||||||
|
if (res.Signers[0].ExtUserPtr) {
|
||||||
|
const ExtUserSigners = res.Signers.map(item => {
|
||||||
|
return {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Users',
|
||||||
|
objectId: item.ExtUserPtr.objectId,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
updateACL.set('Signers', ExtUserSigners);
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log("UsersPtr")
|
||||||
|
// console.log(JSON.stringify(UsersPtr))
|
||||||
|
const newACL = new Parse.ACL();
|
||||||
|
newACL.setPublicReadAccess(false);
|
||||||
|
newACL.setPublicWriteAccess(false);
|
||||||
|
if (res?.CreatedBy) {
|
||||||
|
newACL.setReadAccess(res?.CreatedBy?.objectId, true);
|
||||||
|
newACL.setWriteAccess(res?.CreatedBy?.objectId, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
UsersPtr.forEach(x => {
|
||||||
|
newACL.setReadAccess(x.objectId, true);
|
||||||
|
newACL.setWriteAccess(x.objectId, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
updateACL.setACL(newACL);
|
||||||
|
updateACL.save(null, { useMasterKey: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateSelfDoc(objId) {
|
||||||
|
// console.log("Inside updateSelfDoc func")
|
||||||
|
|
||||||
|
const Query = new Parse.Query('contracts_Template');
|
||||||
|
Query.include('CreatedBy');
|
||||||
|
const updateACL = await Query.get(objId, { useMasterKey: true });
|
||||||
|
const res = JSON.parse(JSON.stringify(updateACL));
|
||||||
|
// console.log("res");
|
||||||
|
// console.log(JSON.stringify(res));
|
||||||
|
const newACL = new Parse.ACL();
|
||||||
|
newACL.setPublicReadAccess(false);
|
||||||
|
newACL.setPublicWriteAccess(false);
|
||||||
|
if (res?.CreatedBy) {
|
||||||
|
newACL.setReadAccess(res?.CreatedBy?.objectId, true);
|
||||||
|
newACL.setWriteAccess(res?.CreatedBy?.objectId, true);
|
||||||
|
}
|
||||||
|
updateACL.setACL(newACL);
|
||||||
|
updateACL.save(null, { useMasterKey: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
export default async function callWebhook(request) {
|
||||||
|
const event = request.params.event;
|
||||||
|
const body = request.params.body;
|
||||||
|
const serverUrl = process.env.SERVER_URL;
|
||||||
|
const appId = process.env.APP_ID;
|
||||||
|
const userRes = await axios.get(serverUrl + '/users/me', {
|
||||||
|
headers: {
|
||||||
|
'X-Parse-Application-Id': appId,
|
||||||
|
'X-Parse-Session-Token': request.headers['sessiontoken'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const userId = userRes.data && userRes.data.objectId;
|
||||||
|
if (userId) {
|
||||||
|
const extendcls = new Parse.Query('contracts_Users');
|
||||||
|
extendcls.equalTo('UserId', { __type: 'Pointer', className: '_User', objectId: userId });
|
||||||
|
const res = await extendcls.first({ useMasterKey: true });
|
||||||
|
if (res) {
|
||||||
|
const extUser = JSON.parse(JSON.stringify(res));
|
||||||
|
if (extUser?.Webhook) {
|
||||||
|
const params = {
|
||||||
|
event: event,
|
||||||
|
...body,
|
||||||
|
};
|
||||||
|
await axios
|
||||||
|
.post(extUser?.Webhook, params, {
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
try {
|
||||||
|
// console.log('res ', res);
|
||||||
|
const webhook = new Parse.Object('contracts_Webhook');
|
||||||
|
webhook.set('Log', res?.status);
|
||||||
|
webhook.set('UserId', {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: userId,
|
||||||
|
});
|
||||||
|
webhook.save(null, { useMasterKey: true });
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err save in contracts_Webhook', err);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log('Err send data to webhook', err);
|
||||||
|
try {
|
||||||
|
const webhook = new Parse.Object('contracts_Webhook');
|
||||||
|
webhook.set('Log', err?.status);
|
||||||
|
webhook.set('UserId', {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: userId,
|
||||||
|
});
|
||||||
|
webhook.save(null, { useMasterKey: true });
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err save in contracts_Webhook', err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return { message: 'webhook called!' };
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return { message: 'User not found!' };
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import { generateApiKey } from 'generate-api-key';
|
||||||
|
import axios from 'axios';
|
||||||
|
export default async function generateApiToken(request) {
|
||||||
|
const serverUrl = process.env.SERVER_URL;
|
||||||
|
try {
|
||||||
|
const userRes = await axios.get(serverUrl + '/users/me', {
|
||||||
|
headers: {
|
||||||
|
'X-Parse-Application-Id': process.env.APP_ID,
|
||||||
|
'X-Parse-Session-Token': request.headers['sessiontoken'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const userId = userRes.data && userRes.data.objectId;
|
||||||
|
if (userId) {
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('userId', { __type: 'Pointer', className: '_User', objectId: userId });
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// return exsiting Token
|
||||||
|
console.log('Regenerate API Token');
|
||||||
|
const AppToken = Parse.Object.extend('appToken');
|
||||||
|
const updateToken = new AppToken();
|
||||||
|
updateToken.id = token.id;
|
||||||
|
const newToken = generateApiKey({ method: 'base62', prefix: 'opensign' });
|
||||||
|
updateToken.set('token', newToken);
|
||||||
|
const updatedRes = await updateToken.save(null, { useMasterKey: true });
|
||||||
|
return updatedRes;
|
||||||
|
} else {
|
||||||
|
// Create New Token
|
||||||
|
console.log('New API Token Generation');
|
||||||
|
const appToken = Parse.Object.extend('appToken');
|
||||||
|
const appTokenQuery = new appToken();
|
||||||
|
const token = generateApiKey({ method: 'base62', prefix: 'opensign' });
|
||||||
|
appTokenQuery.set('token', token);
|
||||||
|
appTokenQuery.set('userId', { __type: 'Pointer', className: '_User', objectId: userId });
|
||||||
|
const newRes = await appTokenQuery.save(null, { useMasterKey: true });
|
||||||
|
return newRes;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 'User not found!';
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err ', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ export default async function getDocument(request) {
|
|||||||
query.include('Signers');
|
query.include('Signers');
|
||||||
query.include('AuditTrail.UserPtr');
|
query.include('AuditTrail.UserPtr');
|
||||||
query.include('Placeholders');
|
query.include('Placeholders');
|
||||||
|
query.notEqualTo('IsArchive', true)
|
||||||
const res = await query.first({ useMasterKey: true });
|
const res = await query.first({ useMasterKey: true });
|
||||||
if (res) {
|
if (res) {
|
||||||
const acl = res.getACL();
|
const acl = res.getACL();
|
||||||
@@ -40,7 +41,7 @@ export default async function getDocument(request) {
|
|||||||
return { error: 'Please pass required parameters!' };
|
return { error: 'Please pass required parameters!' };
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('err');
|
console.log('err', err);
|
||||||
if (err.code == 209) {
|
if (err.code == 209) {
|
||||||
return { error: 'Invalid session token' };
|
return { error: 'Invalid session token' };
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ export default async function getDrive(request) {
|
|||||||
if (userId) {
|
if (userId) {
|
||||||
let url;
|
let url;
|
||||||
if (docId) {
|
if (docId) {
|
||||||
url = `${classUrl}?where={"Folder":{"__type":"Pointer","className":"contracts_Document","objectId":"${docId}"},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${userId}"}}&include=ExtUserPtr,Signers,Folder`;
|
url = `${classUrl}?where={"Folder":{"__type":"Pointer","className":"contracts_Document","objectId":"${docId}"},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${userId}"},"IsArchive":{"$ne":true}}&include=ExtUserPtr,Signers,Folder`;
|
||||||
} else {
|
} else {
|
||||||
url = `${classUrl}?where={"Folder":{"$exists":false},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${userId}"}}&include=ExtUserPtr,Signers`;
|
url = `${classUrl}?where={"Folder":{"$exists":false},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${userId}"},"IsArchive":{"$ne":true}}&include=ExtUserPtr,Signers`;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const res = await axios.get(url, {
|
const res = await axios.get(url, {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export default async function getReport(request) {
|
|||||||
const userId = userRes.data && userRes.data.objectId;
|
const userId = userRes.data && userRes.data.objectId;
|
||||||
if (userId) {
|
if (userId) {
|
||||||
const json = reportId && reportJson(reportId, userId);
|
const json = reportId && reportJson(reportId, userId);
|
||||||
const clsName = reportId === '5KhaPr482K' ? 'contracts_Contactbook' : 'contracts_Document';
|
const clsName = json?.reportClass ? json.reportClass : 'contracts_Document';
|
||||||
if (json) {
|
if (json) {
|
||||||
const { params, keys } = json;
|
const { params, keys } = json;
|
||||||
const orderBy = '-updatedAt';
|
const orderBy = '-updatedAt';
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
async function getUserDetails(request) {
|
async function getUserDetails(request) {
|
||||||
try {
|
try {
|
||||||
|
const userId = request.params.userId;
|
||||||
const userQuery = new Parse.Query('contracts_Users');
|
const userQuery = new Parse.Query('contracts_Users');
|
||||||
userQuery.equalTo('Email', request.params.email);
|
userQuery.equalTo('Email', request.params.email);
|
||||||
userQuery.include('TenantId');
|
userQuery.include('TenantId');
|
||||||
userQuery.include('UserId')
|
userQuery.include('UserId');
|
||||||
|
if (userId) {
|
||||||
|
userQuery.equalTo('CreatedBy', { __type: 'Pointer', className: '_User', objectId: userId });
|
||||||
|
}
|
||||||
const res = await userQuery.first({ useMasterKey: true });
|
const res = await userQuery.first({ useMasterKey: true });
|
||||||
return res;
|
return res;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
export default async function getapitoken(request) {
|
||||||
|
const serverUrl = process.env.SERVER_URL;
|
||||||
|
try {
|
||||||
|
const userRes = await axios.get(serverUrl + '/users/me', {
|
||||||
|
headers: {
|
||||||
|
'X-Parse-Application-Id': process.env.APP_ID,
|
||||||
|
'X-Parse-Session-Token': request.headers['sessiontoken'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const userId = userRes.data && userRes.data.objectId;
|
||||||
|
if (userId) {
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('userId', { __type: 'Pointer', className: '_User', objectId: userId });
|
||||||
|
const res = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (res) {
|
||||||
|
return { status: 'success', result: res.get('token') };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('Err', err);
|
||||||
|
console.log('err', err);
|
||||||
|
if (err.code == 209) {
|
||||||
|
return { error: 'Invalid session token' };
|
||||||
|
} else {
|
||||||
|
return { error: "You don't have access!" };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+189
-105
@@ -1,40 +1,36 @@
|
|||||||
import SignPDF from './SignPDF.min.cjs';
|
import SignPDF from './SignPDF.min.cjs';
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import FormData from 'form-data';
|
|
||||||
import plainplaceholder from './customSignPdf/plainplaceholder.min.js';
|
|
||||||
import { plainAddPlaceholder } from 'node-signpdf/dist/helpers/index.js';
|
import { plainAddPlaceholder } from 'node-signpdf/dist/helpers/index.js';
|
||||||
const serverUrl = process.env.SERVER_URL,
|
const serverUrl = process.env.SERVER_URL,
|
||||||
APPID = process.env.APP_ID,
|
APPID = process.env.APP_ID,
|
||||||
masterKEY = process.env.MASTER_KEY;
|
masterKEY = process.env.MASTER_KEY;
|
||||||
async function uploadFile(a) {
|
async function uploadFile(e, a) {
|
||||||
try {
|
try {
|
||||||
var e = new FormData(),
|
var t = fs.readFileSync(a),
|
||||||
t =
|
s = new Parse.File(e, [...t]),
|
||||||
(e.append('file', fs.createReadStream(a)),
|
r = (await s.save({ useMasterKey: !0 }), s.url());
|
||||||
{ 'content-type': 'multipart/form-data', 'X-Parse-Application-Id': process.env.APP_ID }),
|
return { imageUrl: r };
|
||||||
s = process.env.SERVER_URL.slice(0, -4) + '/file_upload';
|
|
||||||
return (await axios.post(s, e, { headers: t })).data;
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('err ', e), fs.unlinkSync(a);
|
console.log('Err ', e), fs.unlinkSync(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function updateDoc(t, s, r, i, o, n) {
|
async function updateDoc(t, s, r, i, n, o) {
|
||||||
try {
|
try {
|
||||||
var d = {
|
var d = {
|
||||||
UserPtr: { __type: 'Pointer', className: n, objectId: r },
|
UserPtr: { __type: 'Pointer', className: o, objectId: r },
|
||||||
SignedUrl: s,
|
SignedUrl: s,
|
||||||
Activity: 'Signed',
|
Activity: 'Signed',
|
||||||
ipAddress: i,
|
ipAddress: i,
|
||||||
};
|
};
|
||||||
let e;
|
let e;
|
||||||
var l = (e = o.AuditTrail && 0 < o.AuditTrail.length ? [...o.AuditTrail, d] : [d]).filter(
|
var l = (e = n.AuditTrail && 0 < n.AuditTrail.length ? [...n.AuditTrail, d] : [d]).filter(
|
||||||
e => 'Signed' === e.Activity
|
e => 'Signed' === e.Activity
|
||||||
);
|
);
|
||||||
let a = !1;
|
let a = !1;
|
||||||
!((o.Signers && 0 < o.Signers.length && l.length !== o.Signers.length) || !(a = !0));
|
!((n.Signers && 0 < n.Signers.length && l.length !== n.Signers.length) || !(a = !0));
|
||||||
var p = { SignedUrl: s, AuditTrail: e, IsCompleted: a };
|
var c = { SignedUrl: s, AuditTrail: e, IsCompleted: a };
|
||||||
await axios.put(serverUrl + '/classes/contracts_Document/' + t, p, {
|
await axios.put(serverUrl + '/classes/contracts_Document/' + t, c, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'X-Parse-Application-Id': APPID,
|
'X-Parse-Application-Id': APPID,
|
||||||
@@ -59,9 +55,9 @@ async function sendMail(e) {
|
|||||||
html:
|
html:
|
||||||
"<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body> <div style='background-color:#f5f5f5;padding:20px'> <div style='box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;background-color:white;'> <div><img src=https://qikinnovation.ams3.digitaloceanspaces.com/logo.png height='50' style='padding:20px'/> </div><div style='padding:2px;font-family:system-ui; background-color: #47a3ad;'> <p style='font-size:20px;font-weight:400;color:white;padding-left:20px',> Document Copy</p></div><div><p style='padding:20px;font-family:system-ui;font-size:14px'>A copy of the document " +
|
"<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body> <div style='background-color:#f5f5f5;padding:20px'> <div style='box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;background-color:white;'> <div><img src=https://qikinnovation.ams3.digitaloceanspaces.com/logo.png height='50' style='padding:20px'/> </div><div style='padding:2px;font-family:system-ui; background-color: #47a3ad;'> <p style='font-size:20px;font-weight:400;color:white;padding-left:20px',> Document Copy</p></div><div><p style='padding:20px;font-family:system-ui;font-size:14px'>A copy of the document " +
|
||||||
s +
|
s +
|
||||||
' Standard is attached to this email. Kindly download the document from the attachment.</p></div> </div><div><p>This is an automated email from Open Sign. For any queries regarding this email, please contact the sender ' +
|
' Standard is attached to this email. Kindly download the document from the attachment.</p></div> </div><div><p>This is an automated email from OpenSign™. For any queries regarding this email, please contact the sender ' +
|
||||||
t.Mail +
|
t.Mail +
|
||||||
' directly. If you think this email is inappropriate or spam, you may file a complaint with Open Sign here.</p></div></div></body></html>',
|
' directly. If you think this email is inappropriate or spam, you may file a complaint with OpenSign™ <a href=www.opensignlabs.com target=_blank>here</a>.</p></div></div></body></html>',
|
||||||
};
|
};
|
||||||
await axios.post(serverUrl + '/functions/sendmailv3', a, {
|
await axios.post(serverUrl + '/functions/sendmailv3', a, {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -84,9 +80,9 @@ async function sendCompletedMail(e) {
|
|||||||
html:
|
html:
|
||||||
"<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body> <div style='background-color:#f5f5f5;padding:20px'> <div style='box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;background-color:white;'> <div><img src=https://qikinnovation.ams3.digitaloceanspaces.com/logo.png height='50' style='padding:20px'/> </div><div style='padding:2px;font-family:system-ui; background-color: #47a3ad;'> <p style='font-size:20px;font-weight:400;color:white;padding-left:20px',> Document sign successfully</p></div><div><p style='padding:20px;font-family:system-ui;font-size:14px'>All parties have successfully signed the document" +
|
"<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body> <div style='background-color:#f5f5f5;padding:20px'> <div style='box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;background-color:white;'> <div><img src=https://qikinnovation.ams3.digitaloceanspaces.com/logo.png height='50' style='padding:20px'/> </div><div style='padding:2px;font-family:system-ui; background-color: #47a3ad;'> <p style='font-size:20px;font-weight:400;color:white;padding-left:20px',> Document sign successfully</p></div><div><p style='padding:20px;font-family:system-ui;font-size:14px'>All parties have successfully signed the document" +
|
||||||
s +
|
s +
|
||||||
'. Kindly download the document from the attachment.</p></div> </div><div><p>This is an automated email from Open Sign. For any queries regarding this email, please contact the sender ' +
|
'. Kindly download the document from the attachment.</p></div> </div><div><p>This is an automated email from OpenSign™. For any queries regarding this email, please contact the sender ' +
|
||||||
t.Mail +
|
t.Mail +
|
||||||
' directly. If you think this email is inappropriate or spam, you may file a complaint with Open Sign here.</p></div></div></body></html>',
|
' directly. If you think this email is inappropriate or spam, you may file a complaint with OpenSign™ <a href=www.opensignlabs.com target=_blank>here</a>.</p></div></div></body></html>',
|
||||||
};
|
};
|
||||||
await axios.post(serverUrl + '/functions/sendmailv3', a, {
|
await axios.post(serverUrl + '/functions/sendmailv3', a, {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -96,115 +92,203 @@ async function sendCompletedMail(e) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
async function PDF(s, r) {
|
async function sendDoctoWebhook(t, e, a, s) {
|
||||||
try {
|
let r = [];
|
||||||
var i = s.params.sign,
|
(r = s
|
||||||
e = s.params.docId,
|
? { name: s?.Name, email: s?.Email, phone: s?.Phone }
|
||||||
o = s.params.userId,
|
: t?.data?.Signers?.map(e => ({ name: e.Name, email: e.Email, phone: e.Phone })) || [
|
||||||
n = await axios.get(serverUrl + '/classes/contracts_Document/' + e + '?include=ExtUserPtr', {
|
{
|
||||||
headers: {
|
name: t?.data?.ExtUserPtr?.Name,
|
||||||
'Content-Type': 'application/json',
|
email: t?.data?.ExtUserPtr?.Email,
|
||||||
'X-Parse-Application-Id': APPID,
|
phone: t?.data?.ExtUserPtr?.Phone,
|
||||||
'X-Parse-Master-Key': masterKEY,
|
|
||||||
},
|
},
|
||||||
|
]),
|
||||||
|
t.data.ExtUserPtr?.Webhook &&
|
||||||
|
((s =
|
||||||
|
'signed' === a
|
||||||
|
? { signer: r, signedAt: new Date() }
|
||||||
|
: { signers: r, completedAt: new Date() }),
|
||||||
|
(a = {
|
||||||
|
event: a,
|
||||||
|
objectId: t?.data?.objectId,
|
||||||
|
file: e || '',
|
||||||
|
name: t?.data?.Name,
|
||||||
|
note: t?.data?.Note || '',
|
||||||
|
description: t?.data?.Description || '',
|
||||||
|
...s,
|
||||||
|
createdAt: t?.data?.createdAt,
|
||||||
}),
|
}),
|
||||||
d = await axios.get(serverUrl + '/users/me', {
|
await axios
|
||||||
|
.post(t?.data?.ExtUserPtr?.Webhook, a, { headers: { 'Content-Type': 'application/json' } })
|
||||||
|
.then(e => {
|
||||||
|
try {
|
||||||
|
var a = new Parse.Object('contracts_Webhook');
|
||||||
|
a.set('Log', e?.status),
|
||||||
|
a.set('UserId', {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: t.data.ExtUserPtr.UserId.objectId,
|
||||||
|
}),
|
||||||
|
a.save(null, { useMasterKey: !0 });
|
||||||
|
} catch (e) {
|
||||||
|
console.log('err save in contracts_Webhook', e);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
console.log('Err send data to webhook', e);
|
||||||
|
try {
|
||||||
|
var a = new Parse.Object('contracts_Webhook');
|
||||||
|
a.set('Log', e?.status),
|
||||||
|
a.set('UserId', {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: t.data.ExtUserPtr.UserId.objectId,
|
||||||
|
}),
|
||||||
|
a.save(null, { useMasterKey: !0 });
|
||||||
|
} catch (e) {
|
||||||
|
console.log('err save in contracts_Webhook', e);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
async function PDF(i, n) {
|
||||||
|
try {
|
||||||
|
i.params.sign;
|
||||||
|
var e = i.params.docId,
|
||||||
|
a = i.params.userId,
|
||||||
|
o = await axios.get(
|
||||||
|
serverUrl + '/classes/contracts_Document/' + e + '?include=ExtUserPtr,Signers',
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-Parse-Application-Id': APPID,
|
||||||
|
'X-Parse-Master-Key': masterKEY,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
),
|
||||||
|
t = await axios.get(serverUrl + '/users/me', {
|
||||||
headers: {
|
headers: {
|
||||||
'X-Parse-Application-Id': APPID,
|
'X-Parse-Application-Id': APPID,
|
||||||
'X-Parse-Session-Token': s.headers.sessiontoken,
|
'X-Parse-Session-Token': i.headers.sessiontoken,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (!d.data || !d.data.objectId) return { status: 'error', message: 'this user not allowed!' };
|
if (!t.data || !t.data.objectId) return { status: 'error', message: 'this user not allowed!' };
|
||||||
{
|
{
|
||||||
var l,
|
var d,
|
||||||
p,
|
l,
|
||||||
c,
|
c,
|
||||||
m = JSON.stringify({ objectId: o });
|
p = JSON.stringify({ objectId: a });
|
||||||
let a, t;
|
let s, r;
|
||||||
t = o
|
r = a
|
||||||
? (l = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + m, {
|
? (d = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + p, {
|
||||||
headers: {
|
headers: {
|
||||||
'X-Parse-Application-Id': APPID,
|
'X-Parse-Application-Id': APPID,
|
||||||
'X-Parse-Session-Token': s.headers.sessiontoken,
|
'X-Parse-Session-Token': i.headers.sessiontoken,
|
||||||
},
|
},
|
||||||
})).data && 0 < l.data.results.length
|
})).data && 0 < d.data.results.length
|
||||||
? ((a = l), 'contracts_Contactbook')
|
? ((s = d), 'contracts_Contactbook')
|
||||||
: ((a = await axios.get(serverUrl + '/classes/contracts_Users?where=' + m, {
|
: ((s = await axios.get(serverUrl + '/classes/contracts_Users?where=' + p, {
|
||||||
headers: {
|
headers: { 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY },
|
||||||
'X-Parse-Application-Id': APPID,
|
|
||||||
'X-Parse-Master-Key': masterKEY,
|
|
||||||
},
|
|
||||||
})),
|
})),
|
||||||
'contracts_Users')
|
'contracts_Users')
|
||||||
: ((p = JSON.stringify({
|
: ((l = JSON.stringify({
|
||||||
UserId: { __type: 'Pointer', className: '_User', objectId: d.data.objectId },
|
UserId: { __type: 'Pointer', className: '_User', objectId: t.data.objectId },
|
||||||
})),
|
})),
|
||||||
(c = await axios.get(serverUrl + '/classes/contracts_Users?where=' + p, {
|
(c = await axios.get(serverUrl + '/classes/contracts_Users?where=' + l, {
|
||||||
headers: {
|
headers: { 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY },
|
||||||
'X-Parse-Application-Id': APPID,
|
|
||||||
'X-Parse-Master-Key': masterKEY,
|
|
||||||
},
|
|
||||||
})).data && 0 < c.data.results.length
|
})).data && 0 < c.data.results.length
|
||||||
? ((a = c), 'contracts_Users')
|
? ((s = c), 'contracts_Users')
|
||||||
: ((a = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + p, {
|
: ((s = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + l, {
|
||||||
headers: {
|
headers: {
|
||||||
'X-Parse-Application-Id': APPID,
|
'X-Parse-Application-Id': APPID,
|
||||||
'X-Parse-Session-Token': s.headers.sessiontoken,
|
'X-Parse-Session-Token': i.headers.sessiontoken,
|
||||||
},
|
},
|
||||||
})),
|
})),
|
||||||
'contracts_Contactbook'));
|
'contracts_Contactbook'));
|
||||||
var g = a.data.results[0].Name,
|
var m = s.data.results[0].Name,
|
||||||
h = a.data.results[0].Email;
|
g = s.data.results[0].Email;
|
||||||
if (!s.params.pdfFile) return { status: 'error', message: 'pdf file not present!' };
|
if (!i.params.pdfFile) return { status: 'error', message: 'pdf file not present!' };
|
||||||
{
|
{
|
||||||
let e = Buffer.from(s.params.pdfFile, 'base64');
|
let e = Buffer.from(i.params.pdfFile, 'base64');
|
||||||
var u = process.env.PFX_BASE64,
|
var h = process.env.PFX_BASE64,
|
||||||
f = Buffer.from(u, 'base64');
|
u = Buffer.from(h, 'base64'),
|
||||||
e = i
|
f = {
|
||||||
? plainplaceholder({
|
UserPtr: { __type: 'Pointer', className: r, objectId: s.data.results[0].objectId },
|
||||||
pdfBuffer: e,
|
SignedUrl: '',
|
||||||
reason: 'Digitally signed by Open sign for ' + g + ' <' + h + '>',
|
Activity: 'Signed',
|
||||||
location: 'test location',
|
ipAddress: i.headers['x-real-ip'],
|
||||||
signatureLength: 1e4,
|
};
|
||||||
sign: i,
|
let a;
|
||||||
})
|
var y = (a =
|
||||||
: plainAddPlaceholder({
|
o.data.AuditTrail && 0 < o.data.AuditTrail.length
|
||||||
pdfBuffer: e,
|
? [...o.data.AuditTrail, f]
|
||||||
reason: 'Digitally signed by Open sign for ' + g + ' <' + h + '>',
|
: [f]).filter(e => 'Signed' === e.Activity);
|
||||||
location: 'test location',
|
let t = !1;
|
||||||
signatureLength: 1e4,
|
!(
|
||||||
});
|
(o.data.Signers && 0 < o.data.Signers.length && y.length !== o.data.Signers.length) ||
|
||||||
var y = await new SignPDF(e, f).signPDF(),
|
!(t = !0)
|
||||||
v = `./exports/exported_file_${Math.floor(5e3 * Math.random())}.pdf`,
|
);
|
||||||
P = (fs.writeFileSync(v, y), await uploadFile(v));
|
var v,
|
||||||
if (P && P.imageUrl) {
|
P,
|
||||||
const r = await updateDoc(
|
b = `exported_file_${Math.floor(5e3 * Math.random())}.pdf`,
|
||||||
s.params.docId,
|
x = './exports/' + b,
|
||||||
P.imageUrl,
|
U =
|
||||||
a.data.results[0].objectId,
|
(t
|
||||||
s.headers['x-real-ip'],
|
? ((v = o.data.Signers?.map(e => e.Name + ' <' + e.Email + '>')),
|
||||||
n.data,
|
(e =
|
||||||
t
|
v && 0 < v.length
|
||||||
|
? plainAddPlaceholder({
|
||||||
|
pdfBuffer: e,
|
||||||
|
reason: 'Digitally signed by OpenSign for ' + v?.join(', '),
|
||||||
|
location: 'location',
|
||||||
|
signatureLength: 1e4,
|
||||||
|
})
|
||||||
|
: plainAddPlaceholder({
|
||||||
|
pdfBuffer: e,
|
||||||
|
reason: 'Digitally signed by OpenSign for ' + m + ' <' + g + '>',
|
||||||
|
location: 'location',
|
||||||
|
signatureLength: 1e4,
|
||||||
|
})),
|
||||||
|
(P = await new SignPDF(e, u).signPDF()),
|
||||||
|
fs.writeFileSync(x, P))
|
||||||
|
: fs.writeFileSync(x, e),
|
||||||
|
await uploadFile(b, x));
|
||||||
|
if (U && U.imageUrl) {
|
||||||
|
const n = await updateDoc(
|
||||||
|
i.params.docId,
|
||||||
|
U.imageUrl,
|
||||||
|
s.data.results[0].objectId,
|
||||||
|
i.headers['x-real-ip'],
|
||||||
|
o.data,
|
||||||
|
r
|
||||||
);
|
);
|
||||||
|
var I,
|
||||||
|
w = {
|
||||||
|
url: U.imageUrl,
|
||||||
|
sender: { Mail: o.data.ExtUserPtr.Email, Name: o.data.ExtUserPtr.Name },
|
||||||
|
pdfName: o.data.Name,
|
||||||
|
receiver: g,
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
sendMail({
|
o.data.IsSendMail && !1 === o.data.IsSendMail
|
||||||
url: P.imageUrl,
|
? console.log("don't send mail")
|
||||||
sender: { Mail: n.data.ExtUserPtr.Email, Name: n.data.ExtUserPtr.Name },
|
: sendMail(w),
|
||||||
pdfName: n.data.Name,
|
sendDoctoWebhook(o, U.imageUrl, 'signed', s?.data.results?.[0]),
|
||||||
receiver: h,
|
n &&
|
||||||
}),
|
n.isCompleted &&
|
||||||
r &&
|
((I = {
|
||||||
r.isCompleted &&
|
url: U.imageUrl,
|
||||||
sendCompletedMail({
|
sender: { Mail: o.data.ExtUserPtr.Email, Name: 'OpenSign™' },
|
||||||
url: P.imageUrl,
|
pdfName: o.data.Name,
|
||||||
sender: { Mail: n.data.ExtUserPtr.Email, Name: 'Open sign' },
|
receiver: o.data.ExtUserPtr.Email,
|
||||||
pdfName: n.data.Name,
|
|
||||||
receiver: n.data.ExtUserPtr.Email,
|
|
||||||
}),
|
}),
|
||||||
fs.unlinkSync(v),
|
o.data.IsSendMail && !1 === o.data.IsSendMail
|
||||||
console.log('New Signed PDF created called: ' + v),
|
? console.log("don't send mail")
|
||||||
'success' === r.message
|
: sendCompletedMail(I),
|
||||||
? { status: 'success', data: P.imageUrl }
|
sendDoctoWebhook(o, U.imageUrl, 'completed')),
|
||||||
|
fs.unlinkSync(x),
|
||||||
|
console.log('New Signed PDF created called: ' + x),
|
||||||
|
'success' === n.message
|
||||||
|
? { status: 'success', data: U.imageUrl }
|
||||||
: { status: 'error', message: 'please provide required parameters!' }
|
: { status: 'error', message: 'please provide required parameters!' }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,13 @@ export default function reportJson(id, userId) {
|
|||||||
return {
|
return {
|
||||||
reportName: 'Draft Documents',
|
reportName: 'Draft Documents',
|
||||||
params: {
|
params: {
|
||||||
Type: null,
|
Type: { $ne: 'Folder' },
|
||||||
|
IsCompleted: { $ne: true },
|
||||||
|
IsDeclined: { $ne: true },
|
||||||
|
IsArchive: { $ne: true },
|
||||||
$or: [
|
$or: [
|
||||||
{ Signers: null, SignedUrl: null },
|
{ Signers: { $eq: [] } },
|
||||||
|
{ Signers: null },
|
||||||
{ Signers: { $exists: true }, Placeholders: null },
|
{ Signers: { $exists: true }, Placeholders: null },
|
||||||
],
|
],
|
||||||
CreatedBy: {
|
CreatedBy: {
|
||||||
@@ -18,7 +22,16 @@ export default function reportJson(id, userId) {
|
|||||||
objectId: currentUserId,
|
objectId: currentUserId,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
keys: [
|
||||||
|
'Name',
|
||||||
|
'Note',
|
||||||
|
'Folder.Name',
|
||||||
|
'URL',
|
||||||
|
'ExtUserPtr.Name',
|
||||||
|
'Signers.Name',
|
||||||
|
'Signers.Email',
|
||||||
|
'Signers.Phone',
|
||||||
|
],
|
||||||
};
|
};
|
||||||
// Need your sign report
|
// Need your sign report
|
||||||
case '4Hhwbp482K':
|
case '4Hhwbp482K':
|
||||||
@@ -28,10 +41,23 @@ export default function reportJson(id, userId) {
|
|||||||
Type: { $ne: 'Folder' },
|
Type: { $ne: 'Folder' },
|
||||||
IsCompleted: { $ne: true },
|
IsCompleted: { $ne: true },
|
||||||
IsDeclined: { $ne: true },
|
IsDeclined: { $ne: true },
|
||||||
|
IsArchive: { $ne: true },
|
||||||
ExpiryDate: {
|
ExpiryDate: {
|
||||||
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
||||||
},
|
},
|
||||||
Placeholders: { $ne: null },
|
Placeholders: { $ne: null },
|
||||||
|
Signers: {
|
||||||
|
$inQuery: {
|
||||||
|
where: {
|
||||||
|
UserId: {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: currentUserId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
className: 'contracts_Contactbook',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
keys: [
|
keys: [
|
||||||
'Name',
|
'Name',
|
||||||
@@ -40,6 +66,8 @@ export default function reportJson(id, userId) {
|
|||||||
'URL',
|
'URL',
|
||||||
'ExtUserPtr.Name',
|
'ExtUserPtr.Name',
|
||||||
'Signers.Name',
|
'Signers.Name',
|
||||||
|
'Signers.Email',
|
||||||
|
'Signers.Phone',
|
||||||
'Signers.UserId',
|
'Signers.UserId',
|
||||||
'AuditTrail',
|
'AuditTrail',
|
||||||
],
|
],
|
||||||
@@ -50,10 +78,11 @@ export default function reportJson(id, userId) {
|
|||||||
reportName: 'In-progress documents',
|
reportName: 'In-progress documents',
|
||||||
params: {
|
params: {
|
||||||
Type: { $ne: 'Folder' },
|
Type: { $ne: 'Folder' },
|
||||||
Signers: { $ne: null },
|
Signers: { $exists: true, $ne: [] },
|
||||||
Placeholders: { $ne: null },
|
Placeholders: { $ne: null },
|
||||||
IsCompleted: { $ne: true },
|
IsCompleted: { $ne: true },
|
||||||
IsDeclined: { $ne: true },
|
IsDeclined: { $ne: true },
|
||||||
|
IsArchive: { $ne: true },
|
||||||
CreatedBy: {
|
CreatedBy: {
|
||||||
__type: 'Pointer',
|
__type: 'Pointer',
|
||||||
className: '_User',
|
className: '_User',
|
||||||
@@ -63,22 +92,6 @@ export default function reportJson(id, userId) {
|
|||||||
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
|
||||||
};
|
|
||||||
// completed documents report
|
|
||||||
case 'kQUoW4hUXz':
|
|
||||||
return {
|
|
||||||
reportName: 'Completed Documents',
|
|
||||||
params: {
|
|
||||||
Type: null,
|
|
||||||
IsCompleted: true,
|
|
||||||
CreatedBy: {
|
|
||||||
__type: 'Pointer',
|
|
||||||
className: '_User',
|
|
||||||
objectId: currentUserId,
|
|
||||||
},
|
|
||||||
IsDeclined: { $ne: true },
|
|
||||||
},
|
|
||||||
keys: [
|
keys: [
|
||||||
'Name',
|
'Name',
|
||||||
'Note',
|
'Note',
|
||||||
@@ -86,6 +99,35 @@ export default function reportJson(id, userId) {
|
|||||||
'URL',
|
'URL',
|
||||||
'ExtUserPtr.Name',
|
'ExtUserPtr.Name',
|
||||||
'Signers.Name',
|
'Signers.Name',
|
||||||
|
'Signers.Email',
|
||||||
|
'Signers.Phone',
|
||||||
|
],
|
||||||
|
};
|
||||||
|
// completed documents report
|
||||||
|
case 'kQUoW4hUXz':
|
||||||
|
return {
|
||||||
|
reportName: 'Completed Documents',
|
||||||
|
params: {
|
||||||
|
Type: { $ne: 'Folder' },
|
||||||
|
IsCompleted: true,
|
||||||
|
CreatedBy: {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: currentUserId,
|
||||||
|
},
|
||||||
|
IsDeclined: { $ne: true },
|
||||||
|
IsArchive: { $ne: true },
|
||||||
|
},
|
||||||
|
keys: [
|
||||||
|
'Name',
|
||||||
|
'Note',
|
||||||
|
'Folder.Name',
|
||||||
|
'URL',
|
||||||
|
'SignedUrl',
|
||||||
|
'ExtUserPtr.Name',
|
||||||
|
'Signers.Name',
|
||||||
|
'Signers.Email',
|
||||||
|
'Signers.Phone',
|
||||||
'TimeToCompleteDays',
|
'TimeToCompleteDays',
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
@@ -96,6 +138,7 @@ export default function reportJson(id, userId) {
|
|||||||
reportName: 'Declined Documents',
|
reportName: 'Declined Documents',
|
||||||
params: {
|
params: {
|
||||||
Type: null,
|
Type: null,
|
||||||
|
IsArchive: { $ne: true },
|
||||||
IsDeclined: true,
|
IsDeclined: true,
|
||||||
CreatedBy: {
|
CreatedBy: {
|
||||||
__type: 'Pointer',
|
__type: 'Pointer',
|
||||||
@@ -104,7 +147,16 @@ export default function reportJson(id, userId) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
keys: [
|
||||||
|
'Name',
|
||||||
|
'Note',
|
||||||
|
'Folder.Name',
|
||||||
|
'URL',
|
||||||
|
'ExtUserPtr.Name',
|
||||||
|
'Signers.Name',
|
||||||
|
'Signers.Email',
|
||||||
|
'Signers.Phone',
|
||||||
|
],
|
||||||
};
|
};
|
||||||
// Expired Documents report
|
// Expired Documents report
|
||||||
case 'zNqBHXHsYH':
|
case 'zNqBHXHsYH':
|
||||||
@@ -113,6 +165,7 @@ export default function reportJson(id, userId) {
|
|||||||
params: {
|
params: {
|
||||||
IsCompleted: { $ne: true },
|
IsCompleted: { $ne: true },
|
||||||
IsDeclined: { $ne: true },
|
IsDeclined: { $ne: true },
|
||||||
|
IsArchive: { $ne: true },
|
||||||
Type: { $ne: 'Folder' },
|
Type: { $ne: 'Folder' },
|
||||||
$and: [
|
$and: [
|
||||||
{
|
{
|
||||||
@@ -133,7 +186,16 @@ export default function reportJson(id, userId) {
|
|||||||
objectId: currentUserId,
|
objectId: currentUserId,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
keys: [
|
||||||
|
'Name',
|
||||||
|
'Note',
|
||||||
|
'Folder.Name',
|
||||||
|
'URL',
|
||||||
|
'ExtUserPtr.Name',
|
||||||
|
'Signers.Name',
|
||||||
|
'Signers.Email',
|
||||||
|
'Signers.Phone',
|
||||||
|
],
|
||||||
};
|
};
|
||||||
// Recently sent for signatures report show on dashboard
|
// Recently sent for signatures report show on dashboard
|
||||||
case 'd9k3UfYHBc':
|
case 'd9k3UfYHBc':
|
||||||
@@ -141,10 +203,11 @@ export default function reportJson(id, userId) {
|
|||||||
reportName: 'Recently sent for signatures',
|
reportName: 'Recently sent for signatures',
|
||||||
params: {
|
params: {
|
||||||
Type: { $ne: 'Folder' },
|
Type: { $ne: 'Folder' },
|
||||||
Signers: { $ne: null },
|
Signers: { $exists: true, $ne: [] },
|
||||||
Placeholders: { $ne: null },
|
Placeholders: { $ne: null },
|
||||||
IsCompleted: { $ne: true },
|
IsCompleted: { $ne: true },
|
||||||
IsDeclined: { $ne: true },
|
IsDeclined: { $ne: true },
|
||||||
|
IsArchive: { $ne: true },
|
||||||
CreatedBy: {
|
CreatedBy: {
|
||||||
__type: 'Pointer',
|
__type: 'Pointer',
|
||||||
className: '_User',
|
className: '_User',
|
||||||
@@ -154,7 +217,15 @@ export default function reportJson(id, userId) {
|
|||||||
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
keys: [
|
||||||
|
'Name',
|
||||||
|
'Folder.Name',
|
||||||
|
'URL',
|
||||||
|
'ExtUserPtr.Name',
|
||||||
|
'Signers.Name',
|
||||||
|
'Signers.Email',
|
||||||
|
'Signers.Phone',
|
||||||
|
],
|
||||||
};
|
};
|
||||||
// Recent signature requests report show on dashboard
|
// Recent signature requests report show on dashboard
|
||||||
case '5Go51Q7T8r':
|
case '5Go51Q7T8r':
|
||||||
@@ -164,20 +235,33 @@ export default function reportJson(id, userId) {
|
|||||||
Type: { $ne: 'Folder' },
|
Type: { $ne: 'Folder' },
|
||||||
IsCompleted: { $ne: true },
|
IsCompleted: { $ne: true },
|
||||||
IsDeclined: { $ne: true },
|
IsDeclined: { $ne: true },
|
||||||
|
IsArchive: { $ne: true },
|
||||||
ExpiryDate: {
|
ExpiryDate: {
|
||||||
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
||||||
},
|
},
|
||||||
Placeholders: { $ne: null },
|
Placeholders: { $ne: null },
|
||||||
|
Signers: {
|
||||||
|
$inQuery: {
|
||||||
|
where: {
|
||||||
|
UserId: {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: currentUserId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
className: 'contracts_Contactbook',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
keys: [
|
keys: [
|
||||||
'Name',
|
'Name',
|
||||||
'Note',
|
|
||||||
'Folder.Name',
|
|
||||||
'URL',
|
'URL',
|
||||||
'ExtUserPtr.Name',
|
'ExtUserPtr.Name',
|
||||||
'Signers.Name',
|
'Signers.Name',
|
||||||
'Signers.UserId',
|
'Signers.UserId',
|
||||||
'AuditTrail',
|
'AuditTrail',
|
||||||
|
'Signers.Email',
|
||||||
|
'Signers.Phone',
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
// Drafts report show on dashboard
|
// Drafts report show on dashboard
|
||||||
@@ -185,9 +269,13 @@ export default function reportJson(id, userId) {
|
|||||||
return {
|
return {
|
||||||
reportName: 'Drafts',
|
reportName: 'Drafts',
|
||||||
params: {
|
params: {
|
||||||
Type: null,
|
Type: { $ne: 'Folder' },
|
||||||
|
IsCompleted: { $ne: true },
|
||||||
|
IsDeclined: { $ne: true },
|
||||||
|
IsArchive: { $ne: true },
|
||||||
$or: [
|
$or: [
|
||||||
{ Signers: null, SignedUrl: null },
|
{ Signers: { $eq: [] } },
|
||||||
|
{ Signers: null },
|
||||||
{ Signers: { $exists: true }, Placeholders: null },
|
{ Signers: { $exists: true }, Placeholders: null },
|
||||||
],
|
],
|
||||||
CreatedBy: {
|
CreatedBy: {
|
||||||
@@ -196,12 +284,22 @@ export default function reportJson(id, userId) {
|
|||||||
objectId: currentUserId,
|
objectId: currentUserId,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
keys: [
|
||||||
|
'Name',
|
||||||
|
'Note',
|
||||||
|
'Folder.Name',
|
||||||
|
'URL',
|
||||||
|
'ExtUserPtr.Name',
|
||||||
|
'Signers.Name',
|
||||||
|
'Signers.Email',
|
||||||
|
'Signers.Phone',
|
||||||
|
],
|
||||||
};
|
};
|
||||||
// contact book report
|
// contact book report
|
||||||
case '5KhaPr482K':
|
case '5KhaPr482K':
|
||||||
return {
|
return {
|
||||||
reportName: 'Contactbook',
|
reportName: 'Contactbook',
|
||||||
|
reportClass: 'contracts_Contactbook',
|
||||||
params: {
|
params: {
|
||||||
CreatedBy: {
|
CreatedBy: {
|
||||||
__type: 'Pointer',
|
__type: 'Pointer',
|
||||||
@@ -212,6 +310,31 @@ export default function reportJson(id, userId) {
|
|||||||
},
|
},
|
||||||
keys: ['Name', 'Email', 'Phone'],
|
keys: ['Name', 'Email', 'Phone'],
|
||||||
};
|
};
|
||||||
|
// Templates report
|
||||||
|
case '6TeaPr321t':
|
||||||
|
return {
|
||||||
|
reportName: 'Templates',
|
||||||
|
reportClass: 'contracts_Template',
|
||||||
|
params: {
|
||||||
|
Type: { $ne: 'Folder' },
|
||||||
|
IsArchive: { $ne: true },
|
||||||
|
CreatedBy: {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: currentUserId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
keys: [
|
||||||
|
'Name',
|
||||||
|
'Note',
|
||||||
|
'Folder.Name',
|
||||||
|
'URL',
|
||||||
|
'ExtUserPtr.Name',
|
||||||
|
'Signers.Name',
|
||||||
|
'Signers.Email',
|
||||||
|
'Signers.Phone',
|
||||||
|
],
|
||||||
|
};
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
export default async function savewebhook(request) {
|
||||||
|
const serverUrl = process.env.SERVER_URL;
|
||||||
|
try {
|
||||||
|
const userRes = await axios.get(serverUrl + '/users/me', {
|
||||||
|
headers: {
|
||||||
|
'X-Parse-Application-Id': process.env.APP_ID,
|
||||||
|
'X-Parse-Session-Token': request.headers['sessiontoken'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const userId = userRes.data && userRes.data.objectId;
|
||||||
|
const contractuser = new Parse.Query('contracts_Users');
|
||||||
|
contractuser.equalTo('UserId', { __type: 'Pointer', className: '_User', objectId: userId });
|
||||||
|
const user = await contractuser.first({ useMasterKey: true });
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
const updateUser = new Parse.Object('contracts_Users');
|
||||||
|
updateUser.id = user.id;
|
||||||
|
updateUser.set('Webhook', request.params.url);
|
||||||
|
const updatedRes = await updateUser.save(null, { useMasterKey: true });
|
||||||
|
if (updatedRes) {
|
||||||
|
return { code: 200, Webhook: updatedRes.get('Webhook') };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('update user', err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,7 +38,7 @@ exports.up = async Parse => {
|
|||||||
pageType: 'form',
|
pageType: 'form',
|
||||||
description: '',
|
description: '',
|
||||||
objectId: '8mZzFxbG1z',
|
objectId: '8mZzFxbG1z',
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,588 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Parse} Parse
|
||||||
|
*/
|
||||||
|
exports.up = async Parse => {
|
||||||
|
const className = 'w_menu';
|
||||||
|
const userMenu = new Parse.Query(className);
|
||||||
|
const updateUserMenu = await userMenu.get('H9vRfEYKhT');
|
||||||
|
updateUserMenu.set('menuItems', [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tachometer-alt',
|
||||||
|
title: 'Dashboard',
|
||||||
|
target: '',
|
||||||
|
pageType: 'dashboard',
|
||||||
|
description: '',
|
||||||
|
objectId: '35KBoSgoAK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-newspaper',
|
||||||
|
title: 'New Document',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: null,
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-nib',
|
||||||
|
title: 'Sign yourself',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'sHAnZphf69',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-paper-plane',
|
||||||
|
title: 'Request signatures',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: '8mZzFxbG1z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-file-signature',
|
||||||
|
title: 'New template',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'template',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-file-contract',
|
||||||
|
title: 'Templates',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '6TeaPr321t',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-folder',
|
||||||
|
title: 'OpenSign™ Drive',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-address-card',
|
||||||
|
title: 'Reports',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-signature',
|
||||||
|
title: 'Need your sign',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '4Hhwbp482K',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tasks',
|
||||||
|
title: 'In Progress',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '1MwEuxLEkF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-check-circle',
|
||||||
|
title: 'Completed',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'kQUoW4hUXz',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-edit',
|
||||||
|
title: 'Drafts',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'ByHuevtCFY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-times-circle',
|
||||||
|
title: 'Declined',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'UPr2Fm5WY3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-hourglass-end',
|
||||||
|
title: 'Expired',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'zNqBHXHsYH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-address-book',
|
||||||
|
title: 'Contactbook',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '5KhaPr482K',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-cog',
|
||||||
|
title: 'Settings',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-fancy',
|
||||||
|
title: 'My Signature',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const AdminMenu = new Parse.Query(className);
|
||||||
|
const updateAdminMenu = await AdminMenu.get('VPh91h0ZHk');
|
||||||
|
updateAdminMenu.set('menuItems', [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tachometer-alt',
|
||||||
|
title: 'Dashboard',
|
||||||
|
target: '',
|
||||||
|
pageType: 'dashboard',
|
||||||
|
description: '',
|
||||||
|
objectId: '35KBoSgoAK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-newspaper',
|
||||||
|
title: 'New Document',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: null,
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-nib',
|
||||||
|
title: 'Sign yourself',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'sHAnZphf69',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-paper-plane',
|
||||||
|
title: 'Request signatures',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: '8mZzFxbG1z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-file-signature',
|
||||||
|
title: 'New template',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'template',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-file-contract',
|
||||||
|
title: 'Templates',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '6TeaPr321t',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-folder',
|
||||||
|
title: 'OpenSign™ Drive',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-address-card',
|
||||||
|
title: 'Reports',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-signature',
|
||||||
|
title: 'Need your sign',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '4Hhwbp482K',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tasks',
|
||||||
|
title: 'In Progress',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '1MwEuxLEkF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-check-circle',
|
||||||
|
title: 'Completed',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'kQUoW4hUXz',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-edit',
|
||||||
|
title: 'Drafts',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'ByHuevtCFY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-times-circle',
|
||||||
|
title: 'Declined',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'UPr2Fm5WY3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-hourglass-end',
|
||||||
|
title: 'Expired',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'zNqBHXHsYH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-address-book',
|
||||||
|
title: 'Contactbook',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '5KhaPr482K',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-cog',
|
||||||
|
title: 'Settings',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-fancy',
|
||||||
|
title: 'My Signature',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-user',
|
||||||
|
title: 'Add User',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'lM0xRnM3iE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
// TODO: Set the schema here
|
||||||
|
// Example:
|
||||||
|
// schema.addString('name').addNumber('cash');
|
||||||
|
const batch = [updateUserMenu, updateAdminMenu];
|
||||||
|
return Parse.Object.saveAll(batch, { useMasterKey: true });
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Parse} Parse
|
||||||
|
*/
|
||||||
|
exports.down = async Parse => {
|
||||||
|
// TODO: set className here
|
||||||
|
const className = 'w_menu';
|
||||||
|
const userMenu = new Parse.Query(className);
|
||||||
|
const revertUserMenu = await userMenu.get('H9vRfEYKhT');
|
||||||
|
revertUserMenu.set('menuItems', [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tachometer-alt',
|
||||||
|
title: 'Dashboard',
|
||||||
|
target: '',
|
||||||
|
pageType: 'dashboard',
|
||||||
|
description: '',
|
||||||
|
objectId: '35KBoSgoAK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-newspaper',
|
||||||
|
title: 'New Document',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: null,
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-nib',
|
||||||
|
title: 'Sign yourself',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'sHAnZphf69',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-file-signature',
|
||||||
|
title: 'Request signatures',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: '8mZzFxbG1z',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-folder',
|
||||||
|
title: 'OpenSignDrive™',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-address-card',
|
||||||
|
title: 'Reports',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-signature',
|
||||||
|
title: 'Need your sign',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '4Hhwbp482K',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tasks',
|
||||||
|
title: 'In Progress',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '1MwEuxLEkF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-check-circle',
|
||||||
|
title: 'Completed',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'kQUoW4hUXz',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-edit',
|
||||||
|
title: 'Drafts',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'ByHuevtCFY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-times-circle',
|
||||||
|
title: 'Declined',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'UPr2Fm5WY3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-hourglass-end',
|
||||||
|
title: 'Expired',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'zNqBHXHsYH',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-cog',
|
||||||
|
title: 'Settings',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-fancy',
|
||||||
|
title: 'My Signature',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const adminMenu = new Parse.Query(className);
|
||||||
|
const revertAdminMenu = await adminMenu.get('VPh91h0ZHk');
|
||||||
|
revertAdminMenu.set('menuItems', [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tachometer-alt',
|
||||||
|
title: 'Dashboard',
|
||||||
|
target: '',
|
||||||
|
pageType: 'dashboard',
|
||||||
|
description: '',
|
||||||
|
objectId: '35KBoSgoAK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-newspaper',
|
||||||
|
title: 'New Document',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: null,
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-nib',
|
||||||
|
title: 'Sign yourself',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'sHAnZphf69',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-file-signature',
|
||||||
|
title: 'Request signatures',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: '8mZzFxbG1z',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-folder',
|
||||||
|
title: 'OpenSignDrive™',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-address-card',
|
||||||
|
title: 'Reports',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-signature',
|
||||||
|
title: 'Need your sign',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '4Hhwbp482K',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tasks',
|
||||||
|
title: 'In Progress',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '1MwEuxLEkF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-check-circle',
|
||||||
|
title: 'Completed',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'kQUoW4hUXz',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-edit',
|
||||||
|
title: 'Drafts',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'ByHuevtCFY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-times-circle',
|
||||||
|
title: 'Declined',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'UPr2Fm5WY3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-hourglass-end',
|
||||||
|
title: 'Expired',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'zNqBHXHsYH',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-cog',
|
||||||
|
title: 'Settings',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-fancy',
|
||||||
|
title: 'My Signature',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-user',
|
||||||
|
title: 'Add User',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'lM0xRnM3iE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
// TODO: Set the schema here
|
||||||
|
// Example:
|
||||||
|
// schema.addString('name').addNumber('cash');
|
||||||
|
const batch = [revertUserMenu, revertAdminMenu];
|
||||||
|
return Parse.Object.saveAll(batch, { useMasterKey: true });
|
||||||
|
};
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Parse} Parse
|
||||||
|
*/
|
||||||
|
exports.up = async Parse => {
|
||||||
|
const className = 'contracts_Template';
|
||||||
|
const schema = new Parse.Schema(className);
|
||||||
|
|
||||||
|
schema.addString('Name');
|
||||||
|
schema.addString('URL');
|
||||||
|
schema.addString('Note');
|
||||||
|
schema.addString('Description');
|
||||||
|
schema.addArray('Signers');
|
||||||
|
schema.addBoolean('IsArchive');
|
||||||
|
schema.addArray('Placeholders');
|
||||||
|
schema.addPointer('Folder', 'contracts_Template');
|
||||||
|
schema.addString('Type');
|
||||||
|
schema.addPointer('CreatedBy', '_User');
|
||||||
|
schema.addPointer('ExtUserPtr', 'contracts_Users');
|
||||||
|
schema.addBoolean('EnablePhoneOTP')
|
||||||
|
schema.addBoolean('EnableEmailOTP')
|
||||||
|
schema.addBoolean('SendinOrder')
|
||||||
|
schema.addBoolean('SentToOthers')
|
||||||
|
schema.addBoolean('AutomaticReminders')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return schema.save();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Parse} Parse
|
||||||
|
*/
|
||||||
|
exports.down = async Parse => {
|
||||||
|
const className = 'contracts_Template';
|
||||||
|
const schema = new Parse.Schema(className);
|
||||||
|
|
||||||
|
return schema.purge().then(() => schema.delete());
|
||||||
|
};
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Parse} Parse
|
||||||
|
*/
|
||||||
|
exports.up = async Parse => {
|
||||||
|
// TODO: set className here
|
||||||
|
const className = 'contracts_Document';
|
||||||
|
const schema = new Parse.Schema(className);
|
||||||
|
schema.addBoolean('IsArchive');
|
||||||
|
return schema.update();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Parse} Parse
|
||||||
|
*/
|
||||||
|
exports.down = async Parse => {
|
||||||
|
// TODO: set className here
|
||||||
|
const className = 'contracts_Document';
|
||||||
|
const schema = new Parse.Schema(className);
|
||||||
|
schema.deleteField('IsArchive');
|
||||||
|
return schema.update();
|
||||||
|
};
|
||||||
+652
@@ -0,0 +1,652 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Parse} Parse
|
||||||
|
*/
|
||||||
|
exports.up = async Parse => {
|
||||||
|
const className = 'w_menu';
|
||||||
|
const userMenu = new Parse.Query(className);
|
||||||
|
const updateUserMenu = await userMenu.get('H9vRfEYKhT');
|
||||||
|
updateUserMenu.set('menuItems', [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tachometer-alt',
|
||||||
|
title: 'Dashboard',
|
||||||
|
target: '',
|
||||||
|
pageType: 'dashboard',
|
||||||
|
description: '',
|
||||||
|
objectId: '35KBoSgoAK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-newspaper',
|
||||||
|
title: 'New Document',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: null,
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-nib',
|
||||||
|
title: 'Sign yourself',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'sHAnZphf69',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-paper-plane',
|
||||||
|
title: 'Request signatures',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: '8mZzFxbG1z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-file-signature',
|
||||||
|
title: 'New template',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'template',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-file-contract',
|
||||||
|
title: 'Templates',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '6TeaPr321t',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-folder',
|
||||||
|
title: 'OpenSign™ Drive',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-address-card',
|
||||||
|
title: 'Reports',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-signature',
|
||||||
|
title: 'Need your sign',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '4Hhwbp482K',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tasks',
|
||||||
|
title: 'In Progress',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '1MwEuxLEkF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-check-circle',
|
||||||
|
title: 'Completed',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'kQUoW4hUXz',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-edit',
|
||||||
|
title: 'Drafts',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'ByHuevtCFY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-times-circle',
|
||||||
|
title: 'Declined',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'UPr2Fm5WY3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-hourglass-end',
|
||||||
|
title: 'Expired',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'zNqBHXHsYH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-address-book',
|
||||||
|
title: 'Contactbook',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '5KhaPr482K',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-cog',
|
||||||
|
title: 'Settings',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-fancy',
|
||||||
|
title: 'My Signature',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-key',
|
||||||
|
title: 'API Token',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'generatetoken',
|
||||||
|
description: '',
|
||||||
|
objectId: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const AdminMenu = new Parse.Query(className);
|
||||||
|
const updateAdminMenu = await AdminMenu.get('VPh91h0ZHk');
|
||||||
|
updateAdminMenu.set('menuItems', [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tachometer-alt',
|
||||||
|
title: 'Dashboard',
|
||||||
|
target: '',
|
||||||
|
pageType: 'dashboard',
|
||||||
|
description: '',
|
||||||
|
objectId: '35KBoSgoAK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-newspaper',
|
||||||
|
title: 'New Document',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: null,
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-nib',
|
||||||
|
title: 'Sign yourself',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'sHAnZphf69',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-paper-plane',
|
||||||
|
title: 'Request signatures',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: '8mZzFxbG1z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-file-signature',
|
||||||
|
title: 'New template',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'template',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-file-contract',
|
||||||
|
title: 'Templates',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '6TeaPr321t',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-folder',
|
||||||
|
title: 'OpenSign™ Drive',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-address-card',
|
||||||
|
title: 'Reports',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-signature',
|
||||||
|
title: 'Need your sign',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '4Hhwbp482K',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tasks',
|
||||||
|
title: 'In Progress',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '1MwEuxLEkF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-check-circle',
|
||||||
|
title: 'Completed',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'kQUoW4hUXz',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-edit',
|
||||||
|
title: 'Drafts',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'ByHuevtCFY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-times-circle',
|
||||||
|
title: 'Declined',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'UPr2Fm5WY3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-hourglass-end',
|
||||||
|
title: 'Expired',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'zNqBHXHsYH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-address-book',
|
||||||
|
title: 'Contactbook',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '5KhaPr482K',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-cog',
|
||||||
|
title: 'Settings',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-fancy',
|
||||||
|
title: 'My Signature',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-user',
|
||||||
|
title: 'Add User',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'lM0xRnM3iE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-key',
|
||||||
|
title: 'API Token',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'generatetoken',
|
||||||
|
description: '',
|
||||||
|
objectId: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
// TODO: Set the schema here
|
||||||
|
// Example:
|
||||||
|
// schema.addString('name').addNumber('cash');
|
||||||
|
const batch = [updateUserMenu, updateAdminMenu];
|
||||||
|
return Parse.Object.saveAll(batch, { useMasterKey: true });
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Parse} Parse
|
||||||
|
*/
|
||||||
|
exports.down = async Parse => {
|
||||||
|
// TODO: set className here
|
||||||
|
const className = 'w_menu';
|
||||||
|
const userMenu = new Parse.Query(className);
|
||||||
|
const revertUserMenu = await userMenu.get('H9vRfEYKhT');
|
||||||
|
revertUserMenu.set('menuItems', [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tachometer-alt',
|
||||||
|
title: 'Dashboard',
|
||||||
|
target: '',
|
||||||
|
pageType: 'dashboard',
|
||||||
|
description: '',
|
||||||
|
objectId: '35KBoSgoAK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-newspaper',
|
||||||
|
title: 'New Document',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: null,
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-nib',
|
||||||
|
title: 'Sign yourself',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'sHAnZphf69',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-paper-plane',
|
||||||
|
title: 'Request signatures',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: '8mZzFxbG1z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-file-signature',
|
||||||
|
title: 'New template',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'template',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-file-contract',
|
||||||
|
title: 'Templates',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '6TeaPr321t',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-folder',
|
||||||
|
title: 'OpenSign™ Drive',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-address-card',
|
||||||
|
title: 'Reports',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-signature',
|
||||||
|
title: 'Need your sign',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '4Hhwbp482K',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tasks',
|
||||||
|
title: 'In Progress',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '1MwEuxLEkF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-check-circle',
|
||||||
|
title: 'Completed',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'kQUoW4hUXz',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-edit',
|
||||||
|
title: 'Drafts',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'ByHuevtCFY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-times-circle',
|
||||||
|
title: 'Declined',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'UPr2Fm5WY3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-hourglass-end',
|
||||||
|
title: 'Expired',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'zNqBHXHsYH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-address-book',
|
||||||
|
title: 'Contactbook',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '5KhaPr482K',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-cog',
|
||||||
|
title: 'Settings',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-fancy',
|
||||||
|
title: 'My Signature',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const adminMenu = new Parse.Query(className);
|
||||||
|
const revertAdminMenu = await adminMenu.get('VPh91h0ZHk');
|
||||||
|
revertAdminMenu.set('menuItems', [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tachometer-alt',
|
||||||
|
title: 'Dashboard',
|
||||||
|
target: '',
|
||||||
|
pageType: 'dashboard',
|
||||||
|
description: '',
|
||||||
|
objectId: '35KBoSgoAK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-newspaper',
|
||||||
|
title: 'New Document',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: null,
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-nib',
|
||||||
|
title: 'Sign yourself',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'sHAnZphf69',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-paper-plane',
|
||||||
|
title: 'Request signatures',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: '8mZzFxbG1z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-file-signature',
|
||||||
|
title: 'New template',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'template',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-file-contract',
|
||||||
|
title: 'Templates',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '6TeaPr321t',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-folder',
|
||||||
|
title: 'OpenSign™ Drive',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-address-card',
|
||||||
|
title: 'Reports',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-signature',
|
||||||
|
title: 'Need your sign',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '4Hhwbp482K',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tasks',
|
||||||
|
title: 'In Progress',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '1MwEuxLEkF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-check-circle',
|
||||||
|
title: 'Completed',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'kQUoW4hUXz',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-edit',
|
||||||
|
title: 'Drafts',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'ByHuevtCFY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-times-circle',
|
||||||
|
title: 'Declined',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'UPr2Fm5WY3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-hourglass-end',
|
||||||
|
title: 'Expired',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'zNqBHXHsYH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-address-book',
|
||||||
|
title: 'Contactbook',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '5KhaPr482K',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-cog',
|
||||||
|
title: 'Settings',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-fancy',
|
||||||
|
title: 'My Signature',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-user',
|
||||||
|
title: 'Add User',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'lM0xRnM3iE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
// TODO: Set the schema here
|
||||||
|
// Example:
|
||||||
|
// schema.addString('name').addNumber('cash');
|
||||||
|
const batch = [revertUserMenu, revertAdminMenu];
|
||||||
|
return Parse.Object.saveAll(batch, { useMasterKey: true });
|
||||||
|
};
|
||||||
@@ -0,0 +1,684 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Parse} Parse
|
||||||
|
*/
|
||||||
|
exports.up = async Parse => {
|
||||||
|
const className = 'w_menu';
|
||||||
|
const userMenu = new Parse.Query(className);
|
||||||
|
const updateUserMenu = await userMenu.get('H9vRfEYKhT');
|
||||||
|
updateUserMenu.set('menuItems', [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tachometer-alt',
|
||||||
|
title: 'Dashboard',
|
||||||
|
target: '',
|
||||||
|
pageType: 'dashboard',
|
||||||
|
description: '',
|
||||||
|
objectId: '35KBoSgoAK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-newspaper',
|
||||||
|
title: 'New Document',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: null,
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-nib',
|
||||||
|
title: 'Sign yourself',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'sHAnZphf69',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-paper-plane',
|
||||||
|
title: 'Request signatures',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: '8mZzFxbG1z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-file-signature',
|
||||||
|
title: 'New template',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'template',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-file-contract',
|
||||||
|
title: 'Templates',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '6TeaPr321t',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-folder',
|
||||||
|
title: 'OpenSign™ Drive',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-address-card',
|
||||||
|
title: 'Reports',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-signature',
|
||||||
|
title: 'Need your sign',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '4Hhwbp482K',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tasks',
|
||||||
|
title: 'In Progress',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '1MwEuxLEkF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-check-circle',
|
||||||
|
title: 'Completed',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'kQUoW4hUXz',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-edit',
|
||||||
|
title: 'Drafts',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'ByHuevtCFY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-times-circle',
|
||||||
|
title: 'Declined',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'UPr2Fm5WY3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-hourglass-end',
|
||||||
|
title: 'Expired',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'zNqBHXHsYH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-address-book',
|
||||||
|
title: 'Contactbook',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '5KhaPr482K',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-cog',
|
||||||
|
title: 'Settings',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-fancy',
|
||||||
|
title: 'My Signature',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-key',
|
||||||
|
title: 'API Token',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'generatetoken',
|
||||||
|
description: '',
|
||||||
|
objectId: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-globe',
|
||||||
|
title: 'Webhook',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'webhook',
|
||||||
|
description: '',
|
||||||
|
objectId: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const AdminMenu = new Parse.Query(className);
|
||||||
|
const updateAdminMenu = await AdminMenu.get('VPh91h0ZHk');
|
||||||
|
updateAdminMenu.set('menuItems', [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tachometer-alt',
|
||||||
|
title: 'Dashboard',
|
||||||
|
target: '',
|
||||||
|
pageType: 'dashboard',
|
||||||
|
description: '',
|
||||||
|
objectId: '35KBoSgoAK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-newspaper',
|
||||||
|
title: 'New Document',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: null,
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-nib',
|
||||||
|
title: 'Sign yourself',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'sHAnZphf69',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-paper-plane',
|
||||||
|
title: 'Request signatures',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: '8mZzFxbG1z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-file-signature',
|
||||||
|
title: 'New template',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'template',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-file-contract',
|
||||||
|
title: 'Templates',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '6TeaPr321t',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-folder',
|
||||||
|
title: 'OpenSign™ Drive',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-address-card',
|
||||||
|
title: 'Reports',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-signature',
|
||||||
|
title: 'Need your sign',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '4Hhwbp482K',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tasks',
|
||||||
|
title: 'In Progress',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '1MwEuxLEkF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-check-circle',
|
||||||
|
title: 'Completed',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'kQUoW4hUXz',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-edit',
|
||||||
|
title: 'Drafts',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'ByHuevtCFY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-times-circle',
|
||||||
|
title: 'Declined',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'UPr2Fm5WY3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-hourglass-end',
|
||||||
|
title: 'Expired',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'zNqBHXHsYH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-address-book',
|
||||||
|
title: 'Contactbook',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '5KhaPr482K',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-cog',
|
||||||
|
title: 'Settings',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-fancy',
|
||||||
|
title: 'My Signature',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-user',
|
||||||
|
title: 'Add User',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'lM0xRnM3iE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-key',
|
||||||
|
title: 'API Token',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'generatetoken',
|
||||||
|
description: '',
|
||||||
|
objectId: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-globe',
|
||||||
|
title: 'Webhook',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'webhook',
|
||||||
|
description: '',
|
||||||
|
objectId: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
// TODO: Set the schema here
|
||||||
|
// Example:
|
||||||
|
// schema.addString('name').addNumber('cash');
|
||||||
|
const batch = [updateUserMenu, updateAdminMenu];
|
||||||
|
return Parse.Object.saveAll(batch, { useMasterKey: true });
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Parse} Parse
|
||||||
|
*/
|
||||||
|
exports.down = async Parse => {
|
||||||
|
// TODO: set className here
|
||||||
|
const className = 'w_menu';
|
||||||
|
const userMenu = new Parse.Query(className);
|
||||||
|
const revertUserMenu = await userMenu.get('H9vRfEYKhT');
|
||||||
|
revertUserMenu.set('menuItems', [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tachometer-alt',
|
||||||
|
title: 'Dashboard',
|
||||||
|
target: '',
|
||||||
|
pageType: 'dashboard',
|
||||||
|
description: '',
|
||||||
|
objectId: '35KBoSgoAK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-newspaper',
|
||||||
|
title: 'New Document',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: null,
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-nib',
|
||||||
|
title: 'Sign yourself',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'sHAnZphf69',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-paper-plane',
|
||||||
|
title: 'Request signatures',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: '8mZzFxbG1z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-file-signature',
|
||||||
|
title: 'New template',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'template',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-file-contract',
|
||||||
|
title: 'Templates',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '6TeaPr321t',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-folder',
|
||||||
|
title: 'OpenSign™ Drive',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-address-card',
|
||||||
|
title: 'Reports',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-signature',
|
||||||
|
title: 'Need your sign',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '4Hhwbp482K',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tasks',
|
||||||
|
title: 'In Progress',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '1MwEuxLEkF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-check-circle',
|
||||||
|
title: 'Completed',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'kQUoW4hUXz',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-edit',
|
||||||
|
title: 'Drafts',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'ByHuevtCFY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-times-circle',
|
||||||
|
title: 'Declined',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'UPr2Fm5WY3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-hourglass-end',
|
||||||
|
title: 'Expired',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'zNqBHXHsYH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-address-book',
|
||||||
|
title: 'Contactbook',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '5KhaPr482K',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-cog',
|
||||||
|
title: 'Settings',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-fancy',
|
||||||
|
title: 'My Signature',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-key',
|
||||||
|
title: 'API Token',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'generatetoken',
|
||||||
|
description: '',
|
||||||
|
objectId: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const adminMenu = new Parse.Query(className);
|
||||||
|
const revertAdminMenu = await adminMenu.get('VPh91h0ZHk');
|
||||||
|
revertAdminMenu.set('menuItems', [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tachometer-alt',
|
||||||
|
title: 'Dashboard',
|
||||||
|
target: '',
|
||||||
|
pageType: 'dashboard',
|
||||||
|
description: '',
|
||||||
|
objectId: '35KBoSgoAK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-newspaper',
|
||||||
|
title: 'New Document',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: null,
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-nib',
|
||||||
|
title: 'Sign yourself',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'sHAnZphf69',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-paper-plane',
|
||||||
|
title: 'Request signatures',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: '8mZzFxbG1z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-file-signature',
|
||||||
|
title: 'New template',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'template',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-file-contract',
|
||||||
|
title: 'Templates',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '6TeaPr321t',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-folder',
|
||||||
|
title: 'OpenSign™ Drive',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-address-card',
|
||||||
|
title: 'Reports',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-signature',
|
||||||
|
title: 'Need your sign',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '4Hhwbp482K',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-tasks',
|
||||||
|
title: 'In Progress',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '1MwEuxLEkF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-check-circle',
|
||||||
|
title: 'Completed',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'kQUoW4hUXz',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-edit',
|
||||||
|
title: 'Drafts',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'ByHuevtCFY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-times-circle',
|
||||||
|
title: 'Declined',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'UPr2Fm5WY3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-hourglass-end',
|
||||||
|
title: 'Expired',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: 'zNqBHXHsYH',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-address-book',
|
||||||
|
title: 'Contactbook',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'report',
|
||||||
|
description: '',
|
||||||
|
objectId: '5KhaPr482K',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fas fa-cog',
|
||||||
|
title: 'Settings',
|
||||||
|
target: '_self',
|
||||||
|
pageType: null,
|
||||||
|
description: '',
|
||||||
|
objectId: null,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: 'fas fa-pen-fancy',
|
||||||
|
title: 'My Signature',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'mf',
|
||||||
|
description: '',
|
||||||
|
objectId:
|
||||||
|
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'far fa-user',
|
||||||
|
title: 'Add User',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'form',
|
||||||
|
description: '',
|
||||||
|
objectId: 'lM0xRnM3iE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-key',
|
||||||
|
title: 'API Token',
|
||||||
|
target: '_self',
|
||||||
|
pageType: 'generatetoken',
|
||||||
|
description: '',
|
||||||
|
objectId: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
// TODO: Set the schema here
|
||||||
|
// Example:
|
||||||
|
// schema.addString('name').addNumber('cash');
|
||||||
|
const batch = [revertUserMenu, revertAdminMenu];
|
||||||
|
return Parse.Object.saveAll(batch, { useMasterKey: true });
|
||||||
|
};
|
||||||
Binary file not shown.
@@ -1 +1 @@
|
|||||||
Email Address Verification
|
OpenSign™ Email Address Verification
|
||||||
@@ -19,7 +19,8 @@ import AWS from 'aws-sdk';
|
|||||||
import { app as customRoute } from './cloud/customRoute/customApp.js';
|
import { app as customRoute } from './cloud/customRoute/customApp.js';
|
||||||
import { exec } from 'child_process';
|
import { exec } from 'child_process';
|
||||||
import { createTransport } from 'nodemailer';
|
import { createTransport } from 'nodemailer';
|
||||||
|
import { app as v1 } from './cloud/customRoute/v1/apiV1.js';
|
||||||
|
import { PostHog } from 'posthog-node';
|
||||||
const spacesEndpoint = new AWS.Endpoint(process.env.DO_ENDPOINT);
|
const spacesEndpoint = new AWS.Endpoint(process.env.DO_ENDPOINT);
|
||||||
// console.log("configuration ", configuration);
|
// console.log("configuration ", configuration);
|
||||||
if (process.env.USE_LOCAL !== 'TRUE') {
|
if (process.env.USE_LOCAL !== 'TRUE') {
|
||||||
@@ -69,8 +70,11 @@ if (process.env.SMTP_ENABLE) {
|
|||||||
export const config = {
|
export const config = {
|
||||||
databaseURI:
|
databaseURI:
|
||||||
process.env.DATABASE_URI || process.env.MONGODB_URI || 'mongodb://localhost:27017/dev',
|
process.env.DATABASE_URI || process.env.MONGODB_URI || 'mongodb://localhost:27017/dev',
|
||||||
cloud: process.env.CLOUD || __dirname + '/cloud/main.js',
|
cloud: function () {
|
||||||
|
import('./cloud/main.js');
|
||||||
|
},
|
||||||
appId: process.env.APP_ID || 'myAppId',
|
appId: process.env.APP_ID || 'myAppId',
|
||||||
|
maxLimit: 500,
|
||||||
masterKey: process.env.MASTER_KEY || '', //Add your master key here. Keep it secret!
|
masterKey: process.env.MASTER_KEY || '', //Add your master key here. Keep it secret!
|
||||||
masterKeyIps: ['0.0.0.0/0', '::1'], // '::1'
|
masterKeyIps: ['0.0.0.0/0', '::1'], // '::1'
|
||||||
serverURL: process.env.SERVER_URL || 'http://localhost:8080/app', // Don't forget to change to https if needed
|
serverURL: process.env.SERVER_URL || 'http://localhost:8080/app', // Don't forget to change to https if needed
|
||||||
@@ -127,7 +131,8 @@ export const config = {
|
|||||||
|
|
||||||
export const app = express();
|
export const app = express();
|
||||||
app.use(cors());
|
app.use(cors());
|
||||||
|
app.use(express.json({ limit: '50mb' }));
|
||||||
|
app.use(express.urlencoded({ limit: '50mb', extended: true }));
|
||||||
app.use(function (req, res, next) {
|
app.use(function (req, res, next) {
|
||||||
// console.log("req ", req.headers);
|
// console.log("req ", req.headers);
|
||||||
// console.log("x-forwarded-for", req.headers["x-forwarded-for"]);
|
// console.log("x-forwarded-for", req.headers["x-forwarded-for"]);
|
||||||
@@ -149,6 +154,16 @@ function getUserIP(request) {
|
|||||||
return request.socket.remoteAddress;
|
return request.socket.remoteAddress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
app.use(function (req, res, next) {
|
||||||
|
const ph_project_api_key = process.env.PH_PROJECT_API_KEY;
|
||||||
|
try {
|
||||||
|
req.posthog = new PostHog(ph_project_api_key);
|
||||||
|
} catch (err) {
|
||||||
|
// console.log('Err', err);
|
||||||
|
req.posthog = '';
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
});
|
||||||
// Serve static assets from the /public folder
|
// Serve static assets from the /public folder
|
||||||
app.use('/public', express.static(path.join(__dirname, '/public')));
|
app.use('/public', express.static(path.join(__dirname, '/public')));
|
||||||
|
|
||||||
@@ -162,6 +177,9 @@ if (!process.env.TESTING) {
|
|||||||
// Mount your custom express app
|
// Mount your custom express app
|
||||||
app.use('/', customRoute);
|
app.use('/', customRoute);
|
||||||
|
|
||||||
|
// Mount v1
|
||||||
|
app.use('/v1', v1);
|
||||||
|
|
||||||
// Parse Server plays nicely with the rest of your web routes
|
// Parse Server plays nicely with the rest of your web routes
|
||||||
app.get('/', function (req, res) {
|
app.get('/', function (req, res) {
|
||||||
// res.statusCode = 200;
|
// res.statusCode = 200;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user