14549 Commits

Author SHA1 Message Date
Harsh Mahajan 80beffefd1 Merge pull request #3068 from appwrite/feat-ser542-searchable-project-selector
Feat: searchable project selector
8.4.1
2026-05-29 16:00:25 +05:30
harsh mahajan 26026dd254 perf: prefetch project list on component mount to eliminate dropdown delay
The project list was only fetched after a row appeared, causing a
~1 second blank dropdown. Now the API call fires the instant the
ProjectAccessSelector mounts (when the user switches to "Specific
projects"), so data is ready or in-flight before any interaction.

All rows share a single Promise for unfiltered loads via prefetchPromise;
typed searches still hit the API individually. The generation-counter
race guard still applies so concurrent awaits can't overwrite each other.
2026-05-29 15:28:28 +05:30
harsh mahajan f113c4b81c fix: guard async race and pre-load options for existing project rows
Two bugs in the project access selector:

1. Race condition: loadProjects had no cancellation guard. Two in-flight
   requests for the same row (e.g. rapid typing) could resolve out of
   order, leaving stale results visible. Added a per-row generation
   counter — responses are discarded if a newer request has been
   dispatched since they were started.

2. Edit-mode UUIDs: when the edit modal opens with a member's existing
   project-specific roles, rowOptions starts empty so Input.ComboBox
   falls back to displaying the raw projectId. A $effect now eagerly
   calls loadProjects for any row that has a projectId but no loaded
   options, resolving the label as soon as the dropdown mounts.
2026-05-29 15:24:23 +05:30
harsh mahajan 99b16bc425 fix: invalidate sibling row option caches on project selection/removal
When a project was selected in one row, other rows' cached option lists
still included it, allowing duplicate project assignments. Two places
needed cache busting:

- `onProjectSelected(i)`: clears options for all rows except the one
  that just made a selection; they reload fresh (with takenIds applied)
  on next focus.
- `removeRow(i)`: clears all sibling caches after removal so the
  freed-up project reappears in other rows' dropdowns on next open.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-29 15:17:52 +05:30
harsh mahajan ff267910ad format 2026-05-29 15:11:19 +05:30
harsh mahajan fb13353a67 fix: prevent layout shift when ComboBox dropdown opens inside modal
Two root causes of the shift were identified and fixed:

1. Melt UI's `usePopper` applies `position: absolute` to the dropdown
   via floating-ui after a `tick()` delay. During that one frame the
   `ul` was briefly in normal document flow, momentarily growing the
   `<dialog>` element and causing a reflow. Pre-setting
   `[data-melt-combobox-menu] { position: absolute }` in base.css
   removes the element from flow immediately at mount.

2. Melt UI's ComboBox has `preventScroll: true` by default. On open it
   calls `removeScroll()` which sets `body.overflow: hidden` and adds
   compensatory `padding-right` for the scrollbar width — a body
   reflow that shifts the dialog. Pre-setting `data-melt-scroll-lock`
   on the body in `modal.svelte` tells Melt UI the lock is already
   active so it returns early without touching the body.

Also fix `on:search` on `Input.ComboBox` (which the component never
dispatches) by replacing it with native `oninput`/`onfocusin` handlers
on the wrapper `<div>`, so typed text actually triggers debounced
server-side project search. Projects are now ordered newest-first
(`Query.orderDesc('')`) matching the org projects page.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-29 15:07:54 +05:30
harsh mahajan 3b15be9786 feat: replace static project list with searchable API-backed ComboBox
The project selector previously loaded up to 100 projects upfront,
silently truncating orgs with more. Replace InputSelect with
Input.ComboBox per row — each row fetches the first 25 projects on
open, then debounces API search as the user types. Already-selected
projects are filtered from each row's results. Removes the orgProjects
prefetch from createMember entirely; edit modal no longer needs a
projects prop.
2026-05-29 14:41:16 +05:30
Harsh Mahajan ce9e5967d5 Merge pull request #3066 from appwrite/feat-ser542-granular-project-access
feat: granular project access for org members
8.4.0
2026-05-29 14:05:36 +05:30
harsh mahajan dc9eda4f46 fix: skip membership lookup for owners and guard zero-project fetch loop
- Skip the extra listMemberships call for org owners (they always see
  all projects), avoiding unnecessary latency on every org page load
- Simplify projectScopeQueries type from ReturnType<typeof Query.equal>[]
  to string[]
- Track hasFetchedProjects in createMember to prevent Svelte 5 reactivity
  from re-triggering the listProjects fetch when the org has zero projects
  (assigning a new [] reference would re-run the effect indefinitely)
2026-05-29 13:56:18 +05:30
harsh mahajan 0f24232144 format 2026-05-29 13:49:45 +05:30
harsh mahajan a4062d7c77 fix: constrain overflow tooltip width and wrap long project names
Apply BODY_TOOLTIP_MAX_WIDTH and BODY_TOOLTIP_WRAPPER_STYLE to the
+N project roles tooltip so content stays inside bounds and long
project names wrap instead of overflowing.
2026-05-29 13:45:38 +05:30
harsh mahajan 2b87920286 fix: show overflow project roles in tooltip on +N badge
Members with multiple project-specific roles show the first role badge
inline. Hovering the '+N' badge reveals a tooltip listing all remaining
project roles, keeping the table clean while preserving discoverability.
2026-05-29 13:40:52 +05:30
harsh mahajan b51551ba0f fix: truncate multiple project role badges with +N overflow
Instead of wrapping all project-specific role badges in the members
table cell, show only the first badge and a compact '+N' badge for
the remainder — matching the overflow pattern used in tables DB.
2026-05-29 13:38:27 +05:30
harsh mahajan 33c6729a2a fix: guard against null orgProjects in members table badge renderer
When listProjects fails, orgProjects is null. The optional chain on
.projects alone leaves .find() called on undefined, crashing the
table render. Add ?. before .find() to handle this safely.
2026-05-29 12:59:15 +05:30
harsh mahajan f351d44412 fix: scope project list using raw membership roles
getScopes without projectId collapses project-specific roles to
org-level scopes, so we query the membership directly to get the real
roles (e.g. project-{id}-developer). Members with project-specific
roles only see the projects they have explicit access to.
2026-05-29 12:50:03 +05:30
harsh mahajan 58c538e61f feat: scope org project list to user's project-specific roles
Members with project-specific roles (project-{id}-{role}) now only see
the projects they have explicit access to on the org overview page.
Org-level roles (owner, developer, etc.) continue to see all projects.
2026-05-29 12:45:01 +05:30
harsh mahajan f2efc378db fix: revert client-side filtering, trust backend project scoping
listProjects already returns only the projects a user has access to
based on their org/project roles. Client-side filtering was wrong.
Keep graceful degradation on listPlatforms so a flaky call can't
crash the entire org page.
2026-05-29 12:42:10 +05:30
harsh mahajan 88763df760 fix: correctly paginate after filtering inaccessible projects
Fetch all projects in one call (up to 100) before filtering, then
paginate client-side. This ensures the total count and page numbers
reflect only the projects the user can actually access, avoiding the
broken pagination that occurred when filtering server-paginated results.
2026-05-29 12:37:39 +05:30
harsh mahajan 6c75071100 fix: redirect to org instead of 404 for inaccessible projects
Restore graceful "No apps" degradation on org overview so pagination
stays correct. Add a try/catch around project.get() in the project
layout so clicking an inaccessible project card redirects back to the
org page rather than rendering a 404 error screen.
2026-05-29 12:34:35 +05:30
harsh mahajan 07d8c66c3a fix: hide inaccessible projects from org overview
Projects whose platform API call fails (inaccessible/deleted on backend)
are now filtered out of the org projects list instead of shown as broken
cards. Also corrects the displayed total to match the visible count.
2026-05-29 12:32:09 +05:30
harsh mahajan 4a6fd94b3a fix: gracefully handle inaccessible projects on org overview
If any project's platform API call fails (e.g. project deleted or
inaccessible), fall back to empty platforms instead of crashing the
entire org page with a 404.
2026-05-29 12:30:09 +05:30
harsh mahajan feed34bac0 fix: remove redundant 'Project access' label from selector 2026-05-29 12:21:24 +05:30
harsh mahajan 651c6ecb99 format 2026-05-28 20:05:35 +05:30
harsh mahajan 145e48ea16 fix: address code review issues in granular project access
- listProjects in members page load now uses .catch(() => null) so a
  permissions or network error does not break the entire page
- projectAccessSelector disables "Add project" when projects list is
  empty (prevents unusable required dropdown row)
- createMember resets orgProjects on modal close so subsequent opens
  fetch a fresh list instead of showing a stale one
- edit modal init effect now checks supportsProjectRoles before setting
  accessType to 'specific', preventing a silent role re-submission when
  the org plan is downgraded below the project-roles threshold
2026-05-28 19:59:59 +05:30
harsh mahajan 8614a62750 lint 2026-05-28 19:47:59 +05:30
harsh mahajan a12c6b4d81 feat: granular project access for org members
Add support for assigning org members to specific projects with
per-project roles (owner, developer, editor, analyst) rather than
granting access to all projects in the organization.

- Add project-role helpers to billing store: isProjectSpecificRole,
  parseProjectRole, buildProjectRole, getRoleLabel, projectRoles
- Pass projectId to getScopes in project layout so project-specific
  members receive correct scopes inside their assigned projects
- Add owner-only guard on org settings page
- Load orgProjects alongside members in the members page load
- New projectAccessSelector component for inline project+role rows
  with duplicate-project prevention
- Invite and edit modals use radio toggle (All / Specific projects)
  with inline selector — gated to plans with supportsOrganizationRoles
- Members table shows per-project role badges for project-specific members
- roles.svelte accepts isProjectSpecific prop for contextual role descriptions
2026-05-28 19:03:36 +05:30
Harsh Mahajan f6dba392bf Merge pull request #3065 from appwrite/fix-remaining-settings-clobber
fix: preserve boolean fields and deploymentRetention across all setti…
2026-05-28 12:36:33 +05:30
harsh mahajan e9d0a6fd0d fix: preserve boolean fields and deploymentRetention in git/domain flows
Extends the same fix to three non-settings flows that call functions.update
or sites.update and had the same bugs:

- functions/(modals)/createGit.svelte: enabled/logging || → ??; add deploymentRetention
- functions/domains/add-domain/+page.svelte: enabled/logging || → ??; add
  providerSilentMode, providerRootDirectory, buildSpecification, and deploymentRetention
  which were missing entirely from this connect() call
- sites/deployments/createGitDeploymentModal.svelte: enabled/logging/
  providerSilentMode || → ??; add deploymentRetention
2026-05-28 12:30:13 +05:30
harsh mahajan 47d78fa0fb fix: preserve boolean fields and deploymentRetention across all settings updates
Extends the fix from #3064 to the remaining 20 settings update components
for both functions and sites. Two bugs were present in every file not
touched by that PR:

1. `enabled`, `logging`, and `providerSilentMode` were passed through
   `|| undefined` instead of `?? undefined`, causing `false` values to
   be silently coerced to `undefined` and reset to their API defaults
   whenever any other setting was saved.

2. `deploymentRetention` was absent from every partial-update payload,
   so saving name, timeout, scopes, schedule, runtime, permissions,
   resource limits, build command, events, build triggers, or repository
   settings would silently reset the retention value.

Also fixes `providerSilentMode: silentMode || undefined` in sites/
updateRepository.svelte to `silentMode` (matching the functions version),
so disabling silent mode is correctly preserved on save.
2026-05-28 12:22:39 +05:30
Harsh Mahajan a9baf8b7ef Merge pull request #3064 from ItzNotABug/fix-settings-clobber
Fix: configs being reset
8.3.10
2026-05-28 12:11:13 +05:30
Darshan 6ebe1cb367 bump: lock. 2026-05-28 12:02:50 +05:30
Darshan 6a1edd5092 fix: configs being reset.
fix: configs not being applied correctly.
2026-05-28 11:58:19 +05:30
Harsh Mahajan 594c7a385c Merge pull request #3063 from appwrite/fix-row-delete-freeze
Fix row bulk delete freeze
8.3.9
2026-05-27 18:45:06 +05:30
harsh mahajan 6d84c25d15 lint issue 2026-05-27 18:35:11 +05:30
harsh mahajan 504d61b820 Fix row bulk delete freeze 2026-05-27 18:32:26 +05:30
Harsh Mahajan 7a26e29339 Merge pull request #3058 from appwrite/fix/build-trigger-filters
Add build trigger filters
2026-05-27 17:50:24 +05:30
harsh mahajan 80f4e87f4a fix: parallelize org project lookups in auth preview route 2026-05-27 17:26:09 +05:30
harsh mahajan eed9ee26e6 fix: replace helper text with tooltip info icon on build trigger filters 2026-05-27 17:17:34 +05:30
harsh mahajan d6c3d785b8 format 2026-05-27 17:13:14 +05:30
harsh mahajan 282ec7bb5a fix: migrate project API calls to org-scoped Organization SDK
Bumps @appwrite.io/console SDK to 35c3dea which introduces the Organization
class. All projects.list/create/update calls are now routed through
sdk.forConsole.organization(orgId) so requests carry the
X-Appwrite-Organization header required by the new API contract.
2026-05-27 17:09:10 +05:30
Harsh Mahajan 6d4b05f3f9 Merge pull request #3062 from appwrite/fix-oauth-provider-search-order
Fix OAuth provider search ordering
8.3.8
2026-05-26 13:05:57 +05:30
harsh mahajan c13588f971 Fix OAuth provider search ordering 2026-05-26 11:41:01 +05:30
Harsh Mahajan a17021c1f9 Merge pull request #3061 from appwrite/fix-git-integration-doc-link
fix: point GitHub integration 'Learn more' links to version-control docs
2026-05-26 08:21:31 +05:30
harsh mahajan 2c384f1c6e fix: point GitHub integration 'Learn more' links to version-control docs 2026-05-26 00:18:46 +05:30
Atharva Deosthale b0e14126a0 Merge pull request #3060 from appwrite/feat-presence-api-banner
feat(console): swap promo banner to Presence API announcement
8.3.7
2026-05-25 21:52:48 +05:30
Atharva Deosthale 3034949777 chore(console): rename promo to Presences API and swap cover image 2026-05-25 18:45:01 +05:30
Atharva Deosthale 1af515899a feat(console): swap promo banner to Presence API announcement
Replace the relationships-out-of-beta banner with the new Presence API
announcement linking to the appwrite.io blog post.
2026-05-25 11:20:20 +05:30
Damodar Lohani 94b26483dc Merge pull request #3059 from appwrite/fix-CLO-4381-addon-name
fix(billing): use addon name from API instead of hardcoded label map
8.3.6
2026-05-25 09:06:56 +05:45
Damodar Lohani ded74e8850 fix(billing): use addon name from API instead of hardcoded label map
The plan summary table used a hardcoded `addon_<key> -> label` lookup
to render addon line items, with a fallback that called every unknown
addon an "overage". Switch to reading `addon.name` from the API
response, which the aggregation endpoint now populates from the addon
catalog.

The hardcoded map stays as a fallback for older cloud builds that
don't yet send `addon.name`, and a plain resourceId is the final
fallback in place of the misleading "overage (N)" string.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 05:53:04 +00:00
harsh mahajan a7eb64daba Add build trigger filters 2026-05-22 17:29:47 +05:30