Skip to content

Commit

Permalink
CMS option for default generic list order
Browse files Browse the repository at this point in the history
  • Loading branch information
RunarVestmann committed Dec 20, 2024
1 parent 9364323 commit dbf8b3d
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 30 deletions.
4 changes: 4 additions & 0 deletions apps/web/components/GenericList/GenericList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
GenericListItem,
GenericListItemResponse,
GenericTag,
GetGenericListItemsInputOrderBy,
GetGenericListItemsQueryVariables,
Query,
} from '@island.is/web/graphql/schema'
Expand Down Expand Up @@ -578,13 +579,15 @@ interface GenericListWrapperProps {
searchInputPlaceholder?: string | null
itemType?: string | null
filterTags?: GenericTag[] | null
defaultOrder?: GetGenericListItemsInputOrderBy
}

export const GenericListWrapper = ({
id,
filterTags,
itemType,
searchInputPlaceholder,
defaultOrder,
}: GenericListWrapperProps) => {
const searchQueryId = `${id}q`
const pageQueryId = `${id}page`
Expand Down Expand Up @@ -647,6 +650,7 @@ export const GenericListWrapper = ({
queryString: searchValue,
tags,
tagGroups,
orderBy: defaultOrder,
},
},
})
Expand Down
1 change: 1 addition & 0 deletions apps/web/screens/queries/fragments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,7 @@ export const slices = gql`
id
searchInputPlaceholder
itemType
defaultOrder
filterTags {
id
title
Expand Down
53 changes: 44 additions & 9 deletions libs/cms/src/lib/cms.elasticsearch.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ import {
getElasticsearchIndex,
} from '@island.is/content-search-index-manager'
import { CustomPage } from './models/customPage.model'
import { GetGenericListItemsInput } from './dto/getGenericListItems.input'
import {
GetGenericListItemsInput,
GetGenericListItemsInputOrderBy,
} from './dto/getGenericListItems.input'
import { GenericListItemResponse } from './models/genericListItemResponse.model'
import { GetCustomSubpageInput } from './dto/getCustomSubpage.input'
import { GetGenericListItemBySlugInput } from './dto/getGenericListItemBySlug.input'
Expand Down Expand Up @@ -470,6 +473,7 @@ export class CmsElasticsearchService {
tags?: string[]
tagGroups?: Record<string, string[]>
type: ListItemType
orderBy?: GetGenericListItemsInputOrderBy
}): Promise<
ListItemType extends 'webGenericListItem'
? Omit<GenericListItemResponse, 'input'>
Expand Down Expand Up @@ -525,15 +529,46 @@ export class CmsElasticsearchService {

const size = input.size ?? 10

const sort: sortRule[] = [
{
[SortField.RELEASE_DATE]: {
order: SortDirection.DESC,
let sort: sortRule[] = []

if (
!input.orderBy ||
input.orderBy === GetGenericListItemsInputOrderBy.DATE
) {
sort = [
{
[SortField.RELEASE_DATE]: {
order: SortDirection.DESC,
},
},
},
// Sort items with equal values by ascending title order
{ 'title.sort': { order: SortDirection.ASC } },
]
{ 'title.sort': { order: SortDirection.ASC } },
{ dateCreated: { order: SortDirection.DESC } },
]
}

if (input.orderBy === GetGenericListItemsInputOrderBy.TITLE) {
sort = [
{ 'title.sort': { order: SortDirection.ASC } },
{
[SortField.RELEASE_DATE]: {
order: SortDirection.DESC,
},
},
{ dateCreated: { order: SortDirection.DESC } },
]
}

if (input.orderBy === GetGenericListItemsInputOrderBy.PUBLISH_DATE) {
sort = [
{ dateCreated: { order: SortDirection.DESC } },
{ 'title.sort': { order: SortDirection.ASC } },
{
[SortField.RELEASE_DATE]: {
order: SortDirection.DESC,
},
},
]
}

if (input.tags && input.tags.length > 0 && input.tagGroups) {
must = must.concat(
Expand Down
22 changes: 21 additions & 1 deletion libs/cms/src/lib/dto/getGenericListItems.input.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
import { Field, InputType, Int, ObjectType } from '@nestjs/graphql'
import {
Field,
InputType,
Int,
ObjectType,
registerEnumType,
} from '@nestjs/graphql'
import { IsInt, IsOptional, IsString } from 'class-validator'
import GraphQLJSON from 'graphql-type-json'
import { ElasticsearchIndexLocale } from '@island.is/content-search-index-manager'
import { CacheField } from '@island.is/nest/graphql'

export enum GetGenericListItemsInputOrderBy {
DATE = 'Date',
TITLE = 'Title',
PUBLISH_DATE = 'Publish Date',
}

registerEnumType(GetGenericListItemsInputOrderBy, {
name: 'GetGenericListItemsInputOrderBy',
})

@InputType()
@ObjectType('GenericListItemResponseInput')
Expand Down Expand Up @@ -34,4 +51,7 @@ export class GetGenericListItemsInput {

@Field(() => GraphQLJSON, { nullable: true })
tagGroups?: Record<string, string[]>

@CacheField(() => GetGenericListItemsInputOrderBy, { nullable: true })
orderBy?: GetGenericListItemsInputOrderBy
}
3 changes: 3 additions & 0 deletions libs/cms/src/lib/generated/contentfulTypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1598,6 +1598,9 @@ export interface IGenericListFields {

/** Filter Tags */
filterTags?: IGenericTag[] | undefined

/** Order By */
orderBy?: 'Date' | 'Title' | 'Publish Date' | undefined
}

/** A list of items which can be embedded into rich text */
Expand Down
18 changes: 18 additions & 0 deletions libs/cms/src/lib/models/genericList.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { SystemMetadata } from '@island.is/shared/types'
import { CacheField } from '@island.is/nest/graphql'
import { IGenericList, IGenericListFields } from '../generated/contentfulTypes'
import { GenericTag, mapGenericTag } from './genericTag.model'
import { GetGenericListItemsInputOrderBy } from '../dto/getGenericListItems.input'

enum GenericListItemType {
NonClickable = 'NonClickable',
Expand All @@ -26,13 +27,29 @@ export class GenericList {

@CacheField(() => [GenericTag], { nullable: true })
filterTags?: GenericTag[]

@CacheField(() => GetGenericListItemsInputOrderBy, { nullable: true })
defaultOrder?: GetGenericListItemsInputOrderBy
}

const mapItemType = (itemType?: IGenericListFields['itemType']) =>
itemType === 'Clickable'
? GenericListItemType.Clickable
: GenericListItemType.NonClickable

const mapOrderBy = (orderBy?: IGenericListFields['orderBy']) => {
if (orderBy === 'Date') {
return GetGenericListItemsInputOrderBy.DATE
}
if (orderBy === 'Title') {
return GetGenericListItemsInputOrderBy.TITLE
}
if (orderBy === 'Publish Date') {
return GetGenericListItemsInputOrderBy.PUBLISH_DATE
}
return undefined
}

export const mapGenericList = ({
fields,
sys,
Expand All @@ -42,4 +59,5 @@ export const mapGenericList = ({
searchInputPlaceholder: fields.searchInputPlaceholder,
itemType: mapItemType(fields.itemType),
filterTags: fields.filterTags ? fields.filterTags.map(mapGenericTag) : [],
defaultOrder: mapOrderBy(fields.orderBy),
})
44 changes: 25 additions & 19 deletions libs/cms/src/lib/models/latestGenericListItems.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,28 @@ const mapSeeMorePage = (seeMorePage: IOrganizationSubpage | undefined) => {
export const mapLatestGenericListItems = ({
fields,
sys,
}: ILatestGenericListItems): SystemMetadata<LatestGenericListItems> => ({
typename: 'LatestGenericListItems',
id: sys.id,
title: fields.title ?? '',
genericList: fields.genericList ? mapGenericList(fields.genericList) : null,
seeMorePage: mapSeeMorePage(fields.seeMorePage),
seeMoreLinkText: fields.seeMoreLinkText ?? '',
itemResponse: fields.genericList?.sys.id
? {
genericListId: fields.genericList?.sys.id,
lang:
sys.locale === 'is-IS'
? 'is'
: (sys.locale as ElasticsearchIndexLocale),
page: 1,
size: fields.itemCount ?? 2,
}
: null,
})
}: ILatestGenericListItems): SystemMetadata<LatestGenericListItems> => {
const genericList = fields.genericList
? mapGenericList(fields.genericList)
: null
return {
typename: 'LatestGenericListItems',
id: sys.id,
title: fields.title ?? '',
genericList,
seeMorePage: mapSeeMorePage(fields.seeMorePage),
seeMoreLinkText: fields.seeMoreLinkText ?? '',
itemResponse: fields.genericList?.sys.id
? {
genericListId: fields.genericList?.sys.id,
lang:
sys.locale === 'is-IS'
? 'is'
: (sys.locale as ElasticsearchIndexLocale),
page: 1,
size: fields.itemCount ?? 2,
orderBy: genericList?.defaultOrder,
}
: null,
}
}
4 changes: 3 additions & 1 deletion libs/cms/src/lib/search/importers/genericListItem.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,9 @@ export class GenericListItemSyncService
...mapped,
typename: 'GenericListItem',
}),
dateCreated: entry.sys.createdAt,
dateCreated:
(entry.sys as { firstPublishedAt?: string }).firstPublishedAt ||
entry.sys.createdAt,
dateUpdated: new Date().getTime().toString(),
tags,
releaseDate: mapped.date,
Expand Down

0 comments on commit dbf8b3d

Please sign in to comment.