Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add paging support to getSellers query #168

Merged
merged 10 commits into from
Aug 12, 2024
21 changes: 18 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,39 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

### Added

- Add new `getSellersPaginated` query to allow pagination on sellers query

## [0.53.0] - 2024-08-06

### Fixed

- Add paymentTerms field on create cost center mutation

## [0.52.0] - 2024-08-05

### Added

- New admin user token validation directive

## [0.51.2] - 2024-07-30

### Fixed

- Provide app token on calls to storefront-permissions app

## [0.51.1] - 2024-07-22

### Added

- Audit metrics for some graphql APIs
- Improve access directives

## [0.51.0] - 2024-06-04

### Fixed

- Removed 0.50.0 version changes which contained a bug

## [0.50.0] - 2024-06-03
Expand All @@ -45,21 +54,25 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [0.49.6] - 2024-06-03

### Fixed

- Fix check access directive by allowing appkey tokens for authentication

## [0.49.5] - 2024-05-29

### Changed

- Improve logging and metrics for checkUserAccess and checkAdminAccess directives

## [0.49.4] - 2024-05-07

### Added

- Add metric to check access directives

## [0.49.3] - 2024-04-24

### Fixed

- Provide correct tokens to clients

## [0.49.2] - 2024-04-18
Expand Down Expand Up @@ -101,18 +114,21 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [0.48.2] - 2024-02-21

### Fixed

- Add analytics client to properly send metrics to redshift

## [0.48.1] - 2024-02-07

### Fixed

- Add retries to `sendMetric` to avoid connection errors

## [0.48.0] - 2024-01-19

### Added

- Allow `paymentTerms`, `collections` and `sellers` to be provided by name only on `createOrganizationAndCostCenterWithAdminUser`

## [0.47.1] - 2023-12-18

### Fixed
Expand Down Expand Up @@ -199,7 +215,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [0.37.0] - 2023-09-19


### Added

- Added event trigger on delete a user
Expand All @@ -215,7 +230,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added

- Added metrics for impersonate user
-
-

## [0.35.3] - 2023-08-09

### Fixed
Expand All @@ -234,7 +250,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

- Fix auth problem when fetching orders history


## [0.35.0] - 2023-07-24

### Added
Expand Down
14 changes: 14 additions & 0 deletions graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,20 @@ type Query {
@cacheControl(scope: PUBLIC, maxAge: SHORT)
@auditAccess
getSellers: [Seller] @validateAdminUserAccess @cacheControl(scope: PRIVATE)
getSellersPaginated(page: Int, pageSize: Int): GetSellersPaginatedResponse
@validateAdminUserAccess
@cacheControl(scope: PRIVATE)
}

type PaginationResponse {
page: Int
pageSize: Int
total: Int
}

type GetSellersPaginatedResponse {
items: [Seller]
pagination: PaginationResponse
}

type Mutation {
Expand Down
109 changes: 108 additions & 1 deletion node/clients/sellers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { InstanceOptions, IOContext } from '@vtex/api'
import { JanusClient } from '@vtex/api'
import { isNaN, orderBy } from 'lodash'

const SELLERS_PATH = '/api/seller-register/pvt/sellers'

Expand All @@ -9,6 +10,20 @@ export interface Seller {
email: string
}

export interface GetSellersResponse {
items: Seller[]
pagination: {
page: number
pageSize: number
total: number
}
}

export interface GetSellersOpts {
page: number
pageSize: number
}

export default class SellersClient extends JanusClient {
constructor(context: IOContext, options?: InstanceOptions) {
super(context, {
Expand All @@ -20,6 +35,98 @@ export default class SellersClient extends JanusClient {
}

public async getSellers(): Promise<{ items: Seller[] }> {
return this.http.get(SELLERS_PATH)
return this.http.get(SELLERS_PATH, {
metric: 'sellers-get',
enzomerca marked this conversation as resolved.
Show resolved Hide resolved
})
}

public async getSellersPaginated(
opts?: GetSellersOpts
): Promise<GetSellersResponse> {
const INITIAL_LIST_OPTIONS = {
page: 1,
pageSize: 100,
}

const argsWithDefaults = {
...INITIAL_LIST_OPTIONS,
...opts,
}

const { pageSize } = argsWithDefaults

const page = Math.max(1, argsWithDefaults.page)

const from = (page - 1) * pageSize
const to = page * pageSize

if (from >= to) {
throw new Error(
'Invalid pagination values: `from` should be less than `to`. Please make sure you are passing valid values for `page` and `pageSize`.'
)
}
enzomerca marked this conversation as resolved.
Show resolved Hide resolved

const result = await this.http.get<{
items: Seller[]
paging: {
from: number
to: number
total: number
}
}>(SELLERS_PATH, {
metric: 'sellers-paginated-get',
params: { from, to },
})

if (!result.items) {
return {
items: [],
pagination: {
page: 1,
pageSize: 0,
total: 0,
},
}
}

if (result.items.length > 1) {
result.items = this.sortSellers(result.items)
}

return {
items: result.items,
pagination: {
page,
pageSize,
total: result.paging.total,
},
}
}

private sortSellers(sellers: Seller[]) {
// Sorts the sellers first based on whether the name is a number, then sorts by the actual name
return orderBy(
sellers,
[
(seller: Seller) => {
const name = seller.name ?? ''
// Check if the name is a number and not an empty string
const isNumber = !isNaN(name) && name !== ''

// Returns 1 if the name is a number, or 0 if not, to prioritize sorting numbers first
return isNumber ? 1 : 0
},
(seller: Seller) => {
const name = seller.name ?? ''

// If the name is not a number, return the name as a string for alphabetical sorting
// If it is a number, convert it to a number for numeric sorting

return isNaN(name) ? name : Number(name)
},
],
// Sort both criteria in ascending order
['asc', 'asc']
)
}
}
22 changes: 22 additions & 0 deletions node/resolvers/Queries/Settings.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import GraphQLError from '../../utils/GraphQLError'
import checkConfig from '../config'
import type { B2BSettingsInput } from '../../typings'
import type { GetSellersOpts } from '../../clients/sellers'

const B2BSettings = {
getB2BSettings: async (_: void, __: void, ctx: Context) => {
Expand Down Expand Up @@ -54,6 +55,27 @@ const B2BSettings = {

return (await sellers.getSellers())?.items
},
getSellersPaginated: async (
_: void,
options: GetSellersOpts,
ctx: Context
) => {
const {
clients: { sellers },
} = ctx

try {
return await sellers.getSellersPaginated(options)
} catch (e) {
if (e.message) {
throw new GraphQLError(e.message)
} else if (e.response?.data?.message) {
throw new GraphQLError(e.response.data.message)
} else {
throw new GraphQLError(e)
}
}
},
}

export default B2BSettings
2 changes: 1 addition & 1 deletion node/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3475,7 +3475,7 @@ stack-utils@^2.0.3:
dependencies:
escape-string-regexp "^2.0.0"

"stats-lite@github:vtex/node-stats-lite#dist":
stats-lite@vtex/node-stats-lite#dist:
version "2.2.0"
resolved "https://codeload.github.com/vtex/node-stats-lite/tar.gz/1b0d39cc41ef7aaecfd541191f877887a2044797"
dependencies:
Expand Down