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
60 changes: 49 additions & 11 deletions web/sdk/admin/views/organizations/details/security/domains-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import {
Button,
Flex,
IconButton,
Skeleton,
Text,
toastManager,
} from "@raystack/apsara";
import styles from "./security.module.css";
import { CheckCircledIcon, TrashIcon } from "@radix-ui/react-icons";
import Skeleton from "react-loading-skeleton";
import { useContext, useState } from "react";
import { useMutation, createConnectQueryKey, useTransport } from "@connectrpc/connect-query";
import { useQueryClient } from "@tanstack/react-query";
Expand All @@ -23,7 +23,7 @@ interface DeleteDomainDialogProps {
const DeleteDomainDialog = ({
domain,
}: DeleteDomainDialogProps) => {
const {organization} = useContext(OrganizationContext);
const { organization } = useContext(OrganizationContext);
const [isDialogOpen, setIsDialogOpen] = useState(false);
const queryClient = useQueryClient();
const transport = useTransport();
Expand Down Expand Up @@ -133,21 +133,49 @@ const DomainItem = ({ domain }: DomainItemProps) => {
interface DomainsListProps {
isLoading: boolean;
domains: Domain[];
error?: Error | null;
onRetry: () => void;
}

export const DomainsList = ({
isLoading,
domains = [],
error,
onRetry,
}: DomainsListProps) => {
if (!isLoading && error) {
return (
<Flex
justify="between"
align="center"
className={styles["domains-list"]}
style={{ padding: "var(--rs-space-5) var(--rs-space-7)" }}
>
<Text size="small" variant="secondary">
Couldn&apos;t load email domains
</Text>
<Button
variant="outline"
color="neutral"
size="small"
onClick={() => onRetry()}
data-test-id="retry-domains-button"
>
Retry
</Button>
</Flex>
);
}
Comment on lines +146 to +168

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the target file with line numbers
sed -n '1,240p' web/sdk/admin/views/organizations/details/security/domains-list.tsx | cat -n

# Find the query hook and related state usage in this file
rg -n "useQuery|isLoading|error|domains|onRetry|refetch|fetch" web/sdk/admin/views/organizations/details/security/domains-list.tsx

# Locate the query source / hook definition if it exists nearby
fd -a "domains-list.tsx|*.ts|*.tsx" web/sdk/admin/views/organizations/details/security | head -n 50

Repository: raystack/frontier

Length of output: 8294


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find where DomainsList is used
rg -n "DomainsList" web/sdk/admin -g '*.tsx' -g '*.ts'

# Inspect the parent component that fetches domains
fd -a "domains*.tsx|*security*.tsx|*domain*.tsx" web/sdk/admin/views/organizations/details/security web/sdk/admin/views/organizations/details | head -n 50

# Search for the listOrganizationDomains query usage and its loading/error/data mapping
rg -n "listOrganizationDomains|useQuery\\(|error\\s*:|isLoading\\s*:|domains\\s*=" web/sdk/admin -g '*.tsx' -g '*.ts'

Repository: raystack/frontier

Length of output: 984


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the parent component that supplies isLoading/domains/error/onRetry
sed -n '1,220p' web/sdk/admin/views/organizations/details/security/index.tsx | cat -n

# Search for the exact query state mapping in this directory
rg -n "useQuery|isLoading|isFetching|error|data|refetch|DomainsList" web/sdk/admin/views/organizations/details/security -g '*.tsx' -g '*.ts'

Repository: raystack/frontier

Length of output: 8666


Gate the error state on missing data. A refetch failure after domains have already loaded will replace the visible list with the retry screen. Show this branch only when there’s no existing data to keep on screen, e.g. !domains.length.


return isLoading ? (
<Flex direction="column" className={styles["domains-list"]}>
{[...Array(3)].map((_, index) => (
<Skeleton
key={index}
height={20}
style={{ margin: "var(--rs-space-5) 0" }}
/>
))}
<Flex
justify="between"
align="center"
className={styles["domains-list"]}
style={{ padding: "var(--rs-space-5) var(--rs-space-7)" }}
>
<Skeleton height={16} width={180} />
<Skeleton height={20} width={20} borderRadius="var(--rs-radius-2)" />
</Flex>
) : domains.length ? (
<Flex direction="column" className={styles["domains-list"]}>
Expand All @@ -158,5 +186,15 @@ export const DomainsList = ({
/>
))}
</Flex>
) : null;
) : (
<Flex className={styles["domains-list"]}>
<Text
size="small"
variant="secondary"
style={{ padding: "var(--rs-space-5) 0" }}
>
No allowed email domains added yet
</Text>
</Flex>
);
};
4 changes: 3 additions & 1 deletion web/sdk/admin/views/organizations/details/security/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const AddDomainSection = () => {
export const OrganizationSecurity = () => {
const { organization } = useContext(OrganizationContext);

const { data: domains, isLoading, error } = useQuery(
const { data: domains, isLoading, error, refetch } = useQuery(
FrontierServiceQueries.listOrganizationDomains,
create(ListOrganizationDomainsRequestSchema, {
orgId: organization?.id
Expand Down Expand Up @@ -87,6 +87,8 @@ export const OrganizationSecurity = () => {
<DomainsList
isLoading={isLoading}
domains={domains ?? []}
error={error}
onRetry={() => refetch()}
/>
<Separator />
<BlockOrganizationSection />
Expand Down
Loading