@capillarytech/cap-ui-utils 3.0.9-alpha.1 → 3.0.9-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capillarytech/cap-ui-utils",
3
- "version": "3.0.9-alpha.1",
3
+ "version": "3.0.9-alpha.3",
4
4
  "description": "Utility functions shared accross all the modules",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -105,4 +105,10 @@ export const TMPL_SANITIZE_FORBIDDEN_JS_TAGS = [
105
105
  "vbscript:",
106
106
  "livescript:",
107
107
  "xss:",
108
- ];
108
+ ];
109
+
110
+ /**
111
+ * Constants for timezone feature
112
+ */
113
+ export const TIMEZONE_ENABLED = "TIMEZONE_ENABLED";
114
+ export const DATE_FORMAT = "DD MMM YYYY h:mm A";
package/utils/timezone.js CHANGED
@@ -1,62 +1,88 @@
1
1
  import moment from "moment-timezone";
2
2
  import * as utilsLocalStorageApi from "./utilsLocalStorageApi";
3
+ import { DATE_FORMAT,TIMEZONE_ENABLED } from "./constants";
4
+ import hasFeatureAccess from "../auth/hasFeatureAccess";
3
5
 
4
- export const DATE_FORMAT = "DD MMM YYYY h:mm A";
6
+ const getTimezoneFormattedDate = (date,orgTZ = false,serverTZ = false,customTZ = null) => {
7
+ const orgTimezone = utilsLocalStorageApi.loadItem("orgTZ") || "Asia/Kolkata";
8
+ const serverTimezone = utilsLocalStorageApi.loadItem("serverTZ") || "Asia/Kolkata";
9
+ const targetTimezone = customTZ || (serverTZ ? serverTimezone : orgTZ ? orgTimezone : orgTimezone);
10
+ let momentDate;
11
+
12
+ // If date is epoch (number or numeric string)
13
+ if (typeof date === "number" || (typeof date === "string" && /^\d+$/.test(date))) {
14
+ const timestamp = typeof date === "string" ? parseInt(date, 10) : date;
15
+ // Handle zero and negative timestamps
16
+ if (timestamp === 0) {
17
+ momentDate = moment.utc(0).tz(targetTimezone);
18
+ } else if (timestamp < 0) {
19
+ momentDate = moment.utc(timestamp * 1000).tz(targetTimezone);
20
+ } else {
21
+ const timestampMs = timestamp < 1e12 ? timestamp * 1000 : timestamp;
22
+ momentDate = moment.utc(timestampMs).tz(targetTimezone);
23
+ }
24
+ } else if (typeof date === "string") {
25
+ // Try to parse formatted date string like "10 Oct 2025 4:00 PM IST"
26
+ const formattedDatePattern = /^\d{1,2}\s+\w{3}\s+\d{4}\s+\d{1,2}:\d{2}\s+[AP]M\s+\w+$/;
27
+ if (formattedDatePattern.test(date.trim())) {
28
+ // Extract timezone abbreviation from the string
29
+ const parts = date.trim().split(' ');
30
+ const dateWithoutTz = parts.slice(0, -1).join(' '); // Remove timezone part
31
+
32
+ // Parse the date part first
33
+ momentDate = moment(dateWithoutTz, "DD MMM YYYY h:mm A");
34
+
35
+ // If parsing was successful, convert to target timezone
36
+ if (momentDate.isValid()) {
37
+ momentDate = momentDate.tz(targetTimezone);
38
+ }
39
+ } else {
40
+ // Try standard ISO or other formats
41
+ momentDate = moment.tz(date, targetTimezone);
42
+ }
43
+ } else {
44
+ momentDate = moment.tz(date, targetTimezone);
45
+ }
46
+
47
+ return momentDate;
48
+ }
5
49
 
6
50
  /**
7
51
  * Formats a date into "DD MMM YYYY h:mm A <TZ>" format.
8
- * Handles ISO strings and epoch timestamps.
52
+ * Handles epoch timestamps and ISO date strings with timezone offsets.
9
53
  *
10
- * - ISO input:
11
- * - orgTZ=false keep ISO timezone info
12
- * - orgTZ=true convert to org timezone
13
- * - Epoch input:
14
- * - Always converts to org timezone
54
+ * Timezone Selection Priority:
55
+ * 1. customTZ (if provided) - overrides all others
56
+ * 2. serverTZ=true uses server timezone from localStorage
57
+ * 3. orgTZ=true uses organization timezone from localStorage
58
+ * 4. Default uses organization timezone from localStorage
15
59
  *
16
- * @param {string|number|Date} date - ISO string, epoch (sec/ms), or Date object.
17
- * @param {boolean} orgTZ - Whether to force conversion into org timezone.
18
- * @returns {string} Formatted date string with strict TZ abbreviation or '-'.
60
+ * Input Handling:
61
+ * - Epoch input (number or numeric string):
62
+ * - Treated as UTC timestamp (seconds or milliseconds)
63
+ * - Always converts to target timezone
64
+ * - ISO input (e.g., "2025-01-09T00:00:00+05:30"):
65
+ * - Parses timezone offset correctly
66
+ * - Converts to target timezone (doesn't preserve original timezone)
67
+ * - Date object:
68
+ * - Converts to target timezone
69
+ *
70
+ * @param {string|number|Date} date - Epoch timestamp, ISO string with timezone, or Date object.
71
+ * @param {boolean} orgTZ - Whether to force conversion into organization timezone.
72
+ * @param {boolean} serverTZ - Whether to force conversion into server timezone.
73
+ * @param {string|null} customTZ - Custom timezone override (e.g., "Asia/Kolkata").
74
+ * @returns {string} Formatted date string with timezone abbreviation or '-'.
19
75
  */
20
- export const formatDateWithTimezone = (date, orgTZ = false, onlyAbbr = false) => {
21
- try{
76
+ export const formatDateWithTimezone = (date, orgTZ = false, serverTZ = false, customTZ = null) => {
77
+ try {
22
78
  if (!date) return "-";
23
79
 
24
- let momentDate;
25
- const orgTimezone = utilsLocalStorageApi.loadItem("orgTZ") || "Asia/Kolkata";
26
-
27
- // Epoch (number or numeric string)
28
- if (typeof date === "number" || (typeof date === "string" && /^\d+$/.test(date))) {
29
- const timestamp = typeof date === "string" ? parseInt(date, 10) : date;
30
- const timestampMs = timestamp < 1e12 ? timestamp * 1000 : timestamp;
31
- momentDate = moment.tz(timestampMs, orgTimezone);
32
- }
33
- // ISO string or Date object
34
- else {
35
- momentDate = moment(date);
36
- if(momentDate.isUTC() || orgTZ){
37
- momentDate = momentDate.tz(orgTimezone);
38
- }
39
- }
40
-
80
+ const momentDate = getTimezoneFormattedDate(date,orgTZ,serverTZ,customTZ);
41
81
  if (!momentDate.isValid()) return "-";
42
82
 
43
- // Get strict timezone abbreviation (no offsets like GMT+05:30)
44
- let tzAbbr;
45
- if (momentDate.isValid()) {
46
- const tz = momentDate.tz() || orgTimezone;
47
- tzAbbr = moment.tz.zone(tz)?.abbr(momentDate.valueOf()) || "UTC";
48
- } else {
49
- tzAbbr = "UTC"; // fallback
50
- }
51
-
52
- if(onlyAbbr){
53
- return tzAbbr;
54
- }
55
- else{
56
- return `${momentDate.format(DATE_FORMAT)} ${tzAbbr}`;
57
- }
58
- }
59
- catch(error){
83
+ const tzAbbr = momentDate.format("z"); // e.g., IST, PST
84
+ return `${momentDate.format(DATE_FORMAT)} ${tzAbbr}`;
85
+ } catch (error) {
60
86
  console.error(error);
61
87
  return "-";
62
88
  }
@@ -65,38 +91,54 @@ export const formatDateWithTimezone = (date, orgTZ = false, onlyAbbr = false) =>
65
91
  /**
66
92
  * Returns a tooltip string with the timezone and offset for a given date.
67
93
  *
68
- * - Epoch input:
69
- * - Always uses orgTZ
70
- * - ISO input:
71
- * - orgTZ=falsekeep ISO timezone info
72
- * - orgTZ=true convert to org timezone (orgTZ)
94
+ * Timezone Selection Priority:
95
+ * 1. customTZ (if provided) - overrides all others
96
+ * 2. serverTZ=true uses server timezone from localStorage
97
+ * 3. orgTZ=trueuses organization timezone from localStorage
98
+ * 4. Default uses organization timezone from localStorage
99
+ *
100
+ * Input Handling:
101
+ * - Epoch input (number or numeric string):
102
+ * - Treated as UTC timestamp (seconds or milliseconds)
103
+ * - Returns timezone info for that specific date/time
104
+ * - ISO input (e.g., "2025-01-09T00:00:00+05:30"):
105
+ * - Parses timezone offset correctly
106
+ * - Returns timezone info for that specific date/time
107
+ * - Formatted date string (e.g., "10 Oct 2025 4:00 PM IST"):
108
+ * - Parses formatted date with timezone abbreviation
109
+ * - Returns timezone info for that specific date/time
110
+ * - Date object:
111
+ * - Returns timezone info for that specific date/time
73
112
  *
74
- * @param {string|number|Date} date - ISO string, epoch (sec/ms), or Date object.
75
- * @param {boolean} orgTZ - Whether to force conversion into org timezone.
76
- * @returns {string} Tooltip string with timezone and offset.
113
+ * @param {string|number|Date} date - Epoch timestamp, ISO string with timezone, formatted date string, or Date object.
114
+ * @param {boolean} orgTZ - Whether to force conversion into organization timezone.
115
+ * @param {boolean} serverTZ - Whether to force conversion into server timezone.
116
+ * @param {string|null} customTZ - Custom timezone override (e.g., "Asia/Kolkata").
117
+ * @returns {string} Tooltip string with timezone abbreviation and UTC offset for the specific date.
77
118
  */
78
- export const getTimezoneTooltip = (date, orgTZ = false) => {
79
- const orgTimezone = utilsLocalStorageApi.loadItem("orgTZ") || "Asia/Kolkata";
80
- const serverTimezone = utilsLocalStorageApi.loadItem("serverTZ") || "Asia/Kolkata";
119
+ export const getTimezoneTooltip = (date, orgTZ = false, serverTZ = false, customTZ = null) => {
120
+ try {
121
+ if (!date) return "-";
81
122
 
82
- if(orgTZ){
83
- return `${orgTimezone} (UTC${moment.tz(orgTimezone).format("Z")})`;
84
- }
85
- else{
86
- // case 1: epoch number or numeric string
87
- if(typeof date === "number" || (typeof date === "string" && /^\d+$/.test(date))){
88
- return `${orgTimezone} (UTC${moment.tz(orgTimezone).format("Z")})`;
89
- }
90
- // case 2: ISO string or Date object
91
- else{
92
- let m = moment.parseZone(date); // handles ISO strings like 2025-08-12T23:59:59.000Z or 2025-08-12T23:59:59+05:30
93
- if(!m.isValid()){
94
- m = moment.tz(date, "DD MMM YYYY h:mm A z"); // handles strings like 17 Sep 2025 6:00 AM EDT
95
- }
96
- if(!m.isValid() || m.isUTC()){
97
- return `${orgTimezone} (UTC${moment.tz(orgTimezone).format("Z")})`; // fallback to orgTZ
98
- }
99
- return `${serverTimezone} (UTC${m.format("Z")})`; // return the timezone and offset
100
- }
123
+ const orgTimezone = utilsLocalStorageApi.loadItem("orgTZ") || "Asia/Kolkata";
124
+ const serverTimezone = utilsLocalStorageApi.loadItem("serverTZ") || "Asia/Kolkata";
125
+ const targetTimezone = customTZ || (serverTZ ? serverTimezone : orgTZ ? orgTimezone : orgTimezone);
126
+ const momentDate = getTimezoneFormattedDate(date,orgTZ,serverTZ,customTZ);
127
+ if (!momentDate.isValid()) return "-";
128
+
129
+ const tzAbbr = momentDate.format("z"); // e.g., IST, PST, EDT
130
+ const utcOffset = momentDate.format("Z"); // e.g., +05:30, -04:00
131
+ return `${targetTimezone} (${tzAbbr},UTC${utcOffset})`;
132
+ } catch (error) {
133
+ console.error(error);
134
+ return "-";
101
135
  }
102
136
  };
137
+
138
+ /**
139
+ * checks if Timezone feature is enabled
140
+ * @returns {boolean}
141
+ */
142
+ export const hasTimezoneFeatureAccess = () => {
143
+ return hasFeatureAccess(TIMEZONE_ENABLED);
144
+ };