Pull Requests
-
+
-
-
-
diff --git a/.gitignore b/.gitignore index cf229db..a81db16 100644 --- a/.gitignore +++ b/.gitignore @@ -11,15 +11,7 @@ pnpm-debug.log* # Vite build output dist/ -public/assets/ -public/*.js -public/*.css -public/*.png -public/*.ico -public/*.webmanifest -public/index.html -public/*.br -!public/*.svg +public/ # Firebase .firebase/ diff --git a/index.html b/index.html index 3f09422..8872583 100644 --- a/index.html +++ b/index.html @@ -4,17 +4,21 @@
© GitHelm. All rights reserved.
+ Icons created by Flat Icons diff --git a/public/favicon.svg b/public/favicon.svg deleted file mode 100644 index b9fc59e..0000000 --- a/public/favicon.svg +++ /dev/null @@ -1,84 +0,0 @@ - - diff --git a/pwa-assets.config.ts b/pwa-assets.config.ts index 452b31f..62d8649 100644 --- a/pwa-assets.config.ts +++ b/pwa-assets.config.ts @@ -8,5 +8,5 @@ export default defineConfig({ preset: '2023', }, preset, - images: ['public/favicon.svg'], + images: ['public/assets/helm.svg'], }) diff --git a/src/assets/helm.svg b/src/assets/helm.svg new file mode 100644 index 0000000..f7c169f --- /dev/null +++ b/src/assets/helm.svg @@ -0,0 +1,233 @@ + + \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 8fb5e07..a618078 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,105 +1,56 @@ -import { loadContent, setNoContent } from './modules/ui'; +import { + loadContent, + LOGIN_BUTTON, + LOGOUT_BUTTON, + setNoContent, + showContent, + LastUpdated +} from './modules/ui'; import { initPWA } from './pwa'; -import { Firebase, fetchDataAndSaveToLocalStorage, getSiteData, clearSiteData, getUserRepos } from './modules/services'; -import './style.css'; -import Sortable from 'sortablejs'; +import { Firebase, fetchDataAndSaveToLocalStorage, getSiteData, clearSiteData } from './modules/services'; +const firebase = new Firebase(); +const lastUpdated = new LastUpdated(); document.addEventListener("DOMContentLoaded", async function () { - const firebase = new Firebase(); initPWA(document.getElementById('app')!); + LOGIN_BUTTON.addEventListener('click', async () => { + const signedIn = await firebase.signIn(); + if (!signedIn) { return; } + showContent(); + await updateLocalStorageAndLoadContent(); + }); - const configEntriesContainer = document.getElementById('config-entries'); - if (configEntriesContainer) { - Sortable.create(configEntriesContainer, { - animation: 150, - handle: '.config-entry', // Handle to drag the config entry - ghostClass: 'sortable-ghost', // Class name for the drop placeholder - }); - } + LOGOUT_BUTTON.addEventListener('click', () => { + firebase.signOut(); + clearSiteData(); + window.location.reload(); + }); - wireUpButtons(firebase); + // EDIT_PULL_REQUESTS_BUTTON.addEventListener('click', () => { + // console.log('Edit pull requests'); + // }); + + // EDIT_ACTIONS_BUTTON.addEventListener('click', () => { + // console.log('Edit actions'); + // }); - const isSignedIn = Firebase.signedIn(); const localStorageData = getSiteData(); setInterval(async () => { - if (!isSignedIn) { return; } + if (!Firebase.signedIn()) { return; } await updateLocalStorageAndLoadContent(); }, 60 * 1000); - if (!isSignedIn) { return; } + if (!Firebase.signedIn()) { return; } + showContent(); if (localStorageData) { await loadContent(localStorageData); + lastUpdated.startTimer(); } else { await updateLocalStorageAndLoadContent(); } }); -function wireUpButtons(firebase: Firebase) { - const loginButton = document.getElementById('login-button')!; - const logoutButton = document.getElementById('logout-button')!; - const editPullRequestsButton = document.getElementById('edit-pull-requests')!; - const editActionsButton = document.getElementById('edit-actions')!; - - loginButton.addEventListener('click', async () => { - const firebase = new Firebase(); - const signedIn = await firebase.signIn(); - if (!signedIn) { return; } - await updateLocalStorageAndLoadContent(); - }); - - logoutButton.addEventListener('click', () => { - const firebase = new Firebase(); - firebase.signOut(); - clearSiteData(); - window.location.reload(); - }); - - editPullRequestsButton.addEventListener('click', () => { - console.log('Edit pull requests'); - if (document.getElementById('config-entries')!.children.length === 0) { - initializePullRequestsConfig(firebase); - } - document.getElementById('config-modal')!.classList.remove('hidden'); - }); - - editActionsButton.addEventListener('click', () => { - console.log('Edit actions'); - initializeActionsConfig(firebase); - document.getElementById('config-modal')!.classList.remove('hidden'); - }); - - document.getElementById('add-entry')!.addEventListener('click', () => { - addConfigEntry(); - }); - - document.getElementById('close-modal')!.addEventListener('click', () => { - document.getElementById('config-modal')!.classList.add('hidden'); - }); - ; - - document.getElementById('pull-requests-config-form')!.addEventListener('submit', async (event) => { - event.preventDefault(); - const form = event.target as HTMLFormElement; - const entries = Array.from(form.querySelectorAll('.config-entry')).map(entry => { - const repo = (entry.querySelector('select[name="repo"]') as HTMLSelectElement).value; - const [org, repoName] = repo.split('/'); - return { - org, - repo: repoName, - filter: (entry.querySelector('input[name="filter"]') as HTMLInputElement).value, - }; - }); - - const currentConfig = await firebase.getConfig(); - - await firebase.saveConfig([...entries], currentConfig.actions); - document.getElementById('config-modal')!.classList.add('hidden'); - }); - -} - - async function updateLocalStorageAndLoadContent() { await fetchDataAndSaveToLocalStorage(); const updatedData = getSiteData(); @@ -107,47 +58,5 @@ async function updateLocalStorageAndLoadContent() { setNoContent(); } await loadContent(updatedData); -} - - -export function sanitizeInput(input: string): string { - const div = document.createElement('div'); - div.textContent = input; - return div.innerHTML; -} - -function addConfigEntry(repos: string[], org = '', repo = '', filter = '') { - const entry = document.createElement('div'); - entry.classList.add('config-entry', 'config-group', 'mb-4'); - entry.setAttribute('draggable', 'true'); - entry.innerHTML = ` - - - - - `; - console.log(document.getElementById('config-entries')); - document.getElementById('config-entries')!.appendChild(entry); -} - -async function initializePullRequestsConfig(firebase: Firebase) { - const config = await firebase.getConfig(); - console.log(config); - const repos = await getUserRepos(); - console.log(repos); - config.pullRequests.forEach(prConfig => { - addConfigEntry(repos, prConfig.org, prConfig.repo, prConfig.filter); - }); - document.getElementById('config-modal')!.classList.remove('hidden'); -} - -async function initializeActionsConfig(firebase: Firebase) { - const config = await firebase.getConfig(); - const repos = await getUserRepos(); - config.actions.forEach(actionConfig => { - addConfigEntry(repos, actionConfig.repo, actionConfig.filter); - }); - document.getElementById('config-modal')!.classList.remove('hidden'); + lastUpdated.startTimer(); } diff --git a/src/modules/services/config.ts b/src/modules/services/config.ts index 0eedfea..e55287a 100644 --- a/src/modules/services/config.ts +++ b/src/modules/services/config.ts @@ -1,6 +1,11 @@ export const config = ` { "pullRequests": [ + { + "org": "JHADigitalCore", + "repo": "general-ledger", + "filter": "" + }, { "org": "JHADigitalCore", "repo": "general-ledger-service", diff --git a/src/modules/ui/elements.ts b/src/modules/ui/elements.ts index 5137587..9afcb4f 100644 --- a/src/modules/ui/elements.ts +++ b/src/modules/ui/elements.ts @@ -1,49 +1,53 @@ -export const AUTHORIZED = document.getElementById('authorized'); -export const LOGIN_BUTTON = document.getElementById('login-button'); -export const LOGOUT_BUTTON = document.getElementById('logout-button'); -export const SETTINGS_BUTTON = document.getElementById('settings-button'); -export const TAB_PULL_REQUESTS = document.getElementById('tab-pull-requests'); -export const TAB_ACTIONS = document.getElementById('tab-actions'); -export const PULL_REQUESTS_SECTION = document.getElementById('pull-requests-section'); -export const ACTIONS_SECTION = document.getElementById('actions-section'); -export const PULL_REQUESTS_DIV = document.getElementById('pull-requests'); -export const ACTIONS_DIV = document.getElementById('actions'); -export const LOADING_PULLS = document.getElementById('loading-pulls'); -export const LOADING_ACTIONS = document.getElementById('loading-actions'); +export const AUTHORIZED = document.getElementById('authorized')!; +export const LOGIN_BUTTON = document.getElementById('login-button')!; +export const LOGOUT_BUTTON = document.getElementById('logout-button')!; +export const TAB_PULL_REQUESTS = document.getElementById('tab-pull-requests')!; +export const TAB_ACTIONS = document.getElementById('tab-actions')!; +export const PULL_REQUESTS_SECTION = document.getElementById('pull-requests-section')!; +export const ACTIONS_SECTION = document.getElementById('actions-section')!; +export const PULL_REQUESTS_DIV = document.getElementById('pull-requests')!; +export const ACTIONS_DIV = document.getElementById('actions')!; +export const LOADING = document.getElementById('loading')!; +export const EDIT_PULL_REQUESTS_BUTTON = document.getElementById('edit-pull-requests')!; +export const EDIT_ACTIONS_BUTTON = document.getElementById('edit-actions')!; +export const LAST_UPDATED = document.getElementById('last-updated')!; export function toggleLogin(isAuthorized: boolean) { if (isAuthorized) { - AUTHORIZED?.classList.remove('hidden'); - LOGIN_BUTTON?.classList.add('hidden'); - LOGOUT_BUTTON?.classList.remove('hidden'); - SETTINGS_BUTTON?.classList.remove('hidden'); + AUTHORIZED.classList.remove('hidden'); + LOGIN_BUTTON.classList.add('hidden'); + LOGOUT_BUTTON.classList.remove('hidden'); } else { - AUTHORIZED?.classList.add('hidden'); - LOGIN_BUTTON?.classList.remove('hidden'); - LOGOUT_BUTTON?.classList.add('hidden'); - SETTINGS_BUTTON?.classList.add('hidden'); + AUTHORIZED.classList.add('hidden'); + LOGIN_BUTTON.classList.remove('hidden'); + LOGOUT_BUTTON.classList.add('hidden'); } } -export function removeLoadingIndicators() { - LOADING_PULLS?.remove(); - LOADING_ACTIONS?.remove(); + + +export function hideLoading() { + LOADING.classList.add('hidden'); +} + +export function showLoading() { + LOADING.classList.remove('hidden'); } export function handleTabs() { - TAB_PULL_REQUESTS?.addEventListener('click', () => switchTab(TAB_PULL_REQUESTS)); - TAB_ACTIONS?.addEventListener('click', () => switchTab(TAB_ACTIONS)); + TAB_PULL_REQUESTS.addEventListener('click', () => switchTab(TAB_PULL_REQUESTS)); + TAB_ACTIONS.addEventListener('click', () => switchTab(TAB_ACTIONS)); } function switchTab(activeTab: HTMLElement | null) { activeTab?.classList.add('active'); if (activeTab === TAB_PULL_REQUESTS) { - PULL_REQUESTS_SECTION?.classList.remove('hidden'); - ACTIONS_SECTION?.classList.add('hidden'); - TAB_ACTIONS?.classList.remove('active'); + PULL_REQUESTS_SECTION.classList.remove('hidden'); + ACTIONS_SECTION.classList.add('hidden'); + TAB_ACTIONS.classList.remove('active'); } else { - ACTIONS_SECTION?.classList.remove('hidden'); - PULL_REQUESTS_SECTION?.classList.add('hidden'); - TAB_PULL_REQUESTS?.classList.remove('active'); + ACTIONS_SECTION.classList.remove('hidden'); + PULL_REQUESTS_SECTION.classList.add('hidden'); + TAB_PULL_REQUESTS.classList.remove('active'); } } diff --git a/src/modules/ui/index.ts b/src/modules/ui/index.ts index e96a088..1abf986 100644 --- a/src/modules/ui/index.ts +++ b/src/modules/ui/index.ts @@ -1,2 +1,3 @@ -export { LOGIN_BUTTON, LOGOUT_BUTTON } from './elements'; -export * from './ui'; \ No newline at end of file +export * from './elements'; +export * from './ui'; +export * from './timer'; diff --git a/src/modules/ui/templates.ts b/src/modules/ui/templates.ts index b7fdc8c..6468e58 100644 --- a/src/modules/ui/templates.ts +++ b/src/modules/ui/templates.ts @@ -1,16 +1,18 @@ import checkSVG from '../../assets/check.svg'; import commentSVG from '../../assets/comment.svg'; -export function pullRequestTemplate(repo: any, pullRequests: { items: any[]; }) { +export function pullRequestTemplate(org: string, repo: string, pullRequests: { items: any[]; }) { return ` -No pull requests found. Configure repositories by clicking the pencil icon above.
'); - removeLoadingIndicators(); - + hideLoading(); + saveState([]); } function saveState(results: any[]) { @@ -43,12 +47,12 @@ function updateContent({ type, org, repo, data }: any) { if (JSON.stringify(previousRepoData) !== JSON.stringify(data)) { const existingDiv = container?.querySelector(`[data-org="${org}"][data-repo="${repo}"]`); if (existingDiv) { - existingDiv.innerHTML = template(repo, data); + existingDiv.innerHTML = template(org, repo, data); } else { const div = document.createElement("div"); div.setAttribute("data-org", org); div.setAttribute("data-repo", repo); - div.innerHTML = template(repo, data); + div.innerHTML = template(org, repo, data); container?.appendChild(div); } } diff --git a/src/style.css b/src/style.css index ef65193..958b1c5 100644 --- a/src/style.css +++ b/src/style.css @@ -101,27 +101,15 @@ header, #tabs, #pull-request-header, #actions-header { } .spinner { - border: 4px solid rgba(255, 255, 255, 0.3); - border-top-color: rgba(81, 203, 238, 1); - border-radius: 50%; - width: 2rem; - height: 2rem; - animation: spin 1s linear infinite; + width: 10rem; + height: 10rem; + animation: spin 1.5s linear infinite; } .content { height: calc(100vh - 10rem); } -.link { - text-decoration: none; - color: inherit; -} - -.link:hover { - text-decoration: underline; -} - .tab-button { background-color: transparent; color: white; @@ -137,18 +125,12 @@ header, #tabs, #pull-request-header, #actions-header { border-bottom: 2px solid #2d3748; } -#pr-item { - display: flex; - align-items: center; - justify-content: space-between; +.link { + text-decoration: none; } -#pr-item .link { - flex-grow: 1; - max-width: 70%; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; +.link:hover { + text-decoration: underline; } .reviews-container { diff --git a/vite.config.ts b/vite.config.ts index 0d5061b..1c5c5ae 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -71,6 +71,12 @@ export default defineConfig({ rollupOptions: { input: 'index.html', output: { + assetFileNames: (assetInfo) => { + if (assetInfo.name && assetInfo.name.endsWith('.svg')) { + return 'assets/[name][extname]'; + } + return 'assets/[name]-[hash][extname]'; + }, manualChunks: { firebase: ['firebase/app', 'firebase/analytics', 'firebase/auth', 'firebase/firestore'], sortable: ['sortablejs'],