Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ coverage
.github
.specify
auto-imports.d.ts
components.d.ts
components.d.ts
pnpm-lock.yaml
29 changes: 28 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,39 @@
- `pnpm vue-tsc --noEmit` – perform a strict type check.
- `pnpm lint` – run `vue-tsc` and Prettier (format check only).

## Mandatory Code Quality Checks

**⚠️ CRITICAL: These checks MUST pass before every commit.**

Before committing any code changes, you MUST run and pass:

1. **Lockfile Sync Check**: `pnpm install --frozen-lockfile`
- Ensures `pnpm-lock.yaml` is in sync with `package.json`
- **MUST run `pnpm install` after modifying `package.json` and commit the updated `pnpm-lock.yaml`**
- CI will fail if lockfile is out of sync

2. **TypeScript Type Check**: `pnpm vue-tsc --noEmit`
- Ensures all TypeScript types are correct
- Must have zero errors before committing

3. **Prettier Format Check**: `pnpm prettier --check .`
- Ensures all code follows formatting standards
- If it fails, run `pnpm lint:fix` to auto-fix formatting issues

**Automated Enforcement**: The pre-commit hook (`scripts/pre-commit-check.sh`) automatically runs these checks. If any check fails, the commit will be blocked.

**Quick Fix Command**: If checks fail:

1. Run `pnpm install` to sync lockfile (if package.json changed)
2. Run `pnpm lint:fix` to auto-fix formatting
3. Address any TypeScript errors manually

## Coding Style & Naming Conventions

- Use Prettier defaults (see `.prettierrc.ts`); run `pnpm lint` or `pnpm lint:fix`.
- **Always run `pnpm run lint:fix` after making code changes to ensure formatting compliance before committing.**
- Vue files use `<script setup>` with TypeScript; prefer composables for shared logic.
- Component files use **kebab-case** (e.g. `bucket-selector.vue`), but reference them using **StudlyCase** in templates (e.g. `<BucketSelector />`).
- Component files use **kebab-case** (e.g. `bucket-selector.vue`), but reference them using **StudlyCase** in templates (e.g., `<BucketSelector />`).
- Override shadcn primitives **outside** `components/ui/`; never edit files in that directory directly.
- Render tabular data with the shared `DataTable` + `useDataTable` utilities unless a specific requirement makes them unsuitable.
- Language pack files should exclude test directories when processing translation keys.
Expand Down
145 changes: 0 additions & 145 deletions CLAUDE.md

This file was deleted.

19 changes: 0 additions & 19 deletions components/object/delete/stats.vue

This file was deleted.

38 changes: 0 additions & 38 deletions components/object/delete/task/item.vue

This file was deleted.

15 changes: 0 additions & 15 deletions components/object/delete/task/list.vue

This file was deleted.

42 changes: 24 additions & 18 deletions components/object/list.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@
</label>
</div>
<template #actions>
<object-upload-stats />
<object-delete-stats />
<object-task-stats :tasks="taskStore.tasks" :on-clear-tasks="taskStore.clearTasks">
<template #task-list="{ tasks }">
<object-task-list :tasks="tasks" />
</template>
</object-task-stats>
<!-- <Button variant="outline" @click="() => handleNewObject(true)">
<Icon name="ri:add-line" class="size-4" />
<span>{{ t('New Folder') }}</span>
Expand Down Expand Up @@ -102,9 +105,8 @@ import { saveAs } from 'file-saver'
import JSZip from 'jszip'
import { joinRelativeURL } from 'ufo'
import type { VNode } from 'vue'
import { computed, h, ref, watch } from 'vue'
import { useDeleteTaskManagerStore } from '~/store/delete-tasks'
import { useUploadTaskManagerStore } from '~/store/upload-tasks'
import { computed, h, onMounted, onUnmounted, ref, watch } from 'vue'
import { useTaskManagerStore } from '~/store/tasks'

const { $s3Client } = useNuxtApp()
const { t } = useI18n()
Expand Down Expand Up @@ -139,8 +141,7 @@ watch(searchTerm, () => {
handleSearch()
})

const uploadTaskStore = useUploadTaskManagerStore()
const deleteTaskStore = useDeleteTaskManagerStore()
const taskStore = useTaskManagerStore()

type ObjectRow = {
Key: string
Expand Down Expand Up @@ -352,17 +353,22 @@ const { table, selectedRowIds } = useDataTable<ObjectRow>({
// Use selectedRowIds from data-table instead of manually maintaining checkedKeys
const checkedKeys = computed(() => selectedRowIds.value)

watch(
() => uploadTaskStore.tasks,
() => setTimeout(() => refresh(), 500),
{ deep: true }
)
// 监听任务完成事件,只在所有任务完成时刷新列表
// 这样可以避免在上传/删除大量文件时频繁刷新
// 保存事件处理函数引用,以便在卸载时正确清理
const handleAllTasksCompleted = () => {
refresh()
}

watch(
() => deleteTaskStore.tasks,
() => setTimeout(() => refresh(), 500),
{ deep: true }
)
onMounted(() => {
// 监听所有任务全部完成事件(上传/删除)
taskStore.on('drained', handleAllTasksCompleted)
})

onUnmounted(() => {
// 清理事件监听器
taskStore.off('drained', handleAllTasksCompleted)
})

const goToNextPage = () => {
if (!nextToken.value) return
Expand Down Expand Up @@ -518,7 +524,7 @@ const handleDelete = async (keys: string[]) => {
if (!targets.length) {
message.success(t('Delete Success'))
} else {
deleteTaskStore.addKeys(targets, bucketName.value)
taskStore.addDeleteKeys(targets, bucketName.value)
message.success(t('Delete task created'))
}
table.resetRowSelection()
Expand Down
Loading
Loading