# SASQLookupComponent

A highly configurable component that renders a lookup view for displaying data in a multi-pane layout. **SASQLookupComponent** combines a search and sort query (SASQ) interface, a filter pane, and a main content pane into a unified view. It leverages components from `@folio/stripes/smart-components` and `@folio/stripes/components` to provide a persistent paneset layout with integrated search, filtering, and pagination.

> **Note:** Detailed documentation for sub-components (such as **SearchAndSortQuery**, **PersistedPaneset**, **CollapseFilterPaneButton**, and **ExpandFilterPaneButton**) is available separately. **SASQLookupComponent** is designed to work seamlessly with these components while allowing for significant customization via its props.

## Basic Usage

Below is an example demonstrating how to use **SASQLookupComponent**. In this example, the component is configured with custom fetch parameters, filtering behavior, and a custom table body for rendering results. The component automatically manages query state, pagination, and filter pane visibility.

```jsx
import { FormattedMessage } from 'react-intl';
import { SASQLookupComponent } from '@k-int/stripes-kint-components';
import CustomFilter from './CustomFilter';
import CustomTableBody from './CustomTableBody';

const MyLookupView = () => {
  const fetchParameters = {
    endpoint: '/api/my-items',
    SASQ_MAP: {
      searchKey: 'name',
      perPage: 25,
      // Additional SASQ configuration
    }
  };

  return (
    <SASQLookupComponent
      id="my-lookup"
      path="/my-lookup"
      fetchParameters={fetchParameters}
      FilterComponent={CustomFilter}
      RenderBody={CustomTableBody}
      intlKey="myLookup"
      intlNS="myApp"
      labelOverrides={{ foundValues: 'Items Found' }}
      resultColumns={[
        { propertyPath: 'name', label: <FormattedMessage id="myApp.item.name" /> },
        { propertyPath: 'status', label: <FormattedMessage id="myApp.item.status" /> }
      ]}
      searchFieldAriaLabel="Search items"
    >
      {/* Optionally, additional children can be rendered */}
    </SASQLookupComponent>
  );
};

export default MyLookupView;
````

In this example, **SASQLookupComponent**:

* Uses `fetchParameters` to configure data fetching.
* Provides a custom filter interface via `FilterComponent`.
* Renders results using a custom table body (or defaults to an internal **TableBody**).
* Manages pagination and query state via hooks like `usePrevNextPagination` and `useKiwtSASQuery`.

## Props
| Name                            | Type              | Description                                                                                                                                                                                                                                                                                                                                               | Default                                   | Required |
|---------------------------------|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------|----------|
| `id`                            | `string`          | A unique identifier for the lookup instance. Used to generate unique keys for query state, persistent paneset, and filter pane visibility in local storage.                                                                                                                                                                                               |                                           | ✓        |
| `fetchParameters`               | `object`          | An object that defines the endpoints and SASQ configuration used for fetching data. It must include:\<br\>\<br\>• **endpoint:** The URL used to fetch the main data set. This is effectively required for data fetching to work.\<br\>• **SASQ\_MAP:** An object containing settings for search, filter, pagination (e.g., `searchKey`, `perPage`, etc.). | `{}`                                      | ✕        |
| `FilterComponent`               | `func` or `node`  | A custom component used to render additional filtering options in the filter pane. This component receives props for managing active filters, search state, and resetting filters.                                                                                                                                                                        | `() => null`                              | ✕        |
| `FilterPaneHeaderComponent`     | `func` or `node`  | A component rendered at the top of the filter pane. Use this to customize the header area of the filter pane.                                                                                                                                                                                                                                             | `() => null`                              | ✕        |
| `filterPaneProps`               | `object`          | Additional props to be passed to the filter pane. These props can customize the appearance and behavior of the filter pane (such as first or last menu elements).                                                                                                                                                                                         | `{}`                                      | ✕        |
| `hasFilterPane`                 | boolean           | An "on/off" switch for the filter pane. When `false` the filter pane will not be rendered at all and it will be up to the RenderBody to handle all searching/filtering.                                                                                                                                                                                   | true                                      | ✕        |
| `intlKey`                       | `string`          | A base internationalization key used by the internal `useKintIntl` hook to resolve localized messages (e.g., for labels or pane titles).                                                                                                                                                                                                                  |                                           | ✕        |
| `intlNS`                        | `string`          | An internationalization namespace used by the internal `useKintIntl` hook.                                                                                                                                                                                                                                                                                |                                           | ✕        |
| `labelOverrides`                | `object`          | An object for overriding default labels, such as the text for displaying the count of found values.                                                                                                                                                                                                                                                       | `{}`                                      | ✕        |
| `lookupQueryNamespaceGenerator` | `func`            | A function that generates a query namespace (an array) for `react-query` based on provided parameters such as `currentPage`, `namespace`, `id`, `query`, etc. This ensures that queries are uniquely identified.                                                                                                                                          | See default implementation in source code | ✕        |
| `lookupQueryPromise`            | `func`            | A function to execute the data fetching promise. Receives an object with `endpoint`, `ky` (OkapiKy instance), `queryParams`. Should return a Promise that resolves to the fetched data. This is in place to allow for varying fetch methodologies, such as implementing a non-FOLIO ky instance.                                                          | See default implementation in source code | ✕        |
| `lookupResponseTransform`       | `func`            | A function passed to the "select" prop of react-query useQuery, allowing for direct transformation of the return shape of data.                                                                                                                                                                                                                           | response => response                      | ✕        |
| `mainPaneProps`                 | `object`          | Additional props to be passed to the main pane containing the lookup results. This can include custom menu elements or styling.                                                                                                                                                                                                                           | `{}`                                      | ✕        |
| `mclProps`                      | `object`          | Custom properties to be passed to the underlying Multi-Column List (MCL) component. These properties are merged with pagination props derived from `usePrevNextPagination`.                                                                                                                                                                               | `{}`                                      | ✕        |
| `noResultsProps`                | `object`          | Props to be passed down to the [NoResultsMessage](https://gitlab.com/knowledge-integration/folio/stripes-kint-components/-/tree/main/src/lib/NoResultsMessage) splash screen component rendered when no results are present from the query. If `component` is passed, this will be rendered with the props available to `NoResultsMessage`.               | `{}`                                      | ✕        |
| `noSearchField`                 | `bool`            | When set to `true`, the search field is not rendered in the filter pane. Use this if you want to disable search input.                                                                                                                                                                                                                                    | `false`                                   | ✕        |
| `persistedPanesetProps`         | `object`          | Additional props to be passed to the **PersistedPaneset** component, which manages the persistent layout of the filter and main panes.                                                                                                                                                                                                                    | `{}`                                      | ✕        |
| `queryParameterGenerator`       | `func`            | A function that takes the SASQ\_MAP configuration and current query values to generate an array of query parameters for the fetch call. Defaults to `generateKiwtQuery`.                                                                                                                                                                                  | `generateKiwtQuery`                       | ✕        |
| `RenderBody`                    | `func` or `node`  | A component used to render the body of the main pane (typically a table). If not provided, the internal **TableBody** component is used.                                                                                                                                                                                                                  | `TableBody`                               | ✕        |
| `rowNavigation`                 | `bool`            | Flag to enable or disable row navigation. When enabled, clicking on a row triggers navigation to a detailed view.                                                                                                                                                                                                                                         | `true`                                    | ✕        |
| `sasqProps`                     | `object`          | Additional props to override or extend the default SASQ query behavior. These props can include custom query values, setters, getters, and `initialSortState`.                                                                                                                                                                                            |                                           | ✕        |
| `searchableIndexes`             | `arrayOf(object)` | An array of objects defining the options for the search index selection component (`SearchKeyControl`), rendered below the search field. Each object typically has `key` and `label` keys. If empty or omitted, the qindex checkboxes are not shown.                                                                                                      | `[]`                                      | ✕        |
| `searchFieldAriaLabel`          | `string`          | Accessibility label for the search field.                                                                                                                                                                                                                                                                                                                 |                                           | ✕        |
| `searchFieldProps`              | `object`          | Additional props to be passed to the **SearchField** component for customizing its behavior or styling.                                                                                                                                                                                                                                                   | `{}`                                      | ✕        |
| `children`                      | `node`, `func`    | Optional children to be rendered below the main pane. These are rendered within the **PersistedPaneset** container.                                                                                                                                                                                                                                       |                                           | ✕        |
| `history`                       | `object`          | (Provided by React Router) The history object.                                                                                                                                                                                                                                                                                                            |                                           | ✕        |
| `location`                      | `object`          | (Provided by React Router) The location object.                                                                                                                                                                                                                                                                                                           |                                           | ✕        |
| `match`                         | `object`          | (Provided by React Router) The match object.                                                                                                                                                                                                                                                                                                              |                                           | ✕        |
| `path`                          | `string`          | (Provided by React Router) The path for the current route.                                                                                                                                                                                                                                                                                                |                                           | ✓        |
| `resource`                      | `object`          | (Provided by Stripes) The resource object, typically containing data and metadata for the current resource.                                                                                                                                                                                                                                               |                                           | ✕        |
| `resultColumns`                 | `arrayOf(object)` | An array of objects defining the columns for the MCL component, typically used by `RenderBody` (e.g., `TableBody`).                                                                                                                                                                                                                                       |                                           | ✕        |
| `...props`                      | `object`          | Additional props will be passed down to the `RenderBody`. Use these to further customize behavior or appearance as needed.                                                                                                                                                                                                                                |                                           | ✕        |

## Exposed Ref Functionality

**SASQLookupComponent** uses `forwardRef` and `useImperativeHandle` to expose specific properties to parent components. This allows external components to access certain internal states and query-related information directly. The ref object includes the following properties:

* **`lookupQueryProps`**:
  An object containing:

  * **`data`**: The latest data fetched by the component.

  * Additional query-related properties returned from `useQuery` (such as loading state, error, etc.).

* **`queryParams`**:
  The array of query parameters generated by the component, based on the provided SASQ configuration and current query state. This reflects the current filters, pagination, and search criteria used for the data fetch.

In general it is recommended not to use this functionality, as it represents an antipattern in React to pass information back up to the parents. Instead the implementing developer should try to replace the inner rendered components and do their logic there with the passed information.

### Worked Example

Below is a sample usage demonstrating how to access the exposed ref properties:

```jsx
import { useRef, useEffect } from 'react';
import { SASQLookupComponent } from '@k-int/stripes-kint-components';

const LookupWithRefExample = () => {
  // Create a ref to access SASQLookupComponent's exposed methods and properties
  const lookupRef = useRef();

  useEffect(() => {
    // When the component mounts or updates, you can access the lookupQueryProps and queryParams
    if (lookupRef.current) {
      const { lookupQueryProps, queryParams } = lookupRef.current;
      console.log('Fetched data:', lookupQueryProps.data);
      console.log('Current query parameters:', queryParams);

      // Example: Check if data is loaded and then trigger some side-effect
      if (!lookupQueryProps.isLoading && lookupQueryProps.data) {
        // Perform an action with the fetched data
        console.log('Data is ready for processing');
      }
    }
  }, []);

  const fetchParameters = {
    endpoint: '/api/my-items',
    SASQ_MAP: {
      searchKey: 'name',
      perPage: 25
    }
  };

  return (
    <SASQLookupComponent
      id="my-lookup"
      path="/my-lookup"
      fetchParameters={fetchParameters}
      intlKey="myLookup"
      intlNS="myApp"
      ref={lookupRef}  // Attach the ref here
      searchableIndexes={[
        { key: 'name' },
        { key: 'description' }
      ]} // Provide options for search key selection
    />
  );
};

export default LookupWithRefExample;
```

## How It Works

1.  **Query and Pagination Management:**
* The component leverages hooks such as `usePrevNextPagination` (for page state), `useKiwtSASQuery` (for search/filter/sort state), and `useQuery` (from `react-query` for data fetching). The query parameters string is generated using the provided `queryParameterGenerator` function based on the `fetchParameters.SASQ_MAP` and the current state from the hooks.
2.  **Filter Pane & Main Pane Layout:**
  * **Filter Pane:**
    * Rendered conditionally based on local storage state (`filterPaneVisible`), it contains a search section (SearchField, SearchKeyControl if `searchableIndexes` are provided, Submit/Reset buttons - unless `noSearchField` is true) and custom filtering options provided via `FilterComponent` and `FilterPaneHeaderComponent`. Buttons for collapsing the pane are included.
  * **Main Pane:**
    * Displays the fetched data using the `RenderBody` component (defaulting to `TableBody`). It integrates pagination controls (via `mclProps` passed to `RenderBody`) and displays record counts in the header. An expand button is shown if the filter pane is collapsed.
3.  **Persistent Layout:**
    The component wraps its content in a **PersistedPaneset** which maintains pane states (such as sizes and visibility) across sessions.
4.  **Customization and Extensibility:**
    Through various props, consumers can inject custom components (`FilterComponent`, `FilterPaneHeaderComponent`, `RenderBody`), override query generation (`queryParameterGenerator`, `lookupQueryNamespaceGenerator`), configure data fetching (`fetchParameters`), pass props down to underlying components (`filterPaneProps`, `mainPaneProps`, `mclProps`, `persistedPanesetProps`, `searchFieldProps`), tweak SASQ behavior (`sasqProps`), and adjust UI elements (`noSearchField`, `labelOverrides`, `searchableIndexes`).
5.  **Ref Forwarding:**
    Using `forwardRef` and `useImperativeHandle`, the component exposes certain query properties and generated query parameters to parent components.

This design enables **SASQLookupComponent** to serve as a robust and flexible foundation for building data lookup views with advanced filtering, search, and pagination functionalities.

## Use in Settings

In Settings, often a "search and filter" experience is wanted, but with 2 panes instead of 3. In order to facilitate this,
SASQRoute (via SASQLookupComponent) exposes a set of props.

- `hasFilterPane`. This defaults to true, if set to false it will _instead_ default to rendering a search bar at the
  top of the main pane. It will additionally render any passed FilterHeaderComponent and FilterComponent.
- `noSearchField`. In order to prevent rendering of the search bar, set this to false.

In this way a SASQRoute can be set up to be purely routing with no search/filter, or with search and filter in the main
  body for settings.