From 24ae6d8dcbbcd53f2abcb21b6c1f24e58ef53dff Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 23 Dec 2025 02:56:03 +0000 Subject: [PATCH 01/23] Initial plan From 4ca5d314c489ddd9c2e50b17dc0dae7054b81452 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 23 Dec 2025 03:03:50 +0000 Subject: [PATCH 02/23] Add source detail view and update SourceCard with running job link Co-authored-by: xiaoland <37663413+xiaoland@users.noreply.github.com> --- src/business/info-base/source.ts | 40 ++ .../source/newCollectJob/newCollectJob.md | 25 + .../source/newCollectJob/newCollectJob.scss | 12 + .../source/newCollectJob/newCollectJob.ts | 15 + .../source/newCollectJob/newCollectJob.vue | 43 ++ .../source/sourceCard/sourceCard.scss | 12 + .../source/sourceCard/sourceCard.vue | 27 ++ src/locales/en.json | 23 +- src/router.ts | 6 + src/views/sources/source/source.md | 40 ++ src/views/sources/source/source.scss | 264 +++++++++++ src/views/sources/source/source.ts | 6 + src/views/sources/source/source.vue | 428 ++++++++++++++++++ 13 files changed, 940 insertions(+), 1 deletion(-) create mode 100644 src/components/info-base/source/newCollectJob/newCollectJob.md create mode 100644 src/components/info-base/source/newCollectJob/newCollectJob.scss create mode 100644 src/components/info-base/source/newCollectJob/newCollectJob.ts create mode 100644 src/components/info-base/source/newCollectJob/newCollectJob.vue create mode 100644 src/views/sources/source/source.md create mode 100644 src/views/sources/source/source.scss create mode 100644 src/views/sources/source/source.ts create mode 100644 src/views/sources/source/source.vue diff --git a/src/business/info-base/source.ts b/src/business/info-base/source.ts index 45309b0..68fcdfb 100644 --- a/src/business/info-base/source.ts +++ b/src/business/info-base/source.ts @@ -186,6 +186,46 @@ export class SourceCollectJob extends Z.class({ ); } + static async getBySource( + sourceId: SourceRef, + options?: { + limit?: number; + offset?: number; + order?: "asc" | "desc"; + } + ): Promise<{ data: SourceCollectJob[]; count: number }> { + const { limit = 10, offset = 0, order = "desc" } = options || {}; + const query = this.dbApi + .from() + .select("*", { count: "exact" }) + .eq("source", sourceId) + .order("created_at", { ascending: order === "asc" }) + .range(offset, offset + limit - 1); + + const result = await query; + return { + data: (result.data || []).map((d) => new SourceCollectJob(d)), + count: result.count || 0, + }; + } + + static async getLatestRunningBySource( + sourceId: SourceRef + ): Promise { + const result = await this.dbApi + .from() + .select() + .eq("source", sourceId) + .eq("status", SourceCollectJobStatus.RUNNING) + .order("created_at", { ascending: false }) + .limit(1); + + if (result.data && result.data.length > 0) { + return new SourceCollectJob(result.data[0]); + } + return null; + } + public async getLogs(options?: { limit?: number; cursor?: number; diff --git a/src/components/info-base/source/newCollectJob/newCollectJob.md b/src/components/info-base/source/newCollectJob/newCollectJob.md new file mode 100644 index 0000000..5d0eb69 --- /dev/null +++ b/src/components/info-base/source/newCollectJob/newCollectJob.md @@ -0,0 +1,25 @@ +# newCollectJob + +## Rationale + +Provides a simple form interface to create a new source collect job. + +## Goals + +Allow users to create a new collect job for a source. + +## Specification + +- Simple form with minimal configuration +- Uses source ID as a prop +- Emits `create` event when job is created with the created job object + +## Implementation + +### Props + +- `sourceId` (`number`, required): ID of the source to create job for + +### Events + +- `create(job: SourceCollectJob)`: Emitted when a new job is created diff --git a/src/components/info-base/source/newCollectJob/newCollectJob.scss b/src/components/info-base/source/newCollectJob/newCollectJob.scss new file mode 100644 index 0000000..6e19edc --- /dev/null +++ b/src/components/info-base/source/newCollectJob/newCollectJob.scss @@ -0,0 +1,12 @@ +.new-collect-job { + display: flex; + flex-direction: column; + gap: sys-var(space, md); + padding: sys-var(space, md); + + &__description { + @include apply-font(body-md); + color: sys-var(color, text, base); + margin: 0; + } +} diff --git a/src/components/info-base/source/newCollectJob/newCollectJob.ts b/src/components/info-base/source/newCollectJob/newCollectJob.ts new file mode 100644 index 0000000..2b08396 --- /dev/null +++ b/src/components/info-base/source/newCollectJob/newCollectJob.ts @@ -0,0 +1,15 @@ +import type { PropType } from "vue"; +import { SourceCollectJob } from "@/business/info-base/source"; + +// --- Props --- +export const newCollectJobProps = { + sourceId: { + type: Number as PropType, + required: true, + }, +} as const; + +// --- Emits --- +export const newCollectJobEmits = { + create: (job: SourceCollectJob) => true, +} as const; diff --git a/src/components/info-base/source/newCollectJob/newCollectJob.vue b/src/components/info-base/source/newCollectJob/newCollectJob.vue new file mode 100644 index 0000000..2820157 --- /dev/null +++ b/src/components/info-base/source/newCollectJob/newCollectJob.vue @@ -0,0 +1,43 @@ + + + + +