SeedCompany / cord-api-v3

Bible translation project management API
MIT License
18 stars 4 forks source link

[Neo4j] Nested Sorting + Engagement expanded usage #3226

Closed CarsonF closed 1 month ago

CarsonF commented 1 month ago

Why? Engagement sorters

This new functionality is driven by the need for the new UI to sort by deep fields. Now the engagements list supports sorting by:

sorting -> sortWith

Previously we had

query.apply(sorting(User, input, {
  ...
}))

This still works, but now it's recommended to switch to declare the matchers/sorters separately from application in a query.

// top level
export const userSorters = defineSorters(User, {
  ...
});

// in list()
query.apply(sortWith(userSorters, input))

This split allows the sorters to be referenced as sub/nested sorting in other sorting calls.

Basic sorter

Each key is the sort field string that callers can pick this is a loose string, so it can be an existing field on the type or something completely new.

const userSorters = defineSorters(User, {
  name: (query) => query
    // Do whatever to calculate the sort value.
    // `node` can be assumed to be the current type.
    // One per row.
    .match(...)
    // This "matcher" function should end with a return clause that
    // emits `sortValue`
    .return<SortCol>('x as sortValue'),

This hasn't changed from previous functionality.

Nested sorter

The ability to nest sorting into relationships is possible. This is done by appending .* to the key. For example, the sort field could be "parent.name"

const userSorters = defineSorters(User, {
  'name': (query) => ...

  'parent.*': (query, input) => query
    // Again match as needed
    .match(...)
    // Call sortWith with the sorters of the relationship type.
    // These matchers are also given the current sort _input_
    // (second arg above) which can be passed down like this.
    // `sortWith` understands this nesting and will remove the `parent.`
    // prefix before matching the nested sorters.
    .apply(sortWith(userSorters, input))
});

Extending other sorters

Sorters can "extend" others too. Defined sorters have their declared matchers exposed on the matchers property. So they can be spread/picked/etc. into a new object. For example, say Manager extends User, and we want to add some sorters for that type but keep the User ones as well.

const managerSorters = defineSorters(Manager, {
  ...userSorters.matchers,
  // Add some new ones
});

https://seed-company-squad.monday.com/boards/5989610236/pulses/6766885746