Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
24ae6d8
Initial plan
Copilot Dec 23, 2025
4ca5d31
Add source detail view and update SourceCard with running job link
Copilot Dec 23, 2025
f01fb20
Make SourceCard clickable to navigate to detail view and add Chinese …
Copilot Dec 23, 2025
17c9266
Fix router order to prevent route matching issues
Copilot Dec 23, 2025
d24636a
Address code review feedback: use absolute imports, add i18n, improve…
Copilot Dec 23, 2025
5b34ebb
Rename newCollectJob to collectJobForm, add config field, extract sou…
Copilot Dec 23, 2025
c03f5ca
Fix code review issues: add config field, remove redundant handler, a…
Copilot Dec 23, 2025
6bfa4c2
Extract sourceCollectJobCard component and rename latestRunningJob to…
Copilot Dec 23, 2025
0698d7a
trivias fixes on sourceForm, collectJobForm
xiaoland Dec 23, 2025
b5d3cf3
Merge branch 'copilot/add-views-sources-index' of ssh://github.com/In…
xiaoland Dec 23, 2025
2e4493c
chore(sourceCard): checkRunningJob -> checkOpenJob
xiaoland Dec 23, 2025
32f5e33
upd(sourceCollectJob): add refresh-indicator
xiaoland Dec 23, 2025
a755266
trivias
xiaoland Dec 23, 2025
60e5d58
chore: update agent docs
xiaoland Dec 23, 2025
d8ebfd1
try fix copilot-setup-steps.yml
xiaoland Dec 23, 2025
268ab68
try fix copilot-setup-steps.yml
xiaoland Dec 23, 2025
b504c3a
add pnpm-lock.yaml
xiaoland Dec 23, 2025
48a27d6
rm pnpm-lock
xiaoland Dec 23, 2025
6ab2c97
try fix
xiaoland Dec 23, 2025
40a1acd
try fix
xiaoland Dec 23, 2025
0c7e5ca
Update copilot-setup-steps.yml
xiaoland Dec 23, 2025
45c548b
Update .npmrc
xiaoland Dec 23, 2025
64609d7
Update copilot-setup-steps.yml
xiaoland Dec 23, 2025
eec3721
Update copilot-setup-steps.yml
xiaoland Dec 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/instructions/comp-vue.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const emit = defineEmits(compNameEmits);

- Use `<span>` instead of `<p>` for inline text
- If template is duplicated inside a component and no third one will reuse it, define a reusable template inside the component scope using [VueUse createReusableTemplate](https://vueuse.org/core/createReusableTemplate/), instead of creating a new component.
- Use UnoCSS utility classes for simple styles, instead of writing custom CSS/SCSS.

### Naming

Expand Down
36 changes: 36 additions & 0 deletions .github/workflows/copilot-setup-steps.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: "Copilot Setup Steps"

on:
workflow_dispatch:
push:
paths:
- .github/workflows/copilot-setup-steps.yml
pull_request:
paths:
- .github/workflows/copilot-setup-steps.yml

jobs:
# The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot.
copilot-setup-steps:
runs-on: ubuntu-latest
permissions:
contents: read
packages: read

# These steps will run before agent starts
steps:
- name: Checkout code
uses: actions/checkout@v5

- name: Setup pnpm
uses: pnpm/action-setup@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"

- name: Install dependencies
run: pnpm install
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
11 changes: 8 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
pnpm-workspace.yaml

# Dependency directories
pnpm-workspace.yaml
node_modules
.DS_Store
pnpm-lock.yaml
package-lock.json

# Build output
dist
dist-ssr
coverage
Expand All @@ -31,8 +35,9 @@ coverage
*.sln
*.sw?

# others
.DS_Store
*.tsbuildinfo
pnpm-lock.yaml
.__mf__temp

# env files
Expand Down
3 changes: 2 additions & 1 deletion .npmrc
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
@inkcre:registry=https://npm.pkg.github.com
@inkcre:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}
42 changes: 25 additions & 17 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,50 @@
# InKCre Client-Web

This is a Vue SPA, provides an interface to interact with InKCre (an information management tool).
InKCre is an information management application aims to provides automatic information collection, organization and powerful use of information.
And this is the Vue implemetation of InKCre, mainly provides a GUI to manage info-base and use information.

## Tech Stacks

- Framework: Vue3 + TypeScript + Sass(scss) + Vite
- Framework: Vue3 + TypeScript + SCSS
- Routing: vue-router
- Internalization: vue-i18n
- Date and time: dayjs
- State management: pinia
- Packagae management: pnpm

## Business Domains

- obsrv: Observability
- extension
- source: Data collectors, the input of info-base
- info-base
- block
- relation
- resolver
- storage
- source
- sink
- block: Content units
- relation: Links between blocks
- storage: Store block content somewhere else than database.
- resolver: resolves block content
- sink: Interface to use information base, the output of info-base
- extension: extends info-base, source and sink abilities
- obsrv: Observability

## Source Structure

- `components/`: split by domain
- `components/`: split by business domain
- `views/`
- `business/`: api requests, business logic, split by domain
- `stores/`: split by domain
- `styles/`
- `utils/`: utilities, composables
- `locales/`: locale file, split by language
- `static/`
- router.ts
- `router.ts`

## Coding Guidelines

- Do not repeat yourself:
- Search across the codebase before you creating a new type or something might can be reused.
- Make the code reusable if it's used in over two places.
- [Write code for human](./.github/instructions/human-readable-code.instructions.md)

## Deployment

## Best Practices
This project supports following deployments:

- Search across the codebase before you creating a new type or something might can be reused.
- Common components should be stateless or avoid maintaining state as much as possible.
- Read more in `.github/instructions/`
- Cloudflare Worker
- Build and serve
2 changes: 2 additions & 0 deletions docs/todo.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@
- [ ] 时区转换有问题
- [x] LogsViewer 的滚动到底部实现有问题
- [x] pending job 不应该 poll logs
- [ ] InkPagination new type
- [ ] Source 不是 info-base 的一部分
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"@codemirror/lint": "^6.9.2",
"@codemirror/state": "^6.5.2",
"@codemirror/view": "^6.38.8",
"@inkcre/web-design": "^1.1.1",
"@inkcre/web-design": "^1.1.5",
"@module-federation/runtime": "^0.21.4",
"@supabase/postgrest-js": "^2.84.0",
"@vueuse/core": "^14.0.0",
Expand Down
41 changes: 41 additions & 0 deletions src/business/info-base/source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ export class SourceCollectJob extends Z.class({
.enum(SourceCollectJobStatus)
.default(SourceCollectJobStatus.PENDING),
state: z.looseObject({}).default(() => ({})),
config: z.looseObject({}).default(() => ({})),
}) {
static dbApi: DBAPIClient = new DBAPIClient(
"sources_collect_jobs",
Expand All @@ -186,6 +187,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 getLatestOpenBySource(
sourceId: SourceRef
): Promise<SourceCollectJob | null> {
const result = await this.dbApi
.from()
.select()
.eq("source", sourceId)
.in("status", [SourceCollectJobStatus.PENDING, 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;
Expand Down
26 changes: 26 additions & 0 deletions src/components/info-base/source/collectJobForm/collectJobForm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# collectJobForm

## Rationale

Provides a form interface to configure a source collect job.

## Goals

Allow users to configure collect job settings including config object.

## Specification

- Pure form component with v-model support
- Provides config editor (InkJsonEditor)
- No create/submit buttons - just form fields
- Parent component handles submission

## Implementation

### Props

- `modelValue` (`SourceCollectJobForm`, required): The form data object

### Events

- `update:modelValue(form: SourceCollectJobForm)`: Emitted when form data changes
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.collect-job-form {
display: flex;
flex-direction: column;
gap: sys-var(space, md);
}
15 changes: 15 additions & 0 deletions src/components/info-base/source/collectJobForm/collectJobForm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { PropType } from "vue";
import { SourceCollectJobForm } from "@/business/info-base/source";

// --- Props ---
export const collectJobFormProps = {
modelValue: {
type: Object as PropType<SourceCollectJobForm>,
required: true,
},
} as const;

// --- Emits ---
export const collectJobFormEmits = {
"update:modelValue": (form: SourceCollectJobForm) => true,
} as const;
32 changes: 32 additions & 0 deletions src/components/info-base/source/collectJobForm/collectJobForm.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<script setup lang="ts">
import { computed, ref, watch } from "vue";
import { useI18n } from "vue-i18n";
import { InkForm, InkJsonEditor } from "@inkcre/web-design";
import { collectJobFormProps, collectJobFormEmits } from "./collectJobForm";

const props = defineProps(collectJobFormProps);
const emit = defineEmits(collectJobFormEmits);
const { t } = useI18n();

const configJson = computed<string>({
get: () => {
return JSON.stringify(props.modelValue.config || {}, null, 2);
},
set: (newVal: string) => {
props.modelValue.config = JSON.parse(newVal);
},
});
</script>

<template>
<InkForm class="collect-job-form">
<InkJsonEditor
v-model="configJson"
:label="t('collectJob.config')"
:placeholder="t('source.configPlaceholder')"
:rows="6"
/>
</InkForm>
</template>

<style lang="scss" scoped src="./collectJobForm.scss" />
Loading