tango-app-api-client 3.3.3-beta.1 → 3.3.3-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +42 -43
- package/src/controllers/client.controllers.js +171 -37
- package/src/dtos/client.dtos.js +3 -0
- package/src/hbs/approved-client.hbs +170 -170
- package/src/service/client.service.js +3 -0
package/package.json
CHANGED
|
@@ -1,43 +1,42 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "tango-app-api-client",
|
|
3
|
-
"version": "3.3.3-beta.
|
|
4
|
-
"description": "client",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"scripts": {
|
|
8
|
-
"start": "nodemon --exec \"eslint --fix . && node index.js\""
|
|
9
|
-
},
|
|
10
|
-
"engines": {
|
|
11
|
-
"node": ">=18.10.0"
|
|
12
|
-
},
|
|
13
|
-
"author": "praveenraj",
|
|
14
|
-
"license": "ISC",
|
|
15
|
-
"dependencies": {
|
|
16
|
-
"aws-sdk": "^2.1560.0",
|
|
17
|
-
"cors": "^2.8.5",
|
|
18
|
-
"dotenv": "^16.4.4",
|
|
19
|
-
"express": "^4.18.2",
|
|
20
|
-
"express-fileupload": "^1.4.3",
|
|
21
|
-
"handlebars": "^4.7.8",
|
|
22
|
-
"
|
|
23
|
-
"joi": "^
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"tango-api-
|
|
31
|
-
"
|
|
32
|
-
"winston": "^
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"eslint": "^
|
|
37
|
-
"eslint-config-
|
|
38
|
-
"eslint-config-
|
|
39
|
-
"eslint-
|
|
40
|
-
"eslint-plugin-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "tango-app-api-client",
|
|
3
|
+
"version": "3.3.3-beta.11",
|
|
4
|
+
"description": "client",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"start": "nodemon --exec \"eslint --fix . && node index.js\""
|
|
9
|
+
},
|
|
10
|
+
"engines": {
|
|
11
|
+
"node": ">=18.10.0"
|
|
12
|
+
},
|
|
13
|
+
"author": "praveenraj",
|
|
14
|
+
"license": "ISC",
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"aws-sdk": "^2.1560.0",
|
|
17
|
+
"cors": "^2.8.5",
|
|
18
|
+
"dotenv": "^16.4.4",
|
|
19
|
+
"express": "^4.18.2",
|
|
20
|
+
"express-fileupload": "^1.4.3",
|
|
21
|
+
"handlebars": "^4.7.8",
|
|
22
|
+
"joi": "^17.12.1",
|
|
23
|
+
"joi-to-swagger": "^6.2.0",
|
|
24
|
+
"lodash": "^4.17.21",
|
|
25
|
+
"mongodb": "^6.7.0",
|
|
26
|
+
"nodemon": "^3.0.3",
|
|
27
|
+
"npm": "^10.9.1",
|
|
28
|
+
"swagger-ui-express": "^5.0.0",
|
|
29
|
+
"tango-api-schema": "^2.2.59",
|
|
30
|
+
"tango-app-api-middleware": "^3.1.60",
|
|
31
|
+
"winston": "^3.11.0",
|
|
32
|
+
"winston-daily-rotate-file": "^5.0.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"eslint": "^8.56.0",
|
|
36
|
+
"eslint-config-google": "^0.14.0",
|
|
37
|
+
"eslint-config-semistandard": "^17.0.0",
|
|
38
|
+
"eslint-config-standard": "^17.1.0",
|
|
39
|
+
"eslint-plugin-import": "^2.29.1",
|
|
40
|
+
"eslint-plugin-promise": "^6.1.1"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { billingDetailsUpdate, brandInfoUpdate, domainDetailsConfigurationUpdate, featureConfigurationUpdate, getClientData, signatoryDetailsUpdate, ticketConfigurationUpdate, documentsUpdate, getUserData, CsmUsersGet, OpsUsersGet, userConfigurationUpdate, findClient, aggregateClient, createAuditQueue, findOne, insert, update, findOneClient, updateOneClient } from '../service/client.service.js';
|
|
2
|
-
import { checkFileExist, fileUpload, signedUrl, chunkArray, download, logger, getOpenSearchData, insertOpenSearchData, sendEmailWithSES, createCustomer, createVirtualAccount } from 'tango-app-api-middleware';
|
|
2
|
+
import { checkFileExist, fileUpload, signedUrl, chunkArray, download, logger, getOpenSearchData, insertOpenSearchData, sendEmailWithSES, createCustomer, createVirtualAccount, getUuid } from 'tango-app-api-middleware';
|
|
3
3
|
import { countDocumentsUser, findOneAndUpdateUser, findOneUser, getUserNameEmailById, updateManyUser } from '../service/user.service.js';
|
|
4
4
|
import { aggregateStore, countDocumentsStore, findStore, updateManyStore } from '../service/store.service.js';
|
|
5
5
|
import { aggregateCamera, countDocumentsCamera } from '../service/camera.service.js';
|
|
@@ -37,7 +37,6 @@ export async function create( req, res ) {
|
|
|
37
37
|
];
|
|
38
38
|
const ID = await aggregateClient( countQuery );
|
|
39
39
|
const count = ID[0]?.tangoId || 0;
|
|
40
|
-
logger.info( { count: count } );
|
|
41
40
|
const query = { clientName: inputData.clientName };
|
|
42
41
|
const leadRecord = await findOne( query );
|
|
43
42
|
const tangoId = count + 1;
|
|
@@ -71,7 +70,6 @@ export async function create( req, res ) {
|
|
|
71
70
|
'planDetails.product': product,
|
|
72
71
|
'profileDetails.website': leadRecord?.websiteUrl,
|
|
73
72
|
'reportConfigs.reportName': generatedName,
|
|
74
|
-
'auditConfigs.queueName': generatedName,
|
|
75
73
|
'auditConfigs.zoneQueueName': `${generatedName}-zone`,
|
|
76
74
|
'auditConfigs.trafficQueueName': `${generatedName}-traffic`,
|
|
77
75
|
'auditConfigs.traxQueueName.unattendedCustomer': `${generatedName}-unattendedCustomer`,
|
|
@@ -79,6 +77,10 @@ export async function create( req, res ) {
|
|
|
79
77
|
'auditConfigs.traxQueueName.uniformDetection': `${generatedName}-uniformDetection`,
|
|
80
78
|
'auditConfigs.traxQueueName.mobileDetection': `${generatedName}-mobileDetection`,
|
|
81
79
|
'auditConfigs.traxQueueName.cameraAngleChange': `${generatedName}-cameraAngleChange`,
|
|
80
|
+
'auditConfigs.traxQueueName.hygiene': `${generatedName}-hygiene`,
|
|
81
|
+
'clientApi.apiKey': await getUuid(),
|
|
82
|
+
'clientApi.status': true,
|
|
83
|
+
|
|
82
84
|
};
|
|
83
85
|
|
|
84
86
|
record.featureConfigs = {};
|
|
@@ -330,7 +332,6 @@ export async function create( req, res ) {
|
|
|
330
332
|
// await deleteOneAuthentication( { user: user?._id, type: 'retail' } );
|
|
331
333
|
await findOneAndUpdateUser( userQuery, userRecord );
|
|
332
334
|
await Promise.all( [
|
|
333
|
-
createAuditQueue( generatedName ),
|
|
334
335
|
createAuditQueue( `${generatedName}-zone` ),
|
|
335
336
|
createAuditQueue( `${generatedName}-traffic` ),
|
|
336
337
|
createAuditQueue( `${generatedName}-unattendedCustomer` ),
|
|
@@ -338,7 +339,7 @@ export async function create( req, res ) {
|
|
|
338
339
|
createAuditQueue( `${generatedName}-uniformDetection` ),
|
|
339
340
|
createAuditQueue( `${generatedName}-mobileDetection` ),
|
|
340
341
|
createAuditQueue( `${generatedName}-cameraAngleChange` ),
|
|
341
|
-
|
|
342
|
+
createAuditQueue( `${generatedName}-hygiene` ) ] );
|
|
342
343
|
return res.sendSuccess( { result: { clientId: String( tangoId ) } } );
|
|
343
344
|
}
|
|
344
345
|
} catch ( error ) {
|
|
@@ -395,7 +396,7 @@ export async function changeStatus( req, res, next ) {
|
|
|
395
396
|
|
|
396
397
|
export async function getClients( req, res ) {
|
|
397
398
|
try {
|
|
398
|
-
const field = { clientName: 1, clientId: 1 };
|
|
399
|
+
const field = { clientName: 1, clientId: 1, traxDateRange: '$featureConfigs.traxDateRange', trafficDateRange: '$featureConfigs.trafficDateRange' };
|
|
399
400
|
let result = [];
|
|
400
401
|
if ( req?.user?.role === 'superadmin' ) {
|
|
401
402
|
result = await findClient( {}, field );
|
|
@@ -405,18 +406,6 @@ export async function getClients( req, res ) {
|
|
|
405
406
|
$match: {
|
|
406
407
|
userEmail: req?.user?.email,
|
|
407
408
|
assignedType: { $eq: 'client' },
|
|
408
|
-
// $expr: {
|
|
409
|
-
// $cond: {
|
|
410
|
-
// if: {
|
|
411
|
-
// $and: [
|
|
412
|
-
// { $eq: [ '$userType', 'tango' ] },
|
|
413
|
-
// { $eq: [ '$tangoUserType', 'csm' ] },
|
|
414
|
-
// ],
|
|
415
|
-
// },
|
|
416
|
-
// then: { $eq: [ '$isClientApproved', true ] },
|
|
417
|
-
// else: true,
|
|
418
|
-
// },
|
|
419
|
-
// },
|
|
420
409
|
},
|
|
421
410
|
},
|
|
422
411
|
{
|
|
@@ -450,9 +439,9 @@ export async function getClients( req, res ) {
|
|
|
450
439
|
},
|
|
451
440
|
{
|
|
452
441
|
$project: {
|
|
453
|
-
_id: 0,
|
|
454
442
|
clientId: 1,
|
|
455
443
|
clientName: 1,
|
|
444
|
+
traxDateRange: '$featureConfigs.traxDateRange',
|
|
456
445
|
},
|
|
457
446
|
},
|
|
458
447
|
];
|
|
@@ -711,33 +700,40 @@ export async function updateBrandInfo( req, res ) {
|
|
|
711
700
|
updateKeys.push( camelCaseToWords( element ) );
|
|
712
701
|
} );
|
|
713
702
|
}
|
|
703
|
+
const getPreCientInfo = await findOneClient( { clientId: req.params.id }, { _id: 0, registeredCompanyName: '$profileDetails.registeredCompanyName', industry: '$profileDetails.industry', clientType: '$profileDetails.clientType',
|
|
704
|
+
registeredAddress: '$profileDetails.registeredAddress', headQuarters: '$profileDetails.headQuarters', website: '$profileDetails.website', status: 1, averageTransactionValue: 1 } );
|
|
714
705
|
|
|
715
|
-
const user = await getUserNameEmailById( req.userId );
|
|
716
706
|
|
|
707
|
+
const updateAck = await brandInfoUpdate( {
|
|
708
|
+
clientId: req.params?.id, registeredCompanyName: req.body?.registeredCompanyName, industry: req.body?.industry,
|
|
709
|
+
clientType: req.body?.clientType, registeredAddress: req.body?.registeredAddress, headQuarters: req.body?.headQuarters,
|
|
710
|
+
website: req.body?.website, status: req.body?.status, logo: req.files?.logo ? `brandLogo.${req.files.logo.name.split( '.' )[1]}` : undefined, averageTransactionValue: req.body?.averageTransactionValue,
|
|
711
|
+
} );
|
|
712
|
+
const getPosCientInfo = await findOneClient( { clientId: req.params.id }, { _id: 0, registeredCompanyName: '$profileDetails.registeredCompanyName', industry: '$profileDetails.industry', clientType: '$profileDetails.clientType',
|
|
713
|
+
registeredAddress: '$profileDetails.registeredAddress', headQuarters: '$profileDetails.headQuarters', website: '$profileDetails.website', status: 1, averageTransactionValue: 1 } );
|
|
717
714
|
|
|
718
715
|
const logObj = {
|
|
719
716
|
clientId: req.params?.id,
|
|
720
|
-
userName: user?.userName,
|
|
721
|
-
email: user?.email,
|
|
717
|
+
userName: req?.user?.userName,
|
|
718
|
+
email: req?.user?.email,
|
|
722
719
|
date: new Date(),
|
|
723
720
|
logType: 'brandDetails',
|
|
724
721
|
logSubType: 'brandInfo',
|
|
725
722
|
changes: updateKeys,
|
|
726
723
|
eventType: 'update',
|
|
727
724
|
showTo: [ 'client', 'tango' ],
|
|
725
|
+
previous: getPreCientInfo,
|
|
726
|
+
current: getPosCientInfo,
|
|
728
727
|
};
|
|
729
|
-
|
|
728
|
+
logger.info( { previous: getPreCientInfo,
|
|
729
|
+
current: getPosCientInfo, logObj: logObj } );
|
|
730
730
|
if ( updateKeys.length ) {
|
|
731
|
-
|
|
731
|
+
logger.info( { updateKeys: updateKeys } );
|
|
732
|
+
const a =await insertOpenSearchData( openSearch.activityLog, logObj );
|
|
733
|
+
logger.info( { a: a } );
|
|
732
734
|
}
|
|
733
735
|
|
|
734
736
|
|
|
735
|
-
const updateAck = await brandInfoUpdate( {
|
|
736
|
-
clientId: req.params?.id, registeredCompanyName: req.body?.registeredCompanyName, industry: req.body?.industry,
|
|
737
|
-
clientType: req.body?.clientType, registeredAddress: req.body?.registeredAddress, headQuarters: req.body?.headQuarters,
|
|
738
|
-
website: req.body?.website, status: req.body?.status, logo: req.files?.logo ? `brandLogo.${req.files.logo.name.split( '.' )[1]}` : undefined, averageTransactionValue: req.body?.averageTransactionValue,
|
|
739
|
-
} );
|
|
740
|
-
|
|
741
737
|
if ( req.body?.status === 'active' ) {
|
|
742
738
|
await updateManyStore( { clientId: req.params?.id }, { status: 'active' } );
|
|
743
739
|
await updateManyUser( { clientId: req.params?.id }, { isActive: true } );
|
|
@@ -889,6 +885,7 @@ export async function updateSignatoryDetails( req, res ) {
|
|
|
889
885
|
export async function updateTicketConfiguration( req, res ) {
|
|
890
886
|
try {
|
|
891
887
|
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
888
|
+
let findClient = await findOneClient( { clientId: req.params?.id } );
|
|
892
889
|
const updateAck = await ticketConfigurationUpdate( {
|
|
893
890
|
clientId: req.params?.id, MinFilesCount: req.body?.MinFilesCount, accuracyPercentage: req.body?.accuracyPercentage, downTimeType: req.body?.downTimeType,
|
|
894
891
|
infraDownTime: req.body?.infraDownTime, installationReAssign: req.body?.installationReAssign, isRcaTicketAssign: req.body?.isRcaTicketAssign,
|
|
@@ -904,6 +901,7 @@ export async function updateTicketConfiguration( req, res ) {
|
|
|
904
901
|
}
|
|
905
902
|
|
|
906
903
|
const user = await getUserNameEmailById( req.userId );
|
|
904
|
+
let updatedClient = await findOneClient( { clientId: req.params?.id } );
|
|
907
905
|
|
|
908
906
|
const logObj = {
|
|
909
907
|
clientId: req.params?.id,
|
|
@@ -915,6 +913,8 @@ export async function updateTicketConfiguration( req, res ) {
|
|
|
915
913
|
changes: updateKeys,
|
|
916
914
|
eventType: 'update',
|
|
917
915
|
showTo: [ 'tango' ],
|
|
916
|
+
current: updatedClient.ticketConfigs,
|
|
917
|
+
previous: findClient.ticketConfigs,
|
|
918
918
|
};
|
|
919
919
|
|
|
920
920
|
if ( updateKeys.length ) {
|
|
@@ -1027,6 +1027,7 @@ export async function updateFeatureConfiguration( req, res ) {
|
|
|
1027
1027
|
export async function domainDetailsConfiguration( req, res ) {
|
|
1028
1028
|
try {
|
|
1029
1029
|
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
1030
|
+
const getPreData = await findOneClient( { clientId: req.params?.id }, { domainName: '$domainConfig.ssoLogin.domainName', TwoFactorAuthentication: '$domainConfig.ssoLogin.isEnable', ipWhitelist: '$domainConfig.ipWhitelisting.enableWhitelisting', WhitelistesIps: '$domainConfig.ipWhitelisting.allowedIps', enableOtp: '$domainConfig.enableOtp' } );
|
|
1030
1031
|
const updateAck = await domainDetailsConfigurationUpdate( {
|
|
1031
1032
|
clientId: req.params?.id, domainName: req.body?.domainName, isEnable: req.body?.isEnable,
|
|
1032
1033
|
enableWhitelisting: req.body?.enableWhitelisting, allowedIps: req.body?.allowedIps, enableOtp: req.body?.enableOtp,
|
|
@@ -1041,19 +1042,20 @@ export async function domainDetailsConfiguration( req, res ) {
|
|
|
1041
1042
|
} );
|
|
1042
1043
|
}
|
|
1043
1044
|
|
|
1044
|
-
const
|
|
1045
|
-
|
|
1045
|
+
const getPostData = await findOneClient( { clientId: req.params?.id }, { domainName: '$domainConfig.ssoLogin.domainName', TwoFactorAuthentication: '$domainConfig.enableOtp', ipWhitelist: '$domainConfig.ipWhitelisting.enableWhitelisting', WhitelistesIps: '$domainConfig.ipWhitelisting.allowedIps', isEnable: '$domainConfig.ssoLogin.isEnable' } );
|
|
1046
1046
|
|
|
1047
1047
|
const logObj = {
|
|
1048
1048
|
clientId: req.params?.id,
|
|
1049
|
-
userName: user?.userName,
|
|
1050
|
-
email: user?.email,
|
|
1049
|
+
userName: req?.user?.userName,
|
|
1050
|
+
email: req?.user?.email,
|
|
1051
1051
|
date: new Date(),
|
|
1052
1052
|
logType: 'configuration',
|
|
1053
1053
|
logSubType: 'domainDetails',
|
|
1054
1054
|
changes: updateKeys,
|
|
1055
1055
|
eventType: 'update',
|
|
1056
1056
|
showTo: [ 'client', 'tango' ],
|
|
1057
|
+
previous: getPreData,
|
|
1058
|
+
current: getPostData,
|
|
1057
1059
|
};
|
|
1058
1060
|
|
|
1059
1061
|
if ( updateKeys.length ) {
|
|
@@ -2026,7 +2028,7 @@ export async function getActivityLogs( req, res ) {
|
|
|
2026
2028
|
const query = {
|
|
2027
2029
|
'_source': [
|
|
2028
2030
|
'userId', 'userName', 'email', 'date', 'logType', 'logSubType',
|
|
2029
|
-
'changes', 'eventType',
|
|
2031
|
+
'changes', 'eventType', 'previous', 'current',
|
|
2030
2032
|
],
|
|
2031
2033
|
'query': {
|
|
2032
2034
|
'bool': {
|
|
@@ -2083,9 +2085,25 @@ export async function getActivityLogs( req, res ) {
|
|
|
2083
2085
|
|
|
2084
2086
|
const hits = logs?.body?.hits?.hits;
|
|
2085
2087
|
const totalDocuments = logs?.body?.hits?.total?.value;
|
|
2088
|
+
let temp = [];
|
|
2086
2089
|
if ( totalDocuments ) {
|
|
2087
|
-
|
|
2088
|
-
|
|
2090
|
+
hits.map( ( hit, i ) => {
|
|
2091
|
+
let respo ={};
|
|
2092
|
+
|
|
2093
|
+
if ( ( ( hit?._source?.eventType ).match( /update/ ) || ( hit?._source?.eventType ).match( /edit/ ) )&& hit?._source?.previous ) {
|
|
2094
|
+
const previous = hit?._source?.previous;
|
|
2095
|
+
const current=hit?._source?.current;
|
|
2096
|
+
const logType =hit?._source?.logType;
|
|
2097
|
+
const logSubType =hit?._source?.logSubType;
|
|
2098
|
+
respo = findDifferences( previous, current, logType, logSubType );
|
|
2099
|
+
hit._source.updatedValue = respo;
|
|
2100
|
+
temp.push( hit?._source );
|
|
2101
|
+
} else {
|
|
2102
|
+
temp.push( hit?._source );
|
|
2103
|
+
}
|
|
2104
|
+
},
|
|
2105
|
+
);
|
|
2106
|
+
res.sendSuccess( { data: temp, count: totalDocuments } );
|
|
2089
2107
|
} else {
|
|
2090
2108
|
res.sendError( 'No data found', 204 );
|
|
2091
2109
|
}
|
|
@@ -2096,6 +2114,122 @@ export async function getActivityLogs( req, res ) {
|
|
|
2096
2114
|
}
|
|
2097
2115
|
|
|
2098
2116
|
|
|
2117
|
+
function findDifferences( previous, current, logType, logSubType, path = '' ) {
|
|
2118
|
+
const dbKeys = JSON.parse( process.env.DB_KEYS );
|
|
2119
|
+
const ignoredKeys = new Set( [
|
|
2120
|
+
'_id', 'updatedAt', 'createdAt', 'password', 'clientId',
|
|
2121
|
+
'storeId', 'refreshToken', 'employeeId', 'fcmToken', 'permission',
|
|
2122
|
+
] );
|
|
2123
|
+
const documents = dbKeys.DOCUMENTS;
|
|
2124
|
+
// Get correct key mapping based on logType
|
|
2125
|
+
const keyMapping = logType == 'stores' ?documents.stores: logType == 'users' ?documents.users :logSubType=='reportConfig'?documents.reports: logType=='brandInfo'?documents.client:documents.client;
|
|
2126
|
+
|
|
2127
|
+
let differences = {};
|
|
2128
|
+
|
|
2129
|
+
for ( const key in current ) {
|
|
2130
|
+
if ( !Object.prototype.hasOwnProperty.call( current, key ) || ignoredKeys.has( key ) ) continue;
|
|
2131
|
+
|
|
2132
|
+
const prevValue = previous[key];
|
|
2133
|
+
const currValue = current[key];
|
|
2134
|
+
|
|
2135
|
+
if ( typeof prevValue === 'object' && typeof currValue === 'object' && prevValue !== null && currValue !== null ) {
|
|
2136
|
+
const nestedDiffs = findDifferences( prevValue, currValue, logType, logSubType, `${path}${key}.` );
|
|
2137
|
+
Object.assign( differences, nestedDiffs );
|
|
2138
|
+
} else if ( prevValue !== currValue ) {
|
|
2139
|
+
if (
|
|
2140
|
+
( prevValue === '' && currValue === '' ) ||
|
|
2141
|
+
( Array.isArray( prevValue ) && Array.isArray( currValue ) && prevValue.length === 0 && currValue.length === 0 )
|
|
2142
|
+
) {
|
|
2143
|
+
continue;
|
|
2144
|
+
}
|
|
2145
|
+
differences[`${path}${key}`] = { previous: prevValue, current: currValue };
|
|
2146
|
+
}
|
|
2147
|
+
}
|
|
2148
|
+
|
|
2149
|
+
// **Transform & Filter Differences**
|
|
2150
|
+
let updatedDifferences = {};
|
|
2151
|
+
Object.keys( differences ).forEach( ( key ) => {
|
|
2152
|
+
let newKey = key.replace( /spocDetails\.\d+\./, 'spocDetails.' ).replace( /WhitelistesIps\.\d+/, 'Whitelisted Ips' );
|
|
2153
|
+
let diff = differences[key];
|
|
2154
|
+
|
|
2155
|
+
if ( newKey.toLowerCase().includes( 'isactive' ) ) {
|
|
2156
|
+
diff = {
|
|
2157
|
+
previous: diff.previous ? 'Active' : 'Deactive',
|
|
2158
|
+
current: diff.current ? 'Active' : 'Deactive',
|
|
2159
|
+
};
|
|
2160
|
+
}
|
|
2161
|
+
|
|
2162
|
+
const userFriendlyKey = getUserFriendlyKey( newKey, keyMapping );
|
|
2163
|
+
if ( userFriendlyKey ) {
|
|
2164
|
+
newKey = userFriendlyKey;
|
|
2165
|
+
}
|
|
2166
|
+
|
|
2167
|
+
if ( newKey === 'Infra Email Alert' || newKey === 'Ip Whitelist' ) {
|
|
2168
|
+
diff.previous = ( diff.previous == true || diff.previous == 'Enabled' ) ? 'Enabled' : 'Disabled';
|
|
2169
|
+
diff.current = ( diff.current == true || diff.current == 'Enabled' ) ? 'Enabled' : 'Disabled';
|
|
2170
|
+
}
|
|
2171
|
+
if ( newKey === 'Mat Enabled' ) {
|
|
2172
|
+
diff.previous = ( diff.previous == true || diff.previous == 'Enabled' )?'Enabled' : 'Disabled';
|
|
2173
|
+
diff.current = ( diff.current == true || diff.current == 'Enabled' ) ? 'Enabled' : 'Disabled';
|
|
2174
|
+
}
|
|
2175
|
+
|
|
2176
|
+
if ( newKey === 'Two Factor Authentication' ) {
|
|
2177
|
+
diff.previous = ( diff.previous == true || diff.previous == 'Enabled' ) ? 'Enabled' : 'Disabled';
|
|
2178
|
+
diff.current = ( diff.current == true || diff.current == 'Enabled' ) ? 'Enabled' : 'Disabled';
|
|
2179
|
+
}
|
|
2180
|
+
|
|
2181
|
+
|
|
2182
|
+
// **Transform Roles Permission Keys**
|
|
2183
|
+
const rolesPermissionMatch = newKey.match( /rolespermission\.(\d+)\.modules\.(\d+)\.(isAdd|isEdit)/ );
|
|
2184
|
+
if ( rolesPermissionMatch ) {
|
|
2185
|
+
const [ , roleIndex, moduleIndex, action ] = rolesPermissionMatch;
|
|
2186
|
+
const role = previous.rolespermission?.[roleIndex];
|
|
2187
|
+
const module = role?.modules?.[moduleIndex];
|
|
2188
|
+
|
|
2189
|
+
if ( module ) {
|
|
2190
|
+
newKey = `User's ${module.name} Module ${action === 'isAdd' ? 'Add' : 'Edit'}`;
|
|
2191
|
+
diff.previous = diff.previous ? 'Enabled' : 'Disabled';
|
|
2192
|
+
diff.current = diff.current ? 'Enabled' : 'Disabled';
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
2195
|
+
|
|
2196
|
+
if ( !newKey || ( diff.previous === '' && !diff.current ) ) return;
|
|
2197
|
+
|
|
2198
|
+
if (
|
|
2199
|
+
( diff.previous === '' || diff.previous === null || ( Array.isArray( diff.previous ) && diff.previous.length === 0 ) ) &&
|
|
2200
|
+
diff.current === undefined
|
|
2201
|
+
) {
|
|
2202
|
+
return;
|
|
2203
|
+
}
|
|
2204
|
+
if (
|
|
2205
|
+
( diff.current === '' || diff.current === null || ( Array.isArray( diff.current ) && diff.current.length === 0 ) ) &&
|
|
2206
|
+
diff.previous === undefined
|
|
2207
|
+
) {
|
|
2208
|
+
return;
|
|
2209
|
+
}
|
|
2210
|
+
|
|
2211
|
+
updatedDifferences[newKey] = diff;
|
|
2212
|
+
} );
|
|
2213
|
+
|
|
2214
|
+
return updatedDifferences;
|
|
2215
|
+
}
|
|
2216
|
+
|
|
2217
|
+
|
|
2218
|
+
function getUserFriendlyKey( keyPath, mapping ) {
|
|
2219
|
+
const keys = keyPath.split( '.' ); // Split the key path (e.g., storeProfile.pincode → ['storeProfile', 'pincode'])
|
|
2220
|
+
let value = mapping;
|
|
2221
|
+
|
|
2222
|
+
for ( const key of keys ) {
|
|
2223
|
+
if ( value && typeof value === 'object' && key in value ) {
|
|
2224
|
+
value = value[key]; // Traverse down the object
|
|
2225
|
+
} else {
|
|
2226
|
+
return null; // Return original if not found
|
|
2227
|
+
}
|
|
2228
|
+
}
|
|
2229
|
+
|
|
2230
|
+
return typeof value === 'string' ? value : keyPath; // Return mapped value or original key
|
|
2231
|
+
}
|
|
2232
|
+
|
|
2099
2233
|
async function postApi( url, data ) {
|
|
2100
2234
|
const requestOptions = {
|
|
2101
2235
|
method: 'POST',
|
package/src/dtos/client.dtos.js
CHANGED
|
@@ -121,6 +121,9 @@ export const featureConfigurationSchemaBody = joi.object(
|
|
|
121
121
|
isNewZoneV2: joi.boolean().optional(),
|
|
122
122
|
isTrax: joi.boolean().optional(),
|
|
123
123
|
isControlCenter: joi.boolean().optional(),
|
|
124
|
+
isFootfallDirectoryAudit: joi.boolean().optional(),
|
|
125
|
+
isFootfallDirectoryLimit: joi.boolean().optional(),
|
|
126
|
+
streamBy: joi.string().optional(),
|
|
124
127
|
},
|
|
125
128
|
);
|
|
126
129
|
|
|
@@ -1,171 +1,171 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
|
6
|
-
<title>Your account was approved!</title>
|
|
7
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
8
|
-
<style type="text/css">
|
|
9
|
-
@media screen {
|
|
10
|
-
@font-face {
|
|
11
|
-
font-family: 'Inter';
|
|
12
|
-
font-style: normal;
|
|
13
|
-
font-weight: 400;
|
|
14
|
-
font-display: swap;
|
|
15
|
-
src: local("Inter"), local("Inter-Regular"), url(https://fonts.gstatic.com/s/inter/v12/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZJhiI2B.woff2) format('woff2');
|
|
16
|
-
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
body {
|
|
21
|
-
font-family: "Inter", sans-serif !important;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
body,
|
|
25
|
-
table,
|
|
26
|
-
td,
|
|
27
|
-
a {
|
|
28
|
-
-ms-text-size-adjust: 100%;
|
|
29
|
-
-webkit-text-size-adjust: 100%;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
table,
|
|
33
|
-
td {
|
|
34
|
-
mso-table-rspace: 0pt;
|
|
35
|
-
mso-table-lspace: 0pt;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
img {
|
|
39
|
-
-ms-interpolation-mode: bicubic;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
a[x-apple-data-detectors] {
|
|
43
|
-
font-family: "inherit" !important;
|
|
44
|
-
font-size: inherit !important;
|
|
45
|
-
font-weight: inherit !important;
|
|
46
|
-
line-height: inherit !important;
|
|
47
|
-
color: inherit !important;
|
|
48
|
-
text-decoration: none !important;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
div[style*="margin: 16px 0;"] {
|
|
52
|
-
margin: 0 !important;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
body {
|
|
56
|
-
width: 100% !important;
|
|
57
|
-
height: 100% !important;
|
|
58
|
-
padding: 0 !important;
|
|
59
|
-
margin: 0 !important;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
table {
|
|
63
|
-
border-collapse: collapse !important;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
a {
|
|
67
|
-
color: #1a82e2;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
img {
|
|
71
|
-
height: auto;
|
|
72
|
-
line-height: 100%;
|
|
73
|
-
text-decoration: none;
|
|
74
|
-
border: 0;
|
|
75
|
-
outline: none;
|
|
76
|
-
}
|
|
77
|
-
</style>
|
|
78
|
-
</head>
|
|
79
|
-
<body style="background-color: #dbe5ea;">
|
|
80
|
-
<div class="preheader" style="display: none; max-width: 0; max-height: 0; overflow: hidden; font-size: 1px; line-height: 1px; color: #fff; opacity: 0;"> Email Summary (Hidden) </div>
|
|
81
|
-
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="padding-left:10px;padding-right:10px">
|
|
82
|
-
<tr>
|
|
83
|
-
<td bgcolor="#dbe5ea" style="padding:32px 10px 0 10px">
|
|
84
|
-
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;" align="center">
|
|
85
|
-
<tr>
|
|
86
|
-
<td class="o_bg-white o_px-md o_py-md o_sans o_text" style="margin-top: 0px;margin-bottom: 0px;font-size: 16px;line-height: 24px;background-color: #ffffff;padding-left: 18px;padding-right: 24px;padding-top: 24px;padding-bottom: 24px;">
|
|
87
|
-
<p style="margin-top: 0px;margin-bottom: 0px;">
|
|
88
|
-
<a class="o_text-white" href="https://tangoeye.ai/" style="text-decoration: none;outline: none;color: #ffffff;">
|
|
89
|
-
<img src={{logo}} width="200" height="100" alt="SimpleApp" style="-ms-interpolation-mode: bicubic;vertical-align: middle;border: 0;line-height: 100%;height: auto;outline: none;text-decoration: none;">
|
|
90
|
-
</a>
|
|
91
|
-
</p>
|
|
92
|
-
</td>
|
|
93
|
-
</tr>
|
|
94
|
-
<tr>
|
|
95
|
-
<td align="left" bgcolor="#ffffff" style="padding-left: 30px;padding-right: 24px; font-size: 14px; line-height: 24px;">
|
|
96
|
-
<p class="o_heading o_mb-xxs" style="width: 544px;height: 0px;border: 1px solid #CBD5E1;flex: none;order: 1;flex-grow: 0;"></p>
|
|
97
|
-
</td>
|
|
98
|
-
</tr>
|
|
99
|
-
</table>
|
|
100
|
-
</td>
|
|
101
|
-
</tr>
|
|
102
|
-
<tr>
|
|
103
|
-
<td align="center" bgcolor="#dbe5ea" style="padding:0 10px 0 10px">
|
|
104
|
-
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
|
|
105
|
-
<tr>
|
|
106
|
-
<td class="o_bg-white o_px-md o_py-xl o_xs-py-md" style="background-color: #ffffff;padding-left: 30px;padding-right: 24px;padding-top: 10px;padding-bottom: 10px;">
|
|
107
|
-
<div class="o_col-6s o_sans o_text-md o_text-light o_center" style="margin-top: 0px;margin-bottom: 0px;font-size: 20px;line-height: 28px;color: #82899a;">
|
|
108
|
-
<span class="o_heading o_text-dark o_mb-xxs" style="font-weight: 700;margin-top: 0px;margin-bottom: 4px;color: #242b3d;line-height: 39px;"> Your account was approved!</span>
|
|
109
|
-
</div>
|
|
110
|
-
</td>
|
|
111
|
-
</tr>
|
|
112
|
-
</table>
|
|
113
|
-
</td>
|
|
114
|
-
</tr>
|
|
115
|
-
<tr>
|
|
116
|
-
<td align="center" bgcolor="#dbe5ea" style="padding:0 10px 0 10px">
|
|
117
|
-
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
|
|
118
|
-
<tr>
|
|
119
|
-
<td align="left" bgcolor="#ffffff" style="padding-left: 30px;padding-right: 24px; font-size: 16px;padding-top:10px; line-height: 24px;font-weight:400;color:#384860">
|
|
120
|
-
<p style="margin: 0;">As a verified user, you will be among the first to receive product updates, new feature announcements, enhanced security and personalised support.
|
|
121
|
-
<br><br>
|
|
122
|
-
Head over to the dashboard to finish your setup. </p>
|
|
123
|
-
</td>
|
|
124
|
-
</tr>
|
|
125
|
-
</table>
|
|
126
|
-
</td>
|
|
127
|
-
</tr>
|
|
128
|
-
<tr>
|
|
129
|
-
<td align="center" bgcolor="#dbe5ea" style="padding:0 10px 0 10px">
|
|
130
|
-
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
|
|
131
|
-
<tr>
|
|
132
|
-
<td align="left" bgcolor="#fff" style="border-radius: 6px;padding:14px 30px">
|
|
133
|
-
<a href={{url}} style="display: inline-block;padding: 10px 36px;font-size: 20px;color: #fff;text-decoration: none;border-radius: 6px;background-color: #00a3ff;"> Add Stores</a>
|
|
134
|
-
</td>
|
|
135
|
-
</tr>
|
|
136
|
-
</table>
|
|
137
|
-
</td>
|
|
138
|
-
</tr>
|
|
139
|
-
<tr>
|
|
140
|
-
<td align="center" bgcolor="#dbe5ea" style="padding:0 10px 0 10px">
|
|
141
|
-
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
|
|
142
|
-
<tr>
|
|
143
|
-
<td align="left" bgcolor="#ffffff" style="padding-left: 30px;padding-right: 24px; font-size: 16px;padding-top:10px; line-height: 24px;font-weight:400;color:#384860">
|
|
144
|
-
<p style="margin: 0;">Enjoy the full potential of Tango Traffic Module. If you have any questions or need assistance, our support team is here to help.
|
|
145
|
-
|
|
146
|
-
<br><br>
|
|
147
|
-
|
|
148
|
-
Happy exploring! </p>
|
|
149
|
-
</td>
|
|
150
|
-
</tr>
|
|
151
|
-
</table>
|
|
152
|
-
</td>
|
|
153
|
-
</tr>
|
|
154
|
-
<tr>
|
|
155
|
-
<td align="center" bgcolor="#dbe5ea" style="padding:0 10px 32px 10px">
|
|
156
|
-
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
|
|
157
|
-
<tr>
|
|
158
|
-
<td class="o_bg-white o_px-md o_py-xl o_xs-py-md" style="background-color: #ffffff;padding-left: 30px;padding-right: 24px;padding-bottom:15px">
|
|
159
|
-
<div class="o_col-6s o_sans o_text-md o_text-light o_center" style="margin-top: 0px;margin-bottom: 0px;font-size: 12px;color: #202B3C;font-style: normal;font-weight: 400;font-size: 12px;line-height: 150%;">
|
|
160
|
-
<br>
|
|
161
|
-
<p>If you'd rather not receive this kind of email, Don’t want any more emails from TangoEye?<u style="color:#00A3FF">Unsubscribe</u>.</p>
|
|
162
|
-
<p> © Tango Eye. All rights reserved.</p>
|
|
163
|
-
</div>
|
|
164
|
-
</td>
|
|
165
|
-
</tr>
|
|
166
|
-
</table>
|
|
167
|
-
</td>
|
|
168
|
-
</tr>
|
|
169
|
-
</table>
|
|
170
|
-
</body>
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
|
6
|
+
<title>Your account was approved!</title>
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
8
|
+
<style type="text/css">
|
|
9
|
+
@media screen {
|
|
10
|
+
@font-face {
|
|
11
|
+
font-family: 'Inter';
|
|
12
|
+
font-style: normal;
|
|
13
|
+
font-weight: 400;
|
|
14
|
+
font-display: swap;
|
|
15
|
+
src: local("Inter"), local("Inter-Regular"), url(https://fonts.gstatic.com/s/inter/v12/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZJhiI2B.woff2) format('woff2');
|
|
16
|
+
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
body {
|
|
21
|
+
font-family: "Inter", sans-serif !important;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
body,
|
|
25
|
+
table,
|
|
26
|
+
td,
|
|
27
|
+
a {
|
|
28
|
+
-ms-text-size-adjust: 100%;
|
|
29
|
+
-webkit-text-size-adjust: 100%;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
table,
|
|
33
|
+
td {
|
|
34
|
+
mso-table-rspace: 0pt;
|
|
35
|
+
mso-table-lspace: 0pt;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
img {
|
|
39
|
+
-ms-interpolation-mode: bicubic;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
a[x-apple-data-detectors] {
|
|
43
|
+
font-family: "inherit" !important;
|
|
44
|
+
font-size: inherit !important;
|
|
45
|
+
font-weight: inherit !important;
|
|
46
|
+
line-height: inherit !important;
|
|
47
|
+
color: inherit !important;
|
|
48
|
+
text-decoration: none !important;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
div[style*="margin: 16px 0;"] {
|
|
52
|
+
margin: 0 !important;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
body {
|
|
56
|
+
width: 100% !important;
|
|
57
|
+
height: 100% !important;
|
|
58
|
+
padding: 0 !important;
|
|
59
|
+
margin: 0 !important;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
table {
|
|
63
|
+
border-collapse: collapse !important;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
a {
|
|
67
|
+
color: #1a82e2;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
img {
|
|
71
|
+
height: auto;
|
|
72
|
+
line-height: 100%;
|
|
73
|
+
text-decoration: none;
|
|
74
|
+
border: 0;
|
|
75
|
+
outline: none;
|
|
76
|
+
}
|
|
77
|
+
</style>
|
|
78
|
+
</head>
|
|
79
|
+
<body style="background-color: #dbe5ea;">
|
|
80
|
+
<div class="preheader" style="display: none; max-width: 0; max-height: 0; overflow: hidden; font-size: 1px; line-height: 1px; color: #fff; opacity: 0;"> Email Summary (Hidden) </div>
|
|
81
|
+
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="padding-left:10px;padding-right:10px">
|
|
82
|
+
<tr>
|
|
83
|
+
<td bgcolor="#dbe5ea" style="padding:32px 10px 0 10px">
|
|
84
|
+
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;" align="center">
|
|
85
|
+
<tr>
|
|
86
|
+
<td class="o_bg-white o_px-md o_py-md o_sans o_text" style="margin-top: 0px;margin-bottom: 0px;font-size: 16px;line-height: 24px;background-color: #ffffff;padding-left: 18px;padding-right: 24px;padding-top: 24px;padding-bottom: 24px;">
|
|
87
|
+
<p style="margin-top: 0px;margin-bottom: 0px;">
|
|
88
|
+
<a class="o_text-white" href="https://tangoeye.ai/" style="text-decoration: none;outline: none;color: #ffffff;">
|
|
89
|
+
<img src={{logo}} width="200" height="100" alt="SimpleApp" style="-ms-interpolation-mode: bicubic;vertical-align: middle;border: 0;line-height: 100%;height: auto;outline: none;text-decoration: none;">
|
|
90
|
+
</a>
|
|
91
|
+
</p>
|
|
92
|
+
</td>
|
|
93
|
+
</tr>
|
|
94
|
+
<tr>
|
|
95
|
+
<td align="left" bgcolor="#ffffff" style="padding-left: 30px;padding-right: 24px; font-size: 14px; line-height: 24px;">
|
|
96
|
+
<p class="o_heading o_mb-xxs" style="width: 544px;height: 0px;border: 1px solid #CBD5E1;flex: none;order: 1;flex-grow: 0;"></p>
|
|
97
|
+
</td>
|
|
98
|
+
</tr>
|
|
99
|
+
</table>
|
|
100
|
+
</td>
|
|
101
|
+
</tr>
|
|
102
|
+
<tr>
|
|
103
|
+
<td align="center" bgcolor="#dbe5ea" style="padding:0 10px 0 10px">
|
|
104
|
+
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
|
|
105
|
+
<tr>
|
|
106
|
+
<td class="o_bg-white o_px-md o_py-xl o_xs-py-md" style="background-color: #ffffff;padding-left: 30px;padding-right: 24px;padding-top: 10px;padding-bottom: 10px;">
|
|
107
|
+
<div class="o_col-6s o_sans o_text-md o_text-light o_center" style="margin-top: 0px;margin-bottom: 0px;font-size: 20px;line-height: 28px;color: #82899a;">
|
|
108
|
+
<span class="o_heading o_text-dark o_mb-xxs" style="font-weight: 700;margin-top: 0px;margin-bottom: 4px;color: #242b3d;line-height: 39px;"> Your account was approved!</span>
|
|
109
|
+
</div>
|
|
110
|
+
</td>
|
|
111
|
+
</tr>
|
|
112
|
+
</table>
|
|
113
|
+
</td>
|
|
114
|
+
</tr>
|
|
115
|
+
<tr>
|
|
116
|
+
<td align="center" bgcolor="#dbe5ea" style="padding:0 10px 0 10px">
|
|
117
|
+
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
|
|
118
|
+
<tr>
|
|
119
|
+
<td align="left" bgcolor="#ffffff" style="padding-left: 30px;padding-right: 24px; font-size: 16px;padding-top:10px; line-height: 24px;font-weight:400;color:#384860">
|
|
120
|
+
<p style="margin: 0;">As a verified user, you will be among the first to receive product updates, new feature announcements, enhanced security and personalised support.
|
|
121
|
+
<br><br>
|
|
122
|
+
Head over to the dashboard to finish your setup. </p>
|
|
123
|
+
</td>
|
|
124
|
+
</tr>
|
|
125
|
+
</table>
|
|
126
|
+
</td>
|
|
127
|
+
</tr>
|
|
128
|
+
<tr>
|
|
129
|
+
<td align="center" bgcolor="#dbe5ea" style="padding:0 10px 0 10px">
|
|
130
|
+
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
|
|
131
|
+
<tr>
|
|
132
|
+
<td align="left" bgcolor="#fff" style="border-radius: 6px;padding:14px 30px">
|
|
133
|
+
<a href={{url}} style="display: inline-block;padding: 10px 36px;font-size: 20px;color: #fff;text-decoration: none;border-radius: 6px;background-color: #00a3ff;"> Add Stores</a>
|
|
134
|
+
</td>
|
|
135
|
+
</tr>
|
|
136
|
+
</table>
|
|
137
|
+
</td>
|
|
138
|
+
</tr>
|
|
139
|
+
<tr>
|
|
140
|
+
<td align="center" bgcolor="#dbe5ea" style="padding:0 10px 0 10px">
|
|
141
|
+
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
|
|
142
|
+
<tr>
|
|
143
|
+
<td align="left" bgcolor="#ffffff" style="padding-left: 30px;padding-right: 24px; font-size: 16px;padding-top:10px; line-height: 24px;font-weight:400;color:#384860">
|
|
144
|
+
<p style="margin: 0;">Enjoy the full potential of Tango Traffic Module. If you have any questions or need assistance, our support team is here to help.
|
|
145
|
+
|
|
146
|
+
<br><br>
|
|
147
|
+
|
|
148
|
+
Happy exploring! </p>
|
|
149
|
+
</td>
|
|
150
|
+
</tr>
|
|
151
|
+
</table>
|
|
152
|
+
</td>
|
|
153
|
+
</tr>
|
|
154
|
+
<tr>
|
|
155
|
+
<td align="center" bgcolor="#dbe5ea" style="padding:0 10px 32px 10px">
|
|
156
|
+
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
|
|
157
|
+
<tr>
|
|
158
|
+
<td class="o_bg-white o_px-md o_py-xl o_xs-py-md" style="background-color: #ffffff;padding-left: 30px;padding-right: 24px;padding-bottom:15px">
|
|
159
|
+
<div class="o_col-6s o_sans o_text-md o_text-light o_center" style="margin-top: 0px;margin-bottom: 0px;font-size: 12px;color: #202B3C;font-style: normal;font-weight: 400;font-size: 12px;line-height: 150%;">
|
|
160
|
+
<br>
|
|
161
|
+
<p>If you'd rather not receive this kind of email, Don’t want any more emails from TangoEye?<u style="color:#00A3FF">Unsubscribe</u>.</p>
|
|
162
|
+
<p> © Tango Eye. All rights reserved.</p>
|
|
163
|
+
</div>
|
|
164
|
+
</td>
|
|
165
|
+
</tr>
|
|
166
|
+
</table>
|
|
167
|
+
</td>
|
|
168
|
+
</tr>
|
|
169
|
+
</table>
|
|
170
|
+
</body>
|
|
171
171
|
</html> `
|
|
@@ -161,6 +161,9 @@ export function featureConfigurationUpdate( query, inputData ) {
|
|
|
161
161
|
'featureConfigs.isNewZoneV2': inputData?.isNewZoneV2,
|
|
162
162
|
'featureConfigs.isTrax': inputData?.isTrax,
|
|
163
163
|
'featureConfigs.isControlCenter': inputData?.isControlCenter,
|
|
164
|
+
'featureConfigs.isFootfallDirectoryAudit': inputData?.isFootfallDirectoryAudit,
|
|
165
|
+
'featureConfigs.isFootfallDirectoryLimit': inputData?.isFootfallDirectoryLimit,
|
|
166
|
+
'featureConfigs.streamBy': inputData?.streamBy,
|
|
164
167
|
},
|
|
165
168
|
} );
|
|
166
169
|
}
|