@stoked-ui/github 0.0.0-a.0
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/CHANGELOG.md +15014 -0
- package/GithubCalendar/GithubCalendar.d.ts +7 -0
- package/GithubCalendar/GithubCalendar.js +330 -0
- package/GithubCalendar/index.d.ts +2 -0
- package/GithubCalendar/index.js +2 -0
- package/GithubCalendar/package.json +6 -0
- package/GithubEvents/EventTypes/CreateEvent.d.ts +7 -0
- package/GithubEvents/EventTypes/CreateEvent.js +72 -0
- package/GithubEvents/EventTypes/DeleteEvent.d.ts +7 -0
- package/GithubEvents/EventTypes/DeleteEvent.js +65 -0
- package/GithubEvents/EventTypes/ForkEvent.d.ts +7 -0
- package/GithubEvents/EventTypes/ForkEvent.js +77 -0
- package/GithubEvents/EventTypes/IssueCommentEvent.d.ts +7 -0
- package/GithubEvents/EventTypes/IssueCommentEvent.js +210 -0
- package/GithubEvents/EventTypes/IssuesEvent.d.ts +7 -0
- package/GithubEvents/EventTypes/IssuesEvent.js +97 -0
- package/GithubEvents/EventTypes/ProjectsV2ColumnEvent.d.ts +7 -0
- package/GithubEvents/EventTypes/ProjectsV2ColumnEvent.js +69 -0
- package/GithubEvents/EventTypes/ProjectsV2Event.d.ts +7 -0
- package/GithubEvents/EventTypes/ProjectsV2Event.js +74 -0
- package/GithubEvents/EventTypes/ProjectsV2FieldEvent.d.ts +7 -0
- package/GithubEvents/EventTypes/ProjectsV2FieldEvent.js +77 -0
- package/GithubEvents/EventTypes/ProjectsV2ItemEvent.d.ts +7 -0
- package/GithubEvents/EventTypes/ProjectsV2ItemEvent.js +79 -0
- package/GithubEvents/EventTypes/PullRequest/CommitsList.d.ts +17 -0
- package/GithubEvents/EventTypes/PullRequest/CommitsList.js +99 -0
- package/GithubEvents/EventTypes/PullRequest/FileChanges.d.ts +17 -0
- package/GithubEvents/EventTypes/PullRequest/FileChanges.js +182 -0
- package/GithubEvents/EventTypes/PullRequest/PullRequestEvent.d.ts +8 -0
- package/GithubEvents/EventTypes/PullRequest/PullRequestEvent.js +374 -0
- package/GithubEvents/EventTypes/PullRequest/PullRequestView.d.ts +29 -0
- package/GithubEvents/EventTypes/PullRequest/PullRequestView.js +132 -0
- package/GithubEvents/EventTypes/PushEvent.d.ts +7 -0
- package/GithubEvents/EventTypes/PushEvent.js +106 -0
- package/GithubEvents/GithubEvents.d.ts +49 -0
- package/GithubEvents/GithubEvents.js +1454 -0
- package/GithubEvents/index.d.ts +2 -0
- package/GithubEvents/index.js +2 -0
- package/GithubEvents/package.json +6 -0
- package/LICENSE +21 -0
- package/README.md +29 -0
- package/apiHandlers/getPullRequestDetails.d.ts +7 -0
- package/apiHandlers/getPullRequestDetails.js +120 -0
- package/apiHandlers/index.d.ts +1 -0
- package/apiHandlers/index.js +1 -0
- package/apiHandlers/package.json +6 -0
- package/index.d.ts +3 -0
- package/index.js +10 -0
- package/modern/GithubCalendar/GithubCalendar.js +330 -0
- package/modern/GithubCalendar/index.js +2 -0
- package/modern/GithubEvents/EventTypes/CreateEvent.js +72 -0
- package/modern/GithubEvents/EventTypes/DeleteEvent.js +65 -0
- package/modern/GithubEvents/EventTypes/ForkEvent.js +77 -0
- package/modern/GithubEvents/EventTypes/IssueCommentEvent.js +210 -0
- package/modern/GithubEvents/EventTypes/IssuesEvent.js +97 -0
- package/modern/GithubEvents/EventTypes/ProjectsV2ColumnEvent.js +69 -0
- package/modern/GithubEvents/EventTypes/ProjectsV2Event.js +74 -0
- package/modern/GithubEvents/EventTypes/ProjectsV2FieldEvent.js +77 -0
- package/modern/GithubEvents/EventTypes/ProjectsV2ItemEvent.js +79 -0
- package/modern/GithubEvents/EventTypes/PullRequest/CommitsList.js +99 -0
- package/modern/GithubEvents/EventTypes/PullRequest/FileChanges.js +182 -0
- package/modern/GithubEvents/EventTypes/PullRequest/PullRequestEvent.js +374 -0
- package/modern/GithubEvents/EventTypes/PullRequest/PullRequestView.js +132 -0
- package/modern/GithubEvents/EventTypes/PushEvent.js +106 -0
- package/modern/GithubEvents/GithubEvents.js +1454 -0
- package/modern/GithubEvents/index.js +2 -0
- package/modern/apiHandlers/getPullRequestDetails.js +120 -0
- package/modern/apiHandlers/index.js +1 -0
- package/modern/index.js +10 -0
- package/modern/types/github.js +1 -0
- package/node/GithubCalendar/GithubCalendar.js +337 -0
- package/node/GithubCalendar/index.js +9 -0
- package/node/GithubEvents/EventTypes/CreateEvent.js +80 -0
- package/node/GithubEvents/EventTypes/DeleteEvent.js +73 -0
- package/node/GithubEvents/EventTypes/ForkEvent.js +85 -0
- package/node/GithubEvents/EventTypes/IssueCommentEvent.js +218 -0
- package/node/GithubEvents/EventTypes/IssuesEvent.js +105 -0
- package/node/GithubEvents/EventTypes/ProjectsV2ColumnEvent.js +77 -0
- package/node/GithubEvents/EventTypes/ProjectsV2Event.js +82 -0
- package/node/GithubEvents/EventTypes/ProjectsV2FieldEvent.js +85 -0
- package/node/GithubEvents/EventTypes/ProjectsV2ItemEvent.js +87 -0
- package/node/GithubEvents/EventTypes/PullRequest/CommitsList.js +107 -0
- package/node/GithubEvents/EventTypes/PullRequest/FileChanges.js +188 -0
- package/node/GithubEvents/EventTypes/PullRequest/PullRequestEvent.js +381 -0
- package/node/GithubEvents/EventTypes/PullRequest/PullRequestView.js +138 -0
- package/node/GithubEvents/EventTypes/PushEvent.js +114 -0
- package/node/GithubEvents/GithubEvents.js +1463 -0
- package/node/GithubEvents/index.js +9 -0
- package/node/apiHandlers/getPullRequestDetails.js +127 -0
- package/node/apiHandlers/index.js +13 -0
- package/node/index.js +27 -0
- package/node/types/github.js +5 -0
- package/package.json +71 -0
- package/types/github.d.ts +107 -0
- package/types/github.js +1 -0
|
@@ -0,0 +1,1454 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
var _div, _Chip, _SmalMi, _SmalMi2, _SmalMi3, _SmalMi4, _SmalMi5, _TableRow, _TableRow2;
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { RequestError } from '@octokit/request-error';
|
|
5
|
+
import Box from "@mui/material/Box";
|
|
6
|
+
import TextField from "@mui/material/TextField";
|
|
7
|
+
import Table from "@mui/material/Table";
|
|
8
|
+
import TableBody from "@mui/material/TableBody";
|
|
9
|
+
import TableCell from "@mui/material/TableCell";
|
|
10
|
+
import TableContainer from "@mui/material/TableContainer";
|
|
11
|
+
import TableHead from "@mui/material/TableHead";
|
|
12
|
+
import TableRow from "@mui/material/TableRow";
|
|
13
|
+
import Paper from "@mui/material/Paper";
|
|
14
|
+
import Typography from "@mui/material/Typography";
|
|
15
|
+
import CircularProgress from "@mui/material/CircularProgress";
|
|
16
|
+
import Select from '@mui/material/Select';
|
|
17
|
+
import MenuItem from '@mui/material/MenuItem';
|
|
18
|
+
import FormControl from '@mui/material/FormControl';
|
|
19
|
+
import { format, parse, parseISO } from 'date-fns';
|
|
20
|
+
import { toZonedTime } from 'date-fns-tz';
|
|
21
|
+
import { styled, useTheme } from '@mui/material/styles';
|
|
22
|
+
import Autocomplete from '@mui/material/Autocomplete';
|
|
23
|
+
import Pagination from '@mui/material/Pagination';
|
|
24
|
+
import dynamic from 'next/dynamic';
|
|
25
|
+
import PullRequestEvent from './EventTypes/PullRequest/PullRequestEvent';
|
|
26
|
+
import PushEvent from './EventTypes/PushEvent';
|
|
27
|
+
import DeleteEvent from './EventTypes/DeleteEvent';
|
|
28
|
+
import CreateEvent from './EventTypes/CreateEvent';
|
|
29
|
+
import IssuesEvent from './EventTypes/IssuesEvent';
|
|
30
|
+
import IssueCommentEvent from './EventTypes/IssueCommentEvent';
|
|
31
|
+
import Chip from '@mui/material/Chip';
|
|
32
|
+
// Extend the EventDetails interface for internal component use
|
|
33
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
34
|
+
// Import react-json-view dynamically to avoid SSR issues
|
|
35
|
+
const ReactJson = dynamic(() => import('react-json-view'), {
|
|
36
|
+
ssr: false,
|
|
37
|
+
loading: () => _div || (_div = /*#__PURE__*/_jsx("div", {
|
|
38
|
+
children: "Loading JSON viewer..."
|
|
39
|
+
}))
|
|
40
|
+
});
|
|
41
|
+
const MetadataDisplay = styled(Box)(({
|
|
42
|
+
theme
|
|
43
|
+
}) => {
|
|
44
|
+
return {
|
|
45
|
+
backgroundColor: 'rgba(255, 255, 255, 0.06)',
|
|
46
|
+
borderRadius: theme.shape.borderRadius,
|
|
47
|
+
boxShadow: theme.shadows[2],
|
|
48
|
+
padding: theme.spacing(2),
|
|
49
|
+
position: 'sticky',
|
|
50
|
+
width: '672px',
|
|
51
|
+
maxWidth: '692px',
|
|
52
|
+
minWidth: '300px',
|
|
53
|
+
top: '84px',
|
|
54
|
+
maxHeight: 'calc(100vh - 100px)',
|
|
55
|
+
overflow: 'auto'
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
function parseLinkHeader(header) {
|
|
59
|
+
if (!header) return {};
|
|
60
|
+
return header.split(',').reduce((links, part) => {
|
|
61
|
+
const match = part.match(/<(.+)>;\s*rel="([\w]+)"/);
|
|
62
|
+
if (match) {
|
|
63
|
+
const [, url, rel] = match;
|
|
64
|
+
if (rel === 'next' || rel === 'last') {
|
|
65
|
+
links[rel] = url;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return links;
|
|
69
|
+
}, {});
|
|
70
|
+
}
|
|
71
|
+
export async function githubEventsQuery({
|
|
72
|
+
query,
|
|
73
|
+
githubUser,
|
|
74
|
+
githubToken
|
|
75
|
+
}) {
|
|
76
|
+
try {
|
|
77
|
+
const {
|
|
78
|
+
page = query.page || 1,
|
|
79
|
+
per_page = query.per_page || 100,
|
|
80
|
+
// Default to 100 per page to minimize API calls
|
|
81
|
+
repo,
|
|
82
|
+
action,
|
|
83
|
+
date,
|
|
84
|
+
description
|
|
85
|
+
} = query;
|
|
86
|
+
const queryParams = new URLSearchParams(_extends({
|
|
87
|
+
page: String(page),
|
|
88
|
+
per_page: String(per_page)
|
|
89
|
+
}, repo && {
|
|
90
|
+
repo
|
|
91
|
+
}, action && {
|
|
92
|
+
action
|
|
93
|
+
}, date && {
|
|
94
|
+
date
|
|
95
|
+
}, description && {
|
|
96
|
+
description
|
|
97
|
+
}));
|
|
98
|
+
|
|
99
|
+
// Get GitHub token from environment variables
|
|
100
|
+
console.log(`Fetching events for user: ${githubUser}, page: ${page}, per_page: ${per_page}`);
|
|
101
|
+
|
|
102
|
+
// Fetch all available pages from GitHub API
|
|
103
|
+
let allEvents = [];
|
|
104
|
+
let hasMore = true;
|
|
105
|
+
let githubPage = 1;
|
|
106
|
+
const maxPages = 30; // GitHub's maximum for events endpoint
|
|
107
|
+
|
|
108
|
+
while (hasMore && githubPage <= maxPages) {
|
|
109
|
+
console.log(`Fetching page ${githubPage}...`);
|
|
110
|
+
const fetchOptions = {
|
|
111
|
+
headers: {
|
|
112
|
+
'User-Agent': 'brianstoker.com-website'
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
if (githubToken) {
|
|
116
|
+
fetchOptions.headers.Authorization = `token ${githubToken}`;
|
|
117
|
+
}
|
|
118
|
+
const response = await fetch(`https://api.github.com/users/${githubUser}/events?${queryParams}`, fetchOptions);
|
|
119
|
+
if (!response.ok) {
|
|
120
|
+
const errorText = await response.text();
|
|
121
|
+
console.error(`GitHub API error: ${response.status}`, errorText);
|
|
122
|
+
throw new Error(`GitHub API error: ${response.status} - ${errorText}`);
|
|
123
|
+
}
|
|
124
|
+
const data = await response.json();
|
|
125
|
+
console.log(`Page ${githubPage}: Received ${data.length} events`);
|
|
126
|
+
if (data.length === 0) {
|
|
127
|
+
hasMore = false;
|
|
128
|
+
} else {
|
|
129
|
+
allEvents = [...allEvents, ...data];
|
|
130
|
+
console.log(`Total events so far: ${allEvents.length}`);
|
|
131
|
+
|
|
132
|
+
// Check Link header to see if there are more pages
|
|
133
|
+
const linkHeader = response.headers.get('Link');
|
|
134
|
+
const links = parseLinkHeader(linkHeader);
|
|
135
|
+
hasMore = !!links.next; // Simplified logic
|
|
136
|
+
|
|
137
|
+
githubPage++;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
console.log(`Final total events: ${allEvents.length}`);
|
|
141
|
+
|
|
142
|
+
// Apply filters
|
|
143
|
+
let filteredEvents = allEvents;
|
|
144
|
+
if (repo) {
|
|
145
|
+
filteredEvents = filteredEvents.filter(event => event.repo.name === repo);
|
|
146
|
+
}
|
|
147
|
+
if (action) {
|
|
148
|
+
filteredEvents = filteredEvents.filter(event => {
|
|
149
|
+
const eventAction = event.type.replace('Event', '');
|
|
150
|
+
return eventAction === action;
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
if (date) {
|
|
154
|
+
const now = new Date();
|
|
155
|
+
let cutoffDate;
|
|
156
|
+
switch (date) {
|
|
157
|
+
case 'today':
|
|
158
|
+
cutoffDate = new Date(now.setHours(0, 0, 0, 0));
|
|
159
|
+
break;
|
|
160
|
+
case 'yesterday':
|
|
161
|
+
cutoffDate = new Date(now);
|
|
162
|
+
cutoffDate.setDate(cutoffDate.getDate() - 1);
|
|
163
|
+
cutoffDate.setHours(0, 0, 0, 0);
|
|
164
|
+
break;
|
|
165
|
+
case 'week':
|
|
166
|
+
cutoffDate = new Date(now);
|
|
167
|
+
cutoffDate.setDate(cutoffDate.getDate() - 7);
|
|
168
|
+
cutoffDate.setHours(0, 0, 0, 0);
|
|
169
|
+
break;
|
|
170
|
+
case 'month':
|
|
171
|
+
cutoffDate = new Date(now);
|
|
172
|
+
cutoffDate.setMonth(cutoffDate.getMonth() - 1);
|
|
173
|
+
cutoffDate.setHours(0, 0, 0, 0);
|
|
174
|
+
break;
|
|
175
|
+
default:
|
|
176
|
+
cutoffDate = new Date(0);
|
|
177
|
+
}
|
|
178
|
+
filteredEvents = filteredEvents.filter(event => {
|
|
179
|
+
const eventDate = new Date(event.created_at);
|
|
180
|
+
return eventDate >= cutoffDate;
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
if (description) {
|
|
184
|
+
filteredEvents = filteredEvents.filter(event => {
|
|
185
|
+
var _event$payload$commit, _event$payload$pull_r, _event$payload$issue, _event$payload$issue2;
|
|
186
|
+
let eventDescription = '';
|
|
187
|
+
if (event.type === 'PushEvent' && (_event$payload$commit = event.payload.commits) != null && _event$payload$commit.length) {
|
|
188
|
+
eventDescription = `Pushed ${event.payload.commits.length} commits`;
|
|
189
|
+
} else if (event.type === 'PullRequestEvent' && (_event$payload$pull_r = event.payload.pull_request) != null && _event$payload$pull_r.title) {
|
|
190
|
+
eventDescription = event.payload.pull_request.title;
|
|
191
|
+
} else if (event.type === 'IssuesEvent' && (_event$payload$issue = event.payload.issue) != null && _event$payload$issue.title) {
|
|
192
|
+
eventDescription = event.payload.issue.title;
|
|
193
|
+
} else if (event.type === 'IssueCommentEvent' && (_event$payload$issue2 = event.payload.issue) != null && _event$payload$issue2.title) {
|
|
194
|
+
eventDescription = `Commented on issue: ${event.payload.issue.title}`;
|
|
195
|
+
}
|
|
196
|
+
return eventDescription.toLowerCase().includes(description.toLowerCase());
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Calculate pagination
|
|
201
|
+
const pageNum = Number(page);
|
|
202
|
+
const perPage = Number(per_page);
|
|
203
|
+
const startIndex = (pageNum - 1) * perPage;
|
|
204
|
+
const endIndex = startIndex + perPage;
|
|
205
|
+
const paginatedEvents = filteredEvents.slice(startIndex, endIndex);
|
|
206
|
+
|
|
207
|
+
// Extract unique values for filters (only on first page)
|
|
208
|
+
const repositories = [...new Set(allEvents.map(event => event.repo.name))].sort();
|
|
209
|
+
const actionTypes = [...new Set(allEvents.map(event => event.type.replace('Event', '')))].sort();
|
|
210
|
+
|
|
211
|
+
// Return paginated results with metadata
|
|
212
|
+
return {
|
|
213
|
+
events: paginatedEvents,
|
|
214
|
+
total: filteredEvents.length,
|
|
215
|
+
repositories,
|
|
216
|
+
actionTypes,
|
|
217
|
+
page: pageNum,
|
|
218
|
+
per_page: perPage,
|
|
219
|
+
total_pages: Math.ceil(filteredEvents.length / perPage),
|
|
220
|
+
total_fetched_events: allEvents.length,
|
|
221
|
+
max_pages_fetched: githubPage - 1
|
|
222
|
+
};
|
|
223
|
+
} catch (error) {
|
|
224
|
+
console.error('Error fetching GitHub events:', error);
|
|
225
|
+
throw new Error(`${error instanceof Error ? error.message : String(error)}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
async function getEvents({
|
|
229
|
+
githubUser,
|
|
230
|
+
githubToken,
|
|
231
|
+
apiUrl = undefined,
|
|
232
|
+
query
|
|
233
|
+
}) {
|
|
234
|
+
const {
|
|
235
|
+
page,
|
|
236
|
+
perPage,
|
|
237
|
+
repo,
|
|
238
|
+
action,
|
|
239
|
+
description,
|
|
240
|
+
date
|
|
241
|
+
} = query;
|
|
242
|
+
console.log(`getEvents called - page: ${page}, perPage: ${perPage}`);
|
|
243
|
+
const queryParams = new URLSearchParams(_extends({
|
|
244
|
+
page: page.toString(),
|
|
245
|
+
per_page: perPage.toString()
|
|
246
|
+
}, repo && {
|
|
247
|
+
repo
|
|
248
|
+
}, action && {
|
|
249
|
+
action
|
|
250
|
+
}, date && {
|
|
251
|
+
date
|
|
252
|
+
}, description && {
|
|
253
|
+
description
|
|
254
|
+
}));
|
|
255
|
+
if (apiUrl) {
|
|
256
|
+
const url = apiUrl;
|
|
257
|
+
console.log(`Fetching from custom API URL: ${url}?${queryParams}`);
|
|
258
|
+
const response = await fetch(`${url}?${queryParams}`);
|
|
259
|
+
return response.json();
|
|
260
|
+
}
|
|
261
|
+
return githubEventsQuery({
|
|
262
|
+
query: {
|
|
263
|
+
page,
|
|
264
|
+
per_page: perPage,
|
|
265
|
+
repo,
|
|
266
|
+
action,
|
|
267
|
+
date,
|
|
268
|
+
description
|
|
269
|
+
},
|
|
270
|
+
githubUser,
|
|
271
|
+
githubToken
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
export function ErrorDetails({
|
|
275
|
+
error
|
|
276
|
+
}) {
|
|
277
|
+
const date = format(new Date(), 'MMM d, yyyy h:mm a');
|
|
278
|
+
const [errorDetails, setErrorDetails] = React.useState({
|
|
279
|
+
type: 'Error: Unknown Error',
|
|
280
|
+
message: 'Sorry but your princess is in another castle',
|
|
281
|
+
status: undefined
|
|
282
|
+
});
|
|
283
|
+
React.useEffect(() => {
|
|
284
|
+
if (error instanceof RequestError) {
|
|
285
|
+
var _error$response;
|
|
286
|
+
console.log('request error', error);
|
|
287
|
+
setErrorDetails({
|
|
288
|
+
type: 'Error: Request Error',
|
|
289
|
+
message: error.message,
|
|
290
|
+
status: (_error$response = error.response) == null ? void 0 : _error$response.status // Add optional chaining
|
|
291
|
+
});
|
|
292
|
+
} else if (typeof error === 'string') {
|
|
293
|
+
// Handle string errors
|
|
294
|
+
setErrorDetails({
|
|
295
|
+
type: 'Error',
|
|
296
|
+
message: error
|
|
297
|
+
});
|
|
298
|
+
} else {
|
|
299
|
+
// Fallback
|
|
300
|
+
setErrorDetails({
|
|
301
|
+
type: 'Unknown Error',
|
|
302
|
+
message: 'An unknown error occurred'
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
}, [error]);
|
|
306
|
+
return /*#__PURE__*/_jsxs(Box, {
|
|
307
|
+
sx: {
|
|
308
|
+
p: '8px',
|
|
309
|
+
display: 'content'
|
|
310
|
+
},
|
|
311
|
+
children: [/*#__PURE__*/_jsxs(Box, {
|
|
312
|
+
sx: {
|
|
313
|
+
display: 'flex',
|
|
314
|
+
alignItems: 'center',
|
|
315
|
+
gap: '16px'
|
|
316
|
+
},
|
|
317
|
+
children: [/*#__PURE__*/_jsx(Typography, {
|
|
318
|
+
variant: "caption",
|
|
319
|
+
color: "text.secondary",
|
|
320
|
+
children: date
|
|
321
|
+
}), _Chip || (_Chip = /*#__PURE__*/_jsx(Chip, {
|
|
322
|
+
label: 'Error',
|
|
323
|
+
size: "small",
|
|
324
|
+
color: "error"
|
|
325
|
+
}))]
|
|
326
|
+
}), /*#__PURE__*/_jsxs(Typography, {
|
|
327
|
+
variant: "h6",
|
|
328
|
+
component: "h3",
|
|
329
|
+
sx: {
|
|
330
|
+
mb: 1
|
|
331
|
+
},
|
|
332
|
+
children: [errorDetails.type, " ", errorDetails.status ? `(${errorDetails.status})` : '']
|
|
333
|
+
}), /*#__PURE__*/_jsx(Box, {
|
|
334
|
+
sx: {
|
|
335
|
+
alignItems: 'center'
|
|
336
|
+
},
|
|
337
|
+
children: /*#__PURE__*/_jsx(Typography, {
|
|
338
|
+
variant: "body2",
|
|
339
|
+
color: "text.secondary",
|
|
340
|
+
children: errorDetails.message
|
|
341
|
+
})
|
|
342
|
+
})]
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
const SmalMi = styled(MenuItem)({
|
|
346
|
+
fontSize: '12px'
|
|
347
|
+
});
|
|
348
|
+
export default function GithubEvents({
|
|
349
|
+
apiUrl,
|
|
350
|
+
eventsPerPage = 40,
|
|
351
|
+
hideMetadata = false,
|
|
352
|
+
githubUser,
|
|
353
|
+
githubToken
|
|
354
|
+
}) {
|
|
355
|
+
const [events, setEvents] = React.useState([]);
|
|
356
|
+
const [loading, setLoading] = React.useState(true);
|
|
357
|
+
const [error, setError] = React.useState(null);
|
|
358
|
+
const [repoFilter, setRepoFilter] = React.useState('');
|
|
359
|
+
const [actionFilter, setActionFilter] = React.useState('');
|
|
360
|
+
const [repositories, setRepositories] = React.useState([]);
|
|
361
|
+
const [actionTypes, setActionTypes] = React.useState([]);
|
|
362
|
+
const [dateFilter, setDateFilter] = React.useState('');
|
|
363
|
+
// @ts-ignore -- setter kept for future use
|
|
364
|
+
const [descriptionFilter, _setDescriptionFilter] = React.useState('');
|
|
365
|
+
// @ts-ignore -- state kept for future use
|
|
366
|
+
const [_descriptions, setDescriptions] = React.useState([]);
|
|
367
|
+
const [page, setPage] = React.useState(1);
|
|
368
|
+
const [totalCount, setTotalCount] = React.useState(0);
|
|
369
|
+
const [cachedEvents, setCachedEvents] = React.useState([]);
|
|
370
|
+
const [lastUpdated, setLastUpdated] = React.useState('');
|
|
371
|
+
const [selectedEvent, selectEvent] = React.useState({
|
|
372
|
+
id: ''
|
|
373
|
+
});
|
|
374
|
+
const theme = useTheme();
|
|
375
|
+
const scrollRef = React.useRef(null);
|
|
376
|
+
// @ts-ignore -- state kept for future use
|
|
377
|
+
const [_showAttached, setShowAttached] = React.useState(false);
|
|
378
|
+
// @ts-ignore -- state kept for future use
|
|
379
|
+
const [_scrollTop, setScrollTop] = React.useState(0);
|
|
380
|
+
const initializedRef = React.useRef(false);
|
|
381
|
+
const isFilterChangeRef = React.useRef(false);
|
|
382
|
+
const isPageChangeRef = React.useRef(false);
|
|
383
|
+
|
|
384
|
+
// Create a more specific cache key with consistent format
|
|
385
|
+
const cacheKey = React.useMemo(() => `github_events_${githubUser.toLowerCase()}`, [githubUser]);
|
|
386
|
+
|
|
387
|
+
// Add a ref to track if we've fetched from API in this session
|
|
388
|
+
const fetchedThisSessionRef = React.useRef(false);
|
|
389
|
+
|
|
390
|
+
// Debug function to clear cache (for development)
|
|
391
|
+
// const clearCache = () => {
|
|
392
|
+
// console.log(`Clearing cache for ${cacheKey}`);
|
|
393
|
+
// localStorage.removeItem(cacheKey);
|
|
394
|
+
// setCachedEvents([]);
|
|
395
|
+
// setEvents([]);
|
|
396
|
+
// fetchedThisSessionRef.current = false;
|
|
397
|
+
// initializedRef.current = false;
|
|
398
|
+
// };
|
|
399
|
+
|
|
400
|
+
React.useEffect(() => {
|
|
401
|
+
const el = scrollRef.current;
|
|
402
|
+
if (!el) return;
|
|
403
|
+
const onScroll = () => {
|
|
404
|
+
setScrollTop(el.scrollTop);
|
|
405
|
+
setShowAttached(true);
|
|
406
|
+
console.log(el.scrollTop);
|
|
407
|
+
|
|
408
|
+
// Hide after 1s of inactivity
|
|
409
|
+
clearTimeout(onScroll.hideTimeout);
|
|
410
|
+
onScroll.hideTimeout = setTimeout(() => {
|
|
411
|
+
setShowAttached(false);
|
|
412
|
+
}, 1000);
|
|
413
|
+
};
|
|
414
|
+
el.addEventListener('scroll', onScroll);
|
|
415
|
+
return () => el.removeEventListener('scroll', onScroll);
|
|
416
|
+
}, []);
|
|
417
|
+
const buildFilterOptionsFromEvents = events => {
|
|
418
|
+
const uniqueRepos = new Set();
|
|
419
|
+
const uniqueActions = new Set();
|
|
420
|
+
const uniqueDescriptions = new Set();
|
|
421
|
+
events.forEach(event => {
|
|
422
|
+
uniqueRepos.add(event.repo.name);
|
|
423
|
+
uniqueActions.add(event.type.replace('Event', ''));
|
|
424
|
+
if (event.payload) {
|
|
425
|
+
var _event$payload$commit2, _event$payload$pull_r2, _event$payload$issue3, _event$payload$issue4;
|
|
426
|
+
if (event.type === 'PushEvent' && (_event$payload$commit2 = event.payload.commits) != null && _event$payload$commit2.length) {
|
|
427
|
+
uniqueDescriptions.add(`Pushed ${event.payload.commits.length} commits`);
|
|
428
|
+
} else if (event.type === 'PullRequestEvent' && (_event$payload$pull_r2 = event.payload.pull_request) != null && _event$payload$pull_r2.title) {
|
|
429
|
+
uniqueDescriptions.add(event.payload.pull_request.title);
|
|
430
|
+
} else if (event.type === 'IssuesEvent' && (_event$payload$issue3 = event.payload.issue) != null && _event$payload$issue3.title) {
|
|
431
|
+
uniqueDescriptions.add(event.payload.issue.title);
|
|
432
|
+
} else if (event.type === 'IssueCommentEvent' && (_event$payload$issue4 = event.payload.issue) != null && _event$payload$issue4.title) {
|
|
433
|
+
uniqueDescriptions.add(`Commented on issue: ${event.payload.issue.title}`);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
setRepositories(Array.from(uniqueRepos).sort());
|
|
438
|
+
setActionTypes(Array.from(uniqueActions).sort());
|
|
439
|
+
setDescriptions(Array.from(uniqueDescriptions).sort());
|
|
440
|
+
};
|
|
441
|
+
const processEvents = rawEvents => {
|
|
442
|
+
console.log('Processing events, count:', rawEvents.length);
|
|
443
|
+
if (rawEvents.length === 0) {
|
|
444
|
+
console.log('No events to process');
|
|
445
|
+
return [];
|
|
446
|
+
}
|
|
447
|
+
try {
|
|
448
|
+
// Log sample event to debug format
|
|
449
|
+
if (rawEvents.length > 0) {
|
|
450
|
+
console.log('Sample raw event to process:', JSON.stringify(rawEvents[0]).substring(0, 500) + '...');
|
|
451
|
+
}
|
|
452
|
+
return rawEvents.map((event, index) => {
|
|
453
|
+
var _event$payload$commit3;
|
|
454
|
+
try {
|
|
455
|
+
var _event$repo2;
|
|
456
|
+
if (!event) {
|
|
457
|
+
console.error(`Event at index ${index} is undefined`);
|
|
458
|
+
return null;
|
|
459
|
+
}
|
|
460
|
+
if (!event.created_at) {
|
|
461
|
+
console.error(`Event at index ${index} missing created_at:`, event);
|
|
462
|
+
return null;
|
|
463
|
+
}
|
|
464
|
+
const dateTime = toZonedTime(parseISO(event.created_at), 'America/Chicago');
|
|
465
|
+
const date = format(dateTime, 'MM-dd-yyyy');
|
|
466
|
+
const formattedDate = format(dateTime, 'MMM d, yyyy h:mm a');
|
|
467
|
+
let action = '';
|
|
468
|
+
let description = '';
|
|
469
|
+
let link = '';
|
|
470
|
+
let id = event.id;
|
|
471
|
+
try {
|
|
472
|
+
switch (event.type) {
|
|
473
|
+
case 'PushEvent':
|
|
474
|
+
action = 'Push';
|
|
475
|
+
description = `Pushed ${((_event$payload$commit3 = event.payload.commits) == null ? void 0 : _event$payload$commit3.length) || 0} commits`;
|
|
476
|
+
link = `https://github.com/${event.repo.name}/commit/${event.payload.head}`;
|
|
477
|
+
break;
|
|
478
|
+
case 'PullRequestEvent':
|
|
479
|
+
action = 'Pull Request';
|
|
480
|
+
description = event.payload.pull_request.title;
|
|
481
|
+
link = event.payload.pull_request.html_url;
|
|
482
|
+
break;
|
|
483
|
+
case 'IssuesEvent':
|
|
484
|
+
action = 'Issue';
|
|
485
|
+
description = event.payload.issue.title;
|
|
486
|
+
link = event.payload.issue.html_url;
|
|
487
|
+
break;
|
|
488
|
+
case 'IssueCommentEvent':
|
|
489
|
+
action = 'Comment';
|
|
490
|
+
description = `Commented on issue: ${event.payload.issue.title}`;
|
|
491
|
+
link = event.payload.comment.html_url;
|
|
492
|
+
break;
|
|
493
|
+
default:
|
|
494
|
+
action = event.type.replace('Event', '');
|
|
495
|
+
description = '';
|
|
496
|
+
link = `https://github.com/${event.repo.name}`;
|
|
497
|
+
}
|
|
498
|
+
} catch (err) {
|
|
499
|
+
var _event$type, _event$repo;
|
|
500
|
+
console.error(`Error processing event type ${event.type} at index ${index}:`, err);
|
|
501
|
+
action = ((_event$type = event.type) == null ? void 0 : _event$type.replace('Event', '')) || 'Unknown';
|
|
502
|
+
description = 'Error processing event details';
|
|
503
|
+
link = (_event$repo = event.repo) != null && _event$repo.name ? `https://github.com/${event.repo.name}` : '';
|
|
504
|
+
}
|
|
505
|
+
const eventDetails = {
|
|
506
|
+
id: id || `event-${index}`,
|
|
507
|
+
date: formattedDate,
|
|
508
|
+
dateOnly: date,
|
|
509
|
+
repo: ((_event$repo2 = event.repo) == null ? void 0 : _event$repo2.name) || 'unknown-repo',
|
|
510
|
+
action,
|
|
511
|
+
actionType: event.type || 'UnknownEvent',
|
|
512
|
+
description,
|
|
513
|
+
url: link,
|
|
514
|
+
state: 'open',
|
|
515
|
+
user: '',
|
|
516
|
+
avatarUrl: '',
|
|
517
|
+
number: 0,
|
|
518
|
+
merged: false,
|
|
519
|
+
comments: 0,
|
|
520
|
+
commits: 0,
|
|
521
|
+
ref: '',
|
|
522
|
+
commitsList: [],
|
|
523
|
+
payload: event.payload
|
|
524
|
+
};
|
|
525
|
+
return eventDetails;
|
|
526
|
+
} catch (err) {
|
|
527
|
+
console.error(`Error processing event at index ${index}:`, err, event);
|
|
528
|
+
// Return a placeholder event to avoid breaking the UI
|
|
529
|
+
return {
|
|
530
|
+
id: `error-${index}`,
|
|
531
|
+
date: format(new Date(), 'MMM d, yyyy h:mm a'),
|
|
532
|
+
dateOnly: format(new Date(), 'MM-dd-yyyy'),
|
|
533
|
+
repo: 'Error processing event',
|
|
534
|
+
action: 'Error',
|
|
535
|
+
actionType: 'ErrorEvent',
|
|
536
|
+
description: err instanceof Error ? err.message : 'Unknown error',
|
|
537
|
+
url: '',
|
|
538
|
+
state: 'open',
|
|
539
|
+
user: '',
|
|
540
|
+
avatarUrl: '',
|
|
541
|
+
number: 0,
|
|
542
|
+
merged: false,
|
|
543
|
+
comments: 0,
|
|
544
|
+
commits: 0,
|
|
545
|
+
ref: '',
|
|
546
|
+
commitsList: [],
|
|
547
|
+
payload: {}
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
}).filter(Boolean); // Filter out any null values
|
|
551
|
+
} catch (err) {
|
|
552
|
+
console.error('Fatal error in processEvents:', err);
|
|
553
|
+
return [];
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
const filterEvents = events => {
|
|
557
|
+
return events.filter(event => {
|
|
558
|
+
const matchesRepo = !repoFilter || event.repo.name === repoFilter;
|
|
559
|
+
const matchesAction = !actionFilter || event.type.replace('Event', '') === actionFilter;
|
|
560
|
+
let matchesDescription = true;
|
|
561
|
+
if (descriptionFilter) {
|
|
562
|
+
const eventDescription = getEventDescription(event);
|
|
563
|
+
matchesDescription = eventDescription.includes(descriptionFilter);
|
|
564
|
+
}
|
|
565
|
+
if (dateFilter) {
|
|
566
|
+
const filterDate = getFilteredDate(dateFilter);
|
|
567
|
+
if (filterDate) {
|
|
568
|
+
const eventDate = new Date(event.created_at);
|
|
569
|
+
if (eventDate < filterDate) return false;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
return matchesRepo && matchesAction && matchesDescription;
|
|
573
|
+
});
|
|
574
|
+
};
|
|
575
|
+
const getEventDescription = event => {
|
|
576
|
+
if (event.type === 'PushEvent') {
|
|
577
|
+
var _event$payload$commit4;
|
|
578
|
+
return `Pushed ${((_event$payload$commit4 = event.payload.commits) == null ? void 0 : _event$payload$commit4.length) || 0} commits`;
|
|
579
|
+
} else if (event.type === 'PullRequestEvent') {
|
|
580
|
+
return event.payload.pull_request.title;
|
|
581
|
+
} else if (event.type === 'IssuesEvent') {
|
|
582
|
+
return event.payload.issue.title;
|
|
583
|
+
} else if (event.type === 'IssueCommentEvent') {
|
|
584
|
+
return `Commented on issue: ${event.payload.issue.title}`;
|
|
585
|
+
}
|
|
586
|
+
return '';
|
|
587
|
+
};
|
|
588
|
+
|
|
589
|
+
// Filter events based on date
|
|
590
|
+
const getFilteredDate = filter => {
|
|
591
|
+
const now = new Date();
|
|
592
|
+
switch (filter) {
|
|
593
|
+
case 'today':
|
|
594
|
+
return new Date(now.setHours(0, 0, 0, 0));
|
|
595
|
+
case 'yesterday':
|
|
596
|
+
{
|
|
597
|
+
const yesterday = new Date(now);
|
|
598
|
+
yesterday.setDate(yesterday.getDate() - 1);
|
|
599
|
+
return yesterday;
|
|
600
|
+
}
|
|
601
|
+
case 'week':
|
|
602
|
+
{
|
|
603
|
+
const weekAgo = new Date(now);
|
|
604
|
+
weekAgo.setDate(weekAgo.getDate() - 7);
|
|
605
|
+
return weekAgo;
|
|
606
|
+
}
|
|
607
|
+
default:
|
|
608
|
+
return null;
|
|
609
|
+
}
|
|
610
|
+
};
|
|
611
|
+
const fetchAllGitHubEvents = async () => {
|
|
612
|
+
// Skip if we've already fetched this session
|
|
613
|
+
if (fetchedThisSessionRef.current) {
|
|
614
|
+
console.log('Already fetched events this session, using cached data');
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
setLoading(true);
|
|
618
|
+
setError(null);
|
|
619
|
+
try {
|
|
620
|
+
console.log('Fetching ALL GitHub events (all pages)');
|
|
621
|
+
const allEvents = [];
|
|
622
|
+
let hasMore = true;
|
|
623
|
+
let pageNum = 1;
|
|
624
|
+
const maxPages = 10; // GitHub API typically limits to 10 pages max
|
|
625
|
+
|
|
626
|
+
while (hasMore && pageNum <= maxPages) {
|
|
627
|
+
console.log(`Fetching page ${pageNum} of GitHub events (100 per page)`);
|
|
628
|
+
const queryParams = _extends({
|
|
629
|
+
page: pageNum,
|
|
630
|
+
perPage: 100
|
|
631
|
+
}, repoFilter && {
|
|
632
|
+
repo: repoFilter
|
|
633
|
+
}, actionFilter && {
|
|
634
|
+
action: actionFilter
|
|
635
|
+
}, dateFilter && {
|
|
636
|
+
date: dateFilter
|
|
637
|
+
}, descriptionFilter && {
|
|
638
|
+
description: descriptionFilter
|
|
639
|
+
});
|
|
640
|
+
try {
|
|
641
|
+
console.log(`API call for page ${pageNum}`);
|
|
642
|
+
const data = await getEvents({
|
|
643
|
+
query: queryParams,
|
|
644
|
+
apiUrl,
|
|
645
|
+
githubUser,
|
|
646
|
+
githubToken
|
|
647
|
+
});
|
|
648
|
+
if (data.events && data.events.length > 0) {
|
|
649
|
+
console.log(`Received ${data.events.length} events for page ${pageNum}`);
|
|
650
|
+
allEvents.push(...data.events);
|
|
651
|
+
pageNum++;
|
|
652
|
+
console.log(`Total events so far: ${allEvents.length}`);
|
|
653
|
+
|
|
654
|
+
// Check if we've reached the end
|
|
655
|
+
if (data.events.length < 100) {
|
|
656
|
+
hasMore = false;
|
|
657
|
+
console.log('Received less than 100 events, reached the end');
|
|
658
|
+
}
|
|
659
|
+
} else {
|
|
660
|
+
hasMore = false;
|
|
661
|
+
console.log('Received 0 events, reached the end');
|
|
662
|
+
}
|
|
663
|
+
} catch (err) {
|
|
664
|
+
console.error(`Error fetching page ${pageNum}:`, err);
|
|
665
|
+
// Break the loop on error but don't fail the whole operation
|
|
666
|
+
hasMore = false;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
console.log(`Fetched a total of ${allEvents.length} events from ${pageNum - 1} pages`);
|
|
670
|
+
if (allEvents.length > 0) {
|
|
671
|
+
// Save all events to cache with user-specific key
|
|
672
|
+
setCachedEvents(allEvents);
|
|
673
|
+
localStorage.setItem(cacheKey, JSON.stringify({
|
|
674
|
+
events: allEvents,
|
|
675
|
+
lastFetched: Date.now(),
|
|
676
|
+
totalCount: allEvents.length
|
|
677
|
+
}));
|
|
678
|
+
|
|
679
|
+
// Mark that we've fetched this session
|
|
680
|
+
sessionStorage.setItem(`${cacheKey}_session_fetched`, 'true');
|
|
681
|
+
fetchedThisSessionRef.current = true;
|
|
682
|
+
|
|
683
|
+
// Update filter options with all data
|
|
684
|
+
buildFilterOptionsFromEvents(allEvents);
|
|
685
|
+
|
|
686
|
+
// Display first page
|
|
687
|
+
const filteredEvents = filterEvents(allEvents);
|
|
688
|
+
setTotalCount(filteredEvents.length);
|
|
689
|
+
const paginatedEvents = filteredEvents.slice(0, eventsPerPage);
|
|
690
|
+
const processedEvents = processEvents(paginatedEvents);
|
|
691
|
+
setEvents(processedEvents);
|
|
692
|
+
|
|
693
|
+
// Select the most recent event by default
|
|
694
|
+
if (processedEvents.length > 0) {
|
|
695
|
+
selectEvent(processedEvents[0]);
|
|
696
|
+
setTimeout(() => {
|
|
697
|
+
const firstRow = document.getElementById(processedEvents[0].id);
|
|
698
|
+
if (firstRow) {
|
|
699
|
+
firstRow.classList.add('selected');
|
|
700
|
+
}
|
|
701
|
+
}, 0);
|
|
702
|
+
}
|
|
703
|
+
} else {
|
|
704
|
+
console.log('No events found, setting empty state');
|
|
705
|
+
setEvents([]);
|
|
706
|
+
setTotalCount(0);
|
|
707
|
+
}
|
|
708
|
+
} catch (err) {
|
|
709
|
+
console.error('Error in fetchAllGitHubEvents:', err);
|
|
710
|
+
if (err instanceof RequestError) {
|
|
711
|
+
setError(err);
|
|
712
|
+
} else if (err instanceof Error) {
|
|
713
|
+
setError(err.message);
|
|
714
|
+
} else {
|
|
715
|
+
setError(String(err));
|
|
716
|
+
}
|
|
717
|
+
setEvents([]);
|
|
718
|
+
setTotalCount(0);
|
|
719
|
+
} finally {
|
|
720
|
+
setLoading(false);
|
|
721
|
+
}
|
|
722
|
+
};
|
|
723
|
+
const fetchNewEvents = async () => {
|
|
724
|
+
// Skip if we've already fetched this session
|
|
725
|
+
if (fetchedThisSessionRef.current) {
|
|
726
|
+
console.log('Already fetched events this session, using cached data');
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
setLoading(true);
|
|
730
|
+
try {
|
|
731
|
+
// First, get the most recent event date from our cache
|
|
732
|
+
let mostRecentDate = new Date(0);
|
|
733
|
+
if (cachedEvents.length > 0) {
|
|
734
|
+
mostRecentDate = new Date(Math.max(...cachedEvents.map(e => new Date(e.created_at).getTime())));
|
|
735
|
+
}
|
|
736
|
+
console.log('Fetching new events since', format(mostRecentDate, 'MMM d, yyyy h:mm a'));
|
|
737
|
+
|
|
738
|
+
// Fetch all new events
|
|
739
|
+
let allNewEvents = [];
|
|
740
|
+
let hasMore = true;
|
|
741
|
+
let pageNum = 1;
|
|
742
|
+
const maxPages = 10; // GitHub API typically limits to 10 pages max
|
|
743
|
+
|
|
744
|
+
while (hasMore && pageNum <= maxPages) {
|
|
745
|
+
const query = {
|
|
746
|
+
page: pageNum,
|
|
747
|
+
perPage: 100 // Maximum allowed by GitHub API
|
|
748
|
+
};
|
|
749
|
+
console.log(`Fetching page ${pageNum} of new events (100 per page)`);
|
|
750
|
+
try {
|
|
751
|
+
const data = await getEvents({
|
|
752
|
+
apiUrl,
|
|
753
|
+
githubUser,
|
|
754
|
+
githubToken,
|
|
755
|
+
query
|
|
756
|
+
});
|
|
757
|
+
if (data.events && data.events.length > 0) {
|
|
758
|
+
// Check if we've reached events we already have
|
|
759
|
+
const allOldEvents = data.events.every(event => {
|
|
760
|
+
const eventDate = new Date(event.created_at);
|
|
761
|
+
return eventDate <= mostRecentDate;
|
|
762
|
+
});
|
|
763
|
+
if (allOldEvents) {
|
|
764
|
+
console.log('All events on this page are already in cache, stopping fetch');
|
|
765
|
+
hasMore = false;
|
|
766
|
+
} else {
|
|
767
|
+
// Filter out events older than our most recent cached event
|
|
768
|
+
const newEvents = data.events.filter(event => {
|
|
769
|
+
const eventDate = new Date(event.created_at);
|
|
770
|
+
return eventDate > mostRecentDate;
|
|
771
|
+
});
|
|
772
|
+
allNewEvents.push(...newEvents);
|
|
773
|
+
console.log(`Found ${newEvents.length} new events on page ${pageNum}`);
|
|
774
|
+
if (data.events.length < 100) {
|
|
775
|
+
console.log('Received less than 100 events, reached the end');
|
|
776
|
+
hasMore = false;
|
|
777
|
+
}
|
|
778
|
+
pageNum++;
|
|
779
|
+
}
|
|
780
|
+
} else {
|
|
781
|
+
hasMore = false;
|
|
782
|
+
console.log('Received 0 events, reached the end');
|
|
783
|
+
}
|
|
784
|
+
} catch (err) {
|
|
785
|
+
console.error(`Error fetching page ${pageNum} in fetchNewEvents:`, err);
|
|
786
|
+
hasMore = false; // Stop on error but continue processing what we've got
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
if (allNewEvents.length > 0) {
|
|
790
|
+
console.log(`Fetched ${allNewEvents.length} new events`);
|
|
791
|
+
|
|
792
|
+
// Combine with existing events and sort by date (newest first)
|
|
793
|
+
const updatedEvents = [...allNewEvents, ...cachedEvents];
|
|
794
|
+
updatedEvents.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
|
|
795
|
+
|
|
796
|
+
// Mark that we've fetched this session
|
|
797
|
+
sessionStorage.setItem(`${cacheKey}_session_fetched`, 'true');
|
|
798
|
+
fetchedThisSessionRef.current = true;
|
|
799
|
+
|
|
800
|
+
// Update cache with new events using user-specific key
|
|
801
|
+
setCachedEvents(updatedEvents);
|
|
802
|
+
localStorage.setItem(cacheKey, JSON.stringify({
|
|
803
|
+
events: updatedEvents,
|
|
804
|
+
lastFetched: Date.now(),
|
|
805
|
+
totalCount: updatedEvents.length
|
|
806
|
+
}));
|
|
807
|
+
|
|
808
|
+
// Update UI
|
|
809
|
+
buildFilterOptionsFromEvents(updatedEvents);
|
|
810
|
+
|
|
811
|
+
// Display first page with updated data
|
|
812
|
+
const filteredEvents = filterEvents(updatedEvents);
|
|
813
|
+
setTotalCount(filteredEvents.length);
|
|
814
|
+
const paginatedEvents = filteredEvents.slice(0, eventsPerPage);
|
|
815
|
+
const processedEvents = processEvents(paginatedEvents);
|
|
816
|
+
setEvents(processedEvents);
|
|
817
|
+
setLastUpdated(format(new Date(), 'MMM d, yyyy h:mm a'));
|
|
818
|
+
console.log('Updated display with new events');
|
|
819
|
+
} else {
|
|
820
|
+
console.log('No new events found');
|
|
821
|
+
|
|
822
|
+
// Mark that we've fetched this session even if no new events
|
|
823
|
+
sessionStorage.setItem(`${cacheKey}_session_fetched`, 'true');
|
|
824
|
+
fetchedThisSessionRef.current = true;
|
|
825
|
+
|
|
826
|
+
// Just update the last fetched time with user-specific key
|
|
827
|
+
const currentCache = JSON.parse(localStorage.getItem(cacheKey) || '{}');
|
|
828
|
+
localStorage.setItem(cacheKey, JSON.stringify(_extends({}, currentCache, {
|
|
829
|
+
lastFetched: Date.now()
|
|
830
|
+
})));
|
|
831
|
+
setLastUpdated(format(new Date(), 'MMM d, yyyy h:mm a'));
|
|
832
|
+
|
|
833
|
+
// Use existing cached data for display
|
|
834
|
+
const filteredEvents = filterEvents(cachedEvents);
|
|
835
|
+
const paginatedEvents = filteredEvents.slice(0, eventsPerPage);
|
|
836
|
+
const processedEvents = processEvents(paginatedEvents);
|
|
837
|
+
console.log('Using existing events for display, count:', processedEvents.length);
|
|
838
|
+
setEvents(processedEvents);
|
|
839
|
+
}
|
|
840
|
+
} catch (err) {
|
|
841
|
+
console.error('Failed to fetch new events:', err);
|
|
842
|
+
if (err instanceof RequestError) {
|
|
843
|
+
setError(err);
|
|
844
|
+
} else if (err instanceof Error) {
|
|
845
|
+
setError(err.message);
|
|
846
|
+
} else {
|
|
847
|
+
setError(String(err));
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
// Use existing cached data for display if available
|
|
851
|
+
if (cachedEvents.length > 0) {
|
|
852
|
+
console.log('Using existing cached data after error');
|
|
853
|
+
const filteredEvents = filterEvents(cachedEvents);
|
|
854
|
+
const paginatedEvents = filteredEvents.slice(0, eventsPerPage);
|
|
855
|
+
const processedEvents = processEvents(paginatedEvents);
|
|
856
|
+
setEvents(processedEvents);
|
|
857
|
+
}
|
|
858
|
+
} finally {
|
|
859
|
+
setLoading(false);
|
|
860
|
+
}
|
|
861
|
+
};
|
|
862
|
+
const fetchGitHubEvents = async (pageNum = 1, isFilterChange = false) => {
|
|
863
|
+
// Always use cached data for pagination and filtering
|
|
864
|
+
if (cachedEvents.length > 0) {
|
|
865
|
+
console.log(`Using ${cachedEvents.length} cached events for pagination/filtering (page ${pageNum})`);
|
|
866
|
+
setLoading(true);
|
|
867
|
+
try {
|
|
868
|
+
const filteredCachedEvents = filterEvents(cachedEvents);
|
|
869
|
+
console.log('Filtered cached events:', filteredCachedEvents.length);
|
|
870
|
+
const startIndex = (pageNum - 1) * eventsPerPage;
|
|
871
|
+
const endIndex = startIndex + eventsPerPage;
|
|
872
|
+
const paginatedEvents = filteredCachedEvents.slice(startIndex, endIndex);
|
|
873
|
+
console.log(`Showing events ${startIndex + 1}-${Math.min(endIndex, filteredCachedEvents.length)} of ${filteredCachedEvents.length}`);
|
|
874
|
+
const processedEvents = processEvents(paginatedEvents);
|
|
875
|
+
console.log('Processed events count:', processedEvents.length);
|
|
876
|
+
setEvents(processedEvents);
|
|
877
|
+
setTotalCount(filteredCachedEvents.length);
|
|
878
|
+
|
|
879
|
+
// Select the most recent event by default if none selected
|
|
880
|
+
if (processedEvents.length > 0 && !selectedEvent.id) {
|
|
881
|
+
selectEvent(processedEvents[0]);
|
|
882
|
+
setTimeout(() => {
|
|
883
|
+
const firstRow = document.getElementById(processedEvents[0].id);
|
|
884
|
+
if (firstRow) {
|
|
885
|
+
firstRow.classList.add('selected');
|
|
886
|
+
}
|
|
887
|
+
}, 0);
|
|
888
|
+
}
|
|
889
|
+
} catch (err) {
|
|
890
|
+
console.error('Error processing cached events:', err);
|
|
891
|
+
if (err instanceof RequestError) {
|
|
892
|
+
setError(err);
|
|
893
|
+
} else if (err instanceof Error) {
|
|
894
|
+
setError(err.message);
|
|
895
|
+
} else {
|
|
896
|
+
setError(String(err));
|
|
897
|
+
}
|
|
898
|
+
} finally {
|
|
899
|
+
setLoading(false);
|
|
900
|
+
}
|
|
901
|
+
return;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
// If we don't have cached data, fetch from API
|
|
905
|
+
console.log('No cached data available in component state, fetching from API');
|
|
906
|
+
fetchAllGitHubEvents();
|
|
907
|
+
};
|
|
908
|
+
|
|
909
|
+
// Single initialization effect to handle all initial data loading
|
|
910
|
+
React.useEffect(() => {
|
|
911
|
+
// Skip if already initialized
|
|
912
|
+
if (initializedRef.current) {
|
|
913
|
+
console.log('Component already initialized, skipping initialization');
|
|
914
|
+
return;
|
|
915
|
+
}
|
|
916
|
+
initializedRef.current = true;
|
|
917
|
+
console.log('Initializing GithubEvents component once');
|
|
918
|
+
console.log(`Using cache key: "${cacheKey}" for GitHub user: ${githubUser}`);
|
|
919
|
+
|
|
920
|
+
// Check session storage to see if we've already fetched this session
|
|
921
|
+
const sessionKey = `${cacheKey}_session_fetched`;
|
|
922
|
+
const fetchedThisSession = sessionStorage.getItem(sessionKey) === 'true';
|
|
923
|
+
console.log('Already fetched this session:', fetchedThisSession);
|
|
924
|
+
fetchedThisSessionRef.current = fetchedThisSession;
|
|
925
|
+
|
|
926
|
+
// Debug all localStorage keys to make sure we're looking at the right one
|
|
927
|
+
console.log('All localStorage keys:', Object.keys(localStorage));
|
|
928
|
+
const cached = localStorage.getItem(cacheKey);
|
|
929
|
+
console.log(`LocalStorage for "${cacheKey}" exists:`, !!cached);
|
|
930
|
+
if (cached) {
|
|
931
|
+
try {
|
|
932
|
+
const parsedCache = JSON.parse(cached);
|
|
933
|
+
console.log('Cache parsed successfully, events count:', parsedCache.events.length);
|
|
934
|
+
console.log('Last fetch time:', new Date(parsedCache.lastFetched).toLocaleString());
|
|
935
|
+
if (!Array.isArray(parsedCache.events) || parsedCache.events.length === 0) {
|
|
936
|
+
console.log('Cached events array is empty or invalid, fetching all events');
|
|
937
|
+
fetchAllGitHubEvents();
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
// Set cached events state
|
|
942
|
+
setCachedEvents(parsedCache.events);
|
|
943
|
+
setTotalCount(parsedCache.totalCount || parsedCache.events.length);
|
|
944
|
+
buildFilterOptionsFromEvents(parsedCache.events);
|
|
945
|
+
|
|
946
|
+
// Format last updated time
|
|
947
|
+
const lastFetchDate = new Date(parsedCache.lastFetched);
|
|
948
|
+
setLastUpdated(format(lastFetchDate, 'MMM d, yyyy h:mm a'));
|
|
949
|
+
|
|
950
|
+
// Check if we should refresh cache (if it's been more than 8 hours and we haven't fetched this session)
|
|
951
|
+
const hoursSinceLastFetch = (Date.now() - parsedCache.lastFetched) / (1000 * 60 * 60);
|
|
952
|
+
console.log('Hours since last fetch:', hoursSinceLastFetch.toFixed(2));
|
|
953
|
+
console.log('Should refresh cache:', hoursSinceLastFetch >= 8 && !fetchedThisSession);
|
|
954
|
+
|
|
955
|
+
// Apply initial filtering to cached events and display them first
|
|
956
|
+
const filteredCachedEvents = filterEvents(parsedCache.events);
|
|
957
|
+
console.log('Filtered events count:', filteredCachedEvents.length);
|
|
958
|
+
const paginatedEvents = filteredCachedEvents.slice(0, eventsPerPage);
|
|
959
|
+
console.log('Paginated events for display:', paginatedEvents.length);
|
|
960
|
+
const processedEvents = processEvents(paginatedEvents);
|
|
961
|
+
setEvents(processedEvents);
|
|
962
|
+
setLoading(false);
|
|
963
|
+
|
|
964
|
+
// Only fetch new events if it's been more than 8 hours AND we haven't fetched this session
|
|
965
|
+
if (hoursSinceLastFetch >= 8 && !fetchedThisSession) {
|
|
966
|
+
console.log('Cache is stale (>= 8 hours old), fetching new events in background');
|
|
967
|
+
// Fetch new events in background
|
|
968
|
+
setTimeout(() => {
|
|
969
|
+
fetchNewEvents();
|
|
970
|
+
// Mark that we've fetched this session
|
|
971
|
+
sessionStorage.setItem(sessionKey, 'true');
|
|
972
|
+
fetchedThisSessionRef.current = true;
|
|
973
|
+
}, 100);
|
|
974
|
+
} else {
|
|
975
|
+
console.log('Using cached events, no need to refresh');
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
// Select the most recent event by default
|
|
979
|
+
if (processedEvents.length > 0) {
|
|
980
|
+
selectEvent(processedEvents[0]);
|
|
981
|
+
setTimeout(() => {
|
|
982
|
+
const firstRow = document.getElementById(processedEvents[0].id);
|
|
983
|
+
if (firstRow) {
|
|
984
|
+
firstRow.classList.add('selected');
|
|
985
|
+
}
|
|
986
|
+
}, 0);
|
|
987
|
+
} else {
|
|
988
|
+
console.log('No events to display after filtering/pagination');
|
|
989
|
+
}
|
|
990
|
+
} catch (err) {
|
|
991
|
+
console.error('Failed to parse cached events, fetching new data:', err);
|
|
992
|
+
fetchAllGitHubEvents();
|
|
993
|
+
}
|
|
994
|
+
} else {
|
|
995
|
+
console.log('No cache found, fetching ALL GitHub events for first time');
|
|
996
|
+
fetchAllGitHubEvents();
|
|
997
|
+
}
|
|
998
|
+
}, [cacheKey, githubUser, eventsPerPage]);
|
|
999
|
+
|
|
1000
|
+
// Update the filter and pagination effect handlers
|
|
1001
|
+
React.useEffect(() => {
|
|
1002
|
+
// Skip the first render and only respond to actual filter changes
|
|
1003
|
+
if (!initializedRef.current) {
|
|
1004
|
+
console.log('Filter change ignored - component not initialized yet');
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
1007
|
+
if (!isFilterChangeRef.current) {
|
|
1008
|
+
console.log('First filter change detected, just setting flag');
|
|
1009
|
+
isFilterChangeRef.current = true;
|
|
1010
|
+
return;
|
|
1011
|
+
}
|
|
1012
|
+
console.log('Filter changed, updating events with the following filters:');
|
|
1013
|
+
console.log(' Repository:', repoFilter || 'None');
|
|
1014
|
+
console.log(' Action type:', actionFilter || 'None');
|
|
1015
|
+
console.log(' Date filter:', dateFilter || 'None');
|
|
1016
|
+
console.log(' Description:', descriptionFilter || 'None');
|
|
1017
|
+
if (page !== 1) {
|
|
1018
|
+
console.log('Resetting to page 1 due to filter change');
|
|
1019
|
+
setPage(1);
|
|
1020
|
+
} else {
|
|
1021
|
+
console.log('Already on page 1, applying filters');
|
|
1022
|
+
fetchGitHubEvents(1, true);
|
|
1023
|
+
}
|
|
1024
|
+
}, [repoFilter, actionFilter, dateFilter, descriptionFilter]);
|
|
1025
|
+
|
|
1026
|
+
// Unified effect to handle page changes
|
|
1027
|
+
React.useEffect(() => {
|
|
1028
|
+
// Skip the first render and only respond to actual page changes
|
|
1029
|
+
if (!initializedRef.current) {
|
|
1030
|
+
console.log('Page change ignored - component not initialized yet');
|
|
1031
|
+
return;
|
|
1032
|
+
}
|
|
1033
|
+
if (!isPageChangeRef.current) {
|
|
1034
|
+
console.log('First page change detected, just setting flag');
|
|
1035
|
+
isPageChangeRef.current = true;
|
|
1036
|
+
return;
|
|
1037
|
+
}
|
|
1038
|
+
console.log(`Page changed to ${page}, fetching events`);
|
|
1039
|
+
fetchGitHubEvents(page, false);
|
|
1040
|
+
}, [page]);
|
|
1041
|
+
const totalPages = React.useMemo(() => {
|
|
1042
|
+
return Math.ceil(totalCount / eventsPerPage);
|
|
1043
|
+
}, [totalCount]);
|
|
1044
|
+
const getTimeOnly = date => {
|
|
1045
|
+
const parsed = parse(date, 'MMM d, yyyy h:mm a', new Date());
|
|
1046
|
+
return format(parsed, 'h:mm a');
|
|
1047
|
+
};
|
|
1048
|
+
let latestDateDisplayed = null;
|
|
1049
|
+
return /*#__PURE__*/_jsxs(Box, {
|
|
1050
|
+
sx: {
|
|
1051
|
+
display: 'flex',
|
|
1052
|
+
flexDirection: 'column',
|
|
1053
|
+
gap: 1
|
|
1054
|
+
},
|
|
1055
|
+
children: [/*#__PURE__*/_jsxs(Box, {
|
|
1056
|
+
sx: {
|
|
1057
|
+
mb: 1,
|
|
1058
|
+
display: 'flex',
|
|
1059
|
+
justifyContent: 'space-between',
|
|
1060
|
+
alignItems: 'end'
|
|
1061
|
+
},
|
|
1062
|
+
children: [/*#__PURE__*/_jsxs(Box, {
|
|
1063
|
+
sx: {
|
|
1064
|
+
display: 'flex',
|
|
1065
|
+
gap: .5,
|
|
1066
|
+
flexDirection: 'column'
|
|
1067
|
+
},
|
|
1068
|
+
children: [/*#__PURE__*/_jsxs(Typography, {
|
|
1069
|
+
variant: "subtitle1",
|
|
1070
|
+
fontWeight: "semiBold",
|
|
1071
|
+
children: [githubUser, "'s Events"]
|
|
1072
|
+
}), lastUpdated && /*#__PURE__*/_jsxs(Typography, {
|
|
1073
|
+
variant: "caption",
|
|
1074
|
+
color: "text.secondary",
|
|
1075
|
+
children: ["Last updated: ", lastUpdated]
|
|
1076
|
+
})]
|
|
1077
|
+
}), totalCount > eventsPerPage && /*#__PURE__*/_jsx(Pagination, {
|
|
1078
|
+
count: totalPages,
|
|
1079
|
+
page: page,
|
|
1080
|
+
onChange: (_, value) => setPage(value),
|
|
1081
|
+
size: "small",
|
|
1082
|
+
sx: {
|
|
1083
|
+
'& .MuiPaginationItem-root': {
|
|
1084
|
+
color: theme.palette.text.secondary,
|
|
1085
|
+
borderColor: theme.palette.divider
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
})]
|
|
1089
|
+
}), /*#__PURE__*/_jsxs(Box, {
|
|
1090
|
+
sx: {
|
|
1091
|
+
display: 'flex',
|
|
1092
|
+
gap: '8px',
|
|
1093
|
+
'& .metadata-display': {
|
|
1094
|
+
width: 'max-content',
|
|
1095
|
+
display: 'flex',
|
|
1096
|
+
padding: '0px'
|
|
1097
|
+
},
|
|
1098
|
+
'@media (max-width:813px)': {
|
|
1099
|
+
'& .metadata-display': {
|
|
1100
|
+
display: 'none'
|
|
1101
|
+
}
|
|
1102
|
+
},
|
|
1103
|
+
'@media (max-width:340px)': {
|
|
1104
|
+
'& .metadata-display': {
|
|
1105
|
+
display: 'none'
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
},
|
|
1109
|
+
children: [/*#__PURE__*/_jsx(Box, {
|
|
1110
|
+
sx: {
|
|
1111
|
+
minWidth: '340px',
|
|
1112
|
+
flexShrink: 0,
|
|
1113
|
+
display: 'block',
|
|
1114
|
+
position: 'relative'
|
|
1115
|
+
},
|
|
1116
|
+
className: "master-container",
|
|
1117
|
+
children: /*#__PURE__*/_jsx(TableContainer, {
|
|
1118
|
+
component: Paper,
|
|
1119
|
+
sx: {
|
|
1120
|
+
mb: 4,
|
|
1121
|
+
borderRadius: 0,
|
|
1122
|
+
position: 'relative'
|
|
1123
|
+
},
|
|
1124
|
+
className: "overflow-visible",
|
|
1125
|
+
children: /*#__PURE__*/_jsxs(Table, {
|
|
1126
|
+
size: "small",
|
|
1127
|
+
children: [/*#__PURE__*/_jsx(TableHead, {
|
|
1128
|
+
sx: {
|
|
1129
|
+
padding: '6px 8px'
|
|
1130
|
+
},
|
|
1131
|
+
children: /*#__PURE__*/_jsxs(TableRow, {
|
|
1132
|
+
sx: {
|
|
1133
|
+
padding: '6px 8px'
|
|
1134
|
+
},
|
|
1135
|
+
children: [/*#__PURE__*/_jsx(TableCell, {
|
|
1136
|
+
sx: {
|
|
1137
|
+
padding: '6px 8px'
|
|
1138
|
+
},
|
|
1139
|
+
children: /*#__PURE__*/_jsxs(Box, {
|
|
1140
|
+
sx: {
|
|
1141
|
+
display: 'flex',
|
|
1142
|
+
flexDirection: 'column',
|
|
1143
|
+
gap: 1
|
|
1144
|
+
},
|
|
1145
|
+
children: ["Date", /*#__PURE__*/_jsx(FormControl, {
|
|
1146
|
+
size: "small",
|
|
1147
|
+
fullWidth: true,
|
|
1148
|
+
children: /*#__PURE__*/_jsxs(Select, {
|
|
1149
|
+
value: dateFilter,
|
|
1150
|
+
onChange: e => setDateFilter(e.target.value),
|
|
1151
|
+
displayEmpty: true,
|
|
1152
|
+
sx: {
|
|
1153
|
+
'& .MuiSelect-select': {
|
|
1154
|
+
py: 0.5,
|
|
1155
|
+
fontSize: '12px'
|
|
1156
|
+
}
|
|
1157
|
+
},
|
|
1158
|
+
children: [_SmalMi || (_SmalMi = /*#__PURE__*/_jsx(SmalMi, {
|
|
1159
|
+
value: "",
|
|
1160
|
+
children: "All time"
|
|
1161
|
+
})), _SmalMi2 || (_SmalMi2 = /*#__PURE__*/_jsx(SmalMi, {
|
|
1162
|
+
value: "today",
|
|
1163
|
+
children: "Today"
|
|
1164
|
+
})), _SmalMi3 || (_SmalMi3 = /*#__PURE__*/_jsx(SmalMi, {
|
|
1165
|
+
value: "yesterday",
|
|
1166
|
+
children: "Yesterday"
|
|
1167
|
+
})), _SmalMi4 || (_SmalMi4 = /*#__PURE__*/_jsx(SmalMi, {
|
|
1168
|
+
value: "week",
|
|
1169
|
+
children: "Week"
|
|
1170
|
+
})), _SmalMi5 || (_SmalMi5 = /*#__PURE__*/_jsx(SmalMi, {
|
|
1171
|
+
value: "month",
|
|
1172
|
+
children: "Month"
|
|
1173
|
+
}))]
|
|
1174
|
+
})
|
|
1175
|
+
})]
|
|
1176
|
+
})
|
|
1177
|
+
}), /*#__PURE__*/_jsx(TableCell, {
|
|
1178
|
+
children: /*#__PURE__*/_jsxs(Box, {
|
|
1179
|
+
sx: {
|
|
1180
|
+
display: 'flex',
|
|
1181
|
+
flexDirection: 'column',
|
|
1182
|
+
gap: 1
|
|
1183
|
+
},
|
|
1184
|
+
children: ["Repository", /*#__PURE__*/_jsx(Autocomplete, {
|
|
1185
|
+
size: "small",
|
|
1186
|
+
options: repositories,
|
|
1187
|
+
value: repoFilter,
|
|
1188
|
+
onChange: (_, newValue) => setRepoFilter(newValue || ''),
|
|
1189
|
+
renderInput: params => /*#__PURE__*/_jsx(TextField, _extends({}, params, {
|
|
1190
|
+
placeholder: "All",
|
|
1191
|
+
sx: {
|
|
1192
|
+
'& .MuiInputBase-root': {
|
|
1193
|
+
height: '32px',
|
|
1194
|
+
minHeight: '32px',
|
|
1195
|
+
fontSize: '12px',
|
|
1196
|
+
p: '0 8px',
|
|
1197
|
+
'& input': {
|
|
1198
|
+
p: '2.5px 4px'
|
|
1199
|
+
},
|
|
1200
|
+
'& fieldset': {
|
|
1201
|
+
borderColor: 'rgba(255, 255, 255, 0.23)'
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
})),
|
|
1206
|
+
slotProps: {
|
|
1207
|
+
paper: {
|
|
1208
|
+
sx: {
|
|
1209
|
+
fontSize: '12px!important',
|
|
1210
|
+
'& .MuiAutocomplete-listbox': {
|
|
1211
|
+
'& .MuiAutocomplete-option': {
|
|
1212
|
+
whiteSpace: 'nowrap',
|
|
1213
|
+
overflow: 'visible',
|
|
1214
|
+
textOverflow: 'ellipsis',
|
|
1215
|
+
fontSize: '12px!important',
|
|
1216
|
+
width: '100%'
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
},
|
|
1222
|
+
freeSolo: true,
|
|
1223
|
+
selectOnFocus: true,
|
|
1224
|
+
clearOnBlur: true,
|
|
1225
|
+
sx: {
|
|
1226
|
+
'& .MuiOutlinedInput-root': {
|
|
1227
|
+
p: 0
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
})]
|
|
1231
|
+
})
|
|
1232
|
+
}), /*#__PURE__*/_jsx(TableCell, {
|
|
1233
|
+
children: /*#__PURE__*/_jsxs(Box, {
|
|
1234
|
+
sx: {
|
|
1235
|
+
display: 'flex',
|
|
1236
|
+
flexDirection: 'column',
|
|
1237
|
+
gap: 1
|
|
1238
|
+
},
|
|
1239
|
+
children: ["Type", /*#__PURE__*/_jsx(Autocomplete, {
|
|
1240
|
+
size: "small",
|
|
1241
|
+
options: actionTypes,
|
|
1242
|
+
value: actionFilter,
|
|
1243
|
+
onChange: (_, newValue) => setActionFilter(newValue || ''),
|
|
1244
|
+
renderInput: params => /*#__PURE__*/_jsx(TextField, _extends({}, params, {
|
|
1245
|
+
placeholder: "All",
|
|
1246
|
+
sx: {
|
|
1247
|
+
'& .MuiInputBase-root': {
|
|
1248
|
+
height: '32px',
|
|
1249
|
+
minHeight: '32px',
|
|
1250
|
+
fontSize: '12px',
|
|
1251
|
+
p: '0 8px',
|
|
1252
|
+
'& input': {
|
|
1253
|
+
p: '2.5px 4px'
|
|
1254
|
+
},
|
|
1255
|
+
'& fieldset': {
|
|
1256
|
+
borderColor: 'rgba(255, 255, 255, 0.23)'
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
})),
|
|
1261
|
+
freeSolo: true,
|
|
1262
|
+
selectOnFocus: true,
|
|
1263
|
+
clearOnBlur: true,
|
|
1264
|
+
slotProps: {
|
|
1265
|
+
paper: {
|
|
1266
|
+
sx: {
|
|
1267
|
+
fontSize: '12px!important',
|
|
1268
|
+
'& .MuiAutocomplete-listbox': {
|
|
1269
|
+
'& .MuiAutocomplete-option': {
|
|
1270
|
+
whiteSpace: 'nowrap',
|
|
1271
|
+
overflow: 'hidden',
|
|
1272
|
+
textOverflow: 'ellipsis',
|
|
1273
|
+
fontSize: '12px!important'
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
},
|
|
1279
|
+
sx: {
|
|
1280
|
+
'& .MuiOutlinedInput-root': {
|
|
1281
|
+
p: 0
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
})]
|
|
1285
|
+
})
|
|
1286
|
+
})]
|
|
1287
|
+
})
|
|
1288
|
+
}), /*#__PURE__*/_jsxs(TableBody, {
|
|
1289
|
+
sx: {
|
|
1290
|
+
cursor: 'pointer',
|
|
1291
|
+
'& tr:hover td': {
|
|
1292
|
+
backgroundColor: theme.palette.action.hover
|
|
1293
|
+
}
|
|
1294
|
+
},
|
|
1295
|
+
children: [events.map((event, index) => {
|
|
1296
|
+
const showDateRow = event.dateOnly !== latestDateDisplayed;
|
|
1297
|
+
latestDateDisplayed = event.dateOnly;
|
|
1298
|
+
return /*#__PURE__*/_jsxs(React.Fragment, {
|
|
1299
|
+
children: [showDateRow && /*#__PURE__*/_jsx(TableRow, {
|
|
1300
|
+
style: {
|
|
1301
|
+
backgroundColor: theme.palette.mode === 'light' ? 'color-mix(in oklab, rgba(0, 97, 194, 0.5) 25%, rgba(235, 235, 235, 0.5))' : 'color-mix(in oklab, rgba(102, 179, 255, 0.5) 25%, rgba(31, 31, 31, 0.5))'
|
|
1302
|
+
},
|
|
1303
|
+
children: /*#__PURE__*/_jsx(TableCell, {
|
|
1304
|
+
colSpan: 4,
|
|
1305
|
+
children: /*#__PURE__*/_jsx(Typography, {
|
|
1306
|
+
variant: "subtitle2",
|
|
1307
|
+
fontWeight: "semiBold",
|
|
1308
|
+
children: event.dateOnly
|
|
1309
|
+
})
|
|
1310
|
+
})
|
|
1311
|
+
}), /*#__PURE__*/_jsxs(TableRow, {
|
|
1312
|
+
id: event.id,
|
|
1313
|
+
sx: {
|
|
1314
|
+
'& td': {
|
|
1315
|
+
backgroundColor: theme.palette.background.paper,
|
|
1316
|
+
transition: 'all 1s cubic-bezier(1.1, 1.4, 2.1, 1.1, 0.8, 0.7,0.6,0.5,0.4,0.3,0.2,0.1,0.05)'
|
|
1317
|
+
},
|
|
1318
|
+
'&.selected td': {
|
|
1319
|
+
backgroundColor: theme.palette.action.selected,
|
|
1320
|
+
transition: 'all 0.3s cubic-bezier(1.1, 1.4, 2.1, 1.1, 0.8, 0.7,0.6,0.5,0.4,0.3,0.2,0.1,0.05)'
|
|
1321
|
+
},
|
|
1322
|
+
'&.hover td': {
|
|
1323
|
+
backgroundColor: theme.palette.action.hover,
|
|
1324
|
+
transition: 'all 0.3s cubic-bezier(1.1, 1.4, 2.1, 1.1, 0.8, 0.7,0.6,0.5,0.4,0.3,0.2,0.1,0.05)'
|
|
1325
|
+
},
|
|
1326
|
+
'&.selected.hover td': {
|
|
1327
|
+
backgroundColor: theme.palette.action.selected,
|
|
1328
|
+
transition: 'all 0.3s cubic-bezier(1.1, 1.4, 2.1, 1.1, 0.8, 0.7,0.6,0.5,0.4,0.3,0.2,0.1,0.05)'
|
|
1329
|
+
}
|
|
1330
|
+
},
|
|
1331
|
+
onClick: e => {
|
|
1332
|
+
e.preventDefault();
|
|
1333
|
+
const newSelectedRow = e.currentTarget;
|
|
1334
|
+
if (newSelectedRow) {
|
|
1335
|
+
if (selectedEvent.id) {
|
|
1336
|
+
const oldSelectedRow = document.getElementById(selectedEvent.id);
|
|
1337
|
+
if (oldSelectedRow) {
|
|
1338
|
+
oldSelectedRow.classList.remove('selected');
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
newSelectedRow.classList.add('selected');
|
|
1342
|
+
selectEvent(event);
|
|
1343
|
+
}
|
|
1344
|
+
},
|
|
1345
|
+
onMouseEnter: e => {
|
|
1346
|
+
const closestRow = e.currentTarget;
|
|
1347
|
+
if (closestRow) {
|
|
1348
|
+
closestRow.classList.add('hover');
|
|
1349
|
+
}
|
|
1350
|
+
},
|
|
1351
|
+
onMouseLeave: e => {
|
|
1352
|
+
const closestRow = e.currentTarget;
|
|
1353
|
+
if (closestRow) {
|
|
1354
|
+
closestRow.classList.remove('hover');
|
|
1355
|
+
}
|
|
1356
|
+
},
|
|
1357
|
+
children: [/*#__PURE__*/_jsx(TableCell, {
|
|
1358
|
+
children: getTimeOnly(event.date)
|
|
1359
|
+
}), /*#__PURE__*/_jsx(TableCell, {
|
|
1360
|
+
children: /*#__PURE__*/_jsx("span", {
|
|
1361
|
+
onClick: e => e.stopPropagation(),
|
|
1362
|
+
style: {
|
|
1363
|
+
textDecoration: 'none',
|
|
1364
|
+
color: theme.palette.primary.main,
|
|
1365
|
+
cursor: 'pointer'
|
|
1366
|
+
},
|
|
1367
|
+
children: event.repo && event.repo.includes('/') ? event.repo.split('/')[1] : event.repo
|
|
1368
|
+
})
|
|
1369
|
+
}), /*#__PURE__*/_jsx(TableCell, {
|
|
1370
|
+
children: /*#__PURE__*/_jsx("span", {
|
|
1371
|
+
onClick: e => e.stopPropagation(),
|
|
1372
|
+
style: {
|
|
1373
|
+
textDecoration: 'none',
|
|
1374
|
+
color: theme.palette.primary.main,
|
|
1375
|
+
cursor: 'pointer'
|
|
1376
|
+
},
|
|
1377
|
+
children: event.action
|
|
1378
|
+
})
|
|
1379
|
+
})]
|
|
1380
|
+
})]
|
|
1381
|
+
}, event.id || `event-${index}`);
|
|
1382
|
+
}), events.length === 0 && !loading && (_TableRow || (_TableRow = /*#__PURE__*/_jsx(TableRow, {
|
|
1383
|
+
children: /*#__PURE__*/_jsx(TableCell, {
|
|
1384
|
+
colSpan: 4,
|
|
1385
|
+
align: "center",
|
|
1386
|
+
children: "No events found"
|
|
1387
|
+
})
|
|
1388
|
+
}))), loading && (_TableRow2 || (_TableRow2 = /*#__PURE__*/_jsx(TableRow, {
|
|
1389
|
+
children: /*#__PURE__*/_jsx(TableCell, {
|
|
1390
|
+
colSpan: 4,
|
|
1391
|
+
align: "center",
|
|
1392
|
+
children: /*#__PURE__*/_jsx(CircularProgress, {
|
|
1393
|
+
size: 40
|
|
1394
|
+
})
|
|
1395
|
+
})
|
|
1396
|
+
})))]
|
|
1397
|
+
})]
|
|
1398
|
+
})
|
|
1399
|
+
})
|
|
1400
|
+
}), !hideMetadata && selectedEvent.id && /*#__PURE__*/_jsx(MetadataDisplay, {
|
|
1401
|
+
className: "metadata-display",
|
|
1402
|
+
sx: {
|
|
1403
|
+
backgroundColor: 'rgba(255, 255, 255, 0.06)',
|
|
1404
|
+
borderRadiusBottomLeft: theme.shape.borderRadius,
|
|
1405
|
+
borderRadiusBottomRight: theme.shape.borderRadius,
|
|
1406
|
+
borderRadiusTopLeft: 0,
|
|
1407
|
+
borderRadiusTopRight: 0,
|
|
1408
|
+
boxShadow: theme.shadows[2],
|
|
1409
|
+
position: 'sticky',
|
|
1410
|
+
width: 'fit-content',
|
|
1411
|
+
maxWidth: '692px',
|
|
1412
|
+
minWidth: '300px',
|
|
1413
|
+
top: '84px',
|
|
1414
|
+
maxHeight: 'calc(100vh - 100px)',
|
|
1415
|
+
overflow: 'auto',
|
|
1416
|
+
height: 'fit-content'
|
|
1417
|
+
},
|
|
1418
|
+
children: error ? /*#__PURE__*/_jsx(ErrorDetails, {
|
|
1419
|
+
error: error
|
|
1420
|
+
}) : selectedEvent.actionType === 'PullRequestEvent' ? /*#__PURE__*/_jsx(PullRequestEvent, {
|
|
1421
|
+
event: selectedEvent
|
|
1422
|
+
}) : selectedEvent.actionType === 'PushEvent' ? /*#__PURE__*/_jsx(PushEvent, {
|
|
1423
|
+
event: selectedEvent
|
|
1424
|
+
}) : selectedEvent.actionType === 'DeleteEvent' ? /*#__PURE__*/_jsx(DeleteEvent, {
|
|
1425
|
+
event: selectedEvent
|
|
1426
|
+
}) : selectedEvent.actionType === 'CreateEvent' ? /*#__PURE__*/_jsx(CreateEvent, {
|
|
1427
|
+
event: selectedEvent
|
|
1428
|
+
}) : selectedEvent.actionType === 'IssuesEvent' ? /*#__PURE__*/_jsx(IssuesEvent, {
|
|
1429
|
+
event: selectedEvent
|
|
1430
|
+
}) : selectedEvent.actionType === 'IssueCommentEvent' ? /*#__PURE__*/_jsx(IssueCommentEvent, {
|
|
1431
|
+
event: selectedEvent
|
|
1432
|
+
}) : /*#__PURE__*/_jsx(ReactJson, {
|
|
1433
|
+
src: selectedEvent,
|
|
1434
|
+
name: false,
|
|
1435
|
+
theme: "monokai",
|
|
1436
|
+
displayDataTypes: false,
|
|
1437
|
+
enableClipboard: false,
|
|
1438
|
+
displayObjectSize: false,
|
|
1439
|
+
collapsed: 1,
|
|
1440
|
+
collapseStringsAfterLength: 50,
|
|
1441
|
+
style: {
|
|
1442
|
+
backgroundColor: 'transparent',
|
|
1443
|
+
fontSize: '0.875rem',
|
|
1444
|
+
fontFamily: 'monospace',
|
|
1445
|
+
padding: '8px',
|
|
1446
|
+
borderRadius: '4px',
|
|
1447
|
+
overflow: 'auto',
|
|
1448
|
+
maxHeight: 'calc(100vh - 200px)'
|
|
1449
|
+
}
|
|
1450
|
+
})
|
|
1451
|
+
})]
|
|
1452
|
+
})]
|
|
1453
|
+
});
|
|
1454
|
+
}
|