Skip to content

Commit

Permalink
feat: #1243475 #1244616 Refactor GrapQl queries and add getAutoComple…
Browse files Browse the repository at this point in the history
…teSearchQuery
  • Loading branch information
botisSmile committed Oct 25, 2023
1 parent dd17f2f commit fe6918f
Show file tree
Hide file tree
Showing 8 changed files with 360 additions and 55 deletions.
225 changes: 172 additions & 53 deletions packages/shared/src/constants/graphql.ts
Original file line number Diff line number Diff line change
@@ -1,75 +1,194 @@
import { VariableType, jsonToGraphQLQuery } from 'json-to-graphql-query'

import { IProductFieldFilterInput } from '../types'
import { IGraphqlQueryContent, IProductFieldFilterInput } from '../types'
import { IDocumentFieldFilterInput } from '../types/documents'

export function getSearchProductsQuery(
filter: IProductFieldFilterInput | IProductFieldFilterInput[] = null,
withAggregations = false
): string {
const productQueryContent = getSearchProductsQueryContent(
filter,
withAggregations
)
return jsonToGraphQLQuery({
query: {
__name: 'getProducts',
__variables: {
requestType: 'ProductRequestTypeEnum!',
localizedCatalog: 'String!',
currentPage: 'Int',
currentCategoryId: 'String',
pageSize: 'Int',
search: 'String',
sort: 'ProductSortInput',
},
__variables: { ...productQueryContent.variables },
products: {
__args: {
requestType: new VariableType('requestType'),
localizedCatalog: new VariableType('localizedCatalog'),
currentPage: new VariableType('currentPage'),
currentCategoryId: new VariableType('currentCategoryId'),
pageSize: new VariableType('pageSize'),
search: new VariableType('search'),
sort: new VariableType('sort'),
filter,
},
collection: {
__on: {
__typeName: 'Product',
id: true,
sku: true,
name: true,
score: true,
image: true,
__aliasFor: 'products',
__args: { ...productQueryContent.args },
...productQueryContent.fields,
},
},
})
}

stock: {
status: true,
},
price: {
price: true,
},
function getSearchProductsQueryContent(
filter: IProductFieldFilterInput | IProductFieldFilterInput[] = null,
withAggregations = false
): IGraphqlQueryContent {
return {
variables: {
requestType: 'ProductRequestTypeEnum!',
localizedCatalog: 'String!',
currentPage: 'Int',
currentCategoryId: 'String',
pageSize: 'Int',
search: 'String',
sort: 'ProductSortInput',
},
args: {
requestType: new VariableType('requestType'),
localizedCatalog: new VariableType('localizedCatalog'),
currentPage: new VariableType('currentPage'),
currentCategoryId: new VariableType('currentCategoryId'),
pageSize: new VariableType('pageSize'),
search: new VariableType('search'),
sort: new VariableType('sort'),
filter,
},
fields: {
collection: {
__on: {
__typeName: 'Product',
id: true,
sku: true,
name: true,
score: true,
image: true,

stock: {
status: true,
},
price: {
price: true,
},
},
paginationInfo: {
lastPage: true,
itemsPerPage: true,
totalCount: true,
},
paginationInfo: {
lastPage: true,
itemsPerPage: true,
totalCount: true,
},
sortInfo: {
current: {
field: true,
direction: true,
},
sortInfo: {
current: {
field: true,
direction: true,
},
...(withAggregations && {
aggregations: {
field: true,
label: true,
type: true,
options: {
count: true,
label: true,
value: true,
},
hasMore: true,
},
...(withAggregations && {
aggregations: {
field: true,
}),
},
}
}

export function getSearchCategoryQueryContent(
filter: IDocumentFieldFilterInput | IDocumentFieldFilterInput[] = null,
withAggregations = false
): IGraphqlQueryContent {
return getSearchDocumentQueryContent(filter, withAggregations, 'category')
}

export function getSearchDocumentQueryContent(
filter: IDocumentFieldFilterInput | IDocumentFieldFilterInput[] = null,
withAggregations = false,
variablePrefix = 'document'
): IGraphqlQueryContent {
return {
variables: {
[`${variablePrefix}EntityType`]: 'String!',
[`${variablePrefix}LocalizedCatalog`]: 'String!',
[`${variablePrefix}CurrentPage`]: 'Int',
[`${variablePrefix}PageSize`]: 'Int',
[`${variablePrefix}Search`]: 'String',
[`${variablePrefix}Sort`]: 'SortInput',
},
args: {
entityType: new VariableType(`${variablePrefix}EntityType`),
localizedCatalog: new VariableType(`${variablePrefix}LocalizedCatalog`),
currentPage: new VariableType(`${variablePrefix}CurrentPage`),
pageSize: new VariableType(`${variablePrefix}PageSize`),
search: new VariableType(`${variablePrefix}Search`),
sort: new VariableType(`${variablePrefix}Sort`),
filter,
},
fields: {
collection: {
__on: {
__typeName: 'Document',
id: true,
score: true,
source: true,
},
},
paginationInfo: {
lastPage: true,
itemsPerPage: true,
totalCount: true,
},
sortInfo: {
current: {
field: true,
direction: true,
},
},
...(withAggregations && {
aggregations: {
field: true,
label: true,
type: true,
options: {
count: true,
label: true,
type: true,
options: {
count: true,
label: true,
value: true,
},
hasMore: true,
value: true,
},
}),
hasMore: true,
},
}),
},
}
}

export function getAutoCompleteSearchQuery(
filter: IProductFieldFilterInput | IProductFieldFilterInput[] = null,
withAggregations = false
): string {
const productQueryContent = getSearchProductsQueryContent(
filter,
withAggregations
)
const categoryQueryContent = getSearchCategoryQueryContent(
filter,
withAggregations
)
return jsonToGraphQLQuery({
query: {
__name: 'getAutoCompleteDocuments',
__variables: {
...productQueryContent.variables,
...categoryQueryContent.variables,
},
products: {
__aliasFor: 'products',
__args: { ...productQueryContent.args },
...productQueryContent.fields,
},
categories: {
__aliasFor: 'documents',
__args: { ...categoryQueryContent.args },
...categoryQueryContent.fields,
},
},
})
Expand Down
27 changes: 26 additions & 1 deletion packages/shared/src/services/category.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import categories from '../mocks/static/categories.json'
import { ITreeItem } from '../types'

import { flatTree } from './category'
import { flatTree, getCategoryPathLabel } from './category'

describe('Category service', () => {
describe('flatTree', () => {
Expand Down Expand Up @@ -47,4 +47,29 @@ describe('Category service', () => {
])
})
})

describe('getCategoryPathLabel', () => {
it('should replace category path with ids by category path with names (category level 2)', () => {
const pathLabel: string = getCategoryPathLabel(
['one', 'three'],
categories.categories
)
expect(pathLabel).toEqual('Catégorie Trois')
})
it('should replace category path with ids by category path with names (category level 3)', () => {
const pathLabel: string = getCategoryPathLabel(
['one', 'three', 'five'],
categories.categories
)
expect(pathLabel).toEqual('Catégorie Trois / Catégorie Cinq')
})
it('should replace category path with ids by category path with names (category level 3 + "@" separator)', () => {
const pathLabel: string = getCategoryPathLabel(
['one', 'three', 'five'],
categories.categories,
' @ '
)
expect(pathLabel).toEqual('Catégorie Trois @ Catégorie Cinq')
})
})
})
28 changes: 27 additions & 1 deletion packages/shared/src/services/category.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ITreeItem } from '../types'
import { ICategory, ITreeItem } from '../types'

export function flatTree(tree: ITreeItem[], flat: ITreeItem[]): void {
tree.forEach((item) => {
Expand All @@ -8,3 +8,29 @@ export function flatTree(tree: ITreeItem[], flat: ITreeItem[]): void {
}
})
}

export function getCategoryPathLabel(
path: string[],
categories: ICategory[],
separator = ' / '
): string {
let label = ''
if (path.length > 0) {
const category = categories.find(
(category: ICategory) => category.id === path[0]
)

if (category.level === 1) {
const [_parent, ...children] = path
return getCategoryPathLabel(children, category?.children ?? [], separator)
}

path.shift()
label =
category?.name +
(category?.children?.length > 0 && path.length > 0 ? separator : '') +
getCategoryPathLabel(path, category?.children ?? [], separator)
}

return label
}
12 changes: 12 additions & 0 deletions packages/shared/src/services/format.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
addPrefixKeyObject,
firstLetterLowercase,
firstLetterUppercase,
formatPrice,
Expand Down Expand Up @@ -52,6 +53,17 @@ describe('Format service', () => {
})
})

describe('addPrefixKeyObject', () => {
it('Should add the prefix "category", on all keys of the object', () => {
expect(
addPrefixKeyObject(
{ localizedCatalog: 'com_fr', search: 'bag' },
'category'
)
).toEqual({ categoryLocalizedCatalog: 'com_fr', categorySearch: 'bag' })
})
})

describe('formatPrice', () => {
it('Should format price', () => {
expect(formatPrice(100, 'USD', 'fr-FR')).toContain('100,00')
Expand Down
9 changes: 9 additions & 0 deletions packages/shared/src/services/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ export function isObjectEmpty(obj: Record<string, unknown>): boolean {
return Object.keys(obj).length === 0
}

export function addPrefixKeyObject(obj: object, prefix: string): object {
return Object.entries(obj).reduce((acc, [key, value]) => {
return {
...acc,
[prefix + firstLetterUppercase(key)]: value,
}
}, {})
}

export function concatenateValuesWithLineBreaks(global: string[]): string {
return global.join('\n')
}
Expand Down
5 changes: 5 additions & 0 deletions packages/shared/src/types/categories.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { IJsonldBase } from './jsonld'
import { IGraphqlSearchDocument } from './documents'

export interface ICategory {
id: string
Expand All @@ -19,3 +20,7 @@ export interface ICategories extends IJsonldBase {
export interface IGraphqlCategories {
getCategoryTree: Partial<ICategories>
}

export interface IGraphqlSearchCategories {
categories: IGraphqlSearchDocument
}
Loading

0 comments on commit fe6918f

Please sign in to comment.