diff --git a/website/src/views/components/searchkit/RandomPicker.tsx b/website/src/views/components/searchkit/RandomPicker.tsx new file mode 100644 index 0000000000..7b838570cf --- /dev/null +++ b/website/src/views/components/searchkit/RandomPicker.tsx @@ -0,0 +1,45 @@ +import { + PageSizeAccessor, + PaginationAccessor, + SearchkitComponent, + SearchkitComponentProps, +} from 'searchkit'; +import { ModuleCode } from 'types/modules'; + +export type RandomPickerProps = { + getRandomModuleCode: () => Promise; +}; + +interface SearchkitRandomPickerProps extends SearchkitComponentProps { + buttonComponent: React.ElementType; +} + +type State = Record; + +export default class RandomPicker extends SearchkitComponent { + paginationAccessor() { + return this.accessor as PaginationAccessor; + } + + // eslint-disable-next-line class-methods-use-this + override defineAccessor() { + return new PaginationAccessor('p'); + } + + getRandomModuleCode = async (): Promise => { + const sizeAccessor = this.searchkit.getAccessorByType(PageSizeAccessor) as PageSizeAccessor; + const totalPages = Math.ceil(this.searchkit.getHitsCount() / sizeAccessor.getSize()); + const randomPage = Math.floor(Math.random() * totalPages); + + this.paginationAccessor().state = this.paginationAccessor().state.setValue(randomPage); + const { hits } = (await this.searchkit.performSearch()).results.hits; + const randomHit = hits[Math.floor(Math.random() * hits.length)]; + /* eslint-disable no-underscore-dangle */ + return randomHit._source.moduleCode; + }; + + override render() { + const { buttonComponent: Button } = this.props; + return + ); +}; + +export default ModuleRandomButton;