Skip to content

Conversation

@hmacr
Copy link
Contributor

@hmacr hmacr commented Nov 28, 2025

Closes SER-504

Screenshot

Loading

Screenshot 2025-12-05 at 1 39 29 PM

Loaded

Screenshot 2025-12-05 at 1 39 38 PM

Summary by CodeRabbit

  • New Features

    • Inline pagination controls and a total-results display for repository search.
  • Improvements

    • Search resets to first page when queries change.
    • Adjustable skeleton placeholders and cleaner, table-driven repository list rendering.
    • Deployment reference handling unified across template and VCS flows.
  • Chores

    • Updated package dependency source.

✏️ Tip: You can customize this high-level summary in your review settings.

@appwrite
Copy link

appwrite bot commented Nov 28, 2025

Console (appwrite/console)

Project ID: 688b7bf400350cbd60e9

Sites (1)
Site Status Logs Preview QR
 console-stage
688b7cf6003b1842c9dc
Failed Failed View Logs Preview URL QR Code

Tip

Silent mode disables those chatty PR comments if you prefer peace and quiet

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 28, 2025

Walkthrough

This PR updates the @appwrite.io/console dependency reference and adds paging to the Git repositories UI: repositories.svelte now uses offset/limit, a loadRepositoryPage function, displays total results, and shows PaginationInline. The repositories store adds a total field and broadens the repositories type to include framework/runtime variants. skeletonRepoList.svelte accepts a count prop. Multiple files replace Type with TemplateReferenceType and VCSDeploymentType with VCSReferenceType, and Query is newly imported where paging is used.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Verify repository paging logic in src/lib/components/git/repositories.svelte (offset/limit, loadRepositoryPage, search reset, total handling and table rendering).
  • Check store typing and initial value in src/routes/.../store.ts for consumers and union repository types.
  • Confirm skeletonRepoList.svelte count prop is used consistently where invoked.
  • Audit import/enum renames across files (Type → TemplateReferenceType; VCSDeploymentType → VCSReferenceType; new Query import) to ensure all call sites and payload values match the updated symbols.
  • Confirm package.json update aligns with newly used exports.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Pagination for list repositories' accurately describes the main change in the pull request, which implements pagination functionality for the repository listing feature.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ser-504

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/components/git/repositories.svelte (1)

196-198: Disabled state prevents searching when API returns zero results on initial load.

The condition disabled={!search && !$repositories?.repositories?.length} blocks the search input when users haven't typed anything and the repositories array is empty. In the edge case where an installation has no repositories (or the initial query returns zero results), users cannot type to search. Other similar components in the codebase use disabled={totalResults === 0 && !search}, which is clearer and uses the explicit .total property already available in $repositories. Consider using disabled={$repositories.total === 0 && !search} for consistency, or remove the disabled condition entirely since searching an empty result set is still useful for UX.

🧹 Nitpick comments (1)
src/lib/components/git/repositories.svelte (1)

70-84: Pagination reset logic looks correct.

The loadRepositoryPage function handles pagination clicks, while the $effect handles search/installation changes with offset reset. One minor note: the comment on line 81 says "when search changes" but this also resets on installation changes—which is the correct behavior (new context = page 1). Consider updating the comment to clarify.

 $effect(() => {
     if (selectedInstallation && search !== undefined) {
-        offset = 0; // reset offset to 0 when search changes
+        offset = 0; // reset to first page when search or installation changes
         debouncedLoadRepositories(selectedInstallation, search);
     }
 });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4ec08c1 and ff4ff0c.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (4)
  • package.json (1 hunks)
  • src/lib/components/git/repositories.svelte (7 hunks)
  • src/lib/components/git/skeletonRepoList.svelte (1 hunks)
  • src/routes/(console)/project-[region]-[project]/functions/function-[function]/store.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx,js,jsx,svelte}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx,svelte}: Import reusable modules from the src/lib directory using the $lib alias
Use minimal comments in code; reserve comments for TODOs or complex logic explanations
Use $lib, $routes, and $themes aliases instead of relative paths for module imports

Files:

  • src/routes/(console)/project-[region]-[project]/functions/function-[function]/store.ts
  • src/lib/components/git/skeletonRepoList.svelte
  • src/lib/components/git/repositories.svelte
**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.ts: Define types inline or in .d.ts files, avoid creating separate .types.ts files
Use TypeScript in non-strict mode; any type is tolerated in this project

Files:

  • src/routes/(console)/project-[region]-[project]/functions/function-[function]/store.ts
**/*.{ts,tsx,js,jsx,svelte,json}

📄 CodeRabbit inference engine (AGENTS.md)

Use 4 spaces for indentation, single quotes, 100 character line width, and no trailing commas per Prettier configuration

Files:

  • src/routes/(console)/project-[region]-[project]/functions/function-[function]/store.ts
  • src/lib/components/git/skeletonRepoList.svelte
  • src/lib/components/git/repositories.svelte
  • package.json
src/routes/**

📄 CodeRabbit inference engine (AGENTS.md)

Configure dynamic routes using SvelteKit convention with [param] syntax in route directory names

Files:

  • src/routes/(console)/project-[region]-[project]/functions/function-[function]/store.ts
src/lib/components/**/*.svelte

📄 CodeRabbit inference engine (AGENTS.md)

Use PascalCase for component file names and place them in src/lib/components/[feature]/ directory structure

Files:

  • src/lib/components/git/skeletonRepoList.svelte
  • src/lib/components/git/repositories.svelte
**/*.svelte

📄 CodeRabbit inference engine (AGENTS.md)

Use Svelte 5 + SvelteKit 2 syntax with TypeScript for component development

Files:

  • src/lib/components/git/skeletonRepoList.svelte
  • src/lib/components/git/repositories.svelte
🧠 Learnings (2)
📚 Learning: 2025-10-13T05:13:54.542Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2413
File: src/routes/(console)/project-[region]-[project]/databases/table.svelte:33-39
Timestamp: 2025-10-13T05:13:54.542Z
Learning: In Svelte 5, `import { page } from '$app/state'` provides a reactive state proxy that can be accessed directly (e.g., `page.params`), unlike the older `import { page } from '$app/stores'` which returns a readable store requiring the `$page` syntax for auto-subscription in components.

Applied to files:

  • src/lib/components/git/repositories.svelte
📚 Learning: 2025-09-26T06:48:57.938Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2373
File: src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/empty.svelte:629-631
Timestamp: 2025-09-26T06:48:57.938Z
Learning: In the Appwrite console codebase using appwrite.io/pink-svelte, the Icon component automatically handles CSS variable names passed to its color prop by internally wrapping them with var(). Therefore, passing '--some-css-variable' as a string to the Icon color prop works correctly without needing to manually wrap it with var().

Applied to files:

  • src/lib/components/git/repositories.svelte
  • package.json
🔇 Additional comments (5)
package.json (1)

25-25: LGTM - dependency update enables pagination Query support.

The commit-hash reference ensures reproducible builds. Verify the package provides the expected Query export and ProviderRepositoryRuntimeList/ProviderRepositoryFrameworkList types used in the other changed files.

src/routes/(console)/project-[region]-[project]/functions/function-[function]/store.ts (1)

17-27: LGTM - Store type properly extended for pagination.

The total field and union type for repositories correctly support the pagination feature and multi-product usage (functions/sites).

src/lib/components/git/skeletonRepoList.svelte (1)

4-8: LGTM - Dynamic skeleton count properly implemented.

The Svelte 5 $props() syntax is correct. Minor note: Array(count) creates a sparse array which works here but {#each Array(count).fill(null) as _} or {#each { length: count } as _} would be slightly more explicit. Not blocking.

src/lib/components/git/repositories.svelte (2)

117-143: Pagination queries and type casting implemented correctly.

The Query.limit() and Query.offset() calls properly paginate results, and capturing total enables proper pagination UI. The as unknown as casts are acceptable given the TODO note about backend fixes pending.


301-318: Pagination footer implementation is solid.

Showing the total results count and PaginationInline component with proper bindings provides good UX. The conditional rendering (isLoadingRepositories || $repositories.total > 0) ensures the pagination area maintains layout during loading.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
src/lib/components/git/repositories.svelte (4)

70-77: Consider extracting shared loading logic.

loadRepositoryPage and the callback in debouncedLoadRepositories (lines 59-65) share identical loading-state management. You could extract this into a helper:

+    const withLoading = async (fn: () => Promise<void>) => {
+        isLoadingRepositories = true;
+        try {
+            await fn();
+        } finally {
+            isLoadingRepositories = false;
+        }
+    };
+
     const debouncedLoadRepositories = debounce(
-        async (installationId: string, searchTerm: string) => {
-            isLoadingRepositories = true;
-            try {
-                await loadRepositories(installationId, searchTerm);
-            } finally {
-                isLoadingRepositories = false;
-            }
-        },
+        (installationId: string, searchTerm: string) =>
+            withLoading(() => loadRepositories(installationId, searchTerm)),
         300
     );

-    const loadRepositoryPage = async () => {
-        isLoadingRepositories = true;
-        try {
-            await loadRepositories(selectedInstallation, search);
-        } finally {
-            isLoadingRepositories = false;
-        }
-    };
+    const loadRepositoryPage = () =>
+        withLoading(() => loadRepositories(selectedInstallation, search));

128-134: Type assertions bypass type safety.

The double cast as unknown as indicates a type mismatch between the SDK response and expected types. While the TODO acknowledges this, consider adding runtime validation to catch unexpected shapes:

         $repositories.repositories =
             product === 'functions'
-                ? (result as unknown as Models.ProviderRepositoryRuntimeList)
-                      .runtimeProviderRepositories
-                : (result as unknown as Models.ProviderRepositoryFrameworkList)
-                      .frameworkProviderRepositories; //TODO: remove forced cast after backend fixes
+                ? (result as unknown as Models.ProviderRepositoryRuntimeList)
+                      .runtimeProviderRepositories ?? []
+                : (result as unknown as Models.ProviderRepositoryFrameworkList)
+                      .frameworkProviderRepositories ?? []; //TODO: remove forced cast after backend fixes

The ?? [] fallback guards against undefined if the backend response structure differs from expectations.


296-312: Stale total displayed during loading.

When isLoadingRepositories is true, $repositories.total reflects the previous query's count. This could briefly show an incorrect total (e.g., "Total results: 50" while loading a new search that yields 3 results).

Consider conditionally hiding the total during loading or showing a placeholder:

                     <Typography.Text variant="m-400" color="--fgcolor-neutral-secondary">
-                        Total results: {$repositories.total}
+                        Total results: {isLoadingRepositories ? '...' : $repositories.total}
                     </Typography.Text>

140-140: Unclear purpose of bare expression.

The standalone selectedRepository; statement appears to be dead code or a reactivity workaround. If it's intentional (e.g., to satisfy a linter or trigger reactive tracking), add a comment explaining why. Otherwise, remove it.

-    selectedRepository;
+    // Intentional: reference to maintain reactivity binding
+    selectedRepository;

Or simply remove if not needed.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 97afec4 and 1ab59eb.

📒 Files selected for processing (1)
  • src/lib/components/git/repositories.svelte (7 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx,js,jsx,svelte}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx,svelte}: Import reusable modules from the src/lib directory using the $lib alias
Use minimal comments in code; reserve comments for TODOs or complex logic explanations
Use $lib, $routes, and $themes aliases instead of relative paths for module imports

Files:

  • src/lib/components/git/repositories.svelte
src/lib/components/**/*.svelte

📄 CodeRabbit inference engine (AGENTS.md)

Use PascalCase for component file names and place them in src/lib/components/[feature]/ directory structure

Files:

  • src/lib/components/git/repositories.svelte
**/*.{ts,tsx,js,jsx,svelte,json}

📄 CodeRabbit inference engine (AGENTS.md)

Use 4 spaces for indentation, single quotes, 100 character line width, and no trailing commas per Prettier configuration

Files:

  • src/lib/components/git/repositories.svelte
**/*.svelte

📄 CodeRabbit inference engine (AGENTS.md)

Use Svelte 5 + SvelteKit 2 syntax with TypeScript for component development

Files:

  • src/lib/components/git/repositories.svelte
🧠 Learnings (4)
📚 Learning: 2025-10-13T05:13:54.542Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2413
File: src/routes/(console)/project-[region]-[project]/databases/table.svelte:33-39
Timestamp: 2025-10-13T05:13:54.542Z
Learning: In Svelte 5, `import { page } from '$app/state'` provides a reactive state proxy that can be accessed directly (e.g., `page.params`), unlike the older `import { page } from '$app/stores'` which returns a readable store requiring the `$page` syntax for auto-subscription in components.

Applied to files:

  • src/lib/components/git/repositories.svelte
📚 Learning: 2025-10-05T09:41:40.439Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2398
File: src/routes/(console)/verify-email/+page.svelte:48-51
Timestamp: 2025-10-05T09:41:40.439Z
Learning: In SvelteKit 5, `page` imported from `$app/state` is a reactive state object (using runes), not a store. It should be accessed as `page.data` without the `$` prefix, unlike the store-based `$page` from `$app/stores` in earlier versions.

Applied to files:

  • src/lib/components/git/repositories.svelte
📚 Learning: 2025-11-25T03:15:27.539Z
Learnt from: CR
Repo: appwrite/console PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T03:15:27.539Z
Learning: Applies to **/*.{ts,tsx,js,jsx,svelte} : Import reusable modules from the src/lib directory using the $lib alias

Applied to files:

  • src/lib/components/git/repositories.svelte
📚 Learning: 2025-09-26T06:48:57.938Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2373
File: src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/empty.svelte:629-631
Timestamp: 2025-09-26T06:48:57.938Z
Learning: In the Appwrite console codebase using appwrite.io/pink-svelte, the Icon component automatically handles CSS variable names passed to its color prop by internally wrapping them with var(). Therefore, passing '--some-css-variable' as a string to the Icon color prop works correctly without needing to manually wrap it with var().

Applied to files:

  • src/lib/components/git/repositories.svelte
🔇 Additional comments (4)
src/lib/components/git/repositories.svelte (4)

2-2: LGTM!

Imports are properly organized and use the $lib alias as per coding guidelines.

Also applies to: 20-20


51-52: LGTM!

Correctly uses $state for the mutable offset and const for the immutable limit.


79-84: LGTM!

Correctly resets offset to 0 when the search term or installation changes, ensuring pagination starts from the first page.


198-277: LGTM!

The table rendering correctly handles both product types with proper defensive checks ('framework' in repo, 'runtime' in repo) before accessing type-specific properties. The skeleton count matching limit provides consistent loading UX.

@ItzNotABug ItzNotABug merged commit 6344127 into main Dec 5, 2025
3 of 8 checks passed
@ItzNotABug ItzNotABug deleted the ser-504 branch December 5, 2025 11:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants