@sudobility/devops-components-rn 1.0.0 → 1.0.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 (63) hide show
  1. package/dist/AlertDialog.d.ts.map +1 -1
  2. package/dist/ApiPlayground.d.ts.map +1 -1
  3. package/dist/ApiReference.d.ts.map +1 -1
  4. package/dist/AuditLog.d.ts +26 -4
  5. package/dist/AuditLog.d.ts.map +1 -1
  6. package/dist/BodyMetrics.d.ts.map +1 -1
  7. package/dist/BuildLog.d.ts +16 -5
  8. package/dist/BuildLog.d.ts.map +1 -1
  9. package/dist/ChangelogDisplay.d.ts.map +1 -1
  10. package/dist/CodePlayground.d.ts.map +1 -1
  11. package/dist/ConflictResolver.d.ts.map +1 -1
  12. package/dist/DealPipeline.d.ts.map +1 -1
  13. package/dist/DeploymentStatus.d.ts +11 -4
  14. package/dist/DeploymentStatus.d.ts.map +1 -1
  15. package/dist/DriverLog.d.ts.map +1 -1
  16. package/dist/MemoryUsage.d.ts.map +1 -1
  17. package/dist/MetricsGrid.d.ts +12 -19
  18. package/dist/MetricsGrid.d.ts.map +1 -1
  19. package/dist/PipelineView.d.ts +21 -5
  20. package/dist/PipelineView.d.ts.map +1 -1
  21. package/dist/RegressionTest.d.ts.map +1 -1
  22. package/dist/SystemStatusIndicator.d.ts +9 -8
  23. package/dist/SystemStatusIndicator.d.ts.map +1 -1
  24. package/dist/TestResult.d.ts.map +1 -1
  25. package/dist/TestRunner.d.ts.map +1 -1
  26. package/dist/WebhookLogger.d.ts.map +1 -1
  27. package/dist/WorkflowBuilder.d.ts.map +1 -1
  28. package/dist/WorkflowTemplate.d.ts.map +1 -1
  29. package/dist/XmlParser.d.ts.map +1 -1
  30. package/dist/{index.cjs.js → index.cjs} +634 -614
  31. package/dist/index.cjs.map +1 -0
  32. package/dist/index.d.ts +6 -27
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/{index.esm.js → index.mjs} +637 -617
  35. package/dist/index.mjs.map +1 -0
  36. package/package.json +8 -15
  37. package/src/AlertDialog.tsx +21 -16
  38. package/src/ApiPlayground.tsx +7 -3
  39. package/src/ApiReference.tsx +6 -2
  40. package/src/AuditLog.tsx +244 -21
  41. package/src/BodyMetrics.tsx +6 -2
  42. package/src/BuildLog.tsx +132 -26
  43. package/src/ChangelogDisplay.tsx +6 -2
  44. package/src/CodePlayground.tsx +7 -3
  45. package/src/ConflictResolver.tsx +7 -3
  46. package/src/DealPipeline.tsx +6 -2
  47. package/src/DeploymentStatus.tsx +159 -25
  48. package/src/DriverLog.tsx +4 -2
  49. package/src/MemoryUsage.tsx +6 -2
  50. package/src/MetricsGrid.tsx +99 -94
  51. package/src/PipelineView.tsx +225 -26
  52. package/src/RegressionTest.tsx +6 -2
  53. package/src/SystemStatusIndicator.tsx +70 -47
  54. package/src/TestResult.tsx +6 -2
  55. package/src/TestRunner.tsx +7 -3
  56. package/src/WebhookLogger.tsx +6 -2
  57. package/src/WorkflowBuilder.tsx +7 -3
  58. package/src/WorkflowTemplate.tsx +7 -3
  59. package/src/XmlParser.tsx +4 -2
  60. package/src/index.ts +41 -30
  61. package/src/nativewind.d.ts +3 -0
  62. package/dist/index.cjs.js.map +0 -1
  63. package/dist/index.esm.js.map +0 -1
package/src/AuditLog.tsx CHANGED
@@ -1,27 +1,250 @@
1
1
  import React from 'react';
2
- import { View, Text, type ViewProps } from 'react-native';
3
- import { cn } from '@sudobility/components-rn';
2
+ import { View, Text, ScrollView, Pressable } from 'react-native';
3
+ import { cn, Card } from '@sudobility/components-rn';
4
4
 
5
- export interface AuditLogProps extends ViewProps {
6
- disabled?: boolean;
7
- children?: React.ReactNode;
5
+ export type AuditActionType =
6
+ | 'create'
7
+ | 'update'
8
+ | 'delete'
9
+ | 'login'
10
+ | 'logout'
11
+ | 'access'
12
+ | 'export'
13
+ | 'import'
14
+ | 'approve'
15
+ | 'reject'
16
+ | 'deploy'
17
+ | 'rollback';
18
+
19
+ export interface AuditEntry {
20
+ id: string;
21
+ action: AuditActionType;
22
+ actor: {
23
+ id: string;
24
+ name: string;
25
+ email?: string;
26
+ avatar?: string;
27
+ };
28
+ resource: {
29
+ type: string;
30
+ id: string;
31
+ name: string;
32
+ };
33
+ timestamp: Date;
34
+ metadata?: Record<string, unknown>;
35
+ ipAddress?: string;
36
+ }
37
+
38
+ export interface AuditLogProps {
39
+ entries: AuditEntry[];
40
+ title?: string;
41
+ maxHeight?: number;
42
+ onEntryPress?: (entry: AuditEntry) => void;
43
+ className?: string;
8
44
  }
9
45
 
46
+ const actionConfig: Record<
47
+ AuditActionType,
48
+ { color: string; bgColor: string; darkBgColor: string; icon: string }
49
+ > = {
50
+ create: {
51
+ color: 'text-green-700 dark:text-green-300',
52
+ bgColor: 'bg-green-100',
53
+ darkBgColor: 'dark:bg-green-900',
54
+ icon: '+',
55
+ },
56
+ update: {
57
+ color: 'text-blue-700 dark:text-blue-300',
58
+ bgColor: 'bg-blue-100',
59
+ darkBgColor: 'dark:bg-blue-900',
60
+ icon: '~',
61
+ },
62
+ delete: {
63
+ color: 'text-red-700 dark:text-red-300',
64
+ bgColor: 'bg-red-100',
65
+ darkBgColor: 'dark:bg-red-900',
66
+ icon: '-',
67
+ },
68
+ login: {
69
+ color: 'text-purple-700 dark:text-purple-300',
70
+ bgColor: 'bg-purple-100',
71
+ darkBgColor: 'dark:bg-purple-900',
72
+ icon: '→',
73
+ },
74
+ logout: {
75
+ color: 'text-gray-700 dark:text-gray-300',
76
+ bgColor: 'bg-gray-100',
77
+ darkBgColor: 'dark:bg-gray-800',
78
+ icon: '←',
79
+ },
80
+ access: {
81
+ color: 'text-cyan-700 dark:text-cyan-300',
82
+ bgColor: 'bg-cyan-100',
83
+ darkBgColor: 'dark:bg-cyan-900',
84
+ icon: '◉',
85
+ },
86
+ export: {
87
+ color: 'text-orange-700 dark:text-orange-300',
88
+ bgColor: 'bg-orange-100',
89
+ darkBgColor: 'dark:bg-orange-900',
90
+ icon: '↑',
91
+ },
92
+ import: {
93
+ color: 'text-teal-700 dark:text-teal-300',
94
+ bgColor: 'bg-teal-100',
95
+ darkBgColor: 'dark:bg-teal-900',
96
+ icon: '↓',
97
+ },
98
+ approve: {
99
+ color: 'text-emerald-700 dark:text-emerald-300',
100
+ bgColor: 'bg-emerald-100',
101
+ darkBgColor: 'dark:bg-emerald-900',
102
+ icon: '✓',
103
+ },
104
+ reject: {
105
+ color: 'text-rose-700 dark:text-rose-300',
106
+ bgColor: 'bg-rose-100',
107
+ darkBgColor: 'dark:bg-rose-900',
108
+ icon: '✗',
109
+ },
110
+ deploy: {
111
+ color: 'text-indigo-700 dark:text-indigo-300',
112
+ bgColor: 'bg-indigo-100',
113
+ darkBgColor: 'dark:bg-indigo-900',
114
+ icon: '▲',
115
+ },
116
+ rollback: {
117
+ color: 'text-amber-700 dark:text-amber-300',
118
+ bgColor: 'bg-amber-100',
119
+ darkBgColor: 'dark:bg-amber-900',
120
+ icon: '↺',
121
+ },
122
+ };
123
+
124
+ const formatTimestamp = (date: Date): string => {
125
+ const now = new Date();
126
+ const diffMs = now.getTime() - date.getTime();
127
+ const diffMins = Math.floor(diffMs / 60000);
128
+ const diffHours = Math.floor(diffMs / 3600000);
129
+ const diffDays = Math.floor(diffMs / 86400000);
130
+
131
+ if (diffMins < 1) return 'Just now';
132
+ if (diffMins < 60) return `${diffMins}m ago`;
133
+ if (diffHours < 24) return `${diffHours}h ago`;
134
+ if (diffDays < 7) return `${diffDays}d ago`;
135
+ return date.toLocaleDateString();
136
+ };
137
+
10
138
  export const AuditLog: React.FC<AuditLogProps> = ({
139
+ entries,
140
+ title,
141
+ maxHeight = 500,
142
+ onEntryPress,
11
143
  className,
12
- children,
13
- disabled,
14
- ...props
15
- }) => (
16
- <View
17
- className={cn(
18
- 'p-4 rounded-lg border bg-white dark:bg-gray-900 border-gray-200 dark:border-gray-700',
19
- disabled && 'opacity-50',
20
- className
21
- )}
22
- accessibilityLabel="Audit Log"
23
- {...props}
24
- >
25
- {children || <Text className="text-gray-900 dark:text-white">AuditLog Component</Text>}
26
- </View>
27
- );
144
+ }) => {
145
+ return (
146
+ <Card className={cn('overflow-hidden', className)}>
147
+ {title && (
148
+ <View className='px-4 py-3 border-b border-gray-200 dark:border-gray-700'>
149
+ <Text className='text-base font-semibold text-gray-900 dark:text-gray-100'>
150
+ {title}
151
+ </Text>
152
+ </View>
153
+ )}
154
+ <ScrollView style={{ maxHeight }} showsVerticalScrollIndicator={true}>
155
+ {entries.map((entry, index) => {
156
+ const config = actionConfig[entry.action];
157
+ const isLast = index === entries.length - 1;
158
+
159
+ const content = (
160
+ <View
161
+ className={cn(
162
+ 'px-4 py-3',
163
+ !isLast && 'border-b border-gray-100 dark:border-gray-800'
164
+ )}
165
+ >
166
+ <View className='flex-row items-start'>
167
+ <View
168
+ className={cn(
169
+ 'w-8 h-8 rounded-full items-center justify-center mr-3',
170
+ config.bgColor,
171
+ config.darkBgColor
172
+ )}
173
+ >
174
+ <Text className={cn('text-sm font-bold', config.color)}>
175
+ {config.icon}
176
+ </Text>
177
+ </View>
178
+ <View className='flex-1'>
179
+ <View className='flex-row items-center flex-wrap'>
180
+ <Text className='text-sm font-medium text-gray-900 dark:text-gray-100'>
181
+ {entry.actor.name}
182
+ </Text>
183
+ <Text className='text-sm text-gray-600 dark:text-gray-400 mx-1'>
184
+ {entry.action}d
185
+ </Text>
186
+ <Text className='text-sm font-medium text-gray-900 dark:text-gray-100'>
187
+ {entry.resource.name}
188
+ </Text>
189
+ </View>
190
+ <View className='flex-row items-center mt-1'>
191
+ <View
192
+ className={cn(
193
+ 'px-1.5 py-0.5 rounded mr-2',
194
+ config.bgColor,
195
+ config.darkBgColor
196
+ )}
197
+ >
198
+ <Text
199
+ className={cn(
200
+ 'text-xs font-medium uppercase',
201
+ config.color
202
+ )}
203
+ >
204
+ {entry.action}
205
+ </Text>
206
+ </View>
207
+ <Text className='text-xs text-gray-500 dark:text-gray-500'>
208
+ {entry.resource.type}
209
+ </Text>
210
+ </View>
211
+ <View className='flex-row items-center mt-2'>
212
+ <Text className='text-xs text-gray-400 dark:text-gray-600'>
213
+ {formatTimestamp(entry.timestamp)}
214
+ </Text>
215
+ {entry.ipAddress && (
216
+ <Text className='text-xs text-gray-400 dark:text-gray-600 ml-2'>
217
+ IP: {entry.ipAddress}
218
+ </Text>
219
+ )}
220
+ </View>
221
+ </View>
222
+ </View>
223
+ </View>
224
+ );
225
+
226
+ if (onEntryPress) {
227
+ return (
228
+ <Pressable
229
+ key={entry.id}
230
+ onPress={() => onEntryPress(entry)}
231
+ accessibilityRole='button'
232
+ >
233
+ {content}
234
+ </Pressable>
235
+ );
236
+ }
237
+
238
+ return <View key={entry.id}>{content}</View>;
239
+ })}
240
+ </ScrollView>
241
+ <View className='px-4 py-2 bg-gray-50 dark:bg-gray-900 border-t border-gray-200 dark:border-gray-700'>
242
+ <Text className='text-xs text-gray-500 dark:text-gray-500'>
243
+ Showing {entries.length} audit entries
244
+ </Text>
245
+ </View>
246
+ </Card>
247
+ );
248
+ };
249
+
250
+ export default AuditLog;
@@ -19,9 +19,13 @@ export const BodyMetrics: React.FC<BodyMetricsProps> = ({
19
19
  disabled && 'opacity-50',
20
20
  className
21
21
  )}
22
- accessibilityLabel="Body Metrics"
22
+ accessibilityLabel='Body Metrics'
23
23
  {...props}
24
24
  >
25
- {children || <Text className="text-gray-900 dark:text-white">BodyMetrics Component</Text>}
25
+ {children || (
26
+ <Text className='text-gray-900 dark:text-white'>
27
+ BodyMetrics Component
28
+ </Text>
29
+ )}
26
30
  </View>
27
31
  );
package/src/BuildLog.tsx CHANGED
@@ -1,32 +1,138 @@
1
1
  import React from 'react';
2
- import { Text, Pressable, type ViewProps } from 'react-native';
3
- import { cn } from '@sudobility/components-rn';
2
+ import { View, Text, ScrollView } from 'react-native';
3
+ import { cn, Card } from '@sudobility/components-rn';
4
4
 
5
- export interface BuildLogProps extends ViewProps {
6
- disabled?: boolean;
7
- onPress?: () => void;
8
- children?: React.ReactNode;
5
+ export type LogLevel = 'info' | 'warn' | 'error' | 'debug' | 'success';
6
+
7
+ export interface LogEntry {
8
+ id: string;
9
+ level: LogLevel;
10
+ message: string;
11
+ timestamp: Date;
12
+ source?: string;
13
+ }
14
+
15
+ export interface BuildLogProps {
16
+ entries: LogEntry[];
17
+ title?: string;
18
+ maxHeight?: number;
19
+ showTimestamp?: boolean;
20
+ showSource?: boolean;
21
+ className?: string;
9
22
  }
10
23
 
24
+ const levelConfig: Record<
25
+ LogLevel,
26
+ { color: string; bgColor: string; darkBgColor: string; prefix: string }
27
+ > = {
28
+ info: {
29
+ color: 'text-blue-600 dark:text-blue-400',
30
+ bgColor: 'bg-blue-50',
31
+ darkBgColor: 'dark:bg-blue-950',
32
+ prefix: 'INFO',
33
+ },
34
+ warn: {
35
+ color: 'text-yellow-600 dark:text-yellow-400',
36
+ bgColor: 'bg-yellow-50',
37
+ darkBgColor: 'dark:bg-yellow-950',
38
+ prefix: 'WARN',
39
+ },
40
+ error: {
41
+ color: 'text-red-600 dark:text-red-400',
42
+ bgColor: 'bg-red-50',
43
+ darkBgColor: 'dark:bg-red-950',
44
+ prefix: 'ERROR',
45
+ },
46
+ debug: {
47
+ color: 'text-gray-600 dark:text-gray-400',
48
+ bgColor: 'bg-gray-50',
49
+ darkBgColor: 'dark:bg-gray-900',
50
+ prefix: 'DEBUG',
51
+ },
52
+ success: {
53
+ color: 'text-green-600 dark:text-green-400',
54
+ bgColor: 'bg-green-50',
55
+ darkBgColor: 'dark:bg-green-950',
56
+ prefix: 'SUCCESS',
57
+ },
58
+ };
59
+
60
+ const formatTime = (date: Date): string => {
61
+ return date.toLocaleTimeString('en-US', {
62
+ hour12: false,
63
+ hour: '2-digit',
64
+ minute: '2-digit',
65
+ second: '2-digit',
66
+ });
67
+ };
68
+
11
69
  export const BuildLog: React.FC<BuildLogProps> = ({
70
+ entries,
71
+ title,
72
+ maxHeight = 400,
73
+ showTimestamp = true,
74
+ showSource = false,
12
75
  className,
13
- children,
14
- disabled = false,
15
- onPress,
16
- ...props
17
- }) => (
18
- <Pressable
19
- onPress={disabled ? undefined : onPress}
20
- disabled={disabled}
21
- accessibilityRole="button"
22
- accessibilityLabel="Build Log"
23
- className={cn(
24
- 'p-4 rounded-lg border bg-white dark:bg-gray-900 border-gray-200 dark:border-gray-700',
25
- disabled && 'opacity-50',
26
- className
27
- )}
28
- {...props}
29
- >
30
- {children || <Text className="text-gray-900 dark:text-white">BuildLog Component</Text>}
31
- </Pressable>
32
- );
76
+ }) => {
77
+ return (
78
+ <Card className={cn('overflow-hidden', className)}>
79
+ {title && (
80
+ <View className='px-4 py-3 border-b border-gray-200 dark:border-gray-700'>
81
+ <Text className='text-base font-semibold text-gray-900 dark:text-gray-100'>
82
+ {title}
83
+ </Text>
84
+ </View>
85
+ )}
86
+ <ScrollView
87
+ style={{ maxHeight }}
88
+ className='bg-gray-900 dark:bg-black'
89
+ showsVerticalScrollIndicator={true}
90
+ >
91
+ <View className='p-3'>
92
+ {entries.map(entry => {
93
+ const config = levelConfig[entry.level];
94
+ return (
95
+ <View
96
+ key={entry.id}
97
+ className={cn(
98
+ 'flex-row flex-wrap py-1 px-2 mb-1 rounded',
99
+ config.bgColor,
100
+ config.darkBgColor
101
+ )}
102
+ >
103
+ {showTimestamp && (
104
+ <Text className='font-mono text-xs text-gray-500 dark:text-gray-500 mr-2'>
105
+ [{formatTime(entry.timestamp)}]
106
+ </Text>
107
+ )}
108
+ <Text
109
+ className={cn(
110
+ 'font-mono text-xs font-bold mr-2',
111
+ config.color
112
+ )}
113
+ >
114
+ [{config.prefix}]
115
+ </Text>
116
+ {showSource && entry.source && (
117
+ <Text className='font-mono text-xs text-gray-400 dark:text-gray-600 mr-2'>
118
+ [{entry.source}]
119
+ </Text>
120
+ )}
121
+ <Text className='font-mono text-xs text-gray-200 dark:text-gray-300 flex-1'>
122
+ {entry.message}
123
+ </Text>
124
+ </View>
125
+ );
126
+ })}
127
+ </View>
128
+ </ScrollView>
129
+ <View className='px-4 py-2 bg-gray-800 dark:bg-gray-950 border-t border-gray-700'>
130
+ <Text className='text-xs text-gray-400 dark:text-gray-500'>
131
+ {entries.length} log entries
132
+ </Text>
133
+ </View>
134
+ </Card>
135
+ );
136
+ };
137
+
138
+ export default BuildLog;
@@ -19,9 +19,13 @@ export const ChangelogDisplay: React.FC<ChangelogDisplayProps> = ({
19
19
  disabled && 'opacity-50',
20
20
  className
21
21
  )}
22
- accessibilityLabel="Changelog Display"
22
+ accessibilityLabel='Changelog Display'
23
23
  {...props}
24
24
  >
25
- {children || <Text className="text-gray-900 dark:text-white">ChangelogDisplay Component</Text>}
25
+ {children || (
26
+ <Text className='text-gray-900 dark:text-white'>
27
+ ChangelogDisplay Component
28
+ </Text>
29
+ )}
26
30
  </View>
27
31
  );
@@ -18,8 +18,8 @@ export const CodePlayground: React.FC<CodePlaygroundProps> = ({
18
18
  <Pressable
19
19
  onPress={disabled ? undefined : onPress}
20
20
  disabled={disabled}
21
- accessibilityRole="button"
22
- accessibilityLabel="Code Playground"
21
+ accessibilityRole='button'
22
+ accessibilityLabel='Code Playground'
23
23
  className={cn(
24
24
  'p-4 rounded-lg border bg-white dark:bg-gray-900 border-gray-200 dark:border-gray-700',
25
25
  disabled && 'opacity-50',
@@ -27,6 +27,10 @@ export const CodePlayground: React.FC<CodePlaygroundProps> = ({
27
27
  )}
28
28
  {...props}
29
29
  >
30
- {children || <Text className="text-gray-900 dark:text-white">CodePlayground Component</Text>}
30
+ {children || (
31
+ <Text className='text-gray-900 dark:text-white'>
32
+ CodePlayground Component
33
+ </Text>
34
+ )}
31
35
  </Pressable>
32
36
  );
@@ -18,8 +18,8 @@ export const ConflictResolver: React.FC<ConflictResolverProps> = ({
18
18
  <Pressable
19
19
  onPress={disabled ? undefined : onPress}
20
20
  disabled={disabled}
21
- accessibilityRole="button"
22
- accessibilityLabel="Conflict Resolver"
21
+ accessibilityRole='button'
22
+ accessibilityLabel='Conflict Resolver'
23
23
  className={cn(
24
24
  'p-4 rounded-lg border bg-white dark:bg-gray-900 border-gray-200 dark:border-gray-700',
25
25
  disabled && 'opacity-50',
@@ -27,6 +27,10 @@ export const ConflictResolver: React.FC<ConflictResolverProps> = ({
27
27
  )}
28
28
  {...props}
29
29
  >
30
- {children || <Text className="text-gray-900 dark:text-white">ConflictResolver Component</Text>}
30
+ {children || (
31
+ <Text className='text-gray-900 dark:text-white'>
32
+ ConflictResolver Component
33
+ </Text>
34
+ )}
31
35
  </Pressable>
32
36
  );
@@ -19,9 +19,13 @@ export const DealPipeline: React.FC<DealPipelineProps> = ({
19
19
  disabled && 'opacity-50',
20
20
  className
21
21
  )}
22
- accessibilityLabel="Deal Pipeline"
22
+ accessibilityLabel='Deal Pipeline'
23
23
  {...props}
24
24
  >
25
- {children || <Text className="text-gray-900 dark:text-white">DealPipeline Component</Text>}
25
+ {children || (
26
+ <Text className='text-gray-900 dark:text-white'>
27
+ DealPipeline Component
28
+ </Text>
29
+ )}
26
30
  </View>
27
31
  );