Search

When using the Embeddables you don’t want to directly show all of the data in any situation, that’s where the concept of searching comes in handy—with this you can filter out the data in an intuitive way. This concept is a lot easier when using TypeScript as the autocomplete handles the schema’s lookup—this is therefore highly recommended.

Structure

When composing a search you will be using this structure:

export type OperatorObject = {
  '='?: {
    value: string | number | boolean | null // The value that will be compared
    // This is used by the library to perform corrections on the search, before
    // sending it to our backend. This only works on strings. See below for more info.
    smartSearchEnabled?: boolean
    // This is the corrected value as we don't want to mutate the original value.
    smartSearchValue?: string
  }
} & {
  [key in Exclude<FilterOperators, '='>]?: {
    // Right hand value that will be compared
    value: string | number | boolean | null // The value that will be compared
  }
}

This is an example with our Core library:

const payments = await embeddable.getPayments({
    body: {
      page: 1,
      size: 100,
      sortBy: 'createdAt',
      sorter: 'Descending',
      // The Search-object:
      search: {
        grossAmount: {
          '>': {
            value: 1000, // 1 000øre (10 NOK)
          },
        },
        'connectedAccountSeller.connectedAccountID': {
          '=': {
            value: 'connected-account-id',
          },
        },
      },
    },
  })

This is the equivalent in our EmbeddableView:

const search: RouteSearchQuery[Routes.PAYMENTS] = {
  grossAmount: {
    '>': {
      value: 1000, // 1 000øre (10 NOK)
    },
  },
  // We want to filter on the connectedAccountID so that we only
  // show the payments for this connected account. This is
  // useful if we want a page which shows all payments
  // for a specific account
  'connectedAccountSeller.connectedAccountID': {
    '=': {
      value: 'connected-account-id',
    },
  },
}

All search happens with the same structure, which means that you can reuse the Search-object if you want the same data as in the table.

When representing nested objects, you need to use the period (.) to represent the path.

Typings

If you want TypeScript-autocomplete, you can use our helper types:

In the core search you can just use the SearchQuery-type in order to get the search typings of any given object: SearchQuery<Payments>

EmbeddableView:

In the EmbeddableView route search, you can use RouteSearchQuery[Routes.PAYMENTS] in order to recieve the needed table search options of a route, alternatively you can use the SearchQuery<Payments['list']> to get the same object.

Raw search structure

When creating a Search-structure we need translate this to a more readable format for our API. The raw structure that is sent to our API, based on the example above, looks like this: grossAmount>1000;connectedAccountSeller.connectedAccountID="connected-account-id". The ampersands (&&) are used to AND-ing the statements together and the pipes (||) are used to OR-ing the statements, this should be familiar. You may also use the OR-operator (|) for column-OR-ing, this makes for more complex queries:

grossAmount>1000;connectedAccountSeller.connectedAccountID=connected-account-id|connected-account-id-2

The OR-statement will be contained within the property, meaning you can only use the OR on a single property and not on multiple. Below is a full example of every concept put together

(grossAmount>1000&&connectedAccountSeller.connectedAccountID="connected-account-id"|"connected-account-id-2")||grossAmount<=1000

Meaning that if the grossAmount is larger than 10 NOK we want to only show the partial payments form these accounts, if not, show every partial payment. Kind of a silly example, but shows the possibilities.

Usages

We have several areas where Search is used, but the concept is always the same. It will always follow this structure, as we are extending this feature, we will also introduce a better search creation experience for more complex searches at a later time.