Skip to content

Commit

Permalink
Used hash instead of comparing entire object
Browse files Browse the repository at this point in the history
  • Loading branch information
RunarVestmann committed Apr 19, 2022
1 parent d045d8d commit 8952d13
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 141 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ import {
getGenericTagGroupHierarchy,
getInitialParameters,
Ordering,
responseInputMatchesRequestInput,
} 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
Expand Down Expand Up @@ -113,13 +113,24 @@ const PublishedMaterial: Screen<PublishedMaterialProps> = ({
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: [],
input: {},
hash: 0,
})

const { data, loading, fetchMore } = useQuery<
Expand Down Expand Up @@ -150,17 +161,25 @@ const PublishedMaterial: Screen<PublishedMaterialProps> = ({
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 }) => {
Expand All @@ -182,17 +201,25 @@ const PublishedMaterial: Screen<PublishedMaterialProps> = ({
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,
},
},
})
Expand Down Expand Up @@ -265,12 +292,11 @@ const PublishedMaterial: Screen<PublishedMaterialProps> = ({
}, [selectedItem])

useEffect(() => {
const responseInput = data?.getPublishedMaterial?.input ?? {}
const requestInput = queryVariables.variables.input
if (responseInputMatchesRequestInput(responseInput, requestInput)) {
const responseHash = data?.getPublishedMaterial?.hash
if (requestHash === responseHash) {
setPublishedMaterialData(data?.getPublishedMaterial)
}
}, [data?.getPublishedMaterial, queryVariables.variables.input])
}, [data?.getPublishedMaterial, requestHash])

const orderByButtonRef = useRef<HTMLDivElement | null>(null)

Expand Down
65 changes: 1 addition & 64 deletions apps/web/screens/Organization/PublishedMaterial/utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
GenericTag,
GenericTagGroup,
GetPublishedMaterialInput,
GetPublishedMaterialObject,
} from '@island.is/web/graphql/schema'
import { GenericTag, GenericTagGroup } from '@island.is/web/graphql/schema'

export interface Ordering {
field: 'title.sort' | 'releaseDate'
Expand Down Expand Up @@ -87,61 +82,3 @@ export const getGenericTagGroupHierarchy = (

return hierarchy
}

export const responseInputMatchesRequestInput = (
responseInput: Partial<Omit<GetPublishedMaterialObject, '__typename'>>,
requestInput: GetPublishedMaterialInput,
) => {
if (responseInput?.lang !== requestInput.lang) {
return false
}
if (responseInput?.organizationSlug !== requestInput.organizationSlug) {
return false
}
if (responseInput?.page !== requestInput.page) {
return false
}
if (responseInput?.searchString !== requestInput.searchString) {
return false
}
if (responseInput?.size !== requestInput.size) {
return false
}

const responseInputSort = responseInput?.sort ?? {}

for (const key in Object.keys(responseInputSort)) {
for (const subKey in Object.keys(responseInputSort[key] ?? {})) {
if (responseInput[key][subKey] !== requestInput[key]?.[subKey]) {
return false
}
}
}

const responseTagGroups = responseInput?.tagGroups ?? {}

for (const key in Object.keys(responseTagGroups)) {
if (!responseTagGroups[key]?.length) {
continue
}
for (let i = 0; i < responseTagGroups[key].length; i += 1) {
if (
responseTagGroups?.[key]?.[i] !== requestInput.tagGroups?.[key]?.[i]
) {
return false
}
}
}

if (responseInput?.tags?.length !== requestInput.tags.length) {
return false
}

for (let i = 0; i < responseInput.tags.length; i += 1) {
if (responseInput.tags[i] !== requestInput.tags[i]) {
return false
}
}

return true
}
11 changes: 1 addition & 10 deletions apps/web/screens/queries/PublishedMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,7 @@ import gql from 'graphql-tag'
export const GET_PUBLISHED_MATERIAL_QUERY = gql`
query GetPublishedMaterial($input: GetPublishedMaterialInput!) {
getPublishedMaterial(input: $input) {
input {
lang
size
page
organizationSlug
searchString
tags
tagGroups
sort
}
hash
total
items {
id
Expand Down
5 changes: 2 additions & 3 deletions libs/cms/src/lib/cms.elasticsearch.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ export class CmsElasticsearchService {
tags,
tagGroups,
sort,
hash = 0,
} = input

// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down Expand Up @@ -320,9 +321,7 @@ export class CmsElasticsearchService {
items: enhancedAssetResponse.body.hits.hits.map((item) =>
JSON.parse(item._source.response ?? '{}'),
),

// Also return the input so we can match the response to the request that was made
input,
hash, // Also return the input hash so we can match the response to the request that was made
}
}
}
Expand Down
41 changes: 3 additions & 38 deletions libs/cms/src/lib/dto/getPublishedMaterial.input.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
import { ElasticsearchIndexLocale } from '@island.is/content-search-index-manager'
import { SortDirection } from '@island.is/content-search-toolkit'
import { Field, InputType, Int, ObjectType } from '@nestjs/graphql'
import { Field, InputType, Int } from '@nestjs/graphql'
import { IsInt, IsOptional, IsString } from 'class-validator'
import GraphQLJSON from 'graphql-type-json'

/**
* We need to make sure that these two classes have the same fields,
* one is used for input and the other one is used for output in order to do request-response matching
*/

@InputType()
export class GetPublishedMaterialInput {
@Field(() => String)
Expand Down Expand Up @@ -43,40 +38,10 @@ export class GetPublishedMaterialInput {

@Field(() => GraphQLJSON)
sort!: { field: 'title.sort' | 'releaseDate'; order: SortDirection }
}

@ObjectType()
export class GetPublishedMaterialObject {
@Field(() => String)
@IsString()
lang: ElasticsearchIndexLocale = 'is'

@Field(() => Int, { nullable: true })
@IsInt()
@IsOptional()
size?: number

@Field(() => Int, { nullable: true })
@IsInt()
@IsOptional()
// The page number is 1-based meaning that page 1 is the first page
page?: number

@Field({ nullable: true })
@IsString()
@IsOptional()
organizationSlug?: string

@Field(() => String)
@IsString()
searchString = ''

@Field(() => [String])
tags!: string[]

@Field(() => GraphQLJSON)
tagGroups!: Record<string, string[]>

@Field(() => GraphQLJSON)
sort!: { field: 'title.sort' | 'releaseDate'; order: SortDirection }
// The unique hash for this input (used to match the response with a request)
hash?: number
}
6 changes: 2 additions & 4 deletions libs/cms/src/lib/models/enhancedAssetSearchResult.model.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { Field, ObjectType } from '@nestjs/graphql'
import { GetPublishedMaterialObject } from '../dto/getPublishedMaterial.input'

import { EnhancedAsset } from './enhancedAsset.model'

@ObjectType()
Expand All @@ -11,6 +9,6 @@ export class EnhancedAssetSearchResult {
@Field()
total!: number

@Field(() => GetPublishedMaterialObject)
input!: GetPublishedMaterialObject
@Field()
hash!: number
}

0 comments on commit 8952d13

Please sign in to comment.