Compare commits

...

802 Commits

Author SHA1 Message Date
Dave Richer
2c0eab9366 IO-3096-GlobalNotifications - Correct time zone from footer in notification email 2025-03-14 11:27:28 -04:00
Patrick Fic
b831d8ca8a IO-3096 Add indexes for notifications. 2025-03-13 15:27:20 -07:00
Dave Richer
69da6bccf7 IO-3096-GlobalNotifications - Adjust splits 2025-03-13 17:37:36 -04:00
Dave Richer
e3d7ebd7d8 IO-3096-GlobalNotifications - Verify status reporter is a function and exists prior to calling it in cleanup task 2025-03-13 14:59:58 -04:00
Dave Richer
5f0b63a192 IO-3096-GlobalNotifications - Add in a function to exclude extra logging from production 2025-03-13 13:56:30 -04:00
Dave Richer
7a5ac739ab Merge branch 'feature/IO-3170-HotFixForRedis' into feature/IO-3096-GlobalNotifications 2025-03-13 11:49:31 -04:00
Dave Richer
e2297be0af IO-3170-HotfixFoRedis 2025-03-13 11:47:21 -04:00
Dave Richer
73c4983342 Merged in feature/IO-3166-Global-Notifications-Part-2 (pull request #2199)
IO-3166-Global-Notifications-Part-2: Remove unused event handler (hasura),
2025-03-13 15:31:28 +00:00
Dave Richer
166e1e4030 IO-3166-Global-Notifications-Part-2: Remove unused event handler (hasura), 2025-03-13 11:29:41 -04:00
Dave Richer
5fa7377121 Merged in feature/IO-3166-Global-Notifications-Part-2 (pull request #2196)
IO-3166-Global-Notifications-Part-2: add additional key prefixes for dev v prod
2025-03-13 01:12:33 +00:00
Dave Richer
f21ba8e087 IO-3166-Global-Notifications-Part-2: add additional key prefixes for dev v prod 2025-03-12 21:10:42 -04:00
Dave Richer
d56d1f369c Merged in feature/IO-3166-Global-Notifications-Part-2 (pull request #2193)
IO-3166-Global-Notifications-Part-2: Make sure BULLMQ prefixes do not collide
2025-03-13 00:01:56 +00:00
Dave Richer
360a1954f4 IO-3166-Global-Notifications-Part-2: Make sure BULLMQ prefixes do not collide 2025-03-12 20:00:53 -04:00
Dave Richer
6b047418cc Merged in feature/IO-3166-Global-Notifications-Part-2 (pull request #2190)
Feature/IO-3166 Global Notifications Part 2
2025-03-12 16:06:34 +00:00
Dave Richer
87db292e5d IO-3166-Global-Notifications-Part-2: Fix typo in builder function name 2025-03-12 12:05:21 -04:00
Dave Richer
9ef8440e64 IO-3166-Global-Notifications-Part-2: Add Enabled key to scenario map (backend), filter out scenarios not enabled. 2025-03-12 11:46:09 -04:00
Dave Richer
8ae3b28cb6 IO-3166-Global-Notifications-Part-2: checkpoint, Modify additional strings as per Allan, Refactor builder down to prevent duplicate logic, comment out supplement imported. 2025-03-12 11:34:50 -04:00
Dave Richer
0d80854196 Merged in feature/IO-3166-Global-Notifications-Part-2 (pull request #2186)
Feature/IO-3166 Global Notifications Part 2
2025-03-11 19:14:02 +00:00
Dave Richer
029fb58f48 IO-3166-Global-Notifications-Part-2: checkpoint 2025-03-11 14:47:54 -04:00
Dave Richer
85929b0bb1 IO-3166-Global-Notifications-Part-2: checkpoint 2025-03-11 14:09:35 -04:00
Dave Richer
dc234e4d72 IO-3166-Global-Notifications-Part-2: checkpoint 2025-03-11 13:57:05 -04:00
Dave Richer
212fc4a7cc Merged in feature/IO-3166-Global-Notifications-Part-2 (pull request #2183)
Feature/IO-3166 Global Notifications Part 2
2025-03-11 17:18:10 +00:00
Dave Richer
8de7db60e6 IO-3166-Global-Notifications-Part-2: checkpoint 2025-03-11 13:16:47 -04:00
Dave Richer
d6df5af1a4 IO-3166-Global-Notifications-Part-2: checkpoint 2025-03-11 11:57:16 -04:00
Dave Richer
8d36ad3589 IO-3166-Global-Notifications-Part-2: checkpoint 2025-03-11 11:38:56 -04:00
Dave Richer
9061821347 IO-3166-Global-Notifications-Part-2: Fixed unread notifications not vanishing once marked as read in unread only 2025-03-11 11:00:42 -04:00
Dave Richer
1fad3968bb Merged in feature/IO-3166-Global-Notifications-Part-2 (pull request #2179)
IO-3166-Global-Notifications-Part-2: getAwsClusterFix
2025-03-07 20:59:43 +00:00
Dave Richer
1d84dd1a83 IO-3166-Global-Notifications-Part-2: getAwsClusterFix 2025-03-07 15:58:52 -05:00
Dave Richer
a492909ad7 Merged in feature/IO-3166-Global-Notifications-Part-2 (pull request #2176)
IO-3170-Enhanced-GetRedisEndpointsFromAWS - Fix to prevent breaking
2025-03-07 20:27:22 +00:00
Dave Richer
14a885b443 Merge branch 'hotfix/IO-3170-Enhanced-GetRedisEndpointsFromAWS' into feature/IO-3166-Global-Notifications-Part-2 2025-03-07 15:26:22 -05:00
Dave Richer
d5bd9d9b59 IO-3170-Enhanced-GetRedisEndpointsFromAWS - Fix to prevent breaking 2025-03-07 15:19:40 -05:00
Dave Richer
6e6cabbd63 Merged in feature/IO-3166-Global-Notifications-Part-2 (pull request #2172)
IO-3166-Global-Notifications-Part-2 - Improved GetRedisNodesFromAWS
2025-03-07 20:11:02 +00:00
Dave Richer
480838b1dc IO-3166-Global-Notifications-Part-2 - Improved GetRedisNodesFromAWS 2025-03-07 15:10:06 -05:00
Dave Richer
ffadd31a5f Merged in feature/IO-3166-Global-Notifications-Part-2 (pull request #2168)
IO-3166-Global-Notifications-Part-2 - Small styling change
2025-03-07 18:51:21 +00:00
Dave Richer
235527140c IO-3166-Global-Notifications-Part-2 - Small styling change 2025-03-07 13:50:40 -05:00
Dave Richer
ef22ba3d2c Merged in feature/IO-3166-Global-Notifications-Part-2 (pull request #2165)
IO-3166-Global-Notifications-Part-2 - Checkpoint
2025-03-07 16:04:27 +00:00
Dave Richer
11ff8e91c7 IO-3166-Global-Notifications-Part-2 - Checkpoint 2025-03-07 10:58:01 -05:00
Dave Richer
71dd138f2f Merged in feature/IO-3166-Global-Notifications-Part-2 (pull request #2162)
Feature/IO-3166 Global Notifications Part 2
2025-03-06 22:43:24 +00:00
Dave Richer
36f4cc8cb8 IO-3166-Global-Notifications-Part-2 - Checkpoint 2025-03-06 17:41:54 -05:00
Patrick Fic
d2944ff902 IO-3166 Update notification strings. 2025-03-06 14:38:00 -08:00
Dave Richer
3cbcbb92eb Merged in feature/IO-3166-Global-Notifications-Part-2 (pull request #2159)
Feature/IO-3166 Global Notifications Part 2
2025-03-06 21:06:15 +00:00
Dave Richer
02e6c6007c IO-3166-Global-Notifications-Part-2 - Checkpoint 2025-03-06 16:05:42 -05:00
Dave Richer
2cee5f1944 IO-3166-Global-Notifications-Part-2 - Checkpoint 2025-03-06 16:02:01 -05:00
Dave Richer
ef695776cd Merged in feature/IO-3166-Global-Notifications-Part-2 (pull request #2156)
Feature/IO-3166 Global Notifications Part 2
2025-03-06 18:39:46 +00:00
Dave Richer
53580fbc78 IO-3166-Global-Notifications-Part-2 - Checkpoint 2025-03-06 13:36:19 -05:00
Dave Richer
21335d4e8c IO-3166-Global-Notifications-Part-2 - Checkpoint - job watchers styling 2025-03-05 21:05:24 -05:00
Dave Richer
9b545d6c8c Merged in feature/IO-3166-Global-Notifications-Part-2 (pull request #2153)
Feature/IO-3166 Global Notifications Part 2
2025-03-05 22:30:11 +00:00
Dave Richer
fbe674a2e5 IO-3166-Global-Notifications-Part-2 - Checkpoint 2025-03-05 17:29:24 -05:00
Dave Richer
2a65cb5025 IO-3166-Global-Notifications-Part-2 - Checkpoint 2025-03-05 17:28:32 -05:00
Dave Richer
b4a3960eac Merged in feature/IO-3166-Global-Notifications-Part-2 (pull request #2150)
Feature/IO-3166 Global Notifications Part 2
2025-03-05 18:54:42 +00:00
Dave Richer
358503f9ef IO-3166-Global-Notifications-Part-2 - Checkpoint 2025-03-05 12:46:45 -05:00
Dave Richer
25a9e6cea1 IO-3166-Global-Notifications-Part-2 - Checkpoint 2025-03-05 12:18:01 -05:00
Dave Richer
e40e0bbb8f Merged release/2024-03-14 into feature/IO-3096-GlobalNotifications 2025-03-05 16:45:08 +00:00
Dave Richer
8fdd07827e Merged in feature/IO-3166-Global-Notifications-Part-2 (pull request #2147)
Feature/IO-3166 Global Notifications Part 2
2025-03-05 16:44:40 +00:00
Dave Richer
059067bc61 IO-3166-Global-Notifications-Part-2 - Checkpoint 2025-03-05 11:43:05 -05:00
Dave Richer
f8ae6dc5af IO-3166-Global-Notifications-Part-2 - Checkpoint 2025-03-05 11:07:28 -05:00
Dave Richer
ac2bb42124 Merged in feature/IO-3096-GlobalNotifications (pull request #2145)
Feature/IO-3096 GlobalNotifications
2025-03-04 22:55:58 +00:00
Dave Richer
b149f70b6f Merged in feature/IO-3166-Global-Notifications-Part-2 (pull request #2144)
Feature/IO-3166 Global Notifications Part 2
2025-03-04 22:55:26 +00:00
Dave Richer
ec8a413ed1 IO-3166-Global-Notifications-Part-2 - Checkpoint 2025-03-04 17:54:57 -05:00
Dave Richer
76ec755d07 IO-3166-Global-Notifications-Part-2 - Checkpoint 2025-03-04 17:50:58 -05:00
Dave Richer
07faa5eec2 IO-3166-Global-Notifications-Part-2 - Checkpoint 2025-03-04 17:07:31 -05:00
Dave Richer
7bbbf5934a Merged in feature/IO-3096-GlobalNotifications (pull request #2143)
Feature/IO-3096 GlobalNotifications
2025-03-04 16:57:30 +00:00
Dave Richer
fd7850b551 IO-3096-GlobalNotifications: Self Watcher env var was not handled correctly 2025-03-04 11:56:46 -05:00
Dave Richer
2b76f8a12d IO-3096-GlobalNotifications: Package Updates to match test-AIO 2025-03-04 11:40:19 -05:00
Dave Richer
aa073cfd68 IO-3096-GlobalNotifications: Fixed a small typo in emailQueue 2025-03-04 11:38:21 -05:00
Dave Richer
03863ce838 Merged in feature/IO-3096-GlobalNotifications (pull request #2141)
Feature/IO-3096 GlobalNotifications
2025-03-04 16:21:54 +00:00
Dave Richer
1b22697429 feature/IO-3096-GlobalNotifications - Code Review Part 5 2025-03-04 11:21:21 -05:00
Dave Richer
4fc3fbdcc0 Merged in release/2025-02-28 (pull request #2140)
IO-2561 Return Items Modal
2025-03-04 16:18:49 +00:00
Dave Richer
163978930f feature/IO-3096-GlobalNotifications - Code Review Part 4 2025-03-03 23:29:47 -05:00
Dave Richer
c75e27e018 feature/IO-3096-GlobalNotifications - Code Review Part 3 2025-03-03 23:20:01 -05:00
Dave Richer
555bedbb6c feature/IO-3096-GlobalNotifications - Code Review Part 2 2025-03-03 23:11:03 -05:00
Dave Richer
a57abec81b feature/IO-3096-GlobalNotifications - Code Review Part 1 2025-03-03 22:14:33 -05:00
Dave Richer
b9df4c2587 feature/IO-3096-GlobalNotifications - Logging / Merge release 2025-03-03 14:36:18 -05:00
Dave Richer
15686bdab8 Merge remote-tracking branch 'origin/release/2025-02-28' into feature/IO-3096-GlobalNotifications 2025-03-03 14:35:52 -05:00
Dave Richer
175e2097fa feature/IO-3096-GlobalNotifications - Logging 2025-03-03 14:00:38 -05:00
Dave Richer
359c4c75a1 feature/IO-3096-GlobalNotifications - typo 2025-03-03 13:43:28 -05:00
Dave Richer
86aa5bf5e7 feature/IO-3096-GlobalNotifications - Checkpoint - Additional String Cleanup, loading spinner 2025-03-03 12:07:19 -05:00
Dave Richer
35b92570e5 feature/IO-3096-GlobalNotifications - Checkpoint - Splits are now in place 2025-03-03 11:41:10 -05:00
Dave Richer
b5c03b8cf0 feature/IO-3096-GlobalNotifications - Checkpoint - add some missing keys (cleanup) 2025-03-03 11:00:55 -05:00
Dave Richer
3c45519457 feature/IO-3096-GlobalNotifications - Checkpoint - merge master 2025-03-03 10:57:27 -05:00
Patrick Fic
dc60b8d18e Merged in feature/IO-3162-sentry-improvements (pull request #2138)
Feature/IO-3162 sentry improvements
2025-02-28 23:44:58 +00:00
Patrick Fic
ea75ac49aa IO-3162 Resize test CI boxes. 2025-02-28 15:25:03 -08:00
Patrick Fic
f3c6c7f004 IO-3162 Sentry cleanup. 2025-02-28 15:18:42 -08:00
Patrick Fic
65fb73ae82 IO-3162 Add Prod/Test restriction on sentry init. 2025-02-28 15:14:56 -08:00
Patrick Fic
617e39eb17 IO-3162 Add CI paramters to aid in sourcemap generation. 2025-02-28 15:03:16 -08:00
Dave Richer
f4a3b75a86 feature/IO-3096-GlobalNotifications - Checkpoint - Header finalized, scenarioParser now uses ENV var for FILTER_SELF from watchers. 2025-02-28 17:33:46 -05:00
Patrick Fic
c0ffda27cf IO-3162 Additional logging improvements. 2025-02-28 14:21:36 -08:00
Dave Richer
f51fa08961 feature/IO-3096-GlobalNotifications - Checkpoint - Header finalized, scenarioParser now uses ENV var for FILTER_SELF from watchers. 2025-02-28 17:17:13 -05:00
Patrick Fic
ba63e8054f IO-3162 Sentry package upgrades and refactors. 2025-02-28 12:15:47 -08:00
Allan Carr
32813032e6 Merged in feature/IO-2561-Return-Items-Modal (pull request #2131)
Feature/IO-2561 Return Items Modal

Approved-by: Dave Richer
2025-02-28 17:36:37 +00:00
Dave Richer
a5904f55aa feature/IO-3096-GlobalNotifications - styling checkpoint 2025-02-28 12:14:50 -05:00
Dave Richer
f6acc1107c feature/IO-3096-GlobalNotifications - add Dayjs, minor packages on backend 2025-02-28 12:05:40 -05:00
Dave Richer
9b871149ac feature/IO-3096-GlobalNotifications - add Dayjs, minor packages on backend 2025-02-28 11:13:08 -05:00
Allan Carr
9a71779cfe IO-2561 Return Items Modal
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-02-27 18:42:43 -08:00
Dave Richer
5bd6f0453d feature/IO-3096-GlobalNotifications -Read Status Sync accross all clients. 2025-02-27 20:28:41 -05:00
Dave Richer
f6328d10f7 feature/IO-3096-GlobalNotifications -Read Status Sync accross all clients. 2025-02-27 20:16:33 -05:00
Dave Richer
3766c3d938 feature/IO-3096-GlobalNotifications - Adjust the Global Placement for notificationContext.jsx, removed adjustments to said location and duration to socket 2025-02-27 13:30:18 -05:00
Dave Richer
01b18a4a02 feature/IO-3096-GlobalNotifications - Checkpoint - Clean up previous socket usages by funneling them all through useSocket vs useContext(SocketConext), package updates. 2025-02-27 11:56:31 -05:00
Dave Richer
17c4e2fd0e Merge remote-tracking branch 'origin/master-AIO' into feature/IO-3096-GlobalNotifications 2025-02-26 16:46:00 -05:00
Dave Richer
eb51085055 feature/IO-3096-GlobalNotifications - Checkpoint - Clicking the alert notification will also navigate you to the job. 2025-02-26 16:44:25 -05:00
Dave Richer
abd530b8b2 feature/IO-3096-GlobalNotifications - Checkpoint - clicking an individual notification will mark it read 2025-02-26 16:30:16 -05:00
Dave Richer
e4d437018d feature/IO-3096-GlobalNotifications - Checkpoint - clicking an individual notification will mark it read 2025-02-26 15:52:21 -05:00
Dave Richer
0767e290f4 feature/IO-3096-GlobalNotifications - Checkpoint - Fix user getting all bodyshop notifications (now by associationId), fix regression in 'Assigned To' scenario. 2025-02-26 13:11:49 -05:00
Dave Richer
b86309e74b feature/IO-3096-GlobalNotifications - Checkpoint 2025-02-25 20:18:59 -05:00
Dave Richer
7e2bd128e8 feature/IO-3096-GlobalNotifications - Checkpoint 2025-02-25 20:08:55 -05:00
Dave Richer
7f547c90c2 feature/IO-3096-GlobalNotifications - Checkpoint 2025-02-25 20:02:27 -05:00
Dave Richer
fa39e2b97e feature/IO-3096-GlobalNotifications - Checkpoint 2025-02-25 19:58:00 -05:00
Dave Richer
c5d00f7641 feature/IO-3096-GlobalNotifications - Checkpoint 2025-02-25 17:23:35 -05:00
Dave Richer
08b7f0e59c feature/IO-3096-GlobalNotifications - Checkpoint - In production, a user can not trigger their own scenario notification. 2025-02-25 15:46:11 -05:00
Patrick Fic
f0af12bc2c Merged in feature/IO-3152-opensearch-improvements (pull request #2129)
feature/IO-3152-opensearch-improvements

Approved-by: Patrick Fic
2025-02-25 19:28:03 +00:00
Patrick Fic
ace9ec792d IO-3152 Restrict searched indexes and remove wildcard search.
IO-3152 Resolve accidentally committed change.
2025-02-25 11:22:36 -08:00
Dave Richer
015f4cc5bd feature/IO-3096-GlobalNotifications - Checkpoint - Notification Center 2025-02-25 14:01:57 -05:00
Dave Richer
4f1c0b9996 feature/IO-3096-GlobalNotifications - Checkpoint - Notification Center 2025-02-24 18:04:15 -05:00
Dave Richer
b395839b37 feature/IO-3096-GlobalNotifications - Checkpoint - Notification Center 2025-02-24 16:02:55 -05:00
Dave Richer
0f067fc503 feature/IO-3096-GlobalNotifications - Checkpoint, Ratify notifications tb table. 2025-02-24 12:52:10 -05:00
Dave Richer
a5cf81bd28 feature/IO-3096-GlobalNotifications - Checkpoint, merge master, ready DB 2025-02-24 12:05:40 -05:00
Dave Richer
e892e4cab1 Merge remote-tracking branch 'origin/master-AIO' into feature/IO-3096-GlobalNotifications 2025-02-24 12:03:43 -05:00
Patrick Fic
ef4bb75ce7 Merged in release/2025-02-28 (pull request #2128)
Add catch error handling.

Approved-by: Patrick Fic
2025-02-21 00:44:05 +00:00
Patrick Fic
459af4f537 Add catch error handling. 2025-02-20 16:39:20 -08:00
Patrick Fic
f860931eab Remove email from handler. 2025-02-20 16:35:47 -08:00
Patrick Fic
0bf9f932b7 Adjust handler logging. 2025-02-20 15:44:49 -08:00
Dave Richer
a077cf0820 feature/IO-3096-GlobalNotifications - Package updates, prepare scenario builder for app notifications, redo header to have right aligned items. 2025-02-20 17:41:52 -05:00
Patrick Fic
c1abe98b89 Merged in release/2025-02-28 (pull request #2123)
release/2025-02-28

Approved-by: Patrick Fic
2025-02-20 22:37:55 +00:00
Patrick Fic
0f32e6ffc7 Add additional logging to OS Handler. 2025-02-20 14:37:25 -08:00
Dave Richer
eca7ff4a42 feature/IO-3096-GlobalNotifications - Clear stage, add notes 2025-02-20 15:25:34 -05:00
Dave Richer
7d6b95d344 feature/IO-3096-GlobalNotifications - Merge master 2025-02-20 14:10:01 -05:00
Dave Richer
9e44ee2a26 Merged in release/2025-02-28 (pull request #2122)
hotfix/IO-3148-Error-In-Email-Bounce-Route: Hot Fix for Broken Import
2025-02-20 19:04:25 +00:00
Dave Richer
5d0500582e Merged in hotfix/IO-3148-Error-In-Email-Bounce-Route (pull request #2121)
hotfix/IO-3148-Error-In-Email-Bounce-Route: Hot Fix for Broken Import
2025-02-20 19:03:52 +00:00
Dave Richer
f53fcc345e hotfix/IO-3148-Error-In-Email-Bounce-Route: Hot Fix for Broken Import 2025-02-20 14:01:11 -05:00
Dave Richer
1b7cb7c852 feature/IO-3096-GlobalNotifications - Checkpoint, fixed some email bugs in other files, consolidated the GetEndpoints on the backend, moved the consolidation delays for queues to ENV vars 2025-02-20 13:43:22 -05:00
Dave Richer
c82cfb3ec2 feature/IO-3096-GlobalNotifications - Checkpoint, fixed some email bugs in other files, consolidated the GetEndpoints on the backend, moved the consolidation delays for queues to ENV vars 2025-02-20 13:13:09 -05:00
Dave Richer
cc5fea9410 feature/IO-3096-GlobalNotifications - Checkpoint, finished testing queue, adjusted timeouts to be pegged to one variable. 2025-02-20 12:21:09 -05:00
Dave Richer
29f7144e72 feature/IO-3096-GlobalNotifications - Email Queue now batches per job per user 2025-02-19 16:10:53 -05:00
Dave Richer
1384616d66 feature/IO-3096-GlobalNotifications - Cleanup and Package bumps 2025-02-19 12:50:01 -05:00
Dave Richer
366f7b9c4a Merge remote-tracking branch 'origin/master-AIO' into feature/IO-3096-GlobalNotifications 2025-02-19 10:42:34 -05:00
Dave Richer
67e904e121 Merged in release/2025-02-28 (pull request #2120)
feature/IO-3146-Hotfix-For-Email-Translations
2025-02-19 15:41:14 +00:00
Dave Richer
83ea51157d Merged in feature/IO-3146-Hotfix-For-Email-Translation (pull request #2118)
feature/IO-3146-Hotfix-For-Email-Translations
2025-02-19 15:40:05 +00:00
Dave Richer
9f207f0946 feature/IO-3146-Hotfix-For-Email-Translations 2025-02-19 10:38:32 -05:00
Dave Richer
2a81517104 feature/IO-3096-GlobalNotifications - Checkpoint, App Queue 2025-02-18 17:37:24 -05:00
Dave Richer
00005c881e feature/IO-3096-GlobalNotifications - Checkpoint, App Queue 2025-02-18 14:29:07 -05:00
Dave Richer
c1ea8e8a3d feature/IO-3096-GlobalNotifications - Checkpoint, App Queue 2025-02-18 13:38:57 -05:00
Dave Richer
adb15a4748 feature/IO-3096-GlobalNotifications - Checkpoint, Builders 2025-02-18 12:57:54 -05:00
Dave Richer
c214ed1dfb feature/IO-3096-GlobalNotifications - Checkpoint, Builders 2025-02-18 12:05:35 -05:00
Dave Richer
c02c36c548 feature/IO-3096-GlobalNotifications - Checkpoint, socket to email to bodyshop mapping. 2025-02-18 11:02:46 -05:00
Dave Richer
a15f86cc4e Merge remote-tracking branch 'origin/master-AIO' into feature/IO-3096-GlobalNotifications 2025-02-18 09:52:35 -05:00
Dave Richer
8a88a241d6 Merged in release/2025-02-14 (pull request #2117)
Release/2025-02-14 - IO-3127 IO-3128 IO-3077 IO-3131 IO-3139 IO-3140
2025-02-16 01:20:59 +00:00
Dave Richer
df13f257db feature/IO-3096-GlobalNotifications - Checkpoint, BULLMQ! 2025-02-13 16:19:36 -05:00
Dave Richer
5cfadf7929 feature/IO-3096-GlobalNotifications - Merge release / Add PropTypes 2025-02-13 11:15:16 -05:00
Dave Richer
4a46870327 Merge remote-tracking branch 'origin/release/2025-02-14' into feature/IO-3096-GlobalNotifications 2025-02-13 11:14:20 -05:00
Allan Carr
4684bada1e Merged in feature/IO-3140-Job-Close-Print-Center (pull request #2115)
IO-3140 Job Close Print Center

Approved-by: Dave Richer
2025-02-13 01:05:17 +00:00
Allan Carr
163354f4b4 IO-3140 Job Close Print Center
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-02-12 16:19:17 -08:00
Dave Richer
3d225c9f92 Merge remote-tracking branch 'origin/release/2025-02-14' into feature/IO-3096-GlobalNotifications 2025-02-12 15:21:29 -05:00
Dave Richer
f3b2edea1c Merged in feature/IO-3139-Header-Deprecation-Bug (pull request #2114)
feature/IO-3139-Header-Deprecation-Bug - Quick fix for header deprecation.
2025-02-12 20:21:12 +00:00
Dave Richer
01e103fd0e feature/IO-3139-Header-Deprecation-Bug - Quick fix for header deprecation. 2025-02-12 15:20:17 -05:00
Dave Richer
1fc21e49a0 feature/IO-3096-GlobalNotifications - Merge 2025-02-14 branch and resolve conflicts 2025-02-12 14:46:58 -05:00
Dave Richer
19d608e2b0 feature/IO-3096-GlobalNotifications - Checkpoint/Refactor cleanup 2025-02-12 14:44:24 -05:00
Dave Richer
4b184d1d42 Merged in hotfix/IO-3128-Unread-Messages-Not-Updating (pull request #2112)
hotfix/IO-3128-Unread-Messages-Not-Updating - Initial fix just to make sure clients see messages, will poll and update every 60 seconds if the chat window is closed and has never been opened.
2025-02-12 19:06:13 +00:00
Dave Richer
3f75041ad9 feature/IO-3096-GlobalNotifications - Checkpoint 2025-02-12 11:57:50 -05:00
Patrick Fic
8c541dad05 Merge branch 'release/2025-02-14' of bitbucket.org:snaptsoft/bodyshop into release/2025-02-14 2025-02-12 07:42:20 -08:00
Patrick Fic
921cca86c1 Remove patrick from support emails. 2025-02-12 07:41:52 -08:00
Allan Carr
841312ebcd Merged in feature/IO-3131-Crisp-Segment-for-BASIC (pull request #2111)
IO-3131 Crisp Segment for Basic

Approved-by: Dave Richer
2025-02-12 14:55:08 +00:00
Allan Carr
5ed00eaffe IO-3131 Crisp Segment for Basic
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-02-11 20:26:44 -08:00
Dave Richer
994ea8bb20 feature/IO-3096-GlobalNotifications - Checkpoint 2025-02-11 17:13:40 -05:00
Dave Richer
580641bae6 feature/IO-3096-GlobalNotifications - Checkpoint 2025-02-11 15:07:42 -05:00
Patrick Fic
024b4fe21b Merged in feature/IO-3077-import-rules-engine (pull request #2110)
Feature/IO-3077 import rules engine
2025-02-11 18:52:08 +00:00
Patrick Fic
40aca91c76 IO-3077 Move parts scan order to correctly update totals. 2025-02-11 10:51:26 -08:00
Dave Richer
72305f91d8 feature/IO-3096-GlobalNotifications - Checkpoint 2025-02-11 13:38:15 -05:00
Dave Richer
abe4f4fb3d feature/IO-3077-import-rules-engine - Fix Translations 2025-02-11 12:34:28 -05:00
Dave Richer
142617bc3d feature/IO-3096-GlobalNotifications - Check-point 2025-02-11 12:33:13 -05:00
Dave Richer
2ee582bfa2 feature/IO-3096-GlobalNotifications - Check-point 2025-02-11 10:40:57 -05:00
Patrick Fic
35a3726cf0 IO-3077 Implement import rules engine. 2025-02-10 14:24:50 -08:00
Dave Richer
54820fe3c8 feature/IO-3096-GlobalNotifications - Check-point 2025-02-10 17:15:53 -05:00
Dave Richer
b1ffbe0e12 feature/IO-3096-GlobalNotifications - Check-point 2025-02-10 15:19:41 -05:00
Dave Richer
ba2d03176f feature/IO-3096-GlobalNotifications - Check-point 2025-02-10 11:24:20 -05:00
Patrick Fic
95a592fb9a Merged in feature/IO-3127-Dashboard-Schedule-Translations (pull request #2106)
IO-3127 Dashboard Schedule Translations

Approved-by: Dave Richer
2025-02-10 14:44:02 +00:00
Dave Richer
6d343e9b7f feature/IO-3096-GlobalNotifications - Watchers - Third version, final. 2025-02-06 17:35:12 -05:00
Dave Richer
c27b1d802f feature/IO-3096-GlobalNotifications - Watchers - Second Version 2025-02-06 16:57:55 -05:00
Dave Richer
f11d9dd804 feature/IO-3096-GlobalNotifications - Watchers - First revision. 2025-02-06 15:03:07 -05:00
Dave Richer
996f5b3c71 feature/IO-3096-GlobalNotifications - Global Notification Settings on profile page 2025-02-06 13:38:15 -05:00
Dave Richer
9bb7f647a7 feature/IO-3096-GlobalNotifications - Global Notification Settings on profile page 2025-02-06 13:36:19 -05:00
Dave Richer
760f2ac7f9 hotfix/IO-3128-Unread-Messages-Not-Updating - Initial fix just to make sure clients see messages, will poll and update every 60 seconds if the chat window is closed and has never been opened. 2025-02-06 12:49:51 -05:00
Allan Carr
872e36a61a Merged in hotfix/2025-02-06 (pull request #2108)
IO-3121 Adjust Footer
2025-02-06 16:33:52 +00:00
Allan Carr
779f608506 Merged in feature/IO-3121-Generic-Report-Header (pull request #2107)
IO-3121 Adjust Footer
2025-02-06 16:32:50 +00:00
Allan Carr
d9f562faa4 IO-3121 Adjust Footer
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-02-06 08:32:52 -08:00
Patrick Fic
14e362ec3f Merged in release/2025-01-31 (pull request #2105)
Release/2025 01 31 - IO-1582, IO-2676, IO-2681, IO-2825, IO-2952, IO-2970, IO-3074, IO-3075, IO-3076, IO-3096, IO-3101, IO-3103, IO-3114, IO-3115, IO-3116, IO-3121, IO-3123
2025-02-06 04:01:53 +00:00
Patrick Fic
c213e13624 Resolve CI issues. 2025-02-05 20:00:48 -08:00
Patrick Fic
dae7642a8c Merged in release/2025-01-31 (pull request #2104)
Release/2025 01 31 - IO-1582, IO-2676, IO-2681, IO-2825, IO-2952, IO-2970, IO-3074, IO-3075, IO-3076, IO-3096, IO-3101, IO-3103, IO-3114, IO-3115, IO-3116, IO-3121, IO-3123
2025-02-06 03:56:56 +00:00
Allan Carr
c751f0cba4 IO-3127 Dashboard Schedule Translations
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-02-05 15:10:18 -08:00
Allan Carr
e128c108f8 Merged in feature/IO-3121-Generic-Report-Header (pull request #2102)
IO-3121 Generic Report Header

Approved-by: Dave Richer
2025-02-05 15:18:45 +00:00
Allan Carr
b8b76cb96c IO-3121 Generic Report Header
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-02-04 18:11:48 -08:00
Allan Carr
fa958cbbfe IO-3121 Generic Report Header
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-02-04 17:42:40 -08:00
Dave Richer
2146672916 release/2025-01-31 - fix teams icon 2025-02-04 13:47:58 -05:00
Dave Richer
f96460f332 Merged in feature/IO-2825-Node-22-Update (pull request #2092)
[DO NOT MERGE] Feature/IO-2825 Node 22 Update

Approved-by: Patrick Fic
2025-02-04 17:54:06 +00:00
Dave Richer
04c70876d0 Merged release/2025-01-31 into feature/IO-2825-Node-22-Update 2025-02-04 17:53:52 +00:00
Dave Richer
bc6a94eede Merged in feature/IO-3123-Code-Review-Adjustments (pull request #2099)
feature/IO-3123-Code-Review-Adjustments: Make Code review adjustments
2025-02-04 17:53:36 +00:00
Dave Richer
f288b0ee22 feature/IO-3123-Code-Review-Adjustments: Make Code review adjustments 2025-02-04 12:28:22 -05:00
Patrick Fic
e54692928b Merged in feature/IO-3076-report-trigger (pull request #2098)
IO-3076 Add cron trigger for RO usage report.

Approved-by: Patrick Fic
2025-02-04 16:28:55 +00:00
Patrick Fic
0fd8bcb1b1 IO-3076 Add cron trigger for RO usage report. 2025-02-04 08:28:06 -08:00
Dave Richer
07b18836f5 feature/IO-2825-Node-22-Update: Fix Header styling 2025-02-03 16:11:14 -05:00
Dave Richer
ff08d19d79 Merged release/2025-01-31 into feature/IO-2825-Node-22-Update 2025-02-03 16:46:01 +00:00
Dave Richer
bd6f300c8d Merged in feature/IO-2970-Production-Board-Unassigned-Filter (pull request #2096)
feature/IO-2970-Production-Board-Unassigned-Filter - Implementation
2025-01-31 18:24:50 +00:00
Dave Richer
ac2fbaf6f7 feature/IO-2970-Production-Board-Unassigned-Filter - Implementation 2025-01-31 13:23:36 -05:00
Allan Carr
f409acc7fd Merged in feature/IO-3116-Production-Flag-Translation (pull request #2093)
IO-3116 Production Flag Translation

Approved-by: Dave Richer
2025-01-31 15:59:15 +00:00
Allan Carr
06dcb20b2b Merged in feature/IO-3074-Mark-as-PST-Exempt-Job-Create (pull request #2094)
IO-3074 Mark as PST Exempt in Manaul Job Creation

Approved-by: Dave Richer
2025-01-31 15:58:42 +00:00
Allan Carr
f4fed0db9d IO-3074 Mark as PST Exempt in Manaul Job Creation
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-30 15:25:39 -08:00
Allan Carr
8430f500ef IO-3116 Production Flag Translation
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-30 14:30:47 -08:00
Dave Richer
68584243f4 Merge remote-tracking branch 'origin/release/2025-01-31' into feature/IO-2825-Node-22-Update 2025-01-30 15:37:37 -05:00
Dave Richer
c8f5c3ed9e release/2025-01-31 - Fix unused import 2025-01-30 15:36:47 -05:00
Dave Richer
994d7e17aa feature/IO-2825-Node-22-Update - Package Updates 2025-01-30 15:36:05 -05:00
Dave Richer
fd1dd6dddd Merge remote-tracking branch 'origin/release/2025-01-31' into feature/IO-2825-Node-22-Update 2025-01-30 15:32:31 -05:00
Dave Richer
1e9b82ba1e feature/IO-2825-Node-22-Update - Merge release 2025-01-30 15:32:11 -05:00
Dave Richer
312795618e Merged in feature/IO-2681-Share-To-Teams-Button (pull request #2090)
Feature/IO-2681 Share To Teams Button
2025-01-30 20:17:24 +00:00
Dave Richer
35b5645d6f feature/IO-2681-Share-To-Teams-Button - Missing translation 2025-01-30 15:16:56 -05:00
Dave Richer
a49d845f50 feature/IO-2681-Share-To-Teams-Button - Merge release 2025-01-30 15:13:48 -05:00
Dave Richer
9d44540ca8 feature/IO-2681-Share-To-Teams-Button - Final revisions. 2025-01-30 15:06:52 -05:00
Allan Carr
cc95d3bd44 Merged in feature/IO-3115-Print-Center-on-Job-Close (pull request #2088)
IO-3115 Print Center on Job Close

Approved-by: Dave Richer
2025-01-30 17:12:11 +00:00
Allan Carr
648c47cde2 IO-3115 Change Icon to internal button prop
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-30 09:12:58 -08:00
Allan Carr
17cf6e7696 Merged in feature/IO-1582-Temp-Docs-to-Exported-Files (pull request #2087)
IO-1582 Temp Docs to Exported/Invoiced Files

Approved-by: Dave Richer
2025-01-30 16:42:54 +00:00
Allan Carr
7326ffbae6 Merged in feature/IO-3114-Quick-Intake (pull request #2086)
Feature/IO-3114 Quick Intake

Approved-by: Dave Richer
2025-01-30 16:42:36 +00:00
Allan Carr
b2f73c4fba IO-3115 Print Center on Job Close
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-29 16:55:31 -08:00
Allan Carr
6628d43e12 IO-1582 Temp Docs to Exported/Invoiced Files
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-29 15:43:38 -08:00
Allan Carr
596132b2af Merge branch 'release/2025-01-31' into feature/IO-3114-Quick-Intake
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>

# Conflicts:
#	client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx
#	client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.toggle-production.jsx
2025-01-29 15:24:47 -08:00
Dave Richer
a064b8e07e feature/IO-2681-Share-To-Teams-Button - checkpoint 2025-01-29 18:19:34 -05:00
Allan Carr
a55102b0ae IO-3114 Quick Intake
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-29 15:16:20 -08:00
Allan Carr
9b75993ac1 IO-3114 Quick Intake
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-29 15:14:03 -08:00
Allan Carr
d5e750c1f0 IO-3114 Quick Intake Data
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-29 15:12:20 -08:00
Allan Carr
8801990d4a Merged in feature/IO-3075-Crisp-in-ROME (pull request #2085)
IO-3075 Crisp in Rome Online

Approved-by: Dave Richer
2025-01-29 21:39:21 +00:00
Allan Carr
e8cda88a33 IO-3075 Crisp in Rome Online
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-28 16:17:11 -08:00
Allan Carr
a240391a28 Merged in feature/IO-2676-Target-Date-to-Schedule-Completion-Translation (pull request #2083)
IO-2676 Target Date to Schedule Completion Translation Adjustment

Approved-by: Dave Richer
2025-01-27 18:10:17 +00:00
Dave Richer
42660a7dd1 release/2025-01-31 - Add ID to tasks upsert modal title 2025-01-27 11:05:42 -05:00
Allan Carr
f186d9f8be IO-2676 Target Date to Schedule Completion Translation Adjustment
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-24 14:07:09 -08:00
Allan Carr
71a74c5437 Merged in hotfix/2025-01-23 (pull request #2082)
Hotfix/2025 01 23
2025-01-23 23:21:28 +00:00
Allan Carr
6fe4d982f5 Merged in feature/IO-3108-Job-Totals-USA-PASL (pull request #2081)
Feature/IO-3108 Job Totals USA PASL
2025-01-23 23:20:44 +00:00
Allan Carr
5ec032d8d6 IO-3108 Remove Console Log
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-23 15:21:10 -08:00
Allan Carr
3f58f9a5f5 Merged in feature/IO-3108-Job-Totals-USA-PASL (pull request #2080)
Feature/IO-3108 Job Totals USA PASL
2025-01-23 23:20:17 +00:00
Allan Carr
2718a66fb0 IO-3108 Adjust Initial Values/FieldValues
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-23 15:19:33 -08:00
Allan Carr
4c737371e3 IO-3108 Adjust Initial Values
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-23 14:49:51 -08:00
Dave Richer
ee7a3d0bdf Merged in hotfix/2025-01-23 (pull request #2079)
Hotfix/2025 01 23
2025-01-23 21:01:43 +00:00
Allan Carr
181af581e5 Merged in feature/IO-3108-Job-Totals-USA-PASL (pull request #2078)
IO-3108 Job Totals USA PASL

Approved-by: Dave Richer
2025-01-23 21:00:43 +00:00
Dave Richer
85fcd64220 release/2025-01-31 - Manual Merge conflict done 2025-01-23 13:00:13 -08:00
Dave Richer
11e2f5d83d feature/IO-3108-Job-Totals-USA-PASL - Fix submit button for Product Fruits reasons, to go into hotfix 2025-01-23 12:57:10 -08:00
Allan Carr
cbc723fa38 IO-3108 Job Totals USA PASL
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-23 12:05:35 -08:00
Dave Richer
da41668b3f feature/IO-3096-Notification-Preferences - Update Circle CI to Node 22 2025-01-22 10:56:53 -08:00
Dave Richer
df008abec9 Merge remote-tracking branch 'origin/master-AIO' into feature/IO-3096-Global-Notification-Preferences 2025-01-22 10:53:42 -08:00
Dave Richer
8a97c5109f Merged in feature/IO-3103-Ant5-Notifications (pull request #2075)
feature/IO-3103-Ant5-Notifications - Job Icons fixed (spacing)
2025-01-22 18:48:12 +00:00
Dave Richer
d767302c4a feature/IO-3103-Ant5-Notifications - Job Icons fixed (spacing) 2025-01-22 10:47:44 -08:00
Dave Richer
2fdb06fabe Merged in feature/IO-3103-Ant5-Notifications (pull request #2071)
feature/IO-3103-Ant5-Notifications
2025-01-22 18:11:05 +00:00
Dave Richer
32bb04939f feature/IO-3103-Ant5-Notifications - Bill Lines Fix 2025-01-22 09:59:57 -08:00
Dave Richer
9cddc9cce0 feature/IO-3103-Ant5-Notifications - Bill Lines Fix 2025-01-22 09:30:27 -08:00
Allan Carr
95c310119f Merged in hotfix/2025-01-22 (pull request #2073)
IO-3099 check for intellipay initialization before calling. rename files to remove erroneous period.
2025-01-22 16:52:28 +00:00
Allan Carr
ebe1facbd1 Merged in feature/IO-3099-wait-for-intellipay (pull request #2072)
IO-3099 check for intellipay initialization before calling. rename files to remove erroneous period.
2025-01-22 16:50:08 +00:00
Dave Richer
ed023cd62a feature/IO-3103-Ant5-Notifications - Missing Deps on UseDep 2025-01-21 18:19:32 -08:00
Dave Richer
b1ca423a59 feature/IO-3103-Ant5-Notifications - Missing Dep on UseDep 2025-01-21 18:16:20 -08:00
Dave Richer
85d25862eb feature/IO-3103-Ant5-Notifications 2025-01-21 17:20:46 -08:00
Allan Carr
b8c56c5c24 Merged in feature/IO-2952-RBAC-Defaults (pull request #2070)
IO-2952 RBAC Defaults

Approved-by: Dave Richer
2025-01-20 23:26:23 +00:00
Patrick Fic
276771a8b7 Merged in feature/IO-3099-wait-for-intellipay (pull request #2069)
IO-3099 check for intellipay initialization before calling. rename files to remove erroneous period.

Approved-by: Dave Richer
2025-01-20 23:25:53 +00:00
Allan Carr
b2239351f6 IO-2952 RBAC Defaults
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-20 15:11:13 -08:00
Patrick Fic
b021992552 IO-3099 check for intellipay initialization before calling. rename files to remove erroneous period. 2025-01-20 12:16:24 -08:00
Patrick Fic
f5be07d028 Merged in feature/IO-3101-default-notification-hasura (pull request #2068)
IO-3101 Update default value for notification settings.

Approved-by: Patrick Fic
2025-01-20 17:50:38 +00:00
Patrick Fic
1202b86529 IO-3101 Update default value for notification settings. 2025-01-20 09:45:42 -08:00
Dave Richer
29c99f2dd9 feature/IO-3096-Global-Notification-Preferences - Upgrade Node to 22 / Remove canvas and replace it 100% with canvas-skia 2025-01-20 09:02:55 -08:00
Dave Richer
3033e84f45 Merge remote-tracking branch 'origin/master-AIO' into feature/IO-3096-Global-Notification-Preferences 2025-01-20 08:33:31 -08:00
Dave Richer
0e218abbf4 Merged in release/2025-01-17 (pull request #2067)
Release/2025 01 17 into master-AIO - IO-999 IO-1927 IO-2951 IO-3022 IO-3060 IO-3063 IO-3065 IO-3076 IO-3078 IO-3080 IO-3082 IO-3083 IO-3094 IO-3096
2025-01-18 04:04:26 +00:00
Dave Richer
0cf7961d7d Merged in hotfix/AdditionalProductFruitIds (pull request #2066)
hotfix/AdditionalProductFruitsIds - Add additional IDs for product fruits
2025-01-17 18:15:56 +00:00
Dave Richer
ca02937461 Merged in hotfix/AdditionalProductFruitIds (pull request #2064)
hotfix/AdditionalProductFruitsIds - Add additional IDs for product fruits
2025-01-17 18:14:26 +00:00
Dave Richer
fa7e0a107b hotfix/AdditionalProductFruitsIds - Add additional IDs for product fruits 2025-01-17 10:13:41 -08:00
Allan Carr
9ccffd73ba Merged in feature/IO-999-Part-Tax-rate-Label (pull request #2062)
IO-999 Part Tax Rate Label

Approved-by: Dave Richer
2025-01-17 17:53:05 +00:00
Dave Richer
f68ad181e4 feature/IO-999-Part-Tax-rate-Label 2025-01-17 09:52:35 -08:00
Dave Richer
23bd6085a8 feature/IO-3096-Global-Notifications-Preferences
-  Package Updates
2025-01-17 09:51:55 -08:00
Dave Richer
18966476e4 feature/IO-3096-Global-Notifications-Preferences
-  Package Updates
2025-01-17 09:26:30 -08:00
Allan Carr
e4325e39bf Merged in feature/IO-2951-Ro-Guard-Labor-Warning (pull request #2061)
IO-2951 RO Guard Labor Warning

Approved-by: Dave Richer
2025-01-17 15:32:51 +00:00
Allan Carr
584c2e5de2 IO-999 Part Tax Rate Label
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-16 18:39:41 -08:00
Allan Carr
eccc992cfa IO-2951 RO Guard Labor Warning
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-16 18:28:54 -08:00
Allan Carr
f293e80d0d Merged in feature/IO-3063-LOU-on-Schedule-PopOver (pull request #2059)
IO-3063 LOU on Schedule PopOver

Approved-by: Dave Richer
2025-01-16 15:23:59 +00:00
Allan Carr
eea2a758b0 IO-3063 LOU on Schedule PopOver
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-15 17:14:08 -08:00
Allan Carr
8d7d4ab4ac Merged in feature/IO-3083-i18-Translation-Shop-Info-Warning (pull request #2044)
IO-3083 i18 Translation Warning in Shop Info

Approved-by: Dave Richer
2025-01-15 15:49:37 +00:00
Dave Richer
f9105806ba feature/IO-3083-i18-Translation-Shop-Info-Warning
resolve conflicts
2025-01-15 07:49:19 -08:00
Dave Richer
acd278f5b4 Merged in release/2025-01-17 (pull request #2057)
Release/2025 01 17 IO-3065, IO-3076, IO-3094
2025-01-15 15:40:44 +00:00
Allan Carr
a4a6fac224 Merged in feature/IO-3094-Purchases-by-Date-Excel (pull request #2056)
IO-3094 Purchases by Date - Excel Report

Approved-by: Dave Richer
2025-01-15 15:39:12 +00:00
Patrick Fic
b2b7064007 Merged in feature/IO-3065-0-dollar-parts-status (pull request #2055)
feature/IO-3065-0-dollar-parts-status

Approved-by: Dave Richer
2025-01-15 15:38:42 +00:00
Allan Carr
4a56fbb135 IO-3094 Purchases by Date - Excel Report
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-14 18:00:46 -08:00
Allan Carr
e1fcb0ecba IO-3083 Merge Conflit Resolution
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-14 17:54:12 -08:00
Allan Carr
ee5e091118 Merge branch 'release/2025-01-17' into feature/IO-3083-i18-Translation-Shop-Info-Warning
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>

# Conflicts:
#	client/src/translations/en_us/common.json
2025-01-14 17:48:10 -08:00
Patrick Fic
9f46f8ec31 IO-3065 All manual toggle to include $0 line in part status count. 2025-01-14 13:49:38 -08:00
Patrick Fic
8c737ff0ae Merged in feature/IO-3076-daily-usage-reports (pull request #2054)
feature/IO-3076-daily-usage-reports

Approved-by: Patrick Fic
2025-01-14 21:14:13 +00:00
Patrick Fic
a8ef681cf1 IO-3076 Adjust daily usage report window. 2025-01-14 13:13:09 -08:00
Dave Richer
494c8b6867 Merged in release/2025-01-17 (pull request #2053)
Release/2025 01 17 into test-AIO - IO-1927, IO-3022, IO-3060, IO-3078, IO-3080, IO-3082
2025-01-14 17:02:26 +00:00
Dave Richer
262b5600d8 Merged in feature/IO-3060-Realtime-Notification-System (pull request #2052)
feature/IO-3060-Realtime-Notifications- Checkpoint
2025-01-14 17:01:20 +00:00
Dave Richer
a06d3c9365 feature/IO-3060-Realtime-Notifications- Checkpoint 2025-01-14 09:00:04 -08:00
Allan Carr
1861bd68d1 Merged in feature/IO-3080-Restrict-Claimable-Hours-Label (pull request #2042)
IO-3080 Restrict Claimable Hours Label

Approved-by: Dave Richer
2025-01-14 14:43:12 +00:00
Allan Carr
348561c812 Merged in feature/IO-3078-Job-Presets-Company-Setup-Markup-Rule (pull request #2043)
IO-3078 Jobs Presets Company Setup Markup Discount

Approved-by: Dave Richer
2025-01-14 14:42:59 +00:00
Allan Carr
bf4a52b3c1 Merged in feature/IO-3022-Export-Payments-Payment-Methods (pull request #2045)
IO-3022 Export Payments - Payment Method

Approved-by: Dave Richer
2025-01-14 14:42:34 +00:00
Allan Carr
1950023f37 Merged in feature/IO-3082-Additional-IO-Basic-Lock-Out-Reports (pull request #2041)
IO-3082 Additional IO Basic Lock Out Reports

Approved-by: Dave Richer
2025-01-14 14:42:17 +00:00
Allan Carr
a2798a02b3 Merged in feature/IO-1927-Mark-Exported-Primary (pull request #2046)
IO-1927 Export Button as Primary

Approved-by: Dave Richer
2025-01-14 14:41:54 +00:00
Dave Richer
5fcb5a3a3e Merged in release/2025-01-17 (pull request #2051)
Release/2025 01 17
2025-01-14 01:44:03 +00:00
Dave Richer
ba41b29538 Merged in feature/IO-3060-Realtime-Notification-System (pull request #2050)
Feature/IO-3060 Realtime Notification System
2025-01-14 01:42:46 +00:00
Dave Richer
8a0916a47f feature/IO-3060-Realtime-Notifications- Checkpoint 2025-01-13 07:27:10 -08:00
Patrick Fic
d187ed6f73 Merged in release/2025-01-10 (pull request #2049)
Release/2025 01 10
2025-01-10 22:03:04 +00:00
Patrick Fic
13a57406d9 Merged in release/2025-01-10 (pull request #2048)
Release/2025 01 10
2025-01-10 20:06:28 +00:00
Patrick Fic
68c1ac3e70 Merged in feature/IO-3076-daily-usage-reports (pull request #2047)
Feature/IO-3076 daily usage reports

Approved-by: Dave Richer
2025-01-10 19:47:37 +00:00
Patrick Fic
2f267a9f2c IO-3076 updates to usage report. 2025-01-10 11:39:18 -08:00
Dave Richer
3bc6504ae6 feature/IO-3060-Realtime-Notifications-Progress Update 2025-01-10 09:33:47 -08:00
Allan Carr
c7f293ceca IO-1927 Export Button as Primary
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-09 19:28:28 -08:00
Allan Carr
66e60e96ad IO-3022 Export Payments - Payment Method
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-09 19:16:45 -08:00
Allan Carr
54a9beb37f IO-3083 i18 Translation Warning in Shop Info
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-09 19:00:23 -08:00
Allan Carr
779cc7d9e8 IO-3078 Jobs Presets Company Setup Markup Discount
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-09 18:57:21 -08:00
Allan Carr
c1b3df9c3b IO-3080 Restrict Claimable Hours Label
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-09 17:43:43 -08:00
Allan Carr
80379cdd79 IO-3082 Additional IO Basic Lock Out Reports
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2025-01-09 17:37:30 -08:00
Dave Richer
e2e5f3f885 feature/IO-3060-Realtime-Notifications-System
- Add handlers for Job and Bill Change / Register Routers
- Add Tables / Modify Tables / Add permissions.
2025-01-09 13:28:56 -08:00
Patrick Fic
d6fbf02092 IO-3076 Initial usage reports design. 2025-01-09 11:22:08 -08:00
Patrick Fic
7a88dd1aae Release/2025 01 10 IO-3069 IO-3067 IO-3070 2025-01-08 14:16:41 -08:00
Patrick Fic
91c3ac56fa Merged in release/2025-01-10 (pull request #2039)
Release/2025 01 10
2025-01-08 18:39:00 +00:00
Patrick Fic
521aa81591 Merged in feature/IO-3067-implement-learn-more-link-for-rome-upsells (pull request #2038)
Feature/IO-3067 implement learn more link for rome upsells
2025-01-08 17:52:41 +00:00
Patrick Fic
d70fee6125 IO-3067 clean up unused imports. 2025-01-08 09:51:52 -08:00
Patrick Fic
7d21cb7d70 Merged in feature/IO-3067-implement-learn-more-link-for-rome-upsells (pull request #2037)
Revert "IO-3067 Add learn more link for Rome."
2025-01-07 18:24:52 +00:00
Patrick Fic
1a8fad26e5 IO-3067 Correct Rome Learn More Link. 2025-01-06 16:09:00 -08:00
Patrick Fic
d69050f006 Revert "IO-3067 Add learn more link for Rome."
This reverts commit c4f7c57c24.
2025-01-06 15:58:56 -08:00
Allan Carr
abe1e80844 Merged in feature/IO-3070-Enter-Bills-Header-Missing-Translation (pull request #2033)
IO-3070 Enter Bills Header Missing Translation

Approved-by: Dave Richer
2025-01-02 16:10:16 +00:00
Allan Carr
58e897db31 Merged in feature/IO-3069-Job-Drawer-Documents-Upsell (pull request #2032)
IO-3069 Job Drawer Documents Upsell correction

Approved-by: Dave Richer
2025-01-02 16:09:59 +00:00
Patrick Fic
b7ed6734a0 Merged in revert/revert-pr-2034 (pull request #2036)
Revert "Feature/IO-3067 implement learn more link for rome upsells (pull request #2034)"
2025-01-02 16:08:29 +00:00
Patrick Fic
7d5a866a5c include intellipay. 2025-01-02 08:07:01 -08:00
Patrick Fic
23becf6494 Revert "Feature/IO-3067 implement learn more link for rome upsells (pull request #2034)" 2025-01-02 16:02:14 +00:00
Patrick Fic
64ee2c1526 Merged in feature/IO-3067-implement-learn-more-link-for-rome-upsells (pull request #2035)
IO-3067 Add learn more link for Rome.
2025-01-01 23:17:26 +00:00
Patrick Fic
c033c0fbc5 Merged in feature/IO-3067-implement-learn-more-link-for-rome-upsells (pull request #2034)
Feature/IO-3067 implement learn more link for rome upsells
2025-01-01 23:09:58 +00:00
Allan Carr
f8ddfeb7d0 IO-3070 Enter Bills Header Missing Translation
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-12-27 10:03:51 -08:00
Allan Carr
bc42d19dff IO-3069 Job Drawer Documents Upsell correction
Would constantly display the upsell component

Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-12-27 10:01:11 -08:00
Patrick Fic
c4f7c57c24 IO-3067 Add learn more link for Rome. 2024-12-20 09:01:51 -08:00
Patrick Fic
c0bf829dc0 Merged in hotfix/IO-3056-intellipay-logging (pull request #2031)
IO-3056 resolve logging issue for intellipay.
2024-12-16 21:17:03 +00:00
Patrick Fic
51cd61c932 IO-3056 resolve logging issue for intellipay. 2024-12-16 13:16:13 -08:00
Allan Carr
4ab77de591 Merged in hotfix/IO-3020-smart-scheduling-upsell (pull request #2030)
IO-3020 Fix PrintCenter Upsell restrictions
2024-12-16 20:56:40 +00:00
Allan Carr
acc6633271 Merged in hotfix/IO-3020-smart-scheduling-upsell (pull request #2029)
IO-3020 Fix PrintCenter Upsell restrictions

Approved-by: Patrick Fic
2024-12-16 20:50:51 +00:00
Allan Carr
2336617077 IO-3020 Fix PrintCenter Upsell restrictions
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-12-16 12:42:21 -08:00
Patrick Fic
836e9b846a Merged in hotfix/IO-3020-smart-scheduling-upsell (pull request #2028)
IO-3020 Resolve smart scheduling upsell displays when they shouldn't.
2024-12-16 18:29:51 +00:00
Patrick Fic
897efde14d Merged in hotfix/IO-3020-smart-scheduling-upsell (pull request #2027)
IO-3020 Resolve smart scheduling upsell displays when they shouldn't.
2024-12-16 18:26:55 +00:00
Patrick Fic
98f7147378 IO-3020 Resolve smart scheduling upsell displays when they shouldn't. 2024-12-16 10:26:03 -08:00
Patrick Fic
fd01746f7d Merged in hotfix/IO-3001-null-cieca-scrubbing (pull request #2026)
Hotfix/IO-3001 null cieca scrubbing
2024-12-16 16:33:42 +00:00
Patrick Fic
54b8f564e4 Merged in hotfix/IO-3001-null-cieca-scrubbing (pull request #2025)
IO-3001 Add CIECA data check for scrubbing.
2024-12-16 16:07:15 +00:00
Patrick Fic
591284c972 IO-3001 Add CIECA data check for scrubbing. 2024-12-16 08:06:39 -08:00
Dave Richer
9e0dae2adf Merged in release/2024-12-13 (pull request #2023)
[DO NOT MERGE] Release/2024-12-13 into master-AIO - IO-2968, IO-3020, IO-3036, IO-3056, IO-3096
2024-12-14 04:35:30 +00:00
Allan Carr
4155203e88 Merged in feature/IO-3059-Kaizen-Datapump-Addition (pull request #2024)
IO-3059 Kaizen Datapump Additional Shop
2024-12-13 19:01:26 +00:00
Allan Carr
24a92e69f2 IO-3059 Kaizen Datapump Additional Shop
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-12-13 11:00:04 -08:00
Patrick Fic
4ec171d93b Merged in release/2024-12-13 (pull request #2022)
IO-3020 IO-3036 Remove Audit and Lifecycle feature wraps.
2024-12-13 16:28:53 +00:00
Patrick Fic
c9cd4c51e8 Merged in feature/IO-3020-IO-3036-imex-lite-rome-lite (pull request #2021)
IO-3020 IO-3036 Remove Audit and Lifecycle feature wraps.
2024-12-13 16:28:32 +00:00
Patrick Fic
e0f4b6daf2 IO-3020 IO-3036 Remove Audit and Lifecycle feature wraps. 2024-12-13 08:27:54 -08:00
Dave Richer
608988c67c Merged in release/2024-12-13 (pull request #2020)
feature/IO-3056-Enhanced-Lightbox-Logging
2024-12-12 21:16:07 +00:00
Dave Richer
9f6854c87b Merged in feature/IO-3056-Enhanced-Lightbox-Logging (pull request #2019)
feature/IO-3056-Enhanced-Lightbox-Logging
2024-12-12 21:15:23 +00:00
Dave Richer
8cee795d70 feature/IO-3056-Enhanced-Lightbox-Logging 2024-12-12 13:12:47 -08:00
Patrick Fic
8da4d0b0f1 Merged in release/2024-12-13 (pull request #2018)
IO-3020 IO-3036 Resolve lock wrapper on payroll allocations.
2024-12-12 20:43:04 +00:00
Patrick Fic
75ef93f0e2 Merged in feature/IO-3020-IO-3036-imex-lite-rome-lite (pull request #2017)
IO-3020 IO-3036 Resolve lock wrapper on payroll allocations.
2024-12-12 20:42:41 +00:00
Patrick Fic
c0dc5f50e3 IO-3020 IO-3036 Resolve lock wrapper on payroll allocations. 2024-12-12 12:42:10 -08:00
Patrick Fic
a54668e030 Merged in release/2024-12-13 (pull request #2016)
Release/2024 12 13
2024-12-12 17:48:33 +00:00
Patrick Fic
53f0ec6c63 Merged in feature/IO-3020-IO-3036-imex-lite-rome-lite (pull request #2015)
IO-3020 IO-3036 Remove date restriction and lock down feature based reports.

Approved-by: Patrick Fic
2024-12-12 17:47:32 +00:00
Patrick Fic
af03a1b4e3 IO-3020 IO-3036 Remove date restriction and lock down feature based reports. 2024-12-12 09:46:01 -08:00
Dave Richer
f645498743 Merged in feature/IO-3056-Enhanced-Lightbox-Logging (pull request #2014)
Feature/IO-3056 Enhanced Lightbox Logging

Approved-by: Patrick Fic
2024-12-12 15:59:54 +00:00
Dave Richer
b3c948f0c7 feature/IO-3056-Enhanced-Lightbox-Logging 2024-12-11 12:08:29 -08:00
Dave Richer
b955eb01b4 feature/IO-3056-Enhanced-Lightbox-Logging 2024-12-11 12:02:27 -08:00
Dave Richer
39640d254a feature/IO-3056-Enhanced-Lightbox-Logging 2024-12-11 12:00:02 -08:00
Dave Richer
2386457cf5 Merged in release/2024-12-13 (pull request #2013)
release/2024-12-13 into test-AIO - IO-2968
2024-12-11 18:26:57 +00:00
Dave Richer
206257ed3b release/2024-12-13: Merge in Rome Lite Branch 2024-12-11 10:26:06 -08:00
Patrick Fic
45944ae8c9 Merged in feature/IO-3020-IO-3036-imex-lite-rome-lite (pull request #2012)
feature/IO-3020-IO-3036-imex-lite-rome-lite

Approved-by: Patrick Fic
2024-12-11 17:45:25 +00:00
Patrick Fic
53d15b0d45 IO-3020 IO-3036 Resolve identified bugs. 2024-12-11 09:44:18 -08:00
Patrick Fic
a630fc5556 IO-3020 IO-3036 Update git attributes file. 2024-12-11 09:07:52 -08:00
Dave Richer
532eb842b3 feature/IO-3056-Enhanced-Logging: Fix up git attributes 2024-12-11 09:04:33 -08:00
Dave Richer
d315617d87 Merged in feature/IO-2968-Parts-Scanning-Extension (pull request #2010)
feature/IO-2968-Parts-Scanning-Extension
2024-12-11 15:41:30 +00:00
Patrick Fic
2c32a4891b Merged in feature/IO-3020-IO-3036-imex-lite-rome-lite (pull request #2011)
feature/IO-3020-IO-3036-imex-lite-rome-lite

Approved-by: Patrick Fic
2024-12-10 21:23:37 +00:00
Patrick Fic
d869dbe97b IO-3020 IO-3036 Transition enum to function to render correctly. 2024-12-10 13:23:07 -08:00
Dave Richer
1ece04ed3e Merged release/2024-12-13 into feature/IO-2968-Parts-Scanning-Extension 2024-12-10 19:55:34 +00:00
Dave Richer
b8a298fc28 feature/IO-2968-Parts-Scanning-Extension 2024-12-10 11:15:24 -08:00
Patrick Fic
2b9fe61d79 Merged in feature/IO-3020-IO-3036-imex-lite-rome-lite (pull request #2009)
IO-3020 IO-3036 Correct masking issue.
2024-12-10 19:03:07 +00:00
Patrick Fic
7fdf109e14 IO-3020 IO-3036 Correct masking issue. 2024-12-10 11:02:00 -08:00
Patrick Fic
95751103a2 Merged in feature/IO-3020-IO-3036-imex-lite-rome-lite (pull request #2004)
Feature/IO-3020 IO 3036 ImEX Lite Rome Starter

Approved-by: Dave Richer
2024-12-10 17:49:56 +00:00
Patrick Fic
2209f49696 IO-3020 IO-3096 Additional cleanup. 2024-12-10 08:19:20 -08:00
Patrick Fic
c7a2c8209a IO-3020 IO-3036 Add additional upsell components. 2024-12-09 18:47:32 -08:00
Allan Carr
e1b00f5081 Merged in hotfix/2024-12-09 (pull request #2008)
IO-3050 Adjust Customer setup
2024-12-09 21:15:35 +00:00
Allan Carr
8ca4c5d7fa Merged in hotfix/2024-12-09 (pull request #2007)
IO-3050 Adjust Customer setup
2024-12-09 19:57:21 +00:00
Allan Carr
cfbf59cd48 Merged in feature/IO-3050-QBO-BillEmail (pull request #2006)
IO-3050 Adjust Customer setup
2024-12-09 19:56:44 +00:00
Allan Carr
6a09209659 IO-3050 Adjust Customer setup
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-12-09 11:00:49 -08:00
Dave Richer
962f471f0f Merge remote-tracking branch 'origin/test-AIO' into feature/IO-3020-IO-3036-imex-lite-rome-lite 2024-12-09 07:26:15 -08:00
Dave Richer
cec5f6e6e7 Merged in release/2024-12-06 (pull request #2005)
Release/2024 12 06 into master-AIO IO-3047 IO-3046 IO-3051 IO-3050 IO-3042 IO-3052
2024-12-07 04:46:43 +00:00
Dave Richer
82acaa35e1 Merged master-AIO into release/2024-12-06 2024-12-07 04:42:07 +00:00
Patrick Fic
cc7cea7139 IO-3020 IO-3036 Additional cleanup. 2024-12-06 15:13:56 -08:00
Patrick Fic
eaea73a955 IO-3020 IO-3036 Add upsell components to several components. Add upsell mask wrapper. 2024-12-06 14:24:03 -08:00
Patrick Fic
77e966dfe1 Merge branch 'release/2024-12-06' into feature/IO-3020-IO-3036-imex-lite-rome-lite 2024-12-06 11:00:00 -08:00
Patrick Fic
b052e97b73 IO-3020 IO-3036 Add basic upsell component and blur out reports. 2024-12-06 10:58:07 -08:00
Dave Richer
92a5c27da4 Merged in release/2024-12-06 (pull request #2003)
IO-3051 Replace inlince css with juice. into TEST-aio
2024-12-05 23:32:06 +00:00
Dave Richer
09b8a05b5a Merged in feature/IO-3051-canvas-handler-optimization (pull request #2002)
IO-3051 Replace inlince css with juice.
2024-12-05 23:31:44 +00:00
Patrick Fic
83a1952880 IO-3051 Replace inlince css with juice. 2024-12-05 15:30:37 -08:00
Dave Richer
9949d12317 Merged in release/2024-12-06 (pull request #2001)
Release/2024 12 06 into test-AIO - IO-3052 IO-3053
2024-12-05 21:07:41 +00:00
Dave Richer
e5d55f27b5 Merged in feature/IO-3052-Skia-Canvas-Handler (pull request #2000)
Feature/IO-3052 Skia Canvas Handler
2024-12-05 21:06:33 +00:00
Dave Richer
bfde72eed8 feature/IO-3052-Skia-Canvas-Handler: Fix missing checks
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-12-05 12:29:11 -08:00
Dave Richer
8fbd08d57f Merge branch 'feature/IO-3052-Skia-Canvas-Handler' of bitbucket.org:snaptsoft/bodyshop into feature/IO-3052-Skia-Canvas-Handler 2024-12-05 12:16:47 -08:00
Dave Richer
20bddb43b6 feature/IO-3052-Skia-Canvas-Handler: Fix missing checks
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-12-05 12:16:32 -08:00
Dave Richer
b38e0f611b Merged release/2024-12-06 into feature/IO-3052-Skia-Canvas-Handler 2024-12-05 20:14:53 +00:00
Dave Richer
c84fbcaba1 feature/IO-3052-Skia-Canvas-Handler: Optimizations
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-12-05 12:14:06 -08:00
Dave Richer
8f752d575a feature/IO-3052-Skia-Canvas-Handler: Optimizations
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-12-05 12:13:49 -08:00
Patrick Fic
2fe9ae513d Merged in feature/IO-3053-datadog (pull request #1999)
IO-3053 Add datadog watcher for Production and Test instances.
2024-12-05 20:10:24 +00:00
Patrick Fic
0001604552 Merged in feature/IO-3053-datadog (pull request #1998)
IO-3053 Add datadog watcher for Production and Test instances.
2024-12-05 20:09:26 +00:00
Patrick Fic
5cb93b1a2c IO-3053 Add datadog watcher for Production and Test instances. 2024-12-05 12:07:16 -08:00
Dave Richer
a04dcffc4c feature/IO-3052-Skia-Canvas-Handler: Merge release and fix PR's
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-12-05 12:01:58 -08:00
Dave Richer
50c99f7a1e feature/IO-3052-Skia-Canvas-Handler: Cleanup
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-12-05 11:52:14 -08:00
Dave Richer
86f3179bc0 feature/IO-3052-Skia-Canvas-Handler: Initial commit
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-12-05 11:26:36 -08:00
Dave Richer
6336e7568f feature/IO-3052-Skia-Canvas-Handler: Initial commit
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-12-05 11:26:23 -08:00
Dave Richer
2b9e0932bd Merged in release/2024-12-06 (pull request #1997)
Release/2024 12 06 into test-AIO IO-3051 IO-3050 IO-3042
2024-12-05 17:23:58 +00:00
Allan Carr
f0f199335c Merged in feature/IO-3050-QBO-BillEmail (pull request #1995)
IO-3050 QBO BillEmail required if NeedToSend

Approved-by: Dave Richer
2024-12-05 17:23:18 +00:00
Allan Carr
9c7c9f4b6d Merged in feature/IO-3042-Jobs-Marked-Total-Loss (pull request #1996)
IO-3042 Jobs Marked as Total Loss

Approved-by: Dave Richer
2024-12-05 17:23:01 +00:00
Allan Carr
9001ceaed8 Merged in feature/IO-3051-canvas-handler-optimization (pull request #1994)
IO-3051 canvas-handler optimization

Approved-by: Dave Richer
2024-12-05 17:22:42 +00:00
Allan Carr
ab82e85c57 Merge branch 'release/2024-12-06' into feature/IO-3042-Jobs-Marked-Total-Loss
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>

# Conflicts:
#	client/src/utils/TemplateConstants.js
2024-12-04 18:33:35 -08:00
Allan Carr
2effe5ef50 IO-3042 Jobs Marked as Total Loss
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-12-04 18:30:22 -08:00
Allan Carr
006a2a5dca IO-3050 QBO BillEmail required if NeedToSend
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-12-04 15:59:05 -08:00
Patrick Fic
43b1ad78a3 IO-3020 IO-3036 Additional blurred components. 2024-12-04 15:37:08 -08:00
Allan Carr
a885bdec74 IO-3051 canvas-handler optimization
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-12-04 14:22:04 -08:00
Patrick Fic
d9c9466953 Merge branch 'master-AIO' into feature/IO-3020-IO-3036-imex-lite-rome-lite 2024-12-04 12:58:23 -08:00
Patrick Fic
6b3fb00cc0 IO-3020 IO-3036 Extend blur wrapper, add lock wrapper to components throughout the system. Many placeholders still left for upsell components. 2024-12-04 11:51:54 -08:00
Dave Richer
8d2bdb171b Merged in feature/IO-3048-Fix-Job-Bug-Messaging (pull request #1986)
feature/IO-3048-Fix-Job-Bug-Messaging - Job Tag weirdness, Messaging Name  Display, Unread Messages
2024-12-03 23:51:54 +00:00
Dave Richer
3fc24677c5 Merged in release/2024-12-06 (pull request #1993)
feature/IO-3048-Fix-Job-Bug-Messaging - Unread count
2024-12-03 22:02:23 +00:00
Dave Richer
5d7eabbfa9 Merged in feature/IO-3048-Fix-Job-Bug-Messaging (pull request #1992)
feature/IO-3048-Fix-Job-Bug-Messaging - Unread count
2024-12-03 22:01:37 +00:00
Dave Richer
a2ada7d88e feature/IO-3048-Fix-Job-Bug-Messaging - Unread count
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-12-03 13:58:16 -08:00
Dave Richer
b741e29374 Merged in release/2024-12-06 (pull request #1991)
feature/IO-3048-Fix-Job-Bug-Messaging - Do not allow more than 1 of the same job to be associated with a conversation
2024-12-03 20:24:31 +00:00
Dave Richer
3a6af12446 Merged in feature/IO-3048-Fix-Job-Bug-Messaging (pull request #1990)
feature/IO-3048-Fix-Job-Bug-Messaging - Do not allow more than 1 of the same job to be associated with a conversation
2024-12-03 20:24:09 +00:00
Dave Richer
b490ab96be feature/IO-3048-Fix-Job-Bug-Messaging - Do not allow more than 1 of the same job to be associated with a conversation
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-12-03 12:17:11 -08:00
Dave Richer
08d50f90d6 Merged in release/2024-12-06 (pull request #1988)
feature/IO-3048-Fix-Job-Bug-Messaging - Do not allow more than 1 of the same job to be associated with a conversation
2024-12-03 18:41:31 +00:00
Dave Richer
ca462f51ec Merged in feature/IO-3048-Fix-Job-Bug-Messaging (pull request #1987)
feature/IO-3048-Fix-Job-Bug-Messaging - Do not allow more than 1 of the same job to be associated with a conversation
2024-12-03 18:40:29 +00:00
Dave Richer
44721019fa feature/IO-3048-Fix-Job-Bug-Messaging - Do not allow more than 1 of the same job to be associated with a conversation
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-12-03 10:39:14 -08:00
Dave Richer
29bbf4badb Merged in release/2024-12-06 (pull request #1985)
Release/2024 12 06 into test-AIO - IO-3047 IO-3046 IO-3048
2024-12-03 17:56:53 +00:00
Dave Richer
8ed81e9aed Merged in feature/IO-3048-Fix-Job-Bug-Messaging (pull request #1984)
feature/IO-3048-Fix-Job-Bug-Messaging - Fix tag weirdness and a vite error

Approved-by: Patrick Fic
2024-12-03 17:55:30 +00:00
Dave Richer
15ba2a1caf feature/IO-3048-Fix-Job-Bug-Messaging - Fix tag weirdness and a vite error
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-12-03 09:48:52 -08:00
Allan Carr
aad22f2e2d Merged in feature/IO-3047-accountingid-on-Owner-Page (pull request #1982)
IO-3047 Accounting ID on Owner Page

Approved-by: Dave Richer
2024-12-02 20:30:50 +00:00
Allan Carr
7a11b18037 Merged in feature/IO-3046-purchase_return_ratio_excel (pull request #1983)
IO-3046 purchase_return_ratio_excel

Approved-by: Dave Richer
2024-12-02 20:30:16 +00:00
Allan Carr
241322fa30 IO-3046 purchase_return_ratio_excel
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-12-02 11:09:30 -08:00
Allan Carr
f0461270de IO-3047 Accounting ID on Owner Page
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-12-02 08:52:18 -08:00
Dave Richer
11b906103a Merged in release/2024-11-22 (pull request #1977)
Release/2024-11-22  /  2024-11-29 - into master-AIO - IO-2920, IO-2921, IO-2959, IO-3000, IO-3001, IO-3037, IO-3040
2024-11-30 05:02:46 +00:00
Patrick Fic
c85a5eb208 IO-3020 IO-3036 Update job actions menu & improve feature wrapper/blur wrapper trace 2024-11-29 15:55:20 -08:00
Patrick Fic
801cd724ac IO-3020 IO-3036 Update ESLint. Add LockWrapper for Header. Add Blur Wrapper. 2024-11-29 14:38:56 -08:00
Patrick Fic
e7567fdaac Merged in release/2024-11-22 (pull request #1981)
IO-3001 Update job costing label for ttl_adjustment
2024-11-29 20:00:44 +00:00
Patrick Fic
3f006f431e Merged in feature/IO-3001-us-est-scrubbing (pull request #1980)
IO-3001 Update job costing label for ttl_adjustment
2024-11-29 19:56:47 +00:00
Patrick Fic
6f2b5e4c55 IO-3001 Update job costing label for ttl_adjustment 2024-11-29 11:56:18 -08:00
Patrick Fic
1dbfe24111 Merged in release/2024-11-22 (pull request #1979)
IO-3001 Add in adjustments to subtotal scrubbing.
2024-11-29 19:34:22 +00:00
Patrick Fic
50d7c5dace Merged in feature/IO-3001-us-est-scrubbing (pull request #1978)
IO-3001 Add in adjustments to subtotal scrubbing.
2024-11-29 19:34:01 +00:00
Patrick Fic
9ac27b6090 IO-3001 Add in adjustments to subtotal scrubbing. 2024-11-29 11:33:19 -08:00
Dave Richer
da2bec67bf Merged in release/2024-11-22 (pull request #1976)
feature/IO-3000-messaging-sockets-migration2 -
2024-11-29 16:58:32 +00:00
Dave Richer
51a1b48da9 Merge remote-tracking branch 'origin/feature/IO-3000-messaging-sockets-migrationv2' into release/2024-11-22 2024-11-28 12:27:39 -08:00
Dave Richer
648a9b8f64 feature/IO-3000-messaging-sockets-migration2 -
- Small change

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-28 12:27:06 -08:00
Dave Richer
f3d8ca5711 Merged in release/2024-11-22 (pull request #1975)
Release/2024 11 22 into test-AIO - IO-3000
2024-11-28 20:18:56 +00:00
Dave Richer
7402679091 Merged in feature/IO-3000-messaging-sockets-migrationv2 (pull request #1974)
Feature/IO-3000 messaging sockets migrationv2
2024-11-28 20:16:43 +00:00
Dave Richer
627174b7d3 feature/IO-3000-messaging-sockets-migration2 -
- Bring back subscription for fallback

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-28 12:14:35 -08:00
Patrick Fic
9fcc01aa9f IO-3000 FInal updates to firebase SW. 2024-11-28 12:11:30 -08:00
Patrick Fic
cb46ee5700 Merged in feature/IO-3000-messaging-sockets-migrationv2 (pull request #1973)
IO-3000 update firebase js version, and add back testing route.
2024-11-28 19:41:05 +00:00
Patrick Fic
299d838ab9 Merged in feature/IO-3000-messaging-sockets-migrationv2 (pull request #1972)
IO-3000 update firebase js version, and add back testing route.
2024-11-28 19:40:46 +00:00
Patrick Fic
43bf1fc8cf IO-3000 update firebase js version, and add back testing route. 2024-11-28 11:39:17 -08:00
Patrick Fic
e3340fe408 Merged in release/2024-11-22 (pull request #1971)
IO-3000 Add back FCM notification subscribe
2024-11-28 19:06:36 +00:00
Patrick Fic
73af18f287 Merged in feature/IO-3000-messaging-sockets-migrationv2 (pull request #1970)
IO-3000 Add back FCM notification subscribe
2024-11-28 19:06:17 +00:00
Patrick Fic
90f4977924 IO-3000 Add back FCM notification subscribe 2024-11-28 11:05:50 -08:00
Dave Richer
79a9b534f9 Merged in release/2024-11-22 (pull request #1969)
Release/2024 11 22 into test-AIO IO-3000
2024-11-28 18:02:46 +00:00
Dave Richer
c3b184d17b Merged in feature/IO-3000-messaging-sockets-migrationv2 (pull request #1968)
Feature/IO-3000 messaging sockets migrationv2
2024-11-28 18:02:13 +00:00
Dave Richer
db5740d487 feature/IO-3000-messaging-sockets-migration2 -
- Various work

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-28 09:57:35 -08:00
Dave Richer
08c0da1bed feature/IO-3000-messaging-sockets-migration2 -
- Various work

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-28 09:10:23 -08:00
Patrick Fic
9a49d1c69e Merged in release/2024-11-22 (pull request #1967)
Release/2024 11 22 - IO-3040 IO-3001
2024-11-28 15:57:01 +00:00
Allan Carr
4d35976241 Merged in feature/IO-3040-Report-Selector-Date-Range-Restriction (pull request #1965)
IO-3040 Report Selector Date Range Restriction for Prod

Approved-by: Patrick Fic
2024-11-28 15:56:25 +00:00
Allan Carr
5edbed3f0b Merged in feature/IO-3001-us-est-scrubbing (pull request #1966)
IO-3001 Correct Commenting of Button
2024-11-28 15:55:59 +00:00
Allan Carr
3d79be06de IO-3001 Correct Commenting of Button
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-27 18:02:28 -08:00
Allan Carr
fd9e7b4d4b IO-3040 Report Selector Date Range Restriction for Prod
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-27 16:24:10 -08:00
Dave Richer
352551e421 Merged in release/2024-11-22 (pull request #1964)
Release/2024 11 22
2024-11-27 22:10:10 +00:00
Dave Richer
2937a07379 Merged in feature/IO-3000-messaging-sockets-migrationv2 (pull request #1963)
feature/IO-3000-messaging-sockets-migration2 -
2024-11-27 22:09:27 +00:00
Dave Richer
ad1761096a feature/IO-3000-messaging-sockets-migration2 -
- found small thing

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-27 14:08:52 -08:00
Patrick Fic
6a7548d11b Merged in feature/IO-2920-cash-discounting (pull request #1962)
IO-2920 Rever test URL to correct value for intellipay.
2024-11-27 21:17:56 +00:00
Patrick Fic
affbb3f168 IO-2920 Rever test URL to correct value for intellipay. 2024-11-27 13:15:03 -08:00
Dave Richer
bf5c61bd86 Merged in release/2024-11-22 (pull request #1961)
Release/2024 11 22
2024-11-27 19:37:03 +00:00
Dave Richer
0522747b49 Merged in feature/IO-3000-messaging-sockets-migrationv2 (pull request #1960)
Feature/IO-3000 messaging sockets migrationv2
2024-11-27 19:36:29 +00:00
Dave Richer
aec7b40ae2 feature/IO-3000-messaging-sockets-migration2 -
-misc

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-27 11:35:28 -08:00
Dave Richer
54d319f1e8 Merge remote-tracking branch 'origin/release/2024-11-22' into feature/IO-3000-messaging-sockets-migrationv2 2024-11-27 11:30:39 -08:00
Dave Richer
8d6fba2b61 feature/IO-3000-messaging-sockets-migration2 -
-misc

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-27 11:27:34 -08:00
Dave Richer
70c31eae9e feature/IO-3000-messaging-sockets-migration2 -
- [EXISTING BUG?] The updated at timeframes do not automatically update as time passes. If you receive a message, and it is changed to a few seconds ago, if you wait a few minutes, it does not change unless you interact with it forcing a re-render. This can be solved by adding a tick state and periodically refreshing - unsure of the performance impact for many elements however.

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-27 10:21:53 -08:00
Dave Richer
5e871b024d feature/IO-3000-messaging-sockets-migration2 -
- Polling Mode indicator now pegged to socket.connected

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-27 10:13:38 -08:00
Dave Richer
f8902efcea Merged in release/2024-11-22 (pull request #1959)
Release/2024 11 22
2024-11-27 18:03:54 +00:00
Dave Richer
eb1786d634 Merged in feature/IO-2959-crisp-status-page (pull request #1958)
IO-2959 Remove debug for crisp status and add sig term handler.
2024-11-27 18:03:02 +00:00
Patrick Fic
5e8d0fddbd IO-2959 Remove debug for crisp status and add sig term handler. 2024-11-27 09:44:42 -08:00
Allan Carr
5d690fd71f Merged in feature/IO-3040-Report-Selector-Date-Range-Restriction (pull request #1956)
Feature/IO-3040 Report Selector Date Range Restriction

Approved-by: Dave Richer
2024-11-27 16:48:07 +00:00
Allan Carr
79a2d902cd Merged in feature/IO-3037-Supplement-Existing-Lines (pull request #1957)
IO-3037 Supplement Existing Lines

Approved-by: Dave Richer
2024-11-27 16:47:52 +00:00
Allan Carr
77f340d08c IO-3037 Supplement Existing Lines
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-27 08:40:55 -08:00
Allan Carr
0770e7b50d IO-3040 Re-add Translations after Merge from Release
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-26 16:12:03 -08:00
Allan Carr
3147212b7b Merge branch 'release/2024-11-22' into feature/IO-3040-Report-Selector-Date-Range-Restriction
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>

# Conflicts:
#	client/src/translations/en_us/common.json
#	client/src/translations/es/common.json
#	client/src/translations/fr/common.json
2024-11-26 16:10:03 -08:00
Allan Carr
24cc9762b2 IO-3040 Report Selector Date Range Restriction
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-26 15:04:39 -08:00
Patrick Fic
3183baf560 Merged in release/2024-11-22 (pull request #1955)
Release/2024 11 22
2024-11-26 18:48:52 +00:00
Dave Richer
2d5153da5b Merged in feature/IO-3000-messaging-sockets-migrationv2 (pull request #1948)
Feature/IO-3000 messaging sockets migrationv2 - Enhanced Socket Migrations

Approved-by: Patrick Fic
2024-11-26 18:48:17 +00:00
Dave Richer
083534c3f3 Merge branch 'feature/IO-3000-messaging-sockets-migrationv2' of bitbucket.org:snaptsoft/bodyshop into feature/IO-3000-messaging-sockets-migrationv2 2024-11-26 10:30:16 -08:00
Dave Richer
63397769d2 feature/IO-3000-messaging-sockets-migration2 - Take last conversation if more than one exists.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-26 10:29:57 -08:00
Dave Richer
b5b7957b2f Merged release/2024-11-22 into feature/IO-3000-messaging-sockets-migrationv2 2024-11-26 17:56:41 +00:00
Patrick Fic
d50c73c82f Merged in feature/IO-2959-crisp-status-page (pull request #1954)
Feature/IO-2959 crisp status page
2024-11-26 16:53:57 +00:00
Patrick Fic
a4bff1a548 IO-2959 Implement logger & best practices. 2024-11-26 08:52:58 -08:00
Dave Richer
5f1daffb3e Merge branch 'feature/IO-3000-messaging-sockets-migrationv2' of bitbucket.org:snaptsoft/bodyshop into feature/IO-3000-messaging-sockets-migrationv2 2024-11-26 08:39:41 -08:00
Dave Richer
e9dfba7d31 feature/IO-3000-messaging-sockets-migration2 - Extra checks on scroll to index to prevent console warns when no messages exist in the conversation.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-26 08:39:21 -08:00
Dave Richer
2f0838b39c Merged release/2024-11-22 into feature/IO-3000-messaging-sockets-migrationv2 2024-11-26 15:30:41 +00:00
Dave Richer
d8311c5163 feature/IO-3000-messaging-sockets-migration2 - remove unused dep
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-26 07:00:54 -08:00
Patrick Fic
62e4843d5b Merged in master-AIO (pull request #1953)
Merge Master into release to update.
2024-11-25 23:46:46 +00:00
Patrick Fic
6058bb1b8f IO-2959 Add Crisp Status Reporter to API. 2024-11-25 15:44:15 -08:00
Patrick Fic
fa6c672583 Merge branch 'feature/IO-2920-cash-discounting' into release/2024-11-22 2024-11-25 14:15:37 -08:00
Patrick Fic
cb4d4e4c2c IO-2920 Remove shop config for intellipay amounts. 2024-11-25 14:09:09 -08:00
Patrick Fic
225b57fd58 IO-2920 Update checkfee method to get CC amount based on new information. 2024-11-25 14:08:38 -08:00
Dave Richer
e1ffcba32f Merge branch 'feature/IO-3000-messaging-sockets-migrationv2' of bitbucket.org:snaptsoft/bodyshop into feature/IO-3000-messaging-sockets-migrationv2 2024-11-25 13:45:25 -08:00
Dave Richer
5c30f33dac feature/IO-3000-messaging-sockets-migration2 - Additional logging
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-25 13:45:09 -08:00
Dave Richer
13908074c6 Merged release/2024-11-22 into feature/IO-3000-messaging-sockets-migrationv2 2024-11-25 21:33:59 +00:00
Dave Richer
c3c66f9646 feature/IO-3000-messaging-sockets-migration2 - Final Modifications
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-25 12:46:10 -08:00
Patrick Fic
4433f0f57f IO-3020 IO-3036 Remove additional TODOs. 2024-11-25 12:29:09 -08:00
Dave Richer
62dd3d7e8e feature/IO-3000-messaging-sockets-migration2 - Final fixes around sync / archive / receive
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-25 11:38:59 -08:00
Patrick Fic
268b1ba9c1 IO-2920 Refactor fee discounting to use API to check. 2024-11-25 10:51:48 -08:00
Dave Richer
239c1502f9 feature/IO-3000-messaging-sockets-migration2 - Fix console warn in archive/unarchive if one query is not existent
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-25 09:57:18 -08:00
Dave Richer
457a3b2d7a feature/IO-3000-messaging-sockets-migration2 - Handle some of the PR notes
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-25 08:42:02 -08:00
Dave Richer
5e2c0f9c4a feature/IO-3000-messaging-sockets-migration2 - Handle some of the PR notes
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-25 08:38:07 -08:00
Dave Richer
cbc8665636 feature/IO-3000-messaging-sockets-migration2 - Handle some of the PR notes
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-25 08:36:33 -08:00
Allan Carr
f6506d6073 Merged in feature/IO-2921-CARSTAR-Canada-Chatter-Integration (pull request #1949)
IO-2921 Chatter Final mods and Cron Trigger

Approved-by: Dave Richer
2024-11-22 19:50:27 +00:00
Allan Carr
91de311351 IO-2921 Chatter Final mods and Cron Trigger
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-22 10:55:19 -08:00
Dave Richer
49044e5669 feature/IO-3000-messaging-sockets-migrations2 -
- Missed a check

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-22 10:03:41 -08:00
Dave Richer
8adaa12618 feature/IO-3000-messaging-sockets-migrations2 -
- Merge release / fix conflicts

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-22 10:02:05 -08:00
Patrick Fic
36aad0f140 Merged in feature/IO-3001-us-est-scrubbing (pull request #1942)
feature/IO-3001-us-est-scrubbing
2024-11-22 17:18:47 +00:00
Patrick Fic
11ab7cd67e IO-3001 Null Coalesce for some items for better handling. 2024-11-22 09:18:09 -08:00
Patrick Fic
eacadc01bd IO-3020 IO-3036 Resolve Linting Issues and implement ES9 2024-11-22 08:26:46 -08:00
Dave Richer
3ab471e629 feature/IO-3000-messaging-sockets-migrations2 -
- Final fix of unread messagages

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-22 08:23:24 -08:00
Dave Richer
6504b27eca feature/IO-3000-messaging-sockets-migrations2 -
- A lot of a lot of testing....

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-21 22:14:39 -08:00
Allan Carr
d40579694f Merged in hotfix/2024-11-21 (pull request #1947)
Hotfix/2024 11 21 IO-2921 IO-3027
2024-11-22 04:41:29 +00:00
Allan Carr
fa24d87966 Merged in feature/IO-3027-Datapumps-Refactor (pull request #1945)
Feature/IO-3027 Datapumps Refactor
2024-11-22 04:40:01 +00:00
Allan Carr
1b6eab8488 Merged in feature/IO-2921-CARSTAR-Canada-Chatter-Integration (pull request #1946)
Feature/IO-2921 CARSTAR Canada Chatter Integration
2024-11-22 04:39:49 +00:00
Allan Carr
e15e92c112 Merged in feature/IO-2921-CARSTAR-Canada-Chatter-Integration (pull request #1944)
IO-2921 Chatter Datapump Adjustment
2024-11-22 04:39:27 +00:00
Allan Carr
fba8cab98a Merged in feature/IO-3027-Datapumps-Refactor (pull request #1943)
IO-3027 Datapump Refactor
2024-11-22 04:39:06 +00:00
Dave Richer
141deff41e feature/IO-3000-messaging-sockets-migrations2 -
- harden openMessageByPhone

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-21 19:37:25 -08:00
Dave Richer
12ed8d3830 feature/IO-3000-messaging-sockets-migrations2 -
- dumb down archive/unarchive

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-21 19:21:51 -08:00
Dave Richer
525f795ce0 feature/IO-3000-messaging-sockets-migrations2 -
- dumb down archive/unarchive

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-21 19:17:42 -08:00
Dave Richer
38f13346e5 feature/IO-3000-messaging-sockets-migrations2 -
- testing and edge cases

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-21 18:44:38 -08:00
Dave Richer
8229e3593c feature/IO-3000-messaging-sockets-migrations2 -
- remove unused query,

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-21 17:39:05 -08:00
Dave Richer
d2e1b32557 feature/IO-3000-messaging-sockets-migrations2 -
- Checkpoint,

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-21 17:35:04 -08:00
Allan Carr
e202bf9a89 IO-3027 Add in bodyshop.id to logging in SFTP
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-21 16:18:23 -08:00
Allan Carr
1a6e8bc5ba Merge branch 'release/2024-11-22' into feature/IO-2921-CARSTAR-Canada-Chatter-Integration
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>

# Conflicts:
#	server/data/chatter.js
2024-11-21 15:09:46 -08:00
Dave Richer
cd592b671c feature/IO-3000-messaging-sockets-migrations2 -
- Checkpoint,

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-21 15:05:52 -08:00
Allan Carr
dd4ba8a467 IO-2921 Chatter Datapump Adjustment
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-21 14:40:36 -08:00
Allan Carr
8ad1dd83c6 IO-3027 Datapump Refactor
Remove Batch and sftp transfer for each shop during processing

Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-21 14:24:31 -08:00
Patrick Fic
9ccbca2678 IO-3020 IO-3036 Initial removal of ProManager 2024-11-21 13:37:36 -08:00
Dave Richer
1cdd905037 feature/IO-3000-messaging-sockets-migrations2 -
- Checkpoint, archiving works, cannot unarchive yet

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-21 13:23:28 -08:00
Dave Richer
e734da7adc feature/IO-3000-messaging-sockets-migrations2 -
- Fix Bug in import

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-21 12:04:32 -08:00
Dave Richer
12aec3e3a0 feature/IO-3000-messaging-sockets-migrations2 -
- Fix Chat Icon logger error
- Fix Socket Robustness
- added additional wss status for error
- Installed ant-design icons

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-21 12:03:01 -08:00
Dave Richer
5392659db6 feature/IO-3000-messaging-sockets-migrations2 -
- Checkpoint

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-21 11:32:43 -08:00
Dave Richer
15151cb4ac feature/IO-3000-messaging-sockets-migrations2 -
- sync send
- fix status events

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-20 19:23:35 -08:00
Dave Richer
06afd6da5b feature/IO-3000-messaging-sockets-migrations2 -
- Conversation Labels Synced
- Job Tagging Synced

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-20 18:22:27 -08:00
Dave Richer
250faa672f feature/IO-3000-messaging-sockets-migrations2 - Updated Polling Intervals is now socket based over FCMToken based
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-20 14:53:01 -08:00
Patrick Fic
ec5258a431 Merge branch 'master-AIO' into feature/IO-3001-us-est-scrubbing 2024-11-20 14:11:14 -08:00
Patrick Fic
fbc7168bde IO-3001 branch cleanup 2024-11-20 14:03:34 -08:00
Patrick Fic
f2d9626888 IO-3001 Reverse n_ttl and g_ttl logic for audatex estimates. 2024-11-20 12:43:03 -08:00
Dave Richer
e15384d0bf feature/IO-3000-messaging-sockets-migrations2 - Everything but tagging and labels works
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-20 12:23:50 -08:00
Dave Richer
261353b511 feature/IO-3000-messaging-sockets-migrations2 - Base cleanup
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-20 11:35:30 -08:00
Allan Carr
80b66fd7e8 Merged in feature/IO-2921-CARSTAR-Canada-Chatter-Integration (pull request #1940)
IO-2921 Chatter modifications as per Dave Bourbeau @ Chatter

Approved-by: Dave Richer
2024-11-20 18:58:31 +00:00
Allan Carr
45ac56e0bc IO-2921 Chatter modifications as per Dave Bourbeau @ Chatter
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-20 10:57:59 -08:00
Allan Carr
1ff1de8739 Merge branch 'master-AIO' into feature/IO-2921-CARSTAR-Canada-Chatter-Integration
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-20 10:56:02 -08:00
Patrick Fic
299a675a9c IO-3000 Adjusted first approach at messaging WS changes. 2024-11-19 15:52:57 -08:00
Patrick Fic
2304e0bf02 IO-3001 Resolve towing totals issue. 2024-11-19 10:59:59 -08:00
Allan Carr
ea1cc23ee7 Merged in feature/IO-3027-Datapumps-Refactor (pull request #1937)
IO-3027 Turn Off SFTP Logging for Production ENV

Approved-by: Dave Richer
2024-11-18 21:37:17 +00:00
Allan Carr
7cbabf8697 IO-3027 Turn Off SFTP Logging for Production ENV
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-18 12:02:08 -08:00
Allan Carr
289a666b6d Merged in release/2024-11-15 (pull request #1935)
IO-3030 Null Check memo
2024-11-18 16:48:26 +00:00
Allan Carr
d2db8c68f3 Merged in release/2024-11-15 (pull request #1936)
IO-3030 Null Check memo
2024-11-18 16:43:21 +00:00
Allan Carr
b8836c7ae1 Merged in feature/IO-3030-QBO-Payment-Private-Note (pull request #1934)
IO-3030 Null Check memo
2024-11-18 16:40:15 +00:00
Allan Carr
eca31c5618 IO-3030 Null Check memo
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-18 08:42:52 -08:00
Allan Carr
7fdbedefce Merged in release/2024-11-15 (pull request #1933)
IO-3031 Appointment Schedule View Day
2024-11-16 01:40:16 +00:00
Allan Carr
ef166a930a Merged in release/2024-11-15 (pull request #1932)
IO-3031 Appointment Schedule View Day
2024-11-16 01:34:25 +00:00
Allan Carr
7140b8d585 Merged in feature/IO-3031-Appointment-Schedule-View-Day (pull request #1931)
IO-3031 Appointment Schedule View Day
2024-11-16 01:33:29 +00:00
Allan Carr
5eed8d9809 IO-3031 Appointment Schedule View Day
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-15 17:35:49 -08:00
Dave Richer
57fe5b4c46 Merged in release/2024-11-15 (pull request #1930)
Release/2024 11 15 into master-AIO IO-2920, IO-3027, IO-3028, IO-3029, IO-3030, IO-3031, IO-3033
2024-11-15 23:59:53 +00:00
Allan Carr
20252c61c6 Merged in release/2024-11-15 (pull request #1929)
IO-3028 Adjust to TextArea with autoSize
2024-11-15 20:55:28 +00:00
Allan Carr
f266ee1cfe Merged in feature/IO-3028-Word-Wrap-Line-Description (pull request #1928)
IO-3028 Adjust to TextArea with autoSize
2024-11-15 20:54:44 +00:00
Allan Carr
9550de5131 IO-3028 Adjust to TextArea with autoSize
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-15 12:57:08 -08:00
Dave Richer
54dcdb49d3 Merged in release/2024-11-15 (pull request #1926)
Release/2024-11-15 into test-AIO - IO-3027 - IO-3033

Approved-by: Patrick Fic
2024-11-15 20:25:29 +00:00
Patrick Fic
1f76ff882c Remove IO Event Logging. 2024-11-15 11:03:10 -08:00
Patrick Fic
749f73a272 Merged in feature/IO-2920-cash-discounting (pull request #1927)
IO-2920 Update config & totals for discount.
2024-11-15 18:58:54 +00:00
Patrick Fic
9c1774c417 Merge branch 'release/2024-11-15' into feature/IO-2920-cash-discounting 2024-11-15 10:58:22 -08:00
Patrick Fic
e363dca3f0 IO-3001 Additional tax changes. 2024-11-15 10:56:07 -08:00
Allan Carr
26b3a43ce5 Merge branch 'feature/IO-3027-Datapumps-Refactor' into release/2024-11-15
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>

# Conflicts:
#	.vscode/settings.json
2024-11-15 10:05:08 -08:00
Allan Carr
78678dd3dc IO-3027 Datapumps Refactor
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-15 10:04:03 -08:00
Allan Carr
9dc4546b2e Merged in feature/IO-3033-Total-Loss-Indicator (pull request #1925)
IO-3033 Total Loss Indicator

Approved-by: Dave Richer
2024-11-15 17:47:56 +00:00
Allan Carr
95aa0e45a6 IO-3033 Total Loss Indicator
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-14 16:47:35 -08:00
Allan Carr
ce9a77efcf IO-3027 Datapumps Refactor
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-14 16:15:17 -08:00
Dave Richer
e9e1e820a7 release/2024-11-15 - Expose S3 client through createS3Client
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-14 11:57:40 -08:00
Allan Carr
b027a4e618 IO-3031 Adjust prop
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-14 11:52:47 -08:00
Dave Richer
0adb6413e4 Merged in release/2024-11-15 (pull request #1923)
Release/2024-11-15 - into test-AIO - IO-3030 IO-3029 IO-3031
2024-11-14 19:51:52 +00:00
Allan Carr
c7fc75aa5c Merged in feature/IO-3031-Appointment-Schedule-View-Day (pull request #1922)
IO-3031 View Day when Scheduling

Approved-by: Dave Richer
2024-11-14 19:50:34 +00:00
Allan Carr
98d2372daf Merged in feature/IO-3030-QBO-Payment-Private-Note (pull request #1920)
IO-3030 QBO Payment Private Note

Approved-by: Dave Richer
2024-11-14 19:40:20 +00:00
Allan Carr
bf51380167 IO-3031 View Day when Scheduling
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-14 11:19:09 -08:00
Dave Richer
1ec827097f Merged in feature/IO-3029-Enhanced-Logging-File-Based (pull request #1921)
feature/IO-3029-Enhanced-Logging-File-Based: Adjust XML and JSON log to always upload
2024-11-14 18:55:57 +00:00
Dave Richer
89fabf85e1 feature/IO-3029-Enhanced-Logging-File-Based: Adjust XML and JSON log to always upload
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-14 10:55:14 -08:00
Allan Carr
ff7dd7d3ea IO-3030 QBO Payment Private Note
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-14 10:37:08 -08:00
Dave Richer
f41416645f Merged in release/2024-11-15 (pull request #1919)
feature/IO-3029-Enhanced-Logging-File-Based: Final Enhancements
2024-11-14 16:36:38 +00:00
Dave Richer
8cc4f88fa7 Merged in feature/IO-3029-Enhanced-Logging-File-Based (pull request #1918)
feature/IO-3029-Enhanced-Logging-File-Based: Final Enhancements
2024-11-14 16:36:13 +00:00
Dave Richer
2439755f9e feature/IO-3029-Enhanced-Logging-File-Based: Final Enhancements
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-14 08:34:21 -08:00
Dave Richer
4468a5be2d Merged in release/2024-11-15 (pull request #1917)
feature/IO-3029-Enhanced-Logging-File-Based: Update Stream Key name
2024-11-14 04:15:29 +00:00
Dave Richer
7e6ab3a5ff Merged in feature/IO-3029-Enhanced-Logging-File-Based (pull request #1916)
feature/IO-3029-Enhanced-Logging-File-Based: Update Stream Key name
2024-11-14 04:14:54 +00:00
Dave Richer
763384f05f feature/IO-3029-Enhanced-Logging-File-Based: Update Stream Key name
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-13 20:14:17 -08:00
Dave Richer
68b711038c Merged in release/2024-11-15 (pull request #1915)
Release/2024 11 15 into test-AIO - IO-3029
2024-11-14 03:58:21 +00:00
Dave Richer
34f876f838 Merged in feature/IO-3029-Enhanced-Logging-File-Based (pull request #1914)
feature/IO-3029-Enhanced-Logging-File-Based: Add File based S3 Logging.
2024-11-14 03:57:24 +00:00
Dave Richer
cba2da8da7 feature/IO-3029-Enhanced-Logging-File-Based: Add fix bugs
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-13 13:09:37 -08:00
Dave Richer
f3d8aa3438 feature/IO-3029-Enhanced-Logging-File-Based: Add File based S3 Logging.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-13 12:59:56 -08:00
Allan Carr
8f3c71ca07 Merged in release/2024-11-15 (pull request #1913)
IO-3028 Extend to Notes
2024-11-13 18:51:19 +00:00
Allan Carr
2f3eccf3d8 Merged in feature/IO-3028-Word-Wrap-Line-Description (pull request #1912)
IO-3028 Extend to Notes
2024-11-13 18:50:32 +00:00
Allan Carr
2b3e64d607 IO-3028 Extend to Notes
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-13 10:49:47 -08:00
Dave Richer
0c360e48cc Merged in release/2024-11-15 (pull request #1911)
Release/2024 11 15 - into test-AIO - IO-3026-Enhanced-Notifications - IO-3028
2024-11-13 18:18:58 +00:00
Allan Carr
05b20505bb Merged in feature/IO-3028-Word-Wrap-Line-Description (pull request #1910)
IO-3028 Word Wrap Line Description

Approved-by: Dave Richer
2024-11-13 18:17:34 +00:00
Allan Carr
bddeae945c IO-3028 Word Wrap Line Description
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-13 10:06:01 -08:00
Patrick Fic
5b267f03b9 Add additional GIN indexes for db. 2024-11-12 20:21:43 -08:00
Dave Richer
357d916e0a Merged in release/2024-11-15 (pull request #1908)
[DO NOT MERGE] - Release/2024 11 15

Approved-by: Patrick Fic
2024-11-13 00:30:22 +00:00
Dave Richer
6ed12ebe7d Merged in feature/IO-3026-Enhanced-Notifications (pull request #1909)
feature/IO-3026-Enhanced-Notifications - final revisions
2024-11-12 22:52:13 +00:00
Dave Richer
6703bc025d feature/IO-3026-Enhanced-Notifications - final revisions
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-12 14:51:50 -08:00
Dave Richer
40e75b491b Merged in release/2024-11-15 (pull request #1907)
Release/2024 11 15
2024-11-12 22:24:05 +00:00
Dave Richer
387dac6779 Merged in feature/IO-3026-Enhanced-Notifications (pull request #1906)
Feature/IO-3026 Enhanced Notifications
2024-11-12 22:23:35 +00:00
Dave Richer
6f454dd4cb feature/IO-3026-Enhanced-Notifications - final revisions
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-12 14:20:49 -08:00
Dave Richer
1440a60228 feature/IO-3026-Enhanced-Notifications - Initial commit
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-12 12:31:46 -08:00
Patrick Fic
cb80b79e1d IO-3001 WIP CDK Adjustments. 2024-11-12 11:58:51 -08:00
Allan Carr
f2aa3960aa Merged in release/2024-11-08 (pull request #1905)
Release/2024 11 08 IO-2921 IO-3025
2024-11-09 08:37:27 +00:00
Allan Carr
8d4195b596 IO-2921 Adjust SFTP setup
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-09 00:35:18 -08:00
Allan Carr
47182c3e99 Merged in release/2024-11-08 (pull request #1904)
Release/2024 11 08 IO-2921 IO-3025
2024-11-09 08:34:29 +00:00
Allan Carr
06508f3ad8 Merged in feature/IO-2921-CARSTAR-Canada-Chatter-Integration (pull request #1903)
Feature/IO-2921 CARSTAR Canada Chatter Integration
2024-11-09 08:33:32 +00:00
Allan Carr
9e190e7fb7 Merged in feature/IO-3025-Autohouse-Datapump-Refactor (pull request #1902)
IO-3025 Adjust for promise and change processing
2024-11-09 08:32:49 +00:00
Allan Carr
5cbf00b0c8 IO-3025 Adjust for promise and change processing
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-09 00:32:51 -08:00
Allan Carr
655aeb86fc IO-2921 Adjust for Promise and change processing
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-08 23:43:18 -08:00
Allan Carr
225549275d Merged in release/2024-11-08 (pull request #1901)
Release/2024 11 08 IO-2921 IO-3025
2024-11-09 06:33:14 +00:00
Allan Carr
f0717b8b36 IO-2921 Shift Email outside of Batch
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-08 22:30:22 -08:00
Allan Carr
cc2261d711 Merged in release/2024-11-08 (pull request #1900)
Release/2024 11 08 IO-2921 IO-3025
2024-11-09 06:28:56 +00:00
Allan Carr
78771ae750 IO-3025 Shift Email send to outside of batch
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-08 22:28:02 -08:00
Allan Carr
0389908398 Merged in feature/IO-2921-CARSTAR-Canada-Chatter-Integration (pull request #1899)
IO-2921 Shift Email outside of Batch
2024-11-09 06:27:57 +00:00
Allan Carr
54bee763df Merged in feature/IO-3025-Autohouse-Datapump-Refactor (pull request #1898)
IO-3025 Shift Email send to outside of batch
2024-11-09 06:25:39 +00:00
Dave Richer
1117a94930 Merged in release/2024-11-08 (pull request #1897)
release/2024-11-08 - Small fix to font script
2024-11-09 05:21:03 +00:00
Dave Richer
c6bdb49569 Merged in release/2024-11-08 (pull request #1896)
release/2024-11-08 - Small fix to font script
2024-11-09 05:20:22 +00:00
Dave Richer
5fbfb992c7 release/2024-11-08 - Small fix to font script
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-08 21:18:58 -08:00
Dave Richer
87b3b65f3e Merged in release/2024-11-08 (pull request #1893)
Release/2024-11-08 into master-AIO - IO-2921, IO-2969, IO-3001, IO-3015, IO-3017, IO-3018, IO-3025

Approved-by: Allan Carr
2024-11-09 04:52:01 +00:00
Allan Carr
82a76a5e3a Merged in release/2024-11-08 (pull request #1895)
IO-3025 Autohouse Datapump Refactor
2024-11-09 03:32:17 +00:00
Allan Carr
9970190909 Merged in feature/IO-3025-Autohouse-Datapump-Refactor (pull request #1894)
IO-3025 Autohouse Datapump Refactor
2024-11-09 03:31:37 +00:00
Allan Carr
8eee371a90 IO-3025 Autohouse Datapump Refactor
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-08 19:30:33 -08:00
Dave Richer
fd7e9c9d3b Merged in release/2024-11-08 (pull request #1892)
Release/2024 11 08
2024-11-08 17:58:14 +00:00
Dave Richer
ba97b1efef Merged in feature/IO-3015-addl-prod-indexes (pull request #1891)
Feature/IO-3015 addl prod indexes
2024-11-08 17:57:47 +00:00
Dave Richer
05a21e8586 Merged in release/2024-11-08 (pull request #1890)
Release/2024-11-08 into test-AIO - IO-2921, IO-2969, IO-3017, IO-3018
2024-11-08 17:35:38 +00:00
Allan Carr
8d8887c28e Merged in feature/IO-3017-Lifecycle-Average-Time (pull request #1889)
IO-3017 Lifecycle Average Time

Approved-by: Dave Richer
2024-11-08 17:33:31 +00:00
Dave Richer
3b19432974 feature/IO-3017-Lifecycle-Average-Time - Small fixes
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-08 09:32:58 -08:00
Allan Carr
a14b2340b0 IO-3017 Lifecycle NaN prevention
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-08 09:24:58 -08:00
Allan Carr
624f8e77cb IO-3017 Lifecycle Average Time
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-07 13:56:53 -08:00
Dave Richer
fb624c817d Merged in feature/IO-2969-Fonts-For-Production (pull request #1888)
Feature/IO-2969 Fonts For Production into release
2024-11-07 20:42:26 +00:00
Dave Richer
c2b4b66ed1 hotfix/IO-2969-Fonts-For-Production
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-07 12:40:13 -08:00
Dave Richer
ffec03ab6c Merge remote-tracking branch 'origin/master-AIO' into hotfix/IO-2969-Fonts-For-Production 2024-11-07 12:37:01 -08:00
Allan Carr
552163d7b9 IO-2921 Upload directory
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-06 15:53:51 -08:00
Allan Carr
db1f59578c Merged in feature/IO-2921-CARSTAR-Canada-Chatter-Integration (pull request #1887)
IO-2921 Re-factor as batch and get docker compose dev working for sftp testing

Approved-by: Dave Richer
2024-11-06 23:51:46 +00:00
Allan Carr
8ec5831ec5 IO-2921 Re-factor as batch and get docker compose dev working for sftp testing
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-06 15:42:14 -08:00
Allan Carr
0146ac5b7b Merged in feature/IO-3018-QBO-Standarize-name (pull request #1886)
IO-3018 QBO Standardize name

Approved-by: Dave Richer
2024-11-06 16:37:47 +00:00
Allan Carr
a603e5c0b8 Merged in feature/IO-2921-CARSTAR-Canada-Chatter-Integration (pull request #1885)
IO-2921 Adjustment for SFTP Private Key

Approved-by: Dave Richer
2024-11-06 16:36:52 +00:00
Patrick Fic
9aab47d8f8 IO-2920 Update config & totals for discount. 2024-11-05 16:37:21 -08:00
Patrick Fic
f2f84e2da8 Merge branch 'master-AIO' into feature/IO-2920-cash-discounting 2024-11-05 16:00:47 -08:00
Patrick Fic
94641ae01d IO-3001 Add resp. centers and begin QB testing. 2024-11-05 15:31:35 -08:00
Allan Carr
338906e288 IO-3018 QBO Standardize name
Trim StandardizeName

Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-05 11:53:42 -08:00
Allan Carr
542997b1a7 IO-2921 Adjustment for SFTP Private Key
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-05 11:02:18 -08:00
Patrick Fic
9bb36d2223 Merge branch 'master-AIO' into feature/IO-3001-us-est-scrubbing 2024-11-05 08:52:49 -08:00
Dave Richer
5fce548666 Merged in release/2024-11-01 (pull request #1884)
Release/2024-11-01 into master-AIO - IO-2921, IO-3006, IO-3008, IO-3009, IO-3010
2024-11-02 15:14:06 +00:00
Dave Richer
49c3ff9043 Merged in release/2024-11-01 (pull request #1883)
release/2024-11-01 - Update Trigger for job_updated - Make the callback work with old and new Hasura
2024-11-02 15:11:56 +00:00
Dave Richer
80322caad0 release/2024-11-01 - Update Trigger for job_updated - Make the callback work with old and new Hasura
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-11-02 08:11:22 -07:00
Patrick Fic
56472d24d9 IO-3015 add additional indexs. 2024-11-01 21:33:03 -07:00
Patrick Fic
db5dcc271d IO-30015 add new indexes to production. 2024-11-01 20:35:44 -07:00
Patrick Fic
1205e71ea6 IO-3001 Add UI adjustments. 2024-11-01 19:54:49 -07:00
Allan Carr
afc5df7f09 Merged in release/2024-11-01 (pull request #1882)
IO-2921 Adjustment to getting Secret
2024-11-02 00:55:56 +00:00
Allan Carr
73ab02225e IO-2921 Adjustment to getting Secret
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-01 17:55:33 -07:00
Allan Carr
83a1b7690d Merged in feature/IO-2921-CARSTAR-Canada-Chatter-Integration (pull request #1881)
IO-2921 Adjustment to getting Secret
2024-11-02 00:54:56 +00:00
Allan Carr
c9e28b1ed2 Merge branch 'master-AIO' into feature/IO-2921-CARSTAR-Canada-Chatter-Integration
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-01 17:52:54 -07:00
Allan Carr
e118e5bcd5 Merged in release/2024-11-01 (pull request #1880)
IO-3009 Correction for nulls
2024-11-01 17:18:39 +00:00
Allan Carr
c25c66d00f Merged in feature/IO-3009-Clear-Dates (pull request #1879)
IO-3009 Correction for nulls
2024-11-01 17:16:23 +00:00
Allan Carr
d319ab49d4 IO-3009 Correction for nulls
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-11-01 10:18:14 -07:00
Dave Richer
95ffeeefcd Merged in release/2024-11-01 (pull request #1878)
Release/2024 11 01
2024-10-31 18:14:44 +00:00
Allan Carr
a069989ea7 Merged in feature/IO-3014-Timeticket-UI-Sort (pull request #1876)
IO-3014 Change Polling Intervals

Approved-by: Dave Richer
2024-10-31 18:13:51 +00:00
Dave Richer
8e3aa186cb Merged in hotfix/2024-10-31-Database-Issues (pull request #1877)
Hotfix/2024 10 31 Database Issues into master-AIO - IO-3012 IO-3009 IO-3014
2024-10-31 18:06:08 +00:00
Allan Carr
01c55d6277 IO-3014 Change Polling Intervals
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-10-31 11:04:05 -07:00
Dave Richer
3438907d8d Merge remote-tracking branch 'origin/feature/IO-3014-Timeticket-UI-Sort' into hotfix/2024-10-31-Database-Issues 2024-10-31 11:02:09 -07:00
Allan Carr
ae020b651e IO-3014 Further Query Refinements for T/T
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-10-31 10:56:05 -07:00
Allan Carr
d22988df15 Merged in feature/IO-3014-Timeticket-UI-Sort (pull request #1875)
IO-3014 TimeTicket UI Sort

Approved-by: Dave Richer
2024-10-31 17:54:36 +00:00
Dave Richer
8136a56ad2 Merge remote-tracking branch 'origin/feature/IO-3014-Timeticket-UI-Sort' into hotfix/2024-10-31-Database-Issues 2024-10-31 10:53:56 -07:00
Allan Carr
830f6c0eea IO-3014 TimeTicket UI Sort
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-10-31 10:48:40 -07:00
Dave Richer
4c1849289a Merge remote-tracking branch 'origin/feature/IO-3014-Timeticket-UI-Sort' into hotfix/2024-10-31-Database-Issues 2024-10-31 10:46:21 -07:00
Dave Richer
c45a4780e3 Merge remote-tracking branch 'origin/feature/IO-3012-Remove-Sort-for-SB-TimeTickets-Query' into hotfix/2024-10-31-Database-Issues 2024-10-31 10:34:56 -07:00
Dave Richer
dba41e7732 Merged in release/2024-11-01 (pull request #1874)
Release/2024-11-01 IO-3012 IO-3009 IO 3010
2024-10-31 17:07:31 +00:00
Allan Carr
d4adc4c1aa Merged in feature/IO-3009-Clear-Dates (pull request #1872)
IO-3009 Clear Dates

Approved-by: Dave Richer
2024-10-31 17:06:38 +00:00
Allan Carr
d9e71423f5 Merged in feature/IO-3010-Task-Table-UI-Mods (pull request #1873)
IO-3010 Task Table UI refactor

Approved-by: Dave Richer
2024-10-31 17:06:02 +00:00
Allan Carr
6cac0f9594 IO-3010 Task Table UI refactor
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-10-30 17:38:09 -07:00
Patrick Fic
f8e65ada76 IO-3001 Initial adjustments to totals. 2024-10-30 14:06:00 -07:00
Allan Carr
2ab4615642 IO-3009 Clear Dates
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-10-30 12:48:27 -07:00
Dave Richer
dd5961d419 release/2024-11-01 - Update Trigger for job_updated
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-30 12:07:50 -07:00
Allan Carr
8190958ba3 Merged in feature/IO-3012-Remove-Sort-for-SB-TimeTickets-Query (pull request #1871)
IO-3012 Remove Sort from SB Timeticket Query

Approved-by: Dave Richer
2024-10-30 19:03:18 +00:00
Allan Carr
77e009f316 IO-3012 Remove Sort from SB Timeticket Query
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-10-30 11:19:46 -07:00
Dave Richer
a715fccd47 Merged in release/2024-11-01 (pull request #1870)
release/2024-11-01 into test-AIO - IO-3006 IO-3008
2024-10-30 16:41:12 +00:00
Dave Richer
2b2738a8d1 Merge branch 'release/2024-11-01' of bitbucket.org:snaptsoft/bodyshop into release/2024-11-01 2024-10-30 09:38:56 -07:00
Dave Richer
3d10c9da7f release/2024-11-01 - Misc fixes
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-30 09:38:27 -07:00
Allan Carr
e82c77d119 Merged in feature/IO-3008-Save-&-New-Time-Ticket (pull request #1868)
IO-3008 Save and New Flat Rate value

Approved-by: Dave Richer
2024-10-30 16:12:21 +00:00
Allan Carr
855a78be05 Merged in feature/IO-3006-CDK-PBS-Error-Log-INSERT_EXPORT_LOG (pull request #1867)
IO-3006 CDK PBS Error Log on INSERT_EXPORT_LOG

Approved-by: Dave Richer
2024-10-30 16:11:49 +00:00
Dave Richer
4f6e1ffc9a Merged in release/2024-11-01 (pull request #1869)
release/2024-11-01 - Misc fixes
2024-10-30 16:10:40 +00:00
Dave Richer
a29e840797 release/2024-11-01 - Misc fixes
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-30 09:09:16 -07:00
Allan Carr
1b30c1ab58 IO-3008 Save and New Flat Rate value
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-10-29 20:03:58 -07:00
Allan Carr
80f235f12e IO-3006 CDK PBS Error Log on INSERT_EXPORT_LOG
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-10-29 13:33:40 -07:00
Dave Richer
9b67148522 Merged in release/2024-11-01 (pull request #1866)
Release/2024-11-01 into master-AIO - IO-2979 - Misc Logger related fixes
2024-10-29 20:10:02 +00:00
Dave Richer
c07efad729 Merged in release/2024-11-01 (pull request #1865)
Release/2024 11 01
2024-10-29 18:05:04 +00:00
Dave Richer
6b501e4619 release/2024-11-01 - Misc fixes
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-29 11:02:08 -07:00
Dave Richer
42f1d6fa13 release/2024-11-01 - Misc fixes
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-29 10:53:09 -07:00
Dave Richer
f65993d097 Merged in release/2024-11-01 (pull request #1864)
release/2024-11-01 - Misc fixes
2024-10-29 16:55:24 +00:00
Dave Richer
3f247a9227 release/2024-11-01 - Misc fixes
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-29 09:54:45 -07:00
Dave Richer
f65ab128f9 Merged in release/2024-11-01 (pull request #1863)
release/2024-11-01 - Misc fixes
2024-10-29 15:26:19 +00:00
Dave Richer
63b914731b release/2024-11-01 - Misc fixes
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-29 08:25:54 -07:00
Dave Richer
b2a7fee021 Merged in release/2024-11-01 (pull request #1862)
release/2024-11-01 - Misc fixes
2024-10-29 15:20:46 +00:00
Dave Richer
23f8f69bbe release/2024-11-01 - Misc fixes
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-29 08:19:58 -07:00
Dave Richer
bcba161ab5 Merged in release/2024-11-01 (pull request #1861)
release/2024-11-01 - Misc fixes
2024-10-29 14:38:31 +00:00
Dave Richer
fc3ea2bdf8 release/2024-11-01 - Misc fixes
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-29 07:37:40 -07:00
Dave Richer
2f04ddc5de Merged in release/2024-11-01 (pull request #1860)
release/2024-11-01 - Misc fixes
2024-10-29 01:17:17 +00:00
Dave Richer
96e970faf7 release/2024-11-01 - Misc fixes
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-28 18:16:48 -07:00
Dave Richer
25d567fd2e Merged in release/2024-11-01 (pull request #1859)
release/2024-11-01 - Misc fixes
2024-10-29 00:49:09 +00:00
Dave Richer
c133195607 release/2024-11-01 - Misc fixes
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-28 17:48:43 -07:00
Dave Richer
84fa129396 Merged in release/2024-11-01 (pull request #1858)
release/2024-11-01 - Misc fixes
2024-10-29 00:39:46 +00:00
Dave Richer
d75ea2b1a6 release/2024-11-01 - Misc fixes
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-28 17:38:46 -07:00
Dave Richer
e6bc52acc6 Merged in release/2024-11-01 (pull request #1857)
Release/2024-11-01 into test-AIO - IO-2979-DST
2024-10-28 21:06:46 +00:00
Dave Richer
ec0fd840e4 Merged in feature/IO-2979-DST (pull request #1856)
IO-2979-DST into release/2024-11-01 - DST Related Fixes
2024-10-28 21:05:57 +00:00
Dave Richer
971a81fc27 feature/IO-2979-DST - Finish DST Stuff
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-28 14:04:14 -07:00
Dave Richer
19050d31f7 Merged in release/2024-11-01 (pull request #1853)
Release/2024-11-01 into master-AIO  - Fix Logging Issues
2024-10-28 20:39:28 +00:00
Dave Richer
e605433379 Merge remote-tracking branch 'origin/release/2024-11-01' into feature/IO-2979-DST 2024-10-28 13:10:08 -07:00
Dave Richer
fc3fc7fa9b Merged in release/2024-11-01 (pull request #1855)
release/2024-11-01 - Remove Trace Log Level
2024-10-28 20:07:35 +00:00
Dave Richer
b9ebb70b7a release/2024-11-01 - Remove Trace Log Level
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-28 13:06:47 -07:00
Dave Richer
3a4f18ef2d Merged in release/2024-11-01 (pull request #1854)
release/2024-11-01 - Remove Trace Log Level
2024-10-28 19:25:13 +00:00
Dave Richer
79ed6f2388 release/2024-11-01 - Remove Trace Log Level
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-28 12:24:40 -07:00
Dave Richer
2653db5404 Merged in release/2024-11-01 (pull request #1852)
release/2024-11-01 - Remove Trace Log Level
2024-10-28 19:05:23 +00:00
Dave Richer
785449a986 release/2024-11-01 - Remove Trace Log Level
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-28 12:03:48 -07:00
Dave Richer
0b7d469e0e feature/IO-2979-DST - Finish DST
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-28 11:55:13 -07:00
Dave Richer
a57156756e feature/IO-2979-DST - Normalize usages of dayjs to dayjs not day, move locale hook
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-28 11:03:30 -07:00
Dave Richer
6435d2f283 Merged in release/2024-11-01 (pull request #1851)
release/2024-11-01 - Adjust hostname check
2024-10-28 17:07:54 +00:00
Dave Richer
c4c30d98d4 release/2024-11-01 - Adjust hostname check
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-28 10:07:10 -07:00
Dave Richer
4c8e930eaa Merged in release/2024-11-01 (pull request #1850)
Release/2024-11-01 into test-AIO
2024-10-28 17:01:17 +00:00
Dave Richer
d4e8803b13 release/2024-11-01 - Adjust client body buffer size
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-28 09:47:27 -07:00
Dave Richer
1f2786ddec release/2024-11-01 - Fix some log things
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-28 09:31:37 -07:00
Dave Richer
fcd5183189 Merged in release/2024-10-25 (pull request #1849)
release/2024-10-25 - Add The local email viewer to the reference folder.
2024-10-26 04:48:24 +00:00
Dave Richer
e90cda07e4 Merged in release/2024-10-25 (pull request #1848)
Release/2024-10-25 - IO-2921, IO-2966, IO-2973, IO-2974, IO-2978, IO-2992, IO-2996, IO-2998
2024-10-26 04:48:05 +00:00
Dave Richer
9793daa04c release/2024-10-25 - Add The local email viewer to the reference folder.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-25 11:58:50 -07:00
Dave Richer
1c062f0310 Merged in release/2024-10-25 (pull request #1847)
Release/2024-10-25 into test-AIO - IO-2973
2024-10-25 18:54:08 +00:00
Allan Carr
117ced8fe7 Merged in feature/IO-2973-Created-By-Tasks (pull request #1846)
IO-2973 Created By Tasks

Approved-by: Dave Richer
2024-10-25 18:53:11 +00:00
Dave Richer
e7909205d1 feature/IO-2973-Created-By-Tasks - Merge in release, fix conflicts
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-25 11:50:11 -07:00
Dave Richer
18028a70ab feature/IO-2973-Created-By-Tasks - Merge in release, fix conflicts
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-25 11:22:59 -07:00
Dave Richer
eeb8d8d26f release/2024-10-25 - Clean up referenceDocuments
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-25 11:21:10 -07:00
Allan Carr
23659fc412 IO-2973 Created By Tasks
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-10-25 11:19:40 -07:00
Dave Richer
042fafe281 Merged in release/2024-10-25 (pull request #1845)
IO-2974 add comment to schedule.
2024-10-25 17:03:48 +00:00
Patrick Fic
ba65057782 Merged in feature/IO-2974-add-comment-to-schedule (pull request #1842)
IO-2974 add comment to schedule.

Approved-by: Dave Richer
2024-10-25 17:03:06 +00:00
Dave Richer
f5307c9a42 Merged in release/2024-10-25 (pull request #1844)
feature/IO-2998-enhanced-api-logging - Missing package
2024-10-25 15:39:13 +00:00
Dave Richer
60a859cac8 Merged in feature/IO-2998-enhanced-api-logging (pull request #1843)
feature/IO-2998-enhanced-api-logging - Missing package
2024-10-25 15:38:46 +00:00
Dave Richer
0cfe26093c feature/IO-2998-enhanced-api-logging - Missing package
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-25 08:37:56 -07:00
Patrick Fic
d085a9c7c9 IO-2974 add comment to schedule. 2024-10-25 08:33:17 -07:00
Dave Richer
9156c25f32 Merged in release/2024-10-25 (pull request #1841)
feature/IO-2998-enhanced-api-logging - Missing package
2024-10-25 15:30:44 +00:00
Dave Richer
ec518a0593 Merged in feature/IO-2998-enhanced-api-logging (pull request #1840)
feature/IO-2998-enhanced-api-logging - Missing package
2024-10-25 15:30:26 +00:00
Dave Richer
1cd64ab6f1 feature/IO-2998-enhanced-api-logging - Missing package
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-25 08:29:51 -07:00
Dave Richer
30d0c28f72 Merged in release/2024-10-25 (pull request #1839)
feature/IO-2998-enhanced-api-logging - Finish
2024-10-25 15:12:49 +00:00
Dave Richer
26836f662a Merged in feature/IO-2998-enhanced-api-logging (pull request #1838)
feature/IO-2998-enhanced-api-logging - Finish
2024-10-25 15:12:24 +00:00
Dave Richer
111f280674 feature/IO-2998-enhanced-api-logging - Finish
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-25 08:11:33 -07:00
Dave Richer
39bd490d43 Merged in release/2024-10-25 (pull request #1837)
Release/2024 10 25 IO-2998
2024-10-25 14:12:29 +00:00
Dave Richer
6e88faa9d8 Merged in feature/IO-2998-enhanced-api-logging (pull request #1836)
Feature/IO-2998 into Release/2024-10-25
2024-10-25 14:11:26 +00:00
Dave Richer
1ca8b2a78d feature/IO-2998-enhanced-api-logging - Finish
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-24 14:36:35 -07:00
Dave Richer
cd2a7cad7f feature/IO-2998-enhanced-api-logging - Finish
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-24 14:21:35 -07:00
Dave Richer
ed16156957 Merge remote-tracking branch 'origin/release/2024-10-25' into feature/IO-2998-enhanced-api-logging 2024-10-24 13:18:21 -07:00
Patrick Fic
8dc1f7e08f IO-2998 remove graylog and additional erroneous console logs. 2024-10-24 12:18:39 -07:00
Patrick Fic
2d3c13c587 IO-2998 Add winston and replace logger.js 2024-10-24 11:50:54 -07:00
Dave Richer
3015d06219 Merged in release/2024-10-25 (pull request #1835)
release/2024-10-25 into test-AIO - IO-2978
2024-10-24 16:50:42 +00:00
Allan Carr
5486907639 Merged in feature/IO-2978-Production-not-in-Production-Status (pull request #1834)
IO-2978 Production not in Production Status

Approved-by: Dave Richer
2024-10-24 16:49:59 +00:00
Allan Carr
9233cef23a IO-2978 Production not in Production Status
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-10-23 17:02:45 -07:00
Dave Richer
a0c814775a Merged in release/2024-10-25 (pull request #1833)
Release/2024-10-25 into test-AIO -IO-2921, IO-2966, IO-2992, IO-2996
2024-10-23 17:25:41 +00:00
Dave Richer
c16eafe892 Merged in feature/IO-2996-Package-Updates-Docker-Debugging (pull request #1832)
feature/IO-2996-Package-Updates-Docker-Debugging - Maintenance
2024-10-23 17:03:44 +00:00
Dave Richer
b479684fe4 feature/IO-2996-Package-Updates-Docker-Debugging - Maintenance
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-10-23 13:00:51 -04:00
Allan Carr
4201f61548 Merged in feature/IO-2966-Contract-Create-Page-Leave-Warning (pull request #1831)
IO-2966 Contract Create Page Leave Warning

Approved-by: Dave Richer
2024-10-23 14:58:22 +00:00
Allan Carr
d04fc76840 IO-2966 Contract Create Page Leave Warning
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-10-22 17:48:40 -07:00
Allan Carr
0f84adc752 IO-2966 Contract Create Page Leave Warning
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-10-22 17:35:54 -07:00
Allan Carr
fbefd80959 Merged in feature/IO-2921-CARSTAR-Canada-Chatter-Integration (pull request #1830)
IO-2921 CHATTER correct secertmanager call from undefined variable to string

Approved-by: Dave Richer
2024-10-22 15:08:11 +00:00
Allan Carr
6a691b54c8 Merged in feature/IO-2992-Bill-Line-UI-Table (pull request #1829)
IO-2992 Bill Line column Width with Word Breaks

Approved-by: Dave Richer
2024-10-22 15:07:43 +00:00
Allan Carr
fc75717d32 IO-2921 CHATTER correct secertmanager call from undefined variable to string
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-10-21 12:43:20 -07:00
Allan Carr
1459c6e993 Merge branch 'master-AIO' into feature/IO-2921-CARSTAR-Canada-Chatter-Integration
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-10-21 12:42:45 -07:00
Dave Richer
bff56ccc96 Merged in release/2024-10-18 (pull request #1827)
release/2024-10-18 into test-AIO - IO-2976
2024-10-18 19:27:03 +00:00
Dave Richer
34e5a86a79 Merged in release/2024-10-18 (pull request #1825)
Release/2024-10-18 into test-AIO - IO-2988 IO-2977
2024-10-18 16:32:02 +00:00
Dave Richer
1719da3402 Merged in release/2024-10-18 (pull request #1822)
Release/2024-10-18 into test-AIO - IO-2971, IO-2984, IO-2985, IO-2987, IO-2988
2024-10-18 01:57:29 +00:00
Dave Richer
8640b94714 Merged in release/2024-10-11 (pull request #1819)
Release/2024-10-11 - Release into test
2024-10-17 18:49:11 +00:00
Dave Richer
5593a9fa80 Merged in release/2024-10-11 (pull request #1810)
Release/2024 10 11
2024-10-12 03:01:34 +00:00
Dave Richer
b4bffcde2b Merged in release/2024-10-11 (pull request #1807)
feature/IO-2979-DST-Handling - Add LocalStack and Adjust local Emailing
2024-10-09 17:04:09 +00:00
Dave Richer
ff6e1d535b Merged in release/2024-10-11 (pull request #1805)
Release/2024-10-11 into test-AIO - IO-2962, IO-2967, IO-2972
2024-10-07 20:23:56 +00:00
Dave Richer
5b00ded5f6 hotfix/IO-2969-Fonts-For-Production - Register fonts
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-09-27 19:29:26 -04:00
Dave Richer
c5b19d8f22 hotfix/IO-2969-Fonts-For-Production - Register fonts
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-09-27 19:20:19 -04:00
Patrick Fic
4139626814 Merged in feature/IO-2924-Refactor-Production-board-to-use-Socket-Provider (pull request #1797)
Add try catch to PBS/CDK and main.
2024-09-27 16:23:11 +00:00
Dave Richer
d8dcc1a5dd Merged in release/2024-09-27 (pull request #1795)
IO-2924 update correct CORS URL.
2024-09-26 23:47:32 +00:00
Patrick Fic
0aca25802c Merged in release/2024-09-27 (pull request #1792)
Release/2024 09 27
2024-09-26 22:32:43 +00:00
Patrick Fic
0fdafdf1a6 Merged in release/2024-09-27 (pull request #1787)
Release/2024 09 27 IO-2924
2024-09-26 18:40:39 +00:00
Patrick Fic
0ccdc1ffb7 Merged in release/2024-09-27 (pull request #1785)
IO-2935 Correct CORS entries.
2024-09-25 19:33:46 +00:00
Patrick Fic
f455892a12 Merged in release/2024-09-27 (pull request #1783)
IO-2935 Resolve roll up issues.
2024-09-25 19:19:28 +00:00
Patrick Fic
06c1f55969 Merged in release/2024-09-27 (pull request #1781)
IO-2935 Comment unused visualizer during build.
2024-09-25 19:05:26 +00:00
Patrick Fic
2890c7d43c Merged in release/2024-09-27 (pull request #1779)
IO-2935 improve chunking for vite build.
2024-09-25 19:00:57 +00:00
Dave Richer
dfab2e5fed Merged in release/2024-09-27 (pull request #1777)
release/2024-09-27 into test-AIO - IO-2931, IO-2935, IO-2938
2024-09-25 18:15:24 +00:00
Dave Richer
4fc31f60b8 Merged in release/2024-09-27 (pull request #1775)
Release/2024-09-27 into test-AIO - IO-2931, IO-2935, IO-2938
2024-09-25 17:42:25 +00:00
Dave Richer
480a45a7ef Merged in release/2024-09-27 (pull request #1772)
Release/2024-09-27 into test-AIO - IO-2931
2024-09-24 14:43:13 +00:00
Patrick Fic
50df34a4dc Merged in feature/IO-2597-task-reminders (pull request #1768)
IO-2957 Resolve task reminders not sending with incorrect references.
2024-09-24 01:03:00 +00:00
Dave Richer
880d87707e Merged in release/2024-09-27 (pull request #1767)
Release/2024-09-27 into test-AIO - IO-2931
2024-09-23 23:28:40 +00:00
Patrick Fic
382492c284 Merged in feature/IO-2945-intellipaypostbackhandling (pull request #1763)
IO-2945 Resolve no success being sent to intellipay creating triple posting.

Approved-by: Patrick Fic
2024-09-23 22:05:15 +00:00
Dave Richer
b24a0ea2d7 Merged in release/2024-09-27 (pull request #1762)
Release/2024-09-27 into test-AIO
2024-09-23 20:44:49 +00:00
Dave Richer
d0df81796a Merged in release/2024-09-20 (pull request #1760)
IO-2782 Adjust to Object for items
2024-09-20 23:58:01 +00:00
Patrick Fic
190b1a64e8 Merged in release/2024-09-20 (pull request #1756)
Release/2024 09 20
2024-09-20 22:57:40 +00:00
Allan Carr
899699a38a Merged in release/2024-09-20 (pull request #1752)
Release/2024 09 20 IO-2933 IO-2928
2024-09-20 22:21:22 +00:00
Patrick Fic
ff2e4b9d3a Merged in release/2024-09-20 (pull request #1749)
Release/2024 09 20 IO-2934 IO-2920 IO-2936 IO-2933 IO-2921 IO-2939 IO-2933 IO-2949 IO-2928 IO-2782 IO-2948 IO-2932
2024-09-20 17:05:40 +00:00
Patrick Fic
8bb6898520 Merged in feature/IO-2950-prod-db-view (pull request #1743)
feature/IO-2950-prod-db-view

Approved-by: Patrick Fic
2024-09-19 20:18:57 +00:00
Patrick Fic
c3c7dfded8 Merged in feature/IO-2950-prod-db-view (pull request #1742)
IO-2950 Add subscription using view instead of variable.

Approved-by: Dave Richer
2024-09-19 20:13:06 +00:00
Dave Richer
6613abb024 Merged in release/2024-09-20 (pull request #1741)
Release/2024 09 20 IO-2934 IO-2920 IO-2936 IO-2920 IO-2933 IO-2921 IO-2939 IO-2932 IO-2782 IO-2948
2024-09-19 17:14:05 +00:00
Dave Richer
c9c4c2f2a2 Merged in release/2024-09-20 (pull request #1737)
Release 2024/09/20 - IO-2934 - IO-2920 - IO-2936 - IO-2920 - IO-2933 - IO-2939 IO-2932 - IO-2921
2024-09-18 19:48:37 +00:00
581 changed files with 39028 additions and 20325 deletions

View File

@@ -9,13 +9,13 @@ orbs:
jobs:
imex-api-deploy:
docker:
- image: cimg/node:18.18.2
- image: cimg/node:22.13.1
steps:
- checkout
- eb/setup
- run:
command: |
eb init imex-online-production-api -r ca-central-1 -p "Node.js 18 running on 64bit Amazon Linux 2"
eb init imex-online-production-api -r ca-central-1 -p "Node.js 22 running on 64bit Amazon Linux 2023"
eb status --verbose
eb deploy
eb status
@@ -28,7 +28,7 @@ jobs:
imex-hasura-migrate:
docker:
- image: cimg/node:18.18.2
- image: cimg/node:22.13.1
parameters:
secret:
type: string
@@ -52,7 +52,7 @@ jobs:
pipeline_number: << pipeline.number >>
imex-app-build:
docker:
- image: cimg/node:18.18.2
- image: cimg/node:22.13.1
resource_class: large
working_directory: ~/repo/client
steps:
@@ -77,7 +77,7 @@ jobs:
imex-app-beta-build:
docker:
- image: cimg/node:18.18.2
- image: cimg/node:22.13.1
resource_class: large
working_directory: ~/repo/client
@@ -88,7 +88,7 @@ jobs:
name: Install Dependencies
command: npm i
- run: npm run build:production:imex
- run: NODE_OPTIONS=--max-old-space-size=8192 npm run build:production:imex
- aws-cli/setup:
aws_access_key_id: AWS_ACCESS_KEY_ID
@@ -114,7 +114,7 @@ jobs:
- eb/setup
- run:
command: |
eb init romeonline-productionapi -r us-east-2 -p "Node.js 18 running on 64bit Amazon Linux 2"
eb init romeonline-productionapi -r us-east-2 -p "Node.js 22 running on 64bit Amazon Linux 2023"
eb status --verbose
eb deploy
eb status
@@ -126,7 +126,7 @@ jobs:
pipeline_number: << pipeline.number >>
rome-hasura-migrate:
docker:
- image: cimg/node:18.18.2
- image: cimg/node:22.13.1
parameters:
secret:
type: string
@@ -150,8 +150,8 @@ jobs:
pipeline_number: << pipeline.number >>
rome-app-build:
docker:
- image: cimg/node:18.18.2
- image: cimg/node:22.13.1
resource_class: large
working_directory: ~/repo/client
steps:
@@ -161,7 +161,7 @@ jobs:
name: Install Dependencies
command: npm i
- run: npm run build:production:rome
- run: NODE_OPTIONS=--max-old-space-size=8192 npm run build:production:rome
- aws-cli/setup:
aws_access_key_id: AWS_ACCESS_KEY_ID
@@ -179,40 +179,9 @@ jobs:
job_type: deployment
pipeline_number: << pipeline.number >>
promanager-app-build:
docker:
- image: cimg/node:18.18.2
working_directory: ~/repo/client
steps:
- checkout:
path: ~/repo
- run:
name: Install Dependencies
command: npm i
- run: npm run build:production:promanager
- aws-cli/setup:
aws_access_key_id: AWS_ACCESS_KEY_ID
aws_secret_access_key: AWS_SECRET_ACCESS_KEY
region: AWS_REGION
- aws-s3/sync:
from: dist
to: "s3://promanager-production/"
arguments: "--exclude '*.map'"
- jira/notify:
environment: Production (ProManager) - Front End
environment_type: production
pipeline_id: << pipeline.id >>
job_type: deployment
pipeline_number: << pipeline.number >>
test-rome-hasura-migrate:
docker:
- image: cimg/node:18.18.2
- image: cimg/node:22.13.1
parameters:
secret:
type: string
@@ -239,8 +208,8 @@ jobs:
test-rome-app-build:
docker:
- image: cimg/node:18.18.2
- image: cimg/node:22.13.1
resource_class: large
working_directory: ~/repo/client
steps:
@@ -250,7 +219,7 @@ jobs:
name: Install Dependencies
command: npm i
- run: npm run build:test:rome
- run: NODE_OPTIONS=--max-old-space-size=8192 npm run build:test:rome
- aws-cli/setup:
aws_access_key_id: AWS_ACCESS_KEY_ID
@@ -268,40 +237,9 @@ jobs:
job_type: deployment
pipeline_number: << pipeline.number >>
test-promanager-app-build:
docker:
- image: cimg/node:18.18.2
working_directory: ~/repo/client
steps:
- checkout:
path: ~/repo
- run:
name: Install Dependencies
command: npm i
- run: npm run build:test:promanager
- aws-cli/setup:
aws_access_key_id: AWS_ACCESS_KEY_ID
aws_secret_access_key: AWS_SECRET_ACCESS_KEY
region: AWS_REGION
- aws-s3/sync:
from: dist
to: "s3://promanager-testing/"
arguments: "--exclude '*.map'"
- jira/notify:
environment: Test (ProManager) - Front End
environment_type: testing
pipeline_id: << pipeline.id >>
job_type: deployment
pipeline_number: << pipeline.number >>
test-hasura-migrate:
docker:
- image: cimg/node:18.18.2
- image: cimg/node:22.13.1
parameters:
secret:
type: string
@@ -328,7 +266,7 @@ jobs:
imex-test-app-build:
docker:
- image: cimg/node:18.18.2
- image: cimg/node:22.13.1
resource_class: large
working_directory: ~/repo/client
@@ -339,7 +277,7 @@ jobs:
name: Install Dependencies
command: npm i
- run: npm run build:test:imex
- run: NODE_OPTIONS=--max-old-space-size=8192 npm run build:test:imex
- aws-s3/sync:
from: build
@@ -348,7 +286,7 @@ jobs:
imex-test-app-beta-build:
docker:
- image: cimg/node:18.18.2
- image: cimg/node:22.13.1
resource_class: large
working_directory: ~/repo/client
@@ -360,7 +298,7 @@ jobs:
name: Install Dependencies
command: npm i
- run: npm run build:test:imex
- run: NODE_OPTIONS=--max-old-space-size=8192 npm run build:test:imex
- aws-cli/setup:
aws_access_key_id: AWS_ACCESS_KEY_ID
@@ -458,14 +396,6 @@ workflows:
filters:
branches:
only: test-AIO
- test-promanager-app-build:
filters:
branches:
only: test-AIO
- promanager-app-build:
filters:
branches:
only: master-AIO
- test-rome-hasura-migrate:
secret: ${HASURA_ROME_TEST_SECRET}
filters:

80
.gitattributes vendored Normal file
View File

@@ -0,0 +1,80 @@
# Ensure all text files use LF for line endings
* text eol=lf
# Binary files should not be modified by Git
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.webp binary
*.svg binary
# Fonts
*.woff binary
*.woff2 binary
*.ttf binary
*.otf binary
*.eot binary
# Videos
*.mp4 binary
*.mov binary
*.avi binary
*.mkv binary
*.webm binary
# Audio
*.mp3 binary
*.wav binary
*.ogg binary
*.flac binary
# Archives and compressed files
*.zip binary
*.gz binary
*.tar binary
*.7z binary
*.rar binary
# PDF and documents
*.pdf binary
*.doc binary
*.docx binary
*.xls binary
*.xlsx binary
*.ppt binary
*.pptx binary
# Exclude JSON and other data files from text processing, if necessary
*.json text
*.xml text
*.csv text
# Scripts and code files should maintain LF endings
*.js text eol=lf
*.jsx text eol=lf
*.ts text eol=lf
*.tsx text eol=lf
*.css text eol=lf
*.scss text eol=lf
*.html text eol=lf
*.yml text eol=lf
*.yaml text eol=lf
*.md text eol=lf
*.sh text eol=lf
*.py text eol=lf
*.rb text eol=lf
*.java text eol=lf
*.php text eol=lf
# Git configuration files
.gitattributes text eol=lf
.gitignore text eol=lf
*.gitattributes text eol=lf
# Exclude some other potential binary files
*.db binary
*.sqlite binary
*.exe binary
*.dll binary

0
.localstack/.gitkeep Normal file
View File

View File

@@ -0,0 +1,24 @@
#!/bin/bash
# Install required packages
dnf install -y fontconfig freetype
# Move to the /tmp directory for temporary download and extraction
cd /tmp
# Download the Montserrat font zip file
wget https://images.imex.online/fonts/montserrat.zip -O montserrat.zip
# Unzip the downloaded font file
unzip montserrat.zip -d montserrat
# Move the font files to the system fonts directory
mv montserrat/montserrat/*.ttf /usr/share/fonts
# Rebuild the font cache
fc-cache -fv
# Clean up
rm -rf /tmp/montserrat /tmp/montserrat.zip
echo "Montserrat fonts installed and cached successfully."

View File

@@ -0,0 +1,5 @@
#!/bin/bash
DD_API_KEY=58d91898a70c6fd659f6eea768a57976 DD_SITE="us3.datadoghq.com" bash -c "$(curl -L https://install.datadoghq.com/scripts/install_script_agent7.sh)"
echo "Datadog agent installed."

View File

@@ -1 +1,2 @@
client_max_body_size 50M;
client_max_body_size 50M;
client_body_buffer_size 5M;

15
.vscode/launch.json vendored
View File

@@ -14,6 +14,21 @@
"request": "launch",
"url": "http://localhost:3000",
"webRoot": "${workspaceRoot}/client/src"
},
{
"name": "Attach to Node.js in Docker",
"type": "node",
"request": "attach",
"address": "localhost",
"port": 9229,
"localRoot": "${workspaceFolder}",
"remoteRoot": "/app",
"protocol": "inspector",
"restart": true,
"sourceMaps": true,
"skipFiles": [
"<node_internals>/**"
]
}
]
}

33
.vscode/settings.json vendored
View File

@@ -8,5 +8,36 @@
"pattern": "**/IMEX.xml",
"systemId": "logs/IMEX.xsd"
}
]
],
"cSpell.words": [
"antd",
"appointmentconfirmation",
"appt",
"autohouse",
"autohouseid",
"billlines",
"bodyshop",
"bodyshopid",
"bodyshops",
"CIECA",
"claimscorp",
"claimscorpid",
"Dinero",
"driveable",
"IMEX",
"imexshopid",
"jobid",
"joblines",
"Kaizen",
"labhrs",
"larhrs",
"mixdata",
"ownr",
"promanager",
"shopname",
"smartscheduling",
"timetickets",
"touchtime"
],
"eslint.workingDirectories": ["./", "./client"]
}

View File

@@ -3,11 +3,10 @@ FROM amazonlinux:2023
# Install Git and Node.js (Amazon Linux 2023 uses the DNF package manager)
RUN dnf install -y git \
&& curl -sL https://rpm.nodesource.com/setup_20.x | bash - \
&& curl -sL https://rpm.nodesource.com/setup_22.x | bash - \
&& dnf install -y nodejs \
&& dnf clean all
# Install dependencies required by node-canvas
RUN dnf install -y \
gcc \
@@ -19,9 +18,22 @@ RUN dnf install -y \
libpng-devel \
make \
python3 \
fontconfig \
freetype \
python3-pip \
wget \
unzip \
&& dnf clean all
# Install Montserrat fonts
RUN cd /tmp \
&& wget https://images.imex.online/fonts/montserrat.zip -O montserrat.zip \
&& unzip montserrat.zip -d montserrat \
&& mv montserrat/montserrat/*.ttf /usr/share/fonts \
&& fc-cache -fv \
&& rm -rf /tmp/montserrat /tmp/montserrat.zip \
&& echo "Montserrat fonts installed and cached successfully."
# Set the working directory
WORKDIR /app
@@ -41,7 +53,7 @@ RUN npm i --no-package-lock
COPY . .
# Expose the port your app runs on (adjust if necessary)
EXPOSE 4000
EXPOSE 4000 9229
# Start the application
CMD ["nodemon", "--legacy-watch", "server.js"]
CMD ["nodemon", "--legacy-watch", "--inspect=0.0.0.0:9229", "server.js"]

View File

@@ -10,5 +10,8 @@
"courtesycars": "date",
"media": "date",
"visualboard": "date",
"scoreboard": "date"
"scoreboard": "date",
"checklist": "date",
"smartscheduling" :"date",
"roguard": "date"
}

View File

@@ -0,0 +1 @@
node_modules

View File

@@ -0,0 +1,7 @@
This will connect to your dockers local stack session and render the email in HTML.
```shell
node index.js
```
http://localhost:3334

View File

@@ -0,0 +1,116 @@
// index.js
import express from 'express';
import fetch from 'node-fetch';
import {simpleParser} from 'mailparser';
const app = express();
const PORT = 3334;
app.get('/', async (req, res) => {
try {
const response = await fetch('http://localhost:4566/_aws/ses');
if (!response.ok) {
throw new Error('Network response was not ok');
}
const data = await response.json();
const messagesHtml = await parseMessages(data.messages);
res.send(renderHtml(messagesHtml));
} catch (error) {
console.error('Error fetching messages:', error);
res.status(500).send('Error fetching messages');
}
});
async function parseMessages(messages) {
const parsedMessages = await Promise.all(
messages.map(async (message, index) => {
try {
const parsed = await simpleParser(message.RawData);
return `
<div class="shadow-md rounded-lg p-4 mb-6" style="background-color: lightgray">
<div class="shadow-md rounded-lg p-4 mb-6" style="background-color: white">
<div class="mb-2">
<span class="font-bold text-lg">Message ${index + 1}</span>
</div>
<div class="mb-2">
<span class="font-semibold">From:</span> ${message.Source}
</div>
<div class="mb-2">
<span class="font-semibold">Region:</span> ${message.Region}
</div>
<div class="mb-2">
<span class="font-semibold">Timestamp:</span> ${message.Timestamp}
</div>
</div>
<div class="prose">
${parsed.html || parsed.textAsHtml || 'No HTML content available'}
</div>
</div>
`;
} catch (error) {
console.error('Error parsing email:', error);
return `
<div class="bg-white shadow-md rounded-lg p-4 mb-6">
<div class="mb-2">
<span class="font-bold text-lg">Message ${index + 1}</span>
</div>
<div class="mb-2">
<span class="font-semibold">From:</span> ${message.Source}
</div>
<div class="mb-2">
<span class="font-semibold">Region:</span> ${message.Region}
</div>
<div class="mb-2">
<span class="font-semibold">Timestamp:</span> ${message.Timestamp}
</div>
<div class="text-red-500">
Error parsing email content
</div>
</div>
`;
}
})
);
return parsedMessages.join('');
}
function renderHtml(messagesHtml) {
return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Email Messages Viewer</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body {
background-color: #f3f4f6;
font-family: Arial, sans-serif;
}
.container {
max-width: 800px;
margin: 50px auto;
padding: 20px;
}
.prose {
line-height: 1.6;
}
</style>
</head>
<body>
<div class="container bg-white shadow-lg rounded-lg p-6">
<h1 class="text-2xl font-bold text-center mb-6">Email Messages Viewer</h1>
<div id="messages-container">
${messagesHtml}
</div>
</div>
</body>
</html>
`;
}
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,18 @@
{
"name": "localemailviewer",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"express": "^4.21.1",
"mailparser": "^3.7.1",
"node-fetch": "^3.3.2"
}
}

File diff suppressed because it is too large Load Diff

27
certs/id_rsa.key Normal file
View File

@@ -0,0 +1,27 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
NhAAAAAwEAAQAAAQEAvNl5fuVmLNv72BZNxnTqX5CHf5Xi8UxjYaYxHITSCx7blnhpVYLd
qXvcOWXzbsfjch/den73QiW4n2FYz75oGMhUGlOYzdWKA9I9Sj09Qy1R06RhwDiZGd5qaM
swEeXpkNmi2u4Qd2kJeDfUQUigjC09V81O/vrniGtQAJScfiG/itdm+Ufn09Z4MYk0HWjq
iDokNEskoEPsibYIrb+Q6vdtuPkZO+wU/smXhPtgw5ST6oQdmm/gVNsRg5XNzxrire+z1G
WatnnVL3hPnnfpnf8W589dyms7GGJwhPerSGTN1bn0T4+9C69Cd7LBJtxiuFdRmdlGLLLP
RR48Rur71wAAA9AEfVsdBH1bHQAAAAdzc2gtcnNhAAABAQC82Xl+5WYs2/vYFk3GdOpfkI
d/leLxTGNhpjEchNILHtuWeGlVgt2pe9w5ZfNux+NyH916fvdCJbifYVjPvmgYyFQaU5jN
1YoD0j1KPT1DLVHTpGHAOJkZ3mpoyzAR5emQ2aLa7hB3aQl4N9RBSKCMLT1XzU7++ueIa1
AAlJx+Ib+K12b5R+fT1ngxiTQdaOqIOiQ0SySgQ+yJtgitv5Dq9224+Rk77BT+yZeE+2DD
lJPqhB2ab+BU2xGDlc3PGuKt77PUZZq2edUveE+ed+md/xbnz13KazsYYnCE96tIZM3Vuf
RPj70Lr0J3ssEm3GK4V1GZ2UYsss9FHjxG6vvXAAAAAwEAAQAAAQAQTosSLQbMmtY9S3e9
yjyusdExcCTfhyQRu4MEHmfws+JsNMuLqbgwOVTD1AzYJQR7x0qdmDcLjCxL/uDnV16vvS
Sd/Vf1dhnryIyoS29tzI0DRG94ZKq7tBvmHp1w/jRT4KcSVnovhW9e5Rs74+SRFhr06PKI
S+wQOIv48Nwue9+QUMsMCpWgKXHx7SHNTHvnAfqdhi9O29SWlMA+v+mELZ5Cl+HU0UTt2I
A1BxOe1N8FjN7KE2viJexsl3is1PuqMkpLl/wyHBJTVzUadl6DRALJQIm7/YO5goE72YOV
Lpo27do3zjhC87dlKdATvZUzfKV0LuUVdxq/PNDZMUbBAAAAgQDShAqDZiDrdTUaGXfUVm
QzcnVNbh2/KgZh4uux9QNHST562W6cnN7qxoRwVrM4BCOk1Kl73QQZW4nDvXX3PVC5j038
8AXkcBHS9j9f4h72ue7D2jqlbHFa7aGU9zYgk9mbBF+GX3tDntkAIQjLtwOLfj1iiJ/clX
mHFUAY1V4L8AAAAIEA3E4t/v0yU5D9AOI0r17UNYqfeyDoKAEDR4QbbFjO1l0kLnEJy7Zx
Mhj18GilYg2y0P0v8dSM/oWXS8Hua2t5i9Exlv6gHhGlQ80mwYcVGIxewZ/pPeCPw0U+kt
EKUjt09m9Oe7+6xHQsTBj9hY8/vqPmQwRalZFcLdhHiDiVKTcAAACBANtykaPXdVzEFx7D
UOlsjVL7zM0EVOFXf9JJQ6BhazhmsEI2PYt3IpgGMo8cXkoUofAOIYjf421AabN1BqSO5J
XTMxM0ZV3JmLLi804Mu9h1iFrVTBdLYOMJdc2VCo1EwHWpo9SXOyjxce/znvcIOU04aZhu
TaPg816X+E+gw5JhAAAAFGRhdmVARGF2ZVJpY2hlci1JTUVYAQIDBAUG
-----END OPENSSH PRIVATE KEY-----

1
certs/id_rsa.pub Normal file
View File

@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC82Xl+5WYs2/vYFk3GdOpfkId/leLxTGNhpjEchNILHtuWeGlVgt2pe9w5ZfNux+NyH916fvdCJbifYVjPvmgYyFQaU5jN1YoD0j1KPT1DLVHTpGHAOJkZ3mpoyzAR5emQ2aLa7hB3aQl4N9RBSKCMLT1XzU7++ueIa1AAlJx+Ib+K12b5R+fT1ngxiTQdaOqIOiQ0SySgQ+yJtgitv5Dq9224+Rk77BT+yZeE+2DDlJPqhB2ab+BU2xGDlc3PGuKt77PUZZq2edUveE+ed+md/xbnz13KazsYYnCE96tIZM3VufRPj70Lr0J3ssEm3GK4V1GZ2UYsss9FHjxG6vvX dave@DaveRicher-IMEX

12
certs/io-ftp-test.key Normal file
View File

@@ -0,0 +1,12 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAArAAAABNlY2RzYS
1zaGEyLW5pc3RwNTIxAAAACG5pc3RwNTIxAAAAhQQBYJnAujo17diR0fM2Ze1d1Ft6XHm5
U31pXdFEN+rGC4SoYTdZE8q3relxMS5GwwBOvgvVUuayfid2XS8ls/CMDiMBJAYqEK4CRY
PbbPB7lLnMWsF7muFhvs+SIpPQC+vtDwM2TKlxF0Y8p+iVRpvCADoggsSze7skmJWKmMTt
8jEdEOcAAAEQIyXsOSMl7DkAAAATZWNkc2Etc2hhMi1uaXN0cDUyMQAAAAhuaXN0cDUyMQ
AAAIUEAWCZwLo6Ne3YkdHzNmXtXdRbelx5uVN9aV3RRDfqxguEqGE3WRPKt63pcTEuRsMA
Tr4L1VLmsn4ndl0vJbPwjA4jASQGKhCuAkWD22zwe5S5zFrBe5rhYb7PkiKT0Avr7Q8DNk
ypcRdGPKfolUabwgA6IILEs3u7JJiVipjE7fIxHRDnAAAAQUO5dO9G7i0bxGTP0zV3eIwv
5g0NhrQJfW/bMHS6XWwaxdpr+QZ+DbBJVzZPwYC0wLMW4bJAf+kjqUnj4wGocoTeAAAAD2
lvLWZ0cC10ZXN0LWtleQECAwQ=
-----END OPENSSH PRIVATE KEY-----

View File

@@ -0,0 +1 @@
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAFgmcC6OjXt2JHR8zZl7V3UW3pceblTfWld0UQ36sYLhKhhN1kTyret6XExLkbDAE6+C9VS5rJ+J3ZdLyWz8IwOIwEkBioQrgJFg9ts8HuUucxawXua4WG+z5Iik9AL6+0PAzZMqXEXRjyn6JVGm8IAOiCCxLN7uySYlYqYxO3yMR0Q5w== io-ftp-test-key

12
certs/io-ftp-test.ppk Normal file
View File

@@ -0,0 +1,12 @@
PuTTY-User-Key-File-3: ecdsa-sha2-nistp521
Encryption: none
Comment: io-ftp-test-key
Public-Lines: 4
AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAFgmcC6OjXt
2JHR8zZl7V3UW3pceblTfWld0UQ36sYLhKhhN1kTyret6XExLkbDAE6+C9VS5rJ+
J3ZdLyWz8IwOIwEkBioQrgJFg9ts8HuUucxawXua4WG+z5Iik9AL6+0PAzZMqXEX
Rjyn6JVGm8IAOiCCxLN7uySYlYqYxO3yMR0Q5w==
Private-Lines: 2
AAAAQUO5dO9G7i0bxGTP0zV3eIwv5g0NhrQJfW/bMHS6XWwaxdpr+QZ+DbBJVzZP
wYC0wLMW4bJAf+kjqUnj4wGocoTe
Private-MAC: d67001d47e13c43dc8bdb9c68a25356a96c1c4a6714f3c5a1836fca646b78b54

View File

@@ -1,14 +0,0 @@
VITE_APP_GRAPHQL_ENDPOINT=https://db.dev.imex.online/v1/graphql
VITE_APP_GRAPHQL_ENDPOINT_WS=wss://db.dev.imex.online/v1/graphql
VITE_APP_GA_CODE=231099835
VITE_APP_FIREBASE_CONFIG={"apiKey":"AIzaSyDPLT8GiDHDR1R4nI66Qi0BY1aYviDPioc","authDomain":"imex-dev.firebaseapp.com","databaseURL":"https://imex-dev.firebaseio.com","projectId":"imex-dev","storageBucket":"imex-dev.appspot.com","messagingSenderId":"759548147434","appId":"1:759548147434:web:e8239868a48ceb36700993","measurementId":"G-K5XRBVVB4S"}
VITE_APP_CLOUDINARY_ENDPOINT_API=https://api.cloudinary.com/v1_1/io-test
VITE_APP_CLOUDINARY_ENDPOINT=https://res.cloudinary.com/io-test
VITE_APP_CLOUDINARY_API_KEY=957865933348715
VITE_APP_CLOUDINARY_THUMB_TRANSFORMATIONS=c_fill,h_250,w_250
VITE_APP_FIREBASE_PUBLIC_VAPID_KEY='BG3tzU7L2BXlGZ_3VLK4PNaRceoEXEnmHfxcVbRMF5o5g05ejslhVPki9kBM9cBBT-08Ad9kN3HSpS6JmrWD6h4'
VITE_APP_STRIPE_PUBLIC_KEY=pk_test_51GqB4TJl3nQjrZ0wCQWAxAhlNF8jKe0tipIa6ExBaxwJGitwvFsIZUEua4dUzaMIAuXp4qwYHXx7lgjyQSwP0Pe900vzm38C7g
VITE_APP_AXIOS_BASE_API_URL=/api/
VITE_APP_REPORTS_SERVER_URL=https://reports3.test.imex.online
VITE_APP_SPLIT_API=ts615lqgnmk84thn72uk18uu5pgce6e0l4rc
VITE_APP_INSTANCE=PROMANAGER

View File

@@ -1,15 +0,0 @@
GENERATE_SOURCEMAP=true
VITE_APP_GRAPHQL_ENDPOINT=https://db.romeonline.io/v1/graphql
VITE_APP_GRAPHQL_ENDPOINT_WS=wss://db.romeonline.io/v1/graphql
VITE_APP_GA_CODE=231103507
VITE_APP_FIREBASE_CONFIG={ "apiKey": "AIzaSyAuLQR9SV5LsVxjU8wh9hvFLdhcAHU6cxE", "authDomain": "rome-prod-1.firebaseapp.com", "projectId": "rome-prod-1", "storageBucket": "rome-prod-1.appspot.com", "messagingSenderId": "147786367145", "appId": "1:147786367145:web:9d4cba68071c3f29a8a9b8", "measurementId": "G-G8Z9DRHTZS"}
VITE_APP_CLOUDINARY_ENDPOINT_API=https://api.cloudinary.com/v1_1/bodyshop
VITE_APP_CLOUDINARY_ENDPOINT=https://res.cloudinary.com/bodyshop
VITE_APP_CLOUDINARY_API_KEY=473322739956866
VITE_APP_CLOUDINARY_THUMB_TRANSFORMATIONS=c_fill,h_250,w_250
VITE_APP_FIREBASE_PUBLIC_VAPID_KEY='BMgZT1NZztW2DsJl8Mg2L04hgY9FzAg6b8fbzgNAfww2VDzH3VE63Ot9EaP_U7KWS2JT-7HPHaw0T_Tw_5vkZc8'
VITE_APP_STRIPE_PUBLIC_KEY=pk_test_51GqB4TJl3nQjrZ0wCQWAxAhlNF8jKe0tipIa6ExBaxwJGitwvFsIZUEua4dUzaMIAuXp4qwYHXx7lgjyQSwP0Pe900vzm38C7g
VITE_APP_AXIOS_BASE_API_URL=https://api.romeonline.io/
VITE_APP_REPORTS_SERVER_URL=https://reports.romeonline.io
VITE_APP_SPLIT_API=et9pjkik6bn67he5evpmpr1agoo7gactphgk
VITE_APP_INSTANCE=PROMANAGER

View File

@@ -1,15 +0,0 @@
VITE_APP_GRAPHQL_ENDPOINT=https://db.test.romeonline.io/v1/graphql
VITE_APP_GRAPHQL_ENDPOINT_WS=wss://db.test.romeonline.io/v1/graphql
VITE_APP_GA_CODE=231099835
VITE_APP_FIREBASE_CONFIG={ "apiKey": "AIzaSyAuLQR9SV5LsVxjU8wh9hvFLdhcAHU6cxE", "authDomain": "rome-prod-1.firebaseapp.com", "projectId": "rome-prod-1", "storageBucket": "rome-prod-1.appspot.com", "messagingSenderId": "147786367145", "appId": "1:147786367145:web:9d4cba68071c3f29a8a9b8", "measurementId": "G-G8Z9DRHTZS"}
VITE_APP_CLOUDINARY_ENDPOINT_API=https://api.cloudinary.com/v1_1/bodyshop
VITE_APP_CLOUDINARY_ENDPOINT=https://res.cloudinary.com/bodyshop
VITE_APP_CLOUDINARY_API_KEY=473322739956866
VITE_APP_CLOUDINARY_THUMB_TRANSFORMATIONS=c_fill,h_250,w_250
VITE_APP_FIREBASE_PUBLIC_VAPID_KEY='BN2GcDPjipR5MTEosO5dT4CfQ3cmrdBIsI4juoOQrRijn_5aRiHlwj1mlq0W145mOusx6xynEKl_tvYJhpCc9lo'
VITE_APP_STRIPE_PUBLIC_KEY=pk_test_51GqB4TJl3nQjrZ0wCQWAxAhlNF8jKe0tipIa6ExBaxwJGitwvFsIZUEua4dUzaMIAuXp4qwYHXx7lgjyQSwP0Pe900vzm38C7g
VITE_APP_AXIOS_BASE_API_URL=https://api.test.romeonline.io/
VITE_APP_REPORTS_SERVER_URL=https://reports.test.romeonline.io
VITE_APP_IS_TEST=true
VITE_APP_SPLIT_API=ts615lqgnmk84thn72uk18uu5pgce6e0l4rc
VITE_APP_INSTANCE=PROMANAGER

21
client/eslint.config.js Normal file
View File

@@ -0,0 +1,21 @@
import globals from "globals";
import pluginJs from "@eslint/js";
import pluginReact from "eslint-plugin-react";
/** @type {import('eslint').Linter.Config[]} */
export default [
{
files: ["**/*.{js,mjs,cjs,jsx}"]
},
{ languageOptions: { globals: globals.browser } },
pluginJs.configs.recommended,
{
...pluginReact.configs.flat.recommended,
rules: {
...pluginReact.configs.flat.recommended.rules,
"react/prop-types": 0
}
},
pluginReact.configs.flat["jsx-runtime"]
];

View File

@@ -1,29 +1,26 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<% if (env.VITE_APP_INSTANCE === 'IMEX') { %>
<link rel="icon" href="/favicon.png"/>
<% } %> <% if (env.VITE_APP_INSTANCE === 'ROME') { %>
<link rel="icon" href="/ro-favicon.png"/>
<% } %> <% if (env.VITE_APP_INSTANCE === 'PROMANAGER') { %>
<link rel="icon" href="/pm/pm-favicon.ico"/>
<% } %>
<head>
<meta charset="utf-8" />
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<% if (env.VITE_APP_INSTANCE === 'IMEX') { %>
<link rel="icon" href="/favicon.png" />
<% } %> <% if (env.VITE_APP_INSTANCE === 'ROME') { %>
<link rel="icon" href="/ro-favicon.png" />
<% } %>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="theme-color" content="#1690ff"/>
<!-- <link rel="apple-touch-icon" href="logo192.png" /> -->
<!-- TODO:AIo Update the individual logos for each.-->
<link rel="apple-touch-icon" href="/logo192.png"/>
<link rel="mask-icon" href="/mask-icon.svg" color="#FFFFFF">
<!--
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#1690ff" />
<!-- <link rel="apple-touch-icon" href="logo192.png" /> -->
<link rel="apple-touch-icon" href="/logo192.png" />
<link rel="mask-icon" href="/mask-icon.svg" color="#FFFFFF" />
<!--
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/
-->
<!--
<!--
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.
@@ -32,95 +29,100 @@
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`.
-->
<% if (env.VITE_APP_INSTANCE === 'IMEX') { %>
<meta name="description" content="ImEX Online"/>
<title>ImEX Online</title>
<script type="text/javascript">
window.$crisp = [];
window.CRISP_WEBSITE_ID = '36724f62-2eb0-4b29-9cdd-9905fb99913e';
(function () {
d = document;
s = d.createElement('script');
s.src = 'https://client.crisp.chat/l.js';
s.async = 1;
d.getElementsByTagName('head')[0].appendChild(s);
})();
</script>
<% } %> <% if (env.VITE_APP_INSTANCE === 'ROME') { %>
<meta name="description" content="Rome Online"/>
<title>Rome Online</title>
<script type="text/javascript" id="zsiqchat">
var $zoho = $zoho || {};
$zoho.salesiq = $zoho.salesiq || {
widgetcode: "siq01bb8ac617280bdacddfeb528f07734dadc64ef3f05efef9f769c1ec171af666",
values: {},
ready: function () {
}
};
var d = document;
s = d.createElement("script");
s.type = "text/javascript";
s.id = "zsiqscript";
s.defer = true;
s.src = "https://salesiq.zohopublic.com/widget";
t = d.getElementsByTagName("script")[0];
t.parentNode.insertBefore(s, t);
</script>
<% if (env.VITE_APP_INSTANCE === 'IMEX') { %>
<meta name="description" content="ImEX Online" />
<title>ImEX Online</title>
<script type="text/javascript">
window.$crisp = [];
window.CRISP_WEBSITE_ID = "36724f62-2eb0-4b29-9cdd-9905fb99913e";
(function () {
d = document;
s = d.createElement("script");
s.src = "https://client.crisp.chat/l.js";
s.async = 1;
d.getElementsByTagName("head")[0].appendChild(s);
})();
</script>
<% } %> <% if (env.VITE_APP_INSTANCE === 'ROME') { %>
<meta name="description" content="Rome Online" />
<title>Rome Online</title>
<script type="text/javascript" id="zsiqchat">
var $zoho = $zoho || {};
$zoho.salesiq = $zoho.salesiq || {
widgetcode: "siq01bb8ac617280bdacddfeb528f07734dadc64ef3f05efef9f769c1ec171af666",
values: {},
ready: function () {}
};
var d = document;
s = d.createElement("script");
s.type = "text/javascript";
s.id = "zsiqscript";
s.defer = true;
s.src = "https://salesiq.zohopublic.com/widget";
t = d.getElementsByTagName("script")[0];
t.parentNode.insertBefore(s, t);
</script>
<script type="text/javascript">
window.$crisp = [];
window.CRISP_WEBSITE_ID = "36724f62-2eb0-4b29-9cdd-9905fb99913e";
(function () {
d = document;
s = d.createElement("script");
s.src = "https://client.crisp.chat/l.js";
s.async = 1;
d.getElementsByTagName("head")[0].appendChild(s);
})();
</script>
<% } %>
<script>
!(function () {
"use strict";
var e = [
"debug",
"destroy",
"do",
"help",
"identify",
"is",
"off",
"on",
"ready",
"render",
"reset",
"safe",
"set"
];
if (window.noticeable) console.warn("Noticeable SDK code snippet loaded more than once");
else {
var n = (window.noticeable = window.noticeable || []);
<% } %> <% if (env.VITE_APP_INSTANCE === 'PROMANAGER') { %>
<title>ProManager</title>
<meta name="description" content="ProManager"/>
<% } %>
<script>
!(function () {
'use strict';
var e = [
'debug',
'destroy',
'do',
'help',
'identify',
'is',
'off',
'on',
'ready',
'render',
'reset',
'safe',
'set',
];
if (window.noticeable) console.warn('Noticeable SDK code snippet loaded more than once');
else {
var n = (window.noticeable = window.noticeable || []);
function t(e) {
return function () {
var t = Array.prototype.slice.call(arguments);
return t.unshift(e), n.push(t), n;
};
}
!(function () {
for (var o = 0; o < e.length; o++) {
var r = e[o];
n[r] = t(r);
function t(e) {
return function () {
var t = Array.prototype.slice.call(arguments);
return t.unshift(e), n.push(t), n;
};
}
})(),
(function () {
var e = document.createElement('script');
(e.async = !0), (e.src = 'https://sdk.noticeable.io/l.js');
var n = document.head;
n.insertBefore(e, n.firstChild);
})();
}
})();
</script>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="src/index.jsx"></script>
</body>
!(function () {
for (var o = 0; o < e.length; o++) {
var r = e[o];
n[r] = t(r);
}
})(),
(function () {
var e = document.createElement("script");
(e.async = !0), (e.src = "https://sdk.noticeable.io/l.js");
var n = document.head;
n.insertBefore(e, n.firstChild);
})();
}
})();
</script>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="src/index.jsx"></script>
</body>
</html>

9591
client/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -8,78 +8,78 @@
"private": true,
"proxy": "http://localhost:4000",
"dependencies": {
"@ant-design/pro-layout": "^7.19.12",
"@apollo/client": "^3.11.8",
"@ant-design/pro-layout": "^7.22.3",
"@apollo/client": "^3.13.1",
"@emotion/is-prop-valid": "^1.3.1",
"@fingerprintjs/fingerprintjs": "^4.5.0",
"@fingerprintjs/fingerprintjs": "^4.6.1",
"@jsreport/browser-client": "^3.1.0",
"@reduxjs/toolkit": "^2.2.7",
"@sentry/cli": "^2.36.2",
"@sentry/react": "^7.114.0",
"@reduxjs/toolkit": "^2.6.0",
"@sentry/cli": "^2.42.2",
"@sentry/react": "^9.3.0",
"@sentry/vite-plugin": "^3.2.2",
"@splitsoftware/splitio-react": "^1.13.0",
"@tanem/react-nprogress": "^5.0.51",
"@vitejs/plugin-react": "^4.3.1",
"antd": "^5.20.1",
"@tanem/react-nprogress": "^5.0.53",
"@vitejs/plugin-react": "^4.3.4",
"antd": "^5.24.2",
"apollo-link-logger": "^2.0.1",
"apollo-link-sentry": "^3.3.0",
"apollo-link-sentry": "^4.1.0",
"autosize": "^6.0.1",
"axios": "^1.7.7",
"axios": "^1.8.1",
"classnames": "^2.5.1",
"css-box-model": "^1.2.1",
"dayjs": "^1.11.13",
"dayjs-business-days2": "^1.2.2",
"dayjs-business-days2": "^1.3.0",
"dinero.js": "^1.9.1",
"dotenv": "^16.4.5",
"dotenv": "^16.4.7",
"env-cmd": "^10.1.0",
"exifr": "^7.1.3",
"firebase": "^10.13.2",
"graphql": "^16.9.0",
"graphql": "^16.10.0",
"i18next": "^23.15.1",
"i18next-browser-languagedetector": "^8.0.0",
"i18next-browser-languagedetector": "^8.0.4",
"immutability-helper": "^3.1.1",
"libphonenumber-js": "^1.11.9",
"libphonenumber-js": "^1.12.4",
"logrocket": "^8.1.2",
"markerjs2": "^2.32.2",
"markerjs2": "^2.32.3",
"memoize-one": "^6.0.0",
"normalize-url": "^8.0.1",
"object-hash": "^3.0.0",
"prop-types": "^15.8.1",
"query-string": "^9.1.0",
"query-string": "^9.1.1",
"raf-schd": "^4.0.3",
"react": "^18.3.1",
"react-big-calendar": "^1.14.1",
"react-big-calendar": "^1.18.0",
"react-color": "^2.19.3",
"react-cookie": "^7.2.0",
"react-cookie": "^7.2.2",
"react-dom": "^18.3.1",
"react-drag-listview": "^2.0.0",
"react-grid-gallery": "^1.0.1",
"react-grid-layout": "1.3.4",
"react-i18next": "^14.1.3",
"react-icons": "^5.3.0",
"react-icons": "^5.5.0",
"react-image-lightbox": "^5.1.4",
"react-markdown": "^9.0.1",
"react-number-format": "^5.4.2",
"react-markdown": "^9.0.3",
"react-number-format": "^5.4.3",
"react-popopo": "^2.1.9",
"react-product-fruits": "^2.2.61",
"react-redux": "^9.1.2",
"react-redux": "^9.2.0",
"react-resizable": "^3.0.5",
"react-router-dom": "^6.26.2",
"react-router-dom": "^6.30.0",
"react-sticky": "^6.0.3",
"react-virtualized": "^9.22.5",
"react-virtuoso": "^4.10.4",
"recharts": "^2.12.7",
"react-virtuoso": "^4.12.5",
"recharts": "^2.15.0",
"redux": "^5.0.1",
"redux-actions": "^3.0.3",
"redux-persist": "^6.0.0",
"redux-saga": "^1.3.0",
"redux-state-sync": "^3.1.4",
"reselect": "^5.1.1",
"sass": "^1.79.3",
"socket.io-client": "^4.8.0",
"styled-components": "^6.1.13",
"sass": "^1.85.1",
"socket.io-client": "^4.8.1",
"styled-components": "^6.1.15",
"subscriptions-transport-ws": "^0.11.0",
"use-memo-one": "^1.1.3",
"userpilot": "^1.3.6",
"userpilot": "^1.3.8",
"vite-plugin-ejs": "^1.7.0",
"web-vitals": "^3.5.2"
},
@@ -90,28 +90,16 @@
"build": "dotenvx run --env-file=.env.development.imex -- vite build",
"start:imex": "dotenvx run --env-file=.env.development.imex -- vite",
"start:rome": "dotenvx run --env-file=.env.development.rome -- vite",
"start:promanager": "dotenvx run --env-file=.env.development.promanager -- vite",
"preview:imex": "dotenvx run --env-file=.env.development.imex -- vite preview",
"preview:rome": "dotenvx run --env-file=.env.development.rome -- vite preview",
"preview:promanager": "dotenvx run --env-file=.env.development.promanager -- vite preview",
"build:test:imex": "env-cmd -f .env.test.imex npm run build",
"build:test:rome": "env-cmd -f .env.test.rome npm run build",
"build:test:promanager": "env-cmd -f .env.test.promanager npm run build",
"build:production:imex": "env-cmd -f .env.production.imex npm run build",
"build:production:rome": "env-cmd -f .env.production.rome npm run build",
"build:production:promanager": "env-cmd -f .env.production.promanager npm run build",
"test": "cypress open",
"eject": "react-scripts eject",
"madge": "madge --image ./madge-graph.svg --extensions js,jsx,ts,tsx --circular .",
"eulaize": "node src/utils/eulaize.js",
"sentry:sourcemaps:imex": "sentry-cli sourcemaps inject --org imex --project imexonline ./build && sentry-cli sourcemaps upload --org imex --project imexonline ./build"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest",
"plugin:cypress/recommended"
]
"eulaize": "node src/utils/eulaize.js"
},
"browserslist": {
"production": [
@@ -132,32 +120,36 @@
"@rollup/rollup-linux-x64-gnu": "4.6.1"
},
"devDependencies": {
"@ant-design/icons": "^5.6.1",
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@babel/preset-react": "^7.24.7",
"@dotenvx/dotenvx": "^1.14.1",
"@emotion/babel-plugin": "^11.12.0",
"@emotion/react": "^11.13.3",
"@sentry/webpack-plugin": "^2.22.4",
"@babel/preset-react": "^7.26.3",
"@dotenvx/dotenvx": "^1.38.3",
"@emotion/babel-plugin": "^11.13.5",
"@emotion/react": "^11.14.0",
"@eslint/js": "^9.21.0",
"@sentry/webpack-plugin": "^3.2.2",
"@testing-library/cypress": "^10.0.2",
"browserslist": "^4.23.3",
"browserslist": "^4.24.4",
"browserslist-to-esbuild": "^2.1.1",
"chalk": "^5.3.0",
"chalk": "^5.4.1",
"cross-env": "^7.0.3",
"cypress": "^13.14.2",
"eslint": "^8.57.0",
"cypress": "^13.17.0",
"eslint": "^8.57.1",
"eslint-config-react-app": "^7.0.1",
"eslint-plugin-cypress": "^2.15.1",
"memfs": "^4.12.0",
"eslint-plugin-react": "^7.37.4",
"globals": "^15.15.0",
"memfs": "^4.17.0",
"os-browserify": "^0.3.0",
"react-error-overlay": "6.0.11",
"react-error-overlay": "^6.1.0",
"redux-logger": "^3.0.6",
"source-map-explorer": "^2.5.3",
"vite": "^5.4.7",
"vite-plugin-babel": "^1.2.0",
"vite": "^6.2.0",
"vite-plugin-babel": "^1.3.0",
"vite-plugin-eslint": "^1.8.1",
"vite-plugin-node-polyfills": "^0.22.0",
"vite-plugin-pwa": "^0.20.5",
"vite-plugin-node-polyfills": "^0.23.0",
"vite-plugin-pwa": "^0.21.1",
"vite-plugin-style-import": "^2.0.0",
"workbox-window": "^7.1.0"
"workbox-window": "^7.3.0"
}
}

View File

@@ -1,6 +1,6 @@
// Scripts for firebase and firebase messaging
importScripts("https://www.gstatic.com/firebasejs/8.2.0/firebase-app.js");
importScripts("https://www.gstatic.com/firebasejs/8.2.0/firebase-messaging.js");
importScripts("https://www.gstatic.com/firebasejs/10.14.1/firebase-app-compat.js");
importScripts("https://www.gstatic.com/firebasejs/10.14.1/firebase-messaging-compat.js");
// Initialize the Firebase app in the service worker by passing the generated config
let firebaseConfig;
@@ -14,7 +14,7 @@ switch (this.location.hostname) {
storageBucket: "imex-dev.appspot.com",
messagingSenderId: "759548147434",
appId: "1:759548147434:web:e8239868a48ceb36700993",
measurementId: "G-K5XRBVVB4S",
measurementId: "G-K5XRBVVB4S"
};
break;
case "test.imex.online":
@@ -24,7 +24,7 @@ switch (this.location.hostname) {
projectId: "imex-test",
storageBucket: "imex-test.appspot.com",
messagingSenderId: "991923618608",
appId: "1:991923618608:web:633437569cdad78299bef5",
appId: "1:991923618608:web:633437569cdad78299bef5"
// measurementId: "${config.measurementId}",
};
break;
@@ -38,7 +38,7 @@ switch (this.location.hostname) {
storageBucket: "imex-prod.appspot.com",
messagingSenderId: "253497221485",
appId: "1:253497221485:web:3c81c483b94db84b227a64",
measurementId: "G-NTWBKG2L0M",
measurementId: "G-NTWBKG2L0M"
};
}
@@ -49,8 +49,6 @@ const messaging = firebase.messaging();
messaging.onBackgroundMessage(function (payload) {
// Customize notification here
const channel = new BroadcastChannel("imex-sw-messages");
channel.postMessage(payload);
//self.registration.showNotification(notificationTitle, notificationOptions);
console.log("[firebase-messaging-sw.js] Received background message ", payload);
self.registration.showNotification(notificationTitle, notificationOptions);
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -2,8 +2,6 @@ import { ApolloProvider } from "@apollo/client";
import { SplitFactoryProvider, SplitSdk } from "@splitsoftware/splitio-react";
import { ConfigProvider } from "antd";
import enLocale from "antd/es/locale/en_US";
import dayjs from "../utils/day";
import "dayjs/locale/en";
import React from "react";
import { useTranslation } from "react-i18next";
import GlobalLoadingBar from "../components/global-loading-bar/global-loading-bar.component";
@@ -19,8 +17,6 @@ if (import.meta.env.DEV) {
Userpilot.initialize("NX-69145f08");
}
dayjs.locale("en");
const config = {
core: {
authorizationKey: import.meta.env.VITE_APP_SPLIT_API,

View File

@@ -1,10 +1,10 @@
import { useSplitClient } from "@splitsoftware/splitio-react";
import { Button, Result } from "antd";
import LogRocket from "logrocket";
import React, { lazy, Suspense, useEffect, useState } from "react";
import { lazy, Suspense, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { Route, Routes } from "react-router-dom";
import { Route, Routes, useNavigate } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import DocumentEditorContainer from "../components/document-editor/document-editor.container";
import ErrorBoundary from "../components/error-boundary/error-boundary.component"; // Component Imports
@@ -21,7 +21,8 @@ import "./App.styles.scss";
import Eula from "../components/eula/eula.component";
import InstanceRenderMgr from "../utils/instanceRenderMgr";
import ProductFruitsWrapper from "./ProductFruitsWrapper.jsx";
import { SocketProvider } from "../contexts/SocketIO/socketContext.jsx";
import { SocketProvider } from "../contexts/SocketIO/useSocket.jsx";
import { NotificationProvider } from "../contexts/Notifications/notificationContext.jsx";
const ResetPassword = lazy(() => import("../pages/reset-password/reset-password.component"));
const ManagePage = lazy(() => import("../pages/manage/manage.page.container"));
@@ -45,6 +46,7 @@ export function App({ bodyshop, checkUserSession, currentUser, online, setOnline
const client = useSplitClient().client;
const [listenersAdded, setListenersAdded] = useState(false);
const { t } = useTranslation();
const navigate = useNavigate();
useEffect(() => {
if (!navigator.onLine) {
@@ -96,8 +98,7 @@ export function App({ bodyshop, checkUserSession, currentUser, online, setOnline
LogRocket.init(
InstanceRenderMgr({
imex: "gvfvfw/bodyshopapp",
rome: "rome-online/rome-online",
promanager: "" // TODO: AIO Add in log rocket for promanager instances.
rome: "rome-online/rome-online"
})
);
}
@@ -134,8 +135,7 @@ export function App({ bodyshop, checkUserSession, currentUser, online, setOnline
<LoadingSpinner
message={InstanceRenderMgr({
imex: t("titles.imexonline"),
rome: t("titles.romeonline"),
promanager: t("titles.promanager")
rome: t("titles.romeonline")
})}
/>
}
@@ -144,88 +144,88 @@ export function App({ bodyshop, checkUserSession, currentUser, online, setOnline
currentUser={currentUser}
workspaceCode={InstanceRenderMgr({
imex: null,
rome: "9BkbEseqNqxw8jUH",
promanager: "aoJoEifvezYI0Z0P"
rome: "9BkbEseqNqxw8jUH"
})}
/>
<Routes>
<Route
path="*"
element={
<ErrorBoundary>
<LandingPage />
</ErrorBoundary>
}
/>
<Route
path="/signin"
element={
<ErrorBoundary>
<SignInPage />
</ErrorBoundary>
}
/>
<Route
path="/resetpassword"
element={
<ErrorBoundary>
<ResetPassword />
</ErrorBoundary>
}
/>
<Route
path="/csi/:surveyId"
element={
<ErrorBoundary>
<CsiPage />
</ErrorBoundary>
}
/>
<Route
path="/disclaimer"
element={
<ErrorBoundary>
<DisclaimerPage />
</ErrorBoundary>
}
/>
<Route
path="/mp/:paymentIs"
element={
<ErrorBoundary>
<MobilePaymentContainer />
</ErrorBoundary>
}
/>
<Route
path="/manage/*"
element={
<ErrorBoundary>
<SocketProvider bodyshop={bodyshop}>
<PrivateRoute isAuthorized={currentUser.authorized} />
</SocketProvider>
</ErrorBoundary>
}
>
<Route path="*" element={<ManagePage />} />
</Route>
<Route
path="/tech/*"
element={
<ErrorBoundary>
<SocketProvider bodyshop={bodyshop}>
<PrivateRoute isAuthorized={currentUser.authorized} />
</SocketProvider>
</ErrorBoundary>
}
>
<Route path="*" element={<TechPageContainer />} />
</Route>
<Route path="/edit/*" element={<PrivateRoute isAuthorized={currentUser.authorized} />}>
<Route path="*" element={<DocumentEditorContainer />} />
</Route>
</Routes>
<NotificationProvider>
<Routes>
<Route
path="*"
element={
<ErrorBoundary>
<LandingPage />
</ErrorBoundary>
}
/>
<Route
path="/signin"
element={
<ErrorBoundary>
<SignInPage />
</ErrorBoundary>
}
/>
<Route
path="/resetpassword"
element={
<ErrorBoundary>
<ResetPassword />
</ErrorBoundary>
}
/>
<Route
path="/csi/:surveyId"
element={
<ErrorBoundary>
<CsiPage />
</ErrorBoundary>
}
/>
<Route
path="/disclaimer"
element={
<ErrorBoundary>
<DisclaimerPage />
</ErrorBoundary>
}
/>
<Route
path="/mp/:paymentIs"
element={
<ErrorBoundary>
<MobilePaymentContainer />
</ErrorBoundary>
}
/>
<Route
path="/manage/*"
element={
<ErrorBoundary>
<SocketProvider bodyshop={bodyshop} navigate={navigate} currentUser={currentUser}>
<PrivateRoute isAuthorized={currentUser.authorized} />
</SocketProvider>
</ErrorBoundary>
}
>
<Route path="*" element={<ManagePage />} />
</Route>
<Route
path="/tech/*"
element={
<ErrorBoundary>
<SocketProvider bodyshop={bodyshop} navigate={navigate} currentUser={currentUser}>
<PrivateRoute isAuthorized={currentUser.authorized} />
</SocketProvider>
</ErrorBoundary>
}
>
<Route path="*" element={<TechPageContainer />} />
</Route>
<Route path="/edit/*" element={<PrivateRoute isAuthorized={currentUser.authorized} />}>
<Route path="*" element={<DocumentEditorContainer />} />
</Route>
</Routes>
</NotificationProvider>
</Suspense>
);
}

View File

@@ -5,6 +5,13 @@
border-bottom: 1px solid #74695c !important;
}
// TODO: This was added because the newest release of ant was making the text color and the background color the same on a selected header
// Tried all available tokens (https://ant.design/components/menu?locale=en-US) and even reverted all our custom styles, to no avail
// This should be kept an eye on, especially if implementing DARK MODE
.ant-menu-submenu-title {
color: rgba(255, 255, 255, 0.65) !important;
}
.imex-table-header {
display: flex;
flex-wrap: wrap;
@@ -173,3 +180,13 @@
.muted-button:hover {
color: darkgrey;
}
.notification-alert-unordered-list {
cursor: pointer;
padding: 0;
margin: 0;
.notification-alert-unordered-list-item {
margin-right: 0;
}
}

View File

@@ -26,13 +26,11 @@ const defaultTheme = {
token: {
colorPrimary: InstanceRenderMgr({
imex: "#1890ff",
rome: "#326ade",
promanager: "#1d69a6"
rome: "#326ade"
}),
colorInfo: InstanceRenderMgr({
imex: "#1890ff",
rome: "#326ade",
promanager: "#1d69a6"
rome: "#326ade"
})
}
};

View File

@@ -85,6 +85,17 @@ export function AccountingPayablesTableComponent({ bodyshop, loading, payments,
sortOrder: state.sortedInfo.columnKey === "amount" && state.sortedInfo.order,
render: (text, record) => <CurrencyFormatter>{record.amount}</CurrencyFormatter>
},
{
title: t("payments.fields.type"),
dataIndex: "type",
key: "type",
sorter: (a, b) => a.type.localeCompare(b.type),
sortOrder: state.sortedInfo.columnKey === "type" && state.sortedInfo.order,
filters: bodyshop.md_payment_types.map((s) => {
return { text: s, value: [s] };
}),
onFilter: (value, record) => value.includes(record.type)
},
{
title: t("payments.fields.memo"),
dataIndex: "memo",

View File

@@ -3,7 +3,7 @@ import AllocationsAssignmentComponent from "./allocations-assignment.component";
import { useMutation } from "@apollo/client";
import { INSERT_ALLOCATION } from "../../graphql/allocations.queries";
import { useTranslation } from "react-i18next";
import { notification } from "antd";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
export default function AllocationsAssignmentContainer({ jobLineId, hours, refetch }) {
const visibilityState = useState(false);
@@ -14,6 +14,7 @@ export default function AllocationsAssignmentContainer({ jobLineId, hours, refet
employeeid: null
});
const [insertAllocation] = useMutation(INSERT_ALLOCATION);
const notification = useNotification();
const handleAssignment = () => {
insertAllocation({ variables: { alloc: { ...assignment } } })

View File

@@ -3,7 +3,7 @@ import AllocationsBulkAssignment from "./allocations-bulk-assignment.component";
import { useMutation } from "@apollo/client";
import { INSERT_ALLOCATION } from "../../graphql/allocations.queries";
import { useTranslation } from "react-i18next";
import { notification } from "antd";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
export default function AllocationsBulkAssignmentContainer({ jobLines, refetch }) {
const visibilityState = useState(false);
@@ -12,6 +12,7 @@ export default function AllocationsBulkAssignmentContainer({ jobLines, refetch }
employeeid: null
});
const [insertAllocation] = useMutation(INSERT_ALLOCATION);
const notification = useNotification();
const handleAssignment = () => {
const allocs = jobLines.reduce((acc, value) => {

View File

@@ -2,12 +2,13 @@ import React from "react";
import { useMutation } from "@apollo/client";
import { DELETE_ALLOCATION } from "../../graphql/allocations.queries";
import AllocationsLabelComponent from "./allocations-employee-label.component";
import { notification } from "antd";
import { useTranslation } from "react-i18next";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
export default function AllocationsLabelContainer({ allocation, refetch }) {
const [deleteAllocation] = useMutation(DELETE_ALLOCATION);
const { t } = useTranslation();
const notification = useNotification();
const handleClick = (e) => {
e.preventDefault();

View File

@@ -1,6 +1,6 @@
import { DeleteFilled } from "@ant-design/icons";
import { useMutation } from "@apollo/client";
import { Button, notification, Popconfirm } from "antd";
import { Button, Popconfirm } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { DELETE_BILL } from "../../graphql/bills.queries";
@@ -9,6 +9,7 @@ import { insertAuditTrail } from "../../redux/application/application.actions";
import AuditTrailMapping from "../../utils/AuditTrailMappings";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
const mapStateToProps = createStructuredSelector({});
const mapDispatchToProps = (dispatch) => ({
@@ -21,6 +22,7 @@ export function BillDeleteButton({ bill, jobid, callback, insertAuditTrail }) {
const [loading, setLoading] = useState(false);
const { t } = useTranslation();
const [deleteBill] = useMutation(DELETE_BILL);
const notification = useNotification();
const handleDelete = async () => {
setLoading(true);

View File

@@ -1,6 +1,6 @@
import { useApolloClient, useMutation } from "@apollo/client";
import { useSplitTreatments } from "@splitsoftware/splitio-react";
import { Button, Checkbox, Form, Modal, notification, Space } from "antd";
import { Button, Checkbox, Form, Modal, Space } from "antd";
import _ from "lodash";
import React, { useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
@@ -24,6 +24,7 @@ import BillFormContainer from "../bill-form/bill-form.container";
import { CalculateBillTotal } from "../bill-form/bill-form.totals.utility";
import { handleUpload as handleLocalUpload } from "../documents-local-upload/documents-local-upload.utility";
import { handleUpload } from "../documents-upload/documents-upload.utility";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
const mapStateToProps = createStructuredSelector({
billEnterModal: selectBillEnterModal,
@@ -49,6 +50,7 @@ function BillEnterModalContainer({ billEnterModal, toggleModalVisible, bodyshop,
const [loading, setLoading] = useState(false);
const client = useApolloClient();
const [generateLabel, setGenerateLabel] = useLocalStorage("enter_bill_generate_label", false);
const notification = useNotification();
const {
treatments: { Enhanced_Payroll }
@@ -291,7 +293,8 @@ function BillEnterModalContainer({ billEnterModal, toggleModalVisible, bodyshop,
jobid: values.jobid,
invoice_number: remainingValues.invoice_number,
vendorid: remainingValues.vendorid
}
},
notification
});
});
} else {
@@ -305,7 +308,8 @@ function BillEnterModalContainer({ billEnterModal, toggleModalVisible, bodyshop,
billId: billId,
tagsArray: null,
callback: null
}
},
notification
);
});
}
@@ -325,7 +329,9 @@ function BillEnterModalContainer({ billEnterModal, toggleModalVisible, bodyshop,
}
},
{},
"p"
"p",
null,
notification
);
}

View File

@@ -228,7 +228,6 @@ export function BillEnterModalLinesComponent({
}}
</Form.Item>
)
//Do not need to set for promanager as it will default to Rome.
})
},
{
@@ -462,7 +461,6 @@ export function BillEnterModalLinesComponent({
...InstanceRenderManager({
rome: [],
promanager: [],
imex: [
{
title: t("billlines.fields.federal_tax_applicable"),
@@ -475,8 +473,7 @@ export function BillEnterModalLinesComponent({
valuePropName: "checked",
initialValue: InstanceRenderManager({
imex: true,
rome: false,
promanager: false
rome: false
}),
name: [field.name, "applicable_taxes", "federal"]
};
@@ -503,7 +500,6 @@ export function BillEnterModalLinesComponent({
...InstanceRenderManager({
rome: [],
promanager: [],
imex: [
{
title: t("billlines.fields.local_tax_applicable"),
@@ -629,11 +625,15 @@ const EditableCell = ({
wrapper,
...restProps
}) => {
const propsFinal = formItemProps && formItemProps(record);
if (propsFinal && "key" in propsFinal) {
delete propsFinal.key;
}
if (additional)
return (
<td {...restProps}>
<div size="small">
<Form.Item name={dataIndex} labelCol={{ span: 0 }} {...(formItemProps && formItemProps(record))}>
<Form.Item name={dataIndex} labelCol={{ span: 0 }} {...propsFinal}>
{(formInput && formInput(record, record.name)) || children}
</Form.Item>
{additional && additional(record, record.name)}
@@ -644,7 +644,7 @@ const EditableCell = ({
return (
<wrapper>
<td {...restProps}>
<Form.Item labelCol={{ span: 0 }} name={dataIndex} {...(formItemProps && formItemProps(record))}>
<Form.Item labelCol={{ span: 0 }} name={dataIndex} {...propsFinal}>
{(formInput && formInput(record, record.name)) || children}
</Form.Item>
</td>
@@ -652,7 +652,7 @@ const EditableCell = ({
);
return (
<td {...restProps}>
<Form.Item labelCol={{ span: 0 }} name={dataIndex} {...(formItemProps && formItemProps(record))}>
<Form.Item labelCol={{ span: 0 }} name={dataIndex} {...propsFinal}>
{(formInput && formInput(record, record.name)) || children}
</Form.Item>
</td>

View File

@@ -1,5 +1,5 @@
import { gql, useMutation } from "@apollo/client";
import { Button, notification } from "antd";
import { Button } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
@@ -8,6 +8,7 @@ import { createStructuredSelector } from "reselect";
import { selectAuthLevel, selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
import { HasRbacAccess } from "../rbac-wrapper/rbac-wrapper.component";
import { INSERT_EXPORT_LOG } from "../../graphql/accounting.queries";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -24,6 +25,7 @@ export function BillMarkExportedButton({ currentUser, bodyshop, authLevel, bill
const { t } = useTranslation();
const [loading, setLoading] = useState(false);
const [insertExportLog] = useMutation(INSERT_EXPORT_LOG);
const notification = useNotification();
const [updateBill] = useMutation(gql`
mutation UPDATE_BILL($billId: uuid!) {

View File

@@ -3,11 +3,13 @@ import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { GenerateDocument } from "../../utils/RenderTemplate";
import { TemplateList } from "../../utils/TemplateConstants";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
export default function BillPrintButton({ billid }) {
const { t } = useTranslation();
const [loading, setLoading] = useState(false);
const Templates = TemplateList("job_special");
const notification = useNotification();
const submitHandler = async () => {
setLoading(true);
@@ -20,7 +22,9 @@ export default function BillPrintButton({ billid }) {
}
},
{},
"p"
"p",
null,
notification
);
} catch (e) {
console.warn("Warning: Error generating a document.");

View File

@@ -1,5 +1,5 @@
import { gql, useMutation } from "@apollo/client";
import { Button, notification } from "antd";
import { Button } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
@@ -7,6 +7,7 @@ import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectAuthLevel, selectBodyshop } from "../../redux/user/user.selectors";
import { HasRbacAccess } from "../rbac-wrapper/rbac-wrapper.component";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -21,6 +22,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(BillMarkForReexportB
export function BillMarkForReexportButton({ bodyshop, authLevel, bill }) {
const { t } = useTranslation();
const [loading, setLoading] = useState(false);
const notification = useNotification();
const [updateBill] = useMutation(gql`
mutation UPDATE_BILL($billId: uuid!) {

View File

@@ -1,6 +1,6 @@
import { FileAddFilled } from "@ant-design/icons";
import { useMutation } from "@apollo/client";
import { Button, notification, Tooltip } from "antd";
import { Button, Tooltip } from "antd";
import { t } from "i18next";
import dayjs from "./../../utils/day";
import React, { useState } from "react";
@@ -11,6 +11,7 @@ import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selecto
import { CalculateBillTotal } from "../bill-form/bill-form.totals.utility";
import queryString from "query-string";
import { useLocation } from "react-router-dom";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -25,6 +26,7 @@ export function BilllineAddInventory({ currentUser, bodyshop, billline, disabled
const [loading, setLoading] = useState(false);
const { billid } = queryString.parse(useLocation().search);
const [insertInventoryLine] = useMutation(INSERT_INVENTORY_AND_CREDIT);
const notification = useNotification();
const addToInventory = async () => {
setLoading(true);

View File

@@ -2,6 +2,7 @@ import { EditFilled, SyncOutlined } from "@ant-design/icons";
import { Button, Card, Checkbox, Input, Space, Table } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { FaTasks } from "react-icons/fa";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectJobReadOnly } from "../../redux/application/application.selectors";
@@ -13,8 +14,10 @@ import { alphaSort, dateSort } from "../../utils/sorters";
import { TemplateList } from "../../utils/TemplateConstants";
import BillDeleteButton from "../bill-delete-button/bill-delete-button.component";
import BillDetailEditReturnComponent from "../bill-detail-edit/bill-detail-edit-return.component";
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
import LockerWrapperComponent from "../lock-wrapper/lock-wrapper.component";
import PrintWrapperComponent from "../print-wrapper/print-wrapper.component";
import { FaTasks } from "react-icons/fa";
import UpsellComponent, { upsellEnum } from "../upsell/upsell.component";
const mapStateToProps = createStructuredSelector({
jobRO: selectJobReadOnly,
@@ -170,6 +173,8 @@ export function BillsListTableComponent({
)
: [];
const hasBillsAccess = HasFeatureAccess({ bodyshop, featureName: "bills" });
return (
<Card
title={t("bills.labels.bills")}
@@ -181,6 +186,7 @@ export function BillsListTableComponent({
{job && job.converted ? (
<>
<Button
disabled={!hasBillsAccess}
onClick={() => {
setBillEnterContext({
actions: { refetch: billsQuery.refetch },
@@ -190,9 +196,10 @@ export function BillsListTableComponent({
});
}}
>
{t("jobs.actions.postbills")}
<LockerWrapperComponent featureName="bills">{t("jobs.actions.postbills")}</LockerWrapperComponent>
</Button>
<Button
disabled={!hasBillsAccess}
onClick={() => {
setReconciliationContext({
actions: { refetch: billsQuery.refetch },
@@ -203,7 +210,7 @@ export function BillsListTableComponent({
});
}}
>
{t("jobs.actions.reconcile")}
<LockerWrapperComponent featureName="bills"> {t("jobs.actions.reconcile")}</LockerWrapperComponent>
</Button>
</>
) : null}
@@ -211,6 +218,7 @@ export function BillsListTableComponent({
<Input.Search
placeholder={t("general.labels.search")}
value={searchText}
disabled={!hasBillsAccess}
onChange={(e) => {
e.preventDefault();
setSearchText(e.target.value);
@@ -226,8 +234,13 @@ export function BillsListTableComponent({
}}
columns={columns}
rowKey="id"
dataSource={filteredBills}
dataSource={hasBillsAccess ? filteredBills : []}
onChange={handleTableChange}
locale={{
...(!hasBillsAccess && {
emptyText: <UpsellComponent upsell={upsellEnum().bills.general} />
})
}}
/>
</Card>
);

View File

@@ -9,6 +9,7 @@ import { selectCaBcEtfTableConvert } from "../../redux/modals/modals.selectors";
import { GenerateDocument } from "../../utils/RenderTemplate";
import { TemplateList } from "../../utils/TemplateConstants";
import CaBcEtfTableModalComponent from "./ca-bc-etf-table.modal.component";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
const mapStateToProps = createStructuredSelector({
caBcEtfTableModal: selectCaBcEtfTableConvert
@@ -25,6 +26,7 @@ export function ContractsFindModalContainer({ caBcEtfTableModal, toggleModalVisi
const [loading, setLoading] = useState(false);
const [form] = Form.useForm();
const EtfTemplate = TemplateList("special").ca_bc_etf_table;
const notification = useNotification();
const handleFinish = async (values) => {
logImEXEvent("ca_bc_etf_table_parse");
@@ -53,7 +55,9 @@ export function ContractsFindModalContainer({ caBcEtfTableModal, toggleModalVisi
}
},
{},
values.sendby === "email" ? "e" : "p"
values.sendby === "email" ? "e" : "p",
null,
notification
);
setLoading(false);
};

View File

@@ -1,6 +1,6 @@
import { DeleteFilled, CopyFilled } from "@ant-design/icons";
import { CopyFilled, DeleteFilled } from "@ant-design/icons";
import { useLazyQuery, useMutation } from "@apollo/client";
import { Button, Card, Col, Form, Input, Row, Space, Spin, Statistic, message, notification } from "antd";
import { Button, Card, Col, Form, Input, message, Row, Space, Spin, Statistic } from "antd";
import axios from "axios";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
@@ -15,6 +15,7 @@ import AuditTrailMapping from "../../utils/AuditTrailMappings";
import CurrencyFormItemComponent from "../form-items-formatted/currency-form-item.component";
import JobSearchSelectComponent from "../job-search-select/job-search-select.component";
import { getCurrentUser } from "../../firebase/firebase.utils";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
const mapStateToProps = createStructuredSelector({
cardPaymentModal: selectCardPayment,
@@ -23,7 +24,14 @@ const mapStateToProps = createStructuredSelector({
});
const mapDispatchToProps = (dispatch) => ({
insertAuditTrail: ({ jobid, operation, type }) => dispatch(insertAuditTrail({ jobid, operation, type })),
insertAuditTrail: ({ jobid, operation, type }) =>
dispatch(
insertAuditTrail({
jobid,
operation,
type
})
),
toggleModalVisible: () => dispatch(toggleModalVisible("cardPayment"))
});
@@ -39,33 +47,42 @@ const CardPaymentModalComponent = ({
const [form] = Form.useForm();
const [paymentLink, setPaymentLink] = useState();
const [loading, setLoading] = useState(false);
// const [insertPayment] = useMutation(INSERT_NEW_PAYMENT);
const [insertPaymentResponse] = useMutation(INSERT_PAYMENT_RESPONSE);
const { t } = useTranslation();
const notification = useNotification();
const [, { data, refetch, queryLoading }] = useLazyQuery(QUERY_RO_AND_OWNER_BY_JOB_PKS, {
variables: { jobids: [context.jobid] },
skip: !context?.jobid
});
//Initialize the intellipay window.
const collectIPayFields = () => {
const iPayFields = document.querySelectorAll(".ipayfield");
const iPayData = {};
iPayFields.forEach((field) => {
iPayData[field.dataset.ipayname] = field.value;
});
return iPayData;
};
const SetIntellipayCallbackFunctions = () => {
console.log("*** Set IntelliPay callback functions.");
window.intellipay.runOnClose(() => {
//window.intellipay.initialize();
});
window.intellipay.runOnApproval(async function (response) {
window.intellipay.runOnApproval(() => {
//2024-04-25: Nothing is going to happen here anymore. We'll completely rely on the callback.
//Add a slight delay to allow the refetch to properly get the data.
setTimeout(() => {
if (actions && actions.refetch && typeof actions.refetch === "function") actions.refetch();
if (actions?.refetch) actions.refetch();
setLoading(false);
toggleModalVisible();
}, 750);
});
window.intellipay.runOnNonApproval(async function (response) {
window.intellipay.runOnNonApproval(async (response) => {
// Mutate unsuccessful payment
const { payments } = form.getFieldsValue();
@@ -98,30 +115,39 @@ const CardPaymentModalComponent = ({
//Validate
try {
await form.validateFields();
} catch (error) {
} catch {
setLoading(false);
return;
}
const iPayData = collectIPayFields();
const { payments } = form.getFieldsValue();
try {
const response = await axios.post("/intellipay/lightbox_credentials", {
bodyshop,
refresh: !!window.intellipay,
paymentSplitMeta: form.getFieldsValue()
paymentSplitMeta: form.getFieldsValue(),
iPayData: iPayData,
comment: btoa(JSON.stringify({ payments, userEmail: currentUser.email }))
});
if (window.intellipay) {
// eslint-disable-next-line no-eval
eval(response.data);
SetIntellipayCallbackFunctions();
window.intellipay.autoOpen();
pollForIntelliPay(() => {
SetIntellipayCallbackFunctions();
window.intellipay.autoOpen();
});
} else {
var rg = document.createRange();
let node = rg.createContextualFragment(response.data);
const rg = document.createRange();
const node = rg.createContextualFragment(response.data);
document.documentElement.appendChild(node);
SetIntellipayCallbackFunctions();
window.intellipay.isAutoOpen = true;
window.intellipay.initialize();
pollForIntelliPay(() => {
SetIntellipayCallbackFunctions();
window.intellipay.isAutoOpen = true;
window.intellipay.initialize();
});
}
} catch (error) {
notification.open({
@@ -137,25 +163,27 @@ const CardPaymentModalComponent = ({
//Validate
try {
await form.validateFields();
} catch (error) {
} catch {
setLoading(false);
return;
}
const iPayData = collectIPayFields();
try {
const { payments } = form.getFieldsValue();
const response = await axios.post("/intellipay/generate_payment_url", {
bodyshop,
amount: payments?.reduce((acc, val) => {
return acc + (val?.amount || 0);
}, 0),
account: payments && data && data.jobs.length > 0 ? data.jobs.map((j) => j.ro_number).join(", ") : null,
amount: payments.reduce((acc, val) => acc + (val?.amount || 0), 0),
account: payments && data?.jobs?.length > 0 ? data.jobs.map((j) => j.ro_number).join(", ") : null,
comment: btoa(JSON.stringify({ payments, userEmail: currentUser.email })),
paymentSplitMeta: form.getFieldsValue()
paymentSplitMeta: form.getFieldsValue(),
iPayData: iPayData
});
if (response.data) {
setPaymentLink(response.data?.shorUrl);
navigator.clipboard.writeText(response.data?.shorUrl);
if (response?.data?.shorUrl) {
setPaymentLink(response.data.shorUrl);
await navigator.clipboard.writeText(response.data.shorUrl);
message.success(t("general.actions.copied"));
}
setLoading(false);
@@ -179,67 +207,44 @@ const CardPaymentModalComponent = ({
}}
>
<Form.List name={["payments"]}>
{(fields, { add, remove, move }) => {
return (
<div>
{fields.map((field, index) => (
<Form.Item key={field.key}>
<Row gutter={[16, 16]}>
<Col span={16}>
<Form.Item
key={`${index}jobid`}
label={t("jobs.fields.ro_number")}
name={[field.name, "jobid"]}
rules={[
{
required: true
//message: t("general.validation.required"),
}
]}
>
<JobSearchSelectComponent notExported={false} clm_no />
</Form.Item>
</Col>
<Col span={6}>
<Form.Item
key={`${index}amount`}
label={t("payments.fields.amount")}
name={[field.name, "amount"]}
rules={[
{
required: true
//message: t("general.validation.required"),
}
]}
>
<CurrencyFormItemComponent />
</Form.Item>
</Col>
<Col span={2}>
<DeleteFilled
style={{ margin: "1rem" }}
onClick={() => {
remove(field.name);
}}
/>
</Col>
</Row>
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
style={{ width: "100%" }}
>
{t("general.actions.add")}
</Button>
{(fields, { add, remove }) => (
<div>
{fields.map((field, index) => (
<Form.Item key={field.key}>
<Row gutter={[16, 16]}>
<Col span={16}>
<Form.Item
key={`${index}jobid`}
label={t("jobs.fields.ro_number")}
name={[field.name, "jobid"]}
rules={[{ required: true }]}
>
<JobSearchSelectComponent notExported={false} clm_no />
</Form.Item>
</Col>
<Col span={6}>
<Form.Item
key={`${index}amount`}
label={t("payments.fields.amount")}
name={[field.name, "amount"]}
rules={[{ required: true }]}
>
<CurrencyFormItemComponent />
</Form.Item>
</Col>
<Col span={2}>
<DeleteFilled style={{ margin: "1rem" }} onClick={() => remove(field.name)} />
</Col>
</Row>
</Form.Item>
</div>
);
}}
))}
<Form.Item>
<Button type="dashed" onClick={() => add()} style={{ width: "100%" }}>
{t("general.actions.add")}
</Button>
</Form.Item>
</div>
)}
</Form.List>
<Form.Item
@@ -283,9 +288,7 @@ const CardPaymentModalComponent = ({
>
{() => {
const { payments } = form.getFieldsValue();
const totalAmountToCharge = payments?.reduce((acc, val) => {
return acc + (val?.amount || 0);
}, 0);
const totalAmountToCharge = payments?.reduce((acc, val) => acc + (val?.amount || 0), 0);
return (
<Space style={{ float: "right" }}>
<Statistic title="Amount To Charge" value={totalAmountToCharge} precision={2} />
@@ -348,3 +351,27 @@ const CardPaymentModalComponent = ({
};
export default connect(mapStateToProps, mapDispatchToProps)(CardPaymentModalComponent);
//Poll for window.IntelliPay.fixAmount for 5 seconds. If it doesn't come up, just try anyways to force the possible error.
function pollForIntelliPay(callbackFunction) {
const timeout = 5000;
const interval = 150; // Poll every 100 milliseconds
const startTime = Date.now();
function checkFixAmount() {
if (window.intellipay && window.intellipay.fixAmount !== undefined) {
callbackFunction();
return;
}
if (Date.now() - startTime >= timeout) {
console.log("Stopped polling IntelliPay after 10 seconds. Attemping to set functions anyways.");
callbackFunction();
return;
}
setTimeout(checkFixAmount, interval);
}
checkFixAmount();
}

View File

@@ -6,7 +6,7 @@ import { createStructuredSelector } from "reselect";
import { toggleModalVisible } from "../../redux/modals/modals.actions";
import { selectCardPayment } from "../../redux/modals/modals.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors";
import CardPaymentModalComponent from "./card-payment-modal.component.";
import CardPaymentModalComponent from "./card-payment-modal.component";
const mapStateToProps = createStructuredSelector({
cardPaymentModal: selectCardPayment,

View File

@@ -1,89 +1,50 @@
import { useApolloClient } from "@apollo/client";
import { getToken, onMessage } from "@firebase/messaging";
import { Button, notification, Space } from "antd";
import { getToken } from "@firebase/messaging";
import axios from "axios";
import React, { useEffect } from "react";
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { useSocket } from "../../contexts/SocketIO/useSocket.jsx";
import { messaging, requestForToken } from "../../firebase/firebase.utils";
import FcmHandler from "../../utils/fcm-handler";
import ChatPopupComponent from "../chat-popup/chat-popup.component";
import "./chat-affix.styles.scss";
import { registerMessagingHandlers, unregisterMessagingHandlers } from "./registerMessagingSocketHandlers";
export function ChatAffixContainer({ bodyshop, chatVisible }) {
const { t } = useTranslation();
const client = useApolloClient();
const { socket } = useSocket();
useEffect(() => {
if (!bodyshop || !bodyshop.messagingservicesid) return;
async function SubscribeToTopic() {
async function SubscribeToTopicForFCMNotification() {
try {
const r = await axios.post("/notifications/subscribe", {
await requestForToken();
await axios.post("/notifications/subscribe", {
fcm_tokens: await getToken(messaging, {
vapidKey: import.meta.env.VITE_APP_FIREBASE_PUBLIC_VAPID_KEY
}),
type: "messaging",
imexshopid: bodyshop.imexshopid
});
console.log("FCM Topic Subscription", r.data);
} catch (error) {
console.log("Error attempting to subscribe to messaging topic: ", error);
notification.open({
key: "fcm",
type: "warning",
message: t("general.errors.fcm"),
btn: (
<Space>
<Button
onClick={async () => {
await requestForToken();
SubscribeToTopic();
}}
>
{t("general.actions.tryagain")}
</Button>
<Button
onClick={() => {
const win = window.open(
"https://help.imex.online/en/article/enabling-notifications-o978xi/",
"_blank"
);
win.focus();
}}
>
{t("general.labels.help")}
</Button>
</Space>
)
});
}
}
SubscribeToTopic();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [bodyshop]);
SubscribeToTopicForFCMNotification();
useEffect(() => {
function handleMessage(payload) {
FcmHandler({
client,
payload: (payload && payload.data && payload.data.data) || payload.data
});
//Register WS handlers
if (socket && socket.connected) {
registerMessagingHandlers({ socket, client });
}
let stopMessageListener, channel;
try {
stopMessageListener = onMessage(messaging, handleMessage);
channel = new BroadcastChannel("imex-sw-messages");
channel.addEventListener("message", handleMessage);
} catch (error) {
console.log("Unable to set event listeners.");
}
return () => {
stopMessageListener && stopMessageListener();
channel && channel.removeEventListener("message", handleMessage);
if (socket && socket.connected) {
unregisterMessagingHandlers({ socket });
}
};
}, [client]);
}, [bodyshop, socket, t, client]);
if (!bodyshop || !bodyshop.messagingservicesid) return <></>;

View File

@@ -0,0 +1,434 @@
import { CONVERSATION_LIST_QUERY, GET_CONVERSATION_DETAILS } from "../../graphql/conversations.queries";
import { gql } from "@apollo/client";
const logLocal = (message, ...args) => {
if (import.meta.env.VITE_APP_IS_TEST || !import.meta.env.PROD) {
console.log(`==================== ${message} ====================`);
console.dir({ ...args });
}
};
// Utility function to enrich conversation data
const enrichConversation = (conversation, isOutbound) => ({
...conversation,
updated_at: conversation.updated_at || new Date().toISOString(),
unreadcnt: conversation.unreadcnt || 0,
archived: conversation.archived || false,
label: conversation.label || null,
job_conversations: conversation.job_conversations || [],
messages_aggregate: conversation.messages_aggregate || {
__typename: "messages_aggregate",
aggregate: {
__typename: "messages_aggregate_fields",
count: isOutbound ? 0 : 1
}
},
__typename: "conversations"
});
export const registerMessagingHandlers = ({ socket, client }) => {
if (!(socket && client)) return;
const handleNewMessageSummary = async (message) => {
const { conversationId, newConversation, existingConversation, isoutbound } = message;
logLocal("handleNewMessageSummary - Start", { message, isNew: !existingConversation });
const queryVariables = { offset: 0 };
if (!existingConversation && conversationId) {
// Attempt to read from the cache to determine if this is actually a new conversation
try {
const cachedConversation = client.cache.readFragment({
id: client.cache.identify({ __typename: "conversations", id: conversationId }),
fragment: gql`
fragment ExistingConversationCheck on conversations {
id
}
`
});
if (cachedConversation) {
logLocal("handleNewMessageSummary - Existing Conversation inferred from cache", {
conversationId
});
return handleNewMessageSummary({
...message,
existingConversation: true
});
}
} catch (error) {
logLocal("handleNewMessageSummary - Cache miss", { conversationId });
}
}
// Handle new conversation
if (!existingConversation && newConversation?.phone_num) {
logLocal("handleNewMessageSummary - New Conversation", newConversation);
try {
const queryResults = client.cache.readQuery({
query: CONVERSATION_LIST_QUERY,
variables: queryVariables
});
const existingConversations = queryResults?.conversations || [];
const enrichedConversation = enrichConversation(newConversation, isoutbound);
if (!existingConversations.some((conv) => conv.id === enrichedConversation.id)) {
client.cache.modify({
id: "ROOT_QUERY",
fields: {
conversations(existingConversations = []) {
return [enrichedConversation, ...existingConversations];
}
}
});
}
} catch (error) {
console.error("Error updating cache for new conversation:", error);
}
return;
}
// Handle existing conversation
if (existingConversation) {
try {
client.cache.modify({
id: client.cache.identify({ __typename: "conversations", id: conversationId }),
fields: {
updated_at: () => new Date().toISOString(),
archived: () => false,
messages_aggregate(cached = { aggregate: { count: 0 } }) {
const currentCount = cached.aggregate?.count || 0;
if (!isoutbound) {
return {
__typename: "messages_aggregate",
aggregate: {
__typename: "messages_aggregate_fields",
count: currentCount + 1
}
};
}
return cached;
}
}
});
} catch (error) {
console.error("Error updating cache for existing conversation:", error);
}
return;
}
logLocal("New Conversation Summary finished without work", { message });
};
const handleNewMessageDetailed = (message) => {
const { conversationId, newMessage } = message;
logLocal("handleNewMessageDetailed - Start", message);
try {
// Check if the conversation exists in the cache
const queryResults = client.cache.readQuery({
query: GET_CONVERSATION_DETAILS,
variables: { conversationId }
});
if (!queryResults?.conversations_by_pk) {
console.warn("Conversation not found in cache:", { conversationId });
return;
}
// Append the new message to the conversation's message list using cache.modify
client.cache.modify({
id: client.cache.identify({ __typename: "conversations", id: conversationId }),
fields: {
messages(existingMessages = []) {
return [...existingMessages, newMessage];
}
}
});
logLocal("handleNewMessageDetailed - Message appended successfully", {
conversationId,
newMessage
});
} catch (error) {
console.error("Error updating conversation messages in cache:", error);
}
};
const handleMessageChanged = (message) => {
if (!message) {
logLocal("handleMessageChanged - No message provided", message);
return;
}
logLocal("handleMessageChanged - Start", message);
try {
client.cache.modify({
id: client.cache.identify({ __typename: "conversations", id: message.conversationid }),
fields: {
messages(existingMessages = [], { readField }) {
return existingMessages.map((messageRef) => {
// Check if this is the message to update
if (readField("id", messageRef) === message.id) {
const currentStatus = readField("status", messageRef);
// Handle known types of message changes
switch (message.type) {
case "status-changed":
// Prevent overwriting if the current status is already "delivered"
if (currentStatus === "delivered") {
logLocal("handleMessageChanged - Status already delivered, skipping update", {
messageId: message.id
});
return messageRef;
}
// Update the status field
return {
...messageRef,
status: message.status
};
case "text-updated":
// Handle changes to the message text
return {
...messageRef,
text: message.text
};
// Add cases for other known message types as needed
default:
// Log a warning for unhandled message types
logLocal("handleMessageChanged - Unhandled message type", { type: message.type });
return messageRef;
}
}
return messageRef; // Keep other messages unchanged
});
}
}
});
logLocal("handleMessageChanged - Message updated successfully", {
messageId: message.id,
type: message.type
});
} catch (error) {
console.error("handleMessageChanged - Error modifying cache:", error);
}
};
const handleConversationChanged = async (data) => {
if (!data) {
logLocal("handleConversationChanged - No data provided", data);
return;
}
const { conversationId, type, job_conversations, messageIds, ...fields } = data;
logLocal("handleConversationChanged - Start", data);
const updatedAt = new Date().toISOString();
const updateConversationList = (newConversation) => {
try {
const existingList = client.cache.readQuery({
query: CONVERSATION_LIST_QUERY,
variables: { offset: 0 }
});
const updatedList = existingList?.conversations
? [
newConversation,
...existingList.conversations.filter((conv) => conv.id !== newConversation.id) // Prevent duplicates
]
: [newConversation];
client.cache.writeQuery({
query: CONVERSATION_LIST_QUERY,
variables: { offset: 0 },
data: {
conversations: updatedList
}
});
logLocal("handleConversationChanged - Conversation list updated successfully", newConversation);
} catch (error) {
console.error("Error updating conversation list in the cache:", error);
}
};
// Handle specific types
try {
switch (type) {
case "conversation-marked-read":
if (conversationId && messageIds?.length > 0) {
client.cache.modify({
id: client.cache.identify({ __typename: "conversations", id: conversationId }),
fields: {
messages(existingMessages = [], { readField }) {
return existingMessages.map((message) => {
if (messageIds.includes(readField("id", message))) {
return { ...message, read: true };
}
return message;
});
},
messages_aggregate: () => ({
__typename: "messages_aggregate",
aggregate: { __typename: "messages_aggregate_fields", count: 0 }
})
}
});
}
break;
case "conversation-created":
updateConversationList({ ...fields, job_conversations, updated_at: updatedAt });
break;
case "conversation-unarchived":
case "conversation-archived":
// Would like to someday figure out how to get this working without refetch queries,
// But I have but a solid 4 hours into it, and there are just too many weird occurrences
try {
const listQueryVariables = { offset: 0 };
const detailsQueryVariables = { conversationId };
// Check if conversation details exist in the cache
const detailsExist = !!client.cache.readQuery({
query: GET_CONVERSATION_DETAILS,
variables: detailsQueryVariables
});
// Refetch conversation list
await client.refetchQueries({
include: [CONVERSATION_LIST_QUERY, ...(detailsExist ? [GET_CONVERSATION_DETAILS] : [])],
variables: [
{ query: CONVERSATION_LIST_QUERY, variables: listQueryVariables },
...(detailsExist
? [
{
query: GET_CONVERSATION_DETAILS,
variables: detailsQueryVariables
}
]
: [])
]
});
logLocal("handleConversationChanged - Refetched queries after state change", {
conversationId,
type
});
} catch (error) {
console.error("Error refetching queries after conversation state change:", error);
}
break;
case "tag-added":
// Ensure `job_conversations` is properly formatted
const formattedJobConversations = job_conversations.map((jc) => ({
__typename: "job_conversations",
jobid: jc.jobid || jc.job?.id,
conversationid: conversationId,
job: jc.job || {
__typename: "jobs",
id: data.selectedJob.id,
ro_number: data.selectedJob.ro_number,
ownr_co_nm: data.selectedJob.ownr_co_nm,
ownr_fn: data.selectedJob.ownr_fn,
ownr_ln: data.selectedJob.ownr_ln
}
}));
client.cache.modify({
id: client.cache.identify({ __typename: "conversations", id: conversationId }),
fields: {
job_conversations: (existing = []) => {
// Ensure no duplicates based on both `conversationid` and `jobid`
const existingLinks = new Set(
existing.map((jc) => {
const jobId = client.cache.readFragment({
id: client.cache.identify(jc),
fragment: gql`
fragment JobConversationLinkAdded on job_conversations {
jobid
conversationid
}
`
})?.jobid;
return `${jobId}:${conversationId}`; // Unique identifier for a job-conversation link
})
);
const newItems = formattedJobConversations.filter((jc) => {
const uniqueLink = `${jc.jobid}:${jc.conversationid}`;
return !existingLinks.has(uniqueLink);
});
return [...existing, ...newItems];
}
}
});
break;
case "tag-removed":
try {
const conversationCacheId = client.cache.identify({ __typename: "conversations", id: conversationId });
// Evict the specific cache entry for job_conversations
client.cache.evict({
id: conversationCacheId,
fieldName: "job_conversations"
});
// Garbage collect evicted entries
client.cache.gc();
logLocal("handleConversationChanged - tag removed - Refetched conversation list after state change", {
conversationId,
type
});
} catch (error) {
console.error("Error refetching queries after conversation state change: (Tag Removed)", error);
}
break;
default:
logLocal("handleConversationChanged - Unhandled type", { type });
client.cache.modify({
id: client.cache.identify({ __typename: "conversations", id: conversationId }),
fields: {
...Object.fromEntries(
Object.entries(fields).map(([key, value]) => [key, (cached) => (value !== undefined ? value : cached)])
)
}
});
}
} catch (error) {
console.error("Error handling conversation changes:", { type, error });
}
};
socket.on("new-message-summary", handleNewMessageSummary);
socket.on("new-message-detailed", handleNewMessageDetailed);
socket.on("message-changed", handleMessageChanged);
socket.on("conversation-changed", handleConversationChanged);
};
export const unregisterMessagingHandlers = ({ socket }) => {
if (!socket) return;
socket.off("new-message-summary");
socket.off("new-message-detailed");
socket.off("message-changed");
socket.off("conversation-changed");
};

View File

@@ -1,27 +1,49 @@
import { useMutation } from "@apollo/client";
import { Button } from "antd";
import React, { useState } from "react";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { TOGGLE_CONVERSATION_ARCHIVE } from "../../graphql/conversations.queries";
import { useSocket } from "../../contexts/SocketIO/useSocket.jsx";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors.js";
import { connect } from "react-redux";
export default function ChatArchiveButton({ conversation }) {
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
});
const mapDispatchToProps = () => ({});
export function ChatArchiveButton({ conversation, bodyshop }) {
const [loading, setLoading] = useState(false);
const { t } = useTranslation();
const [updateConversation] = useMutation(TOGGLE_CONVERSATION_ARCHIVE);
const { socket } = useSocket();
const handleToggleArchive = async () => {
setLoading(true);
await updateConversation({
variables: { id: conversation.id, archived: !conversation.archived },
refetchQueries: ["CONVERSATION_LIST_QUERY"]
const updatedConversation = await updateConversation({
variables: { id: conversation.id, archived: !conversation.archived }
});
if (socket) {
socket.emit("conversation-modified", {
type: "conversation-archived",
conversationId: conversation.id,
bodyshopId: bodyshop.id,
archived: updatedConversation.data.update_conversations_by_pk.archived
});
}
setLoading(false);
};
return (
<Button onClick={handleToggleArchive} loading={loading} type="primary">
<Button onClick={handleToggleArchive} loading={loading} className="archive-button" type="primary">
{conversation.archived ? t("messaging.labels.unarchive") : t("messaging.labels.archive")}
</Button>
);
}
export default connect(mapStateToProps, mapDispatchToProps)(ChatArchiveButton);

View File

@@ -1,7 +1,7 @@
import { Badge, Card, List, Space, Tag } from "antd";
import React from "react";
import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import { AutoSizer, CellMeasurer, CellMeasurerCache, List as VirtualizedList } from "react-virtualized";
import { Virtuoso } from "react-virtuoso";
import { createStructuredSelector } from "reselect";
import { setSelectedConversation } from "../../redux/messaging/messaging.actions";
import { selectSelectedConversation } from "../../redux/messaging/messaging.selectors";
@@ -19,19 +19,26 @@ const mapDispatchToProps = (dispatch) => ({
setSelectedConversation: (conversationId) => dispatch(setSelectedConversation(conversationId))
});
function ChatConversationListComponent({
conversationList,
selectedConversation,
setSelectedConversation,
loadMoreConversations
}) {
const cache = new CellMeasurerCache({
fixedWidth: true,
defaultHeight: 60
});
function ChatConversationListComponent({ conversationList, selectedConversation, setSelectedConversation }) {
// That comma is there for a reason, do not remove it
const [, forceUpdate] = useState(false);
const rowRenderer = ({ index, key, style, parent }) => {
const item = conversationList[index];
// Re-render every minute
useEffect(() => {
const interval = setInterval(() => {
forceUpdate((prev) => !prev); // Toggle state to trigger re-render
}, 60000); // 1 minute in milliseconds
return () => clearInterval(interval); // Cleanup on unmount
}, []);
// Memoize the sorted conversation list
const sortedConversationList = React.useMemo(() => {
return _.orderBy(conversationList, ["updated_at"], ["desc"]);
}, [conversationList]);
const renderConversation = (index) => {
const item = sortedConversationList[index];
const cardContentRight = <TimeAgoFormatter>{item.updated_at}</TimeAgoFormatter>;
const cardContentLeft =
item.job_conversations.length > 0
@@ -52,7 +59,8 @@ function ChatConversationListComponent({
)}
</>
);
const cardExtra = <Badge count={item.messages_aggregate.aggregate.count || 0} />;
const cardExtra = <Badge count={item.messages_aggregate.aggregate.count} />;
const getCardStyle = () =>
item.id === selectedConversation
@@ -60,40 +68,26 @@ function ChatConversationListComponent({
: { backgroundColor: index % 2 === 0 ? "#f0f2f5" : "#ffffff" };
return (
<CellMeasurer key={key} cache={cache} parent={parent} columnIndex={0} rowIndex={index}>
<List.Item
onClick={() => setSelectedConversation(item.id)}
style={style}
className={`chat-list-item
${item.id === selectedConversation ? "chat-list-selected-conversation" : null}`}
>
<Card style={getCardStyle()} bordered={false} size="small" extra={cardExtra} title={cardTitle}>
<div style={{ display: "inline-block", width: "70%", textAlign: "left" }}>{cardContentLeft}</div>
<div style={{ display: "inline-block", width: "30%", textAlign: "right" }}>{cardContentRight}</div>
</Card>
</List.Item>
</CellMeasurer>
<List.Item
key={item.id}
onClick={() => setSelectedConversation(item.id)}
className={`chat-list-item ${item.id === selectedConversation ? "chat-list-selected-conversation" : ""}`}
>
<Card style={getCardStyle()} bordered={false} size="small" extra={cardExtra} title={cardTitle}>
<div style={{ display: "inline-block", width: "70%", textAlign: "left" }}>{cardContentLeft}</div>
<div style={{ display: "inline-block", width: "30%", textAlign: "right" }}>{cardContentRight}</div>
</Card>
</List.Item>
);
};
return (
<div className="chat-list-container">
<AutoSizer>
{({ height, width }) => (
<VirtualizedList
height={height}
width={width}
rowCount={conversationList.length}
rowHeight={cache.rowHeight}
rowRenderer={rowRenderer}
onScroll={({ scrollTop, scrollHeight, clientHeight }) => {
if (scrollTop + clientHeight === scrollHeight) {
loadMoreConversations();
}
}}
/>
)}
</AutoSizer>
<Virtuoso
data={sortedConversationList}
itemContent={(index) => renderConversation(index)}
style={{ height: "100%", width: "100%" }}
/>
</div>
);
}

View File

@@ -1,7 +1,7 @@
.chat-list-container {
overflow: hidden;
height: 100%;
height: 100%; /* Ensure it takes up the full available height */
border: 1px solid gainsboro;
overflow: auto; /* Allow scrolling for the Virtuoso component */
}
.chat-list-item {
@@ -14,3 +14,24 @@
color: #ff7a00;
}
}
/* Virtuoso item container adjustments */
.chat-list-container > div {
height: 100%; /* Ensure Virtuoso takes full height */
display: flex;
flex-direction: column;
}
/* Add spacing and better alignment for items */
.chat-list-item {
padding: 0.5rem 0; /* Add spacing between list items */
.ant-card {
border-radius: 8px; /* Slight rounding for card edges */
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); /* Subtle shadow for better definition */
}
&:hover .ant-card {
border-color: #ff7a00; /* Highlight border on hover */
}
}

View File

@@ -1,18 +1,28 @@
import { useMutation } from "@apollo/client";
import { Tag } from "antd";
import React from "react";
import { Link } from "react-router-dom";
import { logImEXEvent } from "../../firebase/firebase.utils";
import { REMOVE_CONVERSATION_TAG } from "../../graphql/job-conversations.queries";
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
import { useSocket } from "../../contexts/SocketIO/useSocket.jsx";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors.js";
import { connect } from "react-redux";
export default function ChatConversationTitleTags({ jobConversations }) {
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
});
const mapDispatchToProps = () => ({});
export function ChatConversationTitleTags({ jobConversations, bodyshop }) {
const [removeJobConversation] = useMutation(REMOVE_CONVERSATION_TAG);
const { socket } = useSocket();
const handleRemoveTag = (jobId) => {
const handleRemoveTag = async (jobId) => {
const convId = jobConversations[0].conversationid;
if (!!convId) {
removeJobConversation({
await removeJobConversation({
variables: {
conversationId: convId,
jobId: jobId
@@ -28,6 +38,17 @@ export default function ChatConversationTitleTags({ jobConversations }) {
});
}
});
if (socket) {
// Emit the `conversation-modified` event
socket.emit("conversation-modified", {
bodyshopId: bodyshop.id,
conversationId: convId,
type: "tag-removed",
jobId: jobId
});
}
logImEXEvent("messaging_remove_job_tag", {
conversationId: convId,
jobId: jobId
@@ -54,3 +75,5 @@ export default function ChatConversationTitleTags({ jobConversations }) {
</div>
);
}
export default connect(mapStateToProps, mapDispatchToProps)(ChatConversationTitleTags);

View File

@@ -6,10 +6,16 @@ import ChatConversationTitleTags from "../chat-conversation-title-tags/chat-conv
import ChatLabelComponent from "../chat-label/chat-label.component";
import ChatPrintButton from "../chat-print-button/chat-print-button.component";
import ChatTagRoContainer from "../chat-tag-ro/chat-tag-ro.container";
import { createStructuredSelector } from "reselect";
import { connect } from "react-redux";
export default function ChatConversationTitle({ conversation }) {
const mapStateToProps = createStructuredSelector({});
const mapDispatchToProps = () => ({});
export function ChatConversationTitle({ conversation }) {
return (
<Space wrap>
<Space className="chat-title" wrap>
<PhoneNumberFormatter>{conversation && conversation.phone_num}</PhoneNumberFormatter>
<ChatLabelComponent conversation={conversation} />
<ChatPrintButton conversation={conversation} />
@@ -19,3 +25,5 @@ export default function ChatConversationTitle({ conversation }) {
</Space>
);
}
export default connect(mapStateToProps, mapDispatchToProps)(ChatConversationTitle);

View File

@@ -5,10 +5,26 @@ import ChatMessageListComponent from "../chat-messages-list/chat-message-list.co
import ChatSendMessage from "../chat-send-message/chat-send-message.component";
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component.jsx";
import "./chat-conversation.styles.scss";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors.js";
import { connect } from "react-redux";
export default function ChatConversationComponent({ subState, conversation, messages, handleMarkConversationAsRead }) {
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
});
const mapDispatchToProps = () => ({});
export function ChatConversationComponent({
subState,
conversation,
messages,
handleMarkConversationAsRead,
bodyshop
}) {
const [loading, error] = subState;
if (conversation?.archived) return null;
if (loading) return <LoadingSkeleton />;
if (error) return <AlertComponent message={error.message} type="error" />;
@@ -18,9 +34,11 @@ export default function ChatConversationComponent({ subState, conversation, mess
onMouseDown={handleMarkConversationAsRead}
onKeyDown={handleMarkConversationAsRead}
>
<ChatConversationTitle conversation={conversation} />
<ChatConversationTitle conversation={conversation} bodyshop={bodyshop} />
<ChatMessageListComponent messages={messages} />
<ChatSendMessage conversation={conversation} />
</div>
);
}
export default connect(mapStateToProps, mapDispatchToProps)(ChatConversationComponent);

View File

@@ -1,22 +1,25 @@
import { useMutation, useQuery, useSubscription } from "@apollo/client";
import React, { useState } from "react";
import { gql, useApolloClient, useQuery, useSubscription } from "@apollo/client";
import axios from "axios";
import { useCallback, useEffect, useState } from "react";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { useSocket } from "../../contexts/SocketIO/useSocket.jsx";
import { CONVERSATION_SUBSCRIPTION_BY_PK, GET_CONVERSATION_DETAILS } from "../../graphql/conversations.queries";
import { MARK_MESSAGES_AS_READ_BY_CONVERSATION } from "../../graphql/messages.queries";
import { selectSelectedConversation } from "../../redux/messaging/messaging.selectors";
import ChatConversationComponent from "./chat-conversation.component";
import axios from "axios";
import { selectBodyshop } from "../../redux/user/user.selectors";
import ChatConversationComponent from "./chat-conversation.component";
const mapStateToProps = createStructuredSelector({
selectedConversation: selectSelectedConversation,
bodyshop: selectBodyshop
});
export default connect(mapStateToProps, null)(ChatConversationContainer);
function ChatConversationContainer({ bodyshop, selectedConversation }) {
const client = useApolloClient();
const { socket } = useSocket();
const [markingAsReadInProgress, setMarkingAsReadInProgress] = useState(false);
export function ChatConversationContainer({ bodyshop, selectedConversation }) {
// Fetch conversation details
const {
loading: convoLoading,
error: convoError,
@@ -27,55 +30,145 @@ export function ChatConversationContainer({ bodyshop, selectedConversation }) {
nextFetchPolicy: "network-only"
});
const { loading, error, data } = useSubscription(CONVERSATION_SUBSCRIPTION_BY_PK, {
variables: { conversationId: selectedConversation }
});
const [markingAsReadInProgress, setMarkingAsReadInProgress] = useState(false);
const [markConversationRead] = useMutation(MARK_MESSAGES_AS_READ_BY_CONVERSATION, {
// Subscription for conversation updates
useSubscription(CONVERSATION_SUBSCRIPTION_BY_PK, {
skip: socket?.connected,
variables: { conversationId: selectedConversation },
refetchQueries: ["UNREAD_CONVERSATION_COUNT"],
update(cache) {
cache.modify({
id: cache.identify({
__typename: "conversations",
id: selectedConversation
}),
fields: {
messages_aggregate(cached) {
return { aggregate: { count: 0 } };
onData: ({ data: subscriptionResult, client }) => {
// Extract the messages array from the result
const messages = subscriptionResult?.data?.messages;
if (!messages || messages.length === 0) {
console.warn("No messages found in subscription result.");
return;
}
messages.forEach((message) => {
const messageRef = client.cache.identify(message);
// Write the new message to the cache
client.cache.writeFragment({
id: messageRef,
fragment: gql`
fragment NewMessage on messages {
id
status
text
isoutbound
image
image_path
userid
created_at
read
}
`,
data: message
});
// Update the conversation cache to include the new message
client.cache.modify({
id: client.cache.identify({ __typename: "conversations", id: selectedConversation }),
fields: {
messages(existingMessages = []) {
const alreadyExists = existingMessages.some((msg) => msg.__ref === messageRef);
if (alreadyExists) return existingMessages;
return [...existingMessages, { __ref: messageRef }];
},
updated_at() {
return message.created_at;
}
}
}
});
});
}
});
const unreadCount =
data &&
data.messages &&
data.messages.reduce((acc, val) => {
return !val.read && !val.isoutbound ? acc + 1 : acc;
}, 0);
const updateCacheWithReadMessages = useCallback(
(conversationId, messageIds) => {
if (!conversationId || !messageIds?.length) return;
const handleMarkConversationAsRead = async () => {
if (unreadCount > 0 && !!selectedConversation && !markingAsReadInProgress) {
setMarkingAsReadInProgress(true);
await markConversationRead({});
await axios.post("/sms/markConversationRead", {
conversationid: selectedConversation,
imexshopid: bodyshop.imexshopid
messageIds.forEach((messageId) => {
client.cache.modify({
id: client.cache.identify({ __typename: "messages", id: messageId }),
fields: {
read: () => true
}
});
});
setMarkingAsReadInProgress(false);
},
[client.cache]
);
// WebSocket event handlers
useEffect(() => {
if (!socket?.connected) return;
const handleConversationChange = (data) => {
if (data.type === "conversation-marked-read") {
const { conversationId, messageIds } = data;
updateCacheWithReadMessages(conversationId, messageIds);
}
};
socket.on("conversation-changed", handleConversationChange);
return () => {
socket.off("conversation-changed", handleConversationChange);
};
}, [socket, updateCacheWithReadMessages]);
// Join and leave conversation via WebSocket
useEffect(() => {
if (!socket?.connected || !selectedConversation || !bodyshop?.id) return;
socket.emit("join-bodyshop-conversation", {
bodyshopId: bodyshop.id,
conversationId: selectedConversation
});
return () => {
socket.emit("leave-bodyshop-conversation", {
bodyshopId: bodyshop.id,
conversationId: selectedConversation
});
};
}, [socket, bodyshop, selectedConversation]);
// Mark conversation as read
const handleMarkConversationAsRead = async () => {
if (!convoData || markingAsReadInProgress) return;
const conversation = convoData.conversations_by_pk;
if (!conversation) return;
const unreadMessageIds = conversation.messages
?.filter((message) => !message.read && !message.isoutbound)
.map((message) => message.id);
if (unreadMessageIds?.length > 0) {
setMarkingAsReadInProgress(true);
try {
await axios.post("/sms/markConversationRead", {
conversation,
imexshopid: bodyshop?.imexshopid,
bodyshopid: bodyshop?.id
});
updateCacheWithReadMessages(selectedConversation, unreadMessageIds);
} catch (error) {
console.error("Error marking conversation as read:", error.message);
} finally {
setMarkingAsReadInProgress(false);
}
}
};
return (
<ChatConversationComponent
subState={[loading || convoLoading, error || convoError]}
conversation={convoData ? convoData.conversations_by_pk : {}}
messages={data ? data.messages : []}
subState={[convoLoading, convoError]}
conversation={convoData?.conversations_by_pk || {}}
messages={convoData?.conversations_by_pk?.messages || []}
handleMarkConversationAsRead={handleMarkConversationAsRead}
/>
);
}
export default connect(mapStateToProps)(ChatConversationContainer);

View File

@@ -1,14 +1,27 @@
import { PlusOutlined } from "@ant-design/icons";
import { useMutation } from "@apollo/client";
import { Input, notification, Spin, Tag, Tooltip } from "antd";
import React, { useState } from "react";
import { Input, Spin, Tag, Tooltip } from "antd";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { UPDATE_CONVERSATION_LABEL } from "../../graphql/conversations.queries";
import { useSocket } from "../../contexts/SocketIO/useSocket.jsx";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors.js";
import { connect } from "react-redux";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
export default function ChatLabel({ conversation }) {
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
});
const mapDispatchToProps = (dispatch) => ({});
export function ChatLabel({ conversation, bodyshop }) {
const [loading, setLoading] = useState(false);
const [editing, setEditing] = useState(false);
const [value, setValue] = useState(conversation.label);
const { socket } = useSocket();
const notification = useNotification();
const { t } = useTranslation();
const [updateLabel] = useMutation(UPDATE_CONVERSATION_LABEL);
@@ -26,6 +39,14 @@ export default function ChatLabel({ conversation }) {
})
});
} else {
if (socket) {
socket.emit("conversation-modified", {
type: "label-updated",
conversationId: conversation.id,
bodyshopId: bodyshop.id,
label: value
});
}
setEditing(false);
}
} catch (error) {
@@ -57,3 +78,5 @@ export default function ChatLabel({ conversation }) {
);
}
}
export default connect(mapStateToProps, mapDispatchToProps)(ChatLabel);

View File

@@ -1,106 +1,87 @@
import Icon from "@ant-design/icons";
import { Tooltip } from "antd";
import i18n from "i18next";
import dayjs from "../../utils/day";
import React, { useEffect, useRef } from "react";
import { MdDone, MdDoneAll } from "react-icons/md";
import { AutoSizer, CellMeasurer, CellMeasurerCache, List } from "react-virtualized";
import { DateTimeFormatter } from "../../utils/DateFormatter";
import React, { useCallback, useEffect, useRef, useState } from "react";
import { Virtuoso } from "react-virtuoso";
import { renderMessage } from "./renderMessage";
import "./chat-message-list.styles.scss";
export default function ChatMessageListComponent({ messages }) {
const virtualizedListRef = useRef(null);
const virtuosoRef = useRef(null);
const [atBottom, setAtBottom] = useState(true);
const loadedImagesRef = useRef(0);
const _cache = new CellMeasurerCache({
fixedWidth: true,
// minHeight: 50,
defaultHeight: 100
});
const scrollToBottom = (renderedrows) => {
//console.log("Scrolling to", messages.length);
// !!virtualizedListRef.current &&
// virtualizedListRef.current.scrollToRow(messages.length);
// Outstanding isue on virtualization: https://github.com/bvaughn/react-virtualized/issues/1179
//Scrolling does not work on this version of React.
const handleScrollStateChange = (isAtBottom) => {
setAtBottom(isAtBottom);
};
useEffect(scrollToBottom, [messages]);
const _rowRenderer = ({ index, key, parent, style }) => {
return (
<CellMeasurer cache={_cache} key={key} rowIndex={index} parent={parent}>
{({ measure, registerChild }) => (
<div
ref={registerChild}
onLoad={measure}
style={style}
className={`${messages[index].isoutbound ? "mine messages" : "yours messages"}`}
>
<div className="message msgmargin">
{MessageRender(messages[index])}
{StatusRender(messages[index].status)}
</div>
{messages[index].isoutbound && (
<div style={{ fontSize: 10 }}>
{i18n.t("messaging.labels.sentby", {
by: messages[index].userid,
time: dayjs(messages[index].created_at).format("MM/DD/YYYY @ hh:mm a")
})}
</div>
)}
</div>
)}
</CellMeasurer>
);
const resetImageLoadState = () => {
loadedImagesRef.current = 0;
};
const preloadImages = useCallback((imagePaths, onComplete) => {
resetImageLoadState();
if (imagePaths.length === 0) {
onComplete();
return;
}
imagePaths.forEach((url) => {
const img = new Image();
img.src = url;
img.onload = img.onerror = () => {
loadedImagesRef.current += 1;
if (loadedImagesRef.current === imagePaths.length) {
onComplete();
}
};
});
}, []);
// Ensure all images are loaded on initial render
useEffect(() => {
const imagePaths = messages
.filter((message) => message.image && message.image_path?.length > 0)
.flatMap((message) => message.image_path);
preloadImages(imagePaths, () => {
if (virtuosoRef.current) {
virtuosoRef.current.scrollToIndex({
index: messages.length - 1,
align: "end",
behavior: "auto"
});
}
});
}, [messages, preloadImages]);
// Handle scrolling when new messages are added
useEffect(() => {
if (!atBottom) return;
const latestMessage = messages[messages.length - 1];
const imagePaths = latestMessage?.image_path || [];
preloadImages(imagePaths, () => {
if (virtuosoRef.current) {
virtuosoRef.current.scrollToIndex({
index: messages.length - 1,
align: "end",
behavior: "smooth"
});
}
});
}, [messages, atBottom, preloadImages]);
return (
<div className="chat">
<AutoSizer>
{({ height, width }) => (
<List
ref={virtualizedListRef}
width={width}
height={height}
rowHeight={_cache.rowHeight}
rowRenderer={_rowRenderer}
rowCount={messages.length}
overscanRowCount={10}
estimatedRowSize={150}
scrollToIndex={messages.length}
/>
)}
</AutoSizer>
<Virtuoso
ref={virtuosoRef}
data={messages}
overscan={!!messages.reduce((acc, message) => acc + (message.image_path?.length || 0), 0) ? messages.length : 0}
itemContent={(index) => renderMessage(messages, index)}
followOutput={(isAtBottom) => handleScrollStateChange(isAtBottom)}
initialTopMostItemIndex={messages.length - 1}
style={{ height: "100%", width: "100%" }}
/>
</div>
);
}
const MessageRender = (message) => {
return (
<Tooltip title={DateTimeFormatter({ children: message.created_at })}>
<div>
{message.image_path &&
message.image_path.map((i, idx) => (
<div key={idx} style={{ display: "flex", justifyContent: "center" }}>
<a href={i} target="__blank">
<img alt="Received" className="message-img" src={i} />
</a>
</div>
))}
<div>{message.text}</div>
</div>
</Tooltip>
);
};
const StatusRender = (status) => {
switch (status) {
case "sent":
return <Icon component={MdDone} className="message-icon" />;
case "delivered":
return <Icon component={MdDoneAll} className="message-icon" />;
default:
return null;
}
};

View File

@@ -1,119 +1,131 @@
.message-icon {
//position: absolute;
// bottom: 0rem;
color: whitesmoke;
border: #000000;
position: absolute;
margin: 0 0.1rem;
bottom: 0.1rem;
right: 0.3rem;
z-index: 5;
}
.chat {
flex: 1;
//width: 300px;
//border: solid 1px #eee;
display: flex;
flex-direction: column;
margin: 0.8rem 0rem;
height: 100%;
width: 100%;
}
.archive-button {
height: 20px;
border-radius: 4px;
}
.chat-title {
margin-bottom: 5px;
}
.messages {
//margin-top: 30px;
display: flex;
flex-direction: column;
padding: 0.5rem; // Prevent edge clipping
}
.message {
position: relative;
border-radius: 20px;
padding: 0.25rem 0.8rem;
//margin-top: 5px;
// margin-bottom: 5px;
//display: inline-block;
word-wrap: break-word;
.message-img {
&-img {
max-width: 10rem;
max-height: 10rem;
object-fit: contain;
margin: 0.2rem;
border-radius: 4px;
}
&-images {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
}
.yours {
align-items: flex-start;
.chat-send-message-button{
margin: 0.3rem;
padding-left: 0.5rem;
}
.message-icon {
position: absolute;
bottom: 0.1rem;
right: 0.3rem;
margin: 0 0.1rem;
color: whitesmoke;
z-index: 5;
}
.msgmargin {
margin-top: 0.1rem;
margin-bottom: 0.1rem;
margin: 0.1rem 0;
}
.yours .message {
margin-right: 20%;
background-color: #eee;
position: relative;
.yours,
.mine {
display: flex;
flex-direction: column;
.message {
position: relative;
&:last-child:before,
&:last-child:after {
content: "";
position: absolute;
bottom: 0;
height: 20px;
width: 20px;
z-index: 0;
}
&:last-child:after {
width: 10px;
background: white;
z-index: 1;
}
}
}
.yours .message.last:before {
content: "";
position: absolute;
z-index: 0;
bottom: 0;
left: -7px;
height: 20px;
width: 20px;
background: #eee;
border-bottom-right-radius: 15px;
}
.yours .message.last:after {
content: "";
position: absolute;
z-index: 1;
bottom: 0;
left: -10px;
width: 10px;
height: 20px;
background: white;
border-bottom-right-radius: 10px;
/* "Yours" (incoming) message styles */
.yours {
align-items: flex-start;
.message {
margin-right: 20%;
background-color: #eee;
&:last-child:before {
left: -7px;
background: #eee;
border-bottom-right-radius: 15px;
}
&:last-child:after {
left: -10px;
border-bottom-right-radius: 10px;
}
}
}
/* "Mine" (outgoing) message styles */
.mine {
align-items: flex-end;
.message {
color: white;
margin-left: 25%;
background: linear-gradient(to bottom, #00d0ea 0%, #0085d1 100%);
padding-bottom: 0.6rem;
&:last-child:before {
right: -8px;
background: linear-gradient(to bottom, #00d0ea 0%, #0085d1 100%);
border-bottom-left-radius: 15px;
}
&:last-child:after {
right: -10px;
border-bottom-left-radius: 10px;
}
}
}
.mine .message {
color: white;
margin-left: 25%;
background: linear-gradient(to bottom, #00d0ea 0%, #0085d1 100%);
background-attachment: fixed;
position: relative;
padding-bottom: 0.6rem;
}
.mine .message.last:before {
content: "";
position: absolute;
z-index: 0;
bottom: 0;
right: -8px;
height: 20px;
width: 20px;
background: linear-gradient(to bottom, #00d0ea 0%, #0085d1 100%);
background-attachment: fixed;
border-bottom-left-radius: 15px;
}
.mine .message.last:after {
content: "";
position: absolute;
z-index: 1;
bottom: 0;
right: -10px;
width: 10px;
height: 20px;
background: white;
border-bottom-left-radius: 10px;
.virtuoso-container {
flex: 1;
overflow: auto;
}

View File

@@ -0,0 +1,52 @@
import Icon from "@ant-design/icons";
import { Tooltip } from "antd";
import i18n from "i18next";
import dayjs from "../../utils/day";
import { MdDone, MdDoneAll } from "react-icons/md";
import { DateTimeFormatter } from "../../utils/DateFormatter";
export const renderMessage = (messages, index) => {
const message = messages[index];
return (
<div key={index} className={`${message.isoutbound ? "mine messages" : "yours messages"}`}>
<div className="message msgmargin">
<Tooltip title={DateTimeFormatter({ children: message.created_at })}>
<div>
{/* Render images if available */}
{message.image && message.image_path?.length > 0 && (
<div className="message-images">
{message.image_path.map((url, idx) => (
<div key={idx} style={{ display: "flex", justifyContent: "center" }}>
<a href={url} target="_blank" rel="noopener noreferrer">
<img alt="Received" className="message-img" src={url} />
</a>
</div>
))}
</div>
)}
{/* Render text if available */}
{message.text && <div>{message.text}</div>}
</div>
</Tooltip>
{/* Message status icons */}
{message.status && (message.status === "sent" || message.status === "delivered") && (
<div className="message-status">
<Icon component={message.status === "sent" ? MdDone : MdDoneAll} className="message-icon" />
</div>
)}
</div>
{/* Outbound message metadata */}
{message.isoutbound && (
<div style={{ fontSize: 10 }}>
{i18n.t("messaging.labels.sentby", {
by: message.userid,
time: dayjs(message.created_at).format("MM/DD/YYYY @ hh:mm a")
})}
</div>
)}
</div>
);
};

View File

@@ -1,11 +1,11 @@
import { PlusCircleFilled } from "@ant-design/icons";
import { Button, Form, Popover } from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { openChatByPhone } from "../../redux/messaging/messaging.actions";
import PhoneFormItem, { PhoneItemFormatterValidation } from "../form-items-formatted/phone-form-item.component";
import { useSocket } from "../../contexts/SocketIO/useSocket.jsx";
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
@@ -17,8 +17,10 @@ const mapDispatchToProps = (dispatch) => ({
export function ChatNewConversation({ openChatByPhone }) {
const { t } = useTranslation();
const [form] = Form.useForm();
const { socket } = useSocket();
const handleFinish = (values) => {
openChatByPhone({ phone_num: values.phoneNumber });
openChatByPhone({ phone_num: values.phoneNumber, socket });
form.resetFields();
};

View File

@@ -1,6 +1,4 @@
import { notification } from "antd";
import parsePhoneNumber from "libphonenumber-js";
import React from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { openChatByPhone } from "../../redux/messaging/messaging.actions";
@@ -9,6 +7,8 @@ import PhoneNumberFormatter from "../../utils/PhoneFormatter";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { searchingForConversation } from "../../redux/messaging/messaging.selectors";
import { useSocket } from "../../contexts/SocketIO/useSocket.jsx";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -21,6 +21,9 @@ const mapDispatchToProps = (dispatch) => ({
export function ChatOpenButton({ bodyshop, searchingForConversation, phone, jobid, openChatByPhone }) {
const { t } = useTranslation();
const { socket } = useSocket();
const notification = useNotification();
if (!phone) return <></>;
if (!bodyshop.messagingservicesid) return <PhoneNumberFormatter>{phone}</PhoneNumberFormatter>;
@@ -33,7 +36,7 @@ export function ChatOpenButton({ bodyshop, searchingForConversation, phone, jobi
const p = parsePhoneNumber(phone, "CA");
if (searchingForConversation) return; //This is to prevent finding the same thing twice.
if (p && p.isValid()) {
openChatByPhone({ phone_num: p.formatInternational(), jobid: jobid });
openChatByPhone({ phone_num: p.formatInternational(), jobid: jobid, socket });
} else {
notification["error"]({ message: t("messaging.error.invalidphone") });
}

View File

@@ -1,7 +1,7 @@
import { InfoCircleOutlined, MessageOutlined, ShrinkOutlined, SyncOutlined } from "@ant-design/icons";
import { useLazyQuery, useQuery } from "@apollo/client";
import { useApolloClient, useLazyQuery, useQuery } from "@apollo/client";
import { Badge, Card, Col, Row, Space, Tag, Tooltip, Typography } from "antd";
import React, { useCallback, useEffect, useState } from "react";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -12,62 +12,99 @@ import ChatConversationListComponent from "../chat-conversation-list/chat-conver
import ChatConversationContainer from "../chat-conversation/chat-conversation.container";
import ChatNewConversation from "../chat-new-conversation/chat-new-conversation.component";
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
import { useSocket } from "../../contexts/SocketIO/useSocket.jsx";
import "./chat-popup.styles.scss";
const mapStateToProps = createStructuredSelector({
selectedConversation: selectSelectedConversation,
chatVisible: selectChatVisible
});
const mapDispatchToProps = (dispatch) => ({
toggleChatVisible: () => dispatch(toggleChatVisible())
});
export function ChatPopupComponent({ chatVisible, selectedConversation, toggleChatVisible }) {
const { t } = useTranslation();
const [pollInterval, setpollInterval] = useState(0);
const [pollInterval, setPollInterval] = useState(0);
const { socket } = useSocket();
const client = useApolloClient(); // Apollo Client instance for cache operations
const { data: unreadData } = useQuery(UNREAD_CONVERSATION_COUNT, {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
...(pollInterval > 0 ? { pollInterval } : {})
});
const [getConversations, { loading, data, refetch, fetchMore }] = useLazyQuery(CONVERSATION_LIST_QUERY, {
// Lazy query for conversations
const [getConversations, { loading, data, refetch }] = useLazyQuery(CONVERSATION_LIST_QUERY, {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
skip: !chatVisible,
...(pollInterval > 0 ? { pollInterval } : {})
});
const fcmToken = sessionStorage.getItem("fcmtoken");
// Query for unread count when chat is not visible
const { data: unreadData } = useQuery(UNREAD_CONVERSATION_COUNT, {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
pollInterval: 60 * 1000 // TODO: This is a fix for now, should be coming from sockets
});
// Socket connection status
useEffect(() => {
if (fcmToken) {
setpollInterval(0);
} else {
setpollInterval(60000);
}
}, [fcmToken]);
const handleSocketStatus = () => {
if (socket?.connected) {
setPollInterval(15 * 60 * 1000); // 15 minutes
} else {
setPollInterval(60 * 1000); // 60 seconds
}
};
handleSocketStatus();
if (socket) {
socket.on("connect", handleSocketStatus);
socket.on("disconnect", handleSocketStatus);
}
return () => {
if (socket) {
socket.off("connect", handleSocketStatus);
socket.off("disconnect", handleSocketStatus);
}
};
}, [socket]);
// Fetch conversations when chat becomes visible
useEffect(() => {
if (chatVisible)
getConversations({
variables: {
offset: 0
}
}).catch((err) => {
console.error(`Error fetching conversations: ${(err, err.message || "")}`);
});
}, [chatVisible, getConversations]);
const loadMoreConversations = useCallback(() => {
if (data)
fetchMore({
variables: {
offset: data.conversations.length
}
// Get unread count from the cache
const unreadCount = (() => {
try {
const cachedData = client.readQuery({
query: CONVERSATION_LIST_QUERY,
variables: { offset: 0 }
});
}, [data, fetchMore]);
const unreadCount = unreadData?.messages_aggregate.aggregate.count || 0;
if (!cachedData?.conversations) {
return unreadData?.messages_aggregate?.aggregate?.count;
}
// Aggregate unread message count
return cachedData.conversations.reduce((total, conversation) => {
const unread = conversation.messages_aggregate?.aggregate?.count || 0;
return total + unread;
}, 0);
} catch (error) {
console.warn("Unread count not found in cache:", error);
return 0; // Fallback if not in cache
}
})();
return (
<Badge count={unreadCount}>
@@ -81,7 +118,7 @@ export function ChatPopupComponent({ chatVisible, selectedConversation, toggleCh
<InfoCircleOutlined />
</Tooltip>
<SyncOutlined style={{ cursor: "pointer" }} onClick={() => refetch()} />
{pollInterval > 0 && <Tag color="yellow">{t("messaging.labels.nopush")}</Tag>}
{!socket?.connected && <Tag color="yellow">{t("messaging.labels.nopush")}</Tag>}
</Space>
<ShrinkOutlined
onClick={() => toggleChatVisible()}
@@ -93,10 +130,7 @@ export function ChatPopupComponent({ chatVisible, selectedConversation, toggleCh
{loading ? (
<LoadingSpinner />
) : (
<ChatConversationListComponent
conversationList={data ? data.conversations : []}
loadMoreConversations={loadMoreConversations}
/>
<ChatConversationListComponent conversationList={data ? data.conversations : []} />
)}
</Col>
<Col span={16}>{selectedConversation ? <ChatConversationContainer /> : null}</Col>

View File

@@ -6,6 +6,7 @@ import { createStructuredSelector } from "reselect";
import { setEmailOptions } from "../../redux/email/email.actions";
import { GenerateDocument } from "../../utils/RenderTemplate";
import { TemplateList } from "../../utils/TemplateConstants";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
const mapStateToProps = createStructuredSelector({});
@@ -15,6 +16,7 @@ const mapDispatchToProps = (dispatch) => ({
export function ChatPrintButton({ conversation }) {
const [loading, setLoading] = useState(false);
const notification = useNotification();
const generateDocument = (type) => {
setLoading(true);
@@ -27,7 +29,8 @@ export function ChatPrintButton({ conversation }) {
subject: TemplateList("messaging").conversation_list.subject
},
type,
conversation.id
conversation.id,
notification
).catch((e) => {
console.warn("Something went wrong generating a document.");
});

View File

@@ -25,6 +25,7 @@ const mapDispatchToProps = (dispatch) => ({
function ChatSendMessageComponent({ conversation, bodyshop, sendMessage, isSending, message, setMessage }) {
const inputArea = useRef(null);
const [selectedMedia, setSelectedMedia] = useState([]);
useEffect(() => {
inputArea.current.focus();
}, [isSending, setMessage]);
@@ -37,14 +38,15 @@ function ChatSendMessageComponent({ conversation, bodyshop, sendMessage, isSendi
logImEXEvent("messaging_send_message");
if (selectedImages.length < 11) {
sendMessage({
const newMessage = {
to: conversation.phone_num,
body: message || "",
messagingServiceSid: bodyshop.messagingservicesid,
conversationid: conversation.id,
selectedMedia: selectedImages,
imexshopid: bodyshop.imexshopid
});
};
sendMessage(newMessage);
setSelectedMedia(
selectedMedia.map((i) => {
return { ...i, isSelected: false };
@@ -79,7 +81,7 @@ function ChatSendMessageComponent({ conversation, bodyshop, sendMessage, isSendi
/>
</span>
<SendOutlined
className="imex-flex-row__margin"
className="chat-send-message-button"
// disabled={message === "" || !message}
onClick={handleEnter}
/>

View File

@@ -2,22 +2,33 @@ import { PlusOutlined } from "@ant-design/icons";
import { useLazyQuery, useMutation } from "@apollo/client";
import { Tag } from "antd";
import _ from "lodash";
import React, { useState } from "react";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { logImEXEvent } from "../../firebase/firebase.utils";
import { INSERT_CONVERSATION_TAG } from "../../graphql/job-conversations.queries";
import { SEARCH_FOR_JOBS } from "../../graphql/jobs.queries";
import ChatTagRo from "./chat-tag-ro.component";
import { useSocket } from "../../contexts/SocketIO/useSocket.jsx";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors.js";
import { connect } from "react-redux";
export default function ChatTagRoContainer({ conversation }) {
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
});
const mapDispatchToProps = () => ({});
export function ChatTagRoContainer({ conversation, bodyshop }) {
const { t } = useTranslation();
const [open, setOpen] = useState(false);
const { socket } = useSocket();
const [loadRo, { loading, data }] = useLazyQuery(SEARCH_FOR_JOBS);
const executeSearch = (v) => {
logImEXEvent("messaging_search_job_tag", { searchTerm: v });
loadRo(v);
loadRo(v).catch((e) => console.error("Error in ChatTagRoContainer executeSearch:", e));
};
const debouncedExecuteSearch = _.debounce(executeSearch, 500);
@@ -30,9 +41,40 @@ export default function ChatTagRoContainer({ conversation }) {
variables: { conversationId: conversation.id }
});
const handleInsertTag = (value, option) => {
const handleInsertTag = async (value, option) => {
logImEXEvent("messaging_add_job_tag");
insertTag({ variables: { jobId: option.key } });
await insertTag({
variables: { jobId: option.key }
});
if (socket) {
// Find the job details from the search data
const selectedJob = data?.search_jobs.find((job) => job.id === option.key);
if (!selectedJob) return;
socket.emit("conversation-modified", {
conversationId: conversation.id,
bodyshopId: bodyshop.id,
type: "tag-added",
selectedJob,
job_conversations: [
{
__typename: "job_conversations",
jobid: selectedJob.id,
conversationid: conversation.id,
job: {
__typename: "jobs",
id: selectedJob.id,
ro_number: selectedJob.ro_number,
ownr_co_nm: selectedJob.ownr_co_nm,
ownr_fn: selectedJob.ownr_fn,
ownr_ln: selectedJob.ownr_ln
}
}
]
});
}
setOpen(false);
};
@@ -50,9 +92,10 @@ export default function ChatTagRoContainer({ conversation }) {
handleSearch={handleSearch}
handleInsertTag={handleInsertTag}
setOpen={setOpen}
style={{ cursor: "pointer" }}
/>
) : (
<Tag onClick={() => setOpen(true)}>
<Tag style={{ cursor: "pointer" }} onClick={() => setOpen(true)}>
<PlusOutlined />
{t("messaging.actions.link")}
</Tag>
@@ -60,3 +103,5 @@ export default function ChatTagRoContainer({ conversation }) {
</div>
);
}
export default connect(mapStateToProps, mapDispatchToProps)(ChatTagRoContainer);

View File

@@ -16,8 +16,7 @@ export default function ConflictComponent() {
{t("general.labels.instanceconflictext", {
app: InstanceRenderManager({
imex: "$t(titles.imexonline)",
rome: "$t(titles.romeonline)",
promanager: "$t(titles.promanager)"
rome: "$t(titles.romeonline)"
})
})}
</div>

View File

@@ -1,5 +1,5 @@
import { useMutation } from "@apollo/client";
import { Button, Form, InputNumber, notification, Popover, Radio, Select, Space } from "antd";
import { Button, Form, InputNumber, Popover, Radio, Select, Space } from "antd";
import axios from "axios";
import dayjs from "../../utils/day";
import React, { useState } from "react";
@@ -9,6 +9,7 @@ import { useNavigate } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import { INSERT_NEW_JOB } from "../../graphql/jobs.queries";
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
@@ -25,6 +26,7 @@ export function ContractConvertToRo({ bodyshop, currentUser, contract, disabled
const [loading, setLoading] = useState(false);
const [insertJob] = useMutation(INSERT_NEW_JOB);
const history = useNavigate();
const notification = useNotification();
const handleFinish = async (values) => {
setLoading(true);

View File

@@ -1,12 +1,14 @@
import { useLazyQuery } from "@apollo/client";
import { Button, notification } from "antd";
import { Button } from "antd";
import React, { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { GET_JOB_FOR_CC_CONTRACT } from "../../graphql/jobs.queries";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
export default function ContractCreateJobPrefillComponent({ jobId, form }) {
const [call, { loading, error, data }] = useLazyQuery(GET_JOB_FOR_CC_CONTRACT);
const { t } = useTranslation();
const notification = useNotification();
const handleClick = () => {
call({ variables: { id: jobId } });

View File

@@ -1,15 +1,17 @@
import { WarningFilled } from "@ant-design/icons";
import { Form, Input, InputNumber, Space } from "antd";
import dayjs from "../../utils/day";
import React from "react";
import { useTranslation } from "react-i18next";
import { DateFormatter } from "../../utils/DateFormatter";
import dayjs from "../../utils/day";
//import ContractLicenseDecodeButton from "../contract-license-decode-button/contract-license-decode-button.component";
import ContractStatusSelector from "../contract-status-select/contract-status-select.component";
import ContractsRatesChangeButton from "../contracts-rates-change-button/contracts-rates-change-button.component";
import CourtesyCarFuelSlider from "../courtesy-car-fuel-select/courtesy-car-fuel-select.component";
import FormDateTimePicker from "../form-date-time-picker/form-date-time-picker.component";
import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component";
import {
default as DateTimePicker,
default as FormDateTimePicker
} from "../form-date-time-picker/form-date-time-picker.component";
import FormFieldsChanged from "../form-fields-changed-alert/form-fields-changed-alert.component";
import InputPhone, { PhoneItemFormatterValidation } from "../form-items-formatted/phone-form-item.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
@@ -18,10 +20,10 @@ import ContractFormJobPrefill from "./contract-form-job-prefill.component";
export default function ContractFormComponent({ form, create = false, selectedJobState, selectedCar }) {
const { t } = useTranslation();
return (
<div>
<FormFieldsChanged form={form} />
<>
{!create && <FormFieldsChanged form={form} />}
<LayoutFormRow>
{create ? null : (
{!create && (
<Form.Item
label={t("contracts.fields.status")}
name="status"
@@ -50,7 +52,7 @@ export default function ContractFormComponent({ form, create = false, selectedJo
<Form.Item label={t("contracts.fields.scheduledreturn")} name="scheduledreturn">
<FormDateTimePicker />
</Form.Item>
{create ? null : (
{!create && (
<Form.Item label={t("contracts.fields.actualreturn")} name="actualreturn">
<FormDateTimePicker />
</Form.Item>
@@ -122,7 +124,7 @@ export default function ContractFormComponent({ form, create = false, selectedJo
}}
</Form.Item>
)}
{create ? null : (
{!create && (
<Form.Item label={t("contracts.fields.kmend")} name="kmend">
<InputNumber />
</Form.Item>
@@ -145,25 +147,21 @@ export default function ContractFormComponent({ form, create = false, selectedJo
>
<CourtesyCarFuelSlider />
</Form.Item>
{create ? null : (
{!create && (
<Form.Item label={t("contracts.fields.fuelin")} name="fuelin" span={8}>
<CourtesyCarFuelSlider />
</Form.Item>
)}
</LayoutFormRow>
<div>
<Space wrap>
{selectedJobState && (
<div>
<ContractFormJobPrefill jobId={selectedJobState && selectedJobState[0]} form={form} />
</div>
)}
{
//<ContractLicenseDecodeButton form={form} />
}
</Space>
</div>
<LayoutFormRow header={t("contracts.labels.driverinformation")}>
<Space wrap>
{create && selectedJobState && (
<ContractFormJobPrefill jobId={selectedJobState && selectedJobState[0]} form={form} />
)}
{/* {<ContractLicenseDecodeButton form={form} />} */}
</Space>
</LayoutFormRow>
<LayoutFormRow noDivider={true}>
<Form.Item
label={t("contracts.fields.driver_dlnumber")}
name="driver_dlnumber"
@@ -183,9 +181,8 @@ export default function ContractFormComponent({ form, create = false, selectedJo
const dlExpiresBeforeReturn = dayjs(form.getFieldValue("driver_dlexpiry")).isBefore(
dayjs(form.getFieldValue("scheduledreturn"))
);
return (
<div>
<>
<Form.Item
label={t("contracts.fields.driver_dlexpiry")}
name="driver_dlexpiry"
@@ -204,11 +201,10 @@ export default function ContractFormComponent({ form, create = false, selectedJo
<span>{t("contracts.labels.dlexpirebeforereturn")}</span>
</Space>
)}
</div>
</>
);
}}
</Form.Item>
<Form.Item label={t("contracts.fields.driver_dlst")} name="driver_dlst">
<Input />
</Form.Item>
@@ -315,6 +311,6 @@ export default function ContractFormComponent({ form, create = false, selectedJo
<InputNumber precision={2} />
</Form.Item>
</LayoutFormRow>
</div>
</>
);
}

View File

@@ -1,4 +1,4 @@
import { Form, Modal, notification } from "antd";
import { Form, Modal } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -10,6 +10,7 @@ import CourtesyCarReturnModalComponent from "./courtesy-car-return-modal.compone
import dayjs from "../../utils/day";
import { RETURN_CONTRACT } from "../../graphql/cccontracts.queries";
import { useMutation } from "@apollo/client";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
const mapStateToProps = createStructuredSelector({
courtesyCarReturnModal: selectCourtesyCarReturn,
@@ -26,6 +27,8 @@ export function CCReturnModalContainer({ courtesyCarReturnModal, toggleModalVisi
const { t } = useTranslation();
const [form] = Form.useForm();
const [updateContract] = useMutation(RETURN_CONTRACT);
const notification = useNotification();
const handleFinish = (values) => {
setLoading(true);
updateContract({

View File

@@ -10,6 +10,7 @@ import { TemplateList } from "../../utils/TemplateConstants";
import { alphaSort } from "../../utils/sorters";
import useLocalStorage from "../../utils/useLocalStorage";
import { OwnerNameDisplayFunction } from "../owner-name-display/owner-name-display.component";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
export default function CourtesyCarsList({ loading, courtesycars, refetch }) {
const [state, setState] = useState({
@@ -18,6 +19,7 @@ export default function CourtesyCarsList({ loading, courtesycars, refetch }) {
const [searchText, setSearchText] = useState("");
const [filter, setFilter] = useLocalStorage("filter_courtesy_cars_list", null);
const { t } = useTranslation();
const notification = useNotification();
const columns = [
{
@@ -64,8 +66,8 @@ export default function CourtesyCarsList({ loading, courtesycars, refetch }) {
},
{
text: t("courtesycars.status.unavailable"),
value: "courtesycars.status.unavailable",
},
value: "courtesycars.status.unavailable"
}
],
onFilter: (value, record) => record.status === value,
sortOrder: state.sortedInfo.columnKey === "status" && state.sortedInfo.order,
@@ -239,7 +241,9 @@ export default function CourtesyCarsList({ loading, courtesycars, refetch }) {
}
},
{},
"p"
"p",
null,
notification
)
}
];

View File

@@ -1,10 +1,10 @@
import { Card, Table, Tag } from "antd";
import LoadingSkeleton from "../../loading-skeleton/loading-skeleton.component";
import { useTranslation } from "react-i18next";
import React, { useEffect, useState } from "react";
import dayjs from "../../../utils/day";
import DashboardRefreshRequired from "../refresh-required.component";
import axios from "axios";
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import dayjs from "../../../utils/day";
import LoadingSkeleton from "../../loading-skeleton/loading-skeleton.component";
import DashboardRefreshRequired from "../refresh-required.component";
const fortyFiveDaysAgo = () => dayjs().subtract(45, "day").toLocaleString();
@@ -46,6 +46,11 @@ export default function JobLifecycleDashboardComponent({ data, bodyshop, ...card
dataIndex: "humanReadable",
key: "humanReadable"
},
{
title: t("job_lifecycle.columns.average_human_readable"),
dataIndex: "averageHumanReadable",
key: "averageHumanReadable"
},
{
title: t("job_lifecycle.columns.status_count"),
key: "statusCount",

View File

@@ -1,6 +1,6 @@
import Icon, { SyncOutlined } from "@ant-design/icons";
import { gql, useMutation, useQuery } from "@apollo/client";
import { Button, Dropdown, notification, Space } from "antd";
import { Button, Dropdown, Space } from "antd";
import { PageHeader } from "@ant-design/pro-layout";
import i18next from "i18next";
import _ from "lodash";
@@ -46,6 +46,7 @@ import JobLifecycleDashboardComponent, {
} from "../dashboard-components/job-lifecycle/job-lifecycle-dashboard.component";
import "./dashboard-grid.styles.scss";
import { GenerateDashboardData } from "./dashboard-grid.utils";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
const ResponsiveReactGridLayout = WidthProvider(Responsive);
@@ -64,6 +65,7 @@ export function DashboardGridComponent({ currentUser, bodyshop }) {
? bodyshop.associations[0].user.dashboardlayout
: { items: [], layout: {}, layouts: [] })
});
const notification = useNotification();
const { loading, error, data, refetch } = useQuery(createDashboardQuery(state), {
fetchPolicy: "network-only",

View File

@@ -40,13 +40,11 @@ export function DmsLogEvents({ socket, logs, bodyshop }) {
function LogLevelHierarchy(level) {
switch (level) {
case "TRACE":
return "pink";
case "DEBUG":
return "orange";
case "INFO":
return "blue";
case "WARNING":
case "WARN":
return "yellow";
case "ERROR":
return "red";

View File

@@ -9,6 +9,7 @@ import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selecto
import { handleUpload } from "../documents-upload/documents-upload.utility";
import { GenerateSrcUrl } from "../jobs-documents-gallery/job-documents.utility";
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
@@ -24,6 +25,7 @@ export function DocumentEditorComponent({ currentUser, bodyshop, document }) {
const [uploaded, setuploaded] = useState(false);
const markerArea = useRef(null);
const { t } = useTranslation();
const notification = useNotification();
const triggerUpload = useCallback(
async (dataUrl) => {
@@ -45,10 +47,11 @@ export function DocumentEditorComponent({ currentUser, bodyshop, document }) {
//billId: billId,
tagsArray: ["edited"]
//callback: callbackAfterUpload,
}
},
notification
);
},
[bodyshop, currentUser, document]
[bodyshop, currentUser, document, notification]
);
useEffect(() => {

Some files were not shown because too many files have changed in this diff Show More