@oneuptime/common 9.3.22 → 9.4.1

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.
Files changed (130) hide show
  1. package/Models/DatabaseModels/IncomingCallLog.ts +521 -0
  2. package/Models/DatabaseModels/IncomingCallLogItem.ts +463 -0
  3. package/Models/DatabaseModels/IncomingCallPolicy.ts +811 -0
  4. package/Models/DatabaseModels/IncomingCallPolicyEscalationRule.ts +597 -0
  5. package/Models/DatabaseModels/Index.ts +18 -0
  6. package/Models/DatabaseModels/ProjectSCIMLog.ts +422 -0
  7. package/Models/DatabaseModels/StatusPageDomain.ts +2 -0
  8. package/Models/DatabaseModels/StatusPageSCIMLog.ts +455 -0
  9. package/Models/DatabaseModels/User.ts +0 -15
  10. package/Models/DatabaseModels/UserIncomingCallNumber.ts +296 -0
  11. package/Server/API/UserIncomingCallNumberAPI.ts +128 -0
  12. package/Server/Infrastructure/Postgres/SchemaMigrations/1768583966447-MigrationName.ts +121 -0
  13. package/Server/Infrastructure/Postgres/SchemaMigrations/1768825402472-MigrationName.ts +317 -0
  14. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
  15. package/Server/Services/DatabaseService.ts +23 -1
  16. package/Server/Services/DomainService.ts +26 -15
  17. package/Server/Services/IncomingCallLogItemService.ts +10 -0
  18. package/Server/Services/IncomingCallLogService.ts +10 -0
  19. package/Server/Services/IncomingCallPolicyEscalationRuleService.ts +267 -0
  20. package/Server/Services/IncomingCallPolicyService.ts +10 -0
  21. package/Server/Services/Index.ts +7 -0
  22. package/Server/Services/MonitorProbeService.ts +96 -1
  23. package/Server/Services/ProjectSCIMLogService.ts +11 -0
  24. package/Server/Services/StatusPageSCIMLogService.ts +11 -0
  25. package/Server/Services/UserCallService.ts +31 -0
  26. package/Server/Services/UserIncomingCallNumberService.ts +258 -0
  27. package/Server/Services/UserSmsService.ts +31 -0
  28. package/Server/Utils/StartServer.ts +5 -0
  29. package/Types/Call/CallProvider.ts +99 -0
  30. package/Types/Call/CallProviderType.ts +6 -0
  31. package/Types/Domain.ts +23 -0
  32. package/Types/Icon/IconProp.ts +1 -0
  33. package/Types/IncomingCall/IncomingCallStatus.ts +13 -0
  34. package/Types/Permission.ts +126 -0
  35. package/Types/Phone.ts +53 -4
  36. package/Types/SCIM/SCIMLogStatus.ts +7 -0
  37. package/UI/Components/Diagram/ConceptCards.tsx +74 -0
  38. package/UI/Components/Diagram/HorizontalStepChain.tsx +92 -0
  39. package/UI/Components/Diagram/Index.ts +11 -0
  40. package/UI/Components/Diagram/NumberedSteps.tsx +77 -0
  41. package/UI/Components/Diagram/VerticalFlowSteps.tsx +59 -0
  42. package/UI/Components/Icon/Icon.tsx +10 -0
  43. package/UI/Components/SimpleLogViewer/SimpleLogViewer.tsx +86 -2
  44. package/build/dist/Models/DatabaseModels/IncomingCallLog.js +565 -0
  45. package/build/dist/Models/DatabaseModels/IncomingCallLog.js.map +1 -0
  46. package/build/dist/Models/DatabaseModels/IncomingCallLogItem.js +497 -0
  47. package/build/dist/Models/DatabaseModels/IncomingCallLogItem.js.map +1 -0
  48. package/build/dist/Models/DatabaseModels/IncomingCallPolicy.js +840 -0
  49. package/build/dist/Models/DatabaseModels/IncomingCallPolicy.js.map +1 -0
  50. package/build/dist/Models/DatabaseModels/IncomingCallPolicyEscalationRule.js +619 -0
  51. package/build/dist/Models/DatabaseModels/IncomingCallPolicyEscalationRule.js.map +1 -0
  52. package/build/dist/Models/DatabaseModels/Index.js +16 -0
  53. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  54. package/build/dist/Models/DatabaseModels/ProjectSCIMLog.js +455 -0
  55. package/build/dist/Models/DatabaseModels/ProjectSCIMLog.js.map +1 -0
  56. package/build/dist/Models/DatabaseModels/StatusPageDomain.js +2 -0
  57. package/build/dist/Models/DatabaseModels/StatusPageDomain.js.map +1 -1
  58. package/build/dist/Models/DatabaseModels/StatusPageSCIMLog.js +486 -0
  59. package/build/dist/Models/DatabaseModels/StatusPageSCIMLog.js.map +1 -0
  60. package/build/dist/Models/DatabaseModels/User.js +0 -16
  61. package/build/dist/Models/DatabaseModels/User.js.map +1 -1
  62. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js +315 -0
  63. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js.map +1 -0
  64. package/build/dist/Server/API/UserIncomingCallNumberAPI.js +72 -0
  65. package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -0
  66. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1768583966447-MigrationName.js +48 -0
  67. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1768583966447-MigrationName.js.map +1 -0
  68. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1768825402472-MigrationName.js +116 -0
  69. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1768825402472-MigrationName.js.map +1 -0
  70. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  71. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  72. package/build/dist/Server/Services/DatabaseService.js +12 -0
  73. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  74. package/build/dist/Server/Services/DomainService.js +19 -8
  75. package/build/dist/Server/Services/DomainService.js.map +1 -1
  76. package/build/dist/Server/Services/IncomingCallLogItemService.js +9 -0
  77. package/build/dist/Server/Services/IncomingCallLogItemService.js.map +1 -0
  78. package/build/dist/Server/Services/IncomingCallLogService.js +9 -0
  79. package/build/dist/Server/Services/IncomingCallLogService.js.map +1 -0
  80. package/build/dist/Server/Services/IncomingCallPolicyEscalationRuleService.js +197 -0
  81. package/build/dist/Server/Services/IncomingCallPolicyEscalationRuleService.js.map +1 -0
  82. package/build/dist/Server/Services/IncomingCallPolicyService.js +9 -0
  83. package/build/dist/Server/Services/IncomingCallPolicyService.js.map +1 -0
  84. package/build/dist/Server/Services/Index.js +6 -0
  85. package/build/dist/Server/Services/Index.js.map +1 -1
  86. package/build/dist/Server/Services/MonitorProbeService.js +77 -0
  87. package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
  88. package/build/dist/Server/Services/ProjectSCIMLogService.js +10 -0
  89. package/build/dist/Server/Services/ProjectSCIMLogService.js.map +1 -0
  90. package/build/dist/Server/Services/StatusPageSCIMLogService.js +10 -0
  91. package/build/dist/Server/Services/StatusPageSCIMLogService.js.map +1 -0
  92. package/build/dist/Server/Services/UserCallService.js +21 -0
  93. package/build/dist/Server/Services/UserCallService.js.map +1 -1
  94. package/build/dist/Server/Services/UserIncomingCallNumberService.js +225 -0
  95. package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -0
  96. package/build/dist/Server/Services/UserSmsService.js +21 -0
  97. package/build/dist/Server/Services/UserSmsService.js.map +1 -1
  98. package/build/dist/Server/Utils/StartServer.js +5 -0
  99. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  100. package/build/dist/Types/Call/CallProvider.js +2 -0
  101. package/build/dist/Types/Call/CallProvider.js.map +1 -0
  102. package/build/dist/Types/Call/CallProviderType.js +7 -0
  103. package/build/dist/Types/Call/CallProviderType.js.map +1 -0
  104. package/build/dist/Types/Domain.js +23 -1
  105. package/build/dist/Types/Domain.js.map +1 -1
  106. package/build/dist/Types/Icon/IconProp.js +1 -0
  107. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  108. package/build/dist/Types/IncomingCall/IncomingCallStatus.js +14 -0
  109. package/build/dist/Types/IncomingCall/IncomingCallStatus.js.map +1 -0
  110. package/build/dist/Types/Permission.js +104 -0
  111. package/build/dist/Types/Permission.js.map +1 -1
  112. package/build/dist/Types/Phone.js +47 -3
  113. package/build/dist/Types/Phone.js.map +1 -1
  114. package/build/dist/Types/SCIM/SCIMLogStatus.js +8 -0
  115. package/build/dist/Types/SCIM/SCIMLogStatus.js.map +1 -0
  116. package/build/dist/UI/Components/Diagram/ConceptCards.js +30 -0
  117. package/build/dist/UI/Components/Diagram/ConceptCards.js.map +1 -0
  118. package/build/dist/UI/Components/Diagram/HorizontalStepChain.js +30 -0
  119. package/build/dist/UI/Components/Diagram/HorizontalStepChain.js.map +1 -0
  120. package/build/dist/UI/Components/Diagram/Index.js +5 -0
  121. package/build/dist/UI/Components/Diagram/Index.js.map +1 -0
  122. package/build/dist/UI/Components/Diagram/NumberedSteps.js +18 -0
  123. package/build/dist/UI/Components/Diagram/NumberedSteps.js.map +1 -0
  124. package/build/dist/UI/Components/Diagram/VerticalFlowSteps.js +16 -0
  125. package/build/dist/UI/Components/Diagram/VerticalFlowSteps.js.map +1 -0
  126. package/build/dist/UI/Components/Icon/Icon.js +4 -0
  127. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  128. package/build/dist/UI/Components/SimpleLogViewer/SimpleLogViewer.js +30 -1
  129. package/build/dist/UI/Components/SimpleLogViewer/SimpleLogViewer.js.map +1 -1
  130. package/package.json +1 -1
package/Types/Phone.ts CHANGED
@@ -13,7 +13,7 @@ export default class Phone extends DatabaseProperty {
13
13
  public static pickPhoneNumberToSendSMSOrCallFrom(data: {
14
14
  to: Phone | string;
15
15
  primaryPhoneNumberToPickFrom: Phone | string;
16
- seocndaryPhoneNumbersToPickFrom: Phone[] | string[];
16
+ secondaryPhoneNumbersToPickFrom: Phone[] | string[];
17
17
  }): Phone {
18
18
  /*
19
19
  * convert all to string, so that we can compare them
@@ -28,8 +28,8 @@ export default class Phone extends DatabaseProperty {
28
28
  ? data.primaryPhoneNumberToPickFrom
29
29
  : data.primaryPhoneNumberToPickFrom.toString();
30
30
 
31
- const seocndaryPhoneNumbersToPickFrom: string[] =
32
- data.seocndaryPhoneNumbersToPickFrom.map((phone: Phone | string) => {
31
+ const secondaryPhoneNumbersToPickFrom: string[] =
32
+ data.secondaryPhoneNumbersToPickFrom.map((phone: Phone | string) => {
33
33
  return typeof phone === "string" ? phone : phone.toString();
34
34
  });
35
35
 
@@ -51,7 +51,7 @@ export default class Phone extends DatabaseProperty {
51
51
  return new Phone(primaryPhoneNumberToPickFrom);
52
52
  }
53
53
 
54
- for (const secondaryPhoneNumber of seocndaryPhoneNumbersToPickFrom) {
54
+ for (const secondaryPhoneNumber of secondaryPhoneNumbersToPickFrom) {
55
55
  const secondaryPhoneNumberCountryCode: string = normalizePhoneNumber(
56
56
  secondaryPhoneNumber,
57
57
  ).substring(0, 2);
@@ -148,4 +148,53 @@ export default class Phone extends DatabaseProperty {
148
148
  example: { _type: ObjectType.Phone, value: "+1-555-123-4567" },
149
149
  });
150
150
  }
151
+
152
+ // Map of calling code prefixes to ISO country codes
153
+ private static readonly CALLING_CODE_TO_COUNTRY_MAP: Record<string, string> =
154
+ {
155
+ "+1": "US", // US and Canada
156
+ "+44": "GB", // United Kingdom
157
+ "+61": "AU", // Australia
158
+ "+49": "DE", // Germany
159
+ "+33": "FR", // France
160
+ "+91": "IN", // India
161
+ "+81": "JP", // Japan
162
+ "+86": "CN", // China
163
+ "+55": "BR", // Brazil
164
+ "+52": "MX", // Mexico
165
+ };
166
+
167
+ /**
168
+ * Extract ISO country code from a phone number
169
+ * @param phoneNumber - The phone number (e.g., "+15551234567")
170
+ * @returns ISO country code (e.g., "US") or "US" as default
171
+ */
172
+ public static getCountryCodeFromPhoneNumber(phoneNumber: string): string {
173
+ for (const [prefix, countryCode] of Object.entries(
174
+ Phone.CALLING_CODE_TO_COUNTRY_MAP,
175
+ )) {
176
+ if (phoneNumber.startsWith(prefix)) {
177
+ return countryCode;
178
+ }
179
+ }
180
+ return "US"; // Default to US if unknown
181
+ }
182
+
183
+ /**
184
+ * Extract area code from a phone number
185
+ * Currently only supports US/Canada (+1) numbers
186
+ * @param phoneNumber - The phone number (e.g., "+15551234567")
187
+ * @returns Area code (e.g., "555") or empty string for non-US/CA numbers
188
+ */
189
+ public static getAreaCodeFromPhoneNumber(phoneNumber: string): string {
190
+ // For US/Canada numbers (+1), extract the next 3 digits
191
+ if (phoneNumber.startsWith("+1")) {
192
+ const number: string = phoneNumber.substring(2);
193
+ if (number.length >= 3) {
194
+ return number.substring(0, 3);
195
+ }
196
+ }
197
+ // For other countries, area code extraction is more complex
198
+ return "";
199
+ }
151
200
  }
@@ -0,0 +1,7 @@
1
+ enum SCIMLogStatus {
2
+ Success = "Success",
3
+ Error = "Error",
4
+ Warning = "Warning",
5
+ }
6
+
7
+ export default SCIMLogStatus;
@@ -0,0 +1,74 @@
1
+ import React, { FunctionComponent, ReactElement } from "react";
2
+ import Icon from "../Icon/Icon";
3
+ import IconProp from "../../../Types/Icon/IconProp";
4
+ import Color from "../../../Types/Color";
5
+
6
+ export interface ConceptCard {
7
+ title: string;
8
+ description: string;
9
+ icon: IconProp;
10
+ iconColor: Color;
11
+ }
12
+
13
+ export interface ComponentProps {
14
+ cards: ConceptCard[];
15
+ /** Number of columns in the grid (1-4). Default is 2. */
16
+ columns?: 1 | 2 | 3 | 4 | undefined;
17
+ }
18
+
19
+ const ConceptCards: FunctionComponent<ComponentProps> = (
20
+ props: ComponentProps,
21
+ ): ReactElement => {
22
+ const columns: number = props.columns || 2;
23
+
24
+ const getGridClasses: () => string = (): string => {
25
+ switch (columns) {
26
+ case 1:
27
+ return "grid-cols-1";
28
+ case 2:
29
+ return "grid-cols-1 md:grid-cols-2";
30
+ case 3:
31
+ return "grid-cols-1 md:grid-cols-2 lg:grid-cols-3";
32
+ case 4:
33
+ return "grid-cols-1 md:grid-cols-2 lg:grid-cols-4";
34
+ default:
35
+ return "grid-cols-1 md:grid-cols-2";
36
+ }
37
+ };
38
+
39
+ return (
40
+ <div className={`grid ${getGridClasses()} gap-3`}>
41
+ {props.cards.map((card: ConceptCard, index: number) => {
42
+ return (
43
+ <div
44
+ key={index}
45
+ className="border border-gray-200 rounded-md p-3 bg-white hover:border-gray-300 transition-colors"
46
+ >
47
+ <div className="flex items-start space-x-3">
48
+ <div
49
+ className="flex-shrink-0 w-8 h-8 rounded flex items-center justify-center"
50
+ style={{ backgroundColor: `${card.iconColor.toString()}15` }}
51
+ >
52
+ <Icon
53
+ icon={card.icon}
54
+ className="h-4 w-4"
55
+ style={{ color: card.iconColor.toString() }}
56
+ />
57
+ </div>
58
+ <div className="flex-1 min-w-0">
59
+ <h4 className="text-sm font-medium text-gray-900">
60
+ {card.title}
61
+ </h4>
62
+ <p className="text-sm text-gray-500 mt-1 leading-relaxed">
63
+ {card.description}
64
+ </p>
65
+ </div>
66
+ </div>
67
+ </div>
68
+ );
69
+ })}
70
+ </div>
71
+ );
72
+ };
73
+
74
+ export default ConceptCards;
@@ -0,0 +1,92 @@
1
+ import React, { FunctionComponent, ReactElement } from "react";
2
+ import Icon from "../Icon/Icon";
3
+ import IconProp from "../../../Types/Icon/IconProp";
4
+ import Color from "../../../Types/Color";
5
+
6
+ export interface ChainStep {
7
+ stepNumber: number;
8
+ title: string;
9
+ description: string;
10
+ color: Color;
11
+ /** Optional label shown below the step number. Default is "Step" */
12
+ stepLabel?: string | undefined;
13
+ }
14
+
15
+ export interface ChainEndStep {
16
+ title: string;
17
+ description: string;
18
+ icon: IconProp;
19
+ color: Color;
20
+ }
21
+
22
+ export interface ComponentProps {
23
+ steps: ChainStep[];
24
+ endStep?: ChainEndStep | undefined;
25
+ /** Default label for steps. Default is "Step" */
26
+ defaultStepLabel?: string | undefined;
27
+ }
28
+
29
+ const HorizontalStepChain: FunctionComponent<ComponentProps> = (
30
+ props: ComponentProps,
31
+ ): ReactElement => {
32
+ const defaultLabel: string = props.defaultStepLabel || "Step";
33
+
34
+ return (
35
+ <div className="flex items-center flex-wrap gap-3">
36
+ {props.steps.map((step: ChainStep, index: number) => {
37
+ return (
38
+ <React.Fragment key={index}>
39
+ {/* Step */}
40
+ <div className="flex items-center space-x-3">
41
+ <div
42
+ className="w-10 h-10 rounded-full flex items-center justify-center text-white text-sm font-medium"
43
+ style={{ backgroundColor: step.color.toString() }}
44
+ >
45
+ {step.stepNumber}
46
+ </div>
47
+ <div>
48
+ <p className="text-sm font-medium text-gray-900">
49
+ {step.title}
50
+ </p>
51
+ <p className="text-xs text-gray-500">
52
+ {step.stepLabel || defaultLabel} {step.stepNumber} ·{" "}
53
+ {step.description}
54
+ </p>
55
+ </div>
56
+ </div>
57
+
58
+ {/* Arrow */}
59
+ <Icon
60
+ icon={IconProp.ChevronRight}
61
+ className="h-4 w-4 text-gray-300 hidden sm:block"
62
+ />
63
+ </React.Fragment>
64
+ );
65
+ })}
66
+
67
+ {/* End Step */}
68
+ {props.endStep && (
69
+ <div className="flex items-center space-x-3">
70
+ <div
71
+ className="w-10 h-10 rounded-full flex items-center justify-center"
72
+ style={{ backgroundColor: `${props.endStep.color.toString()}15` }}
73
+ >
74
+ <Icon
75
+ icon={props.endStep.icon}
76
+ className="h-4 w-4"
77
+ style={{ color: props.endStep.color.toString() }}
78
+ />
79
+ </div>
80
+ <div>
81
+ <p className="text-sm font-medium text-gray-900">
82
+ {props.endStep.title}
83
+ </p>
84
+ <p className="text-xs text-gray-500">{props.endStep.description}</p>
85
+ </div>
86
+ </div>
87
+ )}
88
+ </div>
89
+ );
90
+ };
91
+
92
+ export default HorizontalStepChain;
@@ -0,0 +1,11 @@
1
+ export { default as VerticalFlowSteps } from "./VerticalFlowSteps";
2
+ export type { FlowStep } from "./VerticalFlowSteps";
3
+
4
+ export { default as HorizontalStepChain } from "./HorizontalStepChain";
5
+ export type { ChainStep, ChainEndStep } from "./HorizontalStepChain";
6
+
7
+ export { default as NumberedSteps } from "./NumberedSteps";
8
+ export type { NumberedStep } from "./NumberedSteps";
9
+
10
+ export { default as ConceptCards } from "./ConceptCards";
11
+ export type { ConceptCard } from "./ConceptCards";
@@ -0,0 +1,77 @@
1
+ import React, { FunctionComponent, ReactElement } from "react";
2
+ import Icon from "../Icon/Icon";
3
+ import IconProp from "../../../Types/Icon/IconProp";
4
+ import Color from "../../../Types/Color";
5
+
6
+ export interface NumberedStep {
7
+ title: string;
8
+ description: string;
9
+ /** If provided, shows an icon instead of number */
10
+ icon?: IconProp | undefined;
11
+ /** Color for the step indicator */
12
+ color?: Color | undefined;
13
+ }
14
+
15
+ export interface ComponentProps {
16
+ steps: NumberedStep[];
17
+ /** Default color for steps */
18
+ defaultColor?: Color | undefined;
19
+ }
20
+
21
+ const NumberedSteps: FunctionComponent<ComponentProps> = (
22
+ props: ComponentProps,
23
+ ): ReactElement => {
24
+ const defaultColor: Color = props.defaultColor || new Color("#6b7280"); // gray-500
25
+
26
+ return (
27
+ <div className="relative">
28
+ {props.steps.map((step: NumberedStep, index: number) => {
29
+ const color: Color = step.color || defaultColor;
30
+ const isLast: boolean = index === props.steps.length - 1;
31
+
32
+ return (
33
+ <div key={index} className="relative flex items-start pb-5 last:pb-0">
34
+ {/* Vertical line connecting steps */}
35
+ {!isLast && (
36
+ <div
37
+ className="absolute left-4 top-10 w-px bg-gray-200"
38
+ style={{ height: "calc(100% - 1.5rem)" }}
39
+ />
40
+ )}
41
+
42
+ {/* Number/Icon indicator */}
43
+ <div
44
+ className="relative flex-shrink-0 w-8 h-8 rounded-full flex items-center justify-center border-2 bg-white"
45
+ style={{ borderColor: color.toString() }}
46
+ >
47
+ {step.icon ? (
48
+ <Icon
49
+ icon={step.icon}
50
+ className="h-4 w-4"
51
+ style={{ color: color.toString() }}
52
+ />
53
+ ) : (
54
+ <span
55
+ className="text-sm font-medium"
56
+ style={{ color: color.toString() }}
57
+ >
58
+ {index + 1}
59
+ </span>
60
+ )}
61
+ </div>
62
+
63
+ {/* Content */}
64
+ <div className="ml-4 flex-1 pt-0.5">
65
+ <h4 className="text-sm font-medium text-gray-900">
66
+ {step.title}
67
+ </h4>
68
+ <p className="text-sm text-gray-500 mt-0.5">{step.description}</p>
69
+ </div>
70
+ </div>
71
+ );
72
+ })}
73
+ </div>
74
+ );
75
+ };
76
+
77
+ export default NumberedSteps;
@@ -0,0 +1,59 @@
1
+ import React, { FunctionComponent, ReactElement } from "react";
2
+ import Icon from "../Icon/Icon";
3
+ import IconProp from "../../../Types/Icon/IconProp";
4
+ import Color from "../../../Types/Color";
5
+
6
+ export interface FlowStep {
7
+ title: string;
8
+ description: string;
9
+ icon: IconProp;
10
+ iconColor: Color;
11
+ }
12
+
13
+ export interface ComponentProps {
14
+ steps: FlowStep[];
15
+ }
16
+
17
+ const VerticalFlowSteps: FunctionComponent<ComponentProps> = (
18
+ props: ComponentProps,
19
+ ): ReactElement => {
20
+ return (
21
+ <div className="relative">
22
+ {props.steps.map((step: FlowStep, index: number) => {
23
+ const isLast: boolean = index === props.steps.length - 1;
24
+
25
+ return (
26
+ <div key={index} className="relative flex items-start pb-6 last:pb-0">
27
+ {/* Vertical line connecting steps */}
28
+ {!isLast && (
29
+ <div
30
+ className="absolute left-4 top-10 w-px bg-gray-200"
31
+ style={{ height: "calc(100% - 1rem)" }}
32
+ />
33
+ )}
34
+
35
+ {/* Icon */}
36
+ <div
37
+ className="relative flex-shrink-0 w-8 h-8 rounded-full flex items-center justify-center border border-gray-200 bg-white"
38
+ style={{ borderColor: `${step.iconColor.toString()}40` }}
39
+ >
40
+ <Icon
41
+ icon={step.icon}
42
+ className="h-4 w-4"
43
+ style={{ color: step.iconColor.toString() }}
44
+ />
45
+ </div>
46
+
47
+ {/* Content */}
48
+ <div className="ml-4 flex-1">
49
+ <p className="text-sm font-medium text-gray-900">{step.title}</p>
50
+ <p className="text-sm text-gray-500 mt-0.5">{step.description}</p>
51
+ </div>
52
+ </div>
53
+ );
54
+ })}
55
+ </div>
56
+ );
57
+ };
58
+
59
+ export default VerticalFlowSteps;
@@ -978,6 +978,16 @@ const Icon: FunctionComponent<ComponentProps> = ({
978
978
  d="M2.25 6.75c0 8.284 6.716 15 15 15h2.25a2.25 2.25 0 002.25-2.25v-1.372c0-.516-.351-.966-.852-1.091l-4.423-1.106c-.44-.11-.902.055-1.173.417l-.97 1.293c-.282.376-.769.542-1.21.38a12.035 12.035 0 01-7.143-7.143c-.162-.441.004-.928.38-1.21l1.293-.97c.363-.271.527-.734.417-1.173L6.963 3.102a1.125 1.125 0 00-1.091-.852H4.5A2.25 2.25 0 002.25 4.5v2.25z"
979
979
  />,
980
980
  );
981
+ } else if (icon === IconProp.IncomingCall) {
982
+ return getSvgWrapper(
983
+ <>
984
+ <path
985
+ strokeLinecap="round"
986
+ strokeLinejoin="round"
987
+ d="M14.25 9.75v-4.5m0 4.5h4.5m-4.5 0l6-6m-3 18c-8.284 0-15-6.716-15-15V4.5A2.25 2.25 0 014.5 2.25h1.372c.516 0 .966.351 1.091.852l1.106 4.423c.11.44-.054.902-.417 1.173l-1.293.97a1.062 1.062 0 00-.38 1.21 12.035 12.035 0 007.143 7.143c.441.162.928-.004 1.21-.38l.97-1.293a1.125 1.125 0 011.173-.417l4.423 1.106c.5.125.852.575.852 1.091V19.5a2.25 2.25 0 01-2.25 2.25h-2.25z"
988
+ />
989
+ </>,
990
+ );
981
991
  } else if (icon === IconProp.More) {
982
992
  return getSvgWrapper(
983
993
  <path
@@ -2,14 +2,98 @@ import React, { FunctionComponent, ReactElement } from "react";
2
2
 
3
3
  export interface ComponentProps {
4
4
  children: ReactElement | string | Array<ReactElement>;
5
+ showLineNumbers?: boolean | undefined;
6
+ height?: string | undefined;
7
+ title?: string | undefined;
5
8
  }
6
9
 
7
10
  const SimpleLogViewer: FunctionComponent<ComponentProps> = (
8
11
  props: ComponentProps,
9
12
  ): ReactElement => {
13
+ const showLineNumbers: boolean = props.showLineNumbers !== false;
14
+ const height: string = props.height || "400px";
15
+ const title: string | undefined = props.title;
16
+
17
+ const renderContent: () => ReactElement = (): ReactElement => {
18
+ if (typeof props.children === "string") {
19
+ const lines: Array<string> = props.children.split("\n");
20
+ return (
21
+ <>
22
+ {lines.map((line: string, index: number) => {
23
+ return (
24
+ <div
25
+ key={index}
26
+ className="flex hover:bg-slate-800/50 transition-colors"
27
+ >
28
+ {showLineNumbers && (
29
+ <span className="select-none text-slate-600 text-right pr-4 w-12 flex-shrink-0 border-r border-slate-800 mr-4">
30
+ {index + 1}
31
+ </span>
32
+ )}
33
+ <span className="text-slate-300 whitespace-pre-wrap break-all flex-1">
34
+ {line || " "}
35
+ </span>
36
+ </div>
37
+ );
38
+ })}
39
+ </>
40
+ );
41
+ }
42
+
43
+ if (Array.isArray(props.children)) {
44
+ return (
45
+ <>
46
+ {props.children.map(
47
+ (child: ReactElement, index: number): ReactElement => {
48
+ return (
49
+ <div
50
+ key={index}
51
+ className="flex hover:bg-slate-800/50 transition-colors"
52
+ >
53
+ {showLineNumbers && (
54
+ <span className="select-none text-slate-600 text-right pr-4 w-12 flex-shrink-0 border-r border-slate-800 mr-4">
55
+ {index + 1}
56
+ </span>
57
+ )}
58
+ <span className="text-slate-300 whitespace-pre-wrap break-all flex-1">
59
+ {child}
60
+ </span>
61
+ </div>
62
+ );
63
+ },
64
+ )}
65
+ </>
66
+ );
67
+ }
68
+
69
+ return (
70
+ <div className="text-slate-300 whitespace-pre-wrap break-all">
71
+ {props.children}
72
+ </div>
73
+ );
74
+ };
75
+
76
+ const scrollbarStyles: React.CSSProperties = {
77
+ maxHeight: height,
78
+ scrollbarWidth: "thin",
79
+ scrollbarColor: "#475569 #1e293b",
80
+ };
81
+
10
82
  return (
11
- <div className="text-gray-500 mt-5 text-sm h-96 overflow-y-auto overflow-x-hidden p-5 border-gray-50 border border-2 bg-gray-100 rounded">
12
- {props.children}
83
+ <div className="rounded-lg overflow-hidden border border-slate-700 bg-slate-900 shadow-lg">
84
+ {/* Title Header */}
85
+ {title && (
86
+ <div className="px-4 py-3 border-b border-slate-700 bg-slate-800">
87
+ <h3 className="text-sm font-medium text-slate-200">{title}</h3>
88
+ </div>
89
+ )}
90
+ {/* Log Content */}
91
+ <div
92
+ className="overflow-auto font-mono text-sm leading-6 p-4 [&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-track]:bg-slate-800 [&::-webkit-scrollbar-thumb]:bg-slate-600 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:hover:bg-slate-500"
93
+ style={scrollbarStyles}
94
+ >
95
+ {renderContent()}
96
+ </div>
13
97
  </div>
14
98
  );
15
99
  };