Skip to content
Merged
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
84 changes: 2 additions & 82 deletions app/[locale]/(user)/aimodels/[modelId]/AIModelDetailsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
'use client';

import { graphql } from '@/gql';
import { useQuery } from '@tanstack/react-query';
import { Spinner, Text } from 'opub-ui';

Expand All @@ -12,81 +11,7 @@ import { generateJsonLd } from '@/lib/utils';
import Metadata from './components/Metadata';
import PrimaryData from './components/PrimaryData';
import Versions from './components/Versions';

const aiModelQuery = graphql(`
query getAIModel($modelId: Int, $publicId: String) {
getAiModel(modelId: $modelId, publicId: $publicId) {
id
urlSlug
name
displayName
description
modelType
domain
metadata
status
isPublic
isActive
createdAt
updatedAt
tags {
id
value
}
sectors {
id
name
}
geographies {
id
name
}
organization {
id
name
logo {
url
}
}
user {
id
fullName
profilePicture {
url
}
}
versions {
id
version
versionNotes
lifecycleStage
isLatest
supportsStreaming
maxTokens
supportedLanguages
status
createdAt
updatedAt
providers {
id
provider
providerModelId
isPrimary
isActive
# API Configuration
apiEndpointUrl
apiHttpMethod
apiTimeoutSeconds
apiAuthType
# HuggingFace Configuration
hfUsePipeline
hfModelClass
framework
}
}
}
}
`);
import { aiModelQuery } from './queries';

export default function AIModelDetailsPage({
modelId,
Expand All @@ -96,12 +21,7 @@ export default function AIModelDetailsPage({
const { data, isLoading, error } = useQuery(
[`aimodel_details_${modelId}`],
() => GraphQL(aiModelQuery, {}, aiModelLookup(modelId)),
{
retry: false,
onError: (err) => {
console.error('Error fetching AI model:', err);
},
}
{ retry: false }
);

const modelData = data?.getAiModel;
Expand Down
31 changes: 16 additions & 15 deletions app/[locale]/(user)/aimodels/[modelId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { graphql } from '@/gql';
import { permanentRedirect } from 'next/navigation';

import { GraphQL } from '@/lib/api';
import {
isCanonicalRedirect,
redirectToCanonical,
} from '@/lib/canonical-redirect';
import { aiModelLookup, publicPageUrl } from '@/lib/public-link';
aiModelLookup,
isIntegerId,
publicHref,
publicPageUrl,
} from '@/lib/public-link';
import { generatePageMetadata } from '@/lib/utils';
import AIModelDetailsPage from './AIModelDetailsPage';

Expand All @@ -29,13 +31,11 @@ export async function generateMetadata({
try {
const res = await GraphQL(aiModelMetaQuery, {}, aiModelLookup(modelId));
const model = res?.getAiModel;
await redirectToCanonical('aimodels', modelId, model?.urlSlug);
const title = model?.displayName || model?.name || 'AI Model Details';
const description =
model?.description ||
'Explore AI model details, capabilities, and specifications';
const segment = model?.urlSlug || modelId;

return generatePageMetadata({
title: `${title} | CivicDataSpace`,
description,
Expand All @@ -50,9 +50,8 @@ export async function generateMetadata({
image: `${process.env.NEXT_PUBLIC_PLATFORM_URL}/og.png`,
},
});
} catch (e) {
if (isCanonicalRedirect(e)) throw e;
console.error('Metadata fetch error', e);
} catch (error) {
console.error('Metadata fetch error', error);
return generatePageMetadata({ title: 'AI Model Details' });
}
}
Expand All @@ -64,12 +63,14 @@ export default async function Page({
}) {
const { modelId } = await params;

try {
const res = await GraphQL(aiModelMetaQuery, {}, aiModelLookup(modelId));
await redirectToCanonical('aimodels', modelId, res?.getAiModel?.urlSlug);
} catch (error) {
if (isCanonicalRedirect(error)) throw error;
console.error('AI model lookup error', error);
if (isIntegerId(modelId)) {
const res = await GraphQL(aiModelMetaQuery, {}, {
modelId: Number.parseInt(modelId, 10),
}).catch(() => null);
const urlSlug = res?.getAiModel?.urlSlug;
if (urlSlug && urlSlug !== modelId) {
permanentRedirect(publicHref('aimodels', urlSlug, urlSlug));
}
}

return <AIModelDetailsPage modelId={modelId} />;
Expand Down
74 changes: 74 additions & 0 deletions app/[locale]/(user)/aimodels/[modelId]/queries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { graphql } from '@/gql';

export const aiModelQuery = graphql(`
query getAIModel($modelId: Int, $publicId: String) {
getAiModel(modelId: $modelId, publicId: $publicId) {
id
urlSlug
name
displayName
description
modelType
domain
metadata
status
isPublic
isActive
createdAt
updatedAt
tags {
id
value
}
sectors {
id
name
}
geographies {
id
name
}
organization {
id
name
logo {
url
}
}
user {
id
fullName
profilePicture {
url
}
}
versions {
id
version
versionNotes
lifecycleStage
isLatest
supportsStreaming
maxTokens
supportedLanguages
status
createdAt
updatedAt
providers {
id
provider
providerModelId
isPrimary
isActive
apiEndpointUrl
apiHttpMethod
apiTimeoutSeconds
apiAuthType
hfUsePipeline
hfModelClass
framework
}
}
}
}
`);
Original file line number Diff line number Diff line change
Expand Up @@ -24,70 +24,7 @@ import {
} from './dataset-cover';
import { DatasetCover } from './components/DatasetCover/DatasetCover';
import { DatasetTabs } from './components/DatasetTabs/DatasetTabs';

const datasetQuery = graphql(`
query getDataset($datasetId: UUID, $publicId: String) {
getDataset(datasetId: $datasetId, publicId: $publicId) {
id
urlSlug
title
description
downloadCount
created
modified
isIndividualDataset
license
formats
user {
fullName
id
bio
location
profilePicture {
url
}
}
tags {
id
value
}
accessType
metadata {
metadataItem {
id
label
dataType
}
value
}
source {
sourceHomepage
sourceUrl
platform
}
resources {
id
noOfEntries
}
organization {
name
description
location
logo {
url
}
slug
id
}
sectors {
name
}
geographies {
name
}
}
}
`);
import { datasetQuery } from './queries';

const chartCountQuery = graphql(`
query datasetVisualisationCount($datasetId: UUID!) {
Expand Down Expand Up @@ -135,7 +72,6 @@ export default function DatasetDetailsPage({
useTourTrigger(true, 1500);
const { trackDataset } = useAnalytics();

// Load this dataset. Old UUID links and the current urlSlug both resolve.
const datasetQueryResult = useQuery(['dataset-cover', datasetId], () =>
GraphQL(datasetQuery, {}, datasetLookup(datasetId))
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ export function DatasetTabs({
<p className="mt-1 font-primary text-100 font-regular leading-2 tracking-[0px] text-[#6b686b]">
Charts and maps created from this dataset.
</p>
{tab === 'visualisations' ? <Details /> : null}
{tab === 'visualisations' ? (
<Details datasetId={datasetId} />
) : null}
</div>
</div>
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
type ReactNode,
} from 'react';
import Image from 'next/image';
import { useParams } from 'next/navigation';
import {
IconChartBar,
IconChartLine,
Expand Down Expand Up @@ -515,13 +514,7 @@ function ChartCard({
const CHART_HEIGHT = 280;
const chartNudge = { transform: 'translateX(calc(-5% + 8px))' };

const Details: React.FC = () => {
const params = useParams();

const datasetId = Array.isArray(params.datasetIdentifier)
? params.datasetIdentifier[0]
: params.datasetIdentifier;

const Details = ({ datasetId }: { datasetId: string }) => {
const { data, isLoading } = useQuery(
[`chartDetails_${datasetId}`],
() => GraphQL(DetailsQuery, {}, { datasetId }),
Expand Down
Loading
Loading