Skip to content
This repository has been archived by the owner on Apr 11, 2023. It is now read-only.

Commit

Permalink
feat: pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
simoneb committed Dec 14, 2020
1 parent 9059f36 commit 30bae22
Show file tree
Hide file tree
Showing 15 changed files with 431 additions and 83 deletions.
15 changes: 13 additions & 2 deletions packages/brokeneck-fastify/lib/plugins/auth/auth0/provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,19 @@ function Auth0Provider(options, logger) {

return {
name: 'auth0',
async listUsers() {
const users = await auth0.getUsers({})
async listUsers({ pageNumber, pageSize }) {
const page = pageNumber ? Number(pageNumber) - 1 : 0

const data = await auth0.getUsers({
page: page,
per_page: pageSize,
include_totals: true
})

const users = {
data: data.users,
nextPage: data.length === data.limit ? (page + 2).toString() : ''
}

logger.debug({ users }, 'loaded users')

Expand Down
52 changes: 52 additions & 0 deletions packages/brokeneck-fastify/lib/plugins/auth/azure/operations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'use strict'

const { Serializer } = require('@azure/ms-rest-js')
const { GraphRbacManagementMappers: Mappers } = require('@azure/graph')

const Parameters = require('./parameters')

const serializer = new Serializer(Mappers)

const listOperationSpec = {
httpMethod: 'GET',
path: '{tenantID}/users',
urlParameters: [Parameters.tenantID],
queryParameters: [
Parameters.filter,
Parameters.top,
Parameters.apiVersion,
Parameters.search
],
headerParameters: [Parameters.acceptLanguage],
responses: {
200: {
bodyMapper: Mappers.UserListResult
},
default: {
bodyMapper: Mappers.GraphError
}
},
serializer
}

const listNextOperationSpec = {
httpMethod: 'GET',
path: '{tenantID}/{nextLink}',
urlParameters: [Parameters.nextLink, Parameters.tenantID],
queryParameters: [Parameters.apiVersion, Parameters.top, Parameters.search],
headerParameters: [Parameters.acceptLanguage],
responses: {
200: {
bodyMapper: Mappers.UserListResult
},
default: {
bodyMapper: Mappers.GraphError
}
},
serializer
}

module.exports = {
listOperationSpec,
listNextOperationSpec
}
83 changes: 83 additions & 0 deletions packages/brokeneck-fastify/lib/plugins/auth/azure/parameters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
'use strict'

const acceptLanguage = {
parameterPath: 'acceptLanguage',
mapper: {
serializedName: 'accept-language',
defaultValue: 'en-US',
type: {
name: 'String'
}
}
}
const apiVersion = {
parameterPath: 'apiVersion',
mapper: {
required: true,
serializedName: 'api-version',
type: {
name: 'String'
}
}
}
const filter = {
parameterPath: ['options', 'filter'],
mapper: {
serializedName: '$filter',
type: {
name: 'String'
}
}
}

const top = {
parameterPath: ['options', 'top'],
mapper: {
serializedName: '$top',
type: {
name: 'Number'
}
}
}

const search = {
parameterPath: ['options', 'search'],
mapper: {
serializedName: '$search',
type: {
name: 'String'
}
}
}

const nextLink = {
parameterPath: 'nextLink',
mapper: {
required: true,
serializedName: 'nextLink',
type: {
name: 'String'
}
},
skipEncoding: true
}
const tenantID = {
parameterPath: 'tenantID',
mapper: {
required: true,
serializedName: 'tenantID',
type: {
name: 'String'
}
}
}

module.exports = {
tenantID,
acceptLanguage,
filter,
apiVersion,
top,
search,
nextLink
}
16 changes: 14 additions & 2 deletions packages/brokeneck-fastify/lib/plugins/auth/azure/provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,25 @@

const { GraphRbacManagementClient } = require('@azure/graph')

const { listNextOperationSpec, listOperationSpec } = require('./operations')

function AzureProvider(options, credentials, logger) {
const azure = new GraphRbacManagementClient(credentials, options.tenantId)

return {
name: 'azure',
async listUsers() {
const users = await azure.users.list()
async listUsers({ pageNumber, pageSize, search }) {
const result = await (pageNumber
? azure.sendOperationRequest(
{ nextLink: pageNumber, options: { top: pageSize, search } },
listNextOperationSpec
)
: azure.sendOperationRequest(
{ options: { top: pageSize, search } },
listOperationSpec
))

const users = { data: result, nextPage: result.odatanextLink }

logger.debug({ users }, 'loaded users')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ function CognitoProvider(options, logger) {

return {
name: 'cognito',
async listUsers() {
async listUsers({ pageNumber, pageSize }) {
const result = await cognito
.listUsers({
UserPoolId
UserPoolId,
Limit: pageSize,
PaginationToken: pageNumber || undefined
})
.promise()

const users = result.Users
const users = { data: result.Users, nextPage: result.PaginationToken }

logger.debug({ users })

Expand Down
4 changes: 2 additions & 2 deletions packages/brokeneck-fastify/lib/plugins/graphql/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
module.exports = function makeResolvers(fastify) {
return {
Query: {
users() {
return fastify.provider.listUsers()
users(_, { pageNumber, pageSize, search }) {
return fastify.provider.listUsers({ pageNumber, pageSize, search })
},
user(_, { id }) {
return fastify.provider.getUser(id)
Expand Down
7 changes: 6 additions & 1 deletion packages/brokeneck-fastify/lib/plugins/graphql/typeDefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,13 @@ const typeDefs = gql`
id: String!
}
type PaginatedUsers {
data: [User]!
nextPage: String
}
type Query {
users: [User]
users(pageNumber: String, pageSize: Int, search: String): PaginatedUsers
user(id: String!): User
groups: [Group]
group(id: String!): Group
Expand Down
3 changes: 3 additions & 0 deletions packages/brokeneck-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@
"precommit": "lint-staged"
},
"dependencies": {
"@material-ui/lab": "^4.0.0-alpha.57",
"graphql-hooks": "^5.0.0",
"lodash.debounce": "^4.0.8",
"lodash.startcase": "^4.4.0",
"lodash.throttle": "^4.1.1",
"prop-types": "^15.7.2"
},
"peerDependencies": {
Expand Down
12 changes: 10 additions & 2 deletions packages/brokeneck-react/src/components/FormField.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import React from 'react'
import T from 'prop-types'
import { Box, Checkbox, FormControlLabel, TextField } from '@material-ui/core'
import Autocomplete from '@material-ui/lab/Autocomplete'

export default function FormField({
field: { initialValue, ...field },
// eslint-disable-next-line no-unused-vars
field: { initialValue, autocomplete, getValueFromObject, ...field },
handleChange,
formValues
}) {
if (autocomplete) {
return <Autocomplete {...field} onChange={handleChange} />
}

switch (field.type) {
case 'checkbox':
return (
Expand Down Expand Up @@ -52,7 +58,9 @@ FormField.propTypes = {
name: T.string.isRequired,
label: T.string.isRequired,
type: T.string.isRequired,
initialValue: T.any.isRequired
initialValue: T.any.isRequired,
autocomplete: T.bool,
getValueFromObject: T.func
}).isRequired,
handleChange: T.func.isRequired,
formValues: T.object.isRequired
Expand Down
Loading

0 comments on commit 30bae22

Please sign in to comment.