Skip to content

Commit

Permalink
Add documentation for inventory components, and add unit tests for in…
Browse files Browse the repository at this point in the history
…ventory utils in platform-bible-react (#1091)
  • Loading branch information
rolfheij-sil authored Aug 28, 2024
2 parents dbdec16 + 36db66e commit f414e0a
Show file tree
Hide file tree
Showing 17 changed files with 1,355 additions and 1,079 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ColumnDef,
Inventory,
ItemData,
Scope,
Status,
inventoryCountColumn,
inventoryItemColumn,
Expand All @@ -20,6 +21,16 @@ const CHARACTER_INVENTORY_STRING_KEYS: LocalizeKey[] = [
'%webView_inventory_table_header_status%',
];

/**
* Function that constructs the column for the inventory component
*
* @param itemLabel Localized label for the item column (e.g. 'Character', 'Repeated Word', etc.)
* @param unicodeValueLabel Localized label for the Unicode Value column
* @param countLabel Localized label for the count column
* @param statusLabel Localized label for the status column
* @param statusChangeHandler Callback function that handles status updates to selected item(s)
* @returns An array of columns that can be passed into the inventory component
*/
const createColumns = (
itemLabel: string,
unicodeValueLabel: string,
Expand Down Expand Up @@ -49,8 +60,8 @@ type CharacterInventoryProps = {
unapprovedItems: string[];
onUnapprovedItemsChange: (items: string[]) => void;
text: string | undefined;
scope: string;
onScopeChange: (scope: string) => void;
scope: Scope;
onScopeChange: (scope: Scope) => void;
};

function CharacterInventory({
Expand Down
23 changes: 21 additions & 2 deletions extensions/src/platform-scripture/src/inventory-utils.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
import { split } from 'platform-bible-utils';

export const extractCharacters = (text: string, item: string | undefined = undefined): string[] => {
/**
* Extracts characters from scripture text. If a target is provided, only extracts occurrences of
* the provided target
*
* @param text The scripture text from which the characters will be extracted
* @param target (Optional) If provided, the function only extracts exact matches of this character
* @returns An array of characters extracted from the provided scripture text
*/
export const extractCharacters = (
text: string,
target: string | undefined = undefined,
): string[] => {
let characters: string[] = split(text, '');
if (item) characters = characters.filter((character) => character === item);
if (target) characters = characters.filter((character) => character === target);
return characters;
};

/**
* Extracts repeated words from scripture text. If a target is provided, only extracts occurences of
* the provided target
*
* @param text The scripture text from which the characters will be extracted
* @param target (Optional) If provided, the function only extracts exact matches of this words
* @returns An array of repeated words extracted from the provided scripture text
*/
export const extractRepeatedWords = (
text: string,
target: string | undefined = undefined,
Expand Down
21 changes: 17 additions & 4 deletions extensions/src/platform-scripture/src/inventory.web-view.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { WebViewProps } from '@papi/core';
import { useLocalizedStrings, useProjectSetting, useSetting } from '@papi/frontend/react';
import { usePromise, INVENTORY_STRING_KEYS } from 'platform-bible-react';
import { Scope, usePromise, INVENTORY_STRING_KEYS } from 'platform-bible-react';
import { ScriptureReference } from 'platform-bible-utils';
import { useCallback, useMemo, useState } from 'react';
import type { ProjectSettingTypes } from 'papi-shared-types';
Expand All @@ -11,7 +11,20 @@ import RepeatedWordsInventory from './repeated-words-inventory.component';

const defaultVerseRef: ScriptureReference = { bookNum: 1, chapterNum: 1, verseNum: 1 };

const getText = async (scope: string, scriptureRef: ScriptureReference, projectId: string) => {
/**
* Get scripture text for the provided scope and reference for the specified projectId
*
* @param scope Scope of text. Can be 'book', 'chapter' or 'verse'.
* @param scriptureRef Reference to requested part of scripture
* @param projectId Id of the project from which the scripture is requested
* @returns Promise of scripture text, that can either resolve to a string or undefined
* @throws If the provided scope does not match any of the allowed values
*/
const getText = async (
scope: Scope,
scriptureRef: ScriptureReference,
projectId: string,
): Promise<string | undefined> => {
const verseRef = new VerseRef(
scriptureRef.bookNum,
scriptureRef.chapterNum,
Expand Down Expand Up @@ -64,7 +77,7 @@ global.webViewComponent = function InventoryWebView({ useWebViewState }: WebView

const [validItems, setValidItems] = useProjectSetting(projectId, validItemsSetting, '');
const [invalidItems, setInvalidItems] = useProjectSetting(projectId, invalidItemsSetting, '');
const [scope, setScope] = useState<string>('book');
const [scope, setScope] = useState<Scope>('book');
const [text] = usePromise(
useCallback(
async () => getText(scope, scriptureRef, projectId),
Expand All @@ -87,7 +100,7 @@ global.webViewComponent = function InventoryWebView({ useWebViewState }: WebView
onUnapprovedItemsChange={(items: string[]) => setInvalidItems?.(items.join(' '))}
text={text}
scope={scope}
onScopeChange={(newScope: string) => setScope(newScope)}
onScopeChange={(newScope: Scope) => setScope(newScope)}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
ColumnDef,
Inventory,
ItemData,
Scope,
Status,
inventoryCountColumn,
inventoryItemColumn,
Expand All @@ -18,6 +19,15 @@ const REPEATED_WORDS_INVENTORY_STRING_KEYS: LocalizeKey[] = [
'%webView_inventory_table_header_status%',
];

/**
* Function that constructs the column for the inventory component
*
* @param itemLabel Localized label for the item column (e.g. 'Character', 'Repeated Word', etc.)
* @param countLabel Localized label for the count column
* @param statusLabel Localized label for the status column
* @param statusChangeHandler Callback function that handles status updates to selected item(s)
* @returns An array of columns that can be passed into the inventory component
*/
const createColumns = (
itemLabel: string,
countLabel: string,
Expand All @@ -38,8 +48,8 @@ interface RepeatedWordsInventoryProps {
unapprovedItems: string[];
onUnapprovedItemsChange: (items: string[]) => void;
text: string | undefined;
scope: string;
onScopeChange: (scope: string) => void;
scope: Scope;
onScopeChange: (scope: Scope) => void;
}

function RepeatedWordsInventory({
Expand Down
364 changes: 182 additions & 182 deletions lib/platform-bible-react/dist/index.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/platform-bible-react/dist/index.cjs.map

Large diffs are not rendered by default.

50 changes: 45 additions & 5 deletions lib/platform-bible-react/dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,17 @@ export interface DataTableProps<TData, TValue> {
stickyHeader?: boolean;
onRowClickHandler?: (row: RowContents<TData>, table: TableContents<TData>) => void;
}
/**
* Feature-rich table component that infuses our basic shadcn-based Table component with features
* from TanStack's React Table library
*/
export declare function DataTable<TData, TValue>({ columns, data, enablePagination, showPaginationControls, showColumnVisibilityControls, stickyHeader, onRowClickHandler, }: DataTableProps<TData, TValue>): import("react/jsx-runtime").JSX.Element;
/**
* Object containing all keys used for localization in this component. If you're using this
* component in Platform.Bible extension, you can pass it into the useLocalizedStrings hook to
* easily obtain the localized strings and pass them into the localizedStrings prop of the Inventory
* component
*/
export declare const INVENTORY_STRING_KEYS: readonly [
"%webView_inventory_all%",
"%webView_inventory_approved%",
Expand All @@ -205,14 +215,22 @@ export declare const INVENTORY_STRING_KEYS: readonly [
export type InventoryLocalizedStrings = {
[localizedInventoryKey in (typeof INVENTORY_STRING_KEYS)[number]]?: LocalizedStringValue;
};
export type Scope = "book" | "chapter" | "verse";
export type Status = "approved" | "unapproved" | "unknown";
export type ItemData = {
item: string;
count: number;
status: Status;
};
/**
* Gets an icon that indicates the current sorting direction based on the provided input
*
* @param sortDirection Sorting direction. Can be ascending ('asc'), descending ('desc') or false (
* i.e. not sorted)
* @returns The appropriate sorting icon for the provided sorting direction
*/
export declare const getSortingIcon: (sortDirection: false | SortDirection) => React$1.ReactNode;
export interface InventoryProps {
export type InventoryProps = {
scriptureReference: ScriptureReference;
setScriptureReference: (scriptureReference: ScriptureReference) => void;
localizedStrings: InventoryLocalizedStrings;
Expand All @@ -222,13 +240,35 @@ export interface InventoryProps {
unapprovedItems: string[];
onUnapprovedItemsChange: (items: string[]) => void;
text: string | undefined;
scope: string;
onScopeChange: (scope: string) => void;
scope: Scope;
onScopeChange: (scope: Scope) => void;
getColumns: (onStatusChange: (newItems: string[], status: Status) => void) => ColumnDef<ItemData>[];
}
export declare function Inventory({ scriptureReference, setScriptureReference, localizedStrings, extractItems, approvedItems, onApprovedItemsChange, unapprovedItems, onUnapprovedItemsChange, text, scope, onScopeChange, getColumns, }: InventoryProps): import("react/jsx-runtime").JSX.Element;
};
/** Inventory component that is used to view and control the status of provided project settings */
export function Inventory({ scriptureReference, setScriptureReference, localizedStrings, extractItems, approvedItems, onApprovedItemsChange, unapprovedItems, onUnapprovedItemsChange, text, scope, onScopeChange, getColumns, }: InventoryProps): import("react/jsx-runtime").JSX.Element;
/**
* Function that creates the item column for inventories
*
* @param itemLabel Localized label for the item column (e.g. 'Character', 'Repeated Word', etc.)
* @returns Column that shows the inventory items. Should be used with the DataTable component
*/
export declare const inventoryItemColumn: (itemLabel: string) => ColumnDef<ItemData>;
/**
* Function that creates the count column for inventories. Should be used with the DataTable
* component.
*
* @param itemLabel Localized label for the count column
* @returns Column that shows the number of occurrences of the related inventory items
*/
export declare const inventoryCountColumn: (countLabel: string) => ColumnDef<ItemData>;
/**
* Function that creates the status column for inventories. Should be used with the DataTable
* component.
*
* @param itemLabel Localized label for the status column
* @param statusChangeHandler Callback function that handles status updates to selected item(s)
* @returns Column that shows the status of the related inventory items.
*/
export declare const inventoryStatusColumn: (statusLabel: string, statusChangeHandler: (items: string[], status: Status) => void) => ColumnDef<ItemData>;
export declare const buttonVariants: (props?: ({
variant?: "link" | "default" | "outline" | "destructive" | "secondary" | "ghost" | null | undefined;
Expand Down
Loading

0 comments on commit f414e0a

Please sign in to comment.