[UI] Details tweaks (#12949)

* Fix hover div element

* Improve badge formatting

* Set staleTime for useQuery in NameBadge

* add staleTime elsewhere

* Improved error handlign for badges

* Better caching for parameterTemplate useQuery

* Disable remoteInstance query without pk
This commit is contained in:
Oliver authored and GitHub committed 2026-09-29 19:58:31 +10:00
1 parent aa78504750
commit afab76835f
3 files changed
+56 -32

No files matched your search

+43 -28
View File
@@ -125,11 +125,18 @@ function HoverNameBadge(data: any, type: BadgeType) {
data.username,
getDetailUrl(ModelType.user, data.pk, true),
data?.image,
<>
{data.is_superuser && <Badge color='red'>{t`Superuser`}</Badge>}
{data.is_staff && <Badge color='orange'>{t`Administrator`}</Badge>}
{data.email && t`Email: ` + data.email}
</>
<Stack gap='xs'>
{data.email}
<Group gap='xs'>
{data.is_superuser && <Badge color='red'>{t`Superuser`}</Badge>}
{data.is_staff && (
<Badge color='orange'>{t`Administrator`}</Badge>
)}
{data.is_active === false && (
<Badge color='gray'>{t`Inactive`}</Badge>
)}
</Group>
</Stack>
];
case 'group':
return [
@@ -163,7 +170,7 @@ function HoverNameBadge(data: any, type: BadgeType) {
</Stack>
</Group>
<Text size='sm' mt='md'>
<Text size='sm' mt='md' component='div'>
{line_data[4]}
</Text>
</HoverCard.Dropdown>
@@ -181,8 +188,10 @@ function NameBadge({
}: Readonly<{ pk: string | number; type: BadgeType }>) {
const api = useApi();
const { data } = useQuery({
const { data, isLoading, isError } = useQuery({
queryKey: ['badge', type, pk],
enabled: !!pk,
staleTime: 5 * 60 * 1000, // 5 minutes
queryFn: async () => {
let path = '';
@@ -202,14 +211,7 @@ function NameBadge({
const url = apiUrl(path, pk);
return api.get(url).then((response) => {
switch (response.status) {
case 200:
return response.data;
default:
return {};
}
});
return api.get(url).then((response) => response.data);
}
});
@@ -219,10 +221,14 @@ function NameBadge({
return HoverNameBadge(data, type);
}, [data]);
if (!data || data.isLoading || data.isFetching) {
if (isLoading) {
return <Skeleton height={12} radius='md' />;
}
if (!pk || isError || !data) {
return <Text size='sm'>'---'</Text>;
}
// Rendering a user's name for the badge
function _render_name() {
if (!data || !data.pk) {
@@ -337,8 +343,20 @@ function TableAnchorValue(props: Readonly<FieldProps>) {
const api = useApi();
const navigate = useNavigate();
const { data } = useQuery({
queryKey: ['detail', props.field_data.model, props.field_value],
const hasValue: boolean =
props.field_value !== null &&
props.field_value !== undefined &&
props.field_value !== '';
const { data, isLoading } = useQuery({
queryKey: [
'detail',
props.field_data.model,
props.field_value,
props.field_data.model_filters
],
enabled: hasValue && !props.field_data.external,
staleTime: 5 * 60 * 1000, // 5 minutes
queryFn: async () => {
if (!props.field_data?.model) {
return {};
@@ -356,14 +374,7 @@ function TableAnchorValue(props: Readonly<FieldProps>) {
.get(url, {
params: props.field_data.model_filters ?? undefined
})
.then((response) => {
switch (response.status) {
case 200:
return response.data;
default:
return {};
}
});
.then((response) => response.data);
}
});
@@ -385,7 +396,11 @@ function TableAnchorValue(props: Readonly<FieldProps>) {
return `/${getBaseUrl()}${detailUrl}`;
}, [detailUrl]);
if (!data || data.isLoading || data.isFetching) {
if (!hasValue) {
return <Text size='sm'>'---'</Text>;
}
if (isLoading) {
return <Skeleton height={12} radius='md' />;
}
@@ -409,7 +424,7 @@ function TableAnchorValue(props: Readonly<FieldProps>) {
// Construct the "return value" for the fetched data
let value = undefined;
if (props.field_data.model_formatter) {
if (data && props.field_data.model_formatter) {
value = props.field_data.model_formatter(data) ?? value;
} else if (props.field_data.model_field) {
value = data?.[props.field_data.model_field] ?? value;
@@ -160,8 +160,10 @@ export function RenderRemoteInstance({
}: Readonly<RemoteInstanceProps>): ReactNode {
const api = useApi();
const { data, isLoading, isFetching } = useQuery({
queryKey: ['model', model, pk],
const { data, isLoading } = useQuery({
queryKey: ['model', model, pk, modelUrl],
enabled: !!pk,
staleTime: 5 * 60 * 1000, // 5 minutes
queryFn: async () => {
const url = modelUrl
? apiUrl(modelUrl, pk)
@@ -171,7 +173,7 @@ export function RenderRemoteInstance({
}
});
if (isLoading || isFetching) {
if (isLoading) {
return <Skeleton />;
}
@@ -178,7 +178,14 @@ export default function ParametricDataTable({
// Fetch all active parameter templates for the given model type
const parameterTemplates = useQuery({
queryKey: ['parameter-templates', modelType],
queryKey: [
'parameter-templates',
modelType,
modelId,
relatedModel,
relatedModelId
],
staleTime: 5 * 60 * 1000, // 5 minutes
queryFn: async () => {
return api
.get(apiUrl(ApiEndpoints.parameter_template_list), {