feat: refresh a single repository from its own button (#2)

* feat(refresh): refresh a single repository with POST /refresh?repo=

The endpoint refreshes one configured repository and returns the full state plus the repo name.
Each repository has a 60-second cooldown that is separate from the full-refresh limit.
A running full refresh or a refresh of the same repository returns 409.
An unknown repository returns 404. Cross-site and disabled-config behaviour stay the same.
The collector reuses its fetch path and replaces only that repository.

* feat(ui): add a refresh button beside each repository

The button appears in the project list and in each attention group header.
It stays hidden when the server disables manual refresh.
The button shows a spinner while its repository refreshes and reports refusals in the notice line.
The store swaps in the returned state, so no extra fetch follows.
This commit is contained in:
2026-10-02 23:16:22 +01:00
committed by GitHub
parent 4c2c9d3341
commit 8cbc495dc7
16 changed files with 760 additions and 19 deletions
+8 -1
View File
@@ -16,9 +16,12 @@ const props = defineProps<{
facets: Facets
owners: string[]
active: number
manualRefresh?: boolean
refreshing?: string[]
scanning?: boolean
}>()
const filters = defineModel<Filters>('filters', { required: true })
defineEmits<{ clear: [] }>()
defineEmits<{ clear: []; refresh: [fullName: string] }>()
const columnCount = useColumns()
// A group's height is its header plus its rows, so rows+2 approximates it.
@@ -59,6 +62,10 @@ defineExpose({ focusSearch: () => bar.value?.focus() })
:block="block"
:now-ms="nowMs"
:crit-seconds="critSeconds"
:manual-refresh="manualRefresh"
:refreshing="refreshing"
:scanning="scanning"
@refresh="(name) => $emit('refresh', name)"
/>
</div>
</div>