Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[STTYPES-6] [UILISTS-92] Add typings for SearchAndSort and friends #51

Merged
merged 6 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion components/lib/AdvancedSearch/AdvancedSearch.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,4 @@ export interface AdvancedSearchProps {
* />
* ```
*/
export default function AdvancedSearch(props: AdvancedSearchProps): ReactNode;
export default function AdvancedSearch(props: AdvancedSearchProps): JSX.Element;
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
},
"dependencies": {
"@folio/stripes-react-hotkeys": "^3.0.0",
"history": "^4.10.1",
"ky": "^0.33.3",
"moment": "^2.29.4",
"popper.js": "^1.16.1",
Expand Down
78 changes: 55 additions & 23 deletions smart-components/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,59 @@ export const LocationSelection: any;
export const PasswordValidationField: any;
export const PersistedPaneset: any;
export const ProxyManager: any;
export const SearchAndSort: any;
export const SearchAndSortQuery: any;
export const SearchAndSortNoResultsMessage: any;
export const SearchAndSortResetButton: any;
export const SearchAndSortSearchButton: any;
export const CheckboxFilter: any;
export const ExpandFilterPaneButton: any;
export const CollapseFilterPaneButton: any;
export const MultiSelectionFilter: any;
export const DateRangeFilter: any;
export const makeQueryFunction: any;
export const makeConnectedSource: any;
export const StripesConnectedSource: any;
export const ApolloConnectedSource: any;
export const getNsKey: any;
export const mapNsKeys: any;
export const removeNsKeys: any;
export const parseFilters: any;
export const deparseFilters: any;
export const buildUrl: any;

export { default as SearchAndSort, SearchAndSortProps } from './lib/SearchAndSort';
export { default as SearchAndSortQuery } from './lib/SearchAndSort/SearchAndSortQuery';
export {
default as SearchAndSortNoResultsMessage,
SearchAndSortNoResultsMessageProps,
} from './lib/SearchAndSort/components/NoResultsMessage';
export {
default as SearchAndSortResetButton,
SearchAndSortResetButtonProps,
} from './lib/SearchAndSort/components/ResetButton';
export {
default as SearchAndSortSearchButton,
SearchAndSortSearchButtonProps,
} from './lib/SearchAndSort/components/SearchButton';
export {
default as CheckboxFilter,
CheckboxFilterProps,
} from './lib/SearchAndSort/components/CheckboxFilter';
export {
default as ExpandFilterPaneButton,
ExpandFilterPaneButtonProps,
} from './lib/SearchAndSort/components/ExpandFilterPaneButton';
export {
default as CollapseFilterPaneButton,
CollapseFilterPaneButtonProps,
} from './lib/SearchAndSort/components/CollapseFilterPaneButton';
export {
default as MultiSelectionFilter,
MultiSelectionFilterProps,
} from './lib/SearchAndSort/components/MultiSelectionFilter';
export {
default as DateRangeFilter,
DateRangeFilterProps,
} from './lib/SearchAndSort/components/DateRangeFilter';

export { default as makeQueryFunction, QueryFunction } from './lib/SearchAndSort/makeQueryFunction';
export { default as advancedSearchQueryToRows } from './lib/SearchAndSort/advancedSearchQueryToRows';

export {
default as makeConnectedSource,
ConnectedSource,
ConnectedSourceProps,
ApolloConnectedSourceProps,
StripesConnectedSourceProps,
} from './lib/SearchAndSort/ConnectedSource';
export { default as StripesConnectedSource } from './lib/SearchAndSort/ConnectedSource/StripesConnectedSource';
export { default as ApolloConnectedSource } from './lib/SearchAndSort/ConnectedSource/ApolloConnectedSource';

export * from './lib/SearchAndSort/nsQueryFunctions';
export * from './lib/SearchAndSort/parseFilters';

export { default as buildUrl } from './lib/SearchAndSort/buildUrl';

export { default as Settings, SettingsProps } from './lib/Settings';

Expand All @@ -62,6 +95,5 @@ export const useRemoteStorageMappings: any;
export const useSetRef: any;
export const useSetRefOnFocus: any;
export const usePrevious: any;
export const ColumnManager: any;
export const ColumnManagerMenu: any;
export const useColumnManager: any;

export * from './lib/ColumnManager';
50 changes: 50 additions & 0 deletions smart-components/lib/ColumnManager/ColumnManager.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { ReactNode } from 'react';

export interface ColumnManagerProps {
/** The render-prop function that will receive the relevant props for implementing toggleable columns */
children: (props: {
/** An array of visible column keys that can be passed directly down to the `<MultiColumnList>` */
visibleColumns: string[];
/** Renders a <MenuSection> that wraps renderCheckboxes for toggling columns. This makes it easy to implement inside e.g. a pane action menu. */
renderColumnsMenu: ReactNode;
/** A method that toggles the visiblity for a given column – e.g. `toggleColumn('email')` */
toggleColumn: (key: string) => void;
}) => ReactNode;
/** An object that maps keys to labels. The order of the keys will determine the default order of the columns. */
columnMapping: Record<string, ReactNode>;
/** An array of keys to exclude from the list of toggleable columns */
excludeKeys?: string[];
/**
* The unique ID is used to generate the storage key for persisting the visible columns in sessionStorage.
* The ID will also be used as a prefixed ID for any UI that is passed down to the render-prop function.
*/
id: string;
/** Whether or not to persist the visible columns in sessionStorage */
persist?: boolean;
}

/**
* A render-prop component for implementing toggleable columns in a `<MultiColumnList>`.
*
* @example
* ```
* const columnMapping = {
* status: 'Status',
* name: 'Name',
* barcode: 'Barcode',
* username: 'Username',
* email: 'Email'
* };
*
* <ColumnManager
* id="users-list-columns" // Required
* columnMapping={columnMapping} // Required
* excludeKeys={['name']} // Exclude these keys from being toggleable
* >
* {({ visibleColumns, renderColumnsMenu, toggleColumn }) => {
* // Render UI
* }}
* </ColumnManager>
* ```
*/
export default function ColumnManager(props: ColumnManagerProps): JSX.Element;
17 changes: 17 additions & 0 deletions smart-components/lib/ColumnManager/ColumnManagerMenu.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { ReactNode } from 'react';

export interface ColumnManagerMenuProps {
/** An object that maps keys to labels */
columnMapping: Record<string, ReactNode>;
/** An array of keys to exclude from the list of columns */
excludeColumns?: string[];
/** Unique ID */
prefix: string;
/** An array of visible column keys */
visibleColumns: string[];
}

/**
* Renders an action menu section for toggling columns. Provided by `<ColumnManager>` as `renderColumnsMenu`.
*/
export default function ColumnManagerMenu(props: ColumnManagerMenuProps): JSX.Element;
3 changes: 3 additions & 0 deletions smart-components/lib/ColumnManager/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { default as ColumnManager, ColumnManagerProps } from './ColumnManager';
export { default as ColumnManagerMenu, ColumnManagerMenuProps } from './ColumnManagerMenu';
export { default as useColumnManager } from './useColumnManager';
11 changes: 11 additions & 0 deletions smart-components/lib/ColumnManager/useColumnManager.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ReactNode } from 'react';

export default function useColumnManager(
prefix: string,
columnMapping: Record<string, ReactNode>,
persist?: boolean,
visibleColumnsProp?: string[],
): {
visibleColumns: string[];
toggleColumn: (key: string) => void;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Logger from '../../../../util/logger';
import { ApolloConnectedSourceProps, ApolloError, ConnectedSource } from './ConnectedSource';

export default class ApolloConnectedSource implements ConnectedSource {
constructor(props: ApolloConnectedSourceProps, logger: Logger, resourceName?: string);
records(): unknown[];
resultCount(): number;
totalCount(): number | null | undefined;
pending(): boolean;
loaded(): boolean;
failure(): ApolloError | null | undefined;

failureMessage(): string;
fetchMore(increment: number): void;
successfulMutations(): unknown[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import Logger from '../../../../util/logger';
import { QueryFunction } from '../makeQueryFunction';

type ApolloError = {
message: string;
graphQLErrors: unknown[];
networkError: Error | null;
extraInfo: any;
};

export interface ApolloConnectedSourceProps {
apolloResource?: string;
apolloRecordsKey: string;
queryFunction: QueryFunction;
parentData: {
// properties directly on parentData
loading?: boolean;
successfulMutations?: unknown[];
error?: ApolloError;
fetchMore(params: {
variables: {
cql: string;
offset: number;
limit: number;
};
// record key is `apolloResource`
updateQuery: (
prev: Record<string, { records: unknown[] }>,
params: { fetchMoreResult: unknown },
) => Record<string, { records: unknown[] }>;
}): void;
} & {
// all within resource name (within recordsObj)
[resourceName: string]: {
totalRecords?: number;
} & {
// equals apolloRecordsKey
[recordsKey: string]: unknown[];
};
};
parentResources: {
query: Record<string, unknown>;
};
}

type StripesError = {
dataKey?: string;
httpStatus?: unknown;
message?: string;
module?: unknown;
resource?: unknown;
throwErrors?: unknown;
};

type StripesResourceType =
| ({
resultCount: number;
notes?: string | boolean;
filters?: string;
} & {
// called recordsObj in code
[resourceName: string]: {
records?: unknown[];
hasLoaded?: boolean;
isPending?: boolean;
failed?: StripesError;
other?: unknown;
successfulMutations?: unknown[];
};
})
| unknown; // these types may not be perfect; putting this to avoid errors

type StripesMutatorType =
| {
resultCount: {
replace: (count: number) => void;
};
resultOffset: {
replace: (offset: number) => void;
};
query: {
replace: (query: unknown) => void;
update: (query: unknown) => void;
};
}
| unknown; // these types may not be perfect; putting this to avoid errors

export interface StripesConnectedSourceProps {
// key is from resourceName
parentResources?: StripesResourceType;
resources?: StripesResourceType;
parentMutator?: StripesMutatorType;
mutator?: StripesMutatorType;
}

export interface ConnectedSource {
records(): unknown[];

/** Number of records retrieved so far */
resultCount(): number;
/**
* Number of records in the result-set, available to be retrieved.
*
* For {@code StripesConnectedSource}, when there are > 10k results to a search, the `totalRecords`
* value comes back as `999999999`, so we use that value to indicate
* that the count is, in fact, undefined vs returning null to indicate
* that the count has not been calculated.
*/
totalCount(): number | null | undefined;

/** True only during a request, false before and after */
pending(): boolean;

/** True only after a request, false before and during */
loaded(): boolean;

failure(): ApolloError | StripesError | undefined | null;

failureMessage(): string;

fetchMore(increment: number): void;

successfulMutations(): unknown[];
}

export type ConnectedSourceProps = ApolloConnectedSourceProps | StripesConnectedSourceProps;

export default function makeConnectedSource(
props: ConnectedSourceProps,
logger: Logger,
resourceName?: string,
): ConnectedSource | null;
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { StripesConnectedSourceProps, ConnectedSource, StripesError } from './ConnectedSource';
import Logger from '../../../../util/logger';

export default class StripesConnectedSource implements ConnectedSource {
constructor(props: StripesConnectedSourceProps, logger: Logger, resourceName?: string);
update(props: StripesConnectedSourceProps, resourceName?: string): void;
records(): unknown[];
resultCount(): number;
totalCount(): number | null | undefined;
pending(): boolean;
loaded(): boolean;
failure(): StripesError | null | undefined;
failureMessage(): string;
fetchMore(increment: number): void;
fetchByBrowsePoint(browsePoint: unknown): void;
fetchOffset(index: number): void;
successfulMutations(): unknown[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export {
default,
ConnectedSource,
ConnectedSourceProps,
ApolloConnectedSourceProps,
StripesConnectedSourceProps,
} from './ConnectedSource';
Loading
Loading