mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-09-05 01:07:39 +02:00
Compare commits
484
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b0440876cd | ||
|
|
6359067839 | ||
|
|
71f36ff383 | ||
|
|
beab4bdfc9 | ||
|
|
c9e6750724 | ||
|
|
06c7355efd | ||
|
|
73f7d1b32f | ||
|
|
fecc87d8c3 | ||
|
|
57c89bf601 | ||
|
|
b10b2617b8 | ||
|
|
eaed35cefd | ||
|
|
44e92344fc | ||
|
|
9aebbde627 | ||
|
|
8ece6ef046 | ||
|
|
7d46e26365 | ||
|
|
e2646bd49f | ||
|
|
6158ac7bc4 | ||
|
|
596340bea9 | ||
|
|
73d1cdee00 | ||
|
|
f88f2c681b | ||
|
|
25ecf7221d | ||
|
|
bb18feaacf | ||
|
|
19324ad0d8 | ||
|
|
8a0f5c460f | ||
|
|
625689b203 | ||
|
|
d919e8514b | ||
|
|
18f183f48b | ||
|
|
69135afe6b | ||
|
|
474a20aa41 | ||
|
|
19478536b3 | ||
|
|
dc29d7a23b | ||
|
|
f5137f54b0 | ||
|
|
42f2122070 | ||
|
|
e4ca29c2c3 | ||
|
|
b8a039bc20 | ||
|
|
331b2d5a40 | ||
|
|
46e390d3c5 | ||
|
|
0b8fb87a29 | ||
|
|
e0249211d2 | ||
|
|
a244c1ba3d | ||
|
|
0a79807cb4 | ||
|
|
b70c473002 | ||
|
|
937390fca0 | ||
|
|
1140318719 | ||
|
|
655371c6d9 | ||
|
|
f07fc78eff | ||
|
|
60034a4ad8 | ||
|
|
ead7bf8841 | ||
|
|
15d2798aab | ||
|
|
58a0af40e6 | ||
|
|
1b79b45b1f | ||
|
|
f831ff3b7a | ||
|
|
f1b6859e9c | ||
|
|
2148f5196c | ||
|
|
5495e569df | ||
|
|
e121df48fe | ||
|
|
39c05b1eb3 | ||
|
|
78892a497d | ||
|
|
ccb08949ff | ||
|
|
74b091b1eb | ||
|
|
264214babd | ||
|
|
38930133f7 | ||
|
|
758cfc8e8d | ||
|
|
2a9ae74c33 | ||
|
|
2f73ba974c | ||
|
|
7c0b744c40 | ||
|
|
010d2dba60 | ||
|
|
c0b45e97ea | ||
|
|
7316fcd18a | ||
|
|
08a2d8a1a4 | ||
|
|
dbd53ba0d2 | ||
|
|
8b0c73c58e | ||
|
|
a292687a8c | ||
|
|
8659c1f4dc | ||
|
|
8ed73ba07b | ||
|
|
a41a31176d | ||
|
|
d6740efaf9 | ||
|
|
aac4ea8e2a | ||
|
|
3fe26cfb07 | ||
|
|
c837df6540 | ||
|
|
03b6b567fc | ||
|
|
09fbd442be | ||
|
|
5f32ca0140 | ||
|
|
46e5aa2815 | ||
|
|
db635f80f8 | ||
|
|
c3a101bc18 | ||
|
|
1af4bd430f | ||
|
|
0459c404f5 | ||
|
|
492f242e4d | ||
|
|
e06d6d5427 | ||
|
|
747c7c549c | ||
|
|
e91d615e68 | ||
|
|
2d527d59b0 | ||
|
|
340947a36d | ||
|
|
91d098ef65 | ||
|
|
d9f8ea8aca | ||
|
|
33bcb55124 | ||
|
|
5a93207dc2 | ||
|
|
fa7c36dbe2 | ||
|
|
faba8b8201 | ||
|
|
3422bc6f9e | ||
|
|
a195b758e6 | ||
|
|
083cd60f2d | ||
|
|
f4b7449262 | ||
|
|
fb68931538 | ||
|
|
be07fcec24 | ||
|
|
f6245cfada | ||
|
|
77cf6de722 | ||
|
|
2b17c26722 | ||
|
|
9862921297 | ||
|
|
685b2ceabd | ||
|
|
786b674db3 | ||
|
|
0b9074611a | ||
|
|
6ebfa038b3 | ||
|
|
4c809bb8d3 | ||
|
|
2dcb7eb7a2 | ||
|
|
743e89038c | ||
|
|
f9f25dc0c3 | ||
|
|
ca75698328 | ||
|
|
f117aeb7c4 | ||
|
|
e36557e844 | ||
|
|
e73b8ed5a5 | ||
|
|
0aaeb28eb7 | ||
|
|
305a5f6fda | ||
|
|
045961be02 | ||
|
|
c612dd3e70 | ||
|
|
ea4527e2dd | ||
|
|
aada33f23f | ||
|
|
1f44582658 | ||
|
|
198a58e524 | ||
|
|
0d78aef414 | ||
|
|
8f99cb0514 | ||
|
|
9a734d9b3c | ||
|
|
7a2c93a3e9 | ||
|
|
a5e1768f7e | ||
|
|
30e27062bd | ||
|
|
97d28a1b48 | ||
|
|
aade153f1c | ||
|
|
df6f5d4b33 | ||
|
|
ab14628769 | ||
|
|
69effb5af0 | ||
|
|
6e9078d64b | ||
|
|
9c73b7818f | ||
|
|
c5246d7a83 | ||
|
|
35511e08ac | ||
|
|
39dc8b226a | ||
|
|
7cb531b183 | ||
|
|
58422b17e5 | ||
|
|
0b2191f97c | ||
|
|
a3e672cde0 | ||
|
|
5a0b10bdff | ||
|
|
dfbf4d8a8f | ||
|
|
4727d622db | ||
|
|
e18e62754f | ||
|
|
bec7af5142 | ||
|
|
0db937eeeb | ||
|
|
c8d26a5ea9 | ||
|
|
1659ebd2ac | ||
|
|
7877d13776 | ||
|
|
2f7cacb933 | ||
|
|
16fcbf8a54 | ||
|
|
719a23c95b | ||
|
|
f4db8af201 | ||
|
|
3549c63cc0 | ||
|
|
b9ed7e5293 | ||
|
|
e34e2c4386 | ||
|
|
a09b2e186f | ||
|
|
cc273261c3 | ||
|
|
26c5c951b6 | ||
|
|
e63178b899 | ||
|
|
eb42f08640 | ||
|
|
2843bfd5c9 | ||
|
|
b2a838dc4e | ||
|
|
c682a6d8eb | ||
|
|
c4a23b4f1b | ||
|
|
12e74533c7 | ||
|
|
24c8f6012f | ||
|
|
b20fb9ea3f | ||
|
|
079e0defc4 | ||
|
|
00ad406e1b | ||
|
|
5c7a9e1d08 | ||
|
|
ea2c981a7f | ||
|
|
ee18d1b317 | ||
|
|
7f6771e56d | ||
|
|
1308b143c4 | ||
|
|
7be2d1f06a | ||
|
|
62021e8870 | ||
|
|
ea5f407786 | ||
|
|
2ecd1823e1 | ||
|
|
1e2eee63df | ||
|
|
8fda979870 | ||
|
|
c59002c375 | ||
|
|
1fe05b402b | ||
|
|
c7d5bef886 | ||
|
|
ca2fc2bd5c | ||
|
|
8bf9fb6299 | ||
|
|
031f24180a | ||
|
|
8663777097 | ||
|
|
342876cd0b | ||
|
|
beaa256e3f | ||
|
|
27ae27187d | ||
|
|
e8d692a707 | ||
|
|
4f71d1bd03 | ||
|
|
8d33d4c44e | ||
|
|
8be55a30c1 | ||
|
|
46a0cfa1eb | ||
|
|
6988bca7f4 | ||
|
|
1a2c0ecbfc | ||
|
|
f2281505a4 | ||
|
|
3ff790c57b | ||
|
|
d5b0fc4e3b | ||
|
|
69129c2d47 | ||
|
|
1486d66b9b | ||
|
|
67323d01f5 | ||
|
|
d0566e6645 | ||
|
|
a3e1fa866e | ||
|
|
6d6b70a888 | ||
|
|
c152d3bf35 | ||
|
|
56a0211b03 | ||
|
|
87fb943ddb | ||
|
|
dacc9bb27e | ||
|
|
43a9fa6820 | ||
|
|
523d7a0896 | ||
|
|
df53e243a5 | ||
|
|
b30d7e3337 | ||
|
|
7a8e2bcd02 | ||
|
|
7aa505f1a3 | ||
|
|
beecd2d26f | ||
|
|
96ecbe97f1 | ||
|
|
7161da4a2f | ||
|
|
462fdfe1be | ||
|
|
dc25133b10 | ||
|
|
bb7552a7bf | ||
|
|
79b4ca053a | ||
|
|
8d91bd218b | ||
|
|
8e0c96589a | ||
|
|
3ac66ea4c5 | ||
|
|
acbff61d9e | ||
|
|
83a1da04d1 | ||
|
|
b86155de49 | ||
|
|
2108ce52ca | ||
|
|
4af96da515 | ||
|
|
eda2085d4b | ||
|
|
6cdcf66e81 | ||
|
|
a701522dca | ||
|
|
ddeb31e530 | ||
|
|
f827ead0b6 | ||
|
|
ae87703a34 | ||
|
|
250c2d768b | ||
|
|
e5e6587490 | ||
|
|
4921152336 | ||
|
|
0c7da91fab | ||
|
|
add07026bc | ||
|
|
7f64418a6c | ||
|
|
e83ceaa815 | ||
|
|
e3dcb99438 | ||
|
|
78821cb5e4 | ||
|
|
548441dded | ||
|
|
7c53ae421c | ||
|
|
a71a867aea | ||
|
|
4d0d2e9a58 | ||
|
|
fcda1e325e | ||
|
|
b41fed0d12 | ||
|
|
ac533d92f6 | ||
|
|
792b48b75a | ||
|
|
175eb921c1 | ||
|
|
4cd959b34b | ||
|
|
0083efb7dc | ||
|
|
18738a56c0 | ||
|
|
3254fc8199 | ||
|
|
4a52299d35 | ||
|
|
7a1247051c | ||
|
|
71d34dd3d3 | ||
|
|
1971ffd221 | ||
|
|
a0af2145f3 | ||
|
|
64bd5cef35 | ||
|
|
4eb511e76e | ||
|
|
6e7fa2a7f8 | ||
|
|
1e3765990a | ||
|
|
2ef608fa33 | ||
|
|
479878a59d | ||
|
|
475eba8b7e | ||
|
|
c0ddec8896 | ||
|
|
38cd32b8c8 | ||
|
|
9a6ee0397b | ||
|
|
57f7bf6375 | ||
|
|
93f3cd7868 | ||
|
|
157b5a891e | ||
|
|
fcd10703a8 | ||
|
|
d17a8524c5 | ||
|
|
2d42013fed | ||
|
|
5288fe1512 | ||
|
|
3988361471 | ||
|
|
62204bda9d | ||
|
|
1ac4418d41 | ||
|
|
23914274b5 | ||
|
|
a668aa11db | ||
|
|
0aefb792dc | ||
|
|
54de1c1f5a | ||
|
|
f53f125e3e | ||
|
|
0269647d75 | ||
|
|
5fc05e7faa | ||
|
|
8c3caed1fb | ||
|
|
fbcb1fc47a | ||
|
|
fdd6e64060 | ||
|
|
3dd88f2453 | ||
|
|
d06bfefc40 | ||
|
|
30236206bc | ||
|
|
24b0231495 | ||
|
|
57946fea6d | ||
|
|
187990ce05 | ||
|
|
8cfcecf440 | ||
|
|
041d290f0f | ||
|
|
291791cb08 | ||
|
|
3d081cb7a0 | ||
|
|
0201159b31 | ||
|
|
4caaa203bb | ||
|
|
783bd63da0 | ||
|
|
82a187fe46 | ||
|
|
8ebf96f1e1 | ||
|
|
b25152a5e8 | ||
|
|
b1b488a8a0 | ||
|
|
8a76b92b5f | ||
|
|
724f3a9724 | ||
|
|
388d9cb29e | ||
|
|
6b463c6f1a | ||
|
|
4afca77d1e | ||
|
|
53d8e60ec3 | ||
|
|
23c22b79d8 | ||
|
|
4943517145 | ||
|
|
c71398c6e3 | ||
|
|
dfaa278636 | ||
|
|
139c3b42f5 | ||
|
|
d89c28334e | ||
|
|
7638bcad02 | ||
|
|
63090b82e3 | ||
|
|
63b7cb8188 | ||
|
|
ad9dda27ba | ||
|
|
3f3137874a | ||
|
|
440eaaeb26 | ||
|
|
2d6d8ce2be | ||
|
|
229d0731b8 | ||
|
|
418cd92f80 | ||
|
|
6e4ed4bc09 | ||
|
|
51b417aa7e | ||
|
|
0fc895ad17 | ||
|
|
2dea2172bc | ||
|
|
fcd3c15ec7 | ||
|
|
4cd9b08698 | ||
|
|
b21b641e2a | ||
|
|
af9c8d71c6 | ||
|
|
8bd1891fcc | ||
|
|
e5a62f17a5 | ||
|
|
db383d0e88 | ||
|
|
e519d86cad | ||
|
|
bf68656d05 | ||
|
|
69913151b6 | ||
|
|
46312eb138 | ||
|
|
1a13936681 | ||
|
|
251ea22f5f | ||
|
|
8f8808ce1c | ||
|
|
bb207b953c | ||
|
|
2984d6876d | ||
|
|
5d2b131c99 | ||
|
|
43c9b4db9c | ||
|
|
ce9e27e116 | ||
|
|
e25b7deaf3 | ||
|
|
81078073cb | ||
|
|
e6e5db95ba | ||
|
|
2cf3af242b | ||
|
|
ed664359a6 | ||
|
|
4a5e855b76 | ||
|
|
1e60863a40 | ||
|
|
10ad3ee5bd | ||
|
|
32c5a0a77a | ||
|
|
b6651f12e2 | ||
|
|
15ad35bf76 | ||
|
|
9a986dd000 | ||
|
|
714146f616 | ||
|
|
96d2b4e9fd | ||
|
|
122c42153e | ||
|
|
32c4ee16a0 | ||
|
|
53cdb411b7 | ||
|
|
0708e0ae1c | ||
|
|
95db24f8ed | ||
|
|
bcdd2e7feb | ||
|
|
4adfa9f830 | ||
|
|
dcc8f99991 | ||
|
|
3bdb56462d | ||
|
|
b8bffe97b5 | ||
|
|
af817b6bc3 | ||
|
|
8e1cbc65d7 | ||
|
|
e38a1f9c1a | ||
|
|
50c3133dae | ||
|
|
b1e2a74ad5 | ||
|
|
7e9dc8cd65 | ||
|
|
7d87cc27fc | ||
|
|
25714cde90 | ||
|
|
8241482c19 | ||
|
|
3044e010f6 | ||
|
|
9743b933da | ||
|
|
1ce8ec4758 | ||
|
|
cb99b7646c | ||
|
|
5af7279c67 | ||
|
|
224d9f6787 | ||
|
|
ed7df13f9b | ||
|
|
2c5f6631d7 | ||
|
|
a32b88f6b0 | ||
|
|
88cb271332 | ||
|
|
e18d1a7a16 | ||
|
|
b2dfc6f32c | ||
|
|
a64e30a94c | ||
|
|
6d5b28f75f | ||
|
|
c7decaec02 | ||
|
|
8600437c5a | ||
|
|
ece3f42ab3 | ||
|
|
32be8dfe3a | ||
|
|
2aebceda24 | ||
|
|
85b463f0e0 | ||
|
|
f6c8d4f51a | ||
|
|
b84c1c8821 | ||
|
|
a3334fdf2d | ||
|
|
d6b12b75b0 | ||
|
|
a9e623391b | ||
|
|
fd34ba778c | ||
|
|
d00d31eaf2 | ||
|
|
016a0f62bd | ||
|
|
cf52292f7c | ||
|
|
8b26c94ada | ||
|
|
582b10b5ee | ||
|
|
b51e152d10 | ||
|
|
5f197f5f9f | ||
|
|
5a3ee25dfd | ||
|
|
7050138e5e | ||
|
|
049d268314 | ||
|
|
6f71afb418 | ||
|
|
7e65692b5a | ||
|
|
bd1f44479b | ||
|
|
c0935001ce | ||
|
|
f65ab5dfea | ||
|
|
dbb7fd576f | ||
|
|
be5cc6126e | ||
|
|
6a4eb24630 | ||
|
|
61a8bc519f | ||
|
|
b15f3c0333 | ||
|
|
5830fda578 | ||
|
|
102f837263 | ||
|
|
5cee42a76e | ||
|
|
8fc7cc924a | ||
|
|
80170b814f | ||
|
|
91fcb71bc3 | ||
|
|
eb13d91bbb | ||
|
|
a464437b3a | ||
|
|
3a67dc9b08 | ||
|
|
a6ff20a657 | ||
|
|
4bf380edf8 | ||
|
|
ab3148b705 | ||
|
|
2ffd1ebf2a | ||
|
|
d1155bc8ef | ||
|
|
33ff706803 | ||
|
|
7fdd819722 | ||
|
|
aeaea23098 | ||
|
|
ff7f45f055 | ||
|
|
40665684a8 | ||
|
|
861f822151 | ||
|
|
62541f1450 | ||
|
|
a356e77f54 | ||
|
|
74abeff8d9 | ||
|
|
78dfaccd38 | ||
|
|
757b72161a | ||
|
|
c2065bf752 | ||
|
|
5608dae6e3 | ||
|
|
2288880eba | ||
|
|
ba7d0a9723 | ||
|
|
1ac8800b40 | ||
|
|
bb7827b762 | ||
|
|
8caa0275ab | ||
|
|
7e1d0f8a49 | ||
|
|
f7f5c2de37 | ||
|
|
f75710c836 | ||
|
|
a02cc89e5d | ||
|
|
f54a51c546 | ||
|
|
b12eb87b38 | ||
|
|
93f7408847 |
+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=
|
MAILGUN_API_KEY=XXXXX
|
||||||
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.yourhost.com
|
SMTP_HOST=
|
||||||
SMTP_PORT=443
|
SMTP_PORT=
|
||||||
SMTP_USER_EMAIL=mailer@yourdomain.com
|
SMTP_USER_EMAIL=
|
||||||
SMTP_PASS=password
|
SMTP_PASS=
|
||||||
|
|
||||||
|
|
||||||
# Base64 encoded PFX or p12 document signing certificate file *********************************************************************************************************************
|
# Base64 encoded PFX or p12 document signing certificate file *********************************************************************************************************************
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
name: Deploy to GitHub Pages
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- feat-docs
|
||||||
|
# Review gh actions docs if you want to further define triggers, paths, etc
|
||||||
|
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
name: Deploy to GitHub Pages
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
cache: npm
|
||||||
|
- name: Install dependencies
|
||||||
|
working-directory: ./docs
|
||||||
|
run: npm ci
|
||||||
|
- name: Clean api-docs
|
||||||
|
working-directory: ./docs
|
||||||
|
run: npm run docusaurus clean-api-docs all
|
||||||
|
- name: Build api-docs
|
||||||
|
working-directory: ./docs
|
||||||
|
run: npm run docusaurus gen-api-docs all
|
||||||
|
- name: Build website
|
||||||
|
working-directory: ./docs
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
# Popular action to deploy to GitHub Pages:
|
||||||
|
# Docs: https://github.com/peaceiris/actions-gh-pages#%EF%B8%8F-docusaurus
|
||||||
|
- name: Deploy to GitHub Pages
|
||||||
|
uses: peaceiris/actions-gh-pages@v3
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
# Build output to publish to the `gh-pages` branch:
|
||||||
|
publish_dir: ./docs/build
|
||||||
|
# The following lines assign commit authorship to the official
|
||||||
|
# GH-Actions bot for deploys to `gh-pages` branch:
|
||||||
|
# https://github.com/actions/checkout/issues/13#issuecomment-724415212
|
||||||
|
# The GH actions bot is used by default if you didn't specify the two fields.
|
||||||
|
# You can swap them out with your own user credentials.
|
||||||
|
user_name: github-actions[bot]
|
||||||
|
user_email: 41898282+github-actions[bot]@users.noreply.github.com
|
||||||
@@ -38,11 +38,10 @@
|
|||||||
7. [Acknowledgments](#acknowledgments)
|
7. [Acknowledgments](#acknowledgments)
|
||||||
|
|
||||||
---
|
---
|
||||||
Please star ⭐ the repo to support us! 😀
|
|
||||||
|
|
||||||
### Introduction
|
### Introduction
|
||||||
|
|
||||||
Welcome to OpenSign, the premier open-source docusign alternative - document e-signing solution designed to provide a secure, reliable, and free alternative to commercial platforms like DocuSign, PandaDoc, SignNow, Adobe Sign, Smartwaiver, SignRequest, HelloSign & Zoho sign. Developed under the OpenSignLabs organization, our mission is to democratize the e-signing process, making it accessible and straightforward for everyone.
|
Welcome to OpenSign, 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.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ 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,6 +9,9 @@
|
|||||||
"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",
|
||||||
@@ -36,6 +39,7 @@
|
|||||||
"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"
|
||||||
@@ -3917,6 +3921,85 @@
|
|||||||
"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",
|
||||||
@@ -6882,6 +6965,27 @@
|
|||||||
"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",
|
||||||
@@ -7572,6 +7676,14 @@
|
|||||||
"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",
|
||||||
@@ -13306,6 +13418,27 @@
|
|||||||
"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",
|
||||||
@@ -13801,11 +13934,21 @@
|
|||||||
"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",
|
||||||
@@ -14167,6 +14310,17 @@
|
|||||||
"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",
|
||||||
@@ -18048,6 +18202,26 @@
|
|||||||
"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",
|
||||||
@@ -20249,6 +20423,38 @@
|
|||||||
"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,6 +4,9 @@
|
|||||||
"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",
|
||||||
@@ -31,6 +34,7 @@
|
|||||||
"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.1.1-beta
|
v1.0.5-beta
|
||||||
|
|||||||
+75
-25
@@ -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 Subscriptions from "./routes/PlanSubscriptions";
|
import PlanSubscriptions 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,10 +15,6 @@ 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);
|
||||||
@@ -62,34 +58,88 @@ function App() {
|
|||||||
) : (
|
) : (
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route element={<ValidateRoute />}>
|
<Route exact path="/" element={<Login />} />
|
||||||
<Route exact path="/" element={<Login />} />
|
<Route exact path="/signup" element={<Signup />} />
|
||||||
<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 exact path="/subscription" element={<Subscriptions />} />
|
<Route
|
||||||
|
exact
|
||||||
|
path="/subscription"
|
||||||
|
element={<PlanSubscriptions />}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<Route element={<HomeLayout />}>
|
<Route
|
||||||
<Route path="/changepassword" element={<ChangePassword />} />
|
exact
|
||||||
<Route path="/mf/:remoteApp/*" element={<Microapp />} />
|
path="/changepassword"
|
||||||
<Route path="/asmf/:remoteApp/*" element={<Microapp />} />
|
element={
|
||||||
<Route path="/rpmf/:remoteApp/*" element={<ReportMicroapp />} />
|
<HomeLayout>
|
||||||
<Route path="/form/:id" element={<Form />} />
|
<ChangePassword />
|
||||||
<Route path="/report/:id" element={<Report />} />
|
</HomeLayout>
|
||||||
<Route path="/dashboard/:id" element={<Dashboard />} />
|
}
|
||||||
<Route path="/profile" element={<UserProfile />} />
|
/>
|
||||||
<Route path="/generatetoken" element={<GenerateToken />} />
|
<Route
|
||||||
<Route path="/webhook" element={<Webhook />} />
|
path="/mf/:remoteApp/*"
|
||||||
</Route>
|
element={
|
||||||
|
<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>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,283 +0,0 @@
|
|||||||
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,7 +1,6 @@
|
|||||||
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("");
|
||||||
@@ -47,7 +46,6 @@ 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);
|
||||||
@@ -107,18 +105,13 @@ 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));
|
||||||
if (props.details) {
|
props.details({
|
||||||
props.details({
|
value: parseData[props.valueKey],
|
||||||
value: parseData[props.valueKey],
|
label: parseData[props.displayKey]
|
||||||
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
|
||||||
@@ -165,18 +158,13 @@ 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));
|
||||||
if (props.details) {
|
props.details({
|
||||||
props.details({
|
value: parseData[props.valueKey],
|
||||||
value: parseData[props.valueKey],
|
label: parseData[props.displayKey]
|
||||||
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);
|
||||||
@@ -294,16 +282,14 @@ const AppendFormInForm = (props) => {
|
|||||||
<div className="mt-4 flex justify-start">
|
<div className="mt-4 flex justify-start">
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
style={{ backgroundColor: modalSubmitBtnColor }}
|
className="bg-[#1ab6ce] text-sm text-white px-4 py-2 rounded shadow focus:outline-none"
|
||||||
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()}
|
||||||
style={{ backgroundColor: modalCancelBtnColor }}
|
className="bg-[#188ae2] text-sm text-white px-4 py-2 rounded ml-2 shadow focus:outline-none"
|
||||||
className="px-4 py-1.5 text-black border-[1px] border-[#ccc] shadow-md rounded focus:outline-none"
|
|
||||||
>
|
>
|
||||||
Reset
|
Reset
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
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("");
|
||||||
@@ -38,18 +37,12 @@ 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()}
|
||||||
<span onClick={openUrl} className="hover:underline cursor-pointer">
|
{appName} ( version: {version ? version : `${Package.version} `})
|
||||||
{appName} ( version: {version ? version : `${Package.version} `})
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
className={`${
|
className={`${
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ 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();
|
||||||
@@ -119,12 +118,6 @@ 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_User",
|
role: "contracts_Admin",
|
||||||
company: userDetails.Company
|
company: userDetails.Company
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ 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
|
||||||
@@ -150,7 +148,7 @@ const GoogleSignInBtn = ({
|
|||||||
email: userDetails.Email,
|
email: userDetails.Email,
|
||||||
// "passsword":userDetails.Phone,
|
// "passsword":userDetails.Phone,
|
||||||
phone: userDetails.Phone,
|
phone: userDetails.Phone,
|
||||||
role: "contracts_User",
|
role: "contracts_Admin",
|
||||||
company: userDetails.Company,
|
company: userDetails.Company,
|
||||||
jobTitle: userDetails.Destination
|
jobTitle: userDetails.Destination
|
||||||
}
|
}
|
||||||
@@ -233,94 +231,118 @@ 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">
|
|
||||||
<form className="px-4 py-3">
|
{isModal && (
|
||||||
<div className="mb-3">
|
<div
|
||||||
<label
|
className="modal fade show"
|
||||||
htmlFor="Phone"
|
id="exampleModal"
|
||||||
style={{ display: "flex" }}
|
tabIndex="-1"
|
||||||
className="block text-xs text-gray-700 font-semibold"
|
role="dialog"
|
||||||
>
|
style={{ display: "block", zIndex: 1 }}
|
||||||
Phone <span style={{ fontSize: 13, color: "red" }}>*</span>
|
>
|
||||||
</label>
|
<div className="modal-dialog" role="document">
|
||||||
<input
|
<div className="modal-content">
|
||||||
type="tel"
|
<div className="modal-header">
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
<h5 className="modal-title">Sign up form</h5>
|
||||||
id="Phone"
|
<span>
|
||||||
value={userDetails.Phone}
|
<span></span>
|
||||||
onChange={(e) =>
|
</span>
|
||||||
setUserDetails({
|
</div>
|
||||||
...userDetails,
|
<div className="modal-body">
|
||||||
Phone: e.target.value
|
<form>
|
||||||
})
|
<div className="form-group">
|
||||||
}
|
<label
|
||||||
required
|
htmlFor="Phone"
|
||||||
/>
|
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 className="mb-3">
|
</div>
|
||||||
<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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,391 @@
|
|||||||
|
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;
|
||||||
@@ -0,0 +1,237 @@
|
|||||||
|
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;
|
||||||
@@ -0,0 +1,895 @@
|
|||||||
|
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);
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
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,8 +41,7 @@ export default function DropboxChooser({ children, onSuccess, onCancel }) {
|
|||||||
[onSuccess, onCancel]
|
[onSuccess, onCancel]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleChoose = useCallback((e) => {
|
const handleChoose = useCallback(() => {
|
||||||
e.preventDefault()
|
|
||||||
if (window.Dropbox) {
|
if (window.Dropbox) {
|
||||||
window.Dropbox.choose(options);
|
window.Dropbox.choose(options);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,308 @@
|
|||||||
|
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;
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
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;
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
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;
|
||||||
@@ -0,0 +1,482 @@
|
|||||||
|
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);
|
||||||
@@ -0,0 +1,709 @@
|
|||||||
|
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);
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
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;
|
||||||
@@ -1,261 +0,0 @@
|
|||||||
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;
|
|
||||||
@@ -1,189 +0,0 @@
|
|||||||
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;
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
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;
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
export const openInNewTab = (url) => {
|
|
||||||
window.open(url, "_blank", "noopener,noreferrer");
|
|
||||||
};
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
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";
|
|
||||||
@@ -5,14 +5,3 @@
|
|||||||
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,26 +1,584 @@
|
|||||||
import { documentCls, templateCls } from "../constant/const";
|
import Parse from "parse";
|
||||||
export const formJson = {
|
export const formJson = (id) => {
|
||||||
|
let formData;
|
||||||
//json form for signYourself
|
//json form for signYourself
|
||||||
sHAnZphf69: {
|
if (id === "sHAnZphf69") {
|
||||||
title: "Sign Yourself",
|
formData = {
|
||||||
redirectRoute: "signaturePdf",
|
jsonSchema: {
|
||||||
msgVar: "Document",
|
title: "Sign Yourself",
|
||||||
Cls: documentCls
|
description: "",
|
||||||
},
|
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=="
|
||||||
|
};
|
||||||
|
|
||||||
//json form for request signatures
|
return formData;
|
||||||
"8mZzFxbG1z": {
|
}
|
||||||
title: "Request Signatures",
|
//json form for request signature
|
||||||
msgVar: "Document",
|
else if (id === "8mZzFxbG1z") {
|
||||||
redirectRoute: "placeHolderSign",
|
const user = Parse.User.current();
|
||||||
Cls: documentCls,
|
const userPtr = JSON.stringify({
|
||||||
signers: true
|
__type: "Pointer",
|
||||||
},
|
className: "_User",
|
||||||
//json form for template
|
objectId: user.id
|
||||||
template: {
|
});
|
||||||
title: "New Template",
|
formData = {
|
||||||
redirectRoute: "template",
|
jsonSchema: {
|
||||||
msgVar: "Template",
|
title: "New Document",
|
||||||
Cls: templateCls
|
description: "",
|
||||||
|
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,9 +1,7 @@
|
|||||||
export default function reportJson(id) {
|
export default function reportJson(id) {
|
||||||
// console.log("json ", json);
|
// console.log("json ", json);
|
||||||
const head = ["Sr.No", "Title", "Note", "Folder", "File", "Owner", "Signers"];
|
const head = ["Sr.No", "Name", "Note", "Folder", "File", "Owner", "Signers"];
|
||||||
const contactbook = ["Sr.No", "Title", "Email", "Phone"];
|
const contactbook = ["Sr.No", "Name", "Email", "Phone"];
|
||||||
const dashboardReportHead = ["Title", "File", "Owner", "Signers"];
|
|
||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
// draft documents report
|
// draft documents report
|
||||||
case "ByHuevtCFY":
|
case "ByHuevtCFY":
|
||||||
@@ -105,7 +103,7 @@ export default function reportJson(id) {
|
|||||||
case "d9k3UfYHBc":
|
case "d9k3UfYHBc":
|
||||||
return {
|
return {
|
||||||
reportName: "Recently sent for signatures",
|
reportName: "Recently sent for signatures",
|
||||||
heading: dashboardReportHead,
|
heading: head,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
btnLabel: "View",
|
btnLabel: "View",
|
||||||
@@ -121,7 +119,7 @@ export default function reportJson(id) {
|
|||||||
case "5Go51Q7T8r":
|
case "5Go51Q7T8r":
|
||||||
return {
|
return {
|
||||||
reportName: "Recent signature requests",
|
reportName: "Recent signature requests",
|
||||||
heading: dashboardReportHead,
|
heading: head,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
btnLabel: "Sign",
|
btnLabel: "Sign",
|
||||||
@@ -137,7 +135,7 @@ export default function reportJson(id) {
|
|||||||
case "kC5mfynCi4":
|
case "kC5mfynCi4":
|
||||||
return {
|
return {
|
||||||
reportName: "Drafts",
|
reportName: "Drafts",
|
||||||
heading: ["Title", "Note", "Folder", "File", "Owner", "Signers"],
|
heading: head,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
btnLabel: "sign",
|
btnLabel: "sign",
|
||||||
@@ -161,31 +159,6 @@ 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 <span style='background-color: yellow;'>'FREEBETA'</span> to get this for free(First 1000 users)",
|
"subtitle": "Use code 'FREEBETA' 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 OpenSign™ Drive",
|
"Unlimited Secure Doc Storage with OpenSignDrive",
|
||||||
"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,37 +7,10 @@ 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";
|
||||||
import ModalUi from "../primitives/ModalUi";
|
const HomeLayout = ({ children }) => {
|
||||||
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);
|
||||||
@@ -46,7 +19,7 @@ const HomeLayout = () => {
|
|||||||
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) {
|
||||||
@@ -55,7 +28,9 @@ const HomeLayout = () => {
|
|||||||
}, [width]);
|
}, [width]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (localStorage.getItem("domain") === "sign" && arr && arr.length > 0) {
|
||||||
|
handleDynamicSteps();
|
||||||
|
} else if (
|
||||||
localStorage.getItem("domain") === "contracts" &&
|
localStorage.getItem("domain") === "contracts" &&
|
||||||
arr &&
|
arr &&
|
||||||
arr.length > 0
|
arr.length > 0
|
||||||
@@ -178,80 +153,32 @@ const HomeLayout = () => {
|
|||||||
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>
|
||||||
{isUserValid ? (
|
<div className="flex md:flex-row flex-col z-50">
|
||||||
<>
|
<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">{<Outlet />}</div>
|
<div className="bg-[#eef1f5] p-3">{children}</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>
|
||||||
</ModalUi>
|
</div>
|
||||||
)}
|
</div>
|
||||||
|
<Tour
|
||||||
|
onRequestClose={closeTour}
|
||||||
|
steps={tourConfigs}
|
||||||
|
isOpen={isTour}
|
||||||
|
closeWithMask={false}
|
||||||
|
disableKeyboardNavigation={["esc"]}
|
||||||
|
// disableInteraction={true}
|
||||||
|
scrollOffset={-100}
|
||||||
|
rounded={5}
|
||||||
|
showCloseButton={isCloseBtn}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
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,9 +3,6 @@ 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,
|
||||||
@@ -14,19 +11,13 @@ 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(() => {
|
||||||
@@ -64,128 +55,39 @@ const ReportTable = ({
|
|||||||
}, [isMoreDocs, pageNumbers, currentPage, setIsNextRecord]);
|
}, [isMoreDocs, pageNumbers, currentPage, setIsNextRecord]);
|
||||||
|
|
||||||
// `handlemicroapp` is used to open microapp
|
// `handlemicroapp` is used to open microapp
|
||||||
const handlemicroapp = async (item, url, btnLabel) => {
|
const handlemicroapp = (item, url) => {
|
||||||
if (ReportName === "Templates") {
|
localStorage.removeItem("rowlevel");
|
||||||
if (btnLabel === "Edit") {
|
navigate("/rpmf/" + url);
|
||||||
navigate(`/asmf/${url}/${item.objectId}`);
|
localStorage.setItem("rowlevel", JSON.stringify(item));
|
||||||
} 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") {
|
||||||
setIsDeleteModal({ [item.objectId]: true });
|
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({});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -199,44 +101,6 @@ 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 && (
|
||||||
@@ -251,23 +115,7 @@ const ReportTable = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="flex flex-row items-center justify-between my-2 mx-3 text-[20px] md:text-[23px]">
|
<h2 className="text-[23px] font-light my-2">{ReportName}</h2>
|
||||||
<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]">
|
||||||
@@ -287,13 +135,11 @@ 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}>
|
||||||
{heading.includes("Sr.No") && (
|
<td className="px-4 py-2">{index + 1}</td>
|
||||||
<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-3 py-2 text-white">
|
<td className="px-4 py-2 flex flex-col justify-center items-center gap-2 text-white">
|
||||||
{actions?.length > 0 &&
|
{actions?.length > 0 &&
|
||||||
actions.map((act, index) => (
|
actions.map((act, index) => (
|
||||||
<button
|
<button
|
||||||
@@ -303,7 +149,7 @@ const ReportTable = ({
|
|||||||
? handlemicroapp(item, act.redirectUrl)
|
? handlemicroapp(item, act.redirectUrl)
|
||||||
: handlebtn(item)
|
: handlebtn(item)
|
||||||
}
|
}
|
||||||
className={`mb-1 flex justify-center items-center gap-1 px-2 py-1 rounded shadow`}
|
className={`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
|
||||||
@@ -329,54 +175,16 @@ 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}>
|
||||||
{heading.includes("Sr.No") && (
|
<td className="px-4 py-2">{index + 1}</td>
|
||||||
<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">{item?.Note || "-"}</td>
|
||||||
<td className="px-4 py-2 font-semibold w-56">
|
<td className="px-4 py-2">
|
||||||
{item?.Name}{" "}
|
{item?.Folder?.Name || "OpenSignDrive"}
|
||||||
</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"
|
||||||
@@ -394,21 +202,17 @@ 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-3 py-2 text-white">
|
<td className="px-4 py-2 flex flex-col justify-center items-center gap-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(
|
? handlemicroapp(item, act.redirectUrl)
|
||||||
item,
|
|
||||||
act.redirectUrl,
|
|
||||||
act.btnLabel
|
|
||||||
)
|
|
||||||
: handlebtn(item)
|
: handlebtn(item)
|
||||||
}
|
}
|
||||||
className={`mb-1 flex justify-center items-center gap-1 px-2 py-1 rounded shadow`}
|
className={`flex justify-center items-center w-full gap-1 px-2 py-1 rounded shadow`}
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: act.btnColor
|
backgroundColor: act.btnColor
|
||||||
? act.btnColor
|
? act.btnColor
|
||||||
@@ -420,9 +224,7 @@ const ReportTable = ({
|
|||||||
{act?.btnIcon && (
|
{act?.btnIcon && (
|
||||||
<i
|
<i
|
||||||
className={
|
className={
|
||||||
actLoader[
|
actLoader[item.objectId]
|
||||||
`${item.objectId}_${act.btnLabel}`
|
|
||||||
]
|
|
||||||
? "fa-solid fa-spinner fa-spin-pulse"
|
? "fa-solid fa-spinner fa-spin-pulse"
|
||||||
: act.btnIcon
|
: act.btnIcon
|
||||||
}
|
}
|
||||||
@@ -433,6 +235,7 @@ const ReportTable = ({
|
|||||||
{act?.btnLabel ? act.btnLabel : "view"}
|
{act?.btnLabel ? act.btnLabel : "view"}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
// )
|
||||||
))}
|
))}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -490,26 +293,6 @@ 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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
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;
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
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;
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
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;
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
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,7 +124,8 @@ 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) {
|
||||||
@@ -214,10 +215,95 @@ 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, state: { from: location } });
|
navigate("/", { replace: true });
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
}, [id]);
|
}, [id]);
|
||||||
|
|||||||
+1287
-377
File diff suppressed because it is too large
Load Diff
@@ -1,184 +0,0 @@
|
|||||||
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,
|
||||||
height: "100%",
|
minHeight: "70vh"
|
||||||
minHeight: "100vh"
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{RemoteComponent && <RemoteComponent />}
|
{RemoteComponent && <RemoteComponent />}
|
||||||
|
|||||||
@@ -8,15 +8,12 @@ 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, useLocation } from "react-router-dom";
|
import { NavLink, useNavigate } 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: "",
|
||||||
@@ -135,9 +132,6 @@ 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")}_`,
|
||||||
@@ -266,8 +260,9 @@ function Login(props) {
|
|||||||
localStorage.removeItem(
|
localStorage.removeItem(
|
||||||
"userDetails"
|
"userDetails"
|
||||||
);
|
);
|
||||||
// Redirect to the appropriate URL after successful login
|
navigate(
|
||||||
navigate(redirectUrl);
|
`/${element.pageType}/${element.pageId}`
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
navigate(`/subscription`, {
|
navigate(`/subscription`, {
|
||||||
replace: true
|
replace: true
|
||||||
@@ -279,8 +274,9 @@ function Login(props) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Redirect to the appropriate URL after successful login
|
navigate(
|
||||||
navigate(redirectUrl);
|
`/${element.pageType}/${element.pageId}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -317,8 +313,9 @@ function Login(props) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Redirect to the appropriate URL after successful login
|
navigate(
|
||||||
navigate(redirectUrl);
|
`/${element.pageType}/${element.pageId}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -465,9 +462,6 @@ 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")}_`,
|
||||||
@@ -575,7 +569,9 @@ function Login(props) {
|
|||||||
if (billingDate) {
|
if (billingDate) {
|
||||||
if (billingDate > new Date()) {
|
if (billingDate > new Date()) {
|
||||||
localStorage.removeItem("userDetails");
|
localStorage.removeItem("userDetails");
|
||||||
navigate(redirectUrl);
|
navigate(
|
||||||
|
`/${element.pageType}/${element.pageId}`
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
navigate(`/subscription`, {
|
navigate(`/subscription`, {
|
||||||
replace: true
|
replace: true
|
||||||
@@ -585,7 +581,9 @@ function Login(props) {
|
|||||||
navigate(`/subscription`, { replace: true });
|
navigate(`/subscription`, { replace: true });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
navigate(redirectUrl);
|
navigate(
|
||||||
|
`/${element.pageType}/${element.pageId}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -601,8 +599,9 @@ function Login(props) {
|
|||||||
if (billingDate) {
|
if (billingDate) {
|
||||||
if (billingDate > new Date()) {
|
if (billingDate > new Date()) {
|
||||||
localStorage.removeItem("userDetails");
|
localStorage.removeItem("userDetails");
|
||||||
// Redirect to the appropriate URL after successful login
|
navigate(
|
||||||
navigate(redirectUrl);
|
`/${element.pageType}/${element.pageId}`
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
navigate(`/subscription`, { replace: true });
|
navigate(`/subscription`, { replace: true });
|
||||||
}
|
}
|
||||||
@@ -610,7 +609,9 @@ function Login(props) {
|
|||||||
navigate(`/subscription`, { replace: true });
|
navigate(`/subscription`, { replace: true });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
navigate(redirectUrl);
|
navigate(
|
||||||
|
`/${element.pageType}/${element.pageId}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1133,76 +1134,100 @@ function Login(props) {
|
|||||||
{state.toastDescription}
|
{state.toastDescription}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ModalUi isOpen={isModal} title="Additional Info" showClose={false}>
|
{isModal && (
|
||||||
<form className="px-4 py-3">
|
<div
|
||||||
<div className="mb-3">
|
className="modal fade show"
|
||||||
<label
|
id="exampleModal"
|
||||||
htmlFor="Company"
|
tabIndex="-1"
|
||||||
style={{ display: "flex" }}
|
role="dialog"
|
||||||
className="block text-xs text-gray-700 font-semibold"
|
style={{
|
||||||
>
|
display: "block",
|
||||||
Company <span style={{ fontSize: 13, color: "red" }}>*</span>
|
zIndex: 1,
|
||||||
</label>
|
backgroundColor: "rgba(0,0,0,0.5)"
|
||||||
<input
|
}}
|
||||||
type="text"
|
>
|
||||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
<div className="modal-dialog" role="document">
|
||||||
id="Company"
|
<div className="modal-content">
|
||||||
value={userDetails.Company}
|
<div className="modal-header">
|
||||||
onChange={(e) =>
|
<h5 className="modal-title font-semibold">
|
||||||
setUserDetails({
|
Additional Info
|
||||||
...userDetails,
|
</h5>
|
||||||
Company: e.target.value
|
<span>
|
||||||
})
|
<span></span>
|
||||||
}
|
</span>
|
||||||
required
|
</div>
|
||||||
/>
|
<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 className="mb-3">
|
</div>
|
||||||
<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 = ({ prefix }) => {
|
const PageNotFound = () => {
|
||||||
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,9 +10,7 @@ const PageNotFound = ({ prefix }) => {
|
|||||||
<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">
|
<p className="text-[30px] lg:text-[50px] text-black">Page Not Found</p>
|
||||||
{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, useLocation } from "react-router-dom";
|
import { useNavigate } 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,7 +13,6 @@ 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({
|
||||||
@@ -75,8 +74,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 updateQuery = new Parse.Object(extClass);
|
const checkUser = new Parse.Query(extClass);
|
||||||
updateQuery.id = res.id;
|
const updateQuery = await checkUser.get(res.id);
|
||||||
updateQuery.set(
|
updateQuery.set(
|
||||||
"Next_billing_date",
|
"Next_billing_date",
|
||||||
new Date(zohoRes.data.result.nextBillingDate)
|
new Date(zohoRes.data.result.nextBillingDate)
|
||||||
@@ -188,7 +187,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("/", { replace: true });
|
navigate("/");
|
||||||
} else {
|
} else {
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
alert("Something went wrong, please try again later!");
|
alert("Something went wrong, please try again later!");
|
||||||
@@ -352,7 +351,7 @@ const PgSignUp = (props) => {
|
|||||||
element.pageType
|
element.pageType
|
||||||
);
|
);
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
navigate("/", { replace: true });
|
navigate("/");
|
||||||
} else {
|
} else {
|
||||||
extendedInfo.forEach((x) => {
|
extendedInfo.forEach((x) => {
|
||||||
if (x.TenantId) {
|
if (x.TenantId) {
|
||||||
@@ -390,12 +389,9 @@ const PgSignUp = (props) => {
|
|||||||
);
|
);
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
alert("Registered user successfully");
|
alert("Registered user successfully");
|
||||||
const redirectUrl =
|
navigate(
|
||||||
location?.state?.from ||
|
`/${element.pageType}/${element.pageId}`
|
||||||
`/${element.pageType}/${element.pageId}`;
|
);
|
||||||
|
|
||||||
// Redirect to the appropriate URL after successful login
|
|
||||||
navigate(redirectUrl);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alert("Registered user successfully");
|
alert("Registered user successfully");
|
||||||
@@ -406,12 +402,7 @@ const PgSignUp = (props) => {
|
|||||||
);
|
);
|
||||||
localStorage.setItem("pageType", element.pageType);
|
localStorage.setItem("pageType", element.pageType);
|
||||||
setIsLoader(false);
|
setIsLoader(false);
|
||||||
const redirectUrl =
|
navigate(`/${element.pageType}/${element.pageId}`);
|
||||||
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("/", { replace: true });
|
navigate("/");
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
}, []);
|
}, []);
|
||||||
@@ -78,6 +78,31 @@ 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) => (
|
||||||
@@ -104,27 +129,11 @@ 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
|
<p>{item.subtitle}</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,7 +5,6 @@ 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();
|
||||||
@@ -16,7 +15,6 @@ 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;
|
||||||
|
|
||||||
@@ -52,7 +50,6 @@ 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;
|
||||||
@@ -157,10 +154,15 @@ const Report = () => {
|
|||||||
setIsNextRecord={setIsNextRecord}
|
setIsNextRecord={setIsNextRecord}
|
||||||
isMoreDocs={isMoreDocs}
|
isMoreDocs={isMoreDocs}
|
||||||
docPerPage={docPerPage}
|
docPerPage={docPerPage}
|
||||||
form={form}
|
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<PageNotFound prefix={"Report"} />
|
<div className="flex items-center justify-center h-screen w-full bg-white rounded">
|
||||||
|
<div className="text-center">
|
||||||
|
<p className="text-[30px] lg:text-[50px] text-black">
|
||||||
|
Report Not Found
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,171 +0,0 @@
|
|||||||
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;
|
|
||||||
+2213
-62
File diff suppressed because it is too large
Load Diff
@@ -1,64 +1,209 @@
|
|||||||
#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;
|
||||||
opacity: 1;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fadein {
|
#_editsnackbar {
|
||||||
from {
|
visibility: hidden;
|
||||||
top: 0;
|
min-width: 250px;
|
||||||
opacity: 0;
|
margin-left: -125px;
|
||||||
}
|
background-color: #333;
|
||||||
to {
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 2px;
|
||||||
|
padding: 16px;
|
||||||
|
position: fixed;
|
||||||
|
z-index: 99999;
|
||||||
|
left: 50%;
|
||||||
top: 30px;
|
top: 30px;
|
||||||
opacity: 1;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@-webkit-keyframes fadeout {
|
#_editsnackbar.show {
|
||||||
from {
|
visibility: visible;
|
||||||
top: 30px;
|
-webkit-animation: fadein 0.5s;
|
||||||
opacity: 1;
|
|
||||||
}
|
}
|
||||||
to {
|
|
||||||
top: 0;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fadeout {
|
#UpdateColumnValue.show {
|
||||||
from {
|
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;
|
||||||
opacity: 1;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
to {
|
|
||||||
top: 0;
|
#deleteObj.show {
|
||||||
opacity: 0;
|
visibility: visible;
|
||||||
|
-webkit-animation: fadein 0.5s;
|
||||||
}
|
}
|
||||||
}
|
#deleteObj {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#UpdateColumnValue {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
//--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);
|
|
||||||
@@ -1,367 +0,0 @@
|
|||||||
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!' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,216 +0,0 @@
|
|||||||
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!' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,379 +0,0 @@
|
|||||||
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!' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
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!' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,214 +0,0 @@
|
|||||||
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!' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
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!' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
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!' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
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!' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
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!' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
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!' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
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!' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
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!' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
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!' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
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!' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
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!' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
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!' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
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!' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
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!' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
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!' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
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!' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
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,12 +17,6 @@ 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);
|
||||||
@@ -32,20 +26,14 @@ 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 && request?.user) {
|
if (acl) {
|
||||||
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,11 +4,20 @@ 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);
|
||||||
@@ -28,23 +37,21 @@ 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 {
|
||||||
if (request?.object?.id && request.user) {
|
await updateSelfDoc(request.object.id);
|
||||||
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 {
|
||||||
if (request?.object?.id) {
|
await updateSelfDoc(request.object.id);
|
||||||
await updateSelfDoc(request.object.id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,7 +65,6 @@ 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");
|
||||||
@@ -81,10 +87,9 @@ 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);
|
||||||
if (res?.CreatedBy) {
|
newACL.setReadAccess(request.user, true);
|
||||||
newACL.setReadAccess(res?.CreatedBy?.objectId, true);
|
newACL.setWriteAccess(request.user, 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);
|
||||||
@@ -95,9 +100,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");
|
||||||
@@ -105,10 +110,8 @@ 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);
|
||||||
if (res?.CreatedBy) {
|
newACL.setReadAccess(request.user, true);
|
||||||
newACL.setReadAccess(res?.CreatedBy?.objectId, true);
|
newACL.setWriteAccess(request.user, true);
|
||||||
newACL.setWriteAccess(res?.CreatedBy?.objectId, true);
|
|
||||||
}
|
|
||||||
updateACL.setACL(newACL);
|
updateACL.setACL(newACL);
|
||||||
updateACL.save(null, { useMasterKey: true });
|
updateACL.save(null, { useMasterKey: true });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +0,0 @@
|
|||||||
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!" };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
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 });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
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!' };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
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,7 +21,6 @@ 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();
|
||||||
@@ -41,7 +40,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', err);
|
console.log('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}"},"IsArchive":{"$ne":true}}&include=ExtUserPtr,Signers,Folder`;
|
url = `${classUrl}?where={"Folder":{"__type":"Pointer","className":"contracts_Document","objectId":"${docId}"},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${userId}"}}&include=ExtUserPtr,Signers,Folder`;
|
||||||
} else {
|
} else {
|
||||||
url = `${classUrl}?where={"Folder":{"$exists":false},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${userId}"},"IsArchive":{"$ne":true}}&include=ExtUserPtr,Signers`;
|
url = `${classUrl}?where={"Folder":{"$exists":false},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${userId}"}}&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 = json?.reportClass ? json.reportClass : 'contracts_Document';
|
const clsName = reportId === '5KhaPr482K' ? 'contracts_Contactbook' : 'contracts_Document';
|
||||||
if (json) {
|
if (json) {
|
||||||
const { params, keys } = json;
|
const { params, keys } = json;
|
||||||
const orderBy = '-updatedAt';
|
const orderBy = '-updatedAt';
|
||||||
|
|||||||
@@ -1,13 +1,9 @@
|
|||||||
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) {
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
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!" };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+106
-190
@@ -1,36 +1,40 @@
|
|||||||
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(e, a) {
|
async function uploadFile(a) {
|
||||||
try {
|
try {
|
||||||
var t = fs.readFileSync(a),
|
var e = new FormData(),
|
||||||
s = new Parse.File(e, [...t]),
|
t =
|
||||||
r = (await s.save({ useMasterKey: !0 }), s.url());
|
(e.append('file', fs.createReadStream(a)),
|
||||||
return { imageUrl: r };
|
{ 'content-type': 'multipart/form-data', 'X-Parse-Application-Id': process.env.APP_ID }),
|
||||||
|
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, n, o) {
|
async function updateDoc(t, s, r, i, o, n) {
|
||||||
try {
|
try {
|
||||||
var d = {
|
var d = {
|
||||||
UserPtr: { __type: 'Pointer', className: o, objectId: r },
|
UserPtr: { __type: 'Pointer', className: n, objectId: r },
|
||||||
SignedUrl: s,
|
SignedUrl: s,
|
||||||
Activity: 'Signed',
|
Activity: 'Signed',
|
||||||
ipAddress: i,
|
ipAddress: i,
|
||||||
};
|
};
|
||||||
let e;
|
let e;
|
||||||
var l = (e = n.AuditTrail && 0 < n.AuditTrail.length ? [...n.AuditTrail, d] : [d]).filter(
|
var l = (e = o.AuditTrail && 0 < o.AuditTrail.length ? [...o.AuditTrail, d] : [d]).filter(
|
||||||
e => 'Signed' === e.Activity
|
e => 'Signed' === e.Activity
|
||||||
);
|
);
|
||||||
let a = !1;
|
let a = !1;
|
||||||
!((n.Signers && 0 < n.Signers.length && l.length !== n.Signers.length) || !(a = !0));
|
!((o.Signers && 0 < o.Signers.length && l.length !== o.Signers.length) || !(a = !0));
|
||||||
var c = { SignedUrl: s, AuditTrail: e, IsCompleted: a };
|
var p = { SignedUrl: s, AuditTrail: e, IsCompleted: a };
|
||||||
await axios.put(serverUrl + '/classes/contracts_Document/' + t, c, {
|
await axios.put(serverUrl + '/classes/contracts_Document/' + t, p, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'X-Parse-Application-Id': APPID,
|
'X-Parse-Application-Id': APPID,
|
||||||
@@ -55,9 +59,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 OpenSign™. 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 Open Sign. 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 OpenSign™ <a href=www.opensignlabs.com target=_blank>here</a>.</p></div></div></body></html>',
|
' directly. If you think this email is inappropriate or spam, you may file a complaint with Open Sign here.</p></div></div></body></html>',
|
||||||
};
|
};
|
||||||
await axios.post(serverUrl + '/functions/sendmailv3', a, {
|
await axios.post(serverUrl + '/functions/sendmailv3', a, {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -80,9 +84,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 OpenSign™. 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 Open Sign. 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 OpenSign™ <a href=www.opensignlabs.com target=_blank>here</a>.</p></div></div></body></html>',
|
' directly. If you think this email is inappropriate or spam, you may file a complaint with Open Sign here.</p></div></div></body></html>',
|
||||||
};
|
};
|
||||||
await axios.post(serverUrl + '/functions/sendmailv3', a, {
|
await axios.post(serverUrl + '/functions/sendmailv3', a, {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -92,203 +96,115 @@ async function sendCompletedMail(e) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
async function sendDoctoWebhook(t, e, a, s) {
|
async function PDF(s, r) {
|
||||||
let r = [];
|
|
||||||
(r = s
|
|
||||||
? { name: s?.Name, email: s?.Email, phone: s?.Phone }
|
|
||||||
: t?.data?.Signers?.map(e => ({ name: e.Name, email: e.Email, phone: e.Phone })) || [
|
|
||||||
{
|
|
||||||
name: t?.data?.ExtUserPtr?.Name,
|
|
||||||
email: t?.data?.ExtUserPtr?.Email,
|
|
||||||
phone: t?.data?.ExtUserPtr?.Phone,
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
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,
|
|
||||||
}),
|
|
||||||
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 {
|
try {
|
||||||
i.params.sign;
|
var i = s.params.sign,
|
||||||
var e = i.params.docId,
|
e = s.params.docId,
|
||||||
a = i.params.userId,
|
o = s.params.userId,
|
||||||
o = await axios.get(
|
n = await axios.get(serverUrl + '/classes/contracts_Document/' + e + '?include=ExtUserPtr', {
|
||||||
serverUrl + '/classes/contracts_Document/' + e + '?include=ExtUserPtr,Signers',
|
headers: {
|
||||||
{
|
'Content-Type': 'application/json',
|
||||||
headers: {
|
'X-Parse-Application-Id': APPID,
|
||||||
'Content-Type': 'application/json',
|
'X-Parse-Master-Key': masterKEY,
|
||||||
'X-Parse-Application-Id': APPID,
|
},
|
||||||
'X-Parse-Master-Key': masterKEY,
|
}),
|
||||||
},
|
d = await axios.get(serverUrl + '/users/me', {
|
||||||
}
|
|
||||||
),
|
|
||||||
t = await axios.get(serverUrl + '/users/me', {
|
|
||||||
headers: {
|
headers: {
|
||||||
'X-Parse-Application-Id': APPID,
|
'X-Parse-Application-Id': APPID,
|
||||||
'X-Parse-Session-Token': i.headers.sessiontoken,
|
'X-Parse-Session-Token': s.headers.sessiontoken,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (!t.data || !t.data.objectId) return { status: 'error', message: 'this user not allowed!' };
|
if (!d.data || !d.data.objectId) return { status: 'error', message: 'this user not allowed!' };
|
||||||
{
|
{
|
||||||
var d,
|
var l,
|
||||||
l,
|
p,
|
||||||
c,
|
c,
|
||||||
p = JSON.stringify({ objectId: a });
|
m = JSON.stringify({ objectId: o });
|
||||||
let s, r;
|
let a, t;
|
||||||
r = a
|
t = o
|
||||||
? (d = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + p, {
|
? (l = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + m, {
|
||||||
headers: {
|
headers: {
|
||||||
'X-Parse-Application-Id': APPID,
|
'X-Parse-Application-Id': APPID,
|
||||||
'X-Parse-Session-Token': i.headers.sessiontoken,
|
'X-Parse-Session-Token': s.headers.sessiontoken,
|
||||||
},
|
},
|
||||||
})).data && 0 < d.data.results.length
|
})).data && 0 < l.data.results.length
|
||||||
? ((s = d), 'contracts_Contactbook')
|
? ((a = l), 'contracts_Contactbook')
|
||||||
: ((s = await axios.get(serverUrl + '/classes/contracts_Users?where=' + p, {
|
: ((a = await axios.get(serverUrl + '/classes/contracts_Users?where=' + m, {
|
||||||
headers: { 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY },
|
headers: {
|
||||||
|
'X-Parse-Application-Id': APPID,
|
||||||
|
'X-Parse-Master-Key': masterKEY,
|
||||||
|
},
|
||||||
})),
|
})),
|
||||||
'contracts_Users')
|
'contracts_Users')
|
||||||
: ((l = JSON.stringify({
|
: ((p = JSON.stringify({
|
||||||
UserId: { __type: 'Pointer', className: '_User', objectId: t.data.objectId },
|
UserId: { __type: 'Pointer', className: '_User', objectId: d.data.objectId },
|
||||||
})),
|
})),
|
||||||
(c = await axios.get(serverUrl + '/classes/contracts_Users?where=' + l, {
|
(c = await axios.get(serverUrl + '/classes/contracts_Users?where=' + p, {
|
||||||
headers: { 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY },
|
headers: {
|
||||||
|
'X-Parse-Application-Id': APPID,
|
||||||
|
'X-Parse-Master-Key': masterKEY,
|
||||||
|
},
|
||||||
})).data && 0 < c.data.results.length
|
})).data && 0 < c.data.results.length
|
||||||
? ((s = c), 'contracts_Users')
|
? ((a = c), 'contracts_Users')
|
||||||
: ((s = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + l, {
|
: ((a = 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': i.headers.sessiontoken,
|
'X-Parse-Session-Token': s.headers.sessiontoken,
|
||||||
},
|
},
|
||||||
})),
|
})),
|
||||||
'contracts_Contactbook'));
|
'contracts_Contactbook'));
|
||||||
var m = s.data.results[0].Name,
|
var g = a.data.results[0].Name,
|
||||||
g = s.data.results[0].Email;
|
h = a.data.results[0].Email;
|
||||||
if (!i.params.pdfFile) return { status: 'error', message: 'pdf file not present!' };
|
if (!s.params.pdfFile) return { status: 'error', message: 'pdf file not present!' };
|
||||||
{
|
{
|
||||||
let e = Buffer.from(i.params.pdfFile, 'base64');
|
let e = Buffer.from(s.params.pdfFile, 'base64');
|
||||||
var h = process.env.PFX_BASE64,
|
var u = process.env.PFX_BASE64,
|
||||||
u = Buffer.from(h, 'base64'),
|
f = Buffer.from(u, 'base64');
|
||||||
f = {
|
e = i
|
||||||
UserPtr: { __type: 'Pointer', className: r, objectId: s.data.results[0].objectId },
|
? plainplaceholder({
|
||||||
SignedUrl: '',
|
pdfBuffer: e,
|
||||||
Activity: 'Signed',
|
reason: 'Digitally signed by Open sign for ' + g + ' <' + h + '>',
|
||||||
ipAddress: i.headers['x-real-ip'],
|
location: 'test location',
|
||||||
};
|
signatureLength: 1e4,
|
||||||
let a;
|
sign: i,
|
||||||
var y = (a =
|
})
|
||||||
o.data.AuditTrail && 0 < o.data.AuditTrail.length
|
: plainAddPlaceholder({
|
||||||
? [...o.data.AuditTrail, f]
|
pdfBuffer: e,
|
||||||
: [f]).filter(e => 'Signed' === e.Activity);
|
reason: 'Digitally signed by Open sign for ' + g + ' <' + h + '>',
|
||||||
let t = !1;
|
location: 'test location',
|
||||||
!(
|
signatureLength: 1e4,
|
||||||
(o.data.Signers && 0 < o.data.Signers.length && y.length !== o.data.Signers.length) ||
|
});
|
||||||
!(t = !0)
|
var y = await new SignPDF(e, f).signPDF(),
|
||||||
);
|
v = `./exports/exported_file_${Math.floor(5e3 * Math.random())}.pdf`,
|
||||||
var v,
|
P = (fs.writeFileSync(v, y), await uploadFile(v));
|
||||||
P,
|
if (P && P.imageUrl) {
|
||||||
b = `exported_file_${Math.floor(5e3 * Math.random())}.pdf`,
|
const r = await updateDoc(
|
||||||
x = './exports/' + b,
|
s.params.docId,
|
||||||
U =
|
P.imageUrl,
|
||||||
(t
|
a.data.results[0].objectId,
|
||||||
? ((v = o.data.Signers?.map(e => e.Name + ' <' + e.Email + '>')),
|
s.headers['x-real-ip'],
|
||||||
(e =
|
n.data,
|
||||||
v && 0 < v.length
|
t
|
||||||
? 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 (
|
||||||
o.data.IsSendMail && !1 === o.data.IsSendMail
|
sendMail({
|
||||||
? console.log("don't send mail")
|
url: P.imageUrl,
|
||||||
: sendMail(w),
|
sender: { Mail: n.data.ExtUserPtr.Email, Name: n.data.ExtUserPtr.Name },
|
||||||
sendDoctoWebhook(o, U.imageUrl, 'signed', s?.data.results?.[0]),
|
pdfName: n.data.Name,
|
||||||
n &&
|
receiver: h,
|
||||||
n.isCompleted &&
|
}),
|
||||||
((I = {
|
r &&
|
||||||
url: U.imageUrl,
|
r.isCompleted &&
|
||||||
sender: { Mail: o.data.ExtUserPtr.Email, Name: 'OpenSign™' },
|
sendCompletedMail({
|
||||||
pdfName: o.data.Name,
|
url: P.imageUrl,
|
||||||
receiver: o.data.ExtUserPtr.Email,
|
sender: { Mail: n.data.ExtUserPtr.Email, Name: 'Open sign' },
|
||||||
|
pdfName: n.data.Name,
|
||||||
|
receiver: n.data.ExtUserPtr.Email,
|
||||||
}),
|
}),
|
||||||
o.data.IsSendMail && !1 === o.data.IsSendMail
|
fs.unlinkSync(v),
|
||||||
? console.log("don't send mail")
|
console.log('New Signed PDF created called: ' + v),
|
||||||
: sendCompletedMail(I),
|
'success' === r.message
|
||||||
sendDoctoWebhook(o, U.imageUrl, 'completed')),
|
? { status: 'success', data: P.imageUrl }
|
||||||
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,13 +7,9 @@ export default function reportJson(id, userId) {
|
|||||||
return {
|
return {
|
||||||
reportName: 'Draft Documents',
|
reportName: 'Draft Documents',
|
||||||
params: {
|
params: {
|
||||||
Type: { $ne: 'Folder' },
|
Type: null,
|
||||||
IsCompleted: { $ne: true },
|
|
||||||
IsDeclined: { $ne: true },
|
|
||||||
IsArchive: { $ne: true },
|
|
||||||
$or: [
|
$or: [
|
||||||
{ Signers: { $eq: [] } },
|
{ Signers: null, SignedUrl: null },
|
||||||
{ Signers: null },
|
|
||||||
{ Signers: { $exists: true }, Placeholders: null },
|
{ Signers: { $exists: true }, Placeholders: null },
|
||||||
],
|
],
|
||||||
CreatedBy: {
|
CreatedBy: {
|
||||||
@@ -22,16 +18,7 @@ export default function reportJson(id, userId) {
|
|||||||
objectId: currentUserId,
|
objectId: currentUserId,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
keys: [
|
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
||||||
'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':
|
||||||
@@ -41,23 +28,10 @@ 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',
|
||||||
@@ -66,8 +40,6 @@ 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',
|
||||||
],
|
],
|
||||||
@@ -78,11 +50,10 @@ export default function reportJson(id, userId) {
|
|||||||
reportName: 'In-progress documents',
|
reportName: 'In-progress documents',
|
||||||
params: {
|
params: {
|
||||||
Type: { $ne: 'Folder' },
|
Type: { $ne: 'Folder' },
|
||||||
Signers: { $exists: true, $ne: [] },
|
Signers: { $ne: null },
|
||||||
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',
|
||||||
@@ -92,23 +63,14 @@ export default function reportJson(id, userId) {
|
|||||||
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
keys: [
|
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
||||||
'Name',
|
|
||||||
'Note',
|
|
||||||
'Folder.Name',
|
|
||||||
'URL',
|
|
||||||
'ExtUserPtr.Name',
|
|
||||||
'Signers.Name',
|
|
||||||
'Signers.Email',
|
|
||||||
'Signers.Phone',
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
// completed documents report
|
// completed documents report
|
||||||
case 'kQUoW4hUXz':
|
case 'kQUoW4hUXz':
|
||||||
return {
|
return {
|
||||||
reportName: 'Completed Documents',
|
reportName: 'Completed Documents',
|
||||||
params: {
|
params: {
|
||||||
Type: { $ne: 'Folder' },
|
Type: null,
|
||||||
IsCompleted: true,
|
IsCompleted: true,
|
||||||
CreatedBy: {
|
CreatedBy: {
|
||||||
__type: 'Pointer',
|
__type: 'Pointer',
|
||||||
@@ -116,18 +78,14 @@ export default function reportJson(id, userId) {
|
|||||||
objectId: currentUserId,
|
objectId: currentUserId,
|
||||||
},
|
},
|
||||||
IsDeclined: { $ne: true },
|
IsDeclined: { $ne: true },
|
||||||
IsArchive: { $ne: true },
|
|
||||||
},
|
},
|
||||||
keys: [
|
keys: [
|
||||||
'Name',
|
'Name',
|
||||||
'Note',
|
'Note',
|
||||||
'Folder.Name',
|
'Folder.Name',
|
||||||
'URL',
|
'URL',
|
||||||
'SignedUrl',
|
|
||||||
'ExtUserPtr.Name',
|
'ExtUserPtr.Name',
|
||||||
'Signers.Name',
|
'Signers.Name',
|
||||||
'Signers.Email',
|
|
||||||
'Signers.Phone',
|
|
||||||
'TimeToCompleteDays',
|
'TimeToCompleteDays',
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
@@ -138,7 +96,6 @@ 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',
|
||||||
@@ -147,16 +104,7 @@ export default function reportJson(id, userId) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
keys: [
|
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
||||||
'Name',
|
|
||||||
'Note',
|
|
||||||
'Folder.Name',
|
|
||||||
'URL',
|
|
||||||
'ExtUserPtr.Name',
|
|
||||||
'Signers.Name',
|
|
||||||
'Signers.Email',
|
|
||||||
'Signers.Phone',
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
// Expired Documents report
|
// Expired Documents report
|
||||||
case 'zNqBHXHsYH':
|
case 'zNqBHXHsYH':
|
||||||
@@ -165,7 +113,6 @@ 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: [
|
||||||
{
|
{
|
||||||
@@ -186,16 +133,7 @@ export default function reportJson(id, userId) {
|
|||||||
objectId: currentUserId,
|
objectId: currentUserId,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
keys: [
|
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
||||||
'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':
|
||||||
@@ -203,11 +141,10 @@ 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: { $exists: true, $ne: [] },
|
Signers: { $ne: null },
|
||||||
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',
|
||||||
@@ -217,15 +154,7 @@ export default function reportJson(id, userId) {
|
|||||||
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
$gt: { __type: 'Date', iso: new Date().toISOString() },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
keys: [
|
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
||||||
'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':
|
||||||
@@ -235,54 +164,10 @@ 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: [
|
|
||||||
'Name',
|
|
||||||
'URL',
|
|
||||||
'ExtUserPtr.Name',
|
|
||||||
'Signers.Name',
|
|
||||||
'Signers.UserId',
|
|
||||||
'AuditTrail',
|
|
||||||
'Signers.Email',
|
|
||||||
'Signers.Phone',
|
|
||||||
],
|
|
||||||
};
|
|
||||||
// Drafts report show on dashboard
|
|
||||||
case 'kC5mfynCi4':
|
|
||||||
return {
|
|
||||||
reportName: 'Drafts',
|
|
||||||
params: {
|
|
||||||
Type: { $ne: 'Folder' },
|
|
||||||
IsCompleted: { $ne: true },
|
|
||||||
IsDeclined: { $ne: true },
|
|
||||||
IsArchive: { $ne: true },
|
|
||||||
$or: [
|
|
||||||
{ Signers: { $eq: [] } },
|
|
||||||
{ Signers: null },
|
|
||||||
{ Signers: { $exists: true }, Placeholders: null },
|
|
||||||
],
|
|
||||||
CreatedBy: {
|
|
||||||
__type: 'Pointer',
|
|
||||||
className: '_User',
|
|
||||||
objectId: currentUserId,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
keys: [
|
keys: [
|
||||||
'Name',
|
'Name',
|
||||||
@@ -291,15 +176,32 @@ export default function reportJson(id, userId) {
|
|||||||
'URL',
|
'URL',
|
||||||
'ExtUserPtr.Name',
|
'ExtUserPtr.Name',
|
||||||
'Signers.Name',
|
'Signers.Name',
|
||||||
'Signers.Email',
|
'Signers.UserId',
|
||||||
'Signers.Phone',
|
'AuditTrail',
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
// Drafts report show on dashboard
|
||||||
|
case 'kC5mfynCi4':
|
||||||
|
return {
|
||||||
|
reportName: 'Drafts',
|
||||||
|
params: {
|
||||||
|
Type: null,
|
||||||
|
$or: [
|
||||||
|
{ Signers: null, SignedUrl: null },
|
||||||
|
{ Signers: { $exists: true }, Placeholders: null },
|
||||||
|
],
|
||||||
|
CreatedBy: {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: '_User',
|
||||||
|
objectId: currentUserId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'],
|
||||||
|
};
|
||||||
// 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',
|
||||||
@@ -310,31 +212,6 @@ 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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
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',
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,588 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* @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 });
|
|
||||||
};
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* @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());
|
|
||||||
};
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* @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
@@ -1,652 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* @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 });
|
|
||||||
};
|
|
||||||
@@ -1,684 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* @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 @@
|
|||||||
OpenSign™ Email Address Verification
|
Email Address Verification
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user