Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
533059e747 | ||
|
|
88b6a83e40 | ||
|
|
26aeab5f12 | ||
|
|
21a479dee9 | ||
|
|
1e31203e13 | ||
|
|
465d5e217c | ||
|
|
d1019e3ef6 | ||
|
|
5c3949239e | ||
|
|
3e0fb1cf15 | ||
|
|
9ffde3b609 | ||
|
|
235665dca2 | ||
|
|
baa1579d1b | ||
|
|
d95c559d01 | ||
|
|
2b3ff7ba92 | ||
|
|
42802da227 | ||
|
|
59c7440c61 | ||
|
|
047c43ecf4 | ||
|
|
a881fd6061 | ||
|
|
672bf237a8 | ||
|
|
1642955a4e | ||
|
|
232b1251fa | ||
|
|
d7846f299a | ||
|
|
aa6eec7a2c | ||
|
|
4c7094c0a5 | ||
|
|
6abdad8d84 | ||
|
|
67b7303c2b | ||
|
|
4ea968219b | ||
|
|
4138ab7e21 | ||
|
|
e7157b3de1 | ||
|
|
771bc3a04e | ||
|
|
db2b788ec9 | ||
|
|
8a7bdfff30 | ||
|
|
fcc1b0634c | ||
|
|
00fc014845 | ||
|
|
8c306714c3 | ||
|
|
e4d0dd9554 | ||
|
|
8287d3988e | ||
|
|
1c5160c356 | ||
|
|
c7dcfb908c | ||
|
|
1c09b6e1fa | ||
|
|
53ee5a36c7 | ||
|
|
c0b7cd08e5 | ||
|
|
bae0f228a8 | ||
|
|
edce724ad8 | ||
|
|
01b0f8ba94 | ||
|
|
94cb7b301c | ||
|
|
0835b1332b | ||
|
|
b98c10a28e | ||
|
|
5a84fcf89d | ||
|
|
26882f9a8b | ||
|
|
731a60f15b | ||
|
|
8f05404029 | ||
|
|
cc8ddc1e55 | ||
|
|
9052edb9c5 | ||
|
|
9073445b37 | ||
|
|
ca5e34e64d | ||
|
|
233c66044d | ||
|
|
64d768386e | ||
|
|
f0a8263aff | ||
|
|
a320835a73 | ||
|
|
805d0d1d84 | ||
|
|
b0d159462a | ||
|
|
84bdcfbcba | ||
|
|
e4a51b5390 | ||
|
|
891ff460a9 | ||
|
|
03c311ca7b | ||
|
|
620274e1eb | ||
|
|
dfb5b1bb94 | ||
|
|
0994f80891 | ||
|
|
cb9f75bf2f | ||
|
|
ee8525dac3 | ||
|
|
8919a2b2e9 | ||
|
|
efa5e2e491 | ||
|
|
c58566ea1b | ||
|
|
e1da69398c | ||
|
|
3f4cffb157 | ||
|
|
3d91b8b12e | ||
|
|
592f35f47f | ||
|
|
ed9fe3c5f9 | ||
|
|
c6e1593df5 | ||
|
|
900f929b53 | ||
|
|
e8093f1bf0 | ||
|
|
97912d2432 | ||
|
|
6fd6cd3eb8 | ||
|
|
37465082e4 | ||
|
|
d011edd3a1 | ||
|
|
694483aa2d | ||
|
|
c6be12b16a | ||
|
|
0213807732 | ||
|
|
d758062c07 | ||
|
|
cf698be79e | ||
|
|
c3298ccc6f | ||
|
|
eefa11d827 | ||
|
|
dadc79600f | ||
|
|
76d10d6ab9 | ||
|
|
c8733e6903 | ||
|
|
88ec854dbd | ||
|
|
717d2c0ddd | ||
|
|
8e2d463089 | ||
|
|
1344d8d12f | ||
|
|
51c8040d60 | ||
|
|
e505396e53 | ||
|
|
606bedd2ec | ||
|
|
dc82af0a0a | ||
|
|
8dfc61eeef | ||
|
|
2133a3a460 | ||
|
|
6f615db29d | ||
|
|
4141b3538c | ||
|
|
3bbb78b7b5 | ||
|
|
2caa231154 | ||
|
|
9ac382c188 | ||
|
|
852e109a52 | ||
|
|
d292b5bd6a | ||
|
|
d868fdf6f2 | ||
|
|
4145ce8c0c | ||
|
|
e093d7a5f4 | ||
|
|
3d4e43ede5 | ||
|
|
0bbfe5ae3d | ||
|
|
8538f0710a | ||
|
|
61be45cba2 | ||
|
|
162e07bacc | ||
|
|
806bb2e387 | ||
|
|
9de3331cd2 | ||
|
|
76699d7dc9 | ||
|
|
5888387dd0 | ||
|
|
83e9537176 | ||
|
|
d973a8fea4 | ||
|
|
ae6f727646 | ||
|
|
f9eb9201f0 | ||
|
|
0d884e2f4f | ||
|
|
1c70e4c059 | ||
|
|
e747d0d699 | ||
|
|
2edbafd520 | ||
|
|
14c57cceb3 | ||
|
|
6337f3057e | ||
|
|
537949b7c3 | ||
|
|
180e7c1435 | ||
|
|
9139422180 | ||
|
|
274d01b548 | ||
|
|
4d62048d36 | ||
|
|
921f7c89e9 | ||
|
|
6bfa3e61b5 | ||
|
|
840c7165ff | ||
|
|
9eeb1e9bc2 | ||
|
|
bc7f2d69cf | ||
|
|
34d9296c70 | ||
|
|
725b67e75e | ||
|
|
71bb6d6206 | ||
|
|
f271a113b6 | ||
|
|
71b254f69d | ||
|
|
28b6e9d4aa | ||
|
|
c6f57db04b | ||
|
|
5626b18ab0 | ||
|
|
5adf336119 | ||
|
|
ef1d4967d9 | ||
|
|
7680c8e140 | ||
|
|
0a14122cbf | ||
|
|
6587268f53 | ||
|
|
96d0db22c8 | ||
|
|
d35a03d588 | ||
|
|
7fd743f325 | ||
|
|
b81ff12ae5 | ||
|
|
65be6d1e20 | ||
|
|
9dfd1fb4f1 | ||
|
|
abbc0e91a9 | ||
|
|
1bf2f5622f | ||
|
|
8a1f2bc9a0 | ||
|
|
75518b3f6b | ||
|
|
53d874fd12 | ||
|
|
b7b61df983 | ||
|
|
20f1e68b13 | ||
|
|
e26fac8498 | ||
|
|
02dfec3a0f | ||
|
|
e6a04670b6 | ||
|
|
41aa91152d | ||
|
|
e69fb8eeba | ||
|
|
cb2dab8222 | ||
|
|
ad2672f205 | ||
|
|
e45314c1df | ||
|
|
34b0a1ca02 | ||
|
|
c05f541189 | ||
|
|
68cad8e10c | ||
|
|
2afad89b29 | ||
|
|
6c57ee6591 | ||
|
|
48bcaa5614 | ||
|
|
e595672e3c | ||
|
|
8fe31ee59b | ||
|
|
c6b139c456 | ||
|
|
10d99f12bb | ||
|
|
55ebdb5919 | ||
|
|
4b6712a0ff | ||
|
|
fcb983f68a | ||
|
|
f92ff170db | ||
|
|
c8b3f1fcbf | ||
|
|
936717fc6f | ||
|
|
be948ed4df | ||
|
|
5d8e7f738d | ||
|
|
128f6378cf | ||
|
|
1641217c43 | ||
|
|
63cc034b4a | ||
|
|
49a63eeb50 | ||
|
|
da45fcfc85 | ||
|
|
b73b0c6b2d | ||
|
|
c9fe580e44 | ||
|
|
b0556310dd | ||
|
|
9da13a23cc | ||
|
|
d727e16ef9 | ||
|
|
1508c63d0e | ||
|
|
8a198c1543 | ||
|
|
da0652d8ed | ||
|
|
59f1453176 | ||
|
|
ad748fbd03 | ||
|
|
2a1afca818 | ||
|
|
8e1cfd1ce5 | ||
|
|
6236353316 | ||
|
|
b5271017dc | ||
|
|
4b6b955fe5 | ||
|
|
a2b3761d5e | ||
|
|
2c5e311c7f | ||
|
|
98facb2f6d | ||
|
|
77618e57ea | ||
|
|
0bb8aa880d | ||
|
|
f97f2c1253 | ||
|
|
b76add3b2b | ||
|
|
07b14a0a47 | ||
|
|
aa7326a941 | ||
|
|
336d3424fe | ||
|
|
73ae7b1c06 | ||
|
|
ccfd7450d5 | ||
|
|
e23c04cf06 | ||
|
|
7bf661d584 | ||
|
|
98c18357cd | ||
|
|
8b7079bd8b | ||
|
|
9f0963d8a3 | ||
|
|
ebc79ddec7 | ||
|
|
24c6e9f5c0 | ||
|
|
475b2e09af | ||
|
|
05a922446a | ||
|
|
81a426b087 | ||
|
|
743b751b5a | ||
|
|
3d6e83b4af | ||
|
|
4f3e8ab95a | ||
|
|
cc00b35ac8 | ||
|
|
1c86caac1f | ||
|
|
20dd3c90d6 | ||
|
|
8b87a90e78 | ||
|
|
bd7937deb2 | ||
|
|
7b0dc4cf9a | ||
|
|
81c47190bf | ||
|
|
cecf22bb85 | ||
|
|
17eacfe86b | ||
|
|
8f5c9d1b40 | ||
|
|
f34e277657 | ||
|
|
7cc7e36f64 | ||
|
|
b340463ea7 | ||
|
|
9364bb7859 | ||
|
|
9f676c12e7 | ||
|
|
0077b71388 | ||
|
|
50af669bd2 | ||
|
|
45055b567f | ||
|
|
4a7fd118bb | ||
|
|
d27e8a43dc | ||
|
|
4d3635a5bd | ||
|
|
aeef6ca567 | ||
|
|
cc68dd109f | ||
|
|
7943f1444f | ||
|
|
876e04d815 | ||
|
|
43dbe71c99 | ||
|
|
73b36fafd7 | ||
|
|
095040713e | ||
|
|
ac884185b4 | ||
|
|
eede170d16 | ||
|
|
c4d6d8e442 | ||
|
|
14a2f6f78a | ||
|
|
dd28cefac8 | ||
|
|
00179f5415 | ||
|
|
7b465687ef | ||
|
|
e67fdfb134 | ||
|
|
ceee0e1089 | ||
|
|
1d184a69b0 | ||
|
|
8e09d7235b | ||
|
|
a39c01ef12 | ||
|
|
d96504bb30 | ||
|
|
0b8c4eac6e | ||
|
|
98f7de5e0c | ||
|
|
998a50412a | ||
|
|
e16c5e08a8 | ||
|
|
72a61bc621 | ||
|
|
f095629134 | ||
|
|
a0c1e08091 | ||
|
|
3583d7a549 | ||
|
|
69e679982a | ||
|
|
3303fcb895 | ||
|
|
6b5815f52a | ||
|
|
a01e361d14 | ||
|
|
c059e95fa9 | ||
|
|
70abddec3a | ||
|
|
ca8eaa492c | ||
|
|
94806c895f | ||
|
|
8b08995e7d | ||
|
|
de9c58e5fd | ||
|
|
6d914829e9 | ||
|
|
0193e4946f | ||
|
|
14c6b14c27 | ||
|
|
794365f6dc | ||
|
|
d0a0a28dec | ||
|
|
1385f12543 | ||
|
|
0d81ffe677 | ||
|
|
9d7376aedb | ||
|
|
5eb7d8ce13 | ||
|
|
4609bba4c1 | ||
|
|
de0de1973e | ||
|
|
16c48e9d23 | ||
|
|
344ccadfb1 | ||
|
|
eb1086e5b1 | ||
|
|
ae568a89d5 | ||
|
|
daa348c2e3 | ||
|
|
78532731da | ||
|
|
2e26d5687e | ||
|
|
4b8b7ed8d9 | ||
|
|
ac986af20f | ||
|
|
a96333bba5 | ||
|
|
78ca0d1fdb | ||
|
|
415760ba52 | ||
|
|
67bd246ef9 | ||
|
|
4963a7ad7f | ||
|
|
94b02105f3 | ||
|
|
6aaeeeeaf5 | ||
|
|
8039f5a744 | ||
|
|
a5ebd67967 | ||
|
|
266a4c5654 | ||
|
|
406a29054e | ||
|
|
57f8ba8a72 | ||
|
|
f1a70eac5a | ||
|
|
f228ae5ba8 | ||
|
|
2c1239dcf0 | ||
|
|
6ca9cbab16 | ||
|
|
9922f22ef7 | ||
|
|
84cc1d65fe | ||
|
|
7a5db1ca40 | ||
|
|
de79c9a4b3 | ||
|
|
7a7e1b506a | ||
|
|
fa2e66914d | ||
|
|
b0c65fe5f1 | ||
|
|
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 | ||
|
|
8c209f5a9e | ||
|
|
995a2a5cef | ||
|
|
71fd7b20a6 | ||
|
|
d8e73eef72 | ||
|
|
61209f4c6c | ||
|
|
c4507dd06b | ||
|
|
773e8b8dbb | ||
|
|
91976d2355 | ||
|
|
77042224a1 | ||
|
|
0b64908eab | ||
|
|
fc3f134bd5 | ||
|
|
d6c2c66fdd | ||
|
|
d5853e6fc3 | ||
|
|
765c3c19fa | ||
|
|
f13991b88b | ||
|
|
47ddac3529 | ||
|
|
e51feaa1fe | ||
|
|
d224a44e54 | ||
|
|
f5c0694e32 | ||
|
|
dec13e8b5f | ||
|
|
dd536dc7d0 | ||
|
|
b6ce00519f | ||
|
|
7495955420 | ||
|
|
d17951af30 | ||
|
|
42c6f03f28 | ||
|
|
a9d6bc2246 | ||
|
|
428bb3b7c3 | ||
|
|
ac0cdd28cf | ||
|
|
37250f8a11 | ||
|
|
0102480954 | ||
|
|
f3a1c74a45 | ||
|
|
2544651ff1 | ||
|
|
93297b972a | ||
|
|
7165ed82f5 | ||
|
|
17422427a8 | ||
|
|
9ef2bc9ee2 | ||
|
|
12ec1bad0f | ||
|
|
fd552cedec | ||
|
|
5784378073 | ||
|
|
e0448cd4fa | ||
|
|
9a4bd79d75 | ||
|
|
9ae0334249 | ||
|
|
eb355f562b | ||
|
|
92dc13185b | ||
|
|
65ec4e78ad | ||
|
|
0c4b8143b2 | ||
|
|
1cc4cf93cb | ||
|
|
944370134a | ||
|
|
c1621f64e6 | ||
|
|
e8c06d0836 | ||
|
|
a6295a6e56 | ||
|
|
47ae52c881 | ||
|
|
f2f0b55596 | ||
|
|
0c415de598 | ||
|
|
411941d9f7 | ||
|
|
3c54f2287c | ||
|
|
dfa121fe57 | ||
|
|
52b17730ef | ||
|
|
346d69124c | ||
|
|
7f35074acd | ||
|
|
b9e9694d61 | ||
|
|
ee4a787b81 | ||
|
|
d801680846 | ||
|
|
d84ab89a9b | ||
|
|
26d38f4ca2 | ||
|
|
745e519eec | ||
|
|
45b3e739d7 | ||
|
|
5ce50db001 | ||
|
|
a8c7b60c1b | ||
|
|
16860bc7b8 | ||
|
|
57f20ae1c0 | ||
|
|
d3b0c614ff | ||
|
|
e28f929ffc | ||
|
|
9f8f9a0992 | ||
|
|
60857638ba | ||
|
|
8041151243 | ||
|
|
7faed512b8 | ||
|
|
5d99a4a9c8 | ||
|
|
25c50d5387 | ||
|
|
5719dcca79 | ||
|
|
db1e81a249 | ||
|
|
ecd3395453 | ||
|
|
4327b2e348 | ||
|
|
06e8140be4 | ||
|
|
14e9330651 | ||
|
|
636910a78e | ||
|
|
e4f9152de8 | ||
|
|
e0b9df9ba5 | ||
|
|
a20bd407a8 | ||
|
|
5630dd45a7 | ||
|
|
20220dd8c9 | ||
|
|
db4b8ec0ee | ||
|
|
2ee9ae16fb | ||
|
|
e50a55403d | ||
|
|
23ae72738d | ||
|
|
8619021f30 | ||
|
|
6c579178c0 | ||
|
|
01e19632a9 | ||
|
|
79ff8fd71d | ||
|
|
8700fd837d | ||
|
|
cdc8eb5bf6 | ||
|
|
95200e234f | ||
|
|
d94527e31a | ||
|
|
903066e6fa | ||
|
|
8c8015fe4a | ||
|
|
a002ac779c | ||
|
|
5c9bfbbdfe | ||
|
|
4a1e6d1318 | ||
|
|
90dc7c738a | ||
|
|
777028f3a7 | ||
|
|
c5a0ff4021 | ||
|
|
bf9f42e94d | ||
|
|
5556de2ef5 | ||
|
|
1b3508a9ef | ||
|
|
3992a9be94 | ||
|
|
eaf875be06 | ||
|
|
e62897e729 | ||
|
|
4c58fe2040 | ||
|
|
298068207e | ||
|
|
d0abe615cb | ||
|
|
87c65e4bea | ||
|
|
be49cb9d6d | ||
|
|
2b73087b7e | ||
|
|
d11dff2987 | ||
|
|
8ac82b1214 | ||
|
|
c46fa19bbb | ||
|
|
2fa2f56bac | ||
|
|
ef50aaa417 | ||
|
|
a1d7275fcd | ||
|
|
080acc9ed6 | ||
|
|
30b888f3a0 | ||
|
|
df11a77971 | ||
|
|
03e660527d | ||
|
|
f7bd439df5 | ||
|
|
2a55c03788 | ||
|
|
f712532793 | ||
|
|
cbdeaf8cc9 | ||
|
|
6bb353fd1f | ||
|
|
523dd43b4d | ||
|
|
bd0216fc39 | ||
|
|
50c40bfec1 | ||
|
|
0e2b6ee180 | ||
|
|
359d86e17b | ||
|
|
0b19c87a50 | ||
|
|
4a35eab7c6 | ||
|
|
b178a3c91e | ||
|
|
9fb0fecba4 | ||
|
|
cfc7408a52 | ||
|
|
aed0b8a3db | ||
|
|
910bd801ac | ||
|
|
22dad33b2e | ||
|
|
4d3ed0232e | ||
|
|
6d83f05b13 | ||
|
|
66cc2e1f2f | ||
|
|
f773fc6e3c | ||
|
|
dc83f21f5e | ||
|
|
0186c48d59 | ||
|
|
43f20508ae | ||
|
|
f678dd02cb | ||
|
|
5c2d6cddcb | ||
|
|
1bbf64fe83 | ||
|
|
296f43101e | ||
|
|
ed6f44fd62 | ||
|
|
776b1a7b43 | ||
|
|
06cdb660b3 | ||
|
|
db9268e1af | ||
|
|
83ce3a1c21 | ||
|
|
bda31de345 | ||
|
|
cdfc952a3f | ||
|
|
9434315775 | ||
|
|
47bb4cac38 | ||
|
|
11d3e6c696 | ||
|
|
0173727bc5 | ||
|
|
3cfa2639e5 | ||
|
|
502400ee56 | ||
|
|
4a3276f4e3 | ||
|
|
750e48ca2e | ||
|
|
823e6a9e2f | ||
|
|
642ef334f6 | ||
|
|
939a67b2c5 | ||
|
|
e1f8481aa2 | ||
|
|
b8e8cd127a | ||
|
|
876a2d78d5 | ||
|
|
16f287fdc0 | ||
|
|
d396a4f71d | ||
|
|
6bee566d8d | ||
|
|
79acd8ae13 | ||
|
|
01666b49cf | ||
|
|
a20ebbf08f | ||
|
|
26cf9c5310 | ||
|
|
3ad58ee52b | ||
|
|
2b67af6097 | ||
|
|
f61dae35ff | ||
|
|
dead3088d6 | ||
|
|
45d65cfbe2 | ||
|
|
6d2010facb | ||
|
|
48d3166049 | ||
|
|
82992d324d | ||
|
|
9a549fa35d | ||
|
|
93a891c8b6 | ||
|
|
2ede742b10 | ||
|
|
c43690faa8 | ||
|
|
a482a92d34 | ||
|
|
1d429cbe36 | ||
|
|
0a36550907 | ||
|
|
09610112fc | ||
|
|
a14454227c | ||
|
|
0d8767ee98 | ||
|
|
f463dc7af7 | ||
|
|
407b01565a | ||
|
|
6c565a144a | ||
|
|
141351de49 | ||
|
|
edecf3ea23 | ||
|
|
e708dad596 | ||
|
|
48012c9343 | ||
|
|
009a24e943 | ||
|
|
04a3251968 | ||
|
|
82694a24f2 | ||
|
|
748cc042dd | ||
|
|
6b8bca0802 | ||
|
|
fed1cff0cb | ||
|
|
b2eba6409f | ||
|
|
81af6a6c61 | ||
|
|
c326849b8d | ||
|
|
a92188d8e2 | ||
|
|
b5dbc69188 | ||
|
|
4055574785 | ||
|
|
9b295f784a | ||
|
|
bfae7f236c | ||
|
|
fe907116e2 | ||
|
|
ade39c2f46 | ||
|
|
31baefcce3 | ||
|
|
59eb4eb9c7 | ||
|
|
3b93f96479 | ||
|
|
dbff436bc2 | ||
|
|
c3cf9c891e | ||
|
|
4e7c8c63bb | ||
|
|
db4494c463 | ||
|
|
d208a90107 | ||
|
|
450a971ca9 | ||
|
|
5ba1f79f3b | ||
|
|
f81f72a147 | ||
|
|
d255d5bfb2 | ||
|
|
f5e835cbc4 | ||
|
|
b40eb7119d | ||
|
|
f56faf3afd | ||
|
|
5fa60d8135 | ||
|
|
695345d911 | ||
|
|
3f60509254 | ||
|
|
6bd9ac0b8f | ||
|
|
2022df000e | ||
|
|
ec6e037422 | ||
|
|
4b11fe77e0 | ||
|
|
d42e11c5c1 | ||
|
|
fe37f3e021 | ||
|
|
95558d1407 | ||
|
|
73978ebce4 | ||
|
|
96ae95a97c | ||
|
|
356d2e81c5 |
@@ -1,183 +0,0 @@
|
||||
{
|
||||
"projectName": "OpenSign",
|
||||
"projectOwner": "OpenSignLabs",
|
||||
"files": [
|
||||
"README.md"
|
||||
],
|
||||
"commitType": "docs",
|
||||
"commitConvention": "angular",
|
||||
"contributorsPerLine": 7,
|
||||
"contributors": [
|
||||
{
|
||||
"login": "ajakov",
|
||||
"name": "Aleksandar Jakovljevic",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/2115393?v=4",
|
||||
"profile": "https://aleksandarjakovljevic.com/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "BuilderPrid",
|
||||
"name": "Priyanshu Dwivedi",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/106882895?v=4",
|
||||
"profile": "https://github.com/BuilderPrid",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Tashuuuu",
|
||||
"name": "Akriti Sengar",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/85075827?v=4",
|
||||
"profile": "https://github.com/Tashuuuu",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "parthrc",
|
||||
"name": "Parth Chawande",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/101104958?v=4",
|
||||
"profile": "https://github.com/parthrc",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Rishabh-git10",
|
||||
"name": "Rishabh Dewangan",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/107680241?v=4",
|
||||
"profile": "https://github.com/Rishabh-git10",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "LemonDrop847",
|
||||
"name": "Nitin Mishra",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/106615670?v=4",
|
||||
"profile": "https://github.com/LemonDrop847",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Jobin-S",
|
||||
"name": "Jobin Selvanose",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/63976083?v=4",
|
||||
"profile": "http://jobinselvanose.com",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "HansF",
|
||||
"name": "Hans Fraiponts",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1503?v=4",
|
||||
"profile": "https://github.com/HansF",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Monilprajapati",
|
||||
"name": "Monil Prajapati",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/99136041?v=4",
|
||||
"profile": "http://linktr.ee/monilprajapati",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Emm-dev0",
|
||||
"name": "Edogbanya Emmanuel",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/97445413?v=4",
|
||||
"profile": "https://emm-dev0.github.io/portfolio/",
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "pranav514",
|
||||
"name": "pranav514",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/76992202?v=4",
|
||||
"profile": "https://github.com/pranav514",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "arianxq",
|
||||
"name": "Aria",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/122199576?v=4",
|
||||
"profile": "https://github.com/arianxq",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "SoumyadiptoPal",
|
||||
"name": "Soumyadipto Pal",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/119007659?v=4",
|
||||
"profile": "https://github.com/SoumyadiptoPal",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "AndreyCurious",
|
||||
"name": "Andrey Didenko",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/105622604?v=4",
|
||||
"profile": "https://github.com/AndreyCurious",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "VishakhaSainani",
|
||||
"name": "VishakhaSainani",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/113436770?v=4",
|
||||
"profile": "https://github.com/VishakhaSainani",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "andrew-opensignlabs",
|
||||
"name": "Andrew",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/148278535?v=4",
|
||||
"profile": "https://github.com/andrew-opensignlabs",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "rishabjasrotia",
|
||||
"name": "Rishab",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/33950743?v=4",
|
||||
"profile": "https://github.com/rishabjasrotia",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "maoo",
|
||||
"name": "Maurizio Pillitu",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/327285?v=4",
|
||||
"profile": "https://session.it",
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "lsprr",
|
||||
"name": "Luis Parra",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/16653744?v=4",
|
||||
"profile": "https://luisparra.dev",
|
||||
"contributions": [
|
||||
"a11y"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
# Frontend config ************************************************************************************************************************************************************************************************
|
||||
# Set CI to false while running the app locally
|
||||
CI=false
|
||||
# Set it to the URL form where the app home page will be accessed
|
||||
PUBLIC_URL=https://app.opensignlabs.com/
|
||||
# Set it to true if you want to generate the Sourcemap for debugging
|
||||
GENERATE_SOURCEMAP=false
|
||||
# Set it to the URL from where APIs will be accessible, for local development it should be localhost:3000/api/app (use your local port number instead)
|
||||
REACT_APP_SERVERURL=https://app.opensignlabs.com/api/app
|
||||
# A 12 character long random app identifier. The value of this should be same as APP_ID which is a variable used by backend API.
|
||||
REACT_APP_APPID=aDsADsqweqwe
|
||||
# Google tag manager container id for configuring GTM on all pages of the app
|
||||
REACT_APP_GTM=GTM-123N7LD
|
||||
|
||||
# Backend ExpressJS config ****************************************************************************************************************************************************************************************
|
||||
# A 12 character long random app identifier. The value of this should be same as REACT_APP_APPID which is a variable used by Frontend React App.
|
||||
APP_ID=aDsADsqweqwe
|
||||
# Name of the app. It will be visible in the verification emails sent out.
|
||||
appName=open_sign_server
|
||||
# A 12 character long random secret key that allows access to all the data. It is used in Parse dashboard config to view all the data in the database.
|
||||
MASTER_KEY=XnAadwKxxByMr
|
||||
# Mongodb URI to connect to
|
||||
MONGODB_URI=mongodb://username:password@localhost:27017
|
||||
# Path on which APIs should be mounted. Do not change this. This variable shall be removed & value hardcoded in the source code in coming versions.
|
||||
PARSE_MOUNT=/app
|
||||
# Set it to the URL from where APIs will be accessible to the NodeJS functions, for local development it should be localhost:3000/api/app (use your local port number instead)
|
||||
SERVER_URL=https://app.opensignlabs.com/api/app
|
||||
|
||||
# Storage config ************************************************************************************************************************************************************************************************
|
||||
# Digital ocean space name or AWS S3 bucket name for uploading documents
|
||||
DO_SPACE=DOSPACENAME
|
||||
# Digital ocean spaces endpoint or AWS S3 endpoint for uploading documents
|
||||
DO_ENDPOINT=ams3.digitaloceanspaces.com
|
||||
# Digital ocean baseurl or AWS S3 base URL
|
||||
DO_BASEURL=https://DOSPACENAME.ams3.digitaloceanspaces.com
|
||||
# Digital ocean spaces access key ID or AWS s3 Access key ID for uploading the docs
|
||||
DO_ACCESS_KEY_ID=
|
||||
# Digital ocean spaces secret access key or AWS s3 secret access key for uploading the docs
|
||||
DO_SECRET_ACCESS_KEY=
|
||||
# Digital ocean spaces region or AWS s3 region
|
||||
DO_REGION=us-west
|
||||
|
||||
# Email mailgun config (The app will not initialize if any of these 3 variables are not set) *********************************************************************************************************************
|
||||
MAILGUN_API_KEY=
|
||||
MAILGUN_DOMAIN=mail.yourdomain.com
|
||||
MAILGUN_SENDER=postmaster@mail.yourdomain.com
|
||||
|
||||
# Base64 encoded PFX or p12 document signing certificate file *********************************************************************************************************************
|
||||
PFX_BASE64=
|
||||
|
||||
# Provide Pass pharse of above PFX or p12 document
|
||||
PASS_PHRASE=
|
||||
@@ -1,14 +0,0 @@
|
||||
# Clone the repo and rename this file to .env if you want to run the frontend react app locally for some quick contributions to the project.
|
||||
# When used as it is, this env config will connect to our hosted UAT backend
|
||||
# Note that any data in staging will get cleared from time to time and you may have to sign up again and again
|
||||
|
||||
# Set CI to false while running the app locally
|
||||
CI=false
|
||||
# Set it to the URL form where the app home page will be accessed
|
||||
PUBLIC_URL=http://localhost:3000
|
||||
# Set it to true if you want to generate the Sourcemap for debugging
|
||||
GENERATE_SOURCEMAP=false
|
||||
# Set it to the URL from where APIs will be accessible, for local development it should be localhost:3000/api/app (use your local port number instead)
|
||||
REACT_APP_SERVERURL=https://staging-app.opensignlabs.com/api/app
|
||||
# A 12 character long random app identifier. The value of this should be same as APP_ID which is a variable used by backend API.
|
||||
REACT_APP_APPID=opensignstgn
|
||||
@@ -1,56 +0,0 @@
|
||||
# Clone the repo and rename this file to .env if you want to run the frontend react app locally for some quick contributions to the project.
|
||||
# When used as it is, this env config will connect to our hosted UAT backend
|
||||
# Note that any data in staging will get cleared from time to time and you may have to sign up again and again
|
||||
|
||||
# Set CI to false while running the app locally
|
||||
CI=false
|
||||
# Set it to the URL form where the app home page will be accessed
|
||||
PUBLIC_URL=http://localhost:3000
|
||||
# Set it to true if you want to generate the Sourcemap for debugging
|
||||
GENERATE_SOURCEMAP=false
|
||||
# Set it to the URL from where APIs will be accessible, for local development it should be localhost:3000/api/app (use your local port number instead)
|
||||
REACT_APP_SERVERURL=http://localhost:8080/app
|
||||
# A 12 character long random app identifier. The value of this should be same as APP_ID which is a variable used by backend API.
|
||||
REACT_APP_APPID=opensignstgn
|
||||
|
||||
|
||||
# Backend ExpressJS config ****************************************************************************************************************************************************************************************
|
||||
# A 12 character long random app identifier. The value of this should be same as REACT_APP_APPID which is a variable used by Frontend React App.
|
||||
APP_ID=opensignstgn
|
||||
# Name of the app. It will be visible in the verification emails sent out.
|
||||
appName=open_sign_server
|
||||
# A 12 character long random secret key that allows access to all the data. It is used in Parse dashboard config to view all the data in the database.
|
||||
MASTER_KEY=XnAadwKxxByMr
|
||||
# Mongodb URI to connect to
|
||||
MONGODB_URI=mongodb://host.docker.internal:27017/OpenSignDB
|
||||
# Path on which APIs should be mounted. Do not change this. This variable shall be removed & value hardcoded in the source code in coming versions.
|
||||
PARSE_MOUNT=/app
|
||||
# Set it to the URL from where APIs will be accessible to the NodeJS functions, for local development it should be localhost:3000/api/app (use your local port number instead)
|
||||
SERVER_URL=http://127.0.0.1:8080/app
|
||||
|
||||
# Storage config ************************************************************************************************************************************************************************************************
|
||||
# Digital ocean space name or AWS S3 bucket name for uploading documents
|
||||
DO_SPACE=DOSPACENAME
|
||||
# Digital ocean spaces endpoint or AWS S3 endpoint for uploading documents
|
||||
DO_ENDPOINT=ams3.digitaloceanspaces.com
|
||||
# Digital ocean baseurl or AWS S3 base URL
|
||||
DO_BASEURL=https://DOSPACENAME.ams3.digitaloceanspaces.com
|
||||
# Digital ocean spaces access key ID or AWS s3 Access key ID for uploading the docs
|
||||
DO_ACCESS_KEY_ID=
|
||||
# Digital ocean spaces secret access key or AWS s3 secret access key for uploading the docs
|
||||
DO_SECRET_ACCESS_KEY=
|
||||
# Digital ocean spaces region or AWS s3 region
|
||||
DO_REGION=us-west
|
||||
# local storage
|
||||
USE_LOCAL=TRUE
|
||||
|
||||
# Email mailgun config (The app will not initialize if any of these 3 variables are not set) *********************************************************************************************************************
|
||||
MAILGUN_API_KEY=XXXXX
|
||||
MAILGUN_DOMAIN=mail.yourdomain.com
|
||||
MAILGUN_SENDER=postmaster@mail.yourdomain.com
|
||||
|
||||
# Base64 encoded PFX or p12 document signing certificate file *********************************************************************************************************************
|
||||
PFX_BASE64=
|
||||
|
||||
# Provide Pass pharse of above PFX or p12 document
|
||||
PASS_PHRASE=
|
||||
@@ -0,0 +1,73 @@
|
||||
name: "Bug Report"
|
||||
labels: ["bug","up-for-grabs"]
|
||||
title: "[Bug]: "
|
||||
assignees:
|
||||
- andrew-opensignlabs
|
||||
description: Create a bug report to help us make OpenSign™ the world's best document e-signature platform
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Issue Description
|
||||
description: Please provide a clear & concise description of the problem.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: Describe what you expected to happen.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Current Behavior
|
||||
description: Describe what is happening instead.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Please provide step-by-step instructions to reproduce the issue. Include code snippets, URLs, error messages and any other relevant information.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Screenshots of the issue(optional)
|
||||
description: Add screenshots to better explain the issue.
|
||||
- type: input
|
||||
attributes:
|
||||
label: Operating System [e.g. MacOS Sonoma 14.1, Windows 11]
|
||||
- type: dropdown
|
||||
id: browsers
|
||||
attributes:
|
||||
label: What browsers are you seeing the problem on?
|
||||
multiple: true
|
||||
options:
|
||||
- Chrome
|
||||
- Firefox
|
||||
- Safari
|
||||
- Microsoft Edge
|
||||
default: 0
|
||||
- type: input
|
||||
attributes:
|
||||
label: What version of OpenSign™ are you seeing this issue on? [e.g. 1.0.6]
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: environment
|
||||
attributes:
|
||||
label: What environment are you seeing the problem on?
|
||||
multiple: true
|
||||
options:
|
||||
- Production (app.opensignlabs.com)
|
||||
- Staging (staging-app.opensignlabs.com)
|
||||
- Hosted (app.yourdomain.com)
|
||||
- Dev (localhost or vercel)
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Please check the boxes that apply to this issue report.
|
||||
options:
|
||||
- label: I have searched the existing issues & discussions to make sure that this is not a duplicate.
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: By submitting this issue, you agree to follow our [Code of Conduct](https://www.opensignlabs.com)
|
||||
options:
|
||||
- label: I agree to follow this project's Code of Conduct
|
||||
required: true
|
||||
- label: I have searched the existing issues & discussions to make sure that this is not a duplicate.
|
||||
required: true
|
||||
@@ -0,0 +1,70 @@
|
||||
name: Feature Request
|
||||
description: Suggest an idea for OpenSign™
|
||||
title: "Feature Request: [Short Description]"
|
||||
labels: [feature request, needs triage]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
## Thanks for taking the time to fill out this feature request!
|
||||
|
||||
- type: input
|
||||
id: title
|
||||
attributes:
|
||||
label: Feature Title
|
||||
description: What would you call this feature?
|
||||
placeholder: e.g., Advanced Signature Verification
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: feature-description
|
||||
attributes:
|
||||
label: Feature Description
|
||||
description: |
|
||||
Please provide a detailed description of the feature you're proposing.
|
||||
placeholder: |
|
||||
e.g., I'm proposing an advanced signature verification feature that...
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: featuretype
|
||||
attributes:
|
||||
label: What type of feature are you requesting?
|
||||
multiple: true
|
||||
options:
|
||||
- UI/UX Improvement
|
||||
- Security / Compliance
|
||||
- Performance / Optimization
|
||||
- 3rd party integration
|
||||
- Other
|
||||
- type: dropdown
|
||||
id: importance
|
||||
attributes:
|
||||
label: Importance
|
||||
description: How important is this feature to you?
|
||||
options:
|
||||
- Critical
|
||||
- High
|
||||
- Medium
|
||||
- Low
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: additional-context
|
||||
attributes:
|
||||
label: Additional Context
|
||||
description: Any other context or screenshots about the feature request here.
|
||||
placeholder: Additional details, examples, or screenshots...
|
||||
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: By submitting this issue, you agree to follow our [Code of Conduct](https://www.opensignlabs.com)
|
||||
options:
|
||||
- label: I agree to follow this project's Code of Conduct
|
||||
required: true
|
||||
- label: I have searched the existing issues & discussions to make sure that this is not a duplicate.
|
||||
required: true
|
||||
@@ -0,0 +1,22 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
# maintain dependencies for frontend
|
||||
- package-ecosystem: "npm" # See documentation for possible values
|
||||
directory: "/apps/OpenSign" # Location of package manifests
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
# maintain dependencies for server
|
||||
- package-ecosystem: "npm" # See documentation for possible values
|
||||
directory: "/apps/OpenSignServer" # Location of package manifests
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
# maintain dependencies for microfrontends
|
||||
- package-ecosystem: "npm" # See documentation for possible values
|
||||
directory: "microfrontends/SignDocuments" # Location of package manifests
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
@@ -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: 20
|
||||
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
|
||||
@@ -22,3 +22,6 @@
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
apps/OpenSign/public/mfbuild/*
|
||||
microfrontends/SignDocuments/build/*
|
||||
apps/OpenSignServer/files/files/*
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
npx eslint '**/*.{js,jsx}'
|
||||
npx pretty-quick --staged '**/*.{js,jsx}'
|
||||
npm run lint-staged-changes
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"*.js": "prettier --write"
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
|
||||
# INSTALLATON INSTRUCTIONS
|
||||
|
||||
You can use our app as a cloud version from [OpenSignLabs](https://www.opensignlabs.com)
|
||||
|
||||
or follow below instructions to install it on your own infrastructure.
|
||||
|
||||
- Localhost(Frontend only)
|
||||
- Digital Ocean
|
||||
- Localhost(Docker)
|
||||
|
||||
## Localhost(Frontend only)
|
||||
|
||||
This is the easiest way to run the frontend application for development or testing purpose without the hassle of installing backend & DB. All the features including document upload, signing, email notifications will work seamlessly from staging backend.
|
||||
|
||||
**Warning:** All data, including user accounts and documents, is stored in the staging backend. This data will be erased every time there is a merge to the main branch. As a result, you may need to recreate user accounts repeatedly. If you find that login attempts are failing, it is likely because the data has been cleared due to a recent merge.
|
||||
|
||||
Below are the steps to follow -
|
||||
- [Clone the repository](https://help.github.com/articles/cloning-a-repository/) to your local machine using below command -
|
||||
```
|
||||
git clone https://github.com/OpenSignLabs/OpenSign.git
|
||||
```
|
||||
- Copy the .env.frontend_dev file to apps/OpenSign/.env using below command(on mac & linux). For windows use COPY command instead.
|
||||
```
|
||||
cp .env.frontend_dev apps/OpenSign/.env
|
||||
```
|
||||
- CD to /apps/OpenSign directory
|
||||
- Install NPM packages using
|
||||
```
|
||||
npm install
|
||||
```
|
||||
- Run the project locally using
|
||||
```
|
||||
npm run start
|
||||
```
|
||||
You should be able to access the application from http://localhost:3000 after this.
|
||||
Create an account by signing-up and start contributing.
|
||||
|
||||
|
||||
## Digital Ocean
|
||||
|
||||
OpenSign application consistes of 3 components -
|
||||
- ReactJS frontend
|
||||
- NodeJS API
|
||||
- MongoDB database
|
||||
|
||||
You can install all 3 components on digital ocean using the button below -
|
||||
|
||||
[](https://cloud.digitalocean.com/apps/new?repo=https://github.com/OpenSignLabs/Deploy-OpenSign-to-Digital-Ocean/tree/main&refcode=30db1c901ab0)
|
||||
|
||||
## You will need to create an AWS S3 bucket or digital ocean space in order to store your uploaded documents
|
||||
|
||||
### AWS S3 -
|
||||
- Step 1 : Create a S3 bucket
|
||||
- Login to AWS console
|
||||
- Navigate to S3 under services
|
||||
- Hit "Create Bucket" button on upper right corner
|
||||
- Remove the check from "block all public access" checkbox(we need this in order to provide access to not-logged in users after OTP verification)
|
||||
- Set bucket versioning and tags as per your requirements
|
||||
- Hit "Create bucket" button
|
||||
- Step 2 : Create IAM user and provide access to AWS bucket
|
||||
- Search for "IAM" on the search bar in AWS console
|
||||
- On IAM dashboard, click the number of users(count) under IAM resources table
|
||||
- Hit "create user" button on the upper right corner of the page
|
||||
- Enter the user name & click next
|
||||
- Click create policy, search for S3 and provide the Read, Write & list permissions
|
||||
- Click next and click "Create user"
|
||||
- Step 3 : Generate Credentials
|
||||
- Go to IAM/Users in AWS console
|
||||
- Hit the hyperlink for the user created in the previous step
|
||||
- Click the "Security credentials" tab
|
||||
- Scroll down to "Access keys" and hit "Create access key"
|
||||
- In the next step select "Application running outside AWS"
|
||||
- Add a description tag if needed & hit "Create access key"
|
||||
- In the next step you will see "Access key" and "Secret Access key". Copy both the values.
|
||||
- Set the value of "Access key" to "DO_ACCESS_KEY_ID" environment variable
|
||||
- Set the value of "Secret Access key" to "DO_SECRET_ACCESS_KEY" environment variable
|
||||
- Step 3 : Copy bucket credentials
|
||||
- Visit "Amazon S3 -> Buckets" in aws console
|
||||
- Click the bucket created in previous steps & visit the properties tab
|
||||
- Under "Bucket overview" you will find the value of AWS region(for ex. ap-south-1). Set that value to env variable "DO_REGION"
|
||||
- You can create the value for "DO_ENDPOINT" env variable by appending the region value to amazonaws.com (for ex. s3.ap-south-1.amazonaws.com)
|
||||
- You can create the value for "DO_BASEURL" by adding the bucketname in front of the endpoint value(for ex. https://bucketname.s3.ap-south-1.amazonaws.com)
|
||||
|
||||
Visit below link if you face any issues while following the above instructions -
|
||||
- https://repost.aws/knowledge-center/create-access-key
|
||||
|
||||
|
||||
## Localhost(Docker)
|
||||
|
||||
Below are the steps to follow -
|
||||
- Execute `make build`
|
||||
@@ -1,661 +0,0 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
@@ -1,136 +0,0 @@
|
||||
<h1 align="center"><a href='https://www.opensignlabs.com'>OpenSign™</a></h1>
|
||||
|
||||
<div align="center">
|
||||
|
||||
The free and open source alternative to DocuSign
|
||||
|
||||
[](http://isitmaintained.com/project/opensignlabs/opensign "Average time to resolve an issue")
|
||||
[](#contributors)
|
||||

|
||||

|
||||
|
||||
|
||||
<a href="https://www.opensignlabs.com/">Website</a>
|
||||
<span> • </span>
|
||||
<a href="https://www.opensignlabs.com">Docs</a>
|
||||
<span> • </span>
|
||||
<a href="https://www.opensignlabs.com/blog">Blog</a>
|
||||
<span> • </span>
|
||||
<a href="https://discord.com/invite/xe9TDuyAyj">Discord</a>
|
||||
<span> • </span>
|
||||
<a href="https://twitter.com/opensignlabs">Twitter</a>
|
||||
<span> • </span>
|
||||
<a href="https://www.linkedin.com/company/opensign%E2%84%A2/about/">LinkedIn</a>
|
||||
|
||||
|
||||
## An open-source document e-signing solution
|
||||
|
||||
---
|
||||
</div>
|
||||
|
||||
### Table of Contents
|
||||
|
||||
1. [Introduction](#introduction)
|
||||
2. [Features](#features)
|
||||
3. [Installation](#installation)
|
||||
4. [Usage](#usage)
|
||||
5. [Contribution Guidelines](#contribution-guidelines)
|
||||
6. [License](#license)
|
||||
7. [Acknowledgments](#acknowledgments)
|
||||
|
||||
---
|
||||
|
||||
### Introduction
|
||||
|
||||
Welcome to OpenSign, an open-source document e-signing solution designed to provide a secure, reliable, and free alternative to commercial platforms like DocuSign, PandaDoc, SignNow, Adobe Sign, Smartwaiver, SignRequest, HelloSign & Zoho sign. Developed under the OpenSignLabs organization, our mission is to democratize the e-signing process, making it accessible and straightforward for everyone.
|
||||
|
||||
---
|
||||
|
||||
### Features
|
||||
|
||||
- **Secure Signing**: Utilizes state-of-the-art cryptographic algorithms to ensure the security & integrity of your documents.
|
||||
- **User-Friendly Interface**: Designed with usability in mind, making it easy for both technical and non-technical users.
|
||||
- **Multi-Platform Support**: Compatible with various browsers and devices.
|
||||
- **Invite & collaborate users**: Bring multiple people from your team into the signing process, all within your own infrastructure.
|
||||
- **Secure**: Allows for the easy, secure and seamless organization of your documents using 'OpenSigDrive'.
|
||||
- **Audit Trails**: Keeps a detailed log of all activities related to the document signing process including IP addresses and access timings.
|
||||
- **Completion Certificate**: Generate secure completion certificate as soon as a document is signed by all participants.
|
||||
- **API Support**: Provides a robust API for integration into other software and services.
|
||||
|
||||
<img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/b37ff443-7099-4273-9aeb-21c46d7154cf height='200'>
|
||||
<img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/86db91b7-6c2f-4885-a33c-58f4fd35ec89 height='200'>
|
||||
<img src=https://github.com/OpenSignLabs/OpenSign/assets/5486116/56835efd-c40e-42de-a206-20202c293876 height='200'>
|
||||
|
||||
|
||||
---
|
||||
|
||||
### Installation
|
||||
|
||||
Please refer to the [Installation Guide](INSTALLATION.md) for detailed instructions on how to install OpenSign on your system.
|
||||
|
||||
---
|
||||
|
||||
### Usage
|
||||
|
||||
For comprehensive guidelines on how to use OpenSign, please consult our [User Manual](USAGE.md).
|
||||
|
||||
---
|
||||
|
||||
### Contribution Guidelines
|
||||
|
||||
We welcome contributions from the open-source community. For more information on how to contribute, please read our [Contribution Guidelines](CONTRIBUTING.md).
|
||||
|
||||
---
|
||||
|
||||
### License
|
||||
|
||||
OpenSign is licensed under the AGPL License. For more details, see the [LICENSE](LICENSE) file.
|
||||
|
||||
---
|
||||
|
||||
### Acknowledgments
|
||||
|
||||
We would like to thank all our contributors and users for their support and feedback. Special thanks to [OpenSignLabs](https://github.com/OpenSignLabs) for spearheading this initiative.
|
||||
|
||||
---
|
||||
|
||||
## Contributors
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
||||
<!-- prettier-ignore-start -->
|
||||
<!-- markdownlint-disable -->
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://aleksandarjakovljevic.com/"><img src="https://avatars.githubusercontent.com/u/2115393?v=4?s=100" width="100px;" alt="Aleksandar Jakovljevic"/><br /><sub><b>Aleksandar Jakovljevic</b></sub></a><br /><a href="#code-ajakov" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/BuilderPrid"><img src="https://avatars.githubusercontent.com/u/106882895?v=4?s=100" width="100px;" alt="Priyanshu Dwivedi"/><br /><sub><b>Priyanshu Dwivedi</b></sub></a><br /><a href="#code-BuilderPrid" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Tashuuuu"><img src="https://avatars.githubusercontent.com/u/85075827?v=4?s=100" width="100px;" alt="Akriti Sengar"/><br /><sub><b>Akriti Sengar</b></sub></a><br /><a href="#code-Tashuuuu" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/parthrc"><img src="https://avatars.githubusercontent.com/u/101104958?v=4?s=100" width="100px;" alt="Parth Chawande"/><br /><sub><b>Parth Chawande</b></sub></a><br /><a href="#code-parthrc" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Rishabh-git10"><img src="https://avatars.githubusercontent.com/u/107680241?v=4?s=100" width="100px;" alt="Rishabh Dewangan"/><br /><sub><b>Rishabh Dewangan</b></sub></a><br /><a href="#code-Rishabh-git10" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LemonDrop847"><img src="https://avatars.githubusercontent.com/u/106615670?v=4?s=100" width="100px;" alt="Nitin Mishra"/><br /><sub><b>Nitin Mishra</b></sub></a><br /><a href="#code-LemonDrop847" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://jobinselvanose.com"><img src="https://avatars.githubusercontent.com/u/63976083?v=4?s=100" width="100px;" alt="Jobin Selvanose"/><br /><sub><b>Jobin Selvanose</b></sub></a><br /><a href="#doc-Jobin-S" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/HansF"><img src="https://avatars.githubusercontent.com/u/1503?v=4?s=100" width="100px;" alt="Hans Fraiponts"/><br /><sub><b>Hans Fraiponts</b></sub></a><br /><a href="#doc-HansF" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://linktr.ee/monilprajapati"><img src="https://avatars.githubusercontent.com/u/99136041?v=4?s=100" width="100px;" alt="Monil Prajapati"/><br /><sub><b>Monil Prajapati</b></sub></a><br /><a href="#code-Monilprajapati" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://emm-dev0.github.io/portfolio/"><img src="https://avatars.githubusercontent.com/u/97445413?v=4?s=100" width="100px;" alt="Edogbanya Emmanuel"/><br /><sub><b>Edogbanya Emmanuel</b></sub></a><br /><a href="#bug-Emm-dev0" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/pranav514"><img src="https://avatars.githubusercontent.com/u/76992202?v=4?s=100" width="100px;" alt="pranav514"/><br /><sub><b>pranav514</b></sub></a><br /><a href="#code-pranav514" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/arianxq"><img src="https://avatars.githubusercontent.com/u/122199576?v=4?s=100" width="100px;" alt="Aria"/><br /><sub><b>Aria</b></sub></a><br /><a href="#code-arianxq" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/SoumyadiptoPal"><img src="https://avatars.githubusercontent.com/u/119007659?v=4?s=100" width="100px;" alt="Soumyadipto Pal"/><br /><sub><b>Soumyadipto Pal</b></sub></a><br /><a href="#code-SoumyadiptoPal" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/AndreyCurious"><img src="https://avatars.githubusercontent.com/u/105622604?v=4?s=100" width="100px;" alt="Andrey Didenko"/><br /><sub><b>Andrey Didenko</b></sub></a><br /><a href="#code-AndreyCurious" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/VishakhaSainani"><img src="https://avatars.githubusercontent.com/u/113436770?v=4?s=100" width="100px;" alt="VishakhaSainani"/><br /><sub><b>VishakhaSainani</b></sub></a><br /><a href="#code-VishakhaSainani" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/andrew-opensignlabs"><img src="https://avatars.githubusercontent.com/u/148278535?v=4?s=100" width="100px;" alt="Andrew"/><br /><sub><b>Andrew</b></sub></a><br /><a href="#code-andrew-opensignlabs" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rishabjasrotia"><img src="https://avatars.githubusercontent.com/u/33950743?v=4?s=100" width="100px;" alt="Rishab"/><br /><sub><b>Rishab</b></sub></a><br /><a href="#code-rishabjasrotia" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://session.it"><img src="https://avatars.githubusercontent.com/u/327285?v=4?s=100" width="100px;" alt="Maurizio Pillitu"/><br /><sub><b>Maurizio Pillitu</b></sub></a><br /><a href="#bug-maoo" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://luisparra.dev"><img src="https://avatars.githubusercontent.com/u/16653744?v=4?s=100" width="100px;" alt="Luis Parra"/><br /><sub><b>Luis Parra</b></sub></a><br /><a href="#a11y-lsprr" title="Accessibility">️️️️♿️</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- markdownlint-restore -->
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
The community is working hard to put together a great usage guide.
|
||||
You will soon see one of the best usage guides here.
|
||||
|
||||
Till then you can view the quick promo video by clicking the link below -
|
||||
|
||||
[<img src="https://i.ytimg.com/vi/szYaBZhXZNo/maxresdefault.jpg" width="50%">](https://www.youtube.com/watch?v=szYaBZhXZNo "OpenSign promo")
|
||||
@@ -1,6 +0,0 @@
|
||||
[tool.commitizen]
|
||||
version = "0.1.0" # This should be your current semver version
|
||||
version_files = [
|
||||
"package.json:\"version\":",
|
||||
"package-lock.json:\"version\":",
|
||||
]
|
||||
@@ -1,2 +0,0 @@
|
||||
node_modules
|
||||
npm-debug.log
|
||||
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2021": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:react/recommended",
|
||||
"plugin:react-hooks/recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
},
|
||||
"ecmaVersion": "latest",
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": ["react"],
|
||||
"rules": {
|
||||
"react/prop-types": 0,
|
||||
"no-unused-vars": 1
|
||||
},
|
||||
"ignorePatterns": ["**/build/**", "**/*.config.js"],
|
||||
"settings": {
|
||||
"react": {
|
||||
"version": "detect"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.env
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx eslint '**/*.{js,jsx}'
|
||||
npx pretty-quick --staged '**/*.{js,jsx}'
|
||||
@@ -1,7 +0,0 @@
|
||||
node_modules/
|
||||
public/
|
||||
build/
|
||||
package.json
|
||||
package-lock.json
|
||||
dist/
|
||||
docs/
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"bracketSpacing": true,
|
||||
"semi": true,
|
||||
"trailingComma": "none",
|
||||
"printWidth": 80,
|
||||
"tabWidth": 2
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
# Use an official Node runtime as the base image
|
||||
FROM node:16
|
||||
|
||||
# Set the working directory inside the container
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Copy package.json and package-lock.json first to leverage Docker cache
|
||||
COPY ./package*.json ./
|
||||
|
||||
# Install application dependencies
|
||||
RUN npm install
|
||||
|
||||
# Copy the current directory contents into the container
|
||||
COPY ./ .
|
||||
COPY ./.husky .
|
||||
|
||||
# Make port 3000 available to the world outside this container
|
||||
EXPOSE 3000
|
||||
|
||||
# Define environment variables if needed
|
||||
# ENV NODE_ENV production
|
||||
|
||||
# Run the application
|
||||
CMD ["npm", "start"]
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
# Open Sign
|
||||
|
||||
Open source is true platform to sign pdf with digital signature
|
||||
|
||||
## Available Scripts
|
||||
|
||||
In the project directory, you can run:
|
||||
|
||||
### `npm start`
|
||||
|
||||
Runs the app in the development mode.\
|
||||
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
|
||||
|
||||
The page will reload when you make changes.\
|
||||
You may also see any lint errors in the console.
|
||||
|
||||
### `npm run build`
|
||||
|
||||
Builds the app for production to the `build` folder.\
|
||||
It correctly bundles React in production mode and optimizes the build for the best performance.
|
||||
|
||||
The build is minified and the filenames include the hashes.\
|
||||
Your app is ready to be deployed!
|
||||
|
||||
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
||||
@@ -1,29 +0,0 @@
|
||||
const { dependencies } = require("./package.json");
|
||||
|
||||
module.exports = {
|
||||
name: "shell_app", // change me
|
||||
filename: "remoteEntry.js",
|
||||
exposes: {},
|
||||
remotes: {},
|
||||
shared: {
|
||||
...dependencies,
|
||||
react: {
|
||||
singleton: true,
|
||||
import: "react", // fallback is also react
|
||||
shareScope: "default",
|
||||
requiredVersion: dependencies.react
|
||||
},
|
||||
"react-dom": {
|
||||
singleton: true,
|
||||
requiredVersion: dependencies["react-dom"]
|
||||
},
|
||||
"react-router-dom": {
|
||||
singleton: true,
|
||||
requiredVersion: dependencies["react-router-dom"]
|
||||
},
|
||||
"rjsf-conditionals": {
|
||||
singleton: true,
|
||||
requiredVersion: dependencies["rjsf-conditionals"]
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,88 +0,0 @@
|
||||
{
|
||||
"name": "open_sign",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@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",
|
||||
"daisyui": "^3.9.2",
|
||||
"file-saver": "^2.0.5",
|
||||
"html-react-parser": "^4.2.2",
|
||||
"json-rules-engine-simplified": "^0.1.17",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"mf-cra": "^0.0.5",
|
||||
"moment": "^2.29.4",
|
||||
"parse": "^4.2.0",
|
||||
"react": "^18.2.0",
|
||||
"react-bootstrap": "^2.9.0",
|
||||
"react-dnd": "^16.0.1",
|
||||
"react-dnd-html5-backend": "^16.0.1",
|
||||
"react-dnd-multi-backend": "^8.0.3",
|
||||
"react-dnd-touch-backend": "^16.0.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-drag-listview": "^2.0.0",
|
||||
"react-gtm-module": "^2.0.11",
|
||||
"react-helmet": "^6.1.0",
|
||||
"react-modal": "^3.16.1",
|
||||
"react-redux": "^8.1.3",
|
||||
"react-router-dom": "^6.16.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"react-select": "^5.7.7",
|
||||
"reactour": "^1.19.2",
|
||||
"redux": "^4.2.1",
|
||||
"redux-thunk": "^2.4.2",
|
||||
"rjsf-conditionals": "github:prafullnavkar-nxg/rjsf-conditionals",
|
||||
"serve": "^14.2.1",
|
||||
"styled-components": "^4.4.1",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "serve -s build",
|
||||
"start-dev": "mf-cra start",
|
||||
"build": "rm -rf public/mfbuild && npm run micro && CI=false && mf-cra build",
|
||||
"micro": "cd ../../microfrontends/SignDocuments && npm install && npm run build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"release": "standard-version",
|
||||
"commit": "cz"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "./node_modules/cz-conventional-changelog"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/runtime-corejs2": "^7.23.2",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"commitizen": "^4.3.0",
|
||||
"eslint": "^8.51.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"lint-staged": "^15.0.1",
|
||||
"postcss": "^8.4.31",
|
||||
"prettier": "^2.8.0",
|
||||
"pretty-quick": "^3.1.3",
|
||||
"tailwindcss": "^3.3.3"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {}
|
||||
}
|
||||
};
|
||||
|
Before Width: | Height: | Size: 15 KiB |
@@ -1,53 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<!-- <link rel="icon" type="image/png"
|
||||
href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAALlJREFUaEPtmN0NwjAMBpNxYDKYiM1Yp90g93CKStH1NbIdfz921Dker2Pc+Js1cDF7MXAxASMGYkAigBI6vh9ZwoXP53uZoAYcvhwdA3mAVbI2aSb+9zFKU4IURB6j/HoPUIEa2G3iGIAhQQDlAUIoE2diabIklISS0NoFPebo77RF6OenEF3QntOm128he0GKrwHyACFoz2MgBqSGkpAEcHs47oHtN5AFakACqMNjQEMoE8SABFCHn4HE2zGHSLeEAAAAAElFTkSuQmCC"
|
||||
sizes="40x40" /> -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="description" content="The fastest way to sign PDFs & request signatures from others" />
|
||||
<!-- <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> -->
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css"
|
||||
integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA=="
|
||||
crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css"
|
||||
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous" />
|
||||
|
||||
<title>Open sign</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 11 KiB |
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"short_name": "Open sign",
|
||||
"name": "Open sign",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
||||
@@ -1,150 +0,0 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Routes, Route, BrowserRouter } from "react-router-dom";
|
||||
import Pgsignup from "./routes/Pgsignup";
|
||||
import Login from "./routes/Login";
|
||||
import Microapp from "./routes/RemoteApp";
|
||||
import Signup from "./routes/Signup";
|
||||
import Form from "./routes/Form";
|
||||
import Report from "./routes/Report";
|
||||
import Dashboard from "./routes/Dashboard";
|
||||
import PlanSubscriptions from "./routes/PlanSubscriptions";
|
||||
import HomeLayout from "./layout/HomeLayout";
|
||||
import UserProfile from "./routes/UserProfile";
|
||||
import PageNotFound from "./routes/PageNotFound";
|
||||
import ForgetPassword from "./routes/ForgetPassword";
|
||||
import ChangePassword from "./routes/ChangePassword";
|
||||
import ReportMicroapp from "./components/ReportMicroapp";
|
||||
import LoadMf from "./routes/LoadMf";
|
||||
|
||||
function App() {
|
||||
const [isloading, setIsLoading] = useState(true);
|
||||
useEffect(() => {
|
||||
handleCredentials();
|
||||
}, []);
|
||||
|
||||
const handleCredentials = () => {
|
||||
const appId = process.env.REACT_APP_APPID;
|
||||
const baseurl = process.env.REACT_APP_SERVERURL;
|
||||
const appName = "contracts";
|
||||
try {
|
||||
localStorage.setItem("BaseUrl12", `${baseurl}/`);
|
||||
localStorage.setItem("AppID12", appId);
|
||||
localStorage.setItem("domain", appName);
|
||||
setIsLoading(false);
|
||||
} catch (error) {
|
||||
console.log("err ", error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-[#eef1f5]">
|
||||
{isloading ? (
|
||||
<div
|
||||
style={{
|
||||
height: "100vh",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontSize: "45px",
|
||||
color: "#3dd3e0"
|
||||
}}
|
||||
className="loader-37"
|
||||
></div>
|
||||
</div>
|
||||
) : (
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route exact path="/" element={<Login />} />
|
||||
<Route exact path="/signup" element={<Signup />} />
|
||||
<Route exact path="/loadmf/:remoteApp/*" element={<LoadMf />} />
|
||||
<Route exact path="/forgetpassword" element={<ForgetPassword />} />
|
||||
{process.env.REACT_APP_ENABLE_SUBSCRIPTION && (
|
||||
<>
|
||||
<Route exact path="/pgsignup" element={<Pgsignup />} />
|
||||
<Route
|
||||
exact
|
||||
path="/subscription"
|
||||
element={<PlanSubscriptions />}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<Route
|
||||
exact
|
||||
path="/changepassword"
|
||||
element={
|
||||
<HomeLayout>
|
||||
<ChangePassword />
|
||||
</HomeLayout>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/mf/:remoteApp/*"
|
||||
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 exact path="/ForgotPassword" element={<ForgotPassword />} /> */}
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
@@ -1,62 +0,0 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import "./index.css";
|
||||
import App from "./App";
|
||||
import { Provider } from "react-redux";
|
||||
import { store } from "./redux/store";
|
||||
import { HTML5Backend } from "react-dnd-html5-backend";
|
||||
import { TouchBackend } from "react-dnd-touch-backend";
|
||||
import {
|
||||
DndProvider,
|
||||
TouchTransition,
|
||||
MouseTransition,
|
||||
Preview
|
||||
} from "react-dnd-multi-backend";
|
||||
import DragElement from "./microappComponent/DragElement";
|
||||
import TagManager from "react-gtm-module";
|
||||
|
||||
const HTML5toTouch = {
|
||||
backends: [
|
||||
{
|
||||
id: "html5",
|
||||
backend: HTML5Backend,
|
||||
transition: MouseTransition
|
||||
},
|
||||
{
|
||||
id: "touch",
|
||||
backend: TouchBackend,
|
||||
options: { enableMouseEvents: true },
|
||||
preview: true,
|
||||
transition: TouchTransition
|
||||
}
|
||||
]
|
||||
};
|
||||
const generatePreview = (props) => {
|
||||
const { item, style } = props;
|
||||
const newStyle = {
|
||||
...style
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={newStyle}>
|
||||
<DragElement {...item} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
if (process.env.REACT_APP_GTM) {
|
||||
const tagManagerArgs = {
|
||||
gtmId: process.env.REACT_APP_GTM
|
||||
};
|
||||
TagManager.initialize(tagManagerArgs);
|
||||
}
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById("root"));
|
||||
root.render(
|
||||
<Provider store={store}>
|
||||
<DndProvider options={HTML5toTouch}>
|
||||
<Preview>{generatePreview}</Preview>
|
||||
<App />
|
||||
</DndProvider>
|
||||
</Provider>
|
||||
);
|
||||
|
Before Width: | Height: | Size: 805 B |
|
Before Width: | Height: | Size: 5.2 KiB |
@@ -1,184 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="691.365" height="586.346" viewBox="0 0 691.365 586.346">
|
||||
<defs>
|
||||
<linearGradient id="linear-gradient" x1="0.5" y1="1" x2="0.5" y2="-0.001" gradientUnits="objectBoundingBox">
|
||||
<stop offset="0" stop-color="gray" stop-opacity="0.251"/>
|
||||
<stop offset="0.54" stop-color="gray" stop-opacity="0.122"/>
|
||||
<stop offset="1" stop-color="gray" stop-opacity="0.102"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Group_644" data-name="Group 644" transform="translate(-588.635 -80)">
|
||||
<g id="Group_642" data-name="Group 642" transform="translate(22538.635 6999)">
|
||||
<path id="Path_472" data-name="Path 472" d="M482.764,637.675c51.612-29.22,67.336-29.693,124.954-17.169,81.646,17.758,88.43-49.93,108.306-186.933,33.946-233.98-108.306-295.737-108.306-295.737s-94.6-8.1-150.536-38.963C377.726,55.027,286.9,49.443,207.046,86.542c-51.069,23.7-93.125,56.714-100.31,102.034-20.09,126.746,12.9,196.58-48.819,237.954S48.944,581.5,96.263,577.564c34.968-2.906,80.842,52.415,130.687,60.111,17.382,2.684,88.7-13.043,99.578,0C341.327,655.4,464.763,647.87,482.764,637.675Z" transform="translate(-21979.895 -6980.982)" fill="#00ddf1" opacity="0.1"/>
|
||||
<g id="Group_641" data-name="Group 641" transform="translate(-21545.08 -6816.88)">
|
||||
<rect id="Rectangle_263" data-name="Rectangle 263" width="217.867" height="15.073" transform="translate(0 39.052)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_264" data-name="Rectangle 264" width="217.867" height="15.073" transform="translate(0 104.137)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_265" data-name="Rectangle 265" width="217.867" height="15.073" transform="translate(0 171.964)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_266" data-name="Rectangle 266" width="13.702" height="39.052" transform="translate(19.183)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_267" data-name="Rectangle 267" width="13.702" height="2.74" transform="translate(19.183 6.166)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_268" data-name="Rectangle 268" width="13.702" height="2.74" transform="translate(19.183 27.405)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_269" data-name="Rectangle 269" width="13.702" height="39.052" transform="translate(39.737)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_270" data-name="Rectangle 270" width="13.702" height="2.74" transform="translate(39.737 6.166)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_271" data-name="Rectangle 271" width="13.702" height="2.74" transform="translate(39.737 27.405)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_272" data-name="Rectangle 272" width="13.702" height="39.052" transform="translate(60.29)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_273" data-name="Rectangle 273" width="13.702" height="2.74" transform="translate(60.29 6.166)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_274" data-name="Rectangle 274" width="13.702" height="2.74" transform="translate(60.29 27.405)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_275" data-name="Rectangle 275" width="13.702" height="39.052" transform="translate(80.844)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_276" data-name="Rectangle 276" width="13.702" height="2.74" transform="translate(80.844 6.166)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_277" data-name="Rectangle 277" width="13.702" height="2.74" transform="translate(80.844 27.405)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_278" data-name="Rectangle 278" width="13.702" height="39.052" transform="translate(101.397)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_279" data-name="Rectangle 279" width="13.702" height="2.74" transform="translate(101.397 6.166)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_280" data-name="Rectangle 280" width="13.702" height="2.74" transform="translate(101.397 27.405)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_281" data-name="Rectangle 281" width="13.702" height="39.052" transform="translate(121.95)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_282" data-name="Rectangle 282" width="13.702" height="2.74" transform="translate(121.95 6.166)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_283" data-name="Rectangle 283" width="13.702" height="2.74" transform="translate(121.95 27.405)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_284" data-name="Rectangle 284" width="13.702" height="39.052" transform="translate(142.504)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_285" data-name="Rectangle 285" width="13.702" height="2.74" transform="translate(142.504 6.166)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_286" data-name="Rectangle 286" width="13.702" height="2.74" transform="translate(142.504 27.405)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_287" data-name="Rectangle 287" width="13.702" height="39.052" transform="matrix(0.894, -0.448, 0.448, 0.894, 135.847, 138.025)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_288" data-name="Rectangle 288" width="13.702" height="2.74" transform="matrix(0.894, -0.448, 0.448, 0.894, 138.614, 143.541)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_289" data-name="Rectangle 289" width="13.702" height="2.74" transform="matrix(0.894, -0.448, 0.448, 0.894, 148.128, 162.529)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_290" data-name="Rectangle 290" width="13.702" height="39.052" transform="translate(19.183 65.771)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_291" data-name="Rectangle 291" width="13.702" height="2.74" transform="translate(19.183 71.937)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_292" data-name="Rectangle 292" width="13.702" height="2.74" transform="translate(19.183 93.176)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_293" data-name="Rectangle 293" width="13.702" height="39.052" transform="translate(39.737 65.771)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_294" data-name="Rectangle 294" width="13.702" height="2.74" transform="translate(39.737 71.937)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_295" data-name="Rectangle 295" width="13.702" height="2.74" transform="translate(39.737 93.176)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_296" data-name="Rectangle 296" width="13.702" height="39.052" transform="translate(60.29 65.771)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_297" data-name="Rectangle 297" width="13.702" height="2.74" transform="translate(60.29 71.937)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_298" data-name="Rectangle 298" width="13.702" height="2.74" transform="translate(60.29 93.176)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_299" data-name="Rectangle 299" width="13.702" height="39.052" transform="translate(145.93 65.771)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_300" data-name="Rectangle 300" width="13.702" height="2.74" transform="translate(145.93 71.937)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_301" data-name="Rectangle 301" width="13.702" height="2.74" transform="translate(145.93 93.176)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_302" data-name="Rectangle 302" width="13.702" height="39.052" transform="translate(166.483 65.771)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_303" data-name="Rectangle 303" width="13.702" height="2.74" transform="translate(166.483 71.937)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_304" data-name="Rectangle 304" width="13.702" height="2.74" transform="translate(166.483 93.176)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_305" data-name="Rectangle 305" width="13.702" height="39.052" transform="translate(187.036 65.771)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_306" data-name="Rectangle 306" width="13.702" height="2.74" transform="translate(187.036 71.937)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_307" data-name="Rectangle 307" width="13.702" height="2.74" transform="translate(187.036 93.176)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_308" data-name="Rectangle 308" width="13.702" height="39.052" transform="translate(19.183 132.912)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_309" data-name="Rectangle 309" width="13.702" height="2.74" transform="translate(19.183 139.078)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_310" data-name="Rectangle 310" width="13.702" height="2.74" transform="translate(19.183 160.317)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_311" data-name="Rectangle 311" width="13.702" height="39.052" transform="translate(39.737 132.912)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_312" data-name="Rectangle 312" width="13.702" height="2.74" transform="translate(39.737 139.078)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_313" data-name="Rectangle 313" width="13.702" height="2.74" transform="translate(39.737 160.317)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_314" data-name="Rectangle 314" width="13.702" height="39.052" transform="translate(60.29 132.912)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_315" data-name="Rectangle 315" width="13.702" height="2.74" transform="translate(60.29 139.078)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_316" data-name="Rectangle 316" width="13.702" height="2.74" transform="translate(60.29 160.317)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_317" data-name="Rectangle 317" width="13.702" height="39.052" transform="translate(80.844 132.912)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_318" data-name="Rectangle 318" width="13.702" height="2.74" transform="translate(80.844 139.078)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_319" data-name="Rectangle 319" width="13.702" height="2.74" transform="translate(80.844 160.317)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_320" data-name="Rectangle 320" width="13.702" height="39.052" transform="translate(101.397 132.912)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_321" data-name="Rectangle 321" width="13.702" height="2.74" transform="translate(101.397 139.078)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_322" data-name="Rectangle 322" width="13.702" height="2.74" transform="translate(101.397 160.317)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_323" data-name="Rectangle 323" width="13.702" height="39.052" transform="translate(121.95 132.912)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_324" data-name="Rectangle 324" width="13.702" height="2.74" transform="translate(121.95 139.078)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_325" data-name="Rectangle 325" width="13.702" height="2.74" transform="translate(121.95 160.317)" fill="#00ddf1" opacity="0.1"/>
|
||||
<path id="Path_473" data-name="Path 473" d="M797.862,159.09v35.571h-13.7V156.48Q791.039,157.693,797.862,159.09Z" transform="translate(-621.103 -155.61)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_326" data-name="Rectangle 326" width="13.702" height="2.74" transform="translate(163.057 6.166)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_327" data-name="Rectangle 327" width="13.702" height="2.74" transform="translate(163.057 27.405)" fill="#00ddf1" opacity="0.1"/>
|
||||
<path id="Path_474" data-name="Path 474" d="M827.862,165.719v30.83h-13.7V162.43c1.781.391,3.556.8,5.33,1.22Q823.7,164.636,827.862,165.719Z" transform="translate(-630.549 -157.483)" fill="#00ddf1" opacity="0.1"/>
|
||||
<path id="Path_475" data-name="Path 475" d="M827.862,166.285v.685h-13.7v-2.74h5.33Q823.7,165.2,827.862,166.285Z" transform="translate(-630.549 -158.05)" fill="#00ddf1" opacity="0.1"/>
|
||||
<rect id="Rectangle_328" data-name="Rectangle 328" width="13.702" height="2.74" transform="translate(183.611 27.405)" fill="#00ddf1" opacity="0.1"/>
|
||||
<path id="Path_476" data-name="Path 476" d="M691.358,287.276s-4.152-1.411-6.166,2.254a6.68,6.68,0,0,0,.089,6.426,9.4,9.4,0,0,0,9.146,5.179c4.35-.233,5.8-3.549,6.166-6.639a6.851,6.851,0,0,0-9.057-7.3Z" transform="translate(-589.693 -196.649)" fill="#00ddf1"/>
|
||||
<path id="Path_477" data-name="Path 477" d="M686.2,296.239a6.68,6.68,0,0,1-.089-6.426c2-3.659,6.166-2.254,6.166-2.254l.212-.075a6.762,6.762,0,0,1,4.885.11,6.762,6.762,0,0,0-5.762-.548l-.212.075s-4.152-1.411-6.166,2.254a6.68,6.68,0,0,0,.089,6.426,9.982,9.982,0,0,0,4.7,4.446A10.277,10.277,0,0,1,686.2,296.239Z" transform="translate(-589.706 -196.595)" fill="#00ddf1" opacity="0.1"/>
|
||||
<path id="Path_478" data-name="Path 478" d="M691.42,290.06s1.542,1.213,5.282,0" transform="translate(-591.9 -197.672)" fill="#00ddf1" opacity="0.2"/>
|
||||
<path id="Path_479" data-name="Path 479" d="M690.93,277.21s2.638,7.153,2.418,9.023l2.09-.219s-3.521-6.269-2.638-8.8Z" transform="translate(-591.746 -193.626)" fill="#00ddf1"/>
|
||||
<path id="Path_480" data-name="Path 480" d="M690.93,277.21s2.638,7.153,2.418,9.023l2.09-.219s-3.521-6.269-2.638-8.8Z" transform="translate(-591.746 -193.626)" fill="#00ddf1" opacity="0.2"/>
|
||||
<path id="Path_481" data-name="Path 481" d="M702.92,277.6s-4.159-2.124-6.015-.37-2.144,6.241-2.144,6.241S701.536,284.391,702.92,277.6Z" transform="translate(-592.952 -193.414)" fill="#00ddf1"/>
|
||||
<path id="Path_482" data-name="Path 482" d="M702.92,277.6s-4.159-2.124-6.015-.37-2.144,6.241-2.144,6.241S701.536,284.391,702.92,277.6Z" transform="translate(-592.952 -193.414)" fill="#00ddf1" opacity="0.1"/>
|
||||
<path id="Path_483" data-name="Path 483" d="M694.75,283.958s1.089-5.207,8.16-5.878" transform="translate(-592.949 -193.9)" fill="#00ddf1"/>
|
||||
<path id="Path_484" data-name="Path 484" d="M819.358,386.276s-4.152-1.411-6.166,2.254a6.68,6.68,0,0,0,.089,6.426,9.4,9.4,0,0,0,9.146,5.18c4.35-.233,5.8-3.549,6.166-6.639a6.851,6.851,0,0,0-9.057-7.3Z" transform="translate(-629.999 -227.823)" fill="#00ddf1"/>
|
||||
<path id="Path_485" data-name="Path 485" d="M814.2,395.239a6.68,6.68,0,0,1-.089-6.426c2-3.659,6.166-2.254,6.166-2.254l.212-.075a6.762,6.762,0,0,1,4.885.11,6.762,6.762,0,0,0-5.762-.548l-.212.075s-4.152-1.411-6.166,2.254a6.68,6.68,0,0,0,.089,6.426,9.982,9.982,0,0,0,4.7,4.446A10.276,10.276,0,0,1,814.2,395.239Z" transform="translate(-630.011 -227.769)" fill="#00ddf1" opacity="0.1"/>
|
||||
<path id="Path_486" data-name="Path 486" d="M819.42,389.06s1.542,1.213,5.282,0" transform="translate(-632.206 -228.846)" fill="#00ddf1" opacity="0.2"/>
|
||||
<path id="Path_487" data-name="Path 487" d="M818.93,376.21s2.638,7.153,2.419,9.023l2.09-.219s-3.522-6.269-2.638-8.8Z" transform="translate(-632.051 -224.799)" fill="#00ddf1"/>
|
||||
<path id="Path_488" data-name="Path 488" d="M818.93,376.21s2.638,7.153,2.419,9.023l2.09-.219s-3.522-6.269-2.638-8.8Z" transform="translate(-632.051 -224.799)" fill="#00ddf1" opacity="0.2"/>
|
||||
<path id="Path_489" data-name="Path 489" d="M830.92,376.6s-4.159-2.124-6.015-.37-2.144,6.241-2.144,6.241S829.536,383.391,830.92,376.6Z" transform="translate(-633.257 -224.588)" fill="#00ddf1"/>
|
||||
<path id="Path_490" data-name="Path 490" d="M830.92,376.6s-4.159-2.124-6.015-.37-2.144,6.241-2.144,6.241S829.536,383.391,830.92,376.6Z" transform="translate(-633.257 -224.588)" fill="#00ddf1" opacity="0.1"/>
|
||||
<path id="Path_491" data-name="Path 491" d="M822.75,382.958s1.089-5.207,8.16-5.878" transform="translate(-633.254 -225.073)" fill="#00ddf1"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Group_643" data-name="Group 643" transform="translate(7 -63)">
|
||||
<g id="Group_639" data-name="Group 639" transform="translate(21233 8372)">
|
||||
<ellipse id="Ellipse_73" data-name="Ellipse 73" cx="49.851" cy="8.007" rx="49.851" ry="8.007" transform="translate(-20118.443 -7772.555)" fill="#00abf6" opacity="0.1"/>
|
||||
<rect id="Rectangle_182" data-name="Rectangle 182" width="3.208" height="72.224" transform="translate(-20070.199 -7917.934)" fill="#535461"/>
|
||||
<path id="Path_268" data-name="Path 268" d="M1025.906,587.251l-.2,3.254-.287,4.6-.118,1.913-.281,4.6-.123,1.913-.286,4.6-3.233,52.22a8.851,8.851,0,0,1-8.83,8.268H995.731a8.841,8.841,0,0,1-8.82-8.3l-3.244-52.225-.281-4.6-.117-1.913-.292-4.6-.117-1.913-.281-4.6-.2-3.254a4.6,4.6,0,0,1,4.574-4.865h34.391a4.6,4.6,0,0,1,4.569,4.9Z" transform="translate(-21072.734 -8433.181)" fill="#565661"/>
|
||||
<path id="Path_269" data-name="Path 269" d="M990.949,517.36l-.287,4.589H948.106l-.286-4.589Z" transform="translate(-21037.977 -8360.036)" fill="#9d9cb5"/>
|
||||
<path id="Path_270" data-name="Path 270" d="M990.93,530.08l-.281,4.594H948.9l-.286-4.594Z" transform="translate(-21038.363 -8366.248)" fill="#9d9cb5"/>
|
||||
<path id="Path_271" data-name="Path 271" d="M990.912,542.8l-.287,4.589H949.686L949.4,542.8Z" transform="translate(-21038.748 -8372.46)" fill="#9d9cb5"/>
|
||||
<path id="Path_272" data-name="Path 272" d="M933.875,490.464c18.684,13.517,26.466,34.656,26.466,34.656s-22.511-.773-41.2-14.289-26.46-34.651-26.46-34.651S915.2,476.953,933.875,490.464Z" transform="translate(-21028.934 -8381.328)" fill="#00abf6"/>
|
||||
<path id="Path_273" data-name="Path 273" d="M892.68,476.18s23.365,12.969,30.865,23.708,36.8,25.233,36.8,25.233" transform="translate(-21028.934 -8381.328)" fill="none" stroke="#535461" stroke-miterlimit="10" stroke-width="2"/>
|
||||
<path id="Path_274" data-name="Path 274" d="M975.393,443.457c10.171,7.352,14.407,18.863,14.407,18.863s-12.279-.425-22.424-7.776S953,435.68,953,435.68,965.227,436.1,975.393,443.457Z" transform="translate(-21058.393 -8361.549)" fill="#00abf6"/>
|
||||
<path id="Path_275" data-name="Path 275" d="M953,435.68s12.719,7.06,16.8,12.9,20.03,13.737,20.03,13.737" transform="translate(-21058.393 -8361.549)" fill="none" stroke="#535461" stroke-miterlimit="10" stroke-width="2"/>
|
||||
<path id="Path_276" data-name="Path 276" d="M1040.3,470.483c-11.68,12.836-14.151,29.612-14.151,29.612s16.469-4.042,28.139-16.883,14.151-29.612,14.151-29.612S1051.981,457.647,1040.3,470.483Z" transform="translate(-21094.119 -8370.301)" fill="#00abf6"/>
|
||||
<path id="Path_277" data-name="Path 277" d="M1068.45,453.61s-15.215,13.159-19.083,22.224S1026.15,500.1,1026.15,500.1" transform="translate(-21094.119 -8370.306)" fill="none" stroke="#535461" stroke-miterlimit="10" stroke-width="2"/>
|
||||
</g>
|
||||
<g id="Group_638" data-name="Group 638" transform="translate(-40 36)">
|
||||
<rect id="Rectangle_254" data-name="Rectangle 254" width="12.343" height="37.459" transform="translate(741.459 392.675)" fill="#3f3d56"/>
|
||||
<rect id="Rectangle_255" data-name="Rectangle 255" width="12.343" height="39.629" transform="translate(1073.647 390.726)" fill="#3f3d56"/>
|
||||
<path id="Path_418" data-name="Path 418" d="M597.889,523.665v8.446l-98.7.909-1.052.02-37.511.344-.9.013-11.4.1h-.338l-69.5.643L264.408,535.2h-.1l-29.007.273-.312.007L106.1,536.658v-9.745l30.306-18.19,60.808-.507,1.3-.007.429-.007,1.3-.019,29.2-.24,1.306-.007.416-.007,1.3-.006,9.362-.078.247-.006,23.1-.195h.188l180.214-1.52,4.411-.032h.442l3.365-.033,24.459-.2,1.3-.02,1.2-.013h.624l7.607-.058,1.507-.02,2.02-.013,6.334-.058,10.05-.084,1.3-.013,2.261-.013h.422l48.536-.416Z" transform="translate(566.82 43)" fill="#65617d"/>
|
||||
<path id="Path_419" data-name="Path 419" d="M597.889,523.665v8.446l-98.7.909-1.052.02-37.511.344-.9.013-11.4.1h-.338l-69.5.643L264.408,535.2h-.1l-29.007.273-.312.007L106.1,536.658v-9.745l30.306-18.19,60.808-.507,1.3-.007.429-.007,1.3-.019,29.2-.24,1.306-.007.416-.007,1.3-.006,9.362-.078.247-.006,23.1-.195h.188l180.214-1.52,4.411-.032h.442l3.365-.033,24.459-.2,1.3-.02,1.2-.013h.624l7.607-.058,1.507-.02,2.02-.013,6.334-.058,10.05-.084,1.3-.013,2.261-.013h.422l48.536-.416Z" transform="translate(566.82 43)" opacity="0.2"/>
|
||||
<path id="Path_420" data-name="Path 420" d="M358.914,656.57v15.91a3.982,3.982,0,0,1-2.274,3.6,3.9,3.9,0,0,1-1.624.39l-22.673.481a3.9,3.9,0,0,1-1.754-.37,3.976,3.976,0,0,1-2.319-3.619V656.57Z" transform="translate(437.441 -122.381)" fill="#3f3d56"/>
|
||||
<path id="Path_421" data-name="Path 421" d="M358.914,656.57v15.91a3.982,3.982,0,0,1-2.274,3.6,3.9,3.9,0,0,1-1.624.39l-22.673.481a3.9,3.9,0,0,1-1.754-.37,3.976,3.976,0,0,1-2.319-3.619V656.57Z" transform="translate(437.441 -122.381)" opacity="0.1"/>
|
||||
<path id="Path_422" data-name="Path 422" d="M360.914,656.57v15.91a3.982,3.982,0,0,1-2.274,3.6,3.9,3.9,0,0,1-1.624.39l-22.673.481a3.9,3.9,0,0,1-1.754-.37,3.976,3.976,0,0,1-2.319-3.619V656.57Z" transform="translate(436.74 -122.381)" fill="#3f3d56"/>
|
||||
<rect id="Rectangle_256" data-name="Rectangle 256" width="30.644" height="20.464" transform="translate(1046.362 534.189)" fill="#3f3d56"/>
|
||||
<rect id="Rectangle_257" data-name="Rectangle 257" width="30.644" height="20.464" transform="translate(1046.362 534.189)" opacity="0.1"/>
|
||||
<rect id="Rectangle_258" data-name="Rectangle 258" width="30.644" height="20.464" transform="translate(1045.062 534.189)" fill="#3f3d56"/>
|
||||
<path id="Path_423" data-name="Path 423" d="M223.943,265.82v3.723l-12.343-.318v-3.4Z" transform="translate(529.859 126.848)" opacity="0.1"/>
|
||||
<path id="Path_424" data-name="Path 424" d="M358.741,271.246,343.909,377.789a2.794,2.794,0,0,1-2.839,2.41L222.314,377.12l-2.254-.058a2.794,2.794,0,0,1-2.7-3.164l16.651-111.533a2.794,2.794,0,0,1,2.949-2.358l119.186,8.069a2.787,2.787,0,0,1,2.6,3.17Z" transform="translate(476.307 16.556)" fill="#65617d"/>
|
||||
<path id="Path_425" data-name="Path 425" d="M169.158,99.16,156.6,197.472l109.142,3.463,13.422-94.85Z" transform="translate(549.128 185.237)" fill="#00ddf1"/>
|
||||
<rect id="Rectangle_259" data-name="Rectangle 259" width="132.965" height="112.605" rx="5.33" transform="translate(853.849 282.877)" fill="#65617d"/>
|
||||
<rect id="Rectangle_260" data-name="Rectangle 260" width="120.836" height="93.765" transform="translate(860.125 290.458)" fill="#00ddf1"/>
|
||||
<path id="Path_426" data-name="Path 426" d="M735.273,262.82v2.462l-12.343.253V262.82Z" transform="translate(350.717 127.899)" opacity="0.1"/>
|
||||
<path id="Path_427" data-name="Path 427" d="M833.626,371a2,2,0,0,1-1.949,2.131l-121.615,2.514a2,2,0,0,1-2.033-1.813L697.575,265.156a2,2,0,0,1,1.9-2.189l120.693-6,1.3-.065a1.994,1.994,0,0,1,2.092,1.819Z" transform="translate(308.06 17.643)" fill="#65617d"/>
|
||||
<path id="Path_428" data-name="Path 428" d="M628.93,100.238,739.157,94.82l9.31,98.748-109.356,2.6Z" transform="translate(383.65 186.757)" fill="#00ddf1"/>
|
||||
<path id="Path_429" data-name="Path 429" d="M899.741,371a2,2,0,0,1-1.949,2.131L886.28,256.963l1.3-.065a2,2,0,0,1,2.092,1.819Z" transform="translate(241.945 17.643)" opacity="0.1"/>
|
||||
<rect id="Rectangle_261" data-name="Rectangle 261" width="12.343" height="11.096" transform="translate(741.459 419.038)" opacity="0.1"/>
|
||||
<path id="Path_431" data-name="Path 431" d="M281.574,483.65v3.229l-30.644.819V483.65Z" transform="translate(516.08 50.533)" opacity="0.1"/>
|
||||
<path id="Path_432" data-name="Path 432" d="M390.8,483.886V593.158a2.6,2.6,0,0,1-2.5,2.566l-124.506,3.313h-.033a2.6,2.6,0,0,1-2.566-2.566V483.886a2.6,2.6,0,0,1,2.566-2.566H388.23A2.6,2.6,0,0,1,390.8,483.886Z" transform="translate(460.942 -60.983)" fill="#65617d"/>
|
||||
<path id="Path_434" data-name="Path 434" d="M194.6,319.15H309.914v96.311L194.6,418.06Z" transform="translate(535.815 108.164)" fill="#d4dfec"/>
|
||||
<rect id="Rectangle_262" data-name="Rectangle 262" width="12.343" height="11.317" transform="translate(1073.647 419.038)" opacity="0.1"/>
|
||||
<path id="Path_435" data-name="Path 435" d="M709.574,483.65v4.164L678.93,487V483.65Z" transform="translate(366.132 50.533)" opacity="0.1"/>
|
||||
<path id="Path_436" data-name="Path 436" d="M797.782,483.886V596.471a2.6,2.6,0,0,1-2.6,2.566h0l-124.532-3.313a2.6,2.6,0,0,1-2.5-2.566V483.886a2.6,2.6,0,0,1,2.566-2.566H795.19a2.6,2.6,0,0,1,2.592,2.566Z" transform="translate(318.365 -60.983)" fill="#65617d"/>
|
||||
<path id="Path_437" data-name="Path 437" d="M866.289,483.886V596.471a2.6,2.6,0,0,1-2.6,2.566h0V481.32h0a2.6,2.6,0,0,1,2.6,2.566Z" transform="translate(249.859 -60.983)" opacity="0.1"/>
|
||||
<path id="Path_438" data-name="Path 438" d="M713.414,319.15H598.1v96.311l115.314,2.6Z" transform="translate(394.451 108.164)" fill="#d4dfec"/>
|
||||
<path id="Path_439" data-name="Path 439" d="M593.3,483.886V593.158a2.6,2.6,0,0,1-2.5,2.566l-124.506,3.313h0a2.6,2.6,0,0,1-2.6-2.566V483.886a2.6,2.6,0,0,1,2.566-2.566H590.73A2.6,2.6,0,0,1,593.3,483.886Z" transform="translate(389.997 -60.983)" fill="#65617d"/>
|
||||
<path id="Path_440" data-name="Path 440" d="M397.1,319.15H512.414v96.311L397.1,418.06Z" transform="translate(464.87 108.164)" fill="#d4dfec"/>
|
||||
<path id="Path_441" data-name="Path 441" d="M597.889,533.65V542.1l-98.7.909-1.052.02-37.511.344-.9.013-11.4.1h-.338l-69.5.643-114.086,1.059h-.1l-29.007.273-.312.007L106.1,546.643V536.9l131.562-.864h.312l26.629-.182h.123l183.9-1.215h.188l.11-.006h.305l3.112-.019h.948l48.393-.325,2.858-.013.637-.007Z" transform="translate(566.82 33.015)" opacity="0.1"/>
|
||||
<circle id="Ellipse_99" data-name="Ellipse 99" cx="33.347" cy="33.347" r="33.347" transform="translate(887.196 363.44)" fill="#fbbebe"/>
|
||||
<path id="Path_442" data-name="Path 442" d="M383.74,592.973a.806.806,0,0,1,.065-.227c.65-2.332,1.806-6.276,2.67-9.427.11-.39.214-.773.312-1.137.955-3.554,2.813-11.876,3.846-17.066.364-1.826.65-3.248.708-3.963.13-1.1,2.085-5.795,4.3-11.194,1.553-3.794,3.248-7.939,4.489-11.434a39.876,39.876,0,0,0,1.9-6.4,3.313,3.313,0,0,0,0-1.384,9.543,9.543,0,0,1-.312-2.274h0c-.149-4.028,1.052-10.394,2.91-13.065,2.274-3.248,3.9-15.371,3.9-15.371s3.365.487,3.9-2.293a4,4,0,0,0,.065-.91,4.815,4.815,0,0,0-.058-.721c-.578-4.054,9.563-8.368,15.267-9.3a12.769,12.769,0,0,1,1.949-.182,17.694,17.694,0,0,0,4.06-.935q.909-.279,1.949-.65c2.391-.806,5.249-1.871,8.283-3.04,11.408-4.424,25.22-10.394,25.22-10.394.1-.461.208-.9.331-1.338a18,18,0,0,1,10.622-12.3h0v-1.3c0-2.241-.1-4.548-.195-6.847,0-.448-.039-.9-.065-1.345v-.734c0-.455-.046-.91-.071-1.358l-.117-.091a10.66,10.66,0,0,1-2.534-2.729,9.916,9.916,0,0,1-.923-1.949c-.812-2.2-1-4.658-1.546-6.984l-.117-.481a54.579,54.579,0,0,0-2.6-6.873c-1.436-3.521-2.54-7.146-3.638-10.817q-1-3.333-2.02-6.678l-1.026-3.4c-.195-.65-.39-1.3-.539-1.949h0a8.627,8.627,0,0,1-.169-.91h0a6.5,6.5,0,0,1,.156-2.995,20.854,20.854,0,0,1,.858-1.949,5.113,5.113,0,0,0,.325-.9h0a1.947,1.947,0,0,0,.052-.208,3.667,3.667,0,0,0,.071-.7,11.993,11.993,0,0,0-.338-2.527.045.045,0,0,1,0-.032,1.661,1.661,0,0,0-.032-.175,16.564,16.564,0,0,1-.234-1.949,18.483,18.483,0,0,1,2.254-10.115l.123-.234a16.383,16.383,0,0,1,1.2-1.806h0a9.122,9.122,0,0,1,.65-.793,2.594,2.594,0,0,1-3.606-.936,2.475,2.475,0,0,1-.149-.292c-.033-.078-.059-.162-.085-.247-.455-1.592.338-3.287,1.377-4.58a12.012,12.012,0,0,1,3.729-3.053h0a2.51,2.51,0,0,1,.26-.136,11.125,11.125,0,0,1,1.715-.689h0a9.781,9.781,0,0,1,1.059-.286l-2.41-.221-.974-.091A9.414,9.414,0,0,1,479,361.527h.7a7.625,7.625,0,0,1,1.02.084A2.885,2.885,0,0,1,479,358.8a9.362,9.362,0,0,0,5.97,1.988h.247a19.494,19.494,0,0,1-.221-2.124h0a21.545,21.545,0,0,1,0-2.9,5.483,5.483,0,0,0,4.4,1.468l-1.351-1.884a6.165,6.165,0,0,0,4.262,1.332l.312-.033a4.547,4.547,0,0,0,.773-.149h.058c-.123-.156-.234-.318-.344-.487l-.039-.078a6.282,6.282,0,0,1-.65-1.358,4.284,4.284,0,0,1-.156-.565h0a5.684,5.684,0,0,1,.292-3.541c2.1,1.754,4.4,4.151,7.146,2.339s2.839-5.139,7.146-4.8a6.626,6.626,0,0,1,5.464,3.976,4.385,4.385,0,0,1,4.983-1.137,4.45,4.45,0,0,1,2.521,4.476c1.786-.448,3.71-.89,5.425-.214s2.82,2.865,1.845,4.327a.931.931,0,0,1-.091.13c-.8,1.033-2.566,1.6-2.378,2.9l.273.195.845.611q4.97,3.586,9.68,7.536c1.611,1.351,3.326,2.975,3.437,5.087a5.617,5.617,0,0,1-.156,1.54h0c-.1.507-.247,1.013-.357,1.52a12.676,12.676,0,0,0-.221,3.93h0c.045.383.1.76.175,1.143.994,5.022,5.009,9.167,5.405,14.292v.364a11.546,11.546,0,0,1-.045,1.644c-.3,3.118-1.741,6.113-2.91,9.1-.072.182-.143.364-.208.546a90.5,90.5,0,0,0-4.548,18.294,65.14,65.14,0,0,1-1.3,6.555,17.365,17.365,0,0,1-3.307,6.776,10.536,10.536,0,0,1-2.183,1.949,12.132,12.132,0,0,1-1.722.916v.039c.071.4.13.793.2,1.189.039.208.071.416.11.65h0a.089.089,0,0,0,0,.039c.546,3.073,1.169,6.081,1.826,8.939l.331,1.423c8.186,2.956,9.154,9.011,9.212,11.33a6.259,6.259,0,0,1,0,.929s12.343.325,17.216,3.9a13.21,13.21,0,0,0,2.93,1.494,53.917,53.917,0,0,0,6.009,1.877c1.046.273,2.137.539,3.248.8,1.949.448,4.015.884,6.009,1.3,5.321,1.072,10.33,1.949,12.87,2.6,6.061,1.533,19.925,14.825,19.925,14.825s1.624,13.409,3.248,15.364,4.548,8.829,4.548,8.829l10.745,19.106,4.548,8.036h2.923a4.97,4.97,0,0,1,2.085,1.364c.773.689,1.631,1.546,2.384,2.326l1.247,1.332.78.864s4.723.117,6,3.852c3.846-.11,8.569.143,11.876,1.624a9.187,9.187,0,0,1,1.3.7,5.639,5.639,0,0,1,2.683,3.677,5.422,5.422,0,0,1,.117.935c0,.37,0,.741,0,1.1-.234,4.918-3.437,9.011-6.38,11.765l.208.37s-.1.234-.286.65c-.052.123-.117.26-.188.416h0c-.383.819-.994,2.046-1.793,3.482a41.136,41.136,0,0,1-6.217,8.556l-.188.195-37.511.344-.11-.13-7.276-8.679-3.619-4.314-.11-.136-.1,1.033-.351,3.443-.845,8.322-.045.416v.11l-.1.961.071-.961h-.188l-69.513.65-114.092,1.26v.546h-.091v-.546l-29.072.312Z" transform="translate(418.007 -14.269)" fill="url(#linear-gradient)"/>
|
||||
<path id="Path_443" data-name="Path 443" d="M586.185,511.522s-64.641,7.8-58.469,0c2.235-2.82,2.852-11.174,2.729-20.691-.039-2.891-.143-5.886-.292-8.868-.715-14.292-2.436-28.26-2.436-28.26s56.52-26.636,50.023-5.522c-2.6,8.53-1.748,20.51.227,31.755.578,3.281,1.247,6.5,1.949,9.55a223.892,223.892,0,0,0,6.269,22.036Z" transform="translate(367.711 -46.521)" fill="#fbbebe"/>
|
||||
<path id="Path_444" data-name="Path 444" d="M586.185,537.354s-64.641,7.8-58.469,0c2.235-2.82,2.852-11.174,2.729-20.692,9.855-4.21,22.394-1.072,22.394-1.072,13.2-2.631,21.666-2.118,27.078-.273A223.888,223.888,0,0,0,586.185,537.354Z" transform="translate(367.711 -72.353)" opacity="0.1"/>
|
||||
<path id="Path_445" data-name="Path 445" d="M413.346,651.973v-.546l114.092-1.241,69.513-.65h.195l-.071.961.1-.961h.123v-.11l.89-8.738.338-3.307.1-1.033.091-.864,4.015-13.389,4.015-13.37,3.378-11.258,5.158-17.2s-2.923-6.821-4.548-8.77-3.248-15.267-3.248-15.267-13.864-13.208-19.925-14.728c-2.54-.65-7.555-1.514-12.883-2.6-1.994-.4-4.041-.832-6.009-1.3-1.111-.253-2.2-.52-3.248-.786a57.086,57.086,0,0,1-6.009-1.858,13.448,13.448,0,0,1-2.924-1.488c-4.775-3.5-16.742-3.9-17.2-3.9h0a.269.269,0,0,1,0-.045v-.058a6.66,6.66,0,0,0,0-.819,5.208,5.208,0,0,0-.059-.91.82.82,0,0,0-.045-.325c-.032-.234-.071-.481-.13-.741a3.226,3.226,0,0,0-.078-.344,11.181,11.181,0,0,0-.812-2.267c-.045-.1-.1-.214-.156-.318a11.861,11.861,0,0,0-1.1-1.709c-.084-.11-.175-.227-.273-.338a12.721,12.721,0,0,0-1.767-1.715c-.175-.136-.357-.279-.546-.409a3.026,3.026,0,0,0-.331-.234l-.578-.377-.539-.312c-.474-.26-.974-.513-1.52-.754-.169-.078-.351-.149-.533-.221s-.468-.182-.708-.273h-.039l-.487-.195c-.37-.123-.747-.234-1.143-.344l-.6-.156-.65-.149-.65-.136c-.65-.13-1.345-.247-2.072-.338l-.741-.091-.76-.078-.786-.065-1.117-.065-1.3-.045a81.017,81.017,0,0,0-17.054,1.814,46.946,46.946,0,0,0-11.855-1.093h-.565l-.65.039h-.416l-.838.078a6.224,6.224,0,0,0-.845.1c-.279.039-.572.071-.851.117l-.429.071c-.422.071-.851.149-1.3.24q-.214.039-.429.1c-.565.123-1.13.273-1.689.442-.279.078-.559.169-.838.266-.143.039-.279.091-.416.143l-.416.149-.409.162-.487.195c-.247.1-.487.214-.728.331-.136.058-.273.123-.4.195s-.266.13-.39.2a18.03,18.03,0,0,0-4.034,2.846l-.331.318-.325.331c-.11.11-.214.227-.318.344a15.473,15.473,0,0,0-1.182,1.462c-.1.136-.2.273-.3.416a17.335,17.335,0,0,0-1.117,1.9c-.084.156-.162.318-.24.474a21.243,21.243,0,0,0-1.3,3.411q-.182.65-.331,1.3s-13.753,6.068-25.161,10.46c-3.034,1.169-5.892,2.228-8.283,3.027-.7.234-1.345.448-1.949.65a17.347,17.347,0,0,1-4.06.935,12.778,12.778,0,0,0-1.949.182c-5.243.851-14.227,4.548-15.208,8.257a2.4,2.4,0,0,0-.065.91v.071c.65,4.548-3.9,3.9-3.9,3.9s-1.624,12.019-3.9,15.267c-1.644,2.339-2.768,7.555-2.91,11.492h0a12.741,12.741,0,0,0,.286,3.658v.091c.26.871-.364,3.248-1.423,6.3-1.15,3.346-2.826,7.5-4.437,11.427-2.43,5.925-4.716,11.3-4.859,12.486-.058.526-.227,1.468-.461,2.683-.948,4.95-3.053,14.377-4.093,18.19-.773,2.845-1.9,6.743-2.67,9.42a.91.91,0,0,1-.065.227l29.124-.286v.546h.091Z" transform="translate(417.856 -73.042)" fill="#00ddf1"/>
|
||||
<path id="Path_446" data-name="Path 446" d="M445.44,607.57s37.03,19.165,50.348,16.891Z" transform="translate(396.391 -105.214)" opacity="0.1"/>
|
||||
<path id="Path_447" data-name="Path 447" d="M561.44,595.57s36.056,11.694,48.074,13.318S561.44,595.57,561.44,595.57Z" transform="translate(355.751 -101.01)" opacity="0.1"/>
|
||||
<path id="Path_448" data-name="Path 448" d="M585.443,530.686c-18.84,3.469-54.311,2.722-69.643,2.2,5.62-20.139,33.022-13.292,33.022-13.292C582.74,512.821,585.339,526.866,585.443,530.686Z" transform="translate(371.74 -73.754)" opacity="0.1"/>
|
||||
<path id="Path_449" data-name="Path 449" d="M585.443,528.686c-18.84,3.469-54.311,2.722-69.643,2.2,5.62-20.139,33.022-13.292,33.022-13.292C582.74,510.821,585.339,524.866,585.443,528.686Z" transform="translate(371.74 -73.053)" fill="#00ddf1"/>
|
||||
<path id="Path_450" data-name="Path 450" d="M776.94,672.008s22.192-3.411,22.628,6.334S788.25,694.9,788.25,694.9Z" transform="translate(280.251 -127.587)" fill="#fbbebe"/>
|
||||
<path id="Path_451" data-name="Path 451" d="M578.17,479.936a30.558,30.558,0,0,1-2.923,1.13c-7,2.417-14.065,4.853-21.439,5.736s-15.111.1-21.543-3.573a18.685,18.685,0,0,1-1.949-1.267c-.715-14.292-2.436-28.26-2.436-28.26s56.52-26.636,50.023-5.522C575.318,456.711,576.195,468.69,578.17,479.936Z" transform="translate(367.508 -46.521)" opacity="0.1"/>
|
||||
<path id="Path_452" data-name="Path 452" d="M536.9,360.29a6.153,6.153,0,0,1-5.405-1.137l1.351,1.878a5.5,5.5,0,0,1-4.4-1.462,22.146,22.146,0,0,0,.208,5.035,9.433,9.433,0,0,1-6.211-1.949,2.872,2.872,0,0,0,1.715,2.8,9.316,9.316,0,0,0-10.135,6.958l3.391.312a12,12,0,0,0-6.782,4.138c-1.039,1.3-1.832,2.962-1.377,4.548s2.651,2.6,3.846,1.468a18.151,18.151,0,0,0-3.963,14.806,9.4,9.4,0,0,1,.3,3.417,28.993,28.993,0,0,1-1.228,3.047c-.65,1.9-.032,3.956.546,5.847l3.047,10.018c1.1,3.619,2.2,7.244,3.645,10.745a53.328,53.328,0,0,1,2.6,6.828c.819,3.144.851,6.588,2.6,9.336a12.948,12.948,0,0,0,4.665,4.112c6.425,3.677,14.188,4.457,21.542,3.573s14.409-3.32,21.406-5.736a20.141,20.141,0,0,0,4.444-1.949c4.84-3.17,5.918-9.654,6.821-15.364a87.242,87.242,0,0,1,4.736-18.71c1.416-3.567,3.248-7.185,2.936-11.005-.4-5.074-4.411-9.186-5.405-14.175a12.344,12.344,0,0,1,.045-5.048,11.473,11.473,0,0,0,.513-3.053c-.11-2.092-1.826-3.7-3.437-5.048q-5.243-4.379-10.823-8.277c-.188-1.3,1.579-1.858,2.378-2.884,1.13-1.449-.039-3.748-1.754-4.424s-3.638-.234-5.425.214a4.281,4.281,0,0,0-7.5-3.32,6.627,6.627,0,0,0-5.47-3.95c-4.307-.338-4.392,2.956-7.146,4.768s-5.028-.578-7.146-2.319A6.029,6.029,0,0,0,536.9,360.29Z" transform="translate(374.5 -15.625)" fill="#3f3d56"/>
|
||||
<path id="Path_453" data-name="Path 453" d="M768.171,669.128s-.578,1.377-1.644,3.372a44.83,44.83,0,0,1-5.847,8.556l-.175.188h-1.052l-37.511.344h-.9l-.11-.13-7.276-8.634-2.741-3.255-.11-.136-.234-.273-.13-.156-.169-.2-5.334-6.328,1.949-8.121,3.32-13.682.084-.331.65-2.6.461-1.949,1.546-6.354,5.3-21.861,9.42,4.872,9.933,17.541,5.334,9.42h2.923c.552,0,1.819,1.065,3.092,2.293.455.435.91.9,1.3,1.3,1.156,1.2,2.072,2.222,2.072,2.222s4.736.1,6.009,3.833a4.537,4.537,0,0,1,.162.552,26.191,26.191,0,0,0,1.644,4.262c.838,1.826,1.891,3.9,2.956,5.97,1.981,3.8,4,7.419,4.736,8.731l.091.162Z" transform="translate(305.476 -105.217)" fill="#00ddf1"/>
|
||||
<path id="Path_454" data-name="Path 454" d="M615.681,653.093l-.065.929v.065l-.11,1.494-.864,12.025L613.6,682.093l-.3,4.08-.65,8.731v.11l-69.513.65L429.061,696.9v.546h-.091v-.728l.292-9.329.559-18.229L430.3,653.7l.045-1.54a6.841,6.841,0,0,1,7.419-6.607c3.066.26,7.049.578,11.811.916l1.949.143c27.5,1.91,78.322,4.379,129.606,1.3,1.078-.059,2.163-.123,3.248-.2,7.952-.5,15.9-1.143,23.764-1.949a6.841,6.841,0,0,1,7.536,7.3Z" transform="translate(402.161 -118.514)" opacity="0.1"/>
|
||||
<path id="Path_455" data-name="Path 455" d="M429.08,698.857v-.546l114.092-1.241,69.513-.65h.195v-.11l.65-8.731.279-3.9,1.065-14.689.838-11.629v-.286a6.893,6.893,0,0,0-.071-1.6.2.2,0,0,0,0-.065,6.751,6.751,0,0,0-1.3-3.014,6.847,6.847,0,0,0-6.12-2.6c-7.867.806-15.813,1.449-23.764,1.949-1.085.078-2.17.143-3.248.2-51.284,3.047-102.106.578-129.606-1.3l-1.949-.143c-4.762-.338-8.744-.65-11.811-.916a6.847,6.847,0,0,0-7.3,5.542,7.146,7.146,0,0,0-.117,1.065l-.442,14.4-.6,18.236-.286,9.329v.728Z" transform="translate(402.122 -119.926)" fill="#3f3d56"/>
|
||||
<path id="Path_456" data-name="Path 456" d="M615.925,661.692l-.8,9.959L613.937,686.5l-.3,3.716-.65,8.322-.039.416v.11h0l-.1.961.071-.961h-.188l-69.513.65L429.11,700.944v-.182l.318-9.329.65-18.229.416-12.116a4.132,4.132,0,0,1,1.988-3.411,4.061,4.061,0,0,1,2.456-.585c1.364.11,3.04.24,5,.383,3.177.234,7.094.507,11.655.793,8.445.533,19.041,1.1,31.183,1.572,33.782,1.3,79.388,1.735,122.707-2.059,1.949-.169,3.963-.357,5.931-.546a4.066,4.066,0,0,1,2.261.429,3.346,3.346,0,0,1,.559.351,3.989,3.989,0,0,1,1.3,1.6,2.315,2.315,0,0,1,.162.4A4.08,4.08,0,0,1,615.925,661.692Z" transform="translate(402.112 -122.559)" opacity="0.1"/>
|
||||
<path id="Path_457" data-name="Path 457" d="M360.914,677.87v2.072a3.982,3.982,0,0,1-2.274,3.6l-26.051.5a3.976,3.976,0,0,1-2.319-3.619v-1.949Z" transform="translate(436.74 -129.843)" opacity="0.1"/>
|
||||
<path id="Path_458" data-name="Path 458" d="M280.294,512.532l-33.944.65V507.55l33.944-.65Z" transform="translate(517.685 42.387)" fill="#3f3d56"/>
|
||||
<path id="Path_459" data-name="Path 459" d="M280.294,512.532l-33.944.65V507.55l33.944-.65Z" transform="translate(517.685 42.387)" opacity="0.1"/>
|
||||
<path id="Path_460" data-name="Path 460" d="M282.294,512.532l-33.944.65V507.55l33.944-.65Z" transform="translate(516.984 42.387)" fill="#3f3d56"/>
|
||||
<path id="Path_461" data-name="Path 461" d="M552.228,360.039A6.334,6.334,0,0,1,551,357.22a6.165,6.165,0,0,0,.273,2.988A5.847,5.847,0,0,0,552.228,360.039Z" transform="translate(359.434 -17.505)"/>
|
||||
<path id="Path_462" data-name="Path 462" d="M540.1,366.9a22.83,22.83,0,0,1-.24-2.4c0,.8,0,1.6,0,2.41Z" transform="translate(363.311 -20.056)"/>
|
||||
<path id="Path_463" data-name="Path 463" d="M621.706,398.627a11.912,11.912,0,0,1,.234-1.722,11.7,11.7,0,0,0,.52-3.047,4.008,4.008,0,0,0-.1-.689c-.11.6-.286,1.2-.416,1.787a12.433,12.433,0,0,0-.234,3.671Z" transform="translate(334.652 -30.1)"/>
|
||||
<path id="Path_464" data-name="Path 464" d="M600.922,368.894l.708.513a12.8,12.8,0,0,0,1.67-1.442,2.384,2.384,0,0,0,.247-2.365,1.95,1.95,0,0,1-.247.416C602.5,367.042,600.734,367.607,600.922,368.894Z" transform="translate(341.923 -20.441)"/>
|
||||
<path id="Path_465" data-name="Path 465" d="M518.455,380.29a8,8,0,0,0-.565,1.481,11.8,11.8,0,0,1,3.248-1.228Z" transform="translate(371.008 -25.587)"/>
|
||||
<path id="Path_466" data-name="Path 466" d="M531.888,368.979a9.637,9.637,0,0,1-1.221-.8,2.758,2.758,0,0,0,.058.767,7.7,7.7,0,0,1,1.163.033Z" transform="translate(366.534 -21.345)"/>
|
||||
<path id="Path_467" data-name="Path 467" d="M587.579,428.33c-.266,3.151-1.735,6.185-2.923,9.173a87.2,87.2,0,0,0-4.736,18.717c-.9,5.71-1.949,12.194-6.821,15.358a19.488,19.488,0,0,1-4.437,1.949c-7,2.423-14.065,4.853-21.439,5.736s-15.111.11-21.543-3.567a12.993,12.993,0,0,1-4.664-4.112c-1.735-2.748-1.767-6.191-2.6-9.336a53.424,53.424,0,0,0-2.6-6.834c-1.436-3.5-2.54-7.146-3.638-10.739q-1.527-5.009-3.047-10.024a18.716,18.716,0,0,1-.741-3.086,11.644,11.644,0,0,0,.741,5.035q1.52,5.022,3.047,10.024c1.1,3.619,2.2,7.244,3.638,10.739a53.417,53.417,0,0,1,2.6,6.834c.819,3.144.851,6.587,2.6,9.336a12.993,12.993,0,0,0,4.664,4.112c6.432,3.677,14.188,4.45,21.543,3.567s14.409-3.313,21.439-5.736a19.487,19.487,0,0,0,4.437-1.949c4.84-3.164,5.918-9.647,6.821-15.358a87.2,87.2,0,0,1,4.736-18.717c1.416-3.56,3.248-7.179,2.936-11.005C587.592,428.408,587.579,428.369,587.579,428.33Z" transform="translate(374.359 -42.418)"/>
|
||||
<path id="Path_468" data-name="Path 468" d="M510.318,421.419v-.071a9.1,9.1,0,0,0-.3-3.411,17.272,17.272,0,0,1-.253-2.157,17.769,17.769,0,0,0,.253,4.106C510.123,420.393,510.24,420.906,510.318,421.419Z" transform="translate(373.864 -38.021)"/>
|
||||
<path id="Path_469" data-name="Path 469" d="M512.452,397.929a18.02,18.02,0,0,1,1.7-2.384c-1.189,1.137-3.385.123-3.846-1.455a3.788,3.788,0,0,0,0,1.949,2.852,2.852,0,0,0,2.15,1.89Z" transform="translate(373.712 -30.422)"/>
|
||||
<path id="Path_470" data-name="Path 470" d="M762.946,656.57s2.059,7.471,0,13.968S762.946,656.57,762.946,656.57Z" transform="translate(285.475 -122.381)" opacity="0.1"/>
|
||||
<path id="Path_471" data-name="Path 471" d="M776,668.3s.864,9.485-1.085,11.168S776,668.3,776,668.3Z" transform="translate(281.189 -126.49)" opacity="0.1"/>
|
||||
<line id="Line_88" data-name="Line 88" y1="0.65" x2="66.011" transform="translate(733.267 442.068)" fill="none" stroke="#00ddf1" stroke-miterlimit="10" stroke-width="2"/>
|
||||
<line id="Line_89" data-name="Line 89" y1="0.643" x2="66.011" transform="translate(733.267 450.176)" fill="none" stroke="#00ddf1" stroke-miterlimit="10" stroke-width="2"/>
|
||||
<line id="Line_90" data-name="Line 90" y1="0.65" x2="66.011" transform="translate(733.267 458.277)" fill="none" stroke="#00ddf1" stroke-miterlimit="10" stroke-width="2"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 5.0 KiB |
@@ -1,304 +0,0 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Parse from "parse";
|
||||
import axios from "axios";
|
||||
|
||||
const AppendFormInForm = (props) => {
|
||||
const [name, setName] = useState("");
|
||||
const [phone, setPhone] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
const [addYourself, setAddYourself] = useState(false);
|
||||
const [isLoader, setIsLoader] = useState(false);
|
||||
const [isUserExist, setIsUserExist] = useState(false);
|
||||
const parseBaseUrl = localStorage.getItem("baseUrl");
|
||||
const parseAppId = localStorage.getItem("parseAppId");
|
||||
|
||||
useEffect(() => {
|
||||
checkUserExist();
|
||||
}, []);
|
||||
// Load user details from localStorage when the component mounts
|
||||
useEffect(() => {
|
||||
const savedUserDetails = JSON.parse(
|
||||
localStorage.getItem("UserInformation")
|
||||
);
|
||||
if (savedUserDetails && addYourself) {
|
||||
setName(savedUserDetails.name);
|
||||
setPhone(savedUserDetails.phone);
|
||||
setEmail(savedUserDetails.email);
|
||||
}
|
||||
}, [addYourself]);
|
||||
|
||||
const checkUserExist = async () => {
|
||||
const user = Parse.User.current();
|
||||
try {
|
||||
const query = new Parse.Query("contracts_Contactbook");
|
||||
query.equalTo("CreatedBy", user);
|
||||
query.equalTo("Email", user.getEmail());
|
||||
const res = await query.first();
|
||||
// console.log(res);
|
||||
if (!res) {
|
||||
setIsUserExist(true);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log("err", err);
|
||||
}
|
||||
};
|
||||
// Define a function to handle form submission
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
setIsLoader(true);
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
try {
|
||||
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 (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_Guest",
|
||||
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));
|
||||
props.details({
|
||||
value: parseData[props.valueKey],
|
||||
label: parseData[props.displayKey]
|
||||
});
|
||||
if (props.closePopup) {
|
||||
props.closePopup();
|
||||
}
|
||||
|
||||
setIsLoader(false);
|
||||
// Reset the form fields
|
||||
setAddYourself(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_Guest",
|
||||
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));
|
||||
props.details({
|
||||
value: parseData[props.valueKey],
|
||||
label: parseData[props.displayKey]
|
||||
});
|
||||
if (props.closePopup) {
|
||||
props.closePopup();
|
||||
}
|
||||
setIsLoader(false);
|
||||
// Reset the form fields
|
||||
setAddYourself(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 handleAddYourselfChange = () => {
|
||||
if (addYourself) {
|
||||
setAddYourself(false);
|
||||
setName("");
|
||||
setPhone("");
|
||||
setEmail("");
|
||||
} else {
|
||||
setAddYourself(true);
|
||||
}
|
||||
};
|
||||
const handleReset = () => {
|
||||
setAddYourself(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="h-full p-[20px]">
|
||||
{isLoader && (
|
||||
<div className="fixed inset-0 flex justify-center items-center bg-black bg-opacity-30">
|
||||
<div
|
||||
style={{
|
||||
fontSize: "45px",
|
||||
color: "#3dd3e0"
|
||||
}}
|
||||
className="loader-37"
|
||||
></div>
|
||||
</div>
|
||||
)}
|
||||
<div className="w-full mx-auto p-2">
|
||||
{isUserExist && (
|
||||
<div className="mb-3">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="addYourself"
|
||||
checked={addYourself}
|
||||
onChange={handleAddYourselfChange}
|
||||
className="form-checkbox"
|
||||
/>
|
||||
<label htmlFor="addYourself" className="ml-2 text-gray-700">
|
||||
Add Yourself
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
<form onSubmit={handleSubmit}>
|
||||
<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
|
||||
disabled={addYourself}
|
||||
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
|
||||
disabled={addYourself}
|
||||
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
|
||||
disabled={addYourself}
|
||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mt-4 flex justify-start">
|
||||
<button
|
||||
type="submit"
|
||||
className="bg-[#1ab6ce] text-sm text-white px-4 py-2 rounded shadow focus:outline-none"
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleReset()}
|
||||
className="bg-[#188ae2] text-sm text-white px-4 py-2 rounded ml-2 shadow focus:outline-none"
|
||||
>
|
||||
Reset
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AppendFormInForm;
|
||||
@@ -1,49 +0,0 @@
|
||||
import React, { Component } from "react";
|
||||
|
||||
export class ErrorBoundary extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { hasError: false };
|
||||
}
|
||||
|
||||
static getDerivedStateFromError() {
|
||||
return {
|
||||
hasError: true
|
||||
};
|
||||
}
|
||||
|
||||
componentDidCatch(error, info) {
|
||||
console.log(error);
|
||||
console.log(info);
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
return (
|
||||
<div className="p-2">
|
||||
<div
|
||||
style={{
|
||||
height: "100vh",
|
||||
display: "flex",
|
||||
|
||||
flexFlow: "column"
|
||||
}}
|
||||
>
|
||||
<h1
|
||||
style={{
|
||||
fontSize: "2em",
|
||||
fontFamily: "sans-serif",
|
||||
textShadow: "0 0 20px black"
|
||||
}}
|
||||
>
|
||||
Something went wrong.
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
|
||||
export default ErrorBoundary;
|
||||
@@ -1,51 +0,0 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Package from "../../package.json";
|
||||
|
||||
const Footer = () => {
|
||||
const [showButton, setShowButton] = useState(false);
|
||||
const handleScroll = () => {
|
||||
if (window.pageYOffset >= 50) {
|
||||
setShowButton(true);
|
||||
} else {
|
||||
setShowButton(false);
|
||||
}
|
||||
};
|
||||
|
||||
const scrollToTop = () => {
|
||||
window.scrollTo(0, 0);
|
||||
setShowButton(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("scroll", handleScroll);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const appName = "OpenSign™";
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-[#222c3c] text-[#98a6ba] text-center text-[13px] py-3">
|
||||
All Rights Reserved © {new Date().getFullYear()}
|
||||
{appName}{" "}
|
||||
(version:{" "}
|
||||
{localStorage.getItem("appVersion") &&
|
||||
`${Package.version}.${localStorage.getItem("appVersion")}`}
|
||||
)
|
||||
</div>
|
||||
<button
|
||||
className={`${
|
||||
showButton ? "block" : "hidden"
|
||||
} fixed bottom-4 right-4 px-3 p-2 text-xl bg-blue-500 text-white rounded focus:outline-none`}
|
||||
onClick={scrollToTop}
|
||||
>
|
||||
<i className="fa-solid fa-angle-up"></i>
|
||||
</button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
||||
@@ -1,82 +0,0 @@
|
||||
// FullScreenButton.js
|
||||
import React, { useState, useEffect } from "react";
|
||||
|
||||
const FullScreenButton = () => {
|
||||
const [isFullScreen, setIsFullScreen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
document.addEventListener("fullscreenchange", handleFullScreenChange);
|
||||
document.addEventListener("webkitfullscreenchange", handleFullScreenChange);
|
||||
document.addEventListener("mozfullscreenchange", handleFullScreenChange);
|
||||
document.addEventListener("MSFullscreenChange", handleFullScreenChange);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("fullscreenchange", handleFullScreenChange);
|
||||
document.removeEventListener(
|
||||
"webkitfullscreenchange",
|
||||
handleFullScreenChange
|
||||
);
|
||||
document.removeEventListener(
|
||||
"mozfullscreenchange",
|
||||
handleFullScreenChange
|
||||
);
|
||||
document.removeEventListener(
|
||||
"MSFullscreenChange",
|
||||
handleFullScreenChange
|
||||
);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleFullScreenChange = () => {
|
||||
setIsFullScreen(!!document.fullscreenElement);
|
||||
};
|
||||
|
||||
const toggleFullScreen = () => {
|
||||
if (isFullScreen) {
|
||||
exitFullScreen();
|
||||
} else {
|
||||
requestFullScreen();
|
||||
}
|
||||
};
|
||||
|
||||
const requestFullScreen = () => {
|
||||
if (document.documentElement.requestFullscreen) {
|
||||
document.documentElement.requestFullscreen();
|
||||
} else if (document.documentElement.mozRequestFullScreen) {
|
||||
document.documentElement.mozRequestFullScreen();
|
||||
} else if (document.documentElement.webkitRequestFullscreen) {
|
||||
document.documentElement.webkitRequestFullscreen();
|
||||
} else if (document.documentElement.msRequestFullscreen) {
|
||||
document.documentElement.msRequestFullscreen();
|
||||
}
|
||||
};
|
||||
|
||||
const exitFullScreen = () => {
|
||||
if (document.exitFullscreen) {
|
||||
document.exitFullscreen();
|
||||
} else if (document.mozCancelFullScreen) {
|
||||
document.mozCancelFullScreen();
|
||||
} else if (document.webkitExitFullscreen) {
|
||||
document.webkitExitFullscreen();
|
||||
} else if (document.msExitFullscreen) {
|
||||
document.msExitFullscreen();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex items-center">
|
||||
<button
|
||||
onClick={toggleFullScreen}
|
||||
className="text-black p-2 text-sm focus:outline-none"
|
||||
>
|
||||
{isFullScreen ? (
|
||||
<i className="fa-solid fa-compress"></i>
|
||||
) : (
|
||||
<i className="fa fa-maximize"></i>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FullScreenButton;
|
||||
@@ -1,151 +0,0 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import dp from "../assets/images/dp.png";
|
||||
import FullScreenButton from "./FullScreenButton";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Parse from "parse";
|
||||
import { useWindowSize } from "../hook/useWindowSize";
|
||||
const Header = ({ showSidebar }) => {
|
||||
const navigation = useNavigate();
|
||||
const { width } = useWindowSize();
|
||||
let applogo = localStorage.getItem("appLogo") || "";
|
||||
let username = localStorage.getItem("username");
|
||||
const image = localStorage.getItem("profileImg") || dp;
|
||||
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
||||
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
||||
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const toggleDropdown = () => {
|
||||
setIsOpen(!isOpen);
|
||||
};
|
||||
|
||||
const closeDropdown = () => {
|
||||
setIsOpen(false);
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
Parse.User.logOut();
|
||||
let appdata = localStorage.getItem("userSettings");
|
||||
let applogo = localStorage.getItem("appLogo");
|
||||
let appName = localStorage.getItem("appName");
|
||||
let defaultmenuid = localStorage.getItem("defaultmenuid");
|
||||
let PageLanding = localStorage.getItem("PageLanding");
|
||||
let domain = localStorage.getItem("domain");
|
||||
let _appName = localStorage.getItem("_appName");
|
||||
let baseUrl = localStorage.getItem("BaseUrl12");
|
||||
let appid = localStorage.getItem("AppID12");
|
||||
|
||||
localStorage.clear();
|
||||
|
||||
localStorage.setItem("appLogo", applogo);
|
||||
localStorage.setItem("appName", appName);
|
||||
localStorage.setItem("_appName", _appName);
|
||||
localStorage.setItem("defaultmenuid", defaultmenuid);
|
||||
localStorage.setItem("PageLanding", PageLanding);
|
||||
localStorage.setItem("domain", domain);
|
||||
localStorage.setItem("userSettings", appdata);
|
||||
localStorage.setItem("BaseUrl12", baseUrl);
|
||||
localStorage.setItem("AppID12", appid);
|
||||
|
||||
navigation("/");
|
||||
};
|
||||
|
||||
//handle to close profile drop down menu onclick screen
|
||||
useEffect(() => {
|
||||
const closeMenuOnOutsideClick = (e) => {
|
||||
if (isOpen && !e.target.closest("#profile-menu")) {
|
||||
setIsOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("click", closeMenuOnOutsideClick);
|
||||
|
||||
return () => {
|
||||
// Cleanup the event listener when the component unmounts
|
||||
document.removeEventListener("click", closeMenuOnOutsideClick);
|
||||
};
|
||||
}, [isOpen]);
|
||||
|
||||
return (
|
||||
<div className="flex flex-row justify-between items-center gap-x-3 md:gap-x-4 bg-white md:px-4 px-2 shadow h-[50px] md:w-full ">
|
||||
<button
|
||||
className="cursor-pointer focus:outline-none"
|
||||
onClick={showSidebar}
|
||||
>
|
||||
<i className={`fa-solid fa-bars text-xl `}></i>
|
||||
</button>
|
||||
<div className="flex-1">
|
||||
<div className="h-[25px] md:h-[40px] w-auto overflow-hidden">
|
||||
<img
|
||||
className="object-contain h-full w-auto"
|
||||
src={applogo}
|
||||
alt="img"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
id="profile-menu"
|
||||
className="flex justify-between items-center gap-x-3"
|
||||
>
|
||||
<div>
|
||||
<FullScreenButton />
|
||||
</div>
|
||||
{width >= 768 && (
|
||||
<div
|
||||
onClick={toggleDropdown}
|
||||
className="cursor-pointer w-[35px] h-[35px] rounded-full ring-[1px] ring-offset-2 ring-gray-400 overflow-hidden"
|
||||
>
|
||||
<img
|
||||
className="w-[35px] h-[35px] object-contain"
|
||||
src={image}
|
||||
alt="img"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{width >= 768 && (
|
||||
<div onClick={toggleDropdown} className="cursor-pointer text-sm">
|
||||
{username && username}
|
||||
</div>
|
||||
)}
|
||||
<div className="relative">
|
||||
<div className="cursor-pointer">
|
||||
<i onClick={toggleDropdown} className="fa-solid fa-angle-down"></i>
|
||||
</div>
|
||||
<div
|
||||
className={`dropdown absolute text-sm text-gray-700 font-light right-0 mt-4 p-1 w-48 bg-white border rounded-lg shadow-lg z-10 ${
|
||||
isOpen ? "block" : "hidden"
|
||||
}`}
|
||||
>
|
||||
<ul>
|
||||
<li
|
||||
className="hover:bg-gray-100 rounded-t-lg py-1 px-2 cursor-pointer font-normal"
|
||||
onClick={() => {
|
||||
setIsOpen(false);
|
||||
navigation("/profile");
|
||||
}}
|
||||
>
|
||||
<i className="fa-regular fa-user"></i> Profile
|
||||
</li>
|
||||
<li
|
||||
className="hover:bg-gray-100 py-1 px-2 cursor-pointer font-normal"
|
||||
onClick={() => {
|
||||
setIsOpen(false);
|
||||
navigation("/changepassword");
|
||||
}}
|
||||
>
|
||||
<i className="fa-solid fa-lock"></i> Change Password
|
||||
</li>
|
||||
<li
|
||||
className="hover:bg-gray-100 rounded-b-lg py-1 px-2 cursor-pointer font-normal"
|
||||
onClick={closeDropdown}
|
||||
>
|
||||
<i className="fa-solid fa-arrow-right-from-bracket"></i> Log Out
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
||||
@@ -1,236 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import Parse from "parse";
|
||||
// import FacebookLogin from "react-facebook-login";
|
||||
|
||||
const LoginFacebook = ({
|
||||
FBCred,
|
||||
thirdpartyLoginfn,
|
||||
thirdpartyLoader,
|
||||
setThirdpartyLoader
|
||||
}) => {
|
||||
const [isModal, setIsModal] = useState(false);
|
||||
const [userDetails, setUserDetails] = useState({
|
||||
Phone: "",
|
||||
Company: "",
|
||||
Name: "",
|
||||
Email: ""
|
||||
});
|
||||
const [fBDetails, setFBDetails] = useState({
|
||||
Id: "",
|
||||
AccessToken: "",
|
||||
Name: "",
|
||||
Email: ""
|
||||
});
|
||||
const responseFacebook = async (response) => {
|
||||
// console.log("response ", response);
|
||||
if (response.userID) {
|
||||
setThirdpartyLoader(true);
|
||||
const details = {
|
||||
Email: response.email,
|
||||
Name: response.name,
|
||||
};
|
||||
setUserDetails({ ...userDetails, ...details });
|
||||
const fDetails = {
|
||||
Id: response.userID,
|
||||
AccessToken: response.accessToken,
|
||||
Name: response.name,
|
||||
Email: response.email,
|
||||
};
|
||||
setFBDetails({ ...fBDetails, ...fDetails });
|
||||
const res = await checkExtUser(fDetails);
|
||||
}
|
||||
};
|
||||
|
||||
const checkExtUser = async (details) => {
|
||||
const extUser = new Parse.Query("contracts_Users");
|
||||
extUser.equalTo("Email", details.Email);
|
||||
const extRes = await extUser.first();
|
||||
// console.log("extRes ", extRes);
|
||||
if (extRes) {
|
||||
const params = { ...details, Phone: extRes.get("Phone") };
|
||||
const payload = await Parse.Cloud.run("facebooksign", params);
|
||||
// console.log("payload ", payload);
|
||||
if (payload && payload.sessiontoken) {
|
||||
const billingDate =
|
||||
extRes.get("Next_billing_date") && extRes.get("Next_billing_date");
|
||||
// console.log("billingDate expired", billingDate > new Date());
|
||||
const LocalUserDetails = {
|
||||
name: details.Name,
|
||||
email: details.Email,
|
||||
phone: extRes.get("Phone"),
|
||||
company: extRes.get("Company")
|
||||
};
|
||||
localStorage.setItem("userDetails", JSON.stringify(LocalUserDetails));
|
||||
thirdpartyLoginfn(payload.sessiontoken, billingDate);
|
||||
}
|
||||
return { msg: "exist" };
|
||||
} else {
|
||||
setIsModal(true);
|
||||
setThirdpartyLoader(false);
|
||||
return { msg: "notexist" };
|
||||
}
|
||||
};
|
||||
const handleSubmitbtn = async () => {
|
||||
if (userDetails.Phone && userDetails.Company) {
|
||||
setThirdpartyLoader(true);
|
||||
const params = { ...fBDetails, Phone: userDetails.Phone };
|
||||
const payload = await Parse.Cloud.run("facebooksign", params);
|
||||
// console.log("payload ", payload);
|
||||
|
||||
if (payload && payload.sessiontoken) {
|
||||
const params = {
|
||||
userDetails: {
|
||||
name: userDetails.Name,
|
||||
email: userDetails.Email,
|
||||
// "passsword":userDetails.Phone,
|
||||
phone: userDetails.Phone,
|
||||
role: "contracts_Admin",
|
||||
company: userDetails.Company
|
||||
}
|
||||
};
|
||||
const userSignUp = await Parse.Cloud.run("usersignup", params);
|
||||
// console.log("userSignUp ", userSignUp);
|
||||
if (userSignUp && userSignUp.sessionToken) {
|
||||
const LocalUserDetails = {
|
||||
name: userDetails.Name,
|
||||
email: userDetails.Email,
|
||||
phone: userDetails.Phone,
|
||||
company: userDetails.Company
|
||||
};
|
||||
localStorage.setItem("userDetails", JSON.stringify(LocalUserDetails));
|
||||
thirdpartyLoginfn(userSignUp.sessionToken);
|
||||
} else {
|
||||
alert(userSignUp.message);
|
||||
}
|
||||
} else {
|
||||
alert("Internal server error !");
|
||||
}
|
||||
} else {
|
||||
alert("Please fill required details!");
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div style={{ position: "relative" }}>
|
||||
{thirdpartyLoader && (
|
||||
<div
|
||||
style={{
|
||||
position: "fixed",
|
||||
width: "100vw",
|
||||
height: "100vh",
|
||||
backgroundColor: "rgba(0,0,0,0.2)",
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: 2
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: "fixed",
|
||||
fontSize: "50px",
|
||||
color: "#3ac9d6",
|
||||
top: "50%",
|
||||
left: "45%"
|
||||
}}
|
||||
className="loader-37"
|
||||
></div>
|
||||
</div>
|
||||
)}
|
||||
{/* <FacebookLogin
|
||||
appId={FBCred}
|
||||
fields="name,email,picture"
|
||||
callback={responseFacebook}
|
||||
cssClass="btn btn-info btn-md btn-fb"
|
||||
icon="fa fa-facebook-f"
|
||||
/> */}
|
||||
{isModal && (
|
||||
<div
|
||||
className="modal fade show"
|
||||
id="exampleModal"
|
||||
tabIndex="-1"
|
||||
role="dialog"
|
||||
style={{ display: "block", zIndex: 1 }}
|
||||
>
|
||||
<div className="modal-dialog" role="document">
|
||||
<div className="modal-content">
|
||||
<div className="modal-header">
|
||||
<h5 className="modal-title">Sign up form</h5>
|
||||
<span>
|
||||
<span></span>
|
||||
</span>
|
||||
</div>
|
||||
<div className="modal-body">
|
||||
<form>
|
||||
<div className="form-group">
|
||||
<label
|
||||
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>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-secondary"
|
||||
onClick={() => setIsModal(false)}
|
||||
style={{ marginRight: 10, width: 90 }}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleSubmitbtn()}
|
||||
className="btn btn-info"
|
||||
>
|
||||
Sign up
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoginFacebook;
|
||||
@@ -1,286 +0,0 @@
|
||||
import React, { useState, useRef } from "react";
|
||||
import Parse from "parse";
|
||||
import jwtDecode from "jwt-decode";
|
||||
import { useScript } from "../hook/useScript";
|
||||
|
||||
/*
|
||||
* `GoogleSignInBtn`as it's name indicates it render google sign in button
|
||||
* and in this `useScript` in which we have created for generate google sign button
|
||||
* and when user click on sign in with google it will be verify on server side
|
||||
* and then generate token
|
||||
*/
|
||||
const GoogleSignInBtn = ({
|
||||
GoogleCred,
|
||||
thirdpartyLoginfn,
|
||||
thirdpartyLoader,
|
||||
setThirdpartyLoader
|
||||
}) => {
|
||||
const [isModal, setIsModal] = useState(false);
|
||||
const googleBtn = useRef();
|
||||
const [userDetails, setUserDetails] = useState({
|
||||
Phone: "",
|
||||
Company: "",
|
||||
Name: "",
|
||||
Email: "",
|
||||
Destination: ""
|
||||
});
|
||||
const [googleDetails, setGoogleDetails] = useState({
|
||||
Id: "",
|
||||
TokenId: "",
|
||||
Gmail: "",
|
||||
Name: ""
|
||||
});
|
||||
useScript("https://accounts.google.com/gsi/client", () => {
|
||||
window.google.accounts.id.initialize({
|
||||
client_id: GoogleCred,
|
||||
callback: responseGoogle,
|
||||
auto_select: false
|
||||
});
|
||||
window.google.accounts.id.renderButton(googleBtn.current, {
|
||||
theme: "outline",
|
||||
size: "large",
|
||||
width: "187px"
|
||||
});
|
||||
});
|
||||
const responseGoogle = async (response) => {
|
||||
setThirdpartyLoader(true);
|
||||
// console.log("response ", response);
|
||||
if (response.credential) {
|
||||
const data = jwtDecode(response.credential);
|
||||
// console.log("data ", data);
|
||||
if (data.sub && data.email) {
|
||||
const details = {
|
||||
Email: data.email,
|
||||
Name: data.name
|
||||
};
|
||||
setUserDetails({ ...userDetails, ...details });
|
||||
const Gdetails = {
|
||||
Id: data.sub,
|
||||
TokenId: response.credential,
|
||||
Gmail: data.email,
|
||||
Name: data.name
|
||||
};
|
||||
setGoogleDetails({ ...googleDetails, ...Gdetails });
|
||||
await checkExtUser(Gdetails);
|
||||
}
|
||||
}
|
||||
};
|
||||
const checkExtUser = async (details) => {
|
||||
const extUser = new Parse.Query("contracts_Users");
|
||||
extUser.equalTo("Email", details.Gmail);
|
||||
const extRes = await extUser.first();
|
||||
// console.log("extRes ", extRes);
|
||||
if (extRes) {
|
||||
const params = { ...details, Phone: extRes.get("Phone") };
|
||||
const payload = await Parse.Cloud.run("googlesign", params);
|
||||
// console.log("payload ", payload);
|
||||
if (payload && payload.sessiontoken) {
|
||||
// setThirdpartyLoader(true);
|
||||
const billingDate =
|
||||
extRes.get("Next_billing_date") && extRes.get("Next_billing_date");
|
||||
// console.log("billingDate expired", billingDate > new Date());
|
||||
const LocalUserDetails = {
|
||||
name: details.Name,
|
||||
email: details.Gmail,
|
||||
phone: extRes.get("Phone"),
|
||||
company: extRes.get("Company")
|
||||
};
|
||||
localStorage.setItem("userDetails", JSON.stringify(LocalUserDetails));
|
||||
thirdpartyLoginfn(payload.sessiontoken, billingDate);
|
||||
}
|
||||
return { msg: "exist" };
|
||||
} else {
|
||||
setIsModal(true);
|
||||
setThirdpartyLoader(false);
|
||||
return { msg: "notexist" };
|
||||
}
|
||||
};
|
||||
const handleSubmitbtn = async () => {
|
||||
if (userDetails.Phone && userDetails.Company) {
|
||||
setThirdpartyLoader(true);
|
||||
// e.preventDefault()
|
||||
// console.log("handelSubmit", userDetails);
|
||||
const params = { ...googleDetails, Phone: userDetails.Phone };
|
||||
const payload = await Parse.Cloud.run("googlesign", params);
|
||||
|
||||
// console.log("payload ", payload);
|
||||
if (payload && payload.sessiontoken) {
|
||||
const params = {
|
||||
userDetails: {
|
||||
name: userDetails.Name,
|
||||
email: userDetails.Email,
|
||||
// "passsword":userDetails.Phone,
|
||||
phone: userDetails.Phone,
|
||||
role: "contracts_Admin",
|
||||
company: userDetails.Company,
|
||||
jobTitle: userDetails.Destination
|
||||
}
|
||||
};
|
||||
const userSignUp = await Parse.Cloud.run("usersignup", params);
|
||||
// console.log("userSignUp ", userSignUp);
|
||||
if (userSignUp && userSignUp.sessionToken) {
|
||||
const LocalUserDetails = {
|
||||
name: userDetails.Name,
|
||||
email: userDetails.Email,
|
||||
phone: userDetails.Phone,
|
||||
company: userDetails.Company
|
||||
// jobTitle: userDetails.JobTitle
|
||||
};
|
||||
localStorage.setItem("userDetails", JSON.stringify(LocalUserDetails));
|
||||
thirdpartyLoginfn(userSignUp.sessionToken);
|
||||
} else {
|
||||
alert(userSignUp.message);
|
||||
}
|
||||
} else if (
|
||||
payload &&
|
||||
payload.message.replace(/ /g, "_") === "Internal_server_err"
|
||||
) {
|
||||
alert("Internal server error !");
|
||||
}
|
||||
} else {
|
||||
alert("Please fill required details!");
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div style={{ position: "relative" }}>
|
||||
{thirdpartyLoader && (
|
||||
<div
|
||||
style={{
|
||||
position: "fixed",
|
||||
width: "100vw",
|
||||
height: "100vh",
|
||||
backgroundColor: "rgba(0,0,0,0.2)",
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: 2
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: "fixed",
|
||||
fontSize: "50px",
|
||||
color: "#3ac9d6",
|
||||
top: "50%",
|
||||
left: "45%"
|
||||
}}
|
||||
className="loader-37"
|
||||
></div>
|
||||
</div>
|
||||
)}
|
||||
<div ref={googleBtn} className="text-sm"></div>
|
||||
|
||||
{isModal && (
|
||||
<div
|
||||
className="modal fade show"
|
||||
id="exampleModal"
|
||||
tabIndex="-1"
|
||||
role="dialog"
|
||||
style={{ display: "block", zIndex: 1 }}
|
||||
>
|
||||
<div className="modal-dialog" role="document">
|
||||
<div className="modal-content">
|
||||
<div className="modal-header">
|
||||
<h5 className="modal-title">Sign up form</h5>
|
||||
<span>
|
||||
<span></span>
|
||||
</span>
|
||||
</div>
|
||||
<div className="modal-body">
|
||||
<form>
|
||||
<div className="form-group">
|
||||
<label
|
||||
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="Destination"
|
||||
style={{ display: "flex" }}
|
||||
className="col-form-label"
|
||||
>
|
||||
Destination{" "}
|
||||
<span style={{ fontSize: 13, color: "red" }}>*</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
id="Destination"
|
||||
value={userDetails.Destination}
|
||||
onChange={(e) =>
|
||||
setUserDetails({
|
||||
...userDetails,
|
||||
Destination: e.target.value
|
||||
})
|
||||
}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-secondary"
|
||||
onClick={() => setIsModal(false)}
|
||||
style={{ marginRight: 10, width: 90 }}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleSubmitbtn()}
|
||||
className="btn btn-info"
|
||||
>
|
||||
Sign up
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default GoogleSignInBtn;
|
||||
@@ -1,90 +0,0 @@
|
||||
import useFederatedComponent from "mf-cra";
|
||||
import React, { Suspense, useEffect } from "react";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
|
||||
const MicroappModal = () => {
|
||||
const { remoteApp } = useParams();
|
||||
|
||||
useEffect(() => {
|
||||
return () => localStorage.removeItem("rowlevel");
|
||||
}, []);
|
||||
let paramString = remoteApp;
|
||||
let queryString = new URLSearchParams(paramString);
|
||||
let obj = {};
|
||||
for (const [key, value] of queryString.entries()) {
|
||||
// console.log("value ", key + ":" + value);
|
||||
|
||||
if (key === "remoteUrl") {
|
||||
const url = window.location.origin + "/mfbuild/remoteEntry.js";
|
||||
// console.log("atob(value) ", atob(value))
|
||||
obj = { ...obj, [key]: url };
|
||||
} else {
|
||||
if (key === "moduleToLoad") {
|
||||
obj = { ...obj, [key]: "./" + value };
|
||||
} else {
|
||||
obj = { ...obj, [key]: value };
|
||||
}
|
||||
}
|
||||
}
|
||||
// console.log("app ", remoteApp);
|
||||
const { Component: RemoteComponent } = useFederatedComponent(obj);
|
||||
const navigate = useNavigate();
|
||||
// console.log("RemoteComponent ", RemoteComponent);
|
||||
return (
|
||||
<div className="w-full h-full flex items-center justify-center ">
|
||||
{/* <!-- Modal Container --> */}
|
||||
<div className="bg-white rounded-lg shadow-lg w-full">
|
||||
{/* <!-- Modal Header --> */}
|
||||
<div className="flex w-full items-center border-b-2 mb-2 p-2">
|
||||
<button
|
||||
className="focus:outline-none bg-blue-500 text-white text-sm shadow px-2.5 py-1 rounded"
|
||||
id="closeModal"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
// setIsModal(false);
|
||||
navigate(-1);
|
||||
}}
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
{localStorage.getItem("domain") && (
|
||||
<p className="flex-1 w-full text-sm md:text-base text-black text-center">
|
||||
{localStorage.getItem("domain") === "contracts" ? "Document" : ""}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
{/* <!-- Modal Body --> */}
|
||||
<div className="w-full">
|
||||
<Suspense
|
||||
fallback={
|
||||
<div style={{ height: "300px" }}>
|
||||
<div
|
||||
style={{
|
||||
marginLeft: "45%",
|
||||
marginTop: "150px",
|
||||
fontSize: "45px",
|
||||
color: "#3dd3e0"
|
||||
}}
|
||||
className="loader-37"
|
||||
></div>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
backgroundColor: "#ffffff",
|
||||
width: "100%",
|
||||
overflow: "hidden",
|
||||
minHeight: "50vh"
|
||||
}}
|
||||
>
|
||||
{RemoteComponent && <RemoteComponent />}
|
||||
</div>
|
||||
</Suspense>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MicroappModal;
|
||||
@@ -1,29 +0,0 @@
|
||||
import React from "react";
|
||||
import { Helmet } from "react-helmet";
|
||||
|
||||
function Title(props) {
|
||||
return (
|
||||
<Helmet>
|
||||
<title>{`${props.title} - OpenSign™`}</title>
|
||||
{/* <title>
|
||||
{`${localStorage.getItem("appTitle") ? localStorage.getItem("appTitle") : ""} - ${props.title}`}
|
||||
</title> */}
|
||||
<meta
|
||||
name="description"
|
||||
content={`${props.title} - OpenSign™`}
|
||||
/>
|
||||
{/* <meta
|
||||
name="description"
|
||||
content={`${localStorage.getItem("appTitle")} - ${props.title}`}
|
||||
/> */}
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
href={localStorage.getItem("fev_Icon")}
|
||||
sizes="40x40"
|
||||
/>
|
||||
</Helmet>
|
||||
);
|
||||
}
|
||||
|
||||
export default Title;
|
||||
@@ -1,391 +0,0 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Form from "@rjsf/core";
|
||||
import validator from "@rjsf/validator-ajv8";
|
||||
import Parse from "parse";
|
||||
import "../styles/loader.css";
|
||||
import LayoutField from "./fields/Rjsf-layout";
|
||||
import TimeWidget from "./fields/TimeWidget";
|
||||
import Level1Dropdown from "./fields/Level1Dropdown";
|
||||
import HiddenField from "./fields/HiddenField";
|
||||
import MultiSelectField from "./fields/MultiSelectField";
|
||||
import TreeWidget from "../components/TreeWidget";
|
||||
import { formJson } from "../json/FormJson";
|
||||
const TreeEditForm = (props) => {
|
||||
const widget = {
|
||||
TimeWidget: TimeWidget
|
||||
};
|
||||
const fields = {
|
||||
layout: LayoutField,
|
||||
Level1Dropdown: Level1Dropdown,
|
||||
HiddenField: HiddenField,
|
||||
MultiSelectField: MultiSelectField,
|
||||
FolderComponent: TreeWidget
|
||||
};
|
||||
|
||||
const [schema, setschema] = useState({});
|
||||
const [ui_schema, setui_schema] = useState({});
|
||||
const [title, settitle] = useState("");
|
||||
const [schemaState, setschemaState] = useState({});
|
||||
const [formData, setformData] = useState({});
|
||||
const [active, setactive] = useState(true);
|
||||
const [loading, setloading] = useState(false);
|
||||
const [_validate, set_validate] = useState(null);
|
||||
const [noValidate, setnoValidate] = useState(false);
|
||||
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
||||
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
||||
|
||||
const getForm = async (id) => {
|
||||
setloading(true);
|
||||
try {
|
||||
//get json form data (schema ,uischema)
|
||||
const results = formJson(id);
|
||||
try {
|
||||
let _record = Parse.Object.extend(results.class);
|
||||
var query1 = new Parse.Query(_record);
|
||||
await query1.get(props.objectId).then(
|
||||
(x) => {
|
||||
try {
|
||||
if (x) {
|
||||
let result = x.toJSON();
|
||||
let new_result = result;
|
||||
for (let [key, value] of Object.entries(result)) {
|
||||
if (value["__type"] === "Date") {
|
||||
let todayTime1 = new Date(value.iso);
|
||||
var month = String(todayTime1.getMonth() + 1);
|
||||
var day = String(todayTime1.getDate());
|
||||
var year = String(todayTime1.getFullYear());
|
||||
if (month.length < 2) month = "0" + month;
|
||||
if (day.length < 2) day = "0" + day;
|
||||
let date1 = year + "-" + month + "-" + day;
|
||||
let bindVar = date1;
|
||||
if (!results.jsonSchema.properties[key].format) {
|
||||
bindVar = todayTime1.toISOString();
|
||||
}
|
||||
new_result[key] = bindVar;
|
||||
}
|
||||
}
|
||||
setschemaState(results.jsonSchema);
|
||||
setformData(new_result);
|
||||
}
|
||||
} catch (error) {
|
||||
//alert(error.message);
|
||||
|
||||
setloading(false);
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
console.log("err", error);
|
||||
setloading(false);
|
||||
}
|
||||
);
|
||||
setschema(results.jsonSchema);
|
||||
setui_schema(results.uiSchema);
|
||||
set_validate(results.validFunction);
|
||||
setnoValidate(results.noValidate);
|
||||
settitle(results.class);
|
||||
setloading(false);
|
||||
setactive(true);
|
||||
} catch (error) {
|
||||
setloading(false);
|
||||
}
|
||||
} catch (e) {
|
||||
setloading(false);
|
||||
console.error("Problem", e);
|
||||
}
|
||||
};
|
||||
|
||||
const wrap = (s) => "{ return " + s + " };";
|
||||
|
||||
const dynamicValidate = (formData, errors) => {
|
||||
try {
|
||||
let body = atob(_validate);
|
||||
let res = new Function(wrap(body))
|
||||
.call(null)
|
||||
.call(null, formData, errors);
|
||||
return res;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = async ({ formData }) => {
|
||||
setactive(false);
|
||||
setloading(true);
|
||||
let RowData = formData;
|
||||
RowData &&
|
||||
Object.entries(RowData).forEach(([key, value]) => {
|
||||
if (typeof value === "string") {
|
||||
RowData[key] = value.trim();
|
||||
}
|
||||
});
|
||||
let _scanData = schemaState;
|
||||
if (_scanData.dependencies) {
|
||||
Object.keys(_scanData.dependencies).forEach((key) => {
|
||||
if (_scanData.dependencies[key].oneOf) {
|
||||
_scanData.dependencies[key].oneOf.forEach((val) => {
|
||||
Object.keys(val.properties).forEach((k) => {
|
||||
if (typeof val.properties[k] === "object") {
|
||||
if (val.properties[k].format === "date") {
|
||||
if (RowData[k]) {
|
||||
let newdate = new Date(RowData[k]);
|
||||
RowData[k] = newdate;
|
||||
}
|
||||
}
|
||||
if (val.properties[k].component === "HtmlEditor") {
|
||||
if (RowData[k]) {
|
||||
let newHtml = RowData[k]
|
||||
.replace(/<p[^>]*>/g, "")
|
||||
.replace(/<\/p>/g, " ");
|
||||
RowData[k] = newHtml;
|
||||
}
|
||||
}
|
||||
if (val.properties[k].component === "DateTime") {
|
||||
if (RowData[k]) {
|
||||
let newDate11 = new Date(RowData[k]);
|
||||
RowData[k] = newDate11;
|
||||
}
|
||||
}
|
||||
if (val.properties[k].component === "CurrencyInput") {
|
||||
if (val.properties[k].currencyColumn) {
|
||||
RowData[`${val.properties[k].currencyColumn}`] =
|
||||
val.properties[k].defaultcurrency;
|
||||
}
|
||||
}
|
||||
if (val.properties[k].type === "string") {
|
||||
if (typeof RowData[k] === "string")
|
||||
RowData[k] = RowData[k].trim();
|
||||
}
|
||||
if (val.properties[k].data !== undefined) {
|
||||
if (val.properties[k].data.isPointer) {
|
||||
let pointer = undefined;
|
||||
if (val.properties[k].data.class) {
|
||||
if (RowData[k]) {
|
||||
pointer = {
|
||||
__type: "Pointer",
|
||||
className: val.properties[k].data.class,
|
||||
objectId: RowData[k]
|
||||
};
|
||||
}
|
||||
} else {
|
||||
if (RowData[k]) {
|
||||
pointer = {
|
||||
__type: "Pointer",
|
||||
className: localStorage.getItem("extended_class"),
|
||||
objectId: RowData[k]
|
||||
};
|
||||
}
|
||||
}
|
||||
RowData[k] = pointer;
|
||||
}
|
||||
if (val.properties[k].data.FolderTypeValue) {
|
||||
if (RowData[k]) {
|
||||
let obj = {
|
||||
__type: "Pointer",
|
||||
className: val.properties[k].data.ClassName,
|
||||
objectId: RowData[k]
|
||||
};
|
||||
RowData[k] = obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
let temp = [];
|
||||
|
||||
let _dd = _scanData.properties;
|
||||
let allowed = [];
|
||||
if (_dd) {
|
||||
Object.keys(_dd).forEach(function (k) {
|
||||
allowed.push(k);
|
||||
if (RowData[k]) {
|
||||
let pointer = {
|
||||
__type: "Pointer",
|
||||
className: _dd[k].class,
|
||||
objectId: RowData[k]
|
||||
};
|
||||
RowData[k] = pointer;
|
||||
}
|
||||
if (_dd[k].format === "date") {
|
||||
if (RowData[k]) {
|
||||
let newdate = new Date(RowData[k]);
|
||||
if (!isNaN(newdate.getTime())) {
|
||||
RowData[k] = newdate;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_dd[k].component === "HtmlEditor") {
|
||||
if (RowData[k]) {
|
||||
let newHtml = RowData[k]
|
||||
.replace(/<p[^>]*>/g, "")
|
||||
.replace(/<\/p>/g, " ");
|
||||
RowData[k] = newHtml;
|
||||
}
|
||||
}
|
||||
if (_dd[k].component === "DateTime") {
|
||||
if (RowData[k]) {
|
||||
let newdate = new Date(RowData[k]);
|
||||
if (!isNaN(newdate.getTime())) {
|
||||
RowData[k] = newdate;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_dd[k].format === "date-time") {
|
||||
let newdate = new Date(RowData[k]);
|
||||
RowData[k] = newdate;
|
||||
}
|
||||
if (_dd[k].component === "CurrencyInput") {
|
||||
if (_dd[k].currencyColumn) {
|
||||
RowData[`${_dd[k].currencyColumn}`] = _dd[k].defaultcurrency;
|
||||
}
|
||||
}
|
||||
if (_dd[k].data !== undefined) {
|
||||
if (_dd[k].data.isPointer) {
|
||||
let pointer = undefined;
|
||||
if (typeof RowData[k] === "object") {
|
||||
if (RowData[k]) {
|
||||
if (RowData[k].objectId !== "Select") {
|
||||
let obj = {
|
||||
__type: "Pointer",
|
||||
className: RowData[k].className,
|
||||
objectId: RowData[k].objectId
|
||||
};
|
||||
pointer = obj;
|
||||
}
|
||||
}
|
||||
} else if (_dd[k].data.class) {
|
||||
if (RowData[k]) {
|
||||
pointer = {
|
||||
__type: "Pointer",
|
||||
className: _dd[k].data.class,
|
||||
objectId: RowData[k]
|
||||
};
|
||||
}
|
||||
} else {
|
||||
if (RowData[k]) {
|
||||
pointer = {
|
||||
__type: "Pointer",
|
||||
className: localStorage.getItem("extended_class"),
|
||||
objectId: RowData[k]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
RowData[k] = pointer;
|
||||
}
|
||||
if (_dd[k].data.FolderTypeValue) {
|
||||
if (RowData[k]) {
|
||||
let obj = {
|
||||
__type: "Pointer",
|
||||
className: _dd[k].data.ClassName,
|
||||
objectId: RowData[k]
|
||||
};
|
||||
RowData[k] = obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_dd[k].type === "string") {
|
||||
if (typeof RowData[k] === "string") RowData[k] = RowData[k].trim();
|
||||
}
|
||||
});
|
||||
}
|
||||
const filtered = Object.keys(RowData)
|
||||
.filter((key) => allowed.includes(key))
|
||||
.reduce((obj, key) => {
|
||||
obj[key] = RowData[key];
|
||||
return obj;
|
||||
}, {});
|
||||
|
||||
try {
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
const currentUser = Parse.User.current();
|
||||
if (temp.length !== 0) {
|
||||
let userPointer = {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: currentUser.id
|
||||
};
|
||||
filtered[[temp[0]]] = userPointer;
|
||||
}
|
||||
var data = Parse.Object.extend(title);
|
||||
var query = new Parse.Query(data);
|
||||
query.get(props.objectId).then(async (object) => {
|
||||
object.save(filtered).then(
|
||||
() => {
|
||||
try {
|
||||
alert("Record updated successfully");
|
||||
props.HideView(false);
|
||||
setloading(false);
|
||||
setactive(true);
|
||||
} catch (error) {
|
||||
console.log("err", error);
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
console.log("err", error);
|
||||
setloading(false);
|
||||
setactive(true);
|
||||
}
|
||||
);
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("err", error);
|
||||
|
||||
alert(error.message);
|
||||
setloading(false);
|
||||
setactive(true);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (props.FormId) {
|
||||
getForm(props.FormId);
|
||||
}
|
||||
// eslint-disable-next-line
|
||||
}, [props.FormId]);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div
|
||||
className="loader-01"
|
||||
style={{
|
||||
marginTop: "50px",
|
||||
marginLeft: "50%",
|
||||
color: "rgb(0,28,28)",
|
||||
fontSize: "35px"
|
||||
}}
|
||||
></div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Form
|
||||
schema={schema}
|
||||
uiSchema={ui_schema}
|
||||
formData={formData}
|
||||
showErrorList={false}
|
||||
widgets={widget}
|
||||
fields={fields}
|
||||
validate={noValidate && dynamicValidate}
|
||||
onSubmit={handleSubmit}
|
||||
validator={validator}
|
||||
>
|
||||
<div>
|
||||
{active ? (
|
||||
<button className="bg-[#1ab6ce] px-3 py-2 rounded text-white text-sm" type="submit">
|
||||
Update
|
||||
</button>
|
||||
) : (
|
||||
<button className="bg-[#1ab6ce] px-3 py-2 rounded text-white text-sm" type="submit" disabled>
|
||||
Update
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
export default TreeEditForm;
|
||||
@@ -1,237 +0,0 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Form from "@rjsf/core";
|
||||
import validator from "@rjsf/validator-ajv8";
|
||||
import LayoutField from "./fields/Rjsf-layout";
|
||||
import Level1Dropdown from "./fields/Level1Dropdown";
|
||||
import HiddenField from "./fields/HiddenField";
|
||||
import MultiSelectField from "./fields/MultiSelectField";
|
||||
import "../styles/loader.css";
|
||||
import "../styles/form.css";
|
||||
import FileUpload from "./fields/FileUpload";
|
||||
import parse from "html-react-parser";
|
||||
import TimeWidget from "./fields/TimeWidget";
|
||||
import { formJson } from "../json/FormJson";
|
||||
function TreeFormComponent(props) {
|
||||
const widget = {
|
||||
TimeWidget: TimeWidget
|
||||
};
|
||||
|
||||
const fields = {
|
||||
layout: LayoutField,
|
||||
FileUpload: FileUpload,
|
||||
Level1Dropdown: Level1Dropdown,
|
||||
HiddenField: HiddenField,
|
||||
MultiSelectField: MultiSelectField
|
||||
};
|
||||
|
||||
const [link, setLink] = useState("");
|
||||
const [help, setHelp] = useState("");
|
||||
const toastDescription = "";
|
||||
const toastColor = "#5cb85c";
|
||||
const [loading, setLoding] = useState(true);
|
||||
const [schemaState, setSchemaState] = useState({});
|
||||
const [formData, setFormData] = useState({});
|
||||
const [ui_schema, setUi_schema] = useState({});
|
||||
const active = true;
|
||||
|
||||
console.log("new form", props);
|
||||
|
||||
const getForm = async (id) => {
|
||||
setLoding(true);
|
||||
try {
|
||||
// get json from data(jsonschema, uischema)
|
||||
const results = formJson(id);
|
||||
// console.log("result", results);
|
||||
if (results) {
|
||||
let parentObject = {},
|
||||
childObject = {};
|
||||
const resultjson = results;
|
||||
for (let [key, value] of Object.entries(
|
||||
resultjson.jsonSchema.properties
|
||||
)) {
|
||||
if (key === props.ParentField) {
|
||||
if (props.ParentValue[key]) {
|
||||
parentObject = { [key]: props.ParentValue[key] };
|
||||
}
|
||||
} else {
|
||||
if (props.ParentValue && typeof props.ParentValue === "object") {
|
||||
Object.entries(props.ParentValue).forEach(([k, value]) => {
|
||||
if (k === key) {
|
||||
let newO = { [k]: value };
|
||||
parentObject = { ...parentObject, ...newO };
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (props.ChildField) {
|
||||
Object.entries(props.ChildField).forEach(([k, value]) => {
|
||||
if (k === key) {
|
||||
let newO = { [k]: value };
|
||||
childObject = { ...childObject, ...newO };
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof value === "object") {
|
||||
for (let [k, v] of Object.entries(value)) {
|
||||
if (k === "format" && v === "date") {
|
||||
let today = new Date();
|
||||
let date =
|
||||
today.getFullYear() +
|
||||
"-" +
|
||||
("0" + (today.getMonth() + 1)).slice(-2) +
|
||||
"-" +
|
||||
("0" + today.getDate()).slice(-2);
|
||||
value.default = date;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (props.ParentField) {
|
||||
setFormData({ ...parentObject, ...childObject });
|
||||
}
|
||||
|
||||
let txt, link;
|
||||
if (resultjson.help) {
|
||||
if (resultjson.help.htmlbody) {
|
||||
txt = resultjson.help.htmlbody;
|
||||
}
|
||||
if (resultjson.help.link) {
|
||||
link = resultjson.help.link;
|
||||
}
|
||||
}
|
||||
setHelp(txt);
|
||||
setLink(link);
|
||||
|
||||
props.ClassName(resultjson.class);
|
||||
props.SchemaState(resultjson.jsonSchema);
|
||||
setSchemaState(resultjson.jsonSchema);
|
||||
setUi_schema(resultjson.uiSchema);
|
||||
setLoding(false);
|
||||
} else {
|
||||
alert("form not found");
|
||||
setLoding(false);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Problem", e);
|
||||
setLoding(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!props.IsEdit) {
|
||||
getForm(props.Id);
|
||||
}
|
||||
// console.log("props tree", props);
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
let formView = (
|
||||
<React.Fragment>
|
||||
<Form
|
||||
schema={schemaState}
|
||||
uiSchema={ui_schema}
|
||||
showErrorList={false}
|
||||
widgets={widget}
|
||||
fields={fields}
|
||||
formData={formData}
|
||||
onSubmit={props.handleSubmit}
|
||||
validator={validator}
|
||||
>
|
||||
{active ? (
|
||||
<button className="btn btn-info submiBtn" type="submit">
|
||||
{props.IsEdit ? "update folder" : "create folder"}
|
||||
</button>
|
||||
) : (
|
||||
<button className="btn btn-info submiBtn " type="submit" disabled>
|
||||
submitting...
|
||||
</button>
|
||||
)}
|
||||
</Form>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
if (loading) {
|
||||
formView = (
|
||||
<div style={{ height: "300px" }}>
|
||||
<div
|
||||
style={{
|
||||
marginLeft: "45%",
|
||||
marginTop: "150px",
|
||||
fontSize: "45px",
|
||||
color: "#3dd3e0"
|
||||
}}
|
||||
className="loader-37"
|
||||
></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="row">
|
||||
<div className="col-md-12">
|
||||
<div className="card">
|
||||
<div className="card-body no-padding height-9">
|
||||
{help ? (
|
||||
<div className="dropdown" style={{ marginTop: "-30px" }}>
|
||||
<i
|
||||
className="far fa-question-circle dropdown-toggle hovereffect"
|
||||
aria-hidden="true"
|
||||
id="dropdownMenuButton"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
style={{
|
||||
fontSize: "18px",
|
||||
color: "purple",
|
||||
cursor: "pointer !important",
|
||||
position: "relative",
|
||||
top: "40px",
|
||||
left: "98%"
|
||||
}}
|
||||
></i>
|
||||
<div
|
||||
className="dropdown-menu"
|
||||
aria-labelledby="dropdownMenuButton"
|
||||
style={{
|
||||
marginleft: "-121px",
|
||||
margintop: "-14px",
|
||||
position: "absolute",
|
||||
padding: "10px",
|
||||
width: "300px",
|
||||
top: "102px!important"
|
||||
}}
|
||||
>
|
||||
{parse(`
|
||||
${help}
|
||||
`)}
|
||||
<br />
|
||||
{link ? (
|
||||
<a
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
window.location.href = link;
|
||||
}}
|
||||
target="_blank"
|
||||
className="btn btn-xs btn-primary"
|
||||
>
|
||||
Read more..
|
||||
</a>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
<div style={{ fontSize: "13px" }}>{formView}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="snackbar" style={{ backgroundColor: toastColor }}>
|
||||
{toastDescription}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
export default TreeFormComponent;
|
||||
@@ -1,894 +0,0 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import LabelField from "./fields/LabelField";
|
||||
import Parse from "parse";
|
||||
import axios from "axios";
|
||||
import "../styles/spinner.css";
|
||||
import TreeFormComponent from "./TreeFormComponent";
|
||||
import TreeEditForm from "./TreeEditForm";
|
||||
import "../styles/modal.css";
|
||||
import Modal from "react-modal";
|
||||
|
||||
const TreeWidget = (props) => {
|
||||
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
||||
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
||||
const [isAddField, setIsAddField] = useState(false);
|
||||
const [folderList, setFolderList] = useState([]);
|
||||
const [tabList, setTabList] = useState([]);
|
||||
const [appId, setAppId] = useState(undefined);
|
||||
const [selectedFolder, setSelectedFolder] = useState(undefined);
|
||||
const [loader, setLoader] = useState(false);
|
||||
const [className, setClassName] = useState("");
|
||||
const [schemaState, setSchemaState] = useState({});
|
||||
const [TabURL, setTabURL] = useState("");
|
||||
const [editable, setEditable] = useState(false);
|
||||
const [editId, setEditId] = useState("");
|
||||
const [defaultState, setDefaultState] = useState(false);
|
||||
const [isShowModal, setIsShowModal] = useState(false);
|
||||
const selectFolderHandle = async () => {
|
||||
setIsShowModal(true);
|
||||
setIsAddField(false);
|
||||
setDefaultState(false);
|
||||
setFolderList([]);
|
||||
setLoader(true);
|
||||
|
||||
if (tabList.length > 0) {
|
||||
let len = tabList.length - 1;
|
||||
selectedItemList(tabList[len]);
|
||||
} else {
|
||||
try {
|
||||
var test;
|
||||
if (props.schema.parent) {
|
||||
try {
|
||||
if (props.parent[props.schema.parent]) {
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
const currentUser = Parse.User.current();
|
||||
let res;
|
||||
if (localStorage.getItem("Extand_Class")) {
|
||||
let data = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||
res = data[0];
|
||||
} else {
|
||||
var emp = Parse.Object.extend(
|
||||
localStorage.getItem("extended_class")
|
||||
);
|
||||
var q = new Parse.Query(emp);
|
||||
q.equalTo("UserId", currentUser);
|
||||
res = await q.first();
|
||||
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 {
|
||||
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();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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
|
||||
);
|
||||
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,365 +0,0 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import axios from "axios";
|
||||
import Parse from "parse";
|
||||
import onSearchFilter from "../../constant/searchQuery";
|
||||
import getReplacedHashQuery from "../../constant/getReplacedHashQuery";
|
||||
import "../../styles/loader.css";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
const DashboardCard = (props) => {
|
||||
const navigate = useNavigate();
|
||||
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
||||
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
||||
const [response, setresponse] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const renderData = async () => {
|
||||
if (props.Data.queryType === "function") {
|
||||
setLoading(true);
|
||||
try {
|
||||
let url = `${parseBaseUrl}${props.Data.class}`;
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": parseAppId,
|
||||
sessionToken: localStorage.getItem("accesstoken")
|
||||
};
|
||||
let body = {};
|
||||
let currentUser;
|
||||
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
let currentUser1 = Parse.User.current();
|
||||
currentUser = currentUser1.id;
|
||||
let res;
|
||||
if (localStorage.getItem("Extand_Class")) {
|
||||
let data = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||
res = data[0];
|
||||
} else {
|
||||
var emp = Parse.Object.extend(localStorage.getItem("extended_class"));
|
||||
var q = new Parse.Query(emp);
|
||||
q.equalTo("UserId", {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: currentUser
|
||||
});
|
||||
res = await q.first();
|
||||
if (res) res = res.toJSON();
|
||||
}
|
||||
if (res) {
|
||||
let json = res;
|
||||
var reg = /(\#.*?\#)/gi; // eslint-disable-line
|
||||
var str = props.Data.query;
|
||||
var test = "";
|
||||
if (str.includes("#filterCondition#")) {
|
||||
str = str.replace(
|
||||
"#filterCondition#",
|
||||
onSearchFilter(props.DefaultQuery)
|
||||
);
|
||||
}
|
||||
if (props.Data.extendkey) {
|
||||
let a = props.Data.extendkey.split(".");
|
||||
if (a.length > 0) {
|
||||
test = str.replace(reg, json[a[0]][a[1]]);
|
||||
} else {
|
||||
test = str.replace(reg, json[a[0]]);
|
||||
}
|
||||
} else {
|
||||
test = str.replace(reg, json.objectId);
|
||||
}
|
||||
if (str.replace(reg, json.objectId)) {
|
||||
body = test;
|
||||
} else {
|
||||
body = props.Data.query;
|
||||
}
|
||||
} else {
|
||||
body = props.Data.query;
|
||||
}
|
||||
await axios.post(url, body, { headers: headers }).then((res) => {
|
||||
if (res) {
|
||||
if (res.data.result.length > 0) {
|
||||
setresponse(res.data.result[0][props.Data.key]);
|
||||
} else {
|
||||
setresponse(0);
|
||||
}
|
||||
setLoading(false);
|
||||
} else {
|
||||
setLoading(false);
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("Problem", e.message);
|
||||
setLoading(false);
|
||||
}
|
||||
} else {
|
||||
setLoading(true);
|
||||
try {
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
const currentUser = Parse.User.current();
|
||||
let reg1 = /(\#.*?\#)/gi; // eslint-disable-line
|
||||
let _query = props.Data.query;
|
||||
let str = _query;
|
||||
var test1;
|
||||
str = str.split("#$").join("$");
|
||||
str = str.split("#*").join("$");
|
||||
str = str.split("_DOT_").join(".");
|
||||
|
||||
if (str.includes("#")) {
|
||||
let resr;
|
||||
if (localStorage.getItem("Extand_Class")) {
|
||||
let data = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||
resr = data[0];
|
||||
} else {
|
||||
let emp = Parse.Object.extend(
|
||||
localStorage.getItem("extended_class")
|
||||
);
|
||||
let q = new Parse.Query(emp);
|
||||
q.equalTo("UserId", currentUser);
|
||||
let t = await q.first();
|
||||
resr = t.toJSON();
|
||||
}
|
||||
|
||||
let json = resr;
|
||||
let output = str.match(reg1);
|
||||
const HashCount = str.match(reg1);
|
||||
if (HashCount.length > 1) {
|
||||
// `getReplacedHashQuery` is used to replace multiple hash keyword with actual values from query
|
||||
test1 = getReplacedHashQuery(str, json);
|
||||
} else {
|
||||
output = output.join();
|
||||
output = output.substring(1, output.length - 1);
|
||||
output = output.split(".");
|
||||
if (output.length > 1) {
|
||||
test1 = str.replace(reg1, json[output[0]][output[1]]);
|
||||
} else if (json[output[0]]) {
|
||||
if (typeof json[output[0]] === "object") {
|
||||
test1 = str.replace(reg1, JSON.stringify(json[output[0]]));
|
||||
} else {
|
||||
test1 = str.replace(reg1, json[output[0]]);
|
||||
}
|
||||
} else {
|
||||
test1 = str.replace(reg1, currentUser.id);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
test1 = str.replace(reg1, currentUser.id);
|
||||
}
|
||||
let url = `${parseBaseUrl}classes/${props.Data.class}?${test1}`;
|
||||
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.data.results.length > 0) {
|
||||
setLoading(false);
|
||||
if (props.Data.key !== "count") {
|
||||
setresponse(res.data.results[0][props.Data.key]);
|
||||
} else {
|
||||
if (props.Label === "Need your Signature") {
|
||||
const listData = res.data?.results.filter(
|
||||
(x) => x.Signers.length > 0
|
||||
);
|
||||
let arr = [];
|
||||
for (const obj of listData) {
|
||||
const isSigner = obj.Signers.some(
|
||||
(item) => item.UserId.objectId === currentUser.id
|
||||
);
|
||||
if (isSigner) {
|
||||
let isRecord;
|
||||
if (obj?.AuditTrail && obj?.AuditTrail.length > 0) {
|
||||
isRecord = obj?.AuditTrail.some(
|
||||
(item) =>
|
||||
item?.UserPtr?.UserId?.objectId === currentUser.id &&
|
||||
item.Activity === "Signed"
|
||||
);
|
||||
} else {
|
||||
isRecord = false;
|
||||
}
|
||||
if (isRecord === false) {
|
||||
arr.push(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
setresponse(arr.length);
|
||||
} else {
|
||||
setresponse(res.data[props.Data.key]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setresponse(0);
|
||||
setLoading(false);
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("Problem", e);
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const filterRender = async () => {
|
||||
if (props.FilterData && props.FilterData.queryType === "function") {
|
||||
setLoading(true);
|
||||
try {
|
||||
let url = `${parseBaseUrl}${props.FilterData.class}`;
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": parseAppId,
|
||||
sessionToken: localStorage.getItem("accesstoken")
|
||||
};
|
||||
|
||||
let body = {};
|
||||
var str = props.FilterData.query;
|
||||
let restr = JSON.stringify(props.FilterData.query);
|
||||
var reg = /(\#.*?\#)/gi; // eslint-disable-line
|
||||
restr = restr.split("#$").join("$");
|
||||
restr = restr.split("#*").join("$");
|
||||
restr = restr.split("_DOT_").join(".");
|
||||
|
||||
if (restr.includes("#")) {
|
||||
try {
|
||||
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 {
|
||||
var emp = Parse.Object.extend(
|
||||
localStorage.getItem("extended_class")
|
||||
);
|
||||
var q = new Parse.Query(emp);
|
||||
q.equalTo("UserId", currentUser);
|
||||
let resr = await q.first();
|
||||
res = resr.toJSON();
|
||||
}
|
||||
|
||||
let json = res;
|
||||
let output = restr.match(reg);
|
||||
if (output.length === 1) {
|
||||
output = output.filter((x) => x === "#filterCondition#");
|
||||
if (output.length === 1) {
|
||||
str = str.replace("#filterCondition#", props.Filter);
|
||||
} else {
|
||||
output = output.join();
|
||||
output = output.substring(1, output.length - 1);
|
||||
output = output.split(".");
|
||||
if (output.length > 0) {
|
||||
str = str.replace(reg, json[output[0]][output[1]]);
|
||||
} else {
|
||||
str = str.replace(reg, json[output[0]]);
|
||||
}
|
||||
}
|
||||
} else if (output.length === 2) {
|
||||
output = output.filter((x) => x !== "#filterCondition#");
|
||||
if (output.length === 1) {
|
||||
str = str.replace("#filterCondition#", props.Filter);
|
||||
output = output.join();
|
||||
output = output.substring(1, output.length - 1);
|
||||
output = output.split(".");
|
||||
if (output.length > 1) {
|
||||
str = str.replace(reg, json[output[0]][output[1]]);
|
||||
} else {
|
||||
str = str.replace(reg, json[output[0]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
body = str;
|
||||
await axios
|
||||
.post(url, body, { headers: headers })
|
||||
.then((response) => {
|
||||
try {
|
||||
if (response.data.result.length > 0) {
|
||||
setresponse(response.data.result[0][props.FilterData.key]);
|
||||
setLoading(false);
|
||||
} else {
|
||||
setresponse("0");
|
||||
setLoading(false);
|
||||
}
|
||||
} catch (error) {
|
||||
setLoading(false);
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Problem", e);
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const setFormat = (val) => {
|
||||
switch (props.Format) {
|
||||
case "INR":
|
||||
if (val)
|
||||
return Number(val)
|
||||
.toFixed(2)
|
||||
.toString()
|
||||
.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||
return 0;
|
||||
default:
|
||||
return val;
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
renderData();
|
||||
//eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.Filter) {
|
||||
filterRender();
|
||||
}
|
||||
//eslint-disable-next-line
|
||||
}, [props.Filter]);
|
||||
|
||||
function openReport() {
|
||||
if (props.Data && props.Data.Redirect_type) {
|
||||
const Redirect_type = props.Data.Redirect_type;
|
||||
const id = props.Data.Redirect_id;
|
||||
if (Redirect_type === "Form") {
|
||||
navigate(`/form/${id}`);
|
||||
} else if (Redirect_type === "Report") {
|
||||
navigate(`/report/${id}`);
|
||||
} else if (Redirect_type === "Url") {
|
||||
window.location = id;
|
||||
} else if (Redirect_type === "Microapp") {
|
||||
navigate(`/microapp/${id}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div
|
||||
onClick={() => openReport()}
|
||||
className={`${
|
||||
props.Data && props.Data.Redirect_type
|
||||
? "cursor-pointer"
|
||||
: "cursor-default"
|
||||
} w-full h-[140px] px-3 pt-4 pb-10 text-white rounded-md shadow overflow-hidden`}
|
||||
>
|
||||
<div className="flex items-center justify-start gap-5">
|
||||
<span className="rounded-full bg-black bg-opacity-20 w-[60px] h-[60px] self-start flex justify-center items-center">
|
||||
<i
|
||||
className={`${
|
||||
props.Icon ? props.Icon : "fa fa-solid fa-info"
|
||||
} text-[25px] lg:text-[30px]`}
|
||||
></i>
|
||||
</span>
|
||||
<div className="">
|
||||
<div className="text-base lg:text-lg"> {props.Label}</div>
|
||||
<div className="text-2xl font-light">
|
||||
{loading ? <div className="loader-01"></div> : setFormat(response)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DashboardCard;
|
||||
@@ -1,120 +0,0 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Parse from "parse";
|
||||
import ReportTable from "../../primitives/GetReportDisplay";
|
||||
import reportJson from "../../json/ReportJson";
|
||||
import axios from "axios";
|
||||
function DashboardReport(props) {
|
||||
// console.log("props ", props)
|
||||
const [List, setList] = useState([]);
|
||||
const [isLoader, setIsLoader] = useState(true);
|
||||
const [reportName, setReportName] = useState("");
|
||||
const [actions, setActions] = useState([]);
|
||||
useEffect(() => {
|
||||
setReportName("");
|
||||
getReportData(props.Record.reportId);
|
||||
}, [props.Record.reportId]);
|
||||
|
||||
const getReportData = async (id) => {
|
||||
setIsLoader(true);
|
||||
const json = reportJson(id);
|
||||
if (json) {
|
||||
setActions(json.actions);
|
||||
setReportName(json.reportName);
|
||||
const { className, params, keys, orderBy } = json;
|
||||
Parse.serverURL = localStorage.getItem("BaseUrl12");
|
||||
Parse.initialize(localStorage.getItem("AppID12"));
|
||||
const serverURL =
|
||||
localStorage.getItem("BaseUrl12") + "classes/" + className;
|
||||
|
||||
const strParams = JSON.stringify(params);
|
||||
const strKeys = keys.join();
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("AppID12"),
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
};
|
||||
try {
|
||||
const url = `${serverURL}?where=${strParams}&keys=${strKeys}&order=${orderBy}&include=AuditTrail.UserPtr`;
|
||||
const res = await axios.get(url, { headers: headers });
|
||||
// console.log("res ", res.data?.results);
|
||||
if (id === "5Go51Q7T8r") {
|
||||
const currentUser = Parse.User.current().id;
|
||||
const listData = res.data?.results.filter(
|
||||
(x) => x.Signers.length > 0
|
||||
);
|
||||
let arr = [];
|
||||
for (const obj of listData) {
|
||||
const isSigner = obj.Signers.some(
|
||||
(item) => item.UserId.objectId === currentUser
|
||||
);
|
||||
if (isSigner) {
|
||||
let isRecord;
|
||||
if (obj?.AuditTrail && obj?.AuditTrail.length > 0) {
|
||||
isRecord = obj?.AuditTrail.some(
|
||||
(item) =>
|
||||
item?.UserPtr?.UserId?.objectId === currentUser &&
|
||||
item.Activity === "Signed"
|
||||
);
|
||||
} else {
|
||||
isRecord = false;
|
||||
}
|
||||
if (isRecord === false) {
|
||||
arr.push(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
setList(arr);
|
||||
} else {
|
||||
setList(res.data?.results);
|
||||
}
|
||||
setIsLoader(false);
|
||||
} catch (err) {
|
||||
console.log("err ", err);
|
||||
setIsLoader(false);
|
||||
}
|
||||
} else {
|
||||
setIsLoader(false);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<>
|
||||
{isLoader ? (
|
||||
<div
|
||||
style={{
|
||||
height: "100vh",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontSize: "45px",
|
||||
color: "#3dd3e0"
|
||||
}}
|
||||
className="loader-37"
|
||||
></div>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{reportName ? (
|
||||
<ReportTable
|
||||
ReportName={reportName}
|
||||
List={List}
|
||||
act={"Sign"}
|
||||
actions={actions}
|
||||
/>
|
||||
) : (
|
||||
<div className="flex items-center justify-center h-[100px] w-full bg-white rounded">
|
||||
<div className="text-center">
|
||||
<p className="text-xl text-black">Report Not Found</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default DashboardReport;
|
||||
@@ -1,431 +0,0 @@
|
||||
import React, { useState, Suspense, lazy } from "react";
|
||||
import moment from "moment";
|
||||
import ErrorBoundary from "../ErrorBoundary";
|
||||
|
||||
const DashboardCard = lazy(() => import("./DashboardCard"));
|
||||
|
||||
const DashboardReport = lazy(() => import("./DashboardReport"));
|
||||
|
||||
const GetDashboard = (props) => {
|
||||
const [filter, setfilter] = useState("");
|
||||
const [option, setoption] = useState("");
|
||||
|
||||
const onSearchFilter = (e) => {
|
||||
let _search = e.target.value;
|
||||
localStorage.setItem("DashboardDefaultFilter", _search);
|
||||
switch (_search) {
|
||||
case "Today": {
|
||||
let d = new Date();
|
||||
let formDate = new Date(
|
||||
Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0)
|
||||
).toISOString();
|
||||
let Todate = new Date(
|
||||
Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59)
|
||||
).toISOString();
|
||||
let Query = `'$gte':'${formDate}','$lte':'${Todate}'`;
|
||||
setfilter(Query);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "Yesterday": {
|
||||
let d1 = new Date();
|
||||
d1.setDate(d1.getDate() - 1);
|
||||
let yesFrDate = new Date(
|
||||
Date.UTC(d1.getFullYear(), d1.getMonth(), d1.getDate(), 0, 0, 0)
|
||||
).toISOString();
|
||||
|
||||
let YesTodate = new Date(
|
||||
Date.UTC(d1.getFullYear(), d1.getMonth(), d1.getDate(), 23, 59, 59)
|
||||
).toISOString();
|
||||
let Query1 = `'$gte':'${yesFrDate}','$lte':'${YesTodate}'`;
|
||||
setfilter(Query1);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "This week": {
|
||||
let oneDay = 24 * 60 * 60 * 1000;
|
||||
let curr = new Date(); // get current date
|
||||
let first = curr.getDate() - curr.getDay(); // First day is the day of the month - the day of the week
|
||||
|
||||
let firstday = new Date(
|
||||
new Date(
|
||||
Date.UTC(
|
||||
curr.getFullYear(),
|
||||
curr.getMonth(),
|
||||
curr.getDate(),
|
||||
0,
|
||||
0,
|
||||
0
|
||||
)
|
||||
).setDate(first)
|
||||
).toISOString();
|
||||
let diffDays = Math.round(
|
||||
Math.abs(
|
||||
(new Date(
|
||||
Date.UTC(
|
||||
curr.getFullYear(),
|
||||
curr.getMonth(),
|
||||
curr.getDate(),
|
||||
23,
|
||||
59,
|
||||
59
|
||||
)
|
||||
) -
|
||||
new Date(firstday)) /
|
||||
oneDay
|
||||
)
|
||||
); //Days since last week
|
||||
let last = first + diffDays;
|
||||
let lastday = new Date(
|
||||
new Date(
|
||||
Date.UTC(
|
||||
curr.getFullYear(),
|
||||
curr.getMonth(),
|
||||
curr.getDate(),
|
||||
23,
|
||||
59,
|
||||
59
|
||||
)
|
||||
).setDate(last)
|
||||
).toISOString();
|
||||
let Query2 = `'$gte':'${firstday}','$lte':'${lastday}'`;
|
||||
setfilter(Query2);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "Last 7 days": {
|
||||
let d7 = new Date();
|
||||
let d7l = new Date();
|
||||
d7.setDate(d7.getDate() - 7);
|
||||
let l7t = new Date(
|
||||
Date.UTC(d7l.getFullYear(), d7l.getMonth(), d7l.getDate(), 23, 59, 59)
|
||||
).toISOString();
|
||||
let date7 = new Date(
|
||||
Date.UTC(d7.getFullYear(), d7.getMonth(), d7.getDate(), 0, 0, 0)
|
||||
).toISOString();
|
||||
let Query7 = `'$gte':'${date7}','$lte':'${l7t}'`;
|
||||
setfilter(Query7);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "Last 14 days": {
|
||||
let d14 = new Date();
|
||||
let d14l = new Date();
|
||||
let l14t = new Date(
|
||||
Date.UTC(
|
||||
d14l.getFullYear(),
|
||||
d14l.getMonth(),
|
||||
d14l.getDate(),
|
||||
23,
|
||||
59,
|
||||
59
|
||||
)
|
||||
).toISOString();
|
||||
d14.setDate(d14.getDate() - 14);
|
||||
let date14 = new Date(
|
||||
Date.UTC(d14.getFullYear(), d14.getMonth(), d14.getDate(), 0, 0, 0)
|
||||
).toISOString();
|
||||
|
||||
let Query14 = `'$gte':'${date14}','$lte':'${l14t}'`;
|
||||
setfilter(Query14);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "Last 30 days": {
|
||||
let d30 = new Date();
|
||||
let d30l = new Date();
|
||||
let l30t = new Date(
|
||||
Date.UTC(
|
||||
d30l.getFullYear(),
|
||||
d30l.getMonth(),
|
||||
d30l.getDate(),
|
||||
23,
|
||||
59,
|
||||
59
|
||||
)
|
||||
).toISOString();
|
||||
d30.setDate(d30.getDate() - 30);
|
||||
let date30 = new Date(
|
||||
Date.UTC(d30.getFullYear(), d30.getMonth(), d30.getDate(), 0, 0, 0)
|
||||
).toISOString();
|
||||
let Query30 = `'$gte':'${date30}','$lte':'${l30t}'`;
|
||||
setfilter(Query30);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "Last week": {
|
||||
const from_date = moment().startOf("week").subtract(7, "days");
|
||||
const to_date = moment().endOf("week").subtract(7, "days");
|
||||
let Queryl = `'$gte':'${from_date.toISOString()}','$lte':'${to_date.toISOString()}'`;
|
||||
setfilter(Queryl);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "This month": {
|
||||
const tdate = new Date();
|
||||
let tfirstDay = new Date(
|
||||
tdate.getFullYear(),
|
||||
tdate.getMonth(),
|
||||
1
|
||||
).toISOString();
|
||||
let tlastDay = new Date(
|
||||
tdate.getFullYear(),
|
||||
tdate.getMonth() + 1,
|
||||
0
|
||||
).toISOString();
|
||||
let Querylt = `'$gte':'${tfirstDay}','$lte':'${tlastDay}'`;
|
||||
setfilter(Querylt);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "Last month": {
|
||||
const ldate = new Date();
|
||||
var lfirstDay = new Date(
|
||||
ldate.getFullYear(),
|
||||
ldate.getMonth() - 1,
|
||||
2
|
||||
).toISOString();
|
||||
var llastDay = new Date(
|
||||
ldate.getFullYear(),
|
||||
ldate.getMonth(),
|
||||
1
|
||||
).toISOString();
|
||||
let Queryltl = `'$gte':'${lfirstDay}','$lte':'${llastDay}'`;
|
||||
setfilter(Queryltl);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "All": {
|
||||
let fall = new Date(
|
||||
new Date().getFullYear() - 100,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
).toISOString();
|
||||
let fall_year = `'$gte':'${fall}'`;
|
||||
setfilter(fall_year);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "This year": {
|
||||
let fcy = new Date(
|
||||
new Date().getFullYear(),
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
).toISOString();
|
||||
let lcy = new Date(
|
||||
new Date().getFullYear(),
|
||||
11,
|
||||
31,
|
||||
23,
|
||||
59,
|
||||
59
|
||||
).toISOString();
|
||||
let cur_year = `'$gte':'${fcy}','$lte':'${lcy}'`;
|
||||
setfilter(cur_year);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
case "Last year": {
|
||||
let fly = new Date(
|
||||
new Date().getFullYear() - 1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
).toISOString();
|
||||
let lly = new Date(
|
||||
new Date().getFullYear() - 1,
|
||||
11,
|
||||
31,
|
||||
23,
|
||||
59,
|
||||
59
|
||||
).toISOString();
|
||||
let last_year = `'$gte':'${fly}','$lte':'${lly}'`;
|
||||
setfilter(last_year);
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
setoption(_search);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
const renderSwitchWithTour = (col) => {
|
||||
switch (col.widget.type) {
|
||||
case "Card":
|
||||
return (
|
||||
<div
|
||||
className={"bg-[#2ed8b6] rounded-md shadow mb-4 md:mb-0"}
|
||||
data-tut={col.widget.data.tourSection}
|
||||
style={{ background: col.widget.bgColor }}
|
||||
>
|
||||
<Suspense fallback={<div>please wait</div>}>
|
||||
<DashboardCard
|
||||
Icon={col.widget.icon}
|
||||
Label={col.widget.label}
|
||||
Filter={filter}
|
||||
Format={col.widget.format && col.widget.format}
|
||||
Data={col.widget.data}
|
||||
FilterData={col.widget.filter}
|
||||
DefaultQuery={props.DefaultQuery}
|
||||
/>
|
||||
</Suspense>
|
||||
</div>
|
||||
);
|
||||
case "customeHtml":
|
||||
return (
|
||||
<div data-tut={col.widget.data.tourSection}>
|
||||
<select
|
||||
id="searchFiltr"
|
||||
className="form-control"
|
||||
value={
|
||||
option ||
|
||||
localStorage.getItem("DashboardDefaultFilter") ||
|
||||
col.widget.data[0].default
|
||||
}
|
||||
onChange={onSearchFilter}
|
||||
>
|
||||
{col.widget.data[0].options.map((opt) => (
|
||||
<option key={opt} value={opt}>
|
||||
{opt}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
<br />
|
||||
</div>
|
||||
);
|
||||
|
||||
case "customeTag":
|
||||
return (
|
||||
<h3
|
||||
data-tut={col.widget.data.tourSection}
|
||||
style={{
|
||||
marginBottom: "4px",
|
||||
color: "currentColor",
|
||||
marginLeft: "4px"
|
||||
}}
|
||||
>
|
||||
{col.widget.label}
|
||||
</h3>
|
||||
);
|
||||
case "report": {
|
||||
let _filter = `${col.widget.filterKey}:${filter}`;
|
||||
return (
|
||||
<div data-tut={col.widget.data.tourSection}>
|
||||
<Suspense fallback={<div>please wait</div>}>
|
||||
<div className="mb-4 md:mb-0">
|
||||
<DashboardReport Filter={_filter} Record={col.widget} />
|
||||
</div>
|
||||
</Suspense>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
const renderSwitch = (col) => {
|
||||
switch (col.widget.type) {
|
||||
case "Card":
|
||||
return (
|
||||
<div
|
||||
className={"bg-[#2ed8b6] rounded-md shadow mb-4 md:mb-0"}
|
||||
style={{ background: col.widget.bgColor }}
|
||||
>
|
||||
<Suspense fallback={<div>please wait</div>}>
|
||||
<DashboardCard
|
||||
Icon={col.widget.icon}
|
||||
Label={col.widget.label}
|
||||
Filter={filter}
|
||||
Format={col.widget.format && col.widget.format}
|
||||
Data={col.widget.data}
|
||||
FilterData={col.widget.filter}
|
||||
DefaultQuery={props.DefaultQuery}
|
||||
/>
|
||||
</Suspense>
|
||||
</div>
|
||||
);
|
||||
case "customeHtml":
|
||||
return (
|
||||
<div>
|
||||
<select
|
||||
id="searchFiltr"
|
||||
className="form-control"
|
||||
value={
|
||||
option ||
|
||||
localStorage.getItem("DashboardDefaultFilter") ||
|
||||
col.widget.data[0].default
|
||||
}
|
||||
onChange={onSearchFilter}
|
||||
>
|
||||
{col.widget.data[0].options.map((opt) => (
|
||||
<option key={opt} value={opt}>
|
||||
{opt}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
<br />
|
||||
</div>
|
||||
);
|
||||
|
||||
case "customeTag":
|
||||
return (
|
||||
<h3
|
||||
style={{
|
||||
marginBottom: "4px",
|
||||
color: "currentColor",
|
||||
marginLeft: "4px"
|
||||
}}
|
||||
>
|
||||
{col.widget.label}
|
||||
</h3>
|
||||
);
|
||||
case "report": {
|
||||
let _filter = `${col.widget.filterKey}:${filter}`;
|
||||
return (
|
||||
<Suspense fallback={<div>please wait</div>}>
|
||||
<div className="mb-4 md:mb-0">
|
||||
<DashboardReport Filter={_filter} Record={col.widget} />
|
||||
</div>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
<div>
|
||||
{props.dashboard.map((val, key) => (
|
||||
<div key={"a" + key} className="row">
|
||||
{val.columns.map((col, i) =>
|
||||
col.widget.data && col.widget.data.tourSection ? (
|
||||
<div key={i} className={props.classnameArray[key][i]}>
|
||||
{renderSwitchWithTour(col)}
|
||||
</div>
|
||||
) : (
|
||||
<div key={i} className={props.classnameArray[key][i]}>
|
||||
{renderSwitch(col)}
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
};
|
||||
|
||||
export default GetDashboard;
|
||||
@@ -1,265 +0,0 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { SaveFileSize } from "../../constant/saveFileSize";
|
||||
import Parse from "parse";
|
||||
import sanitizeFileName from "../../primitives/sanitizeFileName";
|
||||
|
||||
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 [localValue, setLocalValue] = useState("");
|
||||
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;
|
||||
setLocalValue(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);
|
||||
}
|
||||
};
|
||||
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>
|
||||
|
||||
<>
|
||||
{localValue ? (
|
||||
<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}
|
||||
/>
|
||||
) : props.formData ? (
|
||||
<div
|
||||
style={{
|
||||
border: "1px solid #ccc",
|
||||
color: "gray",
|
||||
backgroundColor: "white",
|
||||
padding: "5px 10px",
|
||||
borderRadius: "4px",
|
||||
fontSize: "13px",
|
||||
width: "100%",
|
||||
fontWeight: "bold"
|
||||
}}
|
||||
>
|
||||
file selected : {props.formData.split("/")[3]}
|
||||
</div>
|
||||
) : (
|
||||
<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}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default FileUpload;
|
||||
@@ -1,83 +0,0 @@
|
||||
import React, { Component } from "react";
|
||||
import Parse from "parse";
|
||||
import axios from "axios";
|
||||
|
||||
export class HiddenField extends Component {
|
||||
state = {
|
||||
baseUrl: localStorage.getItem("baseUrl"),
|
||||
parseAppId: localStorage.getItem("parseAppId"),
|
||||
_fields: ""
|
||||
};
|
||||
loadData = async () => {
|
||||
if (this.props.schema.default) {
|
||||
this.setState({ _fields: this.props.schema.default });
|
||||
} else {
|
||||
try {
|
||||
Parse.serverURL = this.state.baseUrl;
|
||||
Parse.initialize(this.state.parseAppId);
|
||||
let currentUser = await Parse.User.current();
|
||||
if (localStorage.getItem("Extand_Class")) {
|
||||
let _rdata = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||
let custome_Filed = "";
|
||||
let splitArray = this.props.schema.data.valueKey.split(".");
|
||||
if (splitArray.length > 1) {
|
||||
custome_Filed = _rdata[0][splitArray[0]][splitArray[1]];
|
||||
} else {
|
||||
let _Filed = _rdata[0][splitArray[0]];
|
||||
if (typeof _Filed === "object") {
|
||||
custome_Filed = {
|
||||
__type: "Pointer",
|
||||
className: _Filed["className"],
|
||||
objectId: _Filed["objectId"]
|
||||
};
|
||||
} else {
|
||||
custome_Filed = _rdata[0][splitArray[0]];
|
||||
}
|
||||
}
|
||||
this.setState({ _fields: custome_Filed });
|
||||
} else {
|
||||
if (currentUser) {
|
||||
let url = `${this.state.baseUrl}classes/${localStorage.getItem(
|
||||
"extended_class"
|
||||
)}?where={"UserId":{"__type":"Pointer","className":"_User","objectId":"${
|
||||
currentUser.id
|
||||
}"}}&keys=${this.props.schema.data.valueKey}`;
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": this.state.parseAppId
|
||||
};
|
||||
await axios.get(url, { headers: headers }).then((res) => {
|
||||
let custome_Filed = "";
|
||||
let _rdata = res.data.results;
|
||||
let splitArray = this.props.schema.data.valueKey.split(".");
|
||||
if (splitArray.length > 1) {
|
||||
custome_Filed = _rdata[0][splitArray[0]][splitArray[1]];
|
||||
} else {
|
||||
console.log(_rdata[0][splitArray[0]]);
|
||||
custome_Filed = _rdata[0][splitArray[0]];
|
||||
}
|
||||
this.setState({ _fields: custome_Filed });
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('err', error)
|
||||
}
|
||||
}
|
||||
};
|
||||
componentDidMount() {
|
||||
this.loadData();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<input
|
||||
type="hidden"
|
||||
value={this.state._fields}
|
||||
onChange={this.props.onChange(this.state._fields)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default HiddenField;
|
||||
@@ -1,70 +0,0 @@
|
||||
import React from "react";
|
||||
import parse from "html-react-parser";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
const LabelField = (props) => {
|
||||
const { Title, Name, Required, HelpBody, HelpLink } = props;
|
||||
const REQUIRED_FIELD_SYMBOL = "*";
|
||||
return (
|
||||
<div style={{ display: "inline-block" }}>
|
||||
<label htmlFor={Name}>
|
||||
{Title}
|
||||
{Required && <span className="required">{REQUIRED_FIELD_SYMBOL}</span>}
|
||||
{HelpBody ? (
|
||||
<div className="dropdown pull-right">
|
||||
<i
|
||||
className="far fa-question-circle dropdown-toggle hovereffect pull-right"
|
||||
aria-hidden="true"
|
||||
id="dropdownMenuButton"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
style={{
|
||||
fontSize: "12px",
|
||||
color: "purple",
|
||||
cursor: "pointer !important",
|
||||
position: "relative",
|
||||
bottom: "0px",
|
||||
left: "0px",
|
||||
paddingBottom: "4px",
|
||||
paddingLeft: "4px"
|
||||
}}
|
||||
></i>
|
||||
<div
|
||||
className="dropdown-menu"
|
||||
aria-labelledby="dropdownMenuButton"
|
||||
style={{
|
||||
marginleft: "-121px",
|
||||
margintop: "-14px",
|
||||
position: "absolute",
|
||||
padding: "10px",
|
||||
top: "102px!important"
|
||||
}}
|
||||
>
|
||||
{parse(`
|
||||
${HelpBody}
|
||||
`)}
|
||||
<br />
|
||||
{HelpLink ? (
|
||||
<a
|
||||
href={HelpLink}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="btn btn-xs btn-primary"
|
||||
>
|
||||
Read more..
|
||||
</a>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
LabelField.propTypes = {
|
||||
Name: PropTypes.string.isRequired,
|
||||
Title: PropTypes.string.isRequired
|
||||
};
|
||||
export default LabelField;
|
||||
@@ -1,484 +0,0 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { onChangeLevel1Dropdown } from "../../redux/actions/index";
|
||||
import axios from "axios";
|
||||
import Parse from "parse";
|
||||
import parse from "html-react-parser";
|
||||
|
||||
const Level1Dropdown = (props) => {
|
||||
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
||||
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
||||
const [Level1_DD, setLevel1_DD] = useState([]);
|
||||
const [toastColor] = useState("#d9534f");
|
||||
const [toastDescription, setToastDescription] = useState("");
|
||||
const [active, setActive] = useState(false);
|
||||
|
||||
const getParams = (offset) => {
|
||||
const params = {
|
||||
skip: offset
|
||||
};
|
||||
return params;
|
||||
};
|
||||
|
||||
const Level1DropdownData = async () => {
|
||||
try {
|
||||
if (
|
||||
props.formData &&
|
||||
props.uiSchema["ui:disabled"] &&
|
||||
props.formData !== "Select"
|
||||
) {
|
||||
let url = `${parseBaseUrl}classes/${props.schema.data.class}/${props.formData}`;
|
||||
if (typeof props.formData === "object") {
|
||||
url = `${parseBaseUrl}classes/${props.schema.data.class}/${props.formData.objectId}`;
|
||||
}
|
||||
let headers1 = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": parseAppId,
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
};
|
||||
let data = [];
|
||||
let response = [];
|
||||
await axios.get(url, { headers: headers1 }).then((res) => {
|
||||
if (res) {
|
||||
data.push(res.data);
|
||||
}
|
||||
});
|
||||
|
||||
if (data.length > 0) {
|
||||
let temp = [];
|
||||
data.forEach((x) => {
|
||||
let opt = "";
|
||||
if (Array.isArray(x[props.schema.data.valueKey])) {
|
||||
x[props.schema.data.valueKey].forEach((tt) => {
|
||||
if (typeof tt === "object") {
|
||||
opt = {
|
||||
objectId: tt[props.schema.data.displayKey],
|
||||
option: tt[props.schema.data.displayKey]
|
||||
};
|
||||
} else {
|
||||
opt = {
|
||||
objectId: tt,
|
||||
option: tt
|
||||
};
|
||||
}
|
||||
temp.push(opt);
|
||||
});
|
||||
} else if (props.schema.data.isPointer) {
|
||||
if (props.schema.data.valueKey.includes(".")) {
|
||||
let newArr = props.schema.data.valueKey.split(".");
|
||||
if (newArr.length === 2) {
|
||||
opt = {
|
||||
objectId: x[newArr[0]][newArr[1]],
|
||||
option: x[props.schema.data.displayKey]
|
||||
};
|
||||
} else {
|
||||
opt = {
|
||||
objectId: x[newArr[0]],
|
||||
option: x[props.schema.data.displayKey]
|
||||
};
|
||||
}
|
||||
} else {
|
||||
opt = {
|
||||
objectId: x[props.schema.data.valueKey],
|
||||
option: x[props.schema.data.displayKey]
|
||||
};
|
||||
}
|
||||
temp.push(opt);
|
||||
} else {
|
||||
opt = {
|
||||
objectId: x[props.schema.data.valueKey],
|
||||
option: x[props.schema.data.displayKey]
|
||||
};
|
||||
temp.push(opt);
|
||||
}
|
||||
});
|
||||
response = temp;
|
||||
setLevel1_DD(response);
|
||||
setActive(false);
|
||||
if (response.length === 1) {
|
||||
props.onChangeLevel1Dropdown(response[0].objectId, props.name);
|
||||
props.onChange(response[0].objectId);
|
||||
} else if (response.length === 0) {
|
||||
props.onChangeLevel1Dropdown("", props.name);
|
||||
props.onChange("");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let response = [];
|
||||
setActive(true);
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
const currentUser = Parse.User.current();
|
||||
|
||||
// eslint-disable-next-line
|
||||
var reg = /(\#.*?\#)/gi;
|
||||
let str = props.schema.data.query;
|
||||
var test;
|
||||
if (str.includes("#")) {
|
||||
let res;
|
||||
if (localStorage.getItem("Extand_Class")) {
|
||||
let data = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||
res = data[0];
|
||||
} else {
|
||||
var emp = Parse.Object.extend(
|
||||
localStorage.getItem("extended_class")
|
||||
);
|
||||
var q = new Parse.Query(emp);
|
||||
q.equalTo("UserId", currentUser);
|
||||
res = await q.first();
|
||||
if (res) res = res.toJSON();
|
||||
}
|
||||
|
||||
if (res) {
|
||||
let json = res;
|
||||
let output = str.match(reg);
|
||||
if (output.length === 1) {
|
||||
output = output.join();
|
||||
output = output.substring(1, output.length - 1);
|
||||
output = output.split(".");
|
||||
if (output.length === 1) {
|
||||
let out = output[0];
|
||||
if (json[out]) {
|
||||
if (typeof json[out] === "object") {
|
||||
test = str.replace(reg, JSON.stringify(json[out]));
|
||||
} else {
|
||||
test = str.replace(reg, json[out]);
|
||||
}
|
||||
} else {
|
||||
test = str.replace(reg, currentUser.id);
|
||||
}
|
||||
} else if (output.length === 2) {
|
||||
let out1 = json[output[0]][output[1]];
|
||||
if (out1) {
|
||||
test = str.replace(reg, out1);
|
||||
}
|
||||
}
|
||||
} else if (output.length === 2) {
|
||||
let output1 = output[0];
|
||||
output1 = output1.substring(1, output1.length - 1);
|
||||
output1 = output1.split(".");
|
||||
if (output1.length === 1) {
|
||||
let out = output1[0];
|
||||
if (json[out]) {
|
||||
if (typeof json[out] === "object") {
|
||||
str = str.replace(output[0], JSON.stringify(json[out]));
|
||||
} else {
|
||||
str = str.replace(output[0], json[out]);
|
||||
}
|
||||
} else {
|
||||
str = str.replace(output[0], currentUser.id);
|
||||
}
|
||||
} else if (output1.length === 2) {
|
||||
let out1 = json[output1[0]][output1[1]];
|
||||
if (out1) {
|
||||
str = str.replace(output[0], out1);
|
||||
}
|
||||
}
|
||||
let output2 = output[1];
|
||||
output2 = output2.substring(1, output2.length - 1);
|
||||
output2 = output2.split(".");
|
||||
if (output2.length === 1) {
|
||||
let out = output2[0];
|
||||
if (json[out]) {
|
||||
if (typeof json[out] === "object") {
|
||||
str = str.replace(output[1], JSON.stringify(json[out]));
|
||||
} else {
|
||||
str = str.replace(output[1], json[out]);
|
||||
}
|
||||
} else {
|
||||
str = str.replace(output[1], currentUser.id);
|
||||
}
|
||||
} else if (output2.length === 2) {
|
||||
let out1 = json[output2[0]][output2[1]];
|
||||
if (out1) {
|
||||
str = str.replace(output[1], out1);
|
||||
}
|
||||
}
|
||||
test = str;
|
||||
}
|
||||
} else {
|
||||
setToastDescription(
|
||||
`User not found in ${localStorage.getItem("extended_class")}`
|
||||
);
|
||||
setActive(false);
|
||||
var x = document.getElementById("Level_1");
|
||||
x.className = "show";
|
||||
setTimeout(function () {
|
||||
x.className = x.className.replace("show", "");
|
||||
}, 5000);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
test = str;
|
||||
}
|
||||
let url = `${parseBaseUrl}classes/${props.schema.data.class}?${test}`;
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": parseAppId,
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
};
|
||||
let fetchCount = 0;
|
||||
let offset = 0;
|
||||
let data = [];
|
||||
/* eslint-disable no-constant-condition */
|
||||
while (true) {
|
||||
const params = getParams(offset);
|
||||
await axios
|
||||
.get(url, { params: params, headers: headers })
|
||||
.then((response) => {
|
||||
fetchCount = response.data.results.length;
|
||||
offset += response.data.results.length;
|
||||
|
||||
if (fetchCount > 0) {
|
||||
response.data.results.forEach((x) => {
|
||||
data.push(x);
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Problem", err.response);
|
||||
setToastDescription(err.response.data.message);
|
||||
setActive(false);
|
||||
var x = document.getElementById("Level_1");
|
||||
x.className = "show";
|
||||
setTimeout(function () {
|
||||
x.className = x.className.replace("show", "");
|
||||
}, 5000);
|
||||
});
|
||||
if (fetchCount === 0 || fetchCount < 100) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (data.length > 0) {
|
||||
let temp = [];
|
||||
data.forEach((x) => {
|
||||
let opt = "";
|
||||
if (Array.isArray(x[props.schema.data.valueKey])) {
|
||||
x[props.schema.data.valueKey].forEach((tt) => {
|
||||
if (typeof tt === "object") {
|
||||
if (props.schema.data.isPointer) {
|
||||
opt = {
|
||||
objectId: tt["objectId"],
|
||||
option: tt[props.schema.data.displayKey]
|
||||
};
|
||||
} else {
|
||||
opt = {
|
||||
objectId: tt[props.schema.data.displayKey],
|
||||
option: tt[props.schema.data.displayKey]
|
||||
};
|
||||
}
|
||||
} else {
|
||||
opt = {
|
||||
objectId: tt,
|
||||
option: tt
|
||||
};
|
||||
}
|
||||
temp.push(opt);
|
||||
});
|
||||
} else if (props.schema.data.isPointer) {
|
||||
if (props.schema.data.valueKey.includes(".")) {
|
||||
let newArr = props.schema.data.valueKey.split(".");
|
||||
if (newArr.length === 2) {
|
||||
let _dis = props.schema.data.displayKey.split(".");
|
||||
if (_dis.length === 2) {
|
||||
opt = {
|
||||
objectId: x[newArr[0]][newArr[1]],
|
||||
option: x[_dis[0]][_dis[1]]
|
||||
};
|
||||
} else {
|
||||
opt = {
|
||||
objectId: x[newArr[0]][newArr[1]],
|
||||
option: x[props.schema.data.displayKey]
|
||||
};
|
||||
}
|
||||
} else {
|
||||
opt = {
|
||||
objectId: x[newArr[0]],
|
||||
option: x[props.schema.data.displayKey]
|
||||
};
|
||||
}
|
||||
} else {
|
||||
opt = {
|
||||
objectId: x[props.schema.data.valueKey],
|
||||
option: x[props.schema.data.displayKey]
|
||||
};
|
||||
}
|
||||
temp.push(opt);
|
||||
} else {
|
||||
opt = {
|
||||
objectId: x[props.schema.data.valueKey],
|
||||
option: x[props.schema.data.displayKey]
|
||||
};
|
||||
temp.push(opt);
|
||||
}
|
||||
});
|
||||
response = temp;
|
||||
setLevel1_DD(response);
|
||||
setActive(false);
|
||||
if (!props.formData) {
|
||||
props.onChangeLevel1Dropdown("", props.name);
|
||||
}
|
||||
if (response.length === 1) {
|
||||
props.onChangeLevel1Dropdown(response[0].objectId, props.name);
|
||||
props.onChange(response[0].objectId);
|
||||
} else if (response.length === 0) {
|
||||
props.onChangeLevel1Dropdown("", props.name);
|
||||
props.onChange("");
|
||||
}
|
||||
} else {
|
||||
setActive(false);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
try {
|
||||
setToastDescription(e.message);
|
||||
setActive(false);
|
||||
x = document.getElementById("Level_1");
|
||||
x.className = "show";
|
||||
setTimeout(function () {
|
||||
x.className = x.className.replace("show", "");
|
||||
}, 5000);
|
||||
} catch (error) {
|
||||
console.log("Err", error)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
Level1DropdownData();
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.formData && props.formData[`objectId`]) {
|
||||
props.onChangeLevel1Dropdown(props.formData.objectId, props.name);
|
||||
} else if (props.formData) {
|
||||
props.onChangeLevel1Dropdown(props.formData, props.name);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
}, [props.formData]);
|
||||
|
||||
const selectDefault = () => {
|
||||
props.onChange(Level1_DD[0].objectId);
|
||||
props.onChangeLevel1Dropdown(Level1_DD[0].objectId, props.name);
|
||||
};
|
||||
|
||||
const REQUIRED_FIELD_SYMBOL = "*";
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div style={{ display: "inline-block" }}>
|
||||
<label htmlFor={props.name}>
|
||||
{props.schema.title}
|
||||
{props.required && (
|
||||
<span className="required">{REQUIRED_FIELD_SYMBOL}</span>
|
||||
)}
|
||||
{props.schema.data.helpbody ? (
|
||||
<div className="dropdown pull-right">
|
||||
<i
|
||||
className="far fa-question-circle dropdown-toggle hovereffect pull-right"
|
||||
aria-hidden="true"
|
||||
id="dropdownMenuButton"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
style={{
|
||||
fontSize: "12px",
|
||||
color: "purple",
|
||||
cursor: "pointer !important",
|
||||
position: "relative",
|
||||
bottom: "0px",
|
||||
left: "0px",
|
||||
paddingBottom: "4px",
|
||||
paddingLeft: "4px"
|
||||
}}
|
||||
></i>
|
||||
<div
|
||||
className="dropdown-menu"
|
||||
aria-labelledby="dropdownMenuButton"
|
||||
style={{
|
||||
marginleft: "-121px",
|
||||
margintop: "-14px",
|
||||
position: "absolute",
|
||||
padding: "10px",
|
||||
top: "102px!important"
|
||||
}}
|
||||
>
|
||||
{parse(`
|
||||
${props.schema.data.helpbody}
|
||||
`)}
|
||||
<br />
|
||||
{props.schema.data.helplink ? (
|
||||
<a
|
||||
href={props.schema.data.helplink}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="btn btn-xs btn-primary"
|
||||
>
|
||||
Read more..
|
||||
</a>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{Level1_DD && (
|
||||
<select
|
||||
className="form-control"
|
||||
name={props.name}
|
||||
value={props.value}
|
||||
required={props.required}
|
||||
disabled={props.uiSchema["ui:disabled"]}
|
||||
onChange={(e) => {
|
||||
if (!e.target.value) {
|
||||
if (props.schema.data.isPointer) {
|
||||
localStorage.setItem("Level1", undefined);
|
||||
props.onChangeLevel1Dropdown(undefined, props.name);
|
||||
return props.onChange(undefined);
|
||||
} else {
|
||||
localStorage.setItem("Level1", e.target.value);
|
||||
props.onChangeLevel1Dropdown(e.target.value, props.name);
|
||||
return props.onChange(e.target.value);
|
||||
}
|
||||
} else {
|
||||
localStorage.setItem("Level1", e.target.value);
|
||||
props.onChangeLevel1Dropdown(e.target.value, props.name);
|
||||
return props.onChange(e.target.value);
|
||||
}
|
||||
}}
|
||||
readOnly={props.uiSchema["ui:disabled"] ? true : false}
|
||||
defaultValue={Level1_DD.length === 1 && selectDefault}
|
||||
>
|
||||
<option value="">{!active ? "Select" : "loading..."}</option>
|
||||
{Level1_DD &&
|
||||
Level1_DD.map((x, i) => (
|
||||
<React.Fragment key={i}>
|
||||
{props.formData && props.formData.objectId ? (
|
||||
props.formData.objectId === x.objectId ? (
|
||||
<option value={x.objectId} selected>
|
||||
{x.option}
|
||||
</option>
|
||||
) : (
|
||||
<option value={x.objectId}>{x.option}</option>
|
||||
)
|
||||
) : props.formData && props.formData === x.objectId ? (
|
||||
<option value={x.objectId} selected>
|
||||
{x.option}
|
||||
</option>
|
||||
) : (
|
||||
<option value={x.objectId}>{x.option}</option>
|
||||
)}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</select>
|
||||
)}
|
||||
<div id="Level_1" style={{ backgroundColor: toastColor }}>
|
||||
{toastDescription}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default connect(null, { onChangeLevel1Dropdown })(Level1Dropdown);
|
||||
@@ -1,709 +0,0 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import Select from "react-select";
|
||||
import axios from "axios";
|
||||
import LabelField from "./LabelField";
|
||||
import ReactDragListView from "react-drag-listview";
|
||||
import AppendFormInForm from "../AppendFormInForm";
|
||||
import Modal from "react-modal";
|
||||
function arrayMove(array, from, to) {
|
||||
array = array.slice();
|
||||
array.splice(to < 0 ? array.length + to : to, 0, array.splice(from, 1)[0]);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* react-sortable-hoc is depcreated not usable from react 18.x.x
|
||||
* need to replace it with @dnd-kit
|
||||
* code changes required
|
||||
*/
|
||||
|
||||
const MultiSelectField = (props) => {
|
||||
Modal.setAppElement("body");
|
||||
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
||||
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
||||
const [state, setState] = useState(undefined);
|
||||
// const [editFormData, setEditFormData] = useState([]);
|
||||
const [selected, setSelected] = React.useState([]);
|
||||
const [isModal, setIsModel] = useState(false);
|
||||
const onChange = (selectedOptions) => setSelected(selectedOptions);
|
||||
const [modalIsOpen, setModalIsOpen] = useState(false);
|
||||
|
||||
const onSortEnd = ({ oldIndex, newIndex }) => {
|
||||
const newValue = arrayMove(selected, oldIndex, newIndex);
|
||||
setSelected(newValue);
|
||||
};
|
||||
// console.log("props",props)
|
||||
const GetSelectListData = async () => {
|
||||
try {
|
||||
let response = [];
|
||||
let str = props.schema.data.query;
|
||||
let _query;
|
||||
/* eslint-disable no-useless-escape */
|
||||
let reg = /(\#.*?\#)/gi;
|
||||
let extclass =
|
||||
localStorage.getItem("Extand_Class") &&
|
||||
JSON.parse(localStorage.getItem("Extand_Class"));
|
||||
let extRow = extclass.length && extclass[0];
|
||||
if (str.includes("#")) {
|
||||
let output = str.match(reg);
|
||||
output = output.join();
|
||||
output = output.substring(1, output.length - 1);
|
||||
output = output.split(".");
|
||||
|
||||
if (output.length === 2) {
|
||||
let out1 = extRow[output[0]][output[1]];
|
||||
_query = str.replace(reg, out1 && out1);
|
||||
} else {
|
||||
let out1 = extRow[output[0]];
|
||||
_query = str.replace(reg, out1 && out1);
|
||||
}
|
||||
} else {
|
||||
_query = str;
|
||||
}
|
||||
let url = `${parseBaseUrl}classes/${props.schema.data.class}?${_query}`;
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": parseAppId,
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
};
|
||||
await axios.get(url, { headers: headers }).then((res) => {
|
||||
let temp = [];
|
||||
let formArray = [];
|
||||
let _selected = [];
|
||||
if (props.schema.uiLayout === "MultiDropdownList") {
|
||||
if (props.formData) {
|
||||
props.formData.forEach((x) => {
|
||||
if (typeof x === "object") {
|
||||
formArray.push(x.objectId);
|
||||
} else {
|
||||
formArray.push(x);
|
||||
}
|
||||
});
|
||||
}
|
||||
res.data.results.forEach((x) => {
|
||||
let obj = {};
|
||||
if (formArray.includes(x[props.schema.data.valueKey])) {
|
||||
obj = {
|
||||
name: x[props.schema.data.displayKey],
|
||||
value: x[props.schema.data.valueKey],
|
||||
isChecked: true
|
||||
};
|
||||
} else {
|
||||
if (props.schema.selectAll) {
|
||||
obj = {
|
||||
name: x[props.schema.data.displayKey],
|
||||
value: x[props.schema.data.valueKey],
|
||||
isChecked: true
|
||||
};
|
||||
} else {
|
||||
obj = {
|
||||
name: x[props.schema.data.displayKey],
|
||||
value: x[props.schema.data.valueKey],
|
||||
isChecked: false
|
||||
};
|
||||
}
|
||||
}
|
||||
temp.push(obj);
|
||||
});
|
||||
response = temp;
|
||||
if (props.formData) {
|
||||
let checkData = [];
|
||||
response.forEach((x) => {
|
||||
if (x.isChecked) {
|
||||
checkData.push(x.value);
|
||||
}
|
||||
});
|
||||
setSelected(checkData);
|
||||
}
|
||||
setState({ [`${props.name}_DD`]: response });
|
||||
} else {
|
||||
res.data.results.forEach((x) => {
|
||||
let obj = {};
|
||||
if (props.formData) {
|
||||
props.formData.forEach((x) => {
|
||||
if (typeof x === "object") {
|
||||
formArray.push(x.objectId);
|
||||
} else {
|
||||
formArray.push(x);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
obj = {
|
||||
label: x[props.schema.data.displayKey],
|
||||
value: x[props.schema.data.valueKey]
|
||||
};
|
||||
if (formArray.includes(x[props.schema.data.valueKey])) {
|
||||
_selected.push(obj);
|
||||
}
|
||||
if (props.schema.selectAll) {
|
||||
_selected.push(obj);
|
||||
}
|
||||
temp.push(obj);
|
||||
});
|
||||
response = temp;
|
||||
setState({ [`${props.name}_DD`]: response });
|
||||
setSelected(_selected);
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("err", error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCheckChieldElement = (event) => {
|
||||
let SelectLists = state[`${props.name}_DD`];
|
||||
let List = [];
|
||||
SelectLists.forEach((select) => {
|
||||
if (select.value === event.target.value) {
|
||||
select.isChecked = event.target.checked;
|
||||
}
|
||||
if (select.isChecked) {
|
||||
List.push(select.value);
|
||||
}
|
||||
});
|
||||
setSelected(List);
|
||||
setState({ [`${props.name}_DD`]: SelectLists });
|
||||
};
|
||||
|
||||
// const Level1CheckList = async (id) => {
|
||||
// try {
|
||||
// let response = [];
|
||||
// // eslint-disable-next-line
|
||||
// let reg = /(\#.*?\#)/gi;
|
||||
// let _query = props.schema.data.query;
|
||||
// let output = _query.match(reg);
|
||||
// if (output.length === 2) {
|
||||
// let res;
|
||||
// if (localStorage.getItem("Extand_Class")) {
|
||||
// let data = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||
// res = data[0];
|
||||
// }
|
||||
// output = output.filter((x) => x !== "#queryString#");
|
||||
// if (output.length === 1) {
|
||||
// _query = _query.replace("#queryString#", id);
|
||||
// output = output.join();
|
||||
// output = output.substring(1, output.length - 1);
|
||||
// output = output.split(".");
|
||||
// if (output.length > 0) {
|
||||
// _query = _query.replace(reg, res[output[0]][output[1]]);
|
||||
// } else {
|
||||
// _query = _query.replace(reg, res[output[0]]);
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// _query = props.schema.data.query.replace(reg, id);
|
||||
// }
|
||||
|
||||
// let url = `${parseBaseUrl}classes/${props.schema.data.class}?${_query}`;
|
||||
// const headers = {
|
||||
// "Content-Type": "application/json",
|
||||
// "X-Parse-Application-Id": parseAppId,
|
||||
// "X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
// };
|
||||
// await axios.get(url, { headers: headers }).then(async (res) => {
|
||||
// let temp = [];
|
||||
// let formArray = [];
|
||||
// let _selected = [];
|
||||
// if (editFormData.length > 0) {
|
||||
// editFormData.forEach((x) => {
|
||||
// if (typeof x === "object") {
|
||||
// formArray.push(x.objectId);
|
||||
// } else {
|
||||
// formArray.push(x);
|
||||
// }
|
||||
// });
|
||||
// } else if (
|
||||
// props.schema.selectedData &&
|
||||
// Object.keys(props.schema.selectedData).length !== 0 &&
|
||||
// props.schema.selectedData.constructor === Object
|
||||
// ) {
|
||||
// try {
|
||||
// let selectedDataQuery = props.schema.selectedData.query.replace(
|
||||
// reg,
|
||||
// id
|
||||
// );
|
||||
// let selectedDataUrl = `${parseBaseUrl}classes/${props.schema.selectedData.class}?${selectedDataQuery}`;
|
||||
|
||||
// await axios.get(selectedDataUrl, { headers }).then((sltres) => {
|
||||
// let sltData = sltres.data.results;
|
||||
// sltData.forEach((x) => {
|
||||
// if (props.schema.selectedData.valueKey.includes(".")) {
|
||||
// let sltArr = props.schema.selectedData.valueKey.split(".");
|
||||
|
||||
// if (Array.isArray(x[sltArr[0]])) {
|
||||
// x[sltArr[0]].forEach((l) => {
|
||||
// formArray.push(l[sltArr[1]]);
|
||||
// });
|
||||
// } else {
|
||||
// formArray.push(x[sltArr[0][sltArr[1]]]);
|
||||
// }
|
||||
// } else {
|
||||
// formArray.push(x[props.schema.selectedData.valueKey]);
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// } catch (error) {}
|
||||
// }
|
||||
// res.data.results.forEach((x) => {
|
||||
// let obj = {};
|
||||
// if (props.schema.data.valueKey.includes(".")) {
|
||||
// let newArr = props.schema.data.valueKey.split(".");
|
||||
// if (Array.isArray(x[newArr[0]])) {
|
||||
// if (props.schema.data.displayKey.includes(".")) {
|
||||
// let _dis = props.schema.data.displayKey.split(".");
|
||||
// x[newArr[0]].forEach((l) => {
|
||||
// if (formArray.includes(l[newArr[1]])) {
|
||||
// obj = {
|
||||
// label: l[_dis[1]],
|
||||
// value: l[newArr[1]],
|
||||
// isChecked: true
|
||||
// };
|
||||
// _selected.push(obj);
|
||||
// } else {
|
||||
// if (props.schema.selectAll) {
|
||||
// obj = {
|
||||
// label: l[_dis[1]],
|
||||
// value: l[newArr[1]],
|
||||
// isChecked: true
|
||||
// };
|
||||
// _selected.push(obj);
|
||||
// } else {
|
||||
// obj = {
|
||||
// label: l[_dis[1]],
|
||||
// value: l[newArr[1]],
|
||||
// isChecked: false
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// temp.push(obj);
|
||||
// });
|
||||
// } else {
|
||||
// x[newArr[0]].forEach((l) => {
|
||||
// if (formArray.includes(l[newArr[1]])) {
|
||||
// obj = {
|
||||
// label: x[props.schema.data.displayKey],
|
||||
// value: l[newArr[1]],
|
||||
// isChecked: true
|
||||
// };
|
||||
// _selected.push(obj);
|
||||
// } else {
|
||||
// if (props.schema.selectAll) {
|
||||
// obj = {
|
||||
// label: x[props.schema.data.displayKey],
|
||||
// value: l[newArr[1]],
|
||||
// isChecked: true
|
||||
// };
|
||||
// _selected.push(obj);
|
||||
// } else {
|
||||
// obj = {
|
||||
// label: x[props.schema.data.displayKey],
|
||||
// value: l[newArr[1]],
|
||||
// isChecked: false
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// temp.push(obj);
|
||||
// });
|
||||
// }
|
||||
// } else {
|
||||
// if (props.schema.data.displayKey.includes(".")) {
|
||||
// let disArr = props.schema.data.displayKey.split(".");
|
||||
// if (formArray.includes(x[newArr[0]][newArr[1]])) {
|
||||
// obj = {
|
||||
// label: x[disArr[0]][disArr[1]],
|
||||
// value: x[newArr[0]][newArr[1]],
|
||||
// isChecked: true
|
||||
// };
|
||||
// _selected.push(obj);
|
||||
// } else {
|
||||
// if (props.schema.selectAll) {
|
||||
// obj = {
|
||||
// label: x[disArr[0]][disArr[1]],
|
||||
// value: x[newArr[0]][newArr[1]],
|
||||
// isChecked: true
|
||||
// };
|
||||
// _selected.push(obj);
|
||||
// } else {
|
||||
// obj = {
|
||||
// label: x[disArr[0]][disArr[1]],
|
||||
// value: x[newArr[0]][newArr[1]],
|
||||
// isChecked: false
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// if (formArray.includes(x[newArr[0]][newArr[1]])) {
|
||||
// obj = {
|
||||
// label: x[props.schema.data.displayKey],
|
||||
// value: x[newArr[0]][newArr[1]],
|
||||
// isChecked: true
|
||||
// };
|
||||
// _selected.push(obj);
|
||||
// } else {
|
||||
// if (props.schema.selectAll) {
|
||||
// obj = {
|
||||
// label: x[props.schema.data.displayKey],
|
||||
// value: x[newArr[0]][newArr[1]],
|
||||
// isChecked: true
|
||||
// };
|
||||
// _selected.push(obj);
|
||||
// } else {
|
||||
// obj = {
|
||||
// label: x[props.schema.data.displayKey],
|
||||
// value: x[newArr[0]][newArr[1]],
|
||||
// isChecked: false
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// if (Array.isArray(x[props.schema.data.valueKey])) {
|
||||
// x[props.schema.data.valueKey].forEach((t) => {
|
||||
// if (formArray.includes(t)) {
|
||||
// obj = {
|
||||
// label: t,
|
||||
// value: t,
|
||||
// isChecked: true
|
||||
// };
|
||||
// _selected.push(obj);
|
||||
// } else {
|
||||
// if (props.schema.selectAll) {
|
||||
// obj = {
|
||||
// label: t,
|
||||
// value: t,
|
||||
// isChecked: true
|
||||
// };
|
||||
// _selected.push(obj);
|
||||
// } else {
|
||||
// obj = {
|
||||
// label: t,
|
||||
// value: t,
|
||||
// isChecked: false
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// temp.push(obj);
|
||||
// });
|
||||
// } else if (formArray.includes(x[props.schema.data.valueKey])) {
|
||||
// obj = {
|
||||
// label: x[props.schema.data.displayKey],
|
||||
// value: x[props.schema.data.valueKey],
|
||||
// isChecked: true
|
||||
// };
|
||||
// _selected.push(obj);
|
||||
// } else {
|
||||
// if (props.schema.selectAll) {
|
||||
// obj = {
|
||||
// label: x[props.schema.data.displayKey],
|
||||
// value: x[props.schema.data.valueKey],
|
||||
// isChecked: true
|
||||
// };
|
||||
// _selected.push(obj);
|
||||
// } else {
|
||||
// obj = {
|
||||
// label: x[props.schema.data.displayKey],
|
||||
// value: x[props.schema.data.valueKey],
|
||||
// isChecked: false
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// temp.push(obj);
|
||||
// }
|
||||
// });
|
||||
// response = temp;
|
||||
// if (props.schema.uiLayout === "MultiDropdownList") {
|
||||
// if (editFormData) {
|
||||
// let checkData = [];
|
||||
// response.forEach((x) => {
|
||||
// if (x.isChecked) {
|
||||
// checkData.push(x.value);
|
||||
// }
|
||||
// });
|
||||
// setSelected(checkData);
|
||||
// }
|
||||
// setState({ [`${props.name}_DD`]: response });
|
||||
// } else {
|
||||
// setState({ [`${props.name}_DD`]: response });
|
||||
// setSelected(_selected);
|
||||
// }
|
||||
// });
|
||||
// } catch (error) {}
|
||||
// };
|
||||
|
||||
const dragProps = {
|
||||
onDragEnd(fromIndex, toIndex) {
|
||||
const data = [...state[`${props.name}_DD`]];
|
||||
const item = data.splice(fromIndex, 1)[0];
|
||||
data.splice(toIndex, 0, item);
|
||||
let NewList = [];
|
||||
data.forEach((x) => {
|
||||
if (x.isChecked) {
|
||||
NewList.push(x.value);
|
||||
}
|
||||
});
|
||||
|
||||
setState({ [`${props.name}_DD`]: data });
|
||||
setSelected(NewList);
|
||||
},
|
||||
nodeSelector: "li",
|
||||
handleSelector: "a"
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!props.schema.parent) GetSelectListData();
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.schema.uiLayout === "MultiDropdownList") {
|
||||
props.onChange(selected);
|
||||
} else {
|
||||
if (selected && selected.length) {
|
||||
let newData = [];
|
||||
selected.forEach((x) => {
|
||||
newData.push(x.value);
|
||||
});
|
||||
props.onChange(newData);
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line
|
||||
}, [selected]);
|
||||
|
||||
// useState(() => {
|
||||
// if (props.formData) {
|
||||
// if (props.formData === "Select") {
|
||||
// } else {
|
||||
// setEditFormData(props.formData);
|
||||
// }
|
||||
// }
|
||||
// // eslint-disable-next-line
|
||||
// }, [props.formData]);
|
||||
|
||||
const handleModalCloseClick = () => {
|
||||
setIsModel(false);
|
||||
setModalIsOpen(false);
|
||||
};
|
||||
|
||||
const openModal = () => {
|
||||
setModalIsOpen(true);
|
||||
};
|
||||
|
||||
// `handleNewDetails` is used to set just save from quick form to selected option in dropdown
|
||||
const handleNewDetails = (data) => {
|
||||
setState({ [`${props.name}_DD`]: [...state[`${props.name}_DD`], data] });
|
||||
if (selected.length > 0) {
|
||||
setSelected([...selected, data]);
|
||||
} else {
|
||||
setSelected([data]);
|
||||
}
|
||||
};
|
||||
if (props.schema.uiLayout === "MultiDropdownList") {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<LabelField
|
||||
Title={props.schema.title}
|
||||
Name={props.name}
|
||||
Required={props.required}
|
||||
HelpBody={props.schema.helpbody}
|
||||
HelpLink={props.schema.helplink}
|
||||
/>
|
||||
<ReactDragListView {...dragProps}>
|
||||
<ul
|
||||
style={{
|
||||
listStyleType: "square",
|
||||
listStylePosition: "outside",
|
||||
maxHeight: "250px",
|
||||
overflow: "auto",
|
||||
paddingTop: "10px",
|
||||
paddingBottom: "10px",
|
||||
border: "0px solid #b3b3b3",
|
||||
borderRadius: "5px"
|
||||
}}
|
||||
>
|
||||
{state && state[`${props.name}_DD`].length > 0 ? (
|
||||
state[`${props.name}_DD`].map((x, i) => {
|
||||
return (
|
||||
<li key={i} className="multiSelectList">
|
||||
<input
|
||||
key={x.value}
|
||||
onClick={handleCheckChieldElement}
|
||||
type="checkbox"
|
||||
checked={x.isChecked}
|
||||
style={{ marginTop: "7px" }}
|
||||
value={x.value}
|
||||
disabled={props.disabled}
|
||||
/>{" "}
|
||||
<span style={{ marginTop: "7px" }}>{x.name}</span>
|
||||
{props.schema.isSortable && !props.disabled && (
|
||||
<a
|
||||
onClick={(e) => e.preventDefault()}
|
||||
className="pull-right"
|
||||
title="Sort List"
|
||||
style={{ textDecoration: "none" }}
|
||||
>
|
||||
<i
|
||||
className="fa fa-bars"
|
||||
style={{
|
||||
fontSize: "30px",
|
||||
color: "skyblue",
|
||||
paddingTop: "11px"
|
||||
}}
|
||||
></i>
|
||||
</a>
|
||||
)}
|
||||
</li>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<li className="multiSelectList">No Record Found</li>
|
||||
)}
|
||||
</ul>
|
||||
</ReactDragListView>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<LabelField
|
||||
Title={props.schema.title}
|
||||
Name={props.name}
|
||||
Required={props.required}
|
||||
HelpBody={props.schema.helpbody}
|
||||
HelpLink={props.schema.helplink}
|
||||
/>
|
||||
<div style={{ display: "flex", gap: 5 }}>
|
||||
<div style={{ flexWrap: "wrap", width: "100%" }}>
|
||||
<Select
|
||||
onSortEnd={onSortEnd}
|
||||
distance={4}
|
||||
isMulti
|
||||
options={(state && state[`${props.name}_DD`]) || []}
|
||||
value={selected}
|
||||
onChange={onChange}
|
||||
closeMenuOnSelect={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{props.schema.data.quickAddFormId && (
|
||||
<div
|
||||
onClick={() => {
|
||||
setIsModel(true);
|
||||
openModal();
|
||||
}}
|
||||
style={{
|
||||
cursor: "pointer",
|
||||
borderRadius: 4,
|
||||
border: "1px solid #ccc",
|
||||
minHeight: 38,
|
||||
minWidth: 48,
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<i className="fas fa-plus"></i>
|
||||
</div>
|
||||
)}
|
||||
{/* {props.schema.data.quickAddFormId && (
|
||||
<div
|
||||
className="modal fade"
|
||||
id={"multiSelectModal" + props.schema.data.quickAddFormId}
|
||||
tabIndex="-1"
|
||||
role="dialog"
|
||||
aria-labelledby="exampleModalLabel"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div className="modal-dialog modal-lg" role="document">
|
||||
<div className="modal-content">
|
||||
<div className="modal-header">
|
||||
<button
|
||||
type="button"
|
||||
className="close"
|
||||
data-dismiss="modal"
|
||||
aria-label="Close"
|
||||
onClick={handleModalCloseClick}
|
||||
>
|
||||
<i className="fa fa-times-circle" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div className="modal-body">
|
||||
{isModal && (
|
||||
<AppendFormInForm
|
||||
id={props.schema.data.quickAddFormId}
|
||||
valueKey={props.schema.data.valueKey}
|
||||
displayKey={props.schema.data.displayKey}
|
||||
details={handleNewDetails}
|
||||
closePopup={handleModalCloseClick}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)} */}
|
||||
<Modal
|
||||
isOpen={modalIsOpen}
|
||||
onRequestClose={handleModalCloseClick}
|
||||
shouldCloseOnOverlayClick={false}
|
||||
contentLabel="Modal"
|
||||
style={{
|
||||
content: {
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
right: "auto",
|
||||
bottom: "auto",
|
||||
transform: "translate(-50%, -50%)",
|
||||
padding: 0
|
||||
},
|
||||
overlay: {
|
||||
width: "100%",
|
||||
backgroundColor: "rgba(0, 0, 0, 0.75)",
|
||||
zIndex: 50
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className="min-w-full md:min-w-[500px]">
|
||||
<div
|
||||
type="button"
|
||||
className="flex justify-between items-center p-3 border-b-[1px] border-gray-300"
|
||||
>
|
||||
<div className=" text-black text-xl font-semibold pl-3">
|
||||
Add Signer
|
||||
</div>
|
||||
<button onClick={handleModalCloseClick}>
|
||||
<i
|
||||
style={{ fontSize: 25 }}
|
||||
className="fa fa-times-circle"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{isModal && (
|
||||
<AppendFormInForm
|
||||
id={props.schema.data.quickAddFormId}
|
||||
valueKey={props.schema.data.valueKey}
|
||||
displayKey={props.schema.data.displayKey}
|
||||
details={handleNewDetails}
|
||||
closePopup={handleModalCloseClick}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
return {
|
||||
Level1_Dropdown: state.Level1_Dropdown,
|
||||
Level2_Dropdown: state.Level2_Dropdown,
|
||||
Level3_Dropdown: state.Level3_Dropdown
|
||||
};
|
||||
};
|
||||
export default connect(mapStateToProps, null)(MultiSelectField);
|
||||
@@ -1,92 +0,0 @@
|
||||
import React from "react";
|
||||
import ObjectField from "@rjsf/core/lib/components/fields/ObjectField";
|
||||
import validator from "@rjsf/validator-ajv8";
|
||||
import { Col } from "react-bootstrap";
|
||||
import { retrieveSchema } from "@rjsf/utils";
|
||||
|
||||
class GridField extends ObjectField {
|
||||
state = {};
|
||||
render() {
|
||||
const {
|
||||
uiSchema,
|
||||
errorSchema,
|
||||
idSchema,
|
||||
|
||||
disabled,
|
||||
readonly,
|
||||
onBlur,
|
||||
formData
|
||||
} = this.props;
|
||||
const { fields, rootSchema } = this.props.registry;
|
||||
|
||||
const { SchemaField } = fields;
|
||||
const schema = retrieveSchema(validator, this.props.schema, rootSchema);
|
||||
const title = schema.title === undefined ? "" : schema.title;
|
||||
const description =
|
||||
schema && schema.description === undefined ? "" : schema.description;
|
||||
// console.log('this.props.schema ', this.props.schema)
|
||||
// console.log("schema ", schema);
|
||||
const layout = uiSchema["ui:layout"];
|
||||
|
||||
return (
|
||||
<fieldset>
|
||||
{title ? <h4>{title}</h4> : null}
|
||||
{description ? <h6>{description}</h6> : null}
|
||||
{layout.map((row, index) => {
|
||||
return (
|
||||
<div className="row" key={index}>
|
||||
{Object.keys(row).map((name, index) => {
|
||||
const { doShow, ...rowProps } = row[name];
|
||||
let style = {};
|
||||
if (doShow && !doShow({ formData })) {
|
||||
style = { display: "none" };
|
||||
}
|
||||
if (schema.properties[name]) {
|
||||
return (
|
||||
<Col {...rowProps} key={index} style={style}>
|
||||
<SchemaField
|
||||
name={name}
|
||||
required={this.isRequired(name)}
|
||||
schema={schema.properties[name]}
|
||||
uiSchema={uiSchema[name]}
|
||||
errorSchema={errorSchema[name]}
|
||||
idSchema={idSchema[name]}
|
||||
formData={formData[name]}
|
||||
onChange={this.onPropertyChange(name)}
|
||||
onBlur={onBlur}
|
||||
registry={this.props.registry}
|
||||
disabled={disabled}
|
||||
readonly={readonly}
|
||||
/>
|
||||
</Col>
|
||||
);
|
||||
} else {
|
||||
const { render, ...rowProps } = row[name];
|
||||
let UIComponent = () => null;
|
||||
|
||||
if (render) {
|
||||
UIComponent = render;
|
||||
}
|
||||
|
||||
return (
|
||||
<Col {...rowProps} key={index} style={style}>
|
||||
<UIComponent
|
||||
name={name}
|
||||
formData={formData}
|
||||
errorSchema={errorSchema}
|
||||
uiSchema={uiSchema}
|
||||
schema={schema}
|
||||
registry={this.props.registry}
|
||||
/>
|
||||
</Col>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</fieldset>
|
||||
);
|
||||
}
|
||||
}
|
||||
export default GridField;
|
||||
@@ -1,26 +0,0 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
function TimeWidget(props) {
|
||||
const {
|
||||
onChange,
|
||||
registry: {
|
||||
widgets: { BaseInput }
|
||||
}
|
||||
} = props;
|
||||
return (
|
||||
<BaseInput
|
||||
type="time"
|
||||
{...props}
|
||||
onChange={(value) => onChange(value || undefined)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
TimeWidget.propTypes = {
|
||||
value: PropTypes.string
|
||||
};
|
||||
}
|
||||
|
||||
export default TimeWidget;
|
||||
@@ -1,21 +0,0 @@
|
||||
import React from "react";
|
||||
import { NavLink } from "react-router-dom";
|
||||
|
||||
const Menu = ({ item, isOpen, closeSidebar }) => {
|
||||
return (
|
||||
<li key={item.title} role="none">
|
||||
<NavLink
|
||||
to={`/${item.pageType}/${item.objectId}`}
|
||||
className="mx-auto flex items-center hover:bg-[#eef1f5] p-3 lg:p-4"
|
||||
onClick={closeSidebar}
|
||||
tabIndex={isOpen ? 0 : -1}
|
||||
role="menuitem"
|
||||
>
|
||||
<i className={`${item.icon} text-[18px]`} aria-hidden="true"></i>
|
||||
<span className="ml-3 lg:ml-4">{item.title}</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
|
||||
export default Menu;
|
||||
@@ -1,78 +0,0 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
|
||||
import Menu from './Menu';
|
||||
import Submenu from "./SubMenu";
|
||||
import SocialMedia from './SocialMedia';
|
||||
|
||||
import Parse from "parse";
|
||||
import dp from "../../assets/images/dp.png";
|
||||
|
||||
const Sidebar = ({ isOpen, closeSidebar }) => {
|
||||
const [menuList, setmenuList] = useState([]);
|
||||
let username = localStorage.getItem("username");
|
||||
const image = localStorage.getItem("profileImg") || dp;
|
||||
const tenantname = localStorage.getItem("TenantName");
|
||||
|
||||
useEffect(() => {
|
||||
if (localStorage.getItem("accesstoken")) {
|
||||
menuItem();
|
||||
}
|
||||
}, []);
|
||||
|
||||
const menuItem = async () => {
|
||||
const parseBaseUrl = localStorage.getItem("baseUrl");
|
||||
const parseAppId = localStorage.getItem("parseAppId");
|
||||
|
||||
try {
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
var sideMenu = Parse.Object.extend("w_menu");
|
||||
var query = new Parse.Query(sideMenu);
|
||||
query.equalTo("objectId", localStorage.getItem("defaultmenuid"));
|
||||
|
||||
const results = await query.first();
|
||||
const resultjson = results.toJSON();
|
||||
let result = resultjson;
|
||||
setmenuList(result.menuItems);
|
||||
} catch (e) {
|
||||
console.error("Problem", e);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<aside
|
||||
className={`${isOpen ? "block" : "hidden"
|
||||
} bg-white text-[#444] h-screen w-full md:w-[300px] overflow-y-auto transform transition-transform z-40 ${isOpen ? "translate-x-0" : "-translate-x-full"
|
||||
}`}
|
||||
>
|
||||
<div className="flex px-2 py-3 gap-2 items-center shadow-md">
|
||||
<div className="w-[75px] h-[75px] rounded-full ring-[2px] ring-offset-2 ring-gray-400 overflow-hidden">
|
||||
<img className="w-full h-full object-cover" src={image} alt="Profile" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-[14px] font-bold">{username}</p>
|
||||
<p className={`text-[12px] ${tenantname ? "mt-2" : ""}`}>
|
||||
{tenantname}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<nav aria-label="OpenSign Sidebar Navigation">
|
||||
<ul className="text-sm" role="menubar" aria-label="OpenSign Sidebar Navigation">
|
||||
{menuList.map((item) => (
|
||||
!item.children ? (
|
||||
<Menu key={item.title} item={item} isOpen={isOpen} closeSidebar={closeSidebar} />
|
||||
) : (
|
||||
<Submenu key={item.title} item={item} closeSidebar={closeSidebar} />
|
||||
)
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
<footer className="mt-4 flex justify-center items-center text-[25px] text-black gap-3">
|
||||
<SocialMedia />
|
||||
</footer>
|
||||
</aside>
|
||||
);
|
||||
};
|
||||
|
||||
export default Sidebar;
|
||||
@@ -1,27 +0,0 @@
|
||||
import React from "react";
|
||||
import { NavLink } from "react-router-dom";
|
||||
|
||||
const SocialMedia = () => {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<NavLink to="https://github.com/opensignlabs/opensign" target="_blank" rel="noopener noreferrer">
|
||||
<i aria-hidden="true" className="fa-brands fa-github"></i>
|
||||
<span className="fa-sr-only">OpenSign's Github</span>
|
||||
</NavLink>
|
||||
<NavLink to="https://www.linkedin.com/company/opensign%E2%84%A2/" target="_blank" rel="noopener noreferrer">
|
||||
<i aria-hidden="true" className="fa-brands fa-linkedin"></i>
|
||||
<span className="fa-sr-only">OpenSign's LinkedIn</span>
|
||||
</NavLink>
|
||||
<NavLink to="https://www.twitter.com/opensignlabs" target="_blank" rel="noopener noreferrer">
|
||||
<i aria-hidden="true" className="fa-brands fa-square-x-twitter"></i>
|
||||
<span className="fa-sr-only">OpenSign's Twitter</span>
|
||||
</NavLink>
|
||||
<NavLink to="https://discord.com/invite/xe9TDuyAyj" target="_blank" rel="noopener noreferrer">
|
||||
<i aria-hidden="true" className="fa-brands fa-discord"></i>
|
||||
<span className="fa-sr-only">OpenSign's Discord</span>
|
||||
</NavLink>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default SocialMedia;
|
||||
@@ -1,53 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import { NavLink } from "react-router-dom";
|
||||
|
||||
const Submenu = ({ item, closeSidebar }) => {
|
||||
const [submenuOpen, setSubmenuOpen] = useState(false);
|
||||
const { title, icon, children } = item;
|
||||
|
||||
const toggleSubmenu = () => {
|
||||
setSubmenuOpen(!submenuOpen);
|
||||
};
|
||||
|
||||
return (
|
||||
<li role="none">
|
||||
<button
|
||||
onClick={toggleSubmenu}
|
||||
className="w-full flex items-center text-left text-[#444] p-3 lg:p-4 hover:bg-[#eef1f5] focus:ring-2 focus:ring-blue-600"
|
||||
aria-expanded={submenuOpen}
|
||||
aria-haspopup="true"
|
||||
aria-controls={`submenu-${title}`}
|
||||
>
|
||||
<i className={`${icon} text-[18px]`}></i>
|
||||
<div className="flex justify-between items-center w-full">
|
||||
<span className="ml-3 lg:ml-4">{title}</span>
|
||||
<i
|
||||
className={`${submenuOpen ? "fa-solid fa-angle-down" : "fa-solid fa-angle-right"
|
||||
}`}
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
</div>
|
||||
</button>
|
||||
{submenuOpen && (
|
||||
<ul id={`submenu-${title}`} role="menu" aria-label={`${title} submenu`}>
|
||||
{children.map((childItem) => (
|
||||
<li key={childItem.title} role="none">
|
||||
<NavLink
|
||||
to={`/${childItem.pageType}/${childItem.objectId}`}
|
||||
className="block pl-6 md:pl-8 py-2 text-sm text-gray-700 hover:bg-blue-500 hover:text-white"
|
||||
onClick={closeSidebar}
|
||||
role="menuitem"
|
||||
tabIndex={submenuOpen ? 0 : -1}
|
||||
>
|
||||
<i className={`${childItem.icon} text-[18px]`} aria-hidden="true"></i>
|
||||
<span className="ml-3 lg:ml-4">{childItem.title}</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
export default Submenu;
|
||||
@@ -1,36 +0,0 @@
|
||||
import logo from "../assets/images/logo.png";
|
||||
export const appInfo = {
|
||||
appTitle: "contracts",
|
||||
applogo: logo,
|
||||
appname: "contracts",
|
||||
baseurl: process.env.REACT_APP_SERVERURL,
|
||||
defaultRole: "contracts_User",
|
||||
fbAppId: process.env.REACT_APP_FBAPPID
|
||||
? `${process.env.REACT_APP_FBAPPID}`
|
||||
: "",
|
||||
fev_Icon:
|
||||
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAALlJREFUaEPtmN0NwjAMBpNxYDKYiM1Yp90g93CKStH1NbIdfz921Dker2Pc+Js1cDF7MXAxASMGYkAigBI6vh9ZwoXP53uZoAYcvhwdA3mAVbI2aSb+9zFKU4IURB6j/HoPUIEa2G3iGIAhQQDlAUIoE2diabIklISS0NoFPebo77RF6OenEF3QntOm128he0GKrwHyACFoz2MgBqSGkpAEcHs47oHtN5AFakACqMNjQEMoE8SABFCHn4HE2zGHSLeEAAAAAElFTkSuQmCC",
|
||||
googleClietId: process.env.REACT_APP_GOOGLECLIENTID
|
||||
? `${process.env.REACT_APP_GOOGLECLIENTID}`
|
||||
: "",
|
||||
metaDescription:
|
||||
"The fastest way to sign PDFs & request signatures from others.",
|
||||
objectId: "aIPmIvMzGM",
|
||||
settings: [
|
||||
{
|
||||
role: "contracts_User",
|
||||
menuId: "H9vRfEYKhT",
|
||||
pageType: "dashboard",
|
||||
pageId: "35KBoSgoAK",
|
||||
extended_class: "contracts_Users"
|
||||
},
|
||||
{
|
||||
role: "contracts_Admin",
|
||||
menuId: "VPh91h0ZHk",
|
||||
pageType: "dashboard",
|
||||
pageId: "35KBoSgoAK",
|
||||
extended_class: "contracts_Users"
|
||||
}
|
||||
],
|
||||
version: "0.1"
|
||||
};
|
||||
@@ -1,40 +0,0 @@
|
||||
import Parse from "parse";
|
||||
/**
|
||||
* Function returning the queryString in which multiple hash replaced with actual values
|
||||
* @param str query string
|
||||
* @param json localstroage data in json
|
||||
*/
|
||||
|
||||
export default function getReplacedHashQuery(str, json) {
|
||||
// eslint-disable-next-line
|
||||
let reg = /(\#.*?\#)/gi;
|
||||
const currentUser = Parse.User.current();
|
||||
const multiHash = str.match(reg);
|
||||
|
||||
let values = {};
|
||||
let key = "";
|
||||
multiHash.forEach((x) => {
|
||||
key = x;
|
||||
key = key.substring(1, key.length - 1);
|
||||
key = key.split(".");
|
||||
if (key.length > 1) {
|
||||
key = x.replace(reg, json[key[0]][key[1]]);
|
||||
} else if (json[key[0]]) {
|
||||
key = x.replace(reg, json[key[0]]);
|
||||
} else if (key[0] === "Date") {
|
||||
key = x.replace(reg, "Date");
|
||||
} else if (key[0] === "today") {
|
||||
key = x.replace(reg, new Date().toISOString());
|
||||
} else {
|
||||
key = x.replace(reg, currentUser.id);
|
||||
}
|
||||
values = { ...values, [x]: key };
|
||||
});
|
||||
const querySplit = str.split(reg);
|
||||
const replacedHashWithValuesArr = querySplit.map((hash) =>
|
||||
values[hash] ? values[hash] : hash
|
||||
);
|
||||
const HashFreeQuery = replacedHashWithValuesArr.join("");
|
||||
// console.log("HashFreeQuery ", HashFreeQuery);
|
||||
return HashFreeQuery;
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
export default function linkURL(url) {
|
||||
let newURL = (url && decodeURIComponent(url)) || "";
|
||||
return newURL.substring(newURL.indexOf(".com/") + 5, newURL.indexOf("_"));
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
import axios from "axios";
|
||||
import Parse from "parse";
|
||||
const parseAppId = localStorage.getItem("AppID12");
|
||||
const serverUrl = localStorage.getItem("BaseUrl12");
|
||||
Parse.serverURL = serverUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
|
||||
export const SaveFileSize = async (size, imageUrl) => {
|
||||
//checking server url and save file's size
|
||||
|
||||
try {
|
||||
const response = await axios
|
||||
.get(`${serverUrl}classes/partners_TenantCredits`, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": parseAppId
|
||||
}
|
||||
})
|
||||
.then((result) => {
|
||||
const res = result.data;
|
||||
// console.log("res", res);
|
||||
|
||||
return res.results;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("axois err ", err);
|
||||
});
|
||||
let data;
|
||||
// console.log("response", response);
|
||||
if (response && response.length > 0) {
|
||||
data = {
|
||||
usedStorage: response[0].usedStorage
|
||||
? response[0].usedStorage + size
|
||||
: size
|
||||
};
|
||||
await axios
|
||||
.put(
|
||||
`${serverUrl}classes/partners_TenantCredits/${response[0].objectId}`,
|
||||
data,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": parseAppId
|
||||
}
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
// const res = result.data;
|
||||
// console.log("save res", res);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("axois err ", err);
|
||||
});
|
||||
} else {
|
||||
data = {
|
||||
usedStorage: size
|
||||
};
|
||||
await axios
|
||||
.post(`${serverUrl}classes/partners_TenantCredits`, data, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": parseAppId
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
// const res = result.data;
|
||||
// console.log("res", res);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("axois err ", err);
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("org app error", e);
|
||||
}
|
||||
saveDataFile(size, imageUrl);
|
||||
};
|
||||
|
||||
//function for save fileUrl and file size in particular client db class partners_DataFiles
|
||||
const saveDataFile = async (size, imageUrl) => {
|
||||
const data = {
|
||||
FileUrl: imageUrl,
|
||||
FileSize: size
|
||||
};
|
||||
|
||||
// console.log("data save",file, data)
|
||||
await axios
|
||||
.post(`${serverUrl}classes/partners_DataFiles`, data, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": parseAppId
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
// const res = result.data;
|
||||
// console.log("res", res);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("axois err ", err);
|
||||
});
|
||||
};
|
||||
@@ -1,210 +0,0 @@
|
||||
import moment from "moment";
|
||||
|
||||
export default function onSearchFilter(_search) {
|
||||
switch (_search) {
|
||||
case "Today": {
|
||||
let d = new Date();
|
||||
let formDate = new Date(
|
||||
Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0)
|
||||
).toISOString();
|
||||
let Todate = new Date(
|
||||
Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59)
|
||||
).toISOString();
|
||||
let Query = `'$gte':'${formDate}','$lte':'${Todate}'`;
|
||||
return Query;
|
||||
}
|
||||
case "Yesterday": {
|
||||
let d1 = new Date();
|
||||
d1.setDate(d1.getDate() - 1);
|
||||
let yesFrDate = new Date(
|
||||
Date.UTC(d1.getFullYear(), d1.getMonth(), d1.getDate(), 0, 0, 0)
|
||||
).toISOString();
|
||||
|
||||
let YesTodate = new Date(
|
||||
Date.UTC(d1.getFullYear(), d1.getMonth(), d1.getDate(), 23, 59, 59)
|
||||
).toISOString();
|
||||
let Query1 = `'$gte':'${yesFrDate}','$lte':'${YesTodate}'`;
|
||||
return Query1;
|
||||
}
|
||||
|
||||
case "This week": {
|
||||
let oneDay = 24 * 60 * 60 * 1000;
|
||||
let curr = new Date(); // get current date
|
||||
let first = curr.getDate() - curr.getDay(); // First day is the day of the month - the day of the week
|
||||
|
||||
let firstday = new Date(
|
||||
new Date(
|
||||
Date.UTC(curr.getFullYear(), curr.getMonth(), curr.getDate(), 0, 0, 0)
|
||||
).setDate(first)
|
||||
).toISOString();
|
||||
let diffDays = Math.round(
|
||||
Math.abs(
|
||||
(new Date(
|
||||
Date.UTC(
|
||||
curr.getFullYear(),
|
||||
curr.getMonth(),
|
||||
curr.getDate(),
|
||||
23,
|
||||
59,
|
||||
59
|
||||
)
|
||||
) -
|
||||
new Date(firstday)) /
|
||||
oneDay
|
||||
)
|
||||
); //Days since last week
|
||||
let last = first + diffDays;
|
||||
let lastday = new Date(
|
||||
new Date(
|
||||
Date.UTC(
|
||||
curr.getFullYear(),
|
||||
curr.getMonth(),
|
||||
curr.getDate(),
|
||||
23,
|
||||
59,
|
||||
59
|
||||
)
|
||||
).setDate(last)
|
||||
).toISOString();
|
||||
let Query2 = `'$gte':'${firstday}','$lte':'${lastday}'`;
|
||||
return Query2;
|
||||
}
|
||||
|
||||
case "Last 7 days": {
|
||||
let d7 = new Date();
|
||||
let d7l = new Date();
|
||||
d7.setDate(d7.getDate() - 7);
|
||||
let l7t = new Date(
|
||||
Date.UTC(d7l.getFullYear(), d7l.getMonth(), d7l.getDate(), 23, 59, 59)
|
||||
).toISOString();
|
||||
let date7 = new Date(
|
||||
Date.UTC(d7.getFullYear(), d7.getMonth(), d7.getDate(), 0, 0, 0)
|
||||
).toISOString();
|
||||
let Query7 = `'$gte':'${date7}','$lte':'${l7t}'`;
|
||||
return Query7;
|
||||
}
|
||||
case "Last 14 days": {
|
||||
let d14 = new Date();
|
||||
let d14l = new Date();
|
||||
let l14t = new Date(
|
||||
Date.UTC(
|
||||
d14l.getFullYear(),
|
||||
d14l.getMonth(),
|
||||
d14l.getDate(),
|
||||
23,
|
||||
59,
|
||||
59
|
||||
)
|
||||
).toISOString();
|
||||
d14.setDate(d14.getDate() - 14);
|
||||
let date14 = new Date(
|
||||
Date.UTC(d14.getFullYear(), d14.getMonth(), d14.getDate(), 0, 0, 0)
|
||||
).toISOString();
|
||||
|
||||
let Query14 = `'$gte':'${date14}','$lte':'${l14t}'`;
|
||||
return Query14;
|
||||
}
|
||||
|
||||
case "Last 30 days": {
|
||||
let d30 = new Date();
|
||||
let d30l = new Date();
|
||||
let l30t = new Date(
|
||||
Date.UTC(
|
||||
d30l.getFullYear(),
|
||||
d30l.getMonth(),
|
||||
d30l.getDate(),
|
||||
23,
|
||||
59,
|
||||
59
|
||||
)
|
||||
).toISOString();
|
||||
d30.setDate(d30.getDate() - 30);
|
||||
let date30 = new Date(
|
||||
Date.UTC(d30.getFullYear(), d30.getMonth(), d30.getDate(), 0, 0, 0)
|
||||
).toISOString();
|
||||
return `'$gte':'${date30}','$lte':'${l30t}'`;
|
||||
}
|
||||
case "Last week": {
|
||||
const from_date = moment().startOf("week").subtract(7, "days");
|
||||
const to_date = moment().endOf("week").subtract(7, "days");
|
||||
return `'$gte':'${from_date.toISOString()}','$lte':'${to_date.toISOString()}'`;
|
||||
}
|
||||
case "This month": {
|
||||
var tdate = new Date();
|
||||
var tfirstDay = new Date(
|
||||
tdate.getFullYear(),
|
||||
tdate.getMonth(),
|
||||
1
|
||||
).toISOString();
|
||||
var tlastDay = new Date(
|
||||
tdate.getFullYear(),
|
||||
tdate.getMonth() + 1,
|
||||
0
|
||||
).toISOString();
|
||||
let Querylt = `'$gte':'${tfirstDay}','$lte':'${tlastDay}'`;
|
||||
return Querylt;
|
||||
}
|
||||
case "Last month": {
|
||||
var ldate = new Date();
|
||||
var lfirstDay = new Date(
|
||||
ldate.getFullYear(),
|
||||
ldate.getMonth() - 1,
|
||||
2
|
||||
).toISOString();
|
||||
var llastDay = new Date(
|
||||
ldate.getFullYear(),
|
||||
ldate.getMonth(),
|
||||
1
|
||||
).toISOString();
|
||||
let Queryltl = `'$gte':'${lfirstDay}','$lte':'${llastDay}'`;
|
||||
return Queryltl;
|
||||
}
|
||||
case "All": {
|
||||
let fall = new Date(
|
||||
new Date().getFullYear() - 100,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
).toISOString();
|
||||
let fall_year = `'$gte':'${fall}'`;
|
||||
return fall_year;
|
||||
}
|
||||
case "This year": {
|
||||
let fcy = new Date(new Date().getFullYear(), 0, 1, 0, 0, 0).toISOString();
|
||||
let lcy = new Date(
|
||||
new Date().getFullYear(),
|
||||
11,
|
||||
31,
|
||||
23,
|
||||
59,
|
||||
59
|
||||
).toISOString();
|
||||
let cur_year = `'$gte':'${fcy}','$lte':'${lcy}'`;
|
||||
return cur_year;
|
||||
}
|
||||
case "Last year": {
|
||||
let fly = new Date(
|
||||
new Date().getFullYear() - 1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
).toISOString();
|
||||
let lly = new Date(
|
||||
new Date().getFullYear() - 1,
|
||||
11,
|
||||
31,
|
||||
23,
|
||||
59,
|
||||
59
|
||||
).toISOString();
|
||||
let last_year = `'$gte':'${fly}','$lte':'${lly}'`;
|
||||
return last_year;
|
||||
}
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { useEffect } from "react";
|
||||
|
||||
/**`useScript` hook is generated scripte for google sign in button */
|
||||
export const useScript = (url, onload) => {
|
||||
useEffect(() => {
|
||||
const script = document.createElement("script");
|
||||
//add url parameter to the script src, for load and it will remove after load in return
|
||||
script.src = url;
|
||||
script.async = true;
|
||||
script.defer = true;
|
||||
script.onload = onload;
|
||||
document.head.appendChild(script);
|
||||
return () => {
|
||||
document.head.removeChild(script);
|
||||
};
|
||||
}, [url, onload]);
|
||||
};
|
||||
@@ -1,25 +0,0 @@
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export function useWindowSize() {
|
||||
const [size, setSize] = useState({
|
||||
width: 0,
|
||||
height: 0
|
||||
});
|
||||
|
||||
const onResize = () => {
|
||||
setSize({
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
onResize();
|
||||
window.addEventListener("resize", onResize);
|
||||
return () => {
|
||||
window.removeEventListener("resize", onResize);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return size;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
body{
|
||||
background-color: white;
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
import("./Bootstrap");
|
||||
@@ -1,585 +0,0 @@
|
||||
import Parse from "parse";
|
||||
export const formJson = (id) => {
|
||||
let formData;
|
||||
//json form for signYourself
|
||||
if (id === "sHAnZphf69") {
|
||||
formData = {
|
||||
jsonSchema: {
|
||||
title: "Sign Yourself",
|
||||
description: "",
|
||||
type: "object",
|
||||
required: ["URL", "Name"],
|
||||
properties: {
|
||||
URL: {
|
||||
type: "string",
|
||||
title: "Select Document",
|
||||
filetypes: [],
|
||||
maxfilesizeKB: "5000",
|
||||
uploadtype: "regular",
|
||||
helpbody: "",
|
||||
helplink: ""
|
||||
},
|
||||
Name: {
|
||||
type: "string",
|
||||
title: "Title",
|
||||
maxLength: 50
|
||||
},
|
||||
Description: {
|
||||
type: "string",
|
||||
title: "Description",
|
||||
maxLength: 500
|
||||
},
|
||||
Folder: {
|
||||
title: "Folder",
|
||||
parent: null,
|
||||
data: {
|
||||
ClassName: "contracts_Document",
|
||||
FolderNameField: "Name",
|
||||
FolderTypeField: "Type",
|
||||
FolderTypeValue: "Folder",
|
||||
FolderDescription: "Description",
|
||||
ParentFolderField: "Folder",
|
||||
FormId: "YjIB7W7Xs6",
|
||||
Query: 'where={"Folder":{"$exists":false},"Type":"Folder"}'
|
||||
}
|
||||
},
|
||||
ExtUserPtr: {
|
||||
data: {
|
||||
valueKey: "objectId",
|
||||
isPointer: true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
uiSchema: {
|
||||
URL: {
|
||||
"ui:field": "FileUpload"
|
||||
},
|
||||
Description: {
|
||||
"ui:widget": "textarea",
|
||||
"ui:options": {
|
||||
rows: 2
|
||||
}
|
||||
},
|
||||
Note: {
|
||||
"ui:widget": "textarea",
|
||||
"ui:options": {
|
||||
rows: 2
|
||||
}
|
||||
},
|
||||
Folder: {
|
||||
"ui:field": "FolderComponent"
|
||||
},
|
||||
ExtUserPtr: {
|
||||
"ui:field": "HiddenField"
|
||||
}
|
||||
},
|
||||
userSchema: {},
|
||||
rules: null,
|
||||
noValidate: false,
|
||||
liveValidate: false,
|
||||
isRegisterForm: false,
|
||||
help: { htmlbody: "" },
|
||||
description: "",
|
||||
class: "contracts_Document",
|
||||
buttons: {
|
||||
add: {
|
||||
resetText: "Reset",
|
||||
submitText: "Submit"
|
||||
},
|
||||
edit: { submitText: "Update", cancelText: "Cancel" }
|
||||
},
|
||||
formACL: {
|
||||
"#currentUser#": { read: true, write: true },
|
||||
"*": { read: true, write: true }
|
||||
},
|
||||
redirect_id:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/signaturePdf",
|
||||
success_message: "Success!",
|
||||
success_redirect: "Microapp",
|
||||
validFunction:
|
||||
"ZnVuY3Rpb24gdmFsaWRhdGUoZm9ybURhdGEsIGVycm9ycykgeyBpZiAoZm9ybURhdGEucGFzczEgIT09IGZvcm1EYXRhLnBhc3MyKSB7IGVycm9ycy5wYXNzMi5hZGRFcnJvcignUGFzc3dvcmRzIGRvbid0IG1hdGNoJyk7IH0gcmV0dXJuIGVycm9yczsgfQ=="
|
||||
};
|
||||
|
||||
return formData;
|
||||
}
|
||||
//json form for request signature
|
||||
else if (id === "8mZzFxbG1z") {
|
||||
const user = Parse.User.current();
|
||||
const userPtr = JSON.stringify({
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: user.id
|
||||
});
|
||||
formData = {
|
||||
jsonSchema: {
|
||||
title: "New Document",
|
||||
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}}&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,388 +0,0 @@
|
||||
import Parse from "parse";
|
||||
export default function reportJson(id) {
|
||||
const currentUserId = Parse.User.current().id;
|
||||
// console.log("json ", json);
|
||||
|
||||
switch (id) {
|
||||
// draft documents report
|
||||
case "ByHuevtCFY":
|
||||
return {
|
||||
reportName: "Draft Documents",
|
||||
className: "contracts_Document",
|
||||
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"
|
||||
],
|
||||
orderBy: "-updatedAt",
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "sign",
|
||||
btnColor: "#4bd396",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-plus",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/draftDocument"
|
||||
}
|
||||
]
|
||||
};
|
||||
// Need your sign report
|
||||
case "4Hhwbp482K":
|
||||
return {
|
||||
reportName: "Need your sign",
|
||||
className: "contracts_Document",
|
||||
params: {
|
||||
Type: { $ne: "Folder" },
|
||||
IsCompleted: { $ne: true },
|
||||
IsDeclined: { $ne: true },
|
||||
ExpiryDate: {
|
||||
$gt: { __type: "Date", iso: new Date().toISOString() }
|
||||
},
|
||||
Placeholders: { $ne: null }
|
||||
},
|
||||
keys: [
|
||||
"Name",
|
||||
"Note",
|
||||
"Folder.Name",
|
||||
"URL",
|
||||
"ExtUserPtr.Name",
|
||||
"Signers.Name",
|
||||
"Signers.UserId",
|
||||
"AuditTrail"
|
||||
],
|
||||
orderBy: "-updatedAt",
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "sign",
|
||||
btnColor: "#3ac9d6",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-eye",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/pdfRequestFiles"
|
||||
}
|
||||
]
|
||||
};
|
||||
// In progess report
|
||||
case "1MwEuxLEkF":
|
||||
return {
|
||||
reportName: "In-progress documents",
|
||||
className: "contracts_Document",
|
||||
params: {
|
||||
Type: { $ne: "Folder" },
|
||||
Signers: { $ne: null },
|
||||
Placeholders: { $ne: null },
|
||||
IsCompleted: { $ne: true },
|
||||
IsDeclined: { $ne: true },
|
||||
CreatedBy: {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: currentUserId
|
||||
},
|
||||
ExpiryDate: {
|
||||
$gt: { __type: "Date", iso: new Date().toISOString() }
|
||||
}
|
||||
},
|
||||
keys: [
|
||||
"Name",
|
||||
"Note",
|
||||
"Folder.Name",
|
||||
"URL",
|
||||
"ExtUserPtr.Name",
|
||||
"Signers.Name"
|
||||
],
|
||||
orderBy: "-updatedAt",
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "View",
|
||||
btnColor: "#3ac9d6",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-eye",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/pdfRequestFiles"
|
||||
}
|
||||
]
|
||||
};
|
||||
// completed documents report
|
||||
case "kQUoW4hUXz":
|
||||
return {
|
||||
reportName: "Completed Documents",
|
||||
className: "contracts_Document",
|
||||
params: {
|
||||
Type: null,
|
||||
IsCompleted: true,
|
||||
CreatedBy: {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: currentUserId
|
||||
},
|
||||
IsDeclined: { $ne: true }
|
||||
},
|
||||
keys: [
|
||||
"Name",
|
||||
"Note",
|
||||
"Folder.Name",
|
||||
"URL",
|
||||
"ExtUserPtr.Name",
|
||||
"Signers.Name",
|
||||
"TimeToCompleteDays"
|
||||
],
|
||||
orderBy: "-updatedAt",
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "View",
|
||||
btnColor: "#4bd396",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-eye",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/draftDocument"
|
||||
}
|
||||
]
|
||||
};
|
||||
// OpenSignDrive™ documents Drafts
|
||||
case "VRFDmUmw5B":
|
||||
return {
|
||||
reportName: "OpenSignDrive™ Drafts",
|
||||
className: "contracts_Document",
|
||||
params: {
|
||||
Type: "AIDoc",
|
||||
$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"
|
||||
],
|
||||
orderBy: "-updatedAt",
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "edit",
|
||||
btnColor: "#3ac9d6",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-plus",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9MZWdhR2VuaWUtTWljcm9hcHBWMi9yZW1vdGVFbnRyeS5qcw==&moduleToLoad=AppRoutes&remoteName=legageniemicroapp/legagenie"
|
||||
}
|
||||
]
|
||||
};
|
||||
// declined documents report
|
||||
case "UPr2Fm5WY3":
|
||||
return {
|
||||
reportName: "Declined Documents",
|
||||
className: "contracts_Document",
|
||||
params: { Type: null, IsDeclined: true },
|
||||
CreatedBy: {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: currentUserId
|
||||
},
|
||||
keys: [
|
||||
"Name",
|
||||
"Note",
|
||||
"Folder.Name",
|
||||
"URL",
|
||||
"ExtUserPtr.Name",
|
||||
"Signers.Name"
|
||||
],
|
||||
orderBy: "-updatedAt",
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "View",
|
||||
btnColor: "#4bd396",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-eye",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/draftDocument"
|
||||
}
|
||||
]
|
||||
};
|
||||
// Expired Documents report
|
||||
case "zNqBHXHsYH":
|
||||
return {
|
||||
reportName: "Expired Documents",
|
||||
className: "contracts_Document",
|
||||
params: {
|
||||
IsCompleted: { $ne: true },
|
||||
IsDeclined: { $ne: true },
|
||||
Type: { $ne: "Folder" },
|
||||
$and: [
|
||||
{
|
||||
$or: [
|
||||
{ Signers: { $ne: null }, SignedUrl: { $ne: null } },
|
||||
{ Placeholders: { $ne: null } }
|
||||
]
|
||||
},
|
||||
{
|
||||
ExpiryDate: {
|
||||
$lt: { __type: "Date", iso: new Date().toISOString() }
|
||||
}
|
||||
}
|
||||
],
|
||||
CreatedBy: {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: currentUserId
|
||||
}
|
||||
},
|
||||
keys: [
|
||||
"Name",
|
||||
"Note",
|
||||
"Folder.Name",
|
||||
"URL",
|
||||
"ExtUserPtr.Name",
|
||||
"Signers.Name"
|
||||
],
|
||||
orderBy: "-updatedAt",
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "View",
|
||||
btnColor: "#4bd396",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-eye",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/draftDocument"
|
||||
}
|
||||
]
|
||||
};
|
||||
// Recently sent for signatures report show on dashboard
|
||||
case "d9k3UfYHBc":
|
||||
return {
|
||||
reportName: "Recently sent for signatures",
|
||||
className: "contracts_Document",
|
||||
params: {
|
||||
Type: { $ne: "Folder" },
|
||||
Signers: { $ne: null },
|
||||
Placeholders: { $ne: null },
|
||||
IsCompleted: { $ne: true },
|
||||
IsDeclined: { $ne: true },
|
||||
CreatedBy: {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: currentUserId
|
||||
},
|
||||
ExpiryDate: {
|
||||
$gt: { __type: "Date", iso: new Date().toISOString() }
|
||||
}
|
||||
},
|
||||
keys: [
|
||||
"Name",
|
||||
"Note",
|
||||
"Folder.Name",
|
||||
"URL",
|
||||
"ExtUserPtr.Name",
|
||||
"Signers.Name"
|
||||
],
|
||||
orderBy: "-updatedAt",
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "View",
|
||||
btnColor: "#4bd396",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-eye",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/pdfRequestFiles"
|
||||
}
|
||||
]
|
||||
};
|
||||
// Recent signature requests report show on dashboard
|
||||
case "5Go51Q7T8r":
|
||||
return {
|
||||
reportName: "Recent signature requests",
|
||||
className: "contracts_Document",
|
||||
params: {
|
||||
Type: { $ne: "Folder" },
|
||||
IsCompleted: { $ne: true },
|
||||
IsDeclined: { $ne: true },
|
||||
ExpiryDate: {
|
||||
$gt: { __type: "Date", iso: new Date().toISOString() }
|
||||
},
|
||||
Placeholders: { $ne: null }
|
||||
},
|
||||
keys: [
|
||||
"Name",
|
||||
"Note",
|
||||
"Folder.Name",
|
||||
"URL",
|
||||
"ExtUserPtr.Name",
|
||||
"Signers.Name",
|
||||
"Signers.UserId",
|
||||
"AuditTrail"
|
||||
],
|
||||
orderBy: "-updatedAt",
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "Sign",
|
||||
btnColor: "#4bd396",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-eye",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/pdfRequestFiles"
|
||||
}
|
||||
]
|
||||
};
|
||||
// Drafts report show on dashboard
|
||||
case "kC5mfynCi4":
|
||||
return {
|
||||
reportName: "Drafts",
|
||||
className: "contracts_Document",
|
||||
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"
|
||||
],
|
||||
orderBy: "-updatedAt",
|
||||
actions: [
|
||||
{
|
||||
btnLabel: "sign",
|
||||
btnColor: "#4bd396",
|
||||
textColor: "white",
|
||||
btnIcon: "fa fa-plus",
|
||||
redirectUrl:
|
||||
"remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/draftDocument"
|
||||
}
|
||||
]
|
||||
};
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
[
|
||||
{
|
||||
"planName": "SELF HOSTED",
|
||||
"currency": "",
|
||||
"price": "Free",
|
||||
"subtitle": "Free for life One click install.",
|
||||
"btnText": "Visit github",
|
||||
"url": "https://github.com/opensignlabs/opensign",
|
||||
"benefits": [
|
||||
"Sign Unlimited Documents",
|
||||
"S3 Doc Storage",
|
||||
"Unlimited Guest Signers",
|
||||
"Unlimited completion certificates",
|
||||
"Unique Code(OTP) verification for guest signers",
|
||||
"Expiring docs & reject signature support",
|
||||
"PDF Template Creation(coming soon)",
|
||||
"Audit Trails",
|
||||
"API support",
|
||||
"Add-ons support(coming soon)",
|
||||
"Self hosted cloud infrastructure",
|
||||
"Free for lifetime",
|
||||
"Community support"
|
||||
]
|
||||
},
|
||||
{
|
||||
"planName": "THANKS PLAN",
|
||||
"currency": "$",
|
||||
"price": "29.99",
|
||||
"subtitle": "Use code 'FREEBETA' to get this for free(First 100 users)",
|
||||
"btnText": "Subscribe",
|
||||
"url": "https://subscriptions.zoho.in/subscribe/ef798486e6a0a11ea65f2bae8f2af901dbadf3175d495584fd25b9af5d2f2b9e/thanks",
|
||||
"benefits": [
|
||||
"Sign Unlimited Documents",
|
||||
"Unlimited Secure Doc Storage with OpenSignDrive",
|
||||
"Unlimited Guest Signers",
|
||||
"Unlimited completion certificates",
|
||||
"Unique Code(OTP) verification for guest signers",
|
||||
"Expiring docs & reject signature support",
|
||||
"PDF Template Creation(coming soon)",
|
||||
"Audit Trails",
|
||||
"API support",
|
||||
"Add-ons support(coming soon)",
|
||||
"Self hosted cloud infrastructure"
|
||||
]
|
||||
},
|
||||
{
|
||||
"planName": "ENTERPRISE",
|
||||
"currency": "",
|
||||
"price": "Request Price",
|
||||
"subtitle": "Customization available Priority support.",
|
||||
"btnText": "Contact us",
|
||||
"url": "https://www.opensignlabs.com/contact-us",
|
||||
"benefits": [
|
||||
"All features",
|
||||
"Custom domain",
|
||||
"Whitelabeling",
|
||||
"Uptime SLA",
|
||||
"SSO support",
|
||||
"24/7 support"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,197 +0,0 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Header from "../components/Header";
|
||||
import Footer from "../components/Footer";
|
||||
import Sidebar from "../components/sidebar/Sidebar";
|
||||
import { useWindowSize } from "../hook/useWindowSize";
|
||||
import Tour from "reactour";
|
||||
import axios from "axios";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
const HomeLayout = ({ children }) => {
|
||||
const { width } = useWindowSize();
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const arr = useSelector((state) => state.TourSteps);
|
||||
|
||||
// reactour state
|
||||
const [isCloseBtn, setIsCloseBtn] = useState(true);
|
||||
const [isTour, setIsTour] = useState(false);
|
||||
const [tourStatusArr, setTourStatusArr] = useState([]);
|
||||
const [tourConfigs, setTourConfigs] = useState([]);
|
||||
|
||||
const showSidebar = () => {
|
||||
setIsOpen(!isOpen);
|
||||
};
|
||||
useEffect(() => {
|
||||
if (width && width <= 768) {
|
||||
setIsOpen(false);
|
||||
} else {
|
||||
setIsOpen(true);
|
||||
}
|
||||
}, [width]);
|
||||
|
||||
useEffect(() => {
|
||||
if (localStorage.getItem("domain") === "sign" && arr && arr.length > 0) {
|
||||
handleDynamicSteps();
|
||||
} else if (
|
||||
localStorage.getItem("domain") === "contracts" &&
|
||||
arr &&
|
||||
arr.length > 0
|
||||
) {
|
||||
handleDynamicSteps();
|
||||
} else {
|
||||
setIsTour(false);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [arr]);
|
||||
|
||||
const handleDynamicSteps = () => {
|
||||
if (arr && arr.length > 0) {
|
||||
// const resArr = arr;
|
||||
const resArr = arr.map((obj, index) => {
|
||||
if (arr.length - 1 === index) {
|
||||
return {
|
||||
...obj
|
||||
// actions: () => {
|
||||
// setIsCloseBtn(true);
|
||||
// },
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
...obj,
|
||||
actions: () => {
|
||||
setIsCloseBtn(false);
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
setTourConfigs([
|
||||
{
|
||||
selector: '[data-tut="reactourFirst"]',
|
||||
content: `You have logged in successfully! Let's take a look.`,
|
||||
position: "top"
|
||||
// style: { backgroundColor: "#abd4d2" },
|
||||
},
|
||||
...resArr,
|
||||
{
|
||||
selector: '[data-tut="reactourLast"]',
|
||||
content: `You are good to go`,
|
||||
position: "top"
|
||||
// style: { backgroundColor: "#abd4d2" },
|
||||
}
|
||||
]);
|
||||
checkTourStatus();
|
||||
// console.log("resArr ", resArr);
|
||||
}
|
||||
};
|
||||
const closeTour = async () => {
|
||||
// console.log("closeTour");
|
||||
setIsTour(false);
|
||||
const serverUrl = localStorage.getItem("baseUrl");
|
||||
const appId = localStorage.getItem("AppID12");
|
||||
const extUserClass = localStorage.getItem("extended_class");
|
||||
const json = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||
const extUserId = json && json.length > 0 && json[0].objectId;
|
||||
// console.log("extUserId ", extUserId)
|
||||
|
||||
let updatedTourStatus = [];
|
||||
if (tourStatusArr.length > 0) {
|
||||
updatedTourStatus = [...tourStatusArr];
|
||||
const loginTourIndex = tourStatusArr.findIndex(
|
||||
(obj) => obj["loginTour"] === false || obj["loginTour"] === true
|
||||
);
|
||||
if (loginTourIndex !== -1) {
|
||||
updatedTourStatus[loginTourIndex] = { loginTour: true };
|
||||
} else {
|
||||
updatedTourStatus.push({ loginTour: true });
|
||||
}
|
||||
} else {
|
||||
updatedTourStatus = [{ loginTour: true }];
|
||||
}
|
||||
|
||||
// console.log("updatedTourStatus ", updatedTourStatus);
|
||||
await axios.put(
|
||||
serverUrl + "classes/" + extUserClass + "/" + extUserId,
|
||||
{
|
||||
TourStatus: updatedTourStatus
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
"X-Parse-Application-Id": appId
|
||||
}
|
||||
}
|
||||
);
|
||||
// console.log("updatedRes ", updatedRes);
|
||||
};
|
||||
|
||||
async function checkTourStatus() {
|
||||
const serverUrl = localStorage.getItem("baseUrl");
|
||||
const appId = localStorage.getItem("AppID12");
|
||||
const extUserClass = localStorage.getItem("extended_class");
|
||||
const json = JSON.parse(localStorage.getItem("Extand_Class"));
|
||||
const extUserId = json && json.length > 0 && json[0].objectId;
|
||||
// console.log("extUserId ", extUserId);
|
||||
const res = await axios.get(
|
||||
serverUrl + "classes/" + extUserClass + "/" + extUserId,
|
||||
{
|
||||
headers: {
|
||||
"X-Parse-Application-Id": appId
|
||||
}
|
||||
}
|
||||
);
|
||||
if (res.data && res.data.TourStatus && res.data.TourStatus.length > 0) {
|
||||
const tourStatus = res.data.TourStatus;
|
||||
// console.log("res ", res.data.TourStatus);
|
||||
setTourStatusArr(tourStatus);
|
||||
const filteredtourStatus = tourStatus.filter((obj) => obj["loginTour"]);
|
||||
if (filteredtourStatus.length > 0) {
|
||||
const loginTour = filteredtourStatus[0]["loginTour"];
|
||||
// console.log("loginTour", loginTour);
|
||||
if (loginTour) {
|
||||
setIsTour(false);
|
||||
} else {
|
||||
setIsTour(true);
|
||||
}
|
||||
} else {
|
||||
setIsTour(true);
|
||||
}
|
||||
} else {
|
||||
setIsTour(true);
|
||||
}
|
||||
}
|
||||
|
||||
const closeSidebar = () => {
|
||||
if (width <= 768) {
|
||||
setIsOpen(false);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<div className="sticky top-0 z-50">
|
||||
<Header showSidebar={showSidebar} />
|
||||
</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="bg-[#eef1f5] p-3">{children}</div>
|
||||
<div className="z-30">
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Tour
|
||||
onRequestClose={closeTour}
|
||||
steps={tourConfigs}
|
||||
isOpen={isTour}
|
||||
closeWithMask={false}
|
||||
disableKeyboardNavigation={["esc"]}
|
||||
// disableInteraction={true}
|
||||
scrollOffset={-100}
|
||||
rounded={5}
|
||||
showCloseButton={isCloseBtn}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default HomeLayout;
|
||||
@@ -1,58 +0,0 @@
|
||||
import React from "react";
|
||||
import stamp from "./stamp2.png";
|
||||
import sign from "./sign3.png";
|
||||
import { themeColor } from "./IconColor.js";
|
||||
|
||||
function DragElement({ id }) {
|
||||
const selectedId = id;
|
||||
|
||||
return (
|
||||
<div>
|
||||
{selectedId === 3 ? (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
userSelect: "none"
|
||||
}}
|
||||
>
|
||||
<img
|
||||
alt="sign img"
|
||||
style={{
|
||||
width: "25px",
|
||||
height: "23px",
|
||||
background: themeColor()
|
||||
}}
|
||||
src={sign}
|
||||
/>
|
||||
<span style={{ color: themeColor(), fontSize: "12px" }}>
|
||||
Signature
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
userSelect: "none"
|
||||
}}
|
||||
>
|
||||
<img
|
||||
alt="stamp img"
|
||||
style={{
|
||||
width: "25px",
|
||||
height: "23px",
|
||||
background: themeColor()
|
||||
}}
|
||||
src={stamp}
|
||||
/>
|
||||
<span style={{ color: themeColor(), fontSize: "12px" }}>Stamp</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default DragElement;
|
||||
@@ -1,3 +0,0 @@
|
||||
export const themeColor = () => {
|
||||
return "#47a3ad";
|
||||
};
|
||||
|
Before Width: | Height: | Size: 804 B |
|
Before Width: | Height: | Size: 561 B |
@@ -1,206 +0,0 @@
|
||||
import React, { useState, useEffect, useMemo } from "react";
|
||||
import pad from "../assets/images/pad.svg";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
const ReportTable = ({
|
||||
ReportName,
|
||||
List,
|
||||
actions,
|
||||
setIsNextRecord,
|
||||
isMoreDocs
|
||||
}) => {
|
||||
const navigate = useNavigate();
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const docPerPage = 10;
|
||||
// const pageNumbers = [];
|
||||
|
||||
// For loop is used to calculate page numbers visible below table
|
||||
// Initialize pageNumbers using useMemo to avoid unnecessary re-creation
|
||||
const pageNumbers = useMemo(() => {
|
||||
const calculatedPageNumbers = [];
|
||||
for (let i = 1; i <= Math.ceil(List.length / docPerPage); i++) {
|
||||
calculatedPageNumbers.push(i);
|
||||
}
|
||||
return calculatedPageNumbers;
|
||||
}, [List]);
|
||||
// below useEffect reset currenpage to 1 if user change route
|
||||
useEffect(() => {
|
||||
return () => setCurrentPage(1);
|
||||
}, []);
|
||||
|
||||
// `formatRow` is used to show data in poper manner like
|
||||
// if data is of array type then it will join array items with ","
|
||||
// if data is of object type then it Name values will be show in row
|
||||
// if no data available it will show hyphen "-"
|
||||
const formatRow = (row) => {
|
||||
if (Array.isArray(row)) {
|
||||
let updateArr = row.map((x) => x.Name);
|
||||
return updateArr.join(", ");
|
||||
} else if (typeof row === "object" && row !== null) {
|
||||
return row?.Name || "-";
|
||||
} else {
|
||||
return "-";
|
||||
}
|
||||
};
|
||||
// below useEffect is used to render next record if IsMoreDoc is true
|
||||
// second last value of pageNumber array is same as currentPage
|
||||
useEffect(() => {
|
||||
if (isMoreDocs && pageNumbers[pageNumbers.length - 1] === currentPage) {
|
||||
setIsNextRecord(true);
|
||||
}
|
||||
}, [isMoreDocs, pageNumbers, currentPage, setIsNextRecord]);
|
||||
|
||||
// `handlemicroapp` is used to open microapp
|
||||
const handlemicroapp = (item, url) => {
|
||||
localStorage.removeItem("rowlevel");
|
||||
navigate("/rpmf/" + url);
|
||||
localStorage.setItem("rowlevel", JSON.stringify(item));
|
||||
// localStorage.setItem("rowlevelMicro");
|
||||
};
|
||||
const handlebtn = () => {
|
||||
console.log("clicked");
|
||||
};
|
||||
|
||||
// Get current list
|
||||
const indexOfLastDoc = currentPage * docPerPage;
|
||||
const indexOfFirstDoc = indexOfLastDoc - docPerPage;
|
||||
// `currentLists` is total record render on current page
|
||||
const currentLists = List.slice(indexOfFirstDoc, indexOfLastDoc);
|
||||
|
||||
// Change page
|
||||
const paginateFront = () => setCurrentPage(currentPage + 1);
|
||||
const paginateBack = () => setCurrentPage(currentPage - 1);
|
||||
|
||||
return (
|
||||
<div className="p-2 overflow-x-scroll w-full bg-white rounded-md">
|
||||
<h2 className="text-[23px] font-light my-2">{ReportName}</h2>
|
||||
<table className="table-auto w-full border-collapse">
|
||||
<thead className="text-[14px]">
|
||||
<tr className="border-y-[1px]">
|
||||
<th className="px-4 py-2 font-thin">Sr.No</th>
|
||||
<th className="px-4 py-2 font-thin">Name</th>
|
||||
<th className="px-4 py-2 font-thin">Note</th>
|
||||
<th className="px-4 py-2 font-thin">Folder</th>
|
||||
<th className="px-4 py-2 font-thin">File</th>
|
||||
<th className="px-4 py-2 font-thin">Owner</th>
|
||||
<th className="px-4 py-2 font-thin">Signers</th>
|
||||
{actions?.length > 0 && (
|
||||
<th className="px-4 py-2 font-thin">Action</th>
|
||||
)}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="text-[12px]">
|
||||
{List?.length > 0 ? (
|
||||
<>
|
||||
{currentLists.map((item, index) => (
|
||||
<tr className="border-y-[1px]" key={index}>
|
||||
<td className="px-4 py-2">{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">
|
||||
{item?.Folder?.Name || "OpenSignDrive"}
|
||||
</td>
|
||||
<td className="px-4 py-2">
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
title={item?.URL}
|
||||
href={item?.URL}
|
||||
download={item?.URL}
|
||||
className="text-[blue] hover:text-[blue] hover:underline"
|
||||
>
|
||||
{item?.URL ? "Download" : "-"}
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td className="px-4 py-2">{formatRow(item?.ExtUserPtr)}</td>
|
||||
<td className="px-4 py-2">
|
||||
{item?.Signers ? formatRow(item?.Signers) : "-"}
|
||||
</td>
|
||||
<td className="px-4 py-2 flex flex-col justify-center items-center gap-2 text-white">
|
||||
{actions?.length > 0 &&
|
||||
actions.map((act, index) => (
|
||||
<button
|
||||
key={index}
|
||||
onClick={() =>
|
||||
act?.redirectUrl
|
||||
? handlemicroapp(item, act.redirectUrl)
|
||||
: handlebtn(item)
|
||||
}
|
||||
className={`flex justify-center items-center w-full gap-1 px-2 py-1 rounded shadow`}
|
||||
style={{
|
||||
backgroundColor: act.btnColor
|
||||
? act.btnColor
|
||||
: "#3ac9d6",
|
||||
color: act?.textColor ? act?.textColor : "white"
|
||||
}}
|
||||
>
|
||||
<span>
|
||||
{act?.btnIcon && <i className={act.btnIcon}></i>}
|
||||
</span>
|
||||
<span className="uppercase">
|
||||
{act?.btnLabel ? act.btnLabel : "view"}
|
||||
</span>
|
||||
</button>
|
||||
// )
|
||||
))}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
<div className="flex flex-wrap items-center gap-2 p-2 ">
|
||||
{List.length > 10 && (
|
||||
<>
|
||||
{currentPage > 1 && (
|
||||
<button
|
||||
onClick={() => paginateBack()}
|
||||
className="bg-blue-400 text-white rounded px-3 py-2 focus:outline-none"
|
||||
>
|
||||
Prev
|
||||
</button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{pageNumbers.map((x) => (
|
||||
<button
|
||||
key={x}
|
||||
onClick={() => setCurrentPage(x)}
|
||||
className=" bg-sky-400 text-white rounded px-3 py-2 focus:outline-none"
|
||||
>
|
||||
{x}
|
||||
</button>
|
||||
))}
|
||||
{isMoreDocs && (
|
||||
<button className="text-black rounded px-1 py-2">...</button>
|
||||
)}
|
||||
{List.length > 10 && (
|
||||
<>
|
||||
{pageNumbers.includes(currentPage + 1) && (
|
||||
<button
|
||||
onClick={() => paginateFront()}
|
||||
className="bg-blue-400 text-white rounded px-3 py-2 focus:outline-none"
|
||||
>
|
||||
Next
|
||||
</button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
{List?.length <= 0 && (
|
||||
<div className="flex flex-col items-center justify-center w-full bg-white rounded py-4">
|
||||
<div className="w-[60px] h-[60px] overflow-hidden">
|
||||
<img className="w-full h-full object-contain" src={pad} alt="img" />
|
||||
</div>
|
||||
<div className="text-sm font-semibold">No Data Available</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ReportTable;
|
||||
@@ -1,5 +0,0 @@
|
||||
function sanitizeFileName(fileName) {
|
||||
// Remove spaces and invalid characters
|
||||
return fileName.replace(/[^a-zA-Z0-9._-]/g, "");
|
||||
}
|
||||
export default sanitizeFileName;
|
||||
@@ -1,317 +0,0 @@
|
||||
import Parse from "parse";
|
||||
import axios from "axios";
|
||||
import { appInfo } from "../../constant/appinfo";
|
||||
|
||||
//For fetching application Information
|
||||
export const fetchAppInfo = (str, burl, app_id) => async (dispatch) => {
|
||||
Parse.serverURL = burl;
|
||||
Parse.initialize(app_id);
|
||||
|
||||
const response = appInfo;
|
||||
let _base = ""; // Define _base here and initialize it to an empty string
|
||||
if (response && response.baseurl) {
|
||||
_base = response.baseurl.charAt(response.baseurl.length - 1);
|
||||
} localStorage.removeItem("baseUrl");
|
||||
localStorage.setItem("_appName", response.appname);
|
||||
localStorage.setItem("_app_objectId", response.objectId);
|
||||
if (_base === "/") {
|
||||
localStorage.setItem("baseUrl", response.baseurl);
|
||||
} else {
|
||||
localStorage.setItem("baseUrl", `${response.baseurl}/`);
|
||||
}
|
||||
localStorage.setItem("appLogo", response.applogo);
|
||||
localStorage.setItem("appVersion", response.version);
|
||||
if (response.enableWebNotification) {
|
||||
localStorage.setItem(
|
||||
"enableWebNotification",
|
||||
response.enableWebNotification
|
||||
);
|
||||
}
|
||||
localStorage.setItem("parseAppId", app_id);
|
||||
localStorage.removeItem("userSettings");
|
||||
localStorage.setItem("userSettings", JSON.stringify(response.settings));
|
||||
localStorage.setItem("appTitle", response.appTitle);
|
||||
localStorage.setItem("fev_Icon", response.fev_Icon);
|
||||
// console.log("response ", response);
|
||||
dispatch({ type: "FATCH_APPINFO", payload: response });
|
||||
};
|
||||
|
||||
//for simple login
|
||||
export const login = (username, password) => async (dispatch) => {
|
||||
let res = {};
|
||||
let baseUrl = localStorage.getItem("baseUrl");
|
||||
let parseAppId = localStorage.getItem("parseAppId");
|
||||
try {
|
||||
Parse.serverURL = baseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
await Parse.User.logIn(username, password).then(
|
||||
async function (res1) {
|
||||
var resultjson = res1.toJSON();
|
||||
res = res1.toJSON();
|
||||
localStorage.setItem("userEmail", username);
|
||||
localStorage.setItem("username", resultjson.name);
|
||||
localStorage.setItem("accesstoken", resultjson.sessionToken);
|
||||
localStorage.setItem("scriptId", true);
|
||||
if (resultjson.ProfilePic) {
|
||||
localStorage.setItem("profileImg", resultjson.ProfilePic);
|
||||
} else {
|
||||
localStorage.setItem("profileImg", "");
|
||||
}
|
||||
let url = `${baseUrl}functions/UserGroups`;
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": parseAppId,
|
||||
sessionToken: resultjson.sessionToken
|
||||
};
|
||||
|
||||
let body = {
|
||||
appname: localStorage.getItem("domain")
|
||||
};
|
||||
let userGroup = "",
|
||||
userGroup1 = "";
|
||||
await axios
|
||||
.post(url, JSON.stringify(body), { headers: headers })
|
||||
.then(async (response) => {
|
||||
userGroup = response.data.result[0];
|
||||
userGroup1 = response.data.result[1];
|
||||
localStorage.setItem("_userGroup", userGroup);
|
||||
});
|
||||
|
||||
let appSetings = JSON.parse(localStorage.getItem("userSettings"));
|
||||
let defaultmenuid = "",
|
||||
PageLanding = "",
|
||||
pageType = "";
|
||||
|
||||
appSetings.forEach(async (element) => {
|
||||
if (`${localStorage.getItem("_appName")}_appeditor` === userGroup) {
|
||||
if (element.role === userGroup1) {
|
||||
defaultmenuid = element.menuId;
|
||||
PageLanding = element.pageId;
|
||||
pageType = element.pageType;
|
||||
localStorage.setItem("PageLanding", PageLanding);
|
||||
localStorage.setItem("defaultmenuid", defaultmenuid);
|
||||
localStorage.setItem("pageType", pageType);
|
||||
let _role = userGroup1.replace(
|
||||
`${localStorage.getItem("_appName")}_`,
|
||||
""
|
||||
);
|
||||
if (userGroup1) {
|
||||
localStorage.setItem("_user_role", _role);
|
||||
} else {
|
||||
localStorage.setItem("_user_role", _role);
|
||||
}
|
||||
}
|
||||
} else if (element.role === userGroup) {
|
||||
defaultmenuid = element.menuId;
|
||||
PageLanding = element.pageId;
|
||||
pageType = element.pageType;
|
||||
localStorage.setItem("PageLanding", PageLanding);
|
||||
localStorage.setItem("defaultmenuid", defaultmenuid);
|
||||
localStorage.setItem("pageType", pageType);
|
||||
localStorage.setItem("extended_class", element.extended_class);
|
||||
localStorage.setItem("userpointer", element.userpointer);
|
||||
let _role = userGroup.replace(
|
||||
`${localStorage.getItem("domain")}_`,
|
||||
""
|
||||
);
|
||||
if (userGroup) {
|
||||
localStorage.setItem("_user_role", _role);
|
||||
} else {
|
||||
localStorage.setItem("_user_role", _role);
|
||||
}
|
||||
try {
|
||||
const tour = Parse.Object.extend(
|
||||
localStorage.getItem("extended_class")
|
||||
);
|
||||
let _tour = new Parse.Query(tour);
|
||||
_tour.equalTo("UserId", {
|
||||
__type: "Pointer",
|
||||
className: "_User",
|
||||
objectId: resultjson.objectId
|
||||
});
|
||||
await _tour.first().then(
|
||||
(results) => {
|
||||
let userinfo = results.toJSON();
|
||||
if (userinfo.TenantId) {
|
||||
localStorage.setItem("TenetId", userinfo.TenantId.objectId);
|
||||
}
|
||||
// console.log("tour found", results);
|
||||
},
|
||||
(error) => {
|
||||
console.error("Error while fetching tour", error);
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
console.log("err ", error)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
dispatch({ type: "APP_LOGIN", payload: res });
|
||||
|
||||
if (pageType !== "") {
|
||||
window.location = `/${pageType}/${PageLanding}`;
|
||||
} else {
|
||||
alert("You dont have access to this application.");
|
||||
localStorage.setItem("accesstoken", null);
|
||||
}
|
||||
},
|
||||
function () {
|
||||
alert("Invalid Login");
|
||||
localStorage.setItem("accesstoken", null);
|
||||
}
|
||||
);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
alert("You dont have access to this application.");
|
||||
localStorage.setItem("accesstoken", null);
|
||||
}
|
||||
};
|
||||
|
||||
//for reset password
|
||||
export const forgetPassword = (username) => async () => {
|
||||
// let res = {};
|
||||
let baseUrl = localStorage.getItem("BaseUrl12");
|
||||
let parseAppId = localStorage.getItem("AppID12");
|
||||
try {
|
||||
Parse.serverURL = baseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
await Parse.User.requestPasswordReset(username).then(
|
||||
async function (res1) {
|
||||
// var resultjson = res1;
|
||||
// console.log("post data", resultjson.length);
|
||||
if (res1.data === undefined) {
|
||||
alert("Reset password link has been sent to your email id ");
|
||||
}
|
||||
},
|
||||
function () {
|
||||
// alert("Password Reset Done")
|
||||
}
|
||||
);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
};
|
||||
|
||||
// Role field wizard
|
||||
export const fetchRoleEnum = (name) => async (dispatch) => {
|
||||
let response = [];
|
||||
let baseUrl = localStorage.getItem("baseUrl");
|
||||
let parseAppId = localStorage.getItem("parseAppId");
|
||||
try {
|
||||
let url = `${baseUrl}roles?where={"name":{"$regex":"${name}","$ne":"${localStorage.getItem(
|
||||
"domain"
|
||||
)}_appeditor"}}`;
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": parseAppId
|
||||
};
|
||||
await axios.get(url, { headers: headers }).then((res) => {
|
||||
let temp = [];
|
||||
res.data.results.forEach((x) => {
|
||||
temp.push(x["name"]);
|
||||
});
|
||||
response = temp;
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("Problem", e);
|
||||
}
|
||||
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) => {
|
||||
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) => {
|
||||
dispatch({ type: "SAVE_TOURSTEPS", payload: steps });
|
||||
};
|
||||
|
||||
export const remove_tourSteps = () => async (dispatch) => {
|
||||
dispatch({ type: "REMOVE_TOURSTEPS", payload: [] });
|
||||
};
|
||||
@@ -1,9 +0,0 @@
|
||||
const ShowTenant = (state = "", action) => {
|
||||
switch (action.type) {
|
||||
case "SHOW_TENANT":
|
||||
return action.payload;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
export default ShowTenant;
|
||||
@@ -1,11 +0,0 @@
|
||||
const tourStepReducer = (state = "", action) => {
|
||||
switch (action.type) {
|
||||
case "SAVE_TOURSTEPS":
|
||||
return action.payload;
|
||||
case "REMOVE_TOURSTEPS":
|
||||
return [];
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
export default tourStepReducer;
|
||||
@@ -1,12 +0,0 @@
|
||||
import { combineReducers } from "redux";
|
||||
import infoReducer from "./infoReducer";
|
||||
import loginReducer from "./loginReducer";
|
||||
import ShowTenant from "./ShowTenant";
|
||||
import TourStepsReducer from "./TourStepsReducer";
|
||||
|
||||
export default combineReducers({
|
||||
appInfo: infoReducer,
|
||||
login: loginReducer,
|
||||
ShowTenant,
|
||||
TourSteps: TourStepsReducer
|
||||
});
|
||||
@@ -1,9 +0,0 @@
|
||||
const infoReducer = (state = {}, action) => {
|
||||
switch (action.type) {
|
||||
case "FATCH_APPINFO":
|
||||
return action.payload;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
export default infoReducer;
|
||||
@@ -1,9 +0,0 @@
|
||||
const loginReducer = (state = {}, action) => {
|
||||
switch (action.type) {
|
||||
case "APP_LOGIN":
|
||||
return action.payload;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
export default loginReducer;
|
||||
@@ -1,5 +0,0 @@
|
||||
import { createStore, applyMiddleware } from "redux";
|
||||
import thunk from "redux-thunk";
|
||||
import reducers from "./reducers";
|
||||
|
||||
export const store = createStore(reducers, applyMiddleware(thunk));
|
||||
@@ -1,115 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import Parse from "parse";
|
||||
import { Navigate } from "react-router-dom";
|
||||
import Title from "../components/Title";
|
||||
|
||||
function ChangePassword() {
|
||||
const [currentpassword, setCurrentPassword] = useState("");
|
||||
const [newpassword, setnewpassword] = useState("");
|
||||
const [confirmpassword, setconfirmpassword] = useState("");
|
||||
const handleSubmit = async (evt) => {
|
||||
evt.preventDefault();
|
||||
try {
|
||||
if (newpassword === confirmpassword) {
|
||||
Parse.serverURL = localStorage.getItem("baseUrl");
|
||||
Parse.initialize(localStorage.getItem("parseAppId"));
|
||||
Parse.User.logIn(localStorage.getItem("userEmail"), currentpassword)
|
||||
.then(async (user) => {
|
||||
if (user) {
|
||||
const User = new Parse.User();
|
||||
const query = new Parse.Query(User);
|
||||
await query.get(user.id).then((user) => {
|
||||
// Updates the data we want
|
||||
user.set("password", newpassword);
|
||||
user
|
||||
.save()
|
||||
.then(() => {
|
||||
alert("Password updated successfully.");
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log("err", error);
|
||||
alert("Something went wrong.");
|
||||
});
|
||||
});
|
||||
} else {
|
||||
alert("Your current password is missing or incorrect.");
|
||||
}
|
||||
console.log("Logged in user", user);
|
||||
})
|
||||
.catch((error) => {
|
||||
alert("Your current password is missing or incorrect.");
|
||||
console.error("Error while logging in user", error);
|
||||
});
|
||||
} else {
|
||||
alert("Your password and confirmation password do not match.");
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("err", error);
|
||||
}
|
||||
};
|
||||
if (localStorage.getItem("accesstoken") === null) {
|
||||
return <Navigate to="/" />;
|
||||
}
|
||||
return (
|
||||
<div className="w-full bg-white shadow rounded p-2">
|
||||
<Title title={"Change Password"} />
|
||||
<div className="text-xl font-bold border-b-[1px] border-gray-300">
|
||||
Change Password
|
||||
</div>
|
||||
<div className="m-2">
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div>
|
||||
<label htmlFor="currentpassword" className="block text-xs ml-1">
|
||||
Current Password
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
name="currentpassword"
|
||||
value={currentpassword}
|
||||
onChange={(e) => setCurrentPassword(e.target.value)}
|
||||
className="px-3 py-2 mb-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||
placeholder="Current Password"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="newpassword" className="text-xs block ml-1">
|
||||
New Password
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
name="newpassword"
|
||||
value={newpassword}
|
||||
onChange={(e) => setnewpassword(e.target.value)}
|
||||
className="px-3 py-2 mb-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||
placeholder="New Password"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="newpassword" className="text-xs block ml-1">
|
||||
Confirm Password
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
name="confirmpassword"
|
||||
className="px-3 py-2 mb-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||
value={confirmpassword}
|
||||
onChange={(e) => setconfirmpassword(e.target.value)}
|
||||
placeholder="Confirm Password"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
className="bg-[#188ae2] m-2 px-4 py-3 rounded-sm shadow-md text-white text-xs font-semibold uppercase"
|
||||
>
|
||||
Change Password
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ChangePassword;
|
||||
@@ -1,142 +0,0 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Parse from "parse";
|
||||
import "../styles/loader.css";
|
||||
import GetDashboard from "../components/dashboard/GetDashboard";
|
||||
import { Navigate, useParams } from "react-router-dom";
|
||||
import Title from "../components/Title";
|
||||
import { save_tourSteps } from "../redux/actions";
|
||||
import { connect } from "react-redux";
|
||||
const Dashboard = (props) => {
|
||||
const { id } = useParams();
|
||||
const [dashboard, setdashboard] = useState([]);
|
||||
const [classnameArray, setclassnameArray] = useState([]);
|
||||
const [loading, setloading] = useState(false);
|
||||
const [parseBaseUrl] = useState(localStorage.getItem("baseUrl"));
|
||||
const [parseAppId] = useState(localStorage.getItem("parseAppId"));
|
||||
const [defaultQuery, setDefaultQuery] = useState("");
|
||||
|
||||
const getDashboard = async (id) => {
|
||||
setloading(true);
|
||||
try {
|
||||
Parse.serverURL = parseBaseUrl;
|
||||
Parse.initialize(parseAppId);
|
||||
var forms = Parse.Object.extend("w_dashboard");
|
||||
var query = new Parse.Query(forms);
|
||||
query.equalTo("objectId", id);
|
||||
const results = await query.first();
|
||||
const resultjson = results.toJSON();
|
||||
let classArray = [];
|
||||
let DefaultQuery = "";
|
||||
resultjson.rows.forEach((x) => {
|
||||
let col_lg = "",
|
||||
col_md = "",
|
||||
col_xs = "",
|
||||
col_sm = "",
|
||||
col_ = "",
|
||||
obj = {};
|
||||
let subItem = [];
|
||||
let item = "";
|
||||
x.columns.forEach((y) => {
|
||||
if (y.widget.type === "customeHtml") {
|
||||
DefaultQuery = y.widget.data[0].default;
|
||||
}
|
||||
if (Number(y["collg"]) > 0) {
|
||||
col_lg = "col-lg-" + y["collg"];
|
||||
}
|
||||
if (Number(y["colmd"]) > 0) {
|
||||
col_md = "col-md-" + y["colmd"];
|
||||
}
|
||||
if (Number(y["colxs"]) > 0) {
|
||||
col_xs = "col-xs-" + y["colxs"];
|
||||
}
|
||||
if (Number(y["colsm"]) > 0) {
|
||||
col_sm = "col-sm-" + y["colsm"];
|
||||
}
|
||||
if (Number(y["col"]) > 0) {
|
||||
col_ = "col-" + y["col"];
|
||||
}
|
||||
item =
|
||||
col_lg + " " + col_md + " " + col_xs + " " + col_sm + " " + col_;
|
||||
subItem.push(item);
|
||||
});
|
||||
obj = subItem;
|
||||
classArray.push(obj);
|
||||
});
|
||||
setdashboard(resultjson.rows);
|
||||
// console.log("resultjson.rows ", resultjson.rows);
|
||||
const arr = resultjson.rows[0].columns
|
||||
.filter((col) => {
|
||||
if (col.widget.data && col.widget.data.tourSection) {
|
||||
return col;
|
||||
}
|
||||
})
|
||||
.map((col) => {
|
||||
return {
|
||||
selector: `[data-tut=${col.widget.data.tourSection}]`,
|
||||
content: col.widget.data.tourMessage,
|
||||
position: "top"
|
||||
// style: { backgroundColor: "#abd4d2" },
|
||||
};
|
||||
});
|
||||
props.save_tourSteps(arr);
|
||||
// console.log("arr ", arr);
|
||||
setclassnameArray(classArray);
|
||||
if (localStorage.getItem("DashboardDefaultFilter")) {
|
||||
setDefaultQuery(localStorage.getItem("DashboardDefaultFilter"));
|
||||
} else {
|
||||
setDefaultQuery(DefaultQuery);
|
||||
}
|
||||
setloading(false);
|
||||
} catch (e) {
|
||||
console.error("Problem", e);
|
||||
setloading(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (id !== undefined) {
|
||||
getDashboard(id);
|
||||
} else {
|
||||
getDashboard(localStorage.getItem("PageLanding"));
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
}, [id]);
|
||||
|
||||
if (localStorage.getItem("accesstoken") === "" || null) {
|
||||
return <Navigate to="/" />;
|
||||
}
|
||||
|
||||
let _dash = (
|
||||
<GetDashboard
|
||||
dashboard={dashboard}
|
||||
classnameArray={classnameArray}
|
||||
DefaultQuery={defaultQuery}
|
||||
/>
|
||||
);
|
||||
if (loading) {
|
||||
_dash = (
|
||||
<div style={{ height: "300px", backgroundColor: "white" }}>
|
||||
<div
|
||||
style={{
|
||||
marginLeft: "45%",
|
||||
marginTop: "150px",
|
||||
fontSize: "45px",
|
||||
color: "#3dd3e0"
|
||||
}}
|
||||
className="loader-37"
|
||||
></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Title title="Dashboard" />
|
||||
{_dash}
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default connect(null, {
|
||||
save_tourSteps
|
||||
})(Dashboard);
|
||||
@@ -1,120 +0,0 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { fetchAppInfo, forgetPassword } from "../redux/actions";
|
||||
import Title from "../components/Title";
|
||||
import { NavLink } from "react-router-dom";
|
||||
import login_img from "../assets/images/login_img.svg";
|
||||
|
||||
function ForgotPassword(props) {
|
||||
const [state, setState] = useState({
|
||||
email: "",
|
||||
password: "",
|
||||
hideNav: ""
|
||||
});
|
||||
const handleChange = (event) => {
|
||||
const { name, value } = event.target;
|
||||
setState({ ...state, [name]: value });
|
||||
};
|
||||
|
||||
const resize = () => {
|
||||
let currentHideNav = window.innerWidth <= 760;
|
||||
if (currentHideNav !== state.hideNav) {
|
||||
setState({ ...state, hideNav: currentHideNav });
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = (event) => {
|
||||
event.preventDefault();
|
||||
localStorage.setItem("appLogo", props.appInfo.applogo);
|
||||
localStorage.setItem("appName", props.appInfo.appname);
|
||||
localStorage.setItem("defaultmenuid", props.appInfo.defaultmenuid);
|
||||
localStorage.setItem("PageLanding", props.appInfo.LandingPageId);
|
||||
localStorage.setItem(
|
||||
"userSettings",
|
||||
JSON.stringify(props.appInfo.settings)
|
||||
);
|
||||
|
||||
if (state.email) {
|
||||
props.forgetPassword(state.email);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
props.fetchAppInfo(localStorage.getItem("domain"));
|
||||
resize();
|
||||
window.addEventListener("resize", resize);
|
||||
return () => window.removeEventListener("resize", resize);
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
let image = props.appInfo.applogo;
|
||||
return (
|
||||
<div className="bg-white">
|
||||
<Title title="Forgot password page" />
|
||||
<div>
|
||||
<div className="md:m-10 lg:m-16 md:p-4 lg:p-10 p-5 bg-[#ffffff] md:border-[1px] md:border-gray-400 ">
|
||||
<div className="w-[250px] h-[66px] inline-block">
|
||||
{state.hideNav ? (
|
||||
<img src={image} width="100%" alt="" />
|
||||
) : (
|
||||
<img src={image} width="100%" alt="" />
|
||||
)}
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-2">
|
||||
<div className="">
|
||||
<form onSubmit={handleSubmit}>
|
||||
<h2 className="text-[30px] mt-6">Welcome Back !</h2>
|
||||
<span className="text-[12px] text-[#878787]">
|
||||
Reset Your Password
|
||||
</span>
|
||||
<div className="shadow-md rounded my-4">
|
||||
<div className="px-6 py-4">
|
||||
<label className="block text-xs">Email</label>
|
||||
<input
|
||||
type="text"
|
||||
className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs"
|
||||
name="email"
|
||||
value={state.email}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
<hr className="my-2 border-none" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-between items-center px-4">
|
||||
<button
|
||||
type="submit"
|
||||
className="rounded-sm bg-[#3ac9d6] text-white px-4 py-3 text-xs font-semibold shadow uppercase"
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
<NavLink
|
||||
to="/"
|
||||
className="rounded-sm bg-white border-[1px] border-[#15b4e9] text-[#15b4e9] px-4 py-3 text-xs font-semibold shadow uppercase"
|
||||
>
|
||||
Login
|
||||
</NavLink>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{!state.hideNav && (
|
||||
<div className="self-center">
|
||||
<div className="mx-auto md:w-[300px] lg:w-[500px]">
|
||||
<img src={login_img} alt="bisec" width="100%" />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
return { appInfo: state.appInfo, forgotPassword: state.forgotPassword };
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, { fetchAppInfo, forgetPassword })(
|
||||
ForgotPassword
|
||||
);
|
||||
@@ -1,84 +0,0 @@
|
||||
import { Suspense } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import useFederatedComponent from "mf-cra";
|
||||
import React from "react";
|
||||
import Title from "../components/Title";
|
||||
function RemoteApp({ app }) {
|
||||
// console.log("app ", app);
|
||||
const { Component: RemoteComponent } = useFederatedComponent(app);
|
||||
// console.log("RemoteComponent ", RemoteComponent);
|
||||
return (
|
||||
<>
|
||||
<Title title={app.remoteName} />
|
||||
<Suspense
|
||||
fallback={
|
||||
<div style={{ height: "300px" }}>
|
||||
<div
|
||||
style={{
|
||||
marginLeft: "45%",
|
||||
marginTop: "150px",
|
||||
fontSize: "45px",
|
||||
color: "#3dd3e0"
|
||||
}}
|
||||
className="loader-37"
|
||||
></div>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
boxShadow: "0 1px 3px 0 rgba(0, 0, 0, 0.33)",
|
||||
backgroundColor: "#ffffff",
|
||||
width: "100%",
|
||||
overflow: "hidden",
|
||||
borderRadius: 3,
|
||||
minHeight: "70vh"
|
||||
}}
|
||||
>
|
||||
{RemoteComponent && <RemoteComponent />}
|
||||
</div>
|
||||
</Suspense>
|
||||
</>
|
||||
);
|
||||
}
|
||||
function checkObjectProperties(obj) {
|
||||
// Check if all three properties exist in the object
|
||||
if (
|
||||
obj &&
|
||||
obj.remoteName !== undefined &&
|
||||
obj.remoteUrl !== undefined &&
|
||||
obj.moduleToLoad !== undefined
|
||||
) {
|
||||
return true; // All properties are present
|
||||
} else {
|
||||
return false; // At least one property is missing
|
||||
}
|
||||
}
|
||||
export default function RemoteAppContainer() {
|
||||
const { remoteApp } = useParams();
|
||||
|
||||
const obj = {
|
||||
remoteUrl: window.location.origin + "/mfbuild/remoteEntry.js",
|
||||
moduleToLoad: "./AppRoutes",
|
||||
remoteName: remoteApp
|
||||
};
|
||||
// console.log("obj ", obj);
|
||||
const isMf = checkObjectProperties(obj);
|
||||
if (isMf) {
|
||||
const appToLoad = obj;
|
||||
return <RemoteApp app={appToLoad} />;
|
||||
} else {
|
||||
return (
|
||||
<div className="flex items-center justify-center h-screen w-full bg-white rounded">
|
||||
<div className="text-center">
|
||||
<h1 className="text-[60px] lg:text-[120px] font-semibold text-black">
|
||||
404
|
||||
</h1>
|
||||
<p className="text-[30px] lg:text-[50px] text-black">
|
||||
Page Not Found
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||