mirror of
https://github.com/lukaszraczylo/ghtracker.git
synced 2026-10-12 00:45:38 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a0fd6d6856 | ||
|
|
ac5eb2f16a | ||
|
|
66ed84bdbf | ||
|
|
e6f28a223a | ||
|
|
0a2469ef7d |
@@ -155,25 +155,25 @@ func (c *Collector) Refresh(ctx context.Context) {
|
||||
c.limited.Store(false)
|
||||
c.scanDone.Store(0)
|
||||
c.scanTotal.Store(int64(len(c.names)))
|
||||
results := make([]model.Repo, len(c.names))
|
||||
sem := make(chan struct{}, c.concurrency)
|
||||
var wg sync.WaitGroup
|
||||
for i, name := range c.names {
|
||||
for _, name := range c.names {
|
||||
wg.Add(1)
|
||||
sem <- struct{}{}
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
defer func() { <-sem }()
|
||||
results[i] = c.refreshOne(ctx, name, start, true)
|
||||
r := c.refreshOne(ctx, name, start, true)
|
||||
// Publish per repo so a running scan shows new and resolved alerts as they land.
|
||||
c.mu.Lock()
|
||||
c.repos[r.FullName] = r
|
||||
c.mu.Unlock()
|
||||
c.scanDone.Add(1)
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
c.mu.Lock()
|
||||
for _, r := range results {
|
||||
c.repos[r.FullName] = r
|
||||
}
|
||||
c.lastRefresh = start
|
||||
c.lastDur = c.now().Sub(start)
|
||||
c.loaded = true
|
||||
|
||||
@@ -553,3 +553,34 @@ func TestRefreshRepoFailureSkipsRefreshHooks(t *testing.T) {
|
||||
case <-time.After(200 * time.Millisecond):
|
||||
}
|
||||
}
|
||||
|
||||
func TestRefreshPublishesEachRepoBeforeTheScanEnds(t *testing.T) {
|
||||
release := make(chan struct{})
|
||||
f := &fakeFetcher{fn: func(name string) (model.Repo, error) {
|
||||
if name == "o/slow" {
|
||||
<-release
|
||||
}
|
||||
return model.Repo{FullName: name, Err: ""}, nil
|
||||
}}
|
||||
cfg := &config.Config{Repos: []string{"o/fast", "o/slow"}, RefreshInterval: time.Hour, Concurrency: 2, Thresholds: th()}
|
||||
c := New(f, cfg, slog.New(slog.NewTextHandler(io.Discard, nil)))
|
||||
c.now = func() time.Time { return t0 }
|
||||
done := make(chan struct{})
|
||||
go func() { c.Refresh(context.Background()); close(done) }()
|
||||
deadline := time.Now().Add(2 * time.Second)
|
||||
for time.Now().Before(deadline) {
|
||||
if v := c.View(); len(v.Repos) == 1 && v.Repos[0].FullName == "o/fast" {
|
||||
break
|
||||
}
|
||||
time.Sleep(5 * time.Millisecond)
|
||||
}
|
||||
v := c.View()
|
||||
if len(v.Repos) != 1 || v.Repos[0].FullName != "o/fast" || !v.Refreshing || v.Loaded {
|
||||
t.Fatalf("mid-scan view: repos=%d refreshing=%v loaded=%v", len(v.Repos), v.Refreshing, v.Loaded)
|
||||
}
|
||||
close(release)
|
||||
<-done
|
||||
if v := c.View(); len(v.Repos) != 2 || !v.Loaded {
|
||||
t.Fatalf("after scan: repos=%d loaded=%v", len(v.Repos), v.Loaded)
|
||||
}
|
||||
}
|
||||
|
||||
+14
-10
@@ -14,14 +14,16 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
maxFailingNames = 5
|
||||
runsPerWorkflow = 5
|
||||
maxWorkflows = 100
|
||||
eventPullRequest = "pull_request"
|
||||
eventPullReqTgt = "pull_request_target"
|
||||
statusStateFail = "failure"
|
||||
statusStateError = "error"
|
||||
statusStatePend = "pending"
|
||||
maxFailingNames = 5
|
||||
runsPerWorkflow = 5
|
||||
// freshRunsWindowDays bounds the created filter of the confirming run query.
|
||||
freshRunsWindowDays = 30
|
||||
maxWorkflows = 100
|
||||
eventPullRequest = "pull_request"
|
||||
eventPullReqTgt = "pull_request_target"
|
||||
statusStateFail = "failure"
|
||||
statusStateError = "error"
|
||||
statusStatePend = "pending"
|
||||
)
|
||||
|
||||
// backgroundEvents are triggers that run without a person pushing code.
|
||||
@@ -374,9 +376,11 @@ func (c *Client) workflowRuns(ctx context.Context, full string, id int64, branch
|
||||
path := fmt.Sprintf("/repos/%s/actions/workflows/%d/runs", full, id)
|
||||
get := c.getJSON
|
||||
if fresh {
|
||||
// GitHub can keep answering one exact query from an old cached result, for weeks, whatever
|
||||
// the connection. A different query string skips that entry and reads current runs.
|
||||
// GitHub can keep answering a branch query from an old cached result, for weeks, whatever
|
||||
// the connection, and page=1 alone does not skip it. A created filter changes the query
|
||||
// every day and reads current runs.
|
||||
q.Set("page", "1")
|
||||
q.Set("created", ">="+c.now().UTC().AddDate(0, 0, -freshRunsWindowDays).Format(time.DateOnly))
|
||||
get = c.getJSONFresh
|
||||
}
|
||||
if err := get(ctx, full, path, q, &out); err != nil {
|
||||
|
||||
@@ -461,12 +461,12 @@ func TestAPIErrorMessageParsing(t *testing.T) {
|
||||
}
|
||||
|
||||
// staleThenFresh models GitHub answering one exact query from an old cached result: the plain
|
||||
// query returns an old failing run every time, and the same query with page=1 returns current runs.
|
||||
// query returns an old failing run every time, and the same query with a created filter returns current runs.
|
||||
func staleThenFresh(f *fakeGitHub, path string) *atomic.Int64 {
|
||||
var calls atomic.Int64
|
||||
f.routes[path] = func(w http.ResponseWriter, r *http.Request) {
|
||||
calls.Add(1)
|
||||
if r.URL.Query().Get("page") == "" {
|
||||
if r.URL.Query().Get("created") == "" {
|
||||
_, _ = w.Write([]byte(`{"workflow_runs":[
|
||||
{"id":1,"html_url":"old","event":"schedule","head_branch":"main","status":"completed","conclusion":"failure","created_at":"2026-09-11T03:02:00Z"}]}`))
|
||||
return
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@
|
||||
"happy-dom": "^20.14.5",
|
||||
"prettier": "^3.9.9",
|
||||
"tailwindcss": "^4.3.3",
|
||||
"typescript": "~5.9.3",
|
||||
"typescript": "~6.0.3",
|
||||
"typescript-eslint": "^8.70.1",
|
||||
"vite": "^8.3.1",
|
||||
"vitest": "^5.0.1",
|
||||
|
||||
Generated
+93
-93
@@ -22,13 +22,13 @@ importers:
|
||||
version: 7.3.1
|
||||
'@fortawesome/vue-fontawesome':
|
||||
specifier: ^3.3.3
|
||||
version: 3.3.3(@fortawesome/[email protected])([email protected](typescript@5.9.3))
|
||||
version: 3.3.3(@fortawesome/[email protected])([email protected](typescript@6.0.3))
|
||||
'@lucide/vue':
|
||||
specifier: ^1.49.0
|
||||
version: 1.51.0([email protected](typescript@5.9.3))
|
||||
version: 1.51.0([email protected](typescript@6.0.3))
|
||||
'@vueuse/core':
|
||||
specifier: ^15.0.0
|
||||
version: 15.0.0([email protected](typescript@5.9.3))
|
||||
version: 15.0.0([email protected](typescript@6.0.3))
|
||||
class-variance-authority:
|
||||
specifier: ^0.7.1
|
||||
version: 0.7.1
|
||||
@@ -37,16 +37,16 @@ importers:
|
||||
version: 2.1.1
|
||||
pinia:
|
||||
specifier: ^4.0.3
|
||||
version: 4.0.3(@vue/[email protected])(typescript@5.9.3)([email protected](typescript@5.9.3))
|
||||
version: 4.0.3(@vue/[email protected])(typescript@6.0.3)([email protected](typescript@6.0.3))
|
||||
reka-ui:
|
||||
specifier: ^2.10.5
|
||||
version: 2.10.5([email protected](typescript@5.9.3))
|
||||
version: 2.10.5([email protected](typescript@6.0.3))
|
||||
tailwind-merge:
|
||||
specifier: ^3.7.0
|
||||
version: 3.7.0
|
||||
vue:
|
||||
specifier: ^3.5.43
|
||||
version: 3.5.43(typescript@5.9.3)
|
||||
version: 3.5.43(typescript@6.0.3)
|
||||
devDependencies:
|
||||
'@eslint/js':
|
||||
specifier: ^10.0.1
|
||||
@@ -59,16 +59,16 @@ importers:
|
||||
version: 26.6.4
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^6.0.9
|
||||
version: 6.0.9([email protected](@types/[email protected])([email protected]))([email protected](typescript@5.9.3))
|
||||
version: 6.0.9([email protected](@types/[email protected])([email protected]))([email protected](typescript@6.0.3))
|
||||
'@vue/test-utils':
|
||||
specifier: ^2.5.1
|
||||
version: 2.5.1(@vue/[email protected])(@vue/[email protected])([email protected](typescript@5.9.3))
|
||||
version: 2.5.1(@vue/[email protected])(@vue/[email protected])([email protected](typescript@6.0.3))
|
||||
eslint:
|
||||
specifier: ^10.11.0
|
||||
version: 10.12.0([email protected])
|
||||
eslint-plugin-vue:
|
||||
specifier: ^10.11.1
|
||||
version: 10.11.1(@typescript-eslint/[email protected]([email protected]([email protected]))(typescript@5.9.3))([email protected]([email protected]))([email protected]([email protected]([email protected])))
|
||||
version: 10.11.1(@typescript-eslint/[email protected]([email protected]([email protected]))(typescript@6.0.3))([email protected]([email protected]))([email protected]([email protected]([email protected])))
|
||||
globals:
|
||||
specifier: ^17.12.0
|
||||
version: 17.13.0
|
||||
@@ -82,11 +82,11 @@ importers:
|
||||
specifier: ^4.3.3
|
||||
version: 4.3.3
|
||||
typescript:
|
||||
specifier: ~5.9.3
|
||||
version: 5.9.3
|
||||
specifier: ~6.0.3
|
||||
version: 6.0.3
|
||||
typescript-eslint:
|
||||
specifier: ^8.70.1
|
||||
version: 8.71.0([email protected]([email protected]))(typescript@5.9.3)
|
||||
version: 8.71.0([email protected]([email protected]))(typescript@6.0.3)
|
||||
vite:
|
||||
specifier: ^8.3.1
|
||||
version: 8.3.2(@types/[email protected])([email protected])
|
||||
@@ -95,7 +95,7 @@ importers:
|
||||
version: 5.0.3(@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected]))
|
||||
vue-tsc:
|
||||
specifier: ^3.3.11
|
||||
version: 3.3.12(typescript@5.9.3)
|
||||
version: 3.3.12(typescript@6.0.3)
|
||||
|
||||
packages:
|
||||
|
||||
@@ -1314,8 +1314,8 @@ packages:
|
||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||
typescript: '>=4.8.4 <6.1.0'
|
||||
|
||||
typescript@5.9.3:
|
||||
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
|
||||
typescript@6.0.3:
|
||||
resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
@@ -1559,11 +1559,11 @@ snapshots:
|
||||
|
||||
'@floating-ui/[email protected]': {}
|
||||
|
||||
'@floating-ui/[email protected]([email protected](typescript@5.9.3))':
|
||||
'@floating-ui/[email protected]([email protected](typescript@6.0.3))':
|
||||
dependencies:
|
||||
'@floating-ui/dom': 1.8.0
|
||||
'@floating-ui/utils': 0.2.12
|
||||
vue-demi: 0.14.10([email protected](typescript@5.9.3))
|
||||
vue-demi: 0.14.10([email protected](typescript@6.0.3))
|
||||
transitivePeerDependencies:
|
||||
- '@vue/composition-api'
|
||||
- vue
|
||||
@@ -1582,10 +1582,10 @@ snapshots:
|
||||
dependencies:
|
||||
'@fortawesome/fontawesome-common-types': 7.3.1
|
||||
|
||||
'@fortawesome/[email protected](@fortawesome/[email protected])([email protected](typescript@5.9.3))':
|
||||
'@fortawesome/[email protected](@fortawesome/[email protected])([email protected](typescript@6.0.3))':
|
||||
dependencies:
|
||||
'@fortawesome/fontawesome-svg-core': 7.3.1
|
||||
vue: 3.5.43(typescript@5.9.3)
|
||||
vue: 3.5.43(typescript@6.0.3)
|
||||
|
||||
'@humanfs/[email protected]':
|
||||
dependencies:
|
||||
@@ -1638,9 +1638,9 @@ snapshots:
|
||||
|
||||
'@keyv/[email protected]': {}
|
||||
|
||||
'@lucide/[email protected]([email protected](typescript@5.9.3))':
|
||||
'@lucide/[email protected]([email protected](typescript@6.0.3))':
|
||||
dependencies:
|
||||
vue: 3.5.43(typescript@5.9.3)
|
||||
vue: 3.5.43(typescript@6.0.3)
|
||||
|
||||
'@one-ini/[email protected]': {}
|
||||
|
||||
@@ -1767,10 +1767,10 @@ snapshots:
|
||||
|
||||
'@tanstack/[email protected]': {}
|
||||
|
||||
'@tanstack/[email protected]([email protected](typescript@5.9.3))':
|
||||
'@tanstack/[email protected]([email protected](typescript@6.0.3))':
|
||||
dependencies:
|
||||
'@tanstack/virtual-core': 3.17.11
|
||||
vue: 3.5.43(typescript@5.9.3)
|
||||
vue: 3.5.43(typescript@6.0.3)
|
||||
|
||||
'@types/[email protected]':
|
||||
dependencies:
|
||||
@@ -1797,40 +1797,40 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/node': 26.6.4
|
||||
|
||||
'@typescript-eslint/[email protected](@typescript-eslint/[email protected]([email protected]([email protected]))(typescript@5.9.3))([email protected]([email protected]))(typescript@5.9.3)':
|
||||
'@typescript-eslint/[email protected](@typescript-eslint/[email protected]([email protected]([email protected]))(typescript@6.0.3))([email protected]([email protected]))(typescript@6.0.3)':
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.12.2
|
||||
'@typescript-eslint/parser': 8.71.0([email protected]([email protected]))(typescript@5.9.3)
|
||||
'@typescript-eslint/parser': 8.71.0([email protected]([email protected]))(typescript@6.0.3)
|
||||
'@typescript-eslint/scope-manager': 8.71.0
|
||||
'@typescript-eslint/type-utils': 8.71.0([email protected]([email protected]))(typescript@5.9.3)
|
||||
'@typescript-eslint/utils': 8.71.0([email protected]([email protected]))(typescript@5.9.3)
|
||||
'@typescript-eslint/type-utils': 8.71.0([email protected]([email protected]))(typescript@6.0.3)
|
||||
'@typescript-eslint/utils': 8.71.0([email protected]([email protected]))(typescript@6.0.3)
|
||||
'@typescript-eslint/visitor-keys': 8.71.0
|
||||
eslint: 10.12.0([email protected])
|
||||
ignore: 7.0.11
|
||||
natural-compare: 1.4.0
|
||||
ts-api-utils: 2.5.0(typescript@5.9.3)
|
||||
typescript: 5.9.3
|
||||
ts-api-utils: 2.5.0(typescript@6.0.3)
|
||||
typescript: 6.0.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/[email protected]([email protected]([email protected]))(typescript@5.9.3)':
|
||||
'@typescript-eslint/[email protected]([email protected]([email protected]))(typescript@6.0.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 8.71.0
|
||||
'@typescript-eslint/types': 8.71.0
|
||||
'@typescript-eslint/typescript-estree': 8.71.0(typescript@5.9.3)
|
||||
'@typescript-eslint/typescript-estree': 8.71.0(typescript@6.0.3)
|
||||
'@typescript-eslint/visitor-keys': 8.71.0
|
||||
debug: 4.4.3
|
||||
eslint: 10.12.0([email protected])
|
||||
typescript: 5.9.3
|
||||
typescript: 6.0.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/[email protected](typescript@5.9.3)':
|
||||
'@typescript-eslint/[email protected](typescript@6.0.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/tsconfig-utils': 8.71.0(typescript@5.9.3)
|
||||
'@typescript-eslint/tsconfig-utils': 8.71.0(typescript@6.0.3)
|
||||
'@typescript-eslint/types': 8.71.0
|
||||
debug: 4.4.3
|
||||
typescript: 5.9.3
|
||||
typescript: 6.0.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -1839,47 +1839,47 @@ snapshots:
|
||||
'@typescript-eslint/types': 8.71.0
|
||||
'@typescript-eslint/visitor-keys': 8.71.0
|
||||
|
||||
'@typescript-eslint/[email protected](typescript@5.9.3)':
|
||||
'@typescript-eslint/[email protected](typescript@6.0.3)':
|
||||
dependencies:
|
||||
typescript: 5.9.3
|
||||
typescript: 6.0.3
|
||||
|
||||
'@typescript-eslint/[email protected]([email protected]([email protected]))(typescript@5.9.3)':
|
||||
'@typescript-eslint/[email protected]([email protected]([email protected]))(typescript@6.0.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.71.0
|
||||
'@typescript-eslint/typescript-estree': 8.71.0(typescript@5.9.3)
|
||||
'@typescript-eslint/utils': 8.71.0([email protected]([email protected]))(typescript@5.9.3)
|
||||
'@typescript-eslint/typescript-estree': 8.71.0(typescript@6.0.3)
|
||||
'@typescript-eslint/utils': 8.71.0([email protected]([email protected]))(typescript@6.0.3)
|
||||
debug: 4.4.3
|
||||
eslint: 10.12.0([email protected])
|
||||
ts-api-utils: 2.5.0(typescript@5.9.3)
|
||||
typescript: 5.9.3
|
||||
ts-api-utils: 2.5.0(typescript@6.0.3)
|
||||
typescript: 6.0.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/[email protected]': {}
|
||||
|
||||
'@typescript-eslint/[email protected](typescript@5.9.3)':
|
||||
'@typescript-eslint/[email protected](typescript@6.0.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/project-service': 8.71.0(typescript@5.9.3)
|
||||
'@typescript-eslint/tsconfig-utils': 8.71.0(typescript@5.9.3)
|
||||
'@typescript-eslint/project-service': 8.71.0(typescript@6.0.3)
|
||||
'@typescript-eslint/tsconfig-utils': 8.71.0(typescript@6.0.3)
|
||||
'@typescript-eslint/types': 8.71.0
|
||||
'@typescript-eslint/visitor-keys': 8.71.0
|
||||
debug: 4.4.3
|
||||
minimatch: 10.2.6
|
||||
semver: 7.8.5
|
||||
tinyglobby: 0.2.17
|
||||
ts-api-utils: 2.5.0(typescript@5.9.3)
|
||||
typescript: 5.9.3
|
||||
ts-api-utils: 2.5.0(typescript@6.0.3)
|
||||
typescript: 6.0.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/[email protected]([email protected]([email protected]))(typescript@5.9.3)':
|
||||
'@typescript-eslint/[email protected]([email protected]([email protected]))(typescript@6.0.3)':
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.10.1([email protected]([email protected]))
|
||||
'@typescript-eslint/scope-manager': 8.71.0
|
||||
'@typescript-eslint/types': 8.71.0
|
||||
'@typescript-eslint/typescript-estree': 8.71.0(typescript@5.9.3)
|
||||
'@typescript-eslint/typescript-estree': 8.71.0(typescript@6.0.3)
|
||||
eslint: 10.12.0([email protected])
|
||||
typescript: 5.9.3
|
||||
typescript: 6.0.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -1888,11 +1888,11 @@ snapshots:
|
||||
'@typescript-eslint/types': 8.71.0
|
||||
eslint-visitor-keys: 5.0.1
|
||||
|
||||
'@vitejs/[email protected]([email protected](@types/[email protected])([email protected]))([email protected](typescript@5.9.3))':
|
||||
'@vitejs/[email protected]([email protected](@types/[email protected])([email protected]))([email protected](typescript@6.0.3))':
|
||||
dependencies:
|
||||
'@rolldown/pluginutils': 1.0.1
|
||||
vite: 8.3.2(@types/[email protected])([email protected])
|
||||
vue: 3.5.43(typescript@5.9.3)
|
||||
vue: 3.5.43(typescript@6.0.3)
|
||||
|
||||
'@vitest/[email protected]([email protected](@types/[email protected])([email protected]))':
|
||||
dependencies:
|
||||
@@ -1911,13 +1911,13 @@ snapshots:
|
||||
|
||||
'@volar/[email protected]': {}
|
||||
|
||||
'@volar/[email protected](typescript@5.9.3)':
|
||||
'@volar/[email protected](typescript@6.0.3)':
|
||||
dependencies:
|
||||
'@volar/language-core': 2.4.28
|
||||
path-browserify: 1.0.1
|
||||
vscode-uri: 3.2.0
|
||||
optionalDependencies:
|
||||
typescript: 5.9.3
|
||||
typescript: 6.0.3
|
||||
|
||||
'@vue/[email protected]':
|
||||
dependencies:
|
||||
@@ -1996,40 +1996,40 @@ snapshots:
|
||||
|
||||
'@vue/[email protected]': {}
|
||||
|
||||
'@vue/[email protected](@vue/[email protected])(@vue/[email protected])([email protected](typescript@5.9.3))':
|
||||
'@vue/[email protected](@vue/[email protected])(@vue/[email protected])([email protected](typescript@6.0.3))':
|
||||
dependencies:
|
||||
'@vue/compiler-dom': 3.5.43
|
||||
js-beautify: 2.0.3
|
||||
vue: 3.5.43(typescript@5.9.3)
|
||||
vue: 3.5.43(typescript@6.0.3)
|
||||
vue-component-type-helpers: 3.3.11
|
||||
optionalDependencies:
|
||||
'@vue/server-renderer': 3.5.43
|
||||
|
||||
'@vueuse/[email protected]([email protected](typescript@5.9.3))':
|
||||
'@vueuse/[email protected]([email protected](typescript@6.0.3))':
|
||||
dependencies:
|
||||
'@types/web-bluetooth': 0.0.21
|
||||
'@vueuse/metadata': 14.4.0
|
||||
'@vueuse/shared': 14.4.0([email protected](typescript@5.9.3))
|
||||
vue: 3.5.43(typescript@5.9.3)
|
||||
'@vueuse/shared': 14.4.0([email protected](typescript@6.0.3))
|
||||
vue: 3.5.43(typescript@6.0.3)
|
||||
|
||||
'@vueuse/[email protected]([email protected](typescript@5.9.3))':
|
||||
'@vueuse/[email protected]([email protected](typescript@6.0.3))':
|
||||
dependencies:
|
||||
'@types/web-bluetooth': 0.0.21
|
||||
'@vueuse/metadata': 15.0.0
|
||||
'@vueuse/shared': 15.0.0([email protected](typescript@5.9.3))
|
||||
vue: 3.5.43(typescript@5.9.3)
|
||||
'@vueuse/shared': 15.0.0([email protected](typescript@6.0.3))
|
||||
vue: 3.5.43(typescript@6.0.3)
|
||||
|
||||
'@vueuse/[email protected]': {}
|
||||
|
||||
'@vueuse/[email protected]': {}
|
||||
|
||||
'@vueuse/[email protected]([email protected](typescript@5.9.3))':
|
||||
'@vueuse/[email protected]([email protected](typescript@6.0.3))':
|
||||
dependencies:
|
||||
vue: 3.5.43(typescript@5.9.3)
|
||||
vue: 3.5.43(typescript@6.0.3)
|
||||
|
||||
'@vueuse/[email protected]([email protected](typescript@5.9.3))':
|
||||
'@vueuse/[email protected]([email protected](typescript@6.0.3))':
|
||||
dependencies:
|
||||
vue: 3.5.43(typescript@5.9.3)
|
||||
vue: 3.5.43(typescript@6.0.3)
|
||||
|
||||
[email protected]: {}
|
||||
|
||||
@@ -2129,7 +2129,7 @@ snapshots:
|
||||
|
||||
[email protected]: {}
|
||||
|
||||
[email protected](@typescript-eslint/[email protected]([email protected]([email protected]))(typescript@5.9.3))([email protected]([email protected]))([email protected]([email protected]([email protected]))):
|
||||
[email protected](@typescript-eslint/[email protected]([email protected]([email protected]))(typescript@6.0.3))([email protected]([email protected]))([email protected]([email protected]([email protected]))):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.10.1([email protected]([email protected]))
|
||||
eslint: 10.12.0([email protected])
|
||||
@@ -2140,7 +2140,7 @@ snapshots:
|
||||
vue-eslint-parser: 10.4.1([email protected]([email protected]))
|
||||
xml-name-validator: 5.0.0
|
||||
optionalDependencies:
|
||||
'@typescript-eslint/parser': 8.71.0([email protected]([email protected]))(typescript@5.9.3)
|
||||
'@typescript-eslint/parser': 8.71.0([email protected]([email protected]))(typescript@6.0.3)
|
||||
|
||||
[email protected]:
|
||||
dependencies:
|
||||
@@ -2498,13 +2498,13 @@ snapshots:
|
||||
|
||||
[email protected]: {}
|
||||
|
||||
[email protected](@vue/[email protected])(typescript@5.9.3)([email protected](typescript@5.9.3)):
|
||||
[email protected](@vue/[email protected])(typescript@6.0.3)([email protected](typescript@6.0.3)):
|
||||
dependencies:
|
||||
'@vue/devtools-api': 8.2.1
|
||||
nostics: 1.3.0
|
||||
vue: 3.5.43(typescript@5.9.3)
|
||||
vue: 3.5.43(typescript@6.0.3)
|
||||
optionalDependencies:
|
||||
typescript: 5.9.3
|
||||
typescript: 6.0.3
|
||||
|
||||
[email protected]:
|
||||
dependencies:
|
||||
@@ -2529,19 +2529,19 @@ snapshots:
|
||||
dependencies:
|
||||
hookified: 2.2.0
|
||||
|
||||
[email protected]([email protected](typescript@5.9.3)):
|
||||
[email protected]([email protected](typescript@6.0.3)):
|
||||
dependencies:
|
||||
'@floating-ui/dom': 1.8.0
|
||||
'@floating-ui/vue': 1.1.11([email protected](typescript@5.9.3))
|
||||
'@floating-ui/vue': 1.1.11([email protected](typescript@6.0.3))
|
||||
'@internationalized/date': 3.12.4
|
||||
'@internationalized/number': 3.6.8
|
||||
'@tanstack/vue-virtual': 3.13.39([email protected](typescript@5.9.3))
|
||||
'@vueuse/core': 14.4.0([email protected](typescript@5.9.3))
|
||||
'@vueuse/shared': 14.4.0([email protected](typescript@5.9.3))
|
||||
'@tanstack/vue-virtual': 3.13.39([email protected](typescript@6.0.3))
|
||||
'@vueuse/core': 14.4.0([email protected](typescript@6.0.3))
|
||||
'@vueuse/shared': 14.4.0([email protected](typescript@6.0.3))
|
||||
aria-hidden: 1.2.6
|
||||
defu: 6.1.7
|
||||
ohash: 2.0.12
|
||||
vue: 3.5.43(typescript@5.9.3)
|
||||
vue: 3.5.43(typescript@6.0.3)
|
||||
transitivePeerDependencies:
|
||||
- '@vue/composition-api'
|
||||
|
||||
@@ -2593,9 +2593,9 @@ snapshots:
|
||||
fdir: 6.5.0([email protected])
|
||||
picomatch: 4.0.7
|
||||
|
||||
[email protected](typescript@5.9.3):
|
||||
[email protected](typescript@6.0.3):
|
||||
dependencies:
|
||||
typescript: 5.9.3
|
||||
typescript: 6.0.3
|
||||
|
||||
[email protected]: {}
|
||||
|
||||
@@ -2603,18 +2603,18 @@ snapshots:
|
||||
dependencies:
|
||||
prelude-ls: 1.2.1
|
||||
|
||||
[email protected]([email protected]([email protected]))(typescript@5.9.3):
|
||||
[email protected]([email protected]([email protected]))(typescript@6.0.3):
|
||||
dependencies:
|
||||
'@typescript-eslint/eslint-plugin': 8.71.0(@typescript-eslint/[email protected]([email protected]([email protected]))(typescript@5.9.3))([email protected]([email protected]))(typescript@5.9.3)
|
||||
'@typescript-eslint/parser': 8.71.0([email protected]([email protected]))(typescript@5.9.3)
|
||||
'@typescript-eslint/typescript-estree': 8.71.0(typescript@5.9.3)
|
||||
'@typescript-eslint/utils': 8.71.0([email protected]([email protected]))(typescript@5.9.3)
|
||||
'@typescript-eslint/eslint-plugin': 8.71.0(@typescript-eslint/[email protected]([email protected]([email protected]))(typescript@6.0.3))([email protected]([email protected]))(typescript@6.0.3)
|
||||
'@typescript-eslint/parser': 8.71.0([email protected]([email protected]))(typescript@6.0.3)
|
||||
'@typescript-eslint/typescript-estree': 8.71.0(typescript@6.0.3)
|
||||
'@typescript-eslint/utils': 8.71.0([email protected]([email protected]))(typescript@6.0.3)
|
||||
eslint: 10.12.0([email protected])
|
||||
typescript: 5.9.3
|
||||
typescript: 6.0.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
typescript@5.9.3: {}
|
||||
typescript@6.0.3: {}
|
||||
|
||||
[email protected]: {}
|
||||
|
||||
@@ -2662,9 +2662,9 @@ snapshots:
|
||||
|
||||
[email protected]: {}
|
||||
|
||||
[email protected]([email protected](typescript@5.9.3)):
|
||||
[email protected]([email protected](typescript@6.0.3)):
|
||||
dependencies:
|
||||
vue: 3.5.43(typescript@5.9.3)
|
||||
vue: 3.5.43(typescript@6.0.3)
|
||||
|
||||
[email protected]([email protected]([email protected])):
|
||||
dependencies:
|
||||
@@ -2678,13 +2678,13 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
[email protected](typescript@5.9.3):
|
||||
[email protected](typescript@6.0.3):
|
||||
dependencies:
|
||||
'@volar/typescript': 2.4.28(typescript@5.9.3)
|
||||
'@volar/typescript': 2.4.28(typescript@6.0.3)
|
||||
'@vue/language-core': 3.3.12
|
||||
typescript: 5.9.3
|
||||
typescript: 6.0.3
|
||||
|
||||
[email protected](typescript@5.9.3):
|
||||
[email protected](typescript@6.0.3):
|
||||
dependencies:
|
||||
'@vue/compiler-dom': 3.5.43
|
||||
'@vue/compiler-sfc': 3.5.43
|
||||
@@ -2692,7 +2692,7 @@ snapshots:
|
||||
'@vue/server-renderer': 3.5.43
|
||||
'@vue/shared': 3.5.43
|
||||
optionalDependencies:
|
||||
typescript: 5.9.3
|
||||
typescript: 6.0.3
|
||||
|
||||
[email protected]: {}
|
||||
|
||||
|
||||
+2
-2
@@ -116,7 +116,7 @@ onBeforeUnmount(() => {
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="mt-10 grid grid-cols-[minmax(0,1fr)] gap-x-10 gap-y-10 sm:mt-14 lg:grid-cols-[minmax(0,1fr)_24rem] 2xl:grid-cols-[minmax(0,1fr)_28rem]"
|
||||
class="mt-10 grid grid-cols-[minmax(0,1fr)] gap-x-10 gap-y-10 sm:mt-14 xl:grid-cols-[minmax(0,1fr)_24rem] 2xl:grid-cols-[minmax(0,1fr)_28rem]"
|
||||
>
|
||||
<AttentionList
|
||||
ref="list"
|
||||
@@ -133,7 +133,7 @@ onBeforeUnmount(() => {
|
||||
@clear="store.clearFilters()"
|
||||
@refresh="store.refreshRepo"
|
||||
/>
|
||||
<aside class="lg:sticky lg:top-6 lg:self-start">
|
||||
<aside class="xl:sticky xl:top-6 xl:self-start">
|
||||
<ProjectList
|
||||
:repos="visibleRepos"
|
||||
:total="state.repos.length"
|
||||
|
||||
@@ -89,7 +89,7 @@ const LABEL = { crit: 'Critical', warn: 'Warning', ok: 'Healthy' } as const
|
||||
<ul
|
||||
v-else
|
||||
ref="scroller"
|
||||
class="border-border bg-surface divide-border max-h-[70vh] divide-y overflow-y-auto rounded-lg border [scrollbar-color:var(--border)_transparent] [scrollbar-width:thin] lg:max-h-[calc(100vh-7rem)]"
|
||||
class="border-border bg-surface divide-border max-h-[70vh] divide-y overflow-y-auto rounded-lg border [scrollbar-color:var(--border)_transparent] [scrollbar-width:thin] xl:max-h-[calc(100vh-7rem)]"
|
||||
>
|
||||
<li
|
||||
v-for="repo in visible"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { faSpinner } from '@fortawesome/free-solid-svg-icons'
|
||||
import { faScrewdriverWrench, faSpinner } from '@fortawesome/free-solid-svg-icons'
|
||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
||||
import {
|
||||
AlertDialog,
|
||||
@@ -44,14 +44,18 @@ function press(a: ActionDef): void {
|
||||
<div class="mt-2 flex flex-wrap items-center gap-2" data-test="row-actions">
|
||||
<template v-for="a in row.actions" :key="a.id">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="xs"
|
||||
size="sm"
|
||||
class="font-semibold shadow-sm"
|
||||
:disabled="busy(a)"
|
||||
:aria-busy="busy(a)"
|
||||
:data-test="`action-${a.id}`"
|
||||
@click="press(a)"
|
||||
>
|
||||
<FontAwesomeIcon v-if="busy(a)" :icon="faSpinner" spin aria-hidden="true" />
|
||||
<FontAwesomeIcon
|
||||
:icon="busy(a) ? faSpinner : faScrewdriverWrench"
|
||||
:spin="busy(a)"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
{{ a.label }}
|
||||
</Button>
|
||||
<Badge v-if="busy(a)" variant="secondary" data-test="action-status">Sending</Badge>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { onBeforeUnmount, onMounted, ref, type Ref } from 'vue'
|
||||
|
||||
/** 1 column below the breakpoint, 2 at or above it; follows the viewport live. */
|
||||
export function useColumns(minWidth = '(min-width: 96rem)'): Ref<number> {
|
||||
export function useColumns(minWidth = '(min-width: 90rem)'): Ref<number> {
|
||||
const columns = ref(1)
|
||||
let query: MediaQueryList | null = null
|
||||
const update = () => {
|
||||
|
||||
+1
-2
@@ -13,8 +13,7 @@
|
||||
"verbatimModuleSyntax": true,
|
||||
"jsx": "preserve",
|
||||
"types": ["vite/client", "node"],
|
||||
"baseUrl": ".",
|
||||
"paths": { "@/*": ["src/*"] }
|
||||
"paths": { "@/*": ["./src/*"] }
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.vue", "vite.config.ts"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user