Replace the boolean "skip first render" ref with a ref that stores the
previously-seen tick value. The effect now compares against the stored
value and only fires when it differs, which makes the dependency
naturally used (removes the `void slideoutOpenedTick;` acknowledgement)
and self-documents the intent of the guard.
Behavior is unchanged — both forms preserve the one-shot-per-event
semantics of the prior window-event implementation. The JSDoc on
`slideoutOpenedTickAtom` is updated to describe the new pattern.
Replace the `SLIDEOUT_PANEL_OPENED_EVENT` window event with a
`slideoutOpenedTickAtom` jotai atom. The dispatcher in
`SidebarSlideOutPanel` now bumps the tick via `useSetAtom`, and the
listener in `Thread` reads it via `useAtomValue` and reacts on change
behind a ref guard that skips the initial render — preserving the
one-shot-per-open semantics of the previous event.
This removes the implicit cross-module string contract, makes the
signal traceable through React DevTools / jotai inspector, and lets
TypeScript catch typos that the string-based event API silently
swallowed.
Replace the duplicated `OAUTH_RESULT_COOKIE` constant and inline payload
type across the callback route and connector dialog hook with a shared
`contracts/types/oauth.types.ts` module that exports:
- OAUTH_RESULT_COOKIE constant
- oauthCallbackResultSchema Zod schema
- OAuthCallbackResult type (inferred from the schema)
- parseOAuthCallbackResult() helper that returns null on invalid JSON
or shape mismatch
The route handler now uses the shared type to constrain the cookie
payload at compile time. The consumer hook validates the cookie value
through the helper instead of an unchecked JSON.parse, removing the
silent runtime risk when the cookie is tampered with or its shape
drifts.
lib/posthog/events.ts was importing from components/assistant-ui/...,
creating an inverted dependency layer (lib → components).
Move ConnectorTelemetryMeta type, CONNECTOR_TELEMETRY_REGISTRY,
getConnectorTelemetryMeta, and getReauthEndpoint into the new
lib/connector-telemetry.ts module so that lib/ no longer depends upward
into the UI tree.
connector-constants.ts now re-exports from the new module for
backward compatibility.
Fixes#1375
- Add canPerform() helper function to members-query.atoms.ts
- Add usePermissionGate() hook for convenience
- Update team-content.tsx to use canPerform()
- Update roles-manager.tsx to use canPerform()
- Eliminates duplicated permission check logic
- Centralizes permission policy in one location
Fixes#1366
Fixes#1359
The SidebarSlideOutPanel was checking '(min-width: 640px)' while the rest of
the dashboard uses the project-wide useIsMobile() at 768px. At viewports
between 640-767px the slide-out rendered the desktop side-attached overlay
while the surrounding layout had already collapsed to mobile, leaving the
panel positioned against a sidebar that was no longer there.
Aligning to the shared hook fixes the layout choice at every viewport size.
useIsMobile's 768px threshold is unchanged; only this call site adapts.