diff --git a/src/index.js b/src/index.js index 6a82b72..038a63f 100644 --- a/src/index.js +++ b/src/index.js @@ -17,7 +17,13 @@ export default async function register(app) { version: pkg.version, collections: { EcontOffices: { - name: "EcontOffices" + name: "EcontOffices", + indexes: [ + [{ code: 1 }], + [{ name: 1 }], + [{ nameEn: 1 }], + [{ "address.address1": 1 }] + ] } }, queries, diff --git a/src/queries/econtOffices.js b/src/queries/econtOffices.js index 56a378e..53dc219 100644 --- a/src/queries/econtOffices.js +++ b/src/queries/econtOffices.js @@ -1,9 +1,33 @@ /** * Fetch all econt offices * @param {Object} context - graphql context + * @param {Object} input - Request input + * @param {String} [query] - Regex match query string * @returns {Promise<*>} - econt offices */ -export default async function econtOffices(context) { +export default async function econtOffices(context, input) { + const { searchQuery } = input; + const { collections: { EcontOffices } } = context; - return EcontOffices.find({}).toArray(); + + const query = {}; + + if (searchQuery) { + query.$or = [ + { + code: { $regex: searchQuery, $options: "i" } + }, + { + name: { $regex: searchQuery, $options: "i" } + }, + { + nameEn: { $regex: searchQuery, $options: "i" } + }, + { + "address.address1": { $regex: searchQuery, $options: "i" } + } + ]; + } + + return EcontOffices.find(query); } diff --git a/src/resolvers/Query/econtOffices.js b/src/resolvers/Query/econtOffices.js index 02ca0c3..e2cc587 100644 --- a/src/resolvers/Query/econtOffices.js +++ b/src/resolvers/Query/econtOffices.js @@ -1,10 +1,25 @@ +import getPaginatedResponse from "@reactioncommerce/api-utils/graphql/getPaginatedResponse.js"; +import wasFieldRequested from "@reactioncommerce/api-utils/graphql/wasFieldRequested.js"; + /** * Fetch all econt offices * @param {Object} parentResult - unused * @param {ConnectionArgs} args - unused * @param {Object} context - graphql execution context + * @param {Object} info Info about the GraphQL request * @returns {Promise} - econt offices */ -export default async function econtOffices(parentResult, args, context) { - return context.queries.econtOffices(context); +export default async function econtOffices(parentResult, args, context, info) { + const { + searchQuery, + ...connectionArgs + } = args; + + const query = await context.queries.econtOffices(context, { searchQuery }); + + return getPaginatedResponse(query, connectionArgs, { + includeHasNextPage: wasFieldRequested("pageInfo.hasNextPage", info), + includeHasPreviousPage: wasFieldRequested("pageInfo.hasPreviousPage", info), + includeTotalCount: wasFieldRequested("totalCount", info) + }); } diff --git a/src/schemas/schemas.graphql b/src/schemas/schemas.graphql index a1cf480..c1f4a5f 100644 --- a/src/schemas/schemas.graphql +++ b/src/schemas/schemas.graphql @@ -34,9 +34,9 @@ type EcontOfficeAddress { region: String! } -type EcontOffice { +type EcontOffice implements Node { "The office ID" - _id: ID + _id: ID! code: String! name: String, nameEn: String, @@ -44,6 +44,58 @@ type EcontOffice { phones: [String], } +"A connection edge in which each node is a `EcontOffice` object" +type EcontOfficeEdge { + "The cursor that represents this node in the paginated results" + cursor: ConnectionCursor! + + "The econt office" + node: EcontOffice +} + +""" +Wraps a list of `CatalogItem`s, providing pagination cursors and information. + +For information about what Relay-compatible connections are and how to use them, see the following articles: +- [Relay Connection Documentation](https://facebook.github.io/relay/docs/en/graphql-server-specification.html#connections) +- [Relay Connection Specification](https://facebook.github.io/relay/graphql/connections.htm) +- [Using Relay-style Connections With Apollo Client](https://www.apollographql.com/docs/react/recipes/pagination.html) +""" +type EcontOfficeConnection { + "The list of nodes that match the query, wrapped in an edge to provide a cursor string for each" + edges: [EcontOfficeEdge] + + """ + You can request the `nodes` directly to avoid the extra wrapping that `NodeEdge` has, + if you know you will not need to paginate the results. + """ + nodes: [EcontOffice] + + "Information to help a client request the next or previous page" + pageInfo: PageInfo! + + "The total number of nodes that match your query" + totalCount: Int! +} + extend type Query { - econtOffices: [EcontOffice] + econtOffices( + "Optional text search query" + searchQuery: String, + + "Return only results that come after this cursor. Use this with `first` to specify the number of results to return." + after: ConnectionCursor, + + "Return only results that come before this cursor. Use this with `last` to specify the number of results to return." + before: ConnectionCursor, + + "Return at most this many results. This parameter may be used with either `after` or `offset` parameters." + first: ConnectionLimitInt, + + "Return at most this many results. This parameter may be used with the `before` parameter." + last: ConnectionLimitInt, + + "Return only results that come after the Nth result. This parameter may be used with the `first` parameter." + offset: Int, + ): EcontOfficeConnection }