Skip to content
Open
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
4 changes: 4 additions & 0 deletions web/sdk/react/assets/inbox-stack.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions web/sdk/react/assets/user-minus.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 16 additions & 12 deletions web/sdk/react/hooks/useOrganizationProjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ interface useOrganizationProjectsProps {

export interface UseOrganizationProjectsReturn {
isFetching: boolean;
isFetched: boolean;
projects: Project[];
userAccessOnProject: Record<string, string[]>;
refetch: () => void;
Expand All @@ -25,33 +26,35 @@ export const useOrganizationProjects = ({
const { activeOrganization: organization } = useFrontier();

// Query for organization projects (all projects)
const {
data: orgProjectsData,
isLoading: isOrgProjectsLoading,
const {
data: orgProjectsData,
isLoading: isOrgProjectsLoading,
isFetched: isOrgProjectsFetched,
error: orgProjectsError,
refetch: refetchOrgProjects
refetch: refetchOrgProjects
} = useQuery(
FrontierServiceQueries.listOrganizationProjects,
create(ListOrganizationProjectsRequestSchema, {
create(ListOrganizationProjectsRequestSchema, {
id: organization?.id || '',
withMemberCount
withMemberCount
}),
{ enabled: !!organization?.id && allProjects }
);

// Query for current user projects
const {
data: userProjectsData,
isLoading: isUserProjectsLoading,
const {
data: userProjectsData,
isLoading: isUserProjectsLoading,
isFetched: isUserProjectsFetched,
error: userProjectsError,
refetch: refetchUserProjects
refetch: refetchUserProjects
} = useQuery(
FrontierServiceQueries.listProjectsByCurrentUser,
create(ListProjectsByCurrentUserRequestSchema, {
create(ListProjectsByCurrentUserRequestSchema, {
orgId: organization?.id || '',
withPermissions: ['update', 'delete'],
nonInherited: true,
withMemberCount
withMemberCount
}),
{ enabled: !!organization?.id && !allProjects }
);
Expand Down Expand Up @@ -89,6 +92,7 @@ export const useOrganizationProjects = ({

return {
isFetching: isLoading,
isFetched: isUserProjectsFetched || isOrgProjectsFetched,
projects: projects,
userAccessOnProject,
refetch: refetch,
Expand Down
8 changes: 5 additions & 3 deletions web/sdk/react/hooks/useOrganizationTeams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const useOrganizationTeams = ({
withMemberCount = false
}: useOrganizationTeamsProps): {
isFetching: boolean;
isFetched: boolean;
teams: Group[];
userAccessOnTeam: Record<string, string[]>;
refetch: () => void;
Expand All @@ -27,14 +28,14 @@ export const useOrganizationTeams = ({
const { activeOrganization: organization } = useFrontier();

// Organization teams query
const { data: orgTeamsData, isLoading: isOrgTeamsLoading, error: orgTeamsError, refetch: refetchOrgTeams } = useQuery(
const { data: orgTeamsData, isLoading: isOrgTeamsLoading, isFetched: isOrgTeamsFetched, error: orgTeamsError, refetch: refetchOrgTeams } = useQuery(
FrontierServiceQueries.listOrganizationGroups,
create(ListOrganizationGroupsRequestSchema, { orgId: organization?.id || '', withMemberCount }),
{ enabled: !!organization?.id && showOrgTeams }
);

// User teams query
const { data: userTeamsData, isLoading: isUserTeamsLoading, error: userTeamsError, refetch: refetchUserTeams } = useQuery(
// User teams query
const { data: userTeamsData, isLoading: isUserTeamsLoading, isFetched: isUserTeamsFetched, error: userTeamsError, refetch: refetchUserTeams } = useQuery(
FrontierServiceQueries.listCurrentUserGroups,
create(ListCurrentUserGroupsRequestSchema, { orgId: organization?.id || '', withPermissions, withMemberCount }),
{ enabled: !!organization?.id && !showOrgTeams }
Expand Down Expand Up @@ -75,6 +76,7 @@ export const useOrganizationTeams = ({

return {
isFetching: isTeamsLoading,
isFetched: isUserTeamsFetched || isOrgTeamsFetched,
teams: teams,
userAccessOnTeam,
refetch,
Expand Down
14 changes: 11 additions & 3 deletions web/sdk/react/views-new/billing/billing-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import { useCallback, useEffect, useMemo } from 'react';
import qs from 'query-string';
import { Flex, Dialog, EmptyState, toastManager } from '@raystack/apsara-v1';
import { ExclamationTriangleIcon } from '@radix-ui/react-icons';
import { Flex, Dialog, EmptyState, Image, toastManager } from '@raystack/apsara-v1';
import exclamationTriangleIcon from '../../assets/exclamation-triangle.svg';
import {
CreateCheckoutRequestSchema,
ListInvoicesRequestSchema,
Expand Down Expand Up @@ -162,7 +162,15 @@ export function BillingView({ onNavigateToPlans }: BillingViewProps) {

{hasNoAccess ? (
<EmptyState
icon={<ExclamationTriangleIcon />}
variant="empty2"
icon={
<Image
src={exclamationTriangleIcon as unknown as string}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the type definition of Image src prop and SVG import handling
rg -n "src\s*:\s*" --type=ts -A2 -g '*apsara*' -g '*Image*' | head -20

# Check bundler configuration for SVG handling
fd -e json -e js -e ts 'vite.config|webpack.config|next.config' --exec cat {}

Repository: raystack/frontier

Length of output: 3435


🏁 Script executed:

# Find the Image component definition from apsara-v1 in the project
rg -n "interface\s+Image|type\s+Image|function\s+Image" --type=ts --type=tsx | grep -i "src\|prop" | head -20

# Check the actual billing-view file to understand the imports
cat -n web/sdk/react/views-new/billing/billing-view.tsx | head -30

# Search for other similar double type casts in the codebase
rg "as unknown as string" --type=ts --type=tsx -n | head -30

# Check if there are type definitions or other Image usages
rg -n "from.*apsara.*Image" --type=ts --type=tsx | head -20

Repository: raystack/frontier

Length of output: 1695


🏁 Script executed:

# Check TypeScript configuration for SVG handling
find . -name "tsconfig*.json" -type f | head -5 | xargs cat

# Search for other Image component usages to see patterns
rg "Image" --type ts -A2 -B2 | grep -A3 "src=" | head -40

# Check other SVG imports and how they're used
rg "from.*\.svg" --type ts -B2 -A2 | head -50

# Look for similar double type casts elsewhere
rg "as unknown as" --type ts -B2 -A2 | head -40

Repository: raystack/frontier

Length of output: 12410


Add TypeScript type declarations for SVG imports to eliminate the double type cast.

The pattern as unknown as string appears in 10+ files across the codebase and indicates a type mismatch between SVG imports and the Image component's src prop. Add a module declaration (e.g., src/vite-env.d.ts) to properly type SVG imports:

declare module '*.svg' {
  const content: string;
  export default content;
}

This eliminates the need for the workaround cast throughout the codebase and provides type safety.

alt=""
width={40}
height={40}
/>
}
heading="Restricted Access"
subHeading="Admin access required, please reach out to your admin to view billing."
/>
Expand Down
6 changes: 3 additions & 3 deletions web/sdk/react/views-new/members/components/member-columns.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import { DotsVerticalIcon } from '@radix-ui/react-icons';
import { DotsHorizontalIcon } from '@radix-ui/react-icons';
import {
Flex,
Text,
Expand Down Expand Up @@ -141,13 +141,13 @@ export const getColumns = ({
}}
render={
<IconButton
size={3}
size={2}
aria-label="Member actions"
data-test-id="member-actions-btn"
/>
}
>
<DotsVerticalIcon />
<DotsHorizontalIcon />
</Menu.Trigger>
</Flex>
);
Expand Down
4 changes: 4 additions & 0 deletions web/sdk/react/views-new/members/members-view.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
table-layout: fixed;
}

.tableRow > td {
padding: var(--rs-space-3);
}

.menuContent {
min-width: 180px;
}
19 changes: 16 additions & 3 deletions web/sdk/react/views-new/members/members-view.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

import { useMemo, useState } from 'react';
import { ExclamationTriangleIcon, TrashIcon, UpdateIcon } from '@radix-ui/react-icons';
import { ExclamationTriangleIcon, UpdateIcon } from '@radix-ui/react-icons';
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

We should import exclamation icon from assets as before in billingview.tsx

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I didn't get your comment. Can you help me understand?

import {
Button,
Tooltip,
Expand All @@ -11,8 +11,10 @@ import {
EmptyState,
DataTable,
Dialog,
Image,
Menu
} from '@raystack/apsara-v1';
import deleteIcon from '../../assets/delete.svg';
import { useFrontier } from '../../contexts/FrontierContext';
import { useOrganizationMembers } from '../../hooks/useOrganizationMembers';
import { usePermissions } from '../../hooks/usePermissions';
Expand Down Expand Up @@ -189,7 +191,8 @@ export function MembersView({ showTeamField = true }: MembersViewProps) {
}
classNames={{
root: styles.tableRoot,
table: styles.table
table: styles.table,
row: styles.tableRow
}}
/>
</Flex>
Expand Down Expand Up @@ -218,14 +221,24 @@ export function MembersView({ showTeamField = true }: MembersViewProps) {
))}
{payload?.canRemove && (
<Menu.Item
leadingIcon={<TrashIcon />}
leadingIcon={
<Image
src={deleteIcon as unknown as string}
alt="Remove"
width={16}
height={16}
/>
}
onClick={() =>
removeMemberDialogHandle.openWithPayload({
memberId: payload.memberId,
invited: String(payload.invited)
})
}
data-test-id="remove-member-dropdown-item"
style={{
color: 'var(--rs-color-foreground-danger-primary)'
}}
>
Remove
</Menu.Item>
Expand Down
17 changes: 14 additions & 3 deletions web/sdk/react/views-new/pat/pat-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import {
Dialog,
EmptyState,
Flex,
Image,
Skeleton
} from '@raystack/apsara-v1';
import keyIcon from '../../assets/key.svg';
import type { DataTableQuery, DataTableSort } from '@raystack/apsara-v1';
import { useDebouncedState } from '@raystack/apsara-v1/hooks';
import { useInfiniteQuery } from '@connectrpc/connect-query';
Expand Down Expand Up @@ -166,13 +168,22 @@ export function PatsView({ onPATClick }: PatsViewProps = {}) {
</Flex>
) : hasNoPats ? (
<EmptyState
icon={<LockClosedIcon />}
variant="empty2"
icon={
<Image
src={keyIcon as unknown as string}
alt=""
width={40}
height={40}
/>
}
heading="No Personal Access Token Found"
subHeading={`Create a new to use the Keys of ${t.appName()} platform`}
primaryAction={
<Button
variant="outline"
color="neutral"
variant="solid"
color="accent"
size="small"
onClick={() => createPATDialogHandle.open(null)}
data-test-id="frontier-sdk-add-pat-btn"
>
Expand Down
1 change: 1 addition & 0 deletions web/sdk/react/views-new/plans/plans-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ export function PlansView() {
<ViewContainer>
<ViewHeader title="Plans" description="View and manage your subscription plan." />
<EmptyState
variant="empty2"
icon={<ExclamationTriangleIcon />}
heading="No Plans Available"
subHeading="No plans available at this moment. Please try again later."
Expand Down
Loading
Loading