diff --git a/apps/web/screens/Organization/PublishedMaterial/PublishedMaterial.tsx b/apps/web/screens/Organization/PublishedMaterial/PublishedMaterial.tsx index 4ab2ff408c49..29b0a230f6b2 100644 --- a/apps/web/screens/Organization/PublishedMaterial/PublishedMaterial.tsx +++ b/apps/web/screens/Organization/PublishedMaterial/PublishedMaterial.tsx @@ -53,6 +53,7 @@ import { } from './utils' import { OrderByItem } from './components/OrderByItem' import { useSelect } from 'downshift' +import { stringHash } from '@island.is/web/utils/stringHash' import * as styles from './PublishedMaterial.css' const ASSETS_PER_PAGE = 20 @@ -112,10 +113,26 @@ const PublishedMaterial: Screen = ({ size: ASSETS_PER_PAGE, tagGroups: {}, sort: ordering, + hash: 0, }, }, }) + // This hash value is used to match the response to a request + const [requestHash, setRequestHash] = useState(0) + + useEffect(() => { + const input = { ...queryVariables.variables.input } + delete input['hash'] + setRequestHash(stringHash(JSON.stringify(input))) + }, [queryVariables]) + + const [publishedMaterialData, setPublishedMaterialData] = useState({ + total: 0, + items: [], + hash: 0, + }) + const { data, loading, fetchMore } = useQuery< Query, QueryGetPublishedMaterialArgs @@ -144,17 +161,25 @@ const PublishedMaterial: Screen = ({ c.selected.forEach((t) => selectedCategories.push(t)), ) + const input = { + lang: activeLocale, + organizationSlug: (router.query.slug as string) ?? '', + tags: selectedCategories, + page: nextPage, + searchString: searchValue, + size: ASSETS_PER_PAGE, + tagGroups: getGenericTagGroupHierarchy(filterCategories), + sort: ordering, + } + + const hash = stringHash(JSON.stringify(input)) + setRequestHash(hash) + fetchMore({ variables: { input: { - lang: activeLocale, - organizationSlug: (router.query.slug as string) ?? '', - tags: selectedCategories, - page: nextPage, - searchString: searchValue, - size: ASSETS_PER_PAGE, - tagGroups: getGenericTagGroupHierarchy(filterCategories), - sort: ordering, + ...input, + hash, }, }, updateQuery: (prevResult, { fetchMoreResult }) => { @@ -176,17 +201,25 @@ const PublishedMaterial: Screen = ({ c.selected.forEach((t) => selectedCategories.push(t)), ) + const input = { + lang: activeLocale, + organizationSlug: (router.query.slug as string) ?? '', + tags: selectedCategories, + page: 1, + searchString: searchValue, + size: ASSETS_PER_PAGE, + tagGroups: getGenericTagGroupHierarchy(filterCategories), + sort: ordering, + } + + const hash = stringHash(JSON.stringify(input)) + setRequestHash(hash) + setQueryVariables({ variables: { input: { - lang: activeLocale, - organizationSlug: (router.query.slug as string) ?? '', - tags: selectedCategories, - page: 1, - searchString: searchValue, - size: ASSETS_PER_PAGE, - tagGroups: getGenericTagGroupHierarchy(filterCategories), - sort: ordering, + ...input, + hash, }, }, }) @@ -258,6 +291,13 @@ const PublishedMaterial: Screen = ({ if (selectedItem?.onClick) selectedItem.onClick() }, [selectedItem]) + useEffect(() => { + const responseHash = data?.getPublishedMaterial?.hash + if (requestHash === responseHash) { + setPublishedMaterialData(data?.getPublishedMaterial) + } + }, [data?.getPublishedMaterial, requestHash]) + const orderByButtonRef = useRef(null) return ( @@ -412,7 +452,7 @@ const PublishedMaterial: Screen = ({ - {(data?.getPublishedMaterial.items ?? []).map((item, index) => { + {(publishedMaterialData?.items ?? []).map((item, index) => { return ( { + const { organizationSlug, searchString, page = 1, // The page number is 1-based meaning that page 1 is the first page @@ -242,8 +244,9 @@ export class CmsElasticsearchService { tags, tagGroups, sort, - }: GetPublishedMaterialInput, - ): Promise { + hash = 0, + } = input + // eslint-disable-next-line @typescript-eslint/no-explicit-any const must: Record[] = [ { @@ -318,6 +321,7 @@ export class CmsElasticsearchService { items: enhancedAssetResponse.body.hits.hits.map((item) => JSON.parse(item._source.response ?? '{}'), ), + hash, // Also return the input hash so we can match the response to the request that was made } } } diff --git a/libs/cms/src/lib/dto/getPublishedMaterial.input.ts b/libs/cms/src/lib/dto/getPublishedMaterial.input.ts index 66eb6caad231..9264a0d2a281 100644 --- a/libs/cms/src/lib/dto/getPublishedMaterial.input.ts +++ b/libs/cms/src/lib/dto/getPublishedMaterial.input.ts @@ -38,4 +38,10 @@ export class GetPublishedMaterialInput { @Field(() => GraphQLJSON) sort!: { field: 'title.sort' | 'releaseDate'; order: SortDirection } + + @Field(() => Int, { nullable: true }) + @IsInt() + @IsOptional() + // The unique hash for this input (used to match the response with a request) + hash?: number } diff --git a/libs/cms/src/lib/models/enhancedAssetSearchResult.model.ts b/libs/cms/src/lib/models/enhancedAssetSearchResult.model.ts index 5fb47d4bde11..c03449018fe6 100644 --- a/libs/cms/src/lib/models/enhancedAssetSearchResult.model.ts +++ b/libs/cms/src/lib/models/enhancedAssetSearchResult.model.ts @@ -8,4 +8,7 @@ export class EnhancedAssetSearchResult { @Field() total!: number + + @Field() + hash!: number }