git-history-ui 1.0.2 → 1.0.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.
Files changed (50) hide show
  1. package/README.md +7 -7
  2. package/dist/backend/server.d.ts.map +1 -1
  3. package/dist/backend/server.js +19 -5
  4. package/dist/backend/server.js.map +1 -1
  5. package/package.json +6 -1
  6. package/.dockerignore +0 -19
  7. package/.eslintrc.js +0 -21
  8. package/Dockerfile +0 -29
  9. package/demo.js +0 -45
  10. package/frontend/.editorconfig +0 -17
  11. package/frontend/.vscode/extensions.json +0 -4
  12. package/frontend/.vscode/launch.json +0 -20
  13. package/frontend/.vscode/tasks.json +0 -42
  14. package/frontend/README.md +0 -59
  15. package/frontend/angular.json +0 -99
  16. package/frontend/package-lock.json +0 -11272
  17. package/frontend/package.json +0 -58
  18. package/frontend/postcss.config.js +0 -6
  19. package/frontend/proxy.conf.json +0 -7
  20. package/frontend/public/favicon.ico +0 -0
  21. package/frontend/src/app/app.component.ts +0 -598
  22. package/frontend/src/app/app.config.ts +0 -12
  23. package/frontend/src/app/app.css +0 -0
  24. package/frontend/src/app/app.html +0 -342
  25. package/frontend/src/app/app.routes.ts +0 -3
  26. package/frontend/src/app/app.spec.ts +0 -23
  27. package/frontend/src/app/app.ts +0 -12
  28. package/frontend/src/app/components/color-palette-selector/color-palette-selector.component.ts +0 -137
  29. package/frontend/src/app/components/commit-detail/commit-detail.component.ts +0 -327
  30. package/frontend/src/app/components/commit-graph/commit-graph.component.ts +0 -294
  31. package/frontend/src/app/components/commit-list/commit-list.component.ts +0 -199
  32. package/frontend/src/app/components/diff-viewer/diff-viewer.component.ts +0 -311
  33. package/frontend/src/app/models/color-palette.models.ts +0 -229
  34. package/frontend/src/app/models/git.models.ts +0 -39
  35. package/frontend/src/app/services/git.service.ts +0 -43
  36. package/frontend/src/index.html +0 -13
  37. package/frontend/src/main.ts +0 -6
  38. package/frontend/src/styles.css +0 -401
  39. package/frontend/tailwind.config.js +0 -11
  40. package/frontend/tsconfig.app.json +0 -15
  41. package/frontend/tsconfig.json +0 -34
  42. package/frontend/tsconfig.spec.json +0 -14
  43. package/jest.config.js +0 -26
  44. package/src/__tests__/gitService.test.ts +0 -533
  45. package/src/__tests__/setup.ts +0 -25
  46. package/src/backend/dev-server.ts +0 -14
  47. package/src/backend/gitService.ts +0 -277
  48. package/src/backend/server.ts +0 -140
  49. package/src/cli.ts +0 -56
  50. package/tsconfig.json +0 -25
@@ -1,199 +0,0 @@
1
- import { Component, Input, Output, EventEmitter, OnInit, OnDestroy } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import { Commit } from '../../models/git.models';
4
- import { ColorPalette } from '../../models/color-palette.models';
5
-
6
- @Component({
7
- selector: 'app-commit-list',
8
- standalone: true,
9
- imports: [CommonModule],
10
- template: `
11
- <div class="commit-list" [style.background-color]="getBackgroundColor()" [style.min-height]="'100vh'">
12
- <div *ngFor="let commit of commits"
13
- class="commit-item"
14
- [style.background-color]="getColor('background', 'white')"
15
- [style.border-color]="getColor('border', '#e5e7eb')"
16
- [style.color]="getColor('text', '#111827')"
17
- (click)="onCommitClick(commit)">
18
- <div class="commit-header">
19
- <div class="commit-info">
20
- <div class="commit-meta">
21
- <span class="commit-hash" [style.color]="getColor('text', '#6b7280')">{{ commit.hash.substring(0, 8) }}</span>
22
- <span class="commit-author" [style.color]="getColor('text', '#374151')">{{ commit.author }}</span>
23
- <span class="commit-date" [style.color]="getColor('text', '#6b7280')">{{ formatDate(commit.date) }}</span>
24
- </div>
25
- <h3 class="commit-message" [style.color]="getColor('text', '#111827')">{{ commit.message }}</h3>
26
- <div class="commit-stats" [style.color]="getColor('text', '#6b7280')">
27
- <span>{{ commit.files.length }} files changed</span>
28
- <span *ngIf="commit.branches.length > 0">
29
- Branch: {{ commit.branches[0] }}
30
- </span>
31
- <span *ngIf="commit.tags.length > 0">
32
- Tag: {{ commit.tags[0] }}
33
- </span>
34
- </div>
35
- </div>
36
- <div class="commit-actions">
37
- <button class="btn btn-primary"
38
- [style.background-color]="getColor('primary', '#3b82f6')"
39
- [style.color]="getColor('text', 'white')"
40
- (click)="onCommitClick(commit); $event.stopPropagation()">
41
- View
42
- </button>
43
- </div>
44
- </div>
45
- </div>
46
-
47
- <!-- No results message -->
48
- <div *ngIf="commits.length === 0"
49
- class="no-results"
50
- [style.color]="getColor('text', '#6b7280')"
51
- [style.text-align]="'center'"
52
- [style.padding]="'2rem'">
53
- No commits found matching your search criteria.
54
- </div>
55
- </div>
56
- `,
57
- styles: [`
58
- .commit-list {
59
- display: flex;
60
- flex-direction: column;
61
- gap: 1rem;
62
- min-height: 100vh;
63
- padding: 1rem 0;
64
- transition: background-color 0.2s ease;
65
- }
66
-
67
- .commit-item {
68
- background-color: white;
69
- border-radius: 0.5rem;
70
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
71
- padding: 1rem;
72
- cursor: pointer;
73
- transition: box-shadow 0.2s;
74
- }
75
-
76
- .commit-item:hover {
77
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
78
- }
79
-
80
- .commit-header {
81
- display: flex;
82
- justify-content: space-between;
83
- align-items: flex-start;
84
- }
85
-
86
- .commit-info {
87
- flex: 1;
88
- }
89
-
90
- .commit-meta {
91
- display: flex;
92
- align-items: center;
93
- gap: 0.5rem;
94
- margin-bottom: 0.5rem;
95
- }
96
-
97
- .commit-hash {
98
- font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
99
- font-size: 0.875rem;
100
- color: #6b7280;
101
- }
102
-
103
- .commit-author {
104
- font-size: 0.875rem;
105
- color: #374151;
106
- }
107
-
108
- .commit-date {
109
- font-size: 0.875rem;
110
- color: #6b7280;
111
- }
112
-
113
- .commit-message {
114
- font-size: 1.125rem;
115
- font-weight: 500;
116
- color: #111827;
117
- margin-bottom: 0.5rem;
118
- }
119
-
120
- .commit-stats {
121
- display: flex;
122
- align-items: center;
123
- gap: 1rem;
124
- font-size: 0.875rem;
125
- color: #6b7280;
126
- }
127
-
128
- .commit-actions {
129
- display: flex;
130
- gap: 0.5rem;
131
- }
132
-
133
- .no-results {
134
- font-size: 1rem;
135
- font-style: italic;
136
- }
137
-
138
- /* Remove hardcoded dark mode styles to let dynamic styling work */
139
- /* All styling is now handled by dynamic [style] bindings */
140
- `]
141
- })
142
- export class CommitListComponent implements OnInit, OnDestroy {
143
- @Input() commits: Commit[] = [];
144
- @Input() colorPalette?: ColorPalette;
145
- @Output() commitClick = new EventEmitter<Commit>();
146
-
147
- private observer?: MutationObserver;
148
-
149
- ngOnInit() {
150
- this.setupDarkModeObserver();
151
- }
152
-
153
- ngOnDestroy() {
154
- if (this.observer) {
155
- this.observer.disconnect();
156
- }
157
- }
158
-
159
- onCommitClick(commit: Commit) {
160
- this.commitClick.emit(commit);
161
- }
162
-
163
- formatDate(dateString: string): string {
164
- const date = new Date(dateString);
165
- return date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
166
- }
167
-
168
- private setupDarkModeObserver() {
169
- // Observe changes to the document element's class list
170
- this.observer = new MutationObserver((mutations) => {
171
- mutations.forEach((mutation) => {
172
- if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
173
- // Force change detection when dark mode changes
174
- // This will trigger a re-render with the correct background color
175
- setTimeout(() => {
176
- // Trigger change detection
177
- this.getBackgroundColor();
178
- }, 0);
179
- }
180
- });
181
- });
182
-
183
- // Start observing the document element for class changes
184
- this.observer.observe(document.documentElement, {
185
- attributes: true,
186
- attributeFilter: ['class']
187
- });
188
- }
189
-
190
- getColor(colorKey: keyof ColorPalette['colors'], defaultValue: string): string {
191
- return this.colorPalette?.colors[colorKey] || defaultValue;
192
- }
193
-
194
- getBackgroundColor(): string {
195
- // Use transparent background so it inherits from the parent container
196
- // This allows the list to blend with the main content background
197
- return 'transparent';
198
- }
199
- }
@@ -1,311 +0,0 @@
1
- import { Component, Input, Output, EventEmitter } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import { DiffFile } from '../../models/git.models';
4
-
5
- @Component({
6
- selector: 'app-diff-viewer',
7
- standalone: true,
8
- imports: [CommonModule],
9
- template: `
10
- <div class="diff-viewer">
11
- <div class="diff-header">
12
- <h3 class="diff-title">Diff: {{ fileName }}</h3>
13
- <button (click)="onClose()" class="close-button">
14
- <svg class="close-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
15
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
16
- </svg>
17
- </button>
18
- </div>
19
-
20
- <div class="diff-content">
21
- <div class="diff-stats">
22
- <span class="stat added">+{{ diffFile?.additions || 0 }} additions</span>
23
- <span class="stat removed">-{{ diffFile?.deletions || 0 }} deletions</span>
24
- </div>
25
-
26
- <div class="diff-lines" *ngIf="diffLines.length > 0">
27
- <div *ngFor="let line of diffLines; trackBy: trackByLine"
28
- class="diff-line"
29
- [class.added]="line.type === 'added'"
30
- [class.removed]="line.type === 'removed'"
31
- [class.context]="line.type === 'context'">
32
- <span class="line-number">{{ line.lineNumber }}</span>
33
- <span class="line-content">{{ line.content }}</span>
34
- </div>
35
- </div>
36
-
37
- <div class="no-diff" *ngIf="diffLines.length === 0">
38
- <p>No diff content available for this file.</p>
39
- </div>
40
- </div>
41
- </div>
42
- `,
43
- styles: [`
44
- .diff-viewer {
45
- background-color: white;
46
- border-radius: 0.5rem;
47
- box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
48
- max-width: 90vw;
49
- width: 100%;
50
- max-height: 80vh;
51
- overflow: hidden;
52
- display: flex;
53
- flex-direction: column;
54
- }
55
-
56
- .diff-header {
57
- display: flex;
58
- justify-content: space-between;
59
- align-items: center;
60
- padding: 1rem 1.5rem;
61
- border-bottom: 1px solid #e5e7eb;
62
- background-color: #f9fafb;
63
- }
64
-
65
- .diff-title {
66
- font-size: 1.125rem;
67
- font-weight: 600;
68
- color: #111827;
69
- margin: 0;
70
- }
71
-
72
- .close-button {
73
- background: none;
74
- border: none;
75
- color: #6b7280;
76
- cursor: pointer;
77
- padding: 0.25rem;
78
- border-radius: 0.25rem;
79
- transition: color 0.2s;
80
- }
81
-
82
- .close-button:hover {
83
- color: #374151;
84
- }
85
-
86
- .close-icon {
87
- width: 1.5rem;
88
- height: 1.5rem;
89
- }
90
-
91
- .diff-content {
92
- flex: 1;
93
- overflow-y: auto;
94
- padding: 1rem;
95
- }
96
-
97
- .diff-stats {
98
- display: flex;
99
- gap: 1rem;
100
- margin-bottom: 1rem;
101
- padding: 0.5rem;
102
- background-color: #f9fafb;
103
- border-radius: 0.375rem;
104
- }
105
-
106
- .stat {
107
- font-size: 0.875rem;
108
- font-weight: 500;
109
- }
110
-
111
- .stat.added {
112
- color: #059669;
113
- }
114
-
115
- .stat.removed {
116
- color: #dc2626;
117
- }
118
-
119
- .diff-lines {
120
- font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
121
- font-size: 0.875rem;
122
- line-height: 1.5;
123
- border: 1px solid #e5e7eb;
124
- border-radius: 0.375rem;
125
- overflow: hidden;
126
- }
127
-
128
- .diff-line {
129
- display: flex;
130
- padding: 0.125rem 0.5rem;
131
- border-bottom: 1px solid #f3f4f6;
132
- }
133
-
134
- .diff-line:last-child {
135
- border-bottom: none;
136
- }
137
-
138
- .diff-line.added {
139
- background-color: #dcfce7;
140
- }
141
-
142
- .diff-line.removed {
143
- background-color: #fee2e2;
144
- }
145
-
146
- .diff-line.context {
147
- background-color: #f9fafb;
148
- }
149
-
150
- .line-number {
151
- min-width: 3rem;
152
- color: #6b7280;
153
- font-size: 0.75rem;
154
- padding-right: 0.5rem;
155
- border-right: 1px solid #e5e7eb;
156
- margin-right: 0.5rem;
157
- }
158
-
159
- .line-content {
160
- flex: 1;
161
- white-space: pre-wrap;
162
- word-break: break-all;
163
- }
164
-
165
- .diff-line.added .line-content {
166
- color: #166534;
167
- }
168
-
169
- .diff-line.removed .line-content {
170
- color: #991b1b;
171
- }
172
-
173
- .diff-line.context .line-content {
174
- color: #374151;
175
- }
176
-
177
- .no-diff {
178
- text-align: center;
179
- padding: 2rem;
180
- color: #6b7280;
181
- }
182
-
183
- /* Dark mode styles */
184
- .dark .diff-viewer {
185
- background-color: #2d2d2d;
186
- color: #e0e0e0;
187
- }
188
-
189
- .dark .diff-header {
190
- background-color: #404040;
191
- border-color: #555;
192
- }
193
-
194
- .dark .diff-title {
195
- color: #e0e0e0;
196
- }
197
-
198
- .dark .close-button {
199
- color: #9ca3af;
200
- }
201
-
202
- .dark .close-button:hover {
203
- color: #d1d5db;
204
- }
205
-
206
- .dark .diff-stats {
207
- background-color: #404040;
208
- }
209
-
210
- .dark .diff-lines {
211
- border-color: #555;
212
- }
213
-
214
- .dark .diff-line {
215
- border-color: #404040;
216
- }
217
-
218
- .dark .diff-line.added {
219
- background-color: #14532d;
220
- }
221
-
222
- .dark .diff-line.removed {
223
- background-color: #7f1d1d;
224
- }
225
-
226
- .dark .diff-line.context {
227
- background-color: #404040;
228
- }
229
-
230
- .dark .line-number {
231
- color: #9ca3af;
232
- border-color: #555;
233
- }
234
-
235
- .dark .diff-line.added .line-content {
236
- color: #bbf7d0;
237
- }
238
-
239
- .dark .diff-line.removed .line-content {
240
- color: #fecaca;
241
- }
242
-
243
- .dark .diff-line.context .line-content {
244
- color: #d1d5db;
245
- }
246
-
247
- .dark .no-diff {
248
- color: #9ca3af;
249
- }
250
- `]
251
- })
252
- export class DiffViewerComponent {
253
- @Input() fileName: string = '';
254
- @Input() diffFile: DiffFile | null = null;
255
- @Output() close = new EventEmitter<void>();
256
-
257
- diffLines: Array<{type: 'added' | 'removed' | 'context', lineNumber: string, content: string}> = [];
258
-
259
- ngOnInit() {
260
- console.log('DiffViewer ngOnInit called');
261
- this.parseDiff();
262
- }
263
-
264
- ngOnChanges() {
265
- console.log('DiffViewer ngOnChanges called');
266
- this.parseDiff();
267
- }
268
-
269
- parseDiff() {
270
- console.log('parseDiff called with diffFile:', this.diffFile);
271
-
272
- if (!this.diffFile?.changes) {
273
- console.log('No changes found in diffFile');
274
- this.diffLines = [];
275
- return;
276
- }
277
-
278
- const lines = this.diffFile.changes.split('\n');
279
- console.log('Parsed lines:', lines.length);
280
-
281
- this.diffLines = lines.map((line, index) => {
282
- let type: 'added' | 'removed' | 'context' = 'context';
283
- let lineNumber = (index + 1).toString();
284
- let content = line;
285
-
286
- if (line.startsWith('+')) {
287
- type = 'added';
288
- content = line.substring(1);
289
- } else if (line.startsWith('-')) {
290
- type = 'removed';
291
- content = line.substring(1);
292
- } else if (line.startsWith('@@')) {
293
- // Git diff header line
294
- lineNumber = '@@';
295
- content = line;
296
- }
297
-
298
- return { type, lineNumber, content };
299
- });
300
-
301
- console.log('Parsed diff lines:', this.diffLines.length);
302
- }
303
-
304
- onClose() {
305
- this.close.emit();
306
- }
307
-
308
- trackByLine(index: number, line: any): string {
309
- return `${line.type}-${index}`;
310
- }
311
- }