diff --git a/.env.example b/.env.example index 852cc1e88..b1f6a988b 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,5 @@ # Immutable image reference built by CI (use a sha-* tag or @sha256 digest) -APP_IMAGE=ghcr.io/your-org/projectx:sha- +APP_IMAGE=ghcr.io/your-org/bookorbit:sha- # App publish port on host APP_PORT=3000 @@ -17,9 +17,9 @@ PGID=1000 NODE_MAX_OLD_SPACE_SIZE=2048 # Database credentials -POSTGRES_USER=projectx +POSTGRES_USER=bookorbit POSTGRES_PASSWORD=change-this-password -POSTGRES_DB=projectx +POSTGRES_DB=bookorbit # App secrets JWT_SECRET=change-this-to-a-long-random-secret @@ -27,21 +27,21 @@ JWT_SECRET=change-this-to-a-long-random-secret SETUP_BOOTSTRAP_TOKEN=change-this-to-a-long-random-secret # External/public URL used by emails and Kobo endpoints -APP_URL=https://projectx.example.com +APP_URL=https://bookorbit.example.com # --- Optional overrides (uncomment to set) --- # If you already run your own PostgreSQL, set DATABASE_URL and remove the # postgres service from docker-compose.yml. Your instance must have the # uuid-ossp, pg_trgm, and vector (pgvector) extensions available. -# DATABASE_URL=postgres://user:password@yourhost:5432/projectx +# DATABASE_URL=postgres://user:password@yourhost:5432/bookorbit # Or set individual parts (POSTGRES_HOST, POSTGRES_PORT, POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB) # CORS origin for the frontend when served from a different domain than APP_URL # CLIENT_URL=https://app.example.com # Set to false only if your platform manages bind mount ownership externally. -# PROJECTX_FIX_PERMISSIONS=true +# BOOKORBIT_FIX_PERMISSIONS=true # Recommended if you store SMTP provider credentials (generate: openssl rand -hex 32) # EMAIL_ENCRYPTION_KEY= diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index f6526f09d..1b7015fd2 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,5 +1,5 @@ name: Bug Report -description: Report a bug in ProjectX +description: Report a bug in BookOrbit title: "[Bug] " labels: ["bug"] body: @@ -35,7 +35,7 @@ body: attributes: label: Your setup placeholder: | - - ProjectX version/image tag: latest + - BookOrbit version/image tag: latest - Deployment: Docker / manual - OS: Ubuntu 22.04 - Browser: Firefox 124 diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 88a4f6dcb..961022cc5 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,5 +1,5 @@ name: Feature Request -description: Suggest a new feature or improvement for ProjectX +description: Suggest a new feature or improvement for BookOrbit title: "[Feature] " labels: ["feature"] body: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fd65c57a5..bee30c1fa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -220,7 +220,7 @@ jobs: if [[ "$PACKAGE" == "server" ]]; then pnpm --filter server type-check else - pnpm --filter @projectx/types build + pnpm --filter @bookorbit/types build pnpm --filter client type-check fi diff --git a/.github/workflows/e2e-runner.yml b/.github/workflows/e2e-runner.yml index e45c8bbb4..543201aa6 100644 --- a/.github/workflows/e2e-runner.yml +++ b/.github/workflows/e2e-runner.yml @@ -30,7 +30,7 @@ env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" NODE_VERSION: "24" PNPM_VERSION: "10" - E2E_DATABASE_URL: postgres://projectx:projectx@localhost:5432/projectx_e2e + E2E_DATABASE_URL: postgres://bookorbit:bookorbit@localhost:5432/bookorbit_e2e NODE_ENV: test JWT_SECRET: scanner-e2e-secret-1234 JWT_EXPIRES_IN: 15m @@ -47,13 +47,13 @@ jobs: postgres: image: pgvector/pgvector:pg16 env: - POSTGRES_USER: projectx - POSTGRES_PASSWORD: projectx - POSTGRES_DB: projectx + POSTGRES_USER: bookorbit + POSTGRES_PASSWORD: bookorbit + POSTGRES_DB: bookorbit ports: - 5432:5432 options: >- - --health-cmd="pg_isready -U projectx" + --health-cmd="pg_isready -U bookorbit" --health-interval=5s --health-timeout=5s --health-retries=20 diff --git a/AI_POLICY.md b/AI_POLICY.md index 9af991610..1ca4d224e 100644 --- a/AI_POLICY.md +++ b/AI_POLICY.md @@ -1,6 +1,6 @@ # AI Usage Policy -ProjectX is maintained by real people. Every pull request, issue, and discussion is read and reviewed by humans who give their time to this project. Submitting unreviewed, untested AI output shifts the burden of that review onto maintainers - that is the problem this policy addresses. It is not a problem with AI tools themselves. +BookOrbit is maintained by real people. Every pull request, issue, and discussion is read and reviewed by humans who give their time to this project. Submitting unreviewed, untested AI output shifts the burden of that review onto maintainers - that is the problem this policy addresses. It is not a problem with AI tools themselves. ## The Rules @@ -39,9 +39,9 @@ AI tools make specific, recurring mistakes on this codebase. Be especially caref **NestJS decorator and module mistakes.** AI frequently invents decorator options, misuses pipes, omits required module imports, or generates module wiring that looks plausible but is wrong. Check every decorator and every module registration. -**Ownership and multi-tenancy logic.** ProjectX is a multi-user app. Every query that touches user-owned data must filter by `userId`. AI-generated service methods routinely omit this. A missed ownership check is a data exposure bug, not a style issue. This applies to every module that manages libraries, books, collections, reading sessions, annotations, and preferences. +**Ownership and multi-tenancy logic.** BookOrbit is a multi-user app. Every query that touches user-owned data must filter by `userId`. AI-generated service methods routinely omit this. A missed ownership check is a data exposure bug, not a style issue. This applies to every module that manages libraries, books, collections, reading sessions, annotations, and preferences. -**Authorization patterns.** We have specific conventions for permission gates: `@RequirePermission(...)` on the backend, `usePermissions()` on the frontend, and the `LensService` superuser-bypass pattern. AI does not know these patterns and will generate code that bypasses them or reimplements them incorrectly. Write auth and permission logic yourself. +**Authorization patterns.** We have specific conventions for permission gates: `@RequirePermission(...)` on the backend, `usePermissions()` on the frontend, and the `SmartScopeService` superuser-bypass pattern. AI does not know these patterns and will generate code that bypasses them or reimplements them incorrectly. Write auth and permission logic yourself. **Tests that prove nothing.** AI-generated tests often mock the exact thing being tested, assert on shallow output without triggering the real path, or simply confirm that a function returns without throwing. Before submitting a test, ask: would this test fail if the implementation were broken? If the answer is no, the test is not worth having. diff --git a/COMMIT_GUIDELINES.md b/COMMIT_GUIDELINES.md index bb2563f68..2262321c6 100644 --- a/COMMIT_GUIDELINES.md +++ b/COMMIT_GUIDELINES.md @@ -30,7 +30,7 @@ The **footer** is optional. Use it to reference issues, close PRs, or document b │ └─ Scope (optional): auth|books|library|metadata|kobo|opds|reader| │ collections|annotations|authors|series|cover| │ users|stats|notifications|settings|scanner| - │ email|audit|lens|types|docker|deps|server|client + │ email|audit|smart-scope|types|docker|deps|server|client │ └─ Type: feat|fix|db|perf|refactor|style|docs|test|build|ci|chore|security|revert ``` @@ -86,7 +86,7 @@ Use one scope from the table below. If a change affects multiple areas, use the | `scanner` | File scanner and upload pipeline | | `email` | Email providers, templates, and send preferences | | `audit` | Audit logging and event tracking | -| `lens` | Custom lenses and collection views | +| `smart-scope` | Custom Smart Scopes and collection views | | `types` | Shared types in `packages/types/` | | `docker` | Dockerfile and Docker Compose files | | `deps` | Dependency upgrades (pair with `build` or `chore`) | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 33d2b684e..2376d0af0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ -# Contributing to ProjectX +# Contributing to BookOrbit -Thanks for your interest in contributing to ProjectX. Whether you are fixing a typo or building a major feature, this guide walks you through the process from start to finish. +Thanks for your interest in contributing to BookOrbit. Whether you are fixing a typo or building a major feature, this guide walks you through the process from start to finish. **Companion docs:** @@ -63,9 +63,9 @@ This step prevents wasted effort on changes that conflict with the project direc [Fork the repository](../../fork), then clone your fork: ```bash -git clone https://github.com//projectx.git -cd projectx -git remote add upstream https://github.com/neonsolstice/projectx.git +git clone https://github.com//bookorbit.git +cd bookorbit +git remote add upstream https://github.com/neonsolstice/bookorbit.git ``` > **Trusted contributors** with direct push access can skip the fork and work on branches in the main repository. The rest of this guide assumes the fork workflow. @@ -228,7 +228,7 @@ Do not add dependencies without prior discussion in the linked issue. If proposi ### Breaking Changes and Self-Hosted Upgrades -ProjectX is self-hosted. Any change that can break existing deployments must include a clear upgrade path before merge. +BookOrbit is self-hosted. Any change that can break existing deployments must include a clear upgrade path before merge. If your PR introduces a breaking change (schema, API contract, environment variable, config format): diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index c3e24b272..b0daf62b7 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -8,7 +8,7 @@ For the contribution process (issues, PRs, review), see [CONTRIBUTING.md](CONTRI ## Architecture Overview -ProjectX is a pnpm monorepo with three workspaces: a Vue 3 single-page app, a NestJS API server, and a shared types package. +BookOrbit is a pnpm monorepo with three workspaces: a Vue 3 single-page app, a NestJS API server, and a shared types package. ```mermaid graph LR @@ -16,7 +16,7 @@ graph LR Server["Server
NestJS + Fastify
localhost:3000/api"] DB["PostgreSQL
Drizzle ORM"] WS["WebSocket
Socket.IO"] - Types["Shared Types
@projectx/types"] + Types["Shared Types
@bookorbit/types"] Client -- "HTTP (fetch)" --> Server Client <-. "real-time events" .-> WS @@ -39,7 +39,7 @@ graph LR ## Project Structure ```text -projectx/ +bookorbit/ ├── client/ # Vue 3 frontend │ └── src/ │ ├── features/ # Feature modules (composables + components) @@ -60,14 +60,14 @@ projectx/ │ └── *.e2e-spec.ts # E2E test suites ├── packages/ │ └── types/ # Shared TypeScript types -│ └── src/ # Exported via @projectx/types +│ └── src/ # Exported via @bookorbit/types ├── scripts/ # Bootstrap, DB reset, E2E orchestration ├── docker/ # Postgres init scripts (extensions) ├── .github/ # CI workflows, PR/issue templates └── .husky/ # Git hooks (pre-commit, pre-push) ``` -> **Shared types** live in `packages/types/` and are imported as `@projectx/types`. Never duplicate types between client and server. +> **Shared types** live in `packages/types/` and are imported as `@bookorbit/types`. Never duplicate types between client and server. --- @@ -96,8 +96,8 @@ This runs all the steps below automatically. If it succeeds, skip to [Running th #### Step 1 - Clone the repository ```bash -git clone https://github.com//projectx.git -cd projectx +git clone https://github.com//bookorbit.git +cd bookorbit ``` If you are an external contributor, fork first and clone your fork. See [CONTRIBUTING.md](CONTRIBUTING.md) for details. @@ -160,11 +160,11 @@ If everything worked, you will see the server, client, and types watcher start u ### Verifying Your Setup -| Check | Expected | -| ---------------------------------------- | ------------------------------------------- | -| Open http://localhost:5173 | ProjectX login page loads | -| Open http://localhost:3000/api/v1/health | Returns `{"status":"ok"}` | -| `docker ps` | Shows `projectx-postgres` container running | +| Check | Expected | +| ---------------------------------------- | ------------------------------------------ | +| Open http://localhost:5173 | BookOrbit login page loads | +| Open http://localhost:3000/api/v1/health | Returns `{"status":"ok"}` | +| `docker ps` | Shows `bookorbit-dev-db` container running | --- @@ -198,7 +198,7 @@ If you are editing shared types (`packages/types/`), also start the types watche ```bash # Terminal 3: Types (only needed when editing packages/types/) -pnpm --filter @projectx/types dev +pnpm --filter @bookorbit/types dev ``` @@ -209,14 +209,14 @@ pnpm --filter @projectx/types dev These are the variables you are most likely to need during development. See `server/.env.example` for the full list with comments. -| Variable | Purpose | Default (dev) | -| --------------- | ---------------------------------- | ------------------------------------------------------ | -| `DATABASE_URL` | PostgreSQL connection string | `postgres://projectx:projectx@localhost:5432/projectx` | -| `PORT` | Server listen port | `3000` | -| `NODE_ENV` | Runtime mode | `development` | -| `JWT_SECRET` | Signing key for auth tokens | `change-me-in-production` | -| `APP_DATA_PATH` | Storage for covers, avatars, cache | `../local/data` | -| `APP_URL` | Base URL for email links | `http://localhost:5173` | +| Variable | Purpose | Default (dev) | +| --------------- | ---------------------------------- | --------------------------------------------------------- | +| `DATABASE_URL` | PostgreSQL connection string | `postgres://bookorbit:bookorbit@localhost:5432/bookorbit` | +| `PORT` | Server listen port | `3000` | +| `NODE_ENV` | Runtime mode | `development` | +| `JWT_SECRET` | Signing key for auth tokens | `change-me-in-production` | +| `APP_DATA_PATH` | Storage for covers, avatars, cache | `../local/data` | +| `APP_URL` | Base URL for email links | `http://localhost:5173` | --- diff --git a/README.md b/README.md index 533b5f507..46b2806d7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# ProjectX +# BookOrbit -[![CI](https://github.com/neonsolstice/projectx/actions/workflows/ci.yml/badge.svg)](https://github.com/neonsolstice/projectx/actions/workflows/ci.yml) +[![CI](https://github.com/neonsolstice/bookorbit/actions/workflows/ci.yml/badge.svg)](https://github.com/neonsolstice/bookorbit/actions/workflows/ci.yml) A self-hostable book and library management app with Kobo device support. Organize your epub, pdf, and cbz collections, track reading progress, and sync with your Kobo. @@ -19,8 +19,8 @@ A self-hostable book and library management app with Kobo device support. Organi ### Setup ```bash -git clone projectx -cd projectx +git clone bookorbit +cd bookorbit pnpm setup ``` @@ -62,11 +62,11 @@ Both must be running. The client proxies all `/api` and `/socket.io` requests to ## Project Structure ``` -projectx/ +bookorbit/ ├── client/ Vue 3 frontend (Vite + Tailwind CSS v4) ├── server/ NestJS 11 backend (Fastify + Drizzle ORM) ├── packages/ -│ └── types/ Shared TypeScript types (@projectx/types) +│ └── types/ Shared TypeScript types (@bookorbit/types) ├── docker/ │ └── postgres/ Postgres init scripts (extensions) ├── local/ Local dev data (covers, docs) - gitignored @@ -82,7 +82,7 @@ This is a **pnpm workspace**. The three packages are: - **`server/`** - NestJS API. Modules live in `src/modules/`, one folder per feature. Database schema is in `src/db/schema/`. - **`client/`** - Vue 3 SPA. Feature code lives in `src/features/`, shared components in `src/components/ui/`. -- **`packages/types/`** - Shared types imported as `@projectx/types` by both server and client. Add any type that crosses the API boundary here. +- **`packages/types/`** - Shared types imported as `@bookorbit/types` by both server and client. Add any type that crosses the API boundary here. --- @@ -203,7 +203,7 @@ The fastest way to learn the patterns is to follow an existing module: - **Backend:** Look at `server/src/modules/bookmark/` for a minimal example (controller, service, repository, DTO, module). Copy it, rename, and adapt. - **Frontend:** Look at `client/src/features/collection/` for a full feature (composables for state/API, components for UI). -- **Shared types:** If the feature adds API request/response shapes, add them in `packages/types/src/` and import via `@projectx/types`. +- **Shared types:** If the feature adds API request/response shapes, add them in `packages/types/src/` and import via `@bookorbit/types`. --- @@ -211,16 +211,16 @@ The fastest way to learn the patterns is to follow an existing module: Server environment is configured in `server/.env` for local development. Production compose uses the repo-root `.env` created from `.env.example`. -| Variable | Default | Description | -| ------------------------- | ------------------------------------------------------ | ---------------------------------------------------------- | -| `DATABASE_URL` | `postgres://projectx:projectx@localhost:5432/projectx` | PostgreSQL connection string | -| `PORT` | `3000` | Server port | -| `NODE_ENV` | `development` | Environment mode | -| `JWT_SECRET` | `change-me-in-production` | JWT signing secret | -| `SETUP_BOOTSTRAP_TOKEN` | (empty) | Required in production for initial `/api/v1/auth/setup` | -| `APP_DATA_PATH` | `../local/data` | App data directory for cover images (not where books live) | -| `APP_URL` | `http://localhost:5173` | Client URL (used in emails) | -| `NODE_MAX_OLD_SPACE_SIZE` | `2048` | Docker Node.js heap limit in MB | +| Variable | Default | Description | +| ------------------------- | --------------------------------------------------------- | ---------------------------------------------------------- | +| `DATABASE_URL` | `postgres://bookorbit:bookorbit@localhost:5432/bookorbit` | PostgreSQL connection string | +| `PORT` | `3000` | Server port | +| `NODE_ENV` | `development` | Environment mode | +| `JWT_SECRET` | `change-me-in-production` | JWT signing secret | +| `SETUP_BOOTSTRAP_TOKEN` | (empty) | Required in production for initial `/api/v1/auth/setup` | +| `APP_DATA_PATH` | `../local/data` | App data directory for cover images (not where books live) | +| `APP_URL` | `http://localhost:5173` | Client URL (used in emails) | +| `NODE_MAX_OLD_SPACE_SIZE` | `2048` | Docker Node.js heap limit in MB | ## Production Deploy @@ -243,7 +243,7 @@ For production compose, `BOOKS_HOST_PATH` is the only host folder most users nee Generated app data and PostgreSQL live in explicit folders beside the compose file: ```text -./data/app generated covers, author images, staging files, and Book Bucket uploads +./data/app generated covers, author images, staging files, and Book Dock uploads ./data/postgres PostgreSQL data ``` @@ -297,7 +297,7 @@ pnpm db:reset - **Backend:** NestJS 11 on Fastify. Global prefix `/api`. Auth via JWT (access + refresh tokens in httpOnly cookies). RBAC with permissions system. - **Frontend:** Vue 3 Composition API (` diff --git a/client/package.json b/client/package.json index d24fbdd61..5a0353654 100644 --- a/client/package.json +++ b/client/package.json @@ -25,13 +25,13 @@ "dependencies": { "@fontsource-variable/fraunces": "^5.2.9", "@fontsource-variable/inter": "^5.2.8", - "@projectx/types": "workspace:*", - "@tailwindcss/vite": "^4.2.2", + "@bookorbit/types": "workspace:*", + "@tailwindcss/vite": "^4.2.3", "@types/howler": "^2.2.12", "@vueuse/core": "^14.2.1", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", - "dompurify": "^3.3.3", + "dompurify": "^3.4.0", "driver.js": "^1.4.0", "echarts": "^6.0.0", "howler": "^2.2.4", @@ -41,7 +41,7 @@ "reka-ui": "^2.9.6", "socket.io-client": "^4.8.3", "tailwind-merge": "^3.5.0", - "tailwindcss": "^4.2.2", + "tailwindcss": "^4.2.3", "vue": "^3.5.32", "vue-draggable-plus": "^0.6.1", "vue-echarts": "8.1.0-beta.2", @@ -56,25 +56,25 @@ "@types/node": "^25.6.0", "@vitejs/plugin-vue": "^6.0.6", "@vitest/coverage-v8": "^4.1.4", - "@vitest/eslint-plugin": "^1.6.15", + "@vitest/eslint-plugin": "^1.6.16", "@vue/eslint-config-typescript": "^14.7.0", "@vue/test-utils": "^2.4.6", "@vue/tsconfig": "^0.9.1", - "eslint": "^10.2.0", + "eslint": "^10.2.1", "eslint-config-prettier": "^10.1.8", - "eslint-plugin-oxlint": "~1.60.0", + "eslint-plugin-oxlint": "~1.61.0", "eslint-plugin-vue": "~10.8.0", "jiti": "^2.6.1", "jsdom": "^29.0.2", "npm-run-all2": "^8.0.4", - "oxlint": "~1.60.0", - "prettier": "3.8.2", + "oxlint": "~1.61.0", + "prettier": "3.8.3", "tw-animate-css": "^1.4.0", "typescript": "~5.9.3", - "vite": "^8.0.8", + "vite": "^8.0.9", "vite-plugin-vue-devtools": "^8.1.1", "vitest": "^4.1.4", - "vue-tsc": "^3.2.6" + "vue-tsc": "^3.2.7" }, "engines": { "node": "^20.19.0 || >=22.12.0" diff --git a/client/src/App.vue b/client/src/App.vue index 341648579..38112bda3 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -3,7 +3,7 @@ import { computed, provide } from 'vue' import { INIT_OPTIONS_KEY, THEME_KEY } from 'vue-echarts' import { useChangePasswordDialog } from '@/composables/useChangePasswordDialog' import { useThemeStore } from '@/stores/theme' -import { getProjectxThemeName, initChartThemes } from '@/lib/echarts' +import { getBookorbitThemeName, initChartThemes } from '@/lib/echarts' import ChangePasswordDialog from '@/features/auth/ChangePasswordDialog.vue' import { Toaster } from '@/components/ui/sonner' import { TooltipProvider } from '@/components/ui/tooltip' @@ -16,7 +16,7 @@ initChartThemes() provide(INIT_OPTIONS_KEY, { renderer: 'svg' }) provide( THEME_KEY, - computed(() => getProjectxThemeName(themeStore.theme, themeStore.accent)), + computed(() => getBookorbitThemeName(themeStore.theme, themeStore.accent)), ) diff --git a/client/src/components/AppHeader.vue b/client/src/components/AppHeader.vue index b539388dd..8b2ced9f4 100644 --- a/client/src/components/AppHeader.vue +++ b/client/src/components/AppHeader.vue @@ -30,11 +30,11 @@ import { useChangePasswordDialog } from '@/composables/useChangePasswordDialog' import { usePermissions } from '@/features/auth/composables/usePermissions' import BookUploadModal from '@/features/library/components/BookUploadModal.vue' import { useLibraryUploadEvents } from '@/features/library/composables/useLibraryUploadEvents' -import { useBookBucketSummary } from '@/features/book-bucket/composables/useBookBucketSummary' +import { useBookDockSummary } from '@/features/book-dock/composables/useBookDockSummary' import NotificationSheet from '@/features/notifications/components/NotificationSheet.vue' import { useNotifications } from '@/features/notifications/composables/useNotifications' import UserAvatar from '@/components/UserAvatar.vue' -import { DEFAULT_FORMAT_PRIORITY } from '@projectx/types' +import { DEFAULT_FORMAT_PRIORITY } from '@bookorbit/types' import { useThemeStore } from '@/stores/theme' const router = useRouter() @@ -43,17 +43,17 @@ const { user, logout } = useAuth() const { open: openChangePassword } = useChangePasswordDialog() const { hasPermission } = usePermissions() const { onLibraryUploadCompleted } = useLibraryUploadEvents() -const { summary: bookBucketSummary, fetchSummary: fetchBookBucketSummary, subscribe: subscribeBookBucketSummary } = useBookBucketSummary() +const { summary: bookDockSummary, fetchSummary: fetchBookDockSummary, subscribe: subscribeBookDockSummary } = useBookDockSummary() const { subscribe: subscribeNotifications } = useNotifications() const themeStore = useThemeStore() -const isBookBucketActive = computed(() => route.name === 'book-bucket') +const isBookDockActive = computed(() => route.name === 'book-dock') const isStatisticsActive = computed(() => route.name === 'statistics') const iconRadiusClass = computed(() => (themeStore.radius === 'sharp' ? 'rounded-none' : 'rounded-full')) -function navigateToBookBucket() { - router.push({ name: 'book-bucket' }) +function navigateToBookDock() { + router.push({ name: 'book-dock' }) } function navigateToStatistics() { @@ -151,9 +151,9 @@ function handleGlobalKeydown(e: KeyboardEvent) { onMounted(() => { window.addEventListener('keydown', handleGlobalKeydown) - if (hasPermission('book_bucket_access')) { - fetchBookBucketSummary() - subscribeBookBucketSummary() + if (hasPermission('book_dock_access')) { + fetchBookDockSummary() + subscribeBookDockSummary() } if (hasPermission('notification_access')) { subscribeNotifications() @@ -459,14 +459,14 @@ function formatBadgeClass(fmt: string): string { - + - Book Bucket + Book Dock - {{ bookBucketSummary.total }} + {{ bookDockSummary.total }} @@ -514,34 +514,34 @@ function formatBadgeClass(fmt: string): string { - +