From 9f833123e2f01640c83f5a208e72220b0f6a5de4 Mon Sep 17 00:00:00 2001 From: Brooke Date: Mon, 19 Sep 2022 15:53:46 -0700 Subject: [PATCH 1/3] GAME-107 #comment This commit refactors the SWR to be a generic hook that lives in the lib and can be re-used elsewhere. It makes the styling of the Load More button static. It moves everything to do w/routing to the .routes page and removes duplicate paths. It creates a breadccrumb provider for the Gamification tool so we're not duplicating the base item. It moves the retrieval of the badge info into a provider so that it's not directly in the presentation layer. #time 4h --- src-ts/lib/pagination/index.ts | 3 + .../lib/pagination/infinite-page-dao.model.ts | 4 + .../pagination/infinite-page-handler.model.ts | 5 + .../lib/pagination/use-infinite-page.hook.ts | 25 ++++ src-ts/lib/table/Table.tsx | 37 +++--- src-ts/lib/table/index.ts | 1 + src-ts/lib/table/table-column.model.ts | 1 - .../table/table-functions/table.functions.ts | 18 +-- .../gamification-config.model.ts | 1 + .../gamification.config.ts | 0 .../gamification.default.config.ts | 1 + .../gamification.dev.config.ts | 3 +- .../gamification.prod.config.ts | 2 + .../{config => game-config}/index.ts | 0 .../game-badge.model.ts} | 3 +- .../gamification-admin/game-lib/index.ts | 3 + .../game-lib/use-get-game-badges-page.hook.ts | 30 +++++ .../useGamificationBreadcrumb.provider.tsx | 16 +++ .../gamification-admin.routes.tsx | 22 +++- .../lib/hooks/getDataSource.ts | 5 - .../pages/badge-detail/BadgeDetailPage.tsx | 44 +++---- .../pages/badge-listing/BadgeListingPage.tsx | 109 ++++++++---------- .../BadgeActionRenderer.tsx | 54 +++++++-- .../badge-listing-table.config.tsx | 6 +- .../BadgeListingNameRenderer.tsx | 10 +- .../badge-listing-table/index.ts | 1 + .../pages/create-badge/CreateBadgePage.tsx | 40 ++++--- 27 files changed, 287 insertions(+), 157 deletions(-) create mode 100644 src-ts/lib/pagination/infinite-page-dao.model.ts create mode 100644 src-ts/lib/pagination/infinite-page-handler.model.ts create mode 100644 src-ts/lib/pagination/use-infinite-page.hook.ts rename src-ts/tools/gamification-admin/{config => game-config}/gamification-config.model.ts (75%) rename src-ts/tools/gamification-admin/{config => game-config}/gamification.config.ts (100%) rename src-ts/tools/gamification-admin/{config => game-config}/gamification.default.config.ts (91%) rename src-ts/tools/gamification-admin/{config => game-config}/gamification.dev.config.ts (56%) rename src-ts/tools/gamification-admin/{config => game-config}/gamification.prod.config.ts (63%) rename src-ts/tools/gamification-admin/{config => game-config}/index.ts (100%) rename src-ts/tools/gamification-admin/{lib/models/badge.model.ts => game-lib/game-badge.model.ts} (60%) create mode 100644 src-ts/tools/gamification-admin/game-lib/index.ts create mode 100644 src-ts/tools/gamification-admin/game-lib/use-get-game-badges-page.hook.ts create mode 100644 src-ts/tools/gamification-admin/game-lib/useGamificationBreadcrumb.provider.tsx delete mode 100644 src-ts/tools/gamification-admin/lib/hooks/getDataSource.ts create mode 100644 src-ts/tools/gamification-admin/pages/badge-listing/badge-listing-table/index.ts diff --git a/src-ts/lib/pagination/index.ts b/src-ts/lib/pagination/index.ts index 3b90b0623..b8e69f71a 100644 --- a/src-ts/lib/pagination/index.ts +++ b/src-ts/lib/pagination/index.ts @@ -1,2 +1,5 @@ +export * from './infinite-page-dao.model' +export * from './infinite-page-handler.model' export * from './page.model' export * from './sort.model' +export * from './use-infinite-page.hook' diff --git a/src-ts/lib/pagination/infinite-page-dao.model.ts b/src-ts/lib/pagination/infinite-page-dao.model.ts new file mode 100644 index 000000000..2b2520095 --- /dev/null +++ b/src-ts/lib/pagination/infinite-page-dao.model.ts @@ -0,0 +1,4 @@ +export interface InfinitePageDao { + count: number + rows: ReadonlyArray +} diff --git a/src-ts/lib/pagination/infinite-page-handler.model.ts b/src-ts/lib/pagination/infinite-page-handler.model.ts new file mode 100644 index 000000000..cab09cc1a --- /dev/null +++ b/src-ts/lib/pagination/infinite-page-handler.model.ts @@ -0,0 +1,5 @@ +export interface InfinitePageHandler { + data?: ReadonlyArray + getAndSetNext: () => void + hasMore: boolean +} diff --git a/src-ts/lib/pagination/use-infinite-page.hook.ts b/src-ts/lib/pagination/use-infinite-page.hook.ts new file mode 100644 index 000000000..6f1367ea2 --- /dev/null +++ b/src-ts/lib/pagination/use-infinite-page.hook.ts @@ -0,0 +1,25 @@ +import { flatten, map } from 'lodash' +// tslint:disable-next-line: no-submodule-imports +import useSWRInfinite, { SWRInfiniteResponse } from 'swr/infinite' + +import { InfinitePageDao } from './infinite-page-dao.model' +import { InfinitePageHandler } from './infinite-page-handler.model' + +export function useGetInfinitePage(getKey: (index: number, previousPageData: InfinitePageDao) => string | undefined): + InfinitePageHandler { + + const { data, setSize, size }: SWRInfiniteResponse> = useSWRInfinite(getKey, { revalidateFirstPage: false }) + + // flatten version of badges paginated data + const outputData: ReadonlyArray = flatten(map(data, dao => dao.rows)) + + function getAndSetNext(): void { + setSize(size + 1) + } + + return { + data: outputData, + getAndSetNext, + hasMore: outputData.length < (data?.[0]?.count || 0), + } +} diff --git a/src-ts/lib/table/Table.tsx b/src-ts/lib/table/Table.tsx index 7858bb476..ad3443d25 100644 --- a/src-ts/lib/table/Table.tsx +++ b/src-ts/lib/table/Table.tsx @@ -1,7 +1,7 @@ import classNames from 'classnames' import { Dispatch, MouseEvent, SetStateAction, useEffect, useState } from 'react' -import { Button, ButtonSize, ButtonStyle } from '../button' +import { Button } from '../button' import { Sort } from '../pagination' import '../styles/_includes.scss' import { IconOutline } from '../svgs' @@ -16,13 +16,10 @@ import styles from './Table.module.scss' interface TableProps { readonly columns: ReadonlyArray> readonly data: ReadonlyArray - readonly loadMoreBtnLabel?: string - readonly loadMoreBtnSize?: ButtonSize - readonly loadMoreBtnStyle?: ButtonStyle readonly moreToLoad?: boolean - readonly onLoadMoreClick?: (data: T) => void + readonly onLoadMoreClick?: () => void readonly onRowClick?: (data: T) => void - readonly onToggleSort?: (sort: Sort | undefined) => void + readonly onToggleSort?: (sort: Sort) => void } interface DefaultSortDirectionMap { @@ -41,7 +38,7 @@ const Table: (props: TableProps) = Dispatch> ] = useState() - const [sortedData, setSortData]: [ReadonlyArray, Dispatch>>] + const [sortedData, setSortedData]: [ReadonlyArray, Dispatch>>] = useState>(props.data) useEffect(() => { @@ -54,7 +51,11 @@ const Table: (props: TableProps) = setDefaultSortDirectionMap(map) } - setSortData(tableGetSorted(data, columns, sort)) + // if we have a sort handler, don't worry about getting the sorted data; + // otherwise, get the sorted data for the table + const sorted: ReadonlyArray = !!props.onToggleSort ? data : tableGetSorted(data, columns, sort) + + setSortedData(sorted) }, [ columns, @@ -84,9 +85,7 @@ const Table: (props: TableProps) = setSort(newSort) // call the callback to notify parent for sort update - if (props.onToggleSort) { - props.onToggleSort(newSort) - } + props.onToggleSort?.(newSort) } const headerRow: Array = props.columns @@ -95,13 +94,12 @@ const Table: (props: TableProps) = const isCurrentlySorted: boolean = isSortable && col.propertyName === sort?.fieldName const colorClass: string = isCurrentlySorted ? 'black-100' : 'black-60' const sortableClass: string | undefined = isSortable ? styles.sortable : undefined - const centerClass: string | undefined = col.centerHeader ? styles.centerHeader : undefined return ( -
+
{col.label} {!!col.tooltip && (
@@ -172,9 +170,16 @@ const Table: (props: TableProps) = { - props.moreToLoad &&
-
+ !!props.moreToLoad && !!props.onLoadMoreClick && ( +
+
+ ) }
) diff --git a/src-ts/lib/table/index.ts b/src-ts/lib/table/index.ts index d7b124c44..396d852ea 100644 --- a/src-ts/lib/table/index.ts +++ b/src-ts/lib/table/index.ts @@ -1,2 +1,3 @@ export * from './table-column.model' +export { tableGetDefaultSort } from './table-functions' export { default as Table } from './Table' diff --git a/src-ts/lib/table/table-column.model.ts b/src-ts/lib/table/table-column.model.ts index 6d7ddb0c9..4323da523 100644 --- a/src-ts/lib/table/table-column.model.ts +++ b/src-ts/lib/table/table-column.model.ts @@ -1,7 +1,6 @@ import { TableCellType } from './table-cell.type' export interface TableColumn { - readonly centerHeader?: boolean readonly defaultSortDirection?: 'asc' | 'desc' readonly isDefaultSort?: boolean readonly label?: string diff --git a/src-ts/lib/table/table-functions/table.functions.ts b/src-ts/lib/table/table-functions/table.functions.ts index cfd4d25af..72e050f05 100644 --- a/src-ts/lib/table/table-functions/table.functions.ts +++ b/src-ts/lib/table/table-functions/table.functions.ts @@ -1,17 +1,21 @@ import { Sort } from '../../pagination' import { TableColumn } from '../table-column.model' -export function getDefaultSort(columns: ReadonlyArray>): Sort | undefined { +export function getDefaultSort(columns: ReadonlyArray>): Sort { const defaultSortColumn: TableColumn | undefined = columns.find(col => col.isDefaultSort) || columns.find(col => !!col.propertyName) + || columns?.[0] - const defaultSort: Sort | undefined = !defaultSortColumn?.propertyName - ? undefined - : { - direction: defaultSortColumn.defaultSortDirection || 'asc', - fieldName: defaultSortColumn.propertyName, - } + // if we didn't find a default sort, we have a problem + if (!defaultSortColumn) { + throw new Error('A table must have at least one column.') + } + + const defaultSort: Sort = { + direction: defaultSortColumn.defaultSortDirection || 'asc', + fieldName: defaultSortColumn.propertyName || '', + } return defaultSort } diff --git a/src-ts/tools/gamification-admin/config/gamification-config.model.ts b/src-ts/tools/gamification-admin/game-config/gamification-config.model.ts similarity index 75% rename from src-ts/tools/gamification-admin/config/gamification-config.model.ts rename to src-ts/tools/gamification-admin/game-config/gamification-config.model.ts index f090f1389..c1b0124fe 100644 --- a/src-ts/tools/gamification-admin/config/gamification-config.model.ts +++ b/src-ts/tools/gamification-admin/game-config/gamification-config.model.ts @@ -1,3 +1,4 @@ export interface GamificationConfigModel { ORG_ID: string + PAGE_SIZE: number } diff --git a/src-ts/tools/gamification-admin/config/gamification.config.ts b/src-ts/tools/gamification-admin/game-config/gamification.config.ts similarity index 100% rename from src-ts/tools/gamification-admin/config/gamification.config.ts rename to src-ts/tools/gamification-admin/game-config/gamification.config.ts diff --git a/src-ts/tools/gamification-admin/config/gamification.default.config.ts b/src-ts/tools/gamification-admin/game-config/gamification.default.config.ts similarity index 91% rename from src-ts/tools/gamification-admin/config/gamification.default.config.ts rename to src-ts/tools/gamification-admin/game-config/gamification.default.config.ts index aa7ad4626..b2c40e4d8 100644 --- a/src-ts/tools/gamification-admin/config/gamification.default.config.ts +++ b/src-ts/tools/gamification-admin/game-config/gamification.default.config.ts @@ -2,4 +2,5 @@ import { GamificationConfigModel } from './gamification-config.model' export const GamificationConfigDefault: GamificationConfigModel = { ORG_ID: '6052dd9b-ea80-494b-b258-edd1331e27a3', + PAGE_SIZE: 12, } diff --git a/src-ts/tools/gamification-admin/config/gamification.dev.config.ts b/src-ts/tools/gamification-admin/game-config/gamification.dev.config.ts similarity index 56% rename from src-ts/tools/gamification-admin/config/gamification.dev.config.ts rename to src-ts/tools/gamification-admin/game-config/gamification.dev.config.ts index 63bd27ddf..02fec4630 100644 --- a/src-ts/tools/gamification-admin/config/gamification.dev.config.ts +++ b/src-ts/tools/gamification-admin/game-config/gamification.dev.config.ts @@ -1,5 +1,6 @@ import { GamificationConfigModel } from './gamification-config.model' +import { GamificationConfigDefault } from './gamification.default.config' export const GamificationConfigDev: GamificationConfigModel = { - ORG_ID: '6052dd9b-ea80-494b-b258-edd1331e27a3', + ...GamificationConfigDefault, } diff --git a/src-ts/tools/gamification-admin/config/gamification.prod.config.ts b/src-ts/tools/gamification-admin/game-config/gamification.prod.config.ts similarity index 63% rename from src-ts/tools/gamification-admin/config/gamification.prod.config.ts rename to src-ts/tools/gamification-admin/game-config/gamification.prod.config.ts index 922edc652..e49185be0 100644 --- a/src-ts/tools/gamification-admin/config/gamification.prod.config.ts +++ b/src-ts/tools/gamification-admin/game-config/gamification.prod.config.ts @@ -1,5 +1,7 @@ import { GamificationConfigModel } from './gamification-config.model' +import { GamificationConfigDefault } from './gamification.default.config' export const GamificationConfigProd: GamificationConfigModel = { + ...GamificationConfigDefault, ORG_ID: 'e111f8df-6ac8-44d1-b4da-bb916f5e3425', } diff --git a/src-ts/tools/gamification-admin/config/index.ts b/src-ts/tools/gamification-admin/game-config/index.ts similarity index 100% rename from src-ts/tools/gamification-admin/config/index.ts rename to src-ts/tools/gamification-admin/game-config/index.ts diff --git a/src-ts/tools/gamification-admin/lib/models/badge.model.ts b/src-ts/tools/gamification-admin/game-lib/game-badge.model.ts similarity index 60% rename from src-ts/tools/gamification-admin/lib/models/badge.model.ts rename to src-ts/tools/gamification-admin/game-lib/game-badge.model.ts index c88efeb78..7c4c719b2 100644 --- a/src-ts/tools/gamification-admin/lib/models/badge.model.ts +++ b/src-ts/tools/gamification-admin/game-lib/game-badge.model.ts @@ -1,4 +1,5 @@ -export interface Badge { +// TODO: add factory to convert snake case property names to camel case +export interface GameBadge { active: boolean badge_description: string badge_image_url: string diff --git a/src-ts/tools/gamification-admin/game-lib/index.ts b/src-ts/tools/gamification-admin/game-lib/index.ts new file mode 100644 index 000000000..f9755858a --- /dev/null +++ b/src-ts/tools/gamification-admin/game-lib/index.ts @@ -0,0 +1,3 @@ +export * from './game-badge.model' +export * from './use-get-game-badges-page.hook' +export * from './game-badge.model' diff --git a/src-ts/tools/gamification-admin/game-lib/use-get-game-badges-page.hook.ts b/src-ts/tools/gamification-admin/game-lib/use-get-game-badges-page.hook.ts new file mode 100644 index 000000000..885d1af51 --- /dev/null +++ b/src-ts/tools/gamification-admin/game-lib/use-get-game-badges-page.hook.ts @@ -0,0 +1,30 @@ +import { EnvironmentConfig } from '../../../config' +import { InfinitePageDao, InfinitePageHandler, Sort, useGetInfinitePage } from '../../../lib' +import { GamificationConfig } from '../game-config' + +import { GameBadge } from './game-badge.model' + +export function useGetGameBadgesPage(sort: Sort): InfinitePageHandler { + + function getKey(index: number, previousPageData: InfinitePageDao): string | undefined { + + // reached the end + if (!!previousPageData && !previousPageData.rows.length) { + return undefined + } + + const params: Record = { + limit: `${GamificationConfig.PAGE_SIZE}`, + offset: `${index * GamificationConfig.PAGE_SIZE}`, + order_by: sort.fieldName, + order_type: sort.direction, + organization_id: GamificationConfig.ORG_ID, + } + + const badgeEndpointUrl: URL = new URL(`${EnvironmentConfig.API.V5}/gamification/badges?${new URLSearchParams(params)}`) + + return badgeEndpointUrl.toString() + } + + return useGetInfinitePage(getKey) +} diff --git a/src-ts/tools/gamification-admin/game-lib/useGamificationBreadcrumb.provider.tsx b/src-ts/tools/gamification-admin/game-lib/useGamificationBreadcrumb.provider.tsx new file mode 100644 index 000000000..274022b16 --- /dev/null +++ b/src-ts/tools/gamification-admin/game-lib/useGamificationBreadcrumb.provider.tsx @@ -0,0 +1,16 @@ +import { BreadcrumbItemModel } from '../../../lib' +import { basePath } from '../gamification-admin.routes' +import { toolTitle } from '../GamificationAdmin' + +export function useGamificationBreadcrumb(items: Array): Array { + + const breadcrumb: Array = [ + { + name: toolTitle, + url: basePath, + }, + ...items, + ] + + return breadcrumb +} diff --git a/src-ts/tools/gamification-admin/gamification-admin.routes.tsx b/src-ts/tools/gamification-admin/gamification-admin.routes.tsx index 24ee0b8c1..108d2cf53 100644 --- a/src-ts/tools/gamification-admin/gamification-admin.routes.tsx +++ b/src-ts/tools/gamification-admin/gamification-admin.routes.tsx @@ -5,8 +5,16 @@ import BadgeDetailPage from './pages/badge-detail/BadgeDetailPage' import BadgeListingPage from './pages/badge-listing/BadgeListingPage' import CreateBadgePage from './pages/create-badge/CreateBadgePage' -export const baseUrl: string = '/gamification-admin' -export const rolesRequired: Array = [UserRole.gamificationAdmin] +const baseDetailPath: string = '/badge-detail' +const createBadgePath: string = '/create-badge' + +export const basePath: string = '/gamification-admin' + +export function badgeDetailPath(badgeId: string, view?: 'edit' | 'award'): string { + return `${basePath}${baseDetailPath}/${badgeId}${!!view ? `#${view}` : ''}` +} + +export const createBadgeRoute: string = `${basePath}${createBadgePath}` export const gamificationAdminRoutes: Array = [ { @@ -18,17 +26,19 @@ export const gamificationAdminRoutes: Array = [ }, { element: , - route: '/create-badge', + route: createBadgePath, }, { element: , - route: '/badge-detail/:id', + route: `${baseDetailPath}/:id`, }, ], element: , hidden: true, - rolesRequired, - route: baseUrl, + rolesRequired: [ + UserRole.gamificationAdmin, + ], + route: basePath, title: toolTitle, }, ] diff --git a/src-ts/tools/gamification-admin/lib/hooks/getDataSource.ts b/src-ts/tools/gamification-admin/lib/hooks/getDataSource.ts deleted file mode 100644 index d81ffdcab..000000000 --- a/src-ts/tools/gamification-admin/lib/hooks/getDataSource.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { EnvironmentConfig } from '../../../../config' - -export default function getDataSource(): string { - return `${EnvironmentConfig.API.V5}/gamification` -} diff --git a/src-ts/tools/gamification-admin/pages/badge-detail/BadgeDetailPage.tsx b/src-ts/tools/gamification-admin/pages/badge-detail/BadgeDetailPage.tsx index 1e84dc1ed..5283989c4 100644 --- a/src-ts/tools/gamification-admin/pages/badge-detail/BadgeDetailPage.tsx +++ b/src-ts/tools/gamification-admin/pages/badge-detail/BadgeDetailPage.tsx @@ -1,32 +1,34 @@ -import { FC, useMemo } from 'react' +import { FC } from 'react' import { Breadcrumb, BreadcrumbItemModel, ContentLayout } from '../../../../lib' -import { baseUrl } from '../../gamification-admin.routes' -import { toolTitle } from '../../GamificationAdmin' +import { useGamificationBreadcrumb } from '../../game-lib' import styles from './BadgeDetailPage.module.scss' const BadgeDetailPage: FC = () => { - // TDOD: use whit GAME-78 - // const { id: badgeID } : { badgeID: string } = useParams() - const breadcrumb: Array = useMemo(() => [ - { name: toolTitle, url: baseUrl }, - { name: 'badge detail', url: '#' }, - ], []) + // TDOD: use whit GAME-78 + // const { id: badgeID } : { badgeID: string } = useParams() - return ( - - -
+ const breadcrumb: Array = useGamificationBreadcrumb([ + { + name: 'badge detail', + url: '#', + }, + ]) -
-
- ) + return ( + + +
+ +
+
+ ) } export default BadgeDetailPage diff --git a/src-ts/tools/gamification-admin/pages/badge-listing/BadgeListingPage.tsx b/src-ts/tools/gamification-admin/pages/badge-listing/BadgeListingPage.tsx index 08dc7c2be..1e192bd60 100644 --- a/src-ts/tools/gamification-admin/pages/badge-listing/BadgeListingPage.tsx +++ b/src-ts/tools/gamification-admin/pages/badge-listing/BadgeListingPage.tsx @@ -1,77 +1,64 @@ -import { flatten, map } from 'lodash' import { Dispatch, FC, SetStateAction, useState } from 'react' import { NavigateFunction, useNavigate } from 'react-router-dom' -// tslint:disable-next-line -import useSWRInfinite from 'swr/infinite' -import { ButtonProps, ContentLayout, LoadingSpinner, Sort, Table, TableColumn } from '../../../../lib' -import { GamificationConfig } from '../../config' -import { baseUrl } from '../../gamification-admin.routes' -import getDataSource from '../../lib/hooks/getDataSource' -import { Badge } from '../../lib/models/badge.model' +import { + ButtonProps, + ContentLayout, + InfinitePageHandler, + LoadingSpinner, + Sort, + Table, + TableColumn, + tableGetDefaultSort +} from '../../../../lib' +import { GameBadge, useGetGameBadgesPage } from '../../game-lib' +import { createBadgeRoute } from '../../gamification-admin.routes' -import { badgeListingColumns } from './badge-listing-table/badge-listing-table.config' +import { badgeListingColumns } from './badge-listing-table' import styles from './BadgeListingPage.module.scss' const BadgeListingPage: FC = () => { - const [order, setOrder]: any = useState({ by: 'badge_name', type: 'asc' }) - const navigate: NavigateFunction = useNavigate() - const dataSource: string = getDataSource() - // server-side pagination hook - const getKey: any = (pageIndex: any, previousPageData: any) => { - if (previousPageData && !previousPageData.rows.length) { return undefined } // reached the end - return `${dataSource}/badges?organization_id=${GamificationConfig.ORG_ID}&limit=12&offset=${pageIndex * 12}&order_by=${order.by}&order_type=${order.type}` - } - const { data: badges, size, setSize }: any = useSWRInfinite(getKey, { revalidateFirstPage: false }) + const [sort, setSort]: [Sort, Dispatch>] = useState(tableGetDefaultSort(badgeListingColumns)) + const [columns]: [ + ReadonlyArray>, + Dispatch>>>, + ] + = useState>>([...badgeListingColumns]) - const tableData: Array = flatten(map(badges, page => page.rows)) // flatten version of badges paginated data - const loadedCnt: any = badges?.reduce((ps: any, a: any) => ps + a.rows.length, 0) // how much data is loaded so far + const gameBadgeDataHandler: InfinitePageHandler = useGetGameBadgesPage(sort) + const navigate: NavigateFunction = useNavigate() - // listing table config - const [columns]: [ - ReadonlyArray>, - Dispatch>>>, - ] - = useState>>([...badgeListingColumns]) + function onSortClick(newSort: Sort): void { + setSort({ ...newSort }) + } - // on sort toggle callback - const onOrderClick: any = (sort: Sort) => { - setOrder({ - by: sort.fieldName, - type: sort.direction, - }) - } + // header button config + const buttonConfig: ButtonProps = { + label: 'Create New Badge', + onClick: () => navigate(createBadgeRoute), + } - // on load more callback - const onLoadMoreClick: any = () => setSize(size + 1) - // header button config - const buttonConfig: ButtonProps = { - label: 'Create New Badge', - onClick: () => navigate(`${baseUrl}/create-badge`), - } + if (!gameBadgeDataHandler.data) { + return + } - if (!badges) { return } - - return ( - -
- - - - ) + return ( + +
+
+ + + ) } export default BadgeListingPage diff --git a/src-ts/tools/gamification-admin/pages/badge-listing/badge-listing-table/badge-action-renderer/BadgeActionRenderer.tsx b/src-ts/tools/gamification-admin/pages/badge-listing/badge-listing-table/badge-action-renderer/BadgeActionRenderer.tsx index 33972e587..6ca456669 100644 --- a/src-ts/tools/gamification-admin/pages/badge-listing/badge-listing-table/badge-action-renderer/BadgeActionRenderer.tsx +++ b/src-ts/tools/gamification-admin/pages/badge-listing/badge-listing-table/badge-action-renderer/BadgeActionRenderer.tsx @@ -1,19 +1,49 @@ -import { Button, useCheckIsMobile } from '../../../../../../lib' -import { baseUrl } from '../../../../gamification-admin.routes' -import { Badge } from '../../../../lib/models/badge.model' +import { Button, ButtonProps, useCheckIsMobile } from '../../../../../../lib' +import { GameBadge } from '../../../../game-lib' +import { badgeDetailPath } from '../../../../gamification-admin.routes' import styles from './BadgeActionRenderer.module.scss' -function BadgeActionRenderer(badge: Badge): JSX.Element { - const isMobile: boolean = useCheckIsMobile() +function BadgeActionRenderer(badge: GameBadge): JSX.Element { - return ( -
-
- ) + const isMobile: boolean = useCheckIsMobile() + + const buttonProps: ButtonProps = { + buttonStyle: 'secondary', + size: isMobile ? 'xs' : 'sm', + } + + const actionButtons: Array<{ + label: string + view?: 'edit' | 'award' + }> = [ + { + label: 'View', + }, + { + label: 'Edit', + view: 'edit', + }, + { + label: 'Award', + view: 'award', + }, + ] + + return ( +
+ {actionButtons.map((button, index) => { + return ( +
+ ) } export default BadgeActionRenderer diff --git a/src-ts/tools/gamification-admin/pages/badge-listing/badge-listing-table/badge-listing-table.config.tsx b/src-ts/tools/gamification-admin/pages/badge-listing/badge-listing-table/badge-listing-table.config.tsx index ab9667ebf..1d6d54ef4 100644 --- a/src-ts/tools/gamification-admin/pages/badge-listing/badge-listing-table/badge-listing-table.config.tsx +++ b/src-ts/tools/gamification-admin/pages/badge-listing/badge-listing-table/badge-listing-table.config.tsx @@ -1,10 +1,10 @@ import { TableColumn } from '../../../../../lib' -import { Badge } from '../../../lib/models/badge.model' +import { GameBadge } from '../../../game-lib' import { BadgeActionRenderer } from './badge-action-renderer' import { BadgeListingNameRenderer } from './badge-name-renderer' -export const badgeListingColumns: ReadonlyArray> = [ +export const badgeListingColumns: ReadonlyArray> = [ { defaultSortDirection: 'asc', isDefaultSort: true, @@ -14,8 +14,6 @@ export const badgeListingColumns: ReadonlyArray> = [ type: 'element', }, { - centerHeader: true, - label: 'Actions', renderer: BadgeActionRenderer, type: 'action', }, diff --git a/src-ts/tools/gamification-admin/pages/badge-listing/badge-listing-table/badge-name-renderer/BadgeListingNameRenderer.tsx b/src-ts/tools/gamification-admin/pages/badge-listing/badge-listing-table/badge-name-renderer/BadgeListingNameRenderer.tsx index 333aed2e7..7b9c604ca 100644 --- a/src-ts/tools/gamification-admin/pages/badge-listing/badge-listing-table/badge-name-renderer/BadgeListingNameRenderer.tsx +++ b/src-ts/tools/gamification-admin/pages/badge-listing/badge-listing-table/badge-name-renderer/BadgeListingNameRenderer.tsx @@ -1,11 +1,15 @@ -import { Badge } from '../../../../lib/models/badge.model' +import { GameBadge } from '../../../../game-lib' import styles from './BadgeListingNameRenderer.module.scss' -function BadgeListingNameRenderer(badge: Badge): JSX.Element { +function BadgeListingNameRenderer(badge: GameBadge): JSX.Element { return (
- {badge.badge_name} + {badge.badge_name}

{badge.badge_name}

) diff --git a/src-ts/tools/gamification-admin/pages/badge-listing/badge-listing-table/index.ts b/src-ts/tools/gamification-admin/pages/badge-listing/badge-listing-table/index.ts new file mode 100644 index 000000000..8fa32ec69 --- /dev/null +++ b/src-ts/tools/gamification-admin/pages/badge-listing/badge-listing-table/index.ts @@ -0,0 +1 @@ +export * from './badge-listing-table.config' diff --git a/src-ts/tools/gamification-admin/pages/create-badge/CreateBadgePage.tsx b/src-ts/tools/gamification-admin/pages/create-badge/CreateBadgePage.tsx index 020b7f8eb..22d7e59d6 100644 --- a/src-ts/tools/gamification-admin/pages/create-badge/CreateBadgePage.tsx +++ b/src-ts/tools/gamification-admin/pages/create-badge/CreateBadgePage.tsx @@ -1,30 +1,32 @@ -import { FC, useMemo } from 'react' +import { FC } from 'react' import { Breadcrumb, BreadcrumbItemModel, ContentLayout } from '../../../../lib' -import { baseUrl } from '../../gamification-admin.routes' -import { toolTitle } from '../../GamificationAdmin' +import { useGamificationBreadcrumb } from '../../game-lib' import styles from './CreateBadgePage.module.scss' const CreateBadgePage: FC = () => { - const breadcrumb: Array = useMemo(() => [ - { name: toolTitle, url: baseUrl }, - { name: 'create badge', url: '#' }, - ], []) - return ( - - -
+ const breadcrumb: Array = useGamificationBreadcrumb([ + { + name: 'create badge', + url: '#', + }, + ]) -
-
- ) + return ( + + +
+ +
+
+ ) } export default CreateBadgePage From 95cefd191d7fd777a194ed0c27124e7d8a2b439e Mon Sep 17 00:00:00 2001 From: Brooke Date: Mon, 19 Sep 2022 15:55:06 -0700 Subject: [PATCH 2/3] GAME-107 clean-up --- src-ts/tools/gamification-admin/game-lib/index.ts | 2 +- ...dcrumb.provider.tsx => use-gamification-breadcrumb.hook.tsx} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src-ts/tools/gamification-admin/game-lib/{useGamificationBreadcrumb.provider.tsx => use-gamification-breadcrumb.hook.tsx} (100%) diff --git a/src-ts/tools/gamification-admin/game-lib/index.ts b/src-ts/tools/gamification-admin/game-lib/index.ts index f9755858a..6cb57fe53 100644 --- a/src-ts/tools/gamification-admin/game-lib/index.ts +++ b/src-ts/tools/gamification-admin/game-lib/index.ts @@ -1,3 +1,3 @@ export * from './game-badge.model' export * from './use-get-game-badges-page.hook' -export * from './game-badge.model' +export * from './use-gamification-breadcrumb.hook' diff --git a/src-ts/tools/gamification-admin/game-lib/useGamificationBreadcrumb.provider.tsx b/src-ts/tools/gamification-admin/game-lib/use-gamification-breadcrumb.hook.tsx similarity index 100% rename from src-ts/tools/gamification-admin/game-lib/useGamificationBreadcrumb.provider.tsx rename to src-ts/tools/gamification-admin/game-lib/use-gamification-breadcrumb.hook.tsx From 5ac9f54ee24956ee4db9aabb1da7de41e29ce90b Mon Sep 17 00:00:00 2001 From: Brooke Date: Mon, 19 Sep 2022 16:09:52 -0700 Subject: [PATCH 3/3] GAMe-107 clean up --- src-ts/lib/pagination/infinite-page-dao.model.ts | 1 + .../pages/badge-listing/BadgeListingPage.tsx | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src-ts/lib/pagination/infinite-page-dao.model.ts b/src-ts/lib/pagination/infinite-page-dao.model.ts index 2b2520095..ae1ca01da 100644 --- a/src-ts/lib/pagination/infinite-page-dao.model.ts +++ b/src-ts/lib/pagination/infinite-page-dao.model.ts @@ -1,4 +1,5 @@ export interface InfinitePageDao { count: number + // TODO: rename this 'items' so it can be used in a grid/card view rows: ReadonlyArray } diff --git a/src-ts/tools/gamification-admin/pages/badge-listing/BadgeListingPage.tsx b/src-ts/tools/gamification-admin/pages/badge-listing/BadgeListingPage.tsx index 1e192bd60..dfa788084 100644 --- a/src-ts/tools/gamification-admin/pages/badge-listing/BadgeListingPage.tsx +++ b/src-ts/tools/gamification-admin/pages/badge-listing/BadgeListingPage.tsx @@ -26,7 +26,7 @@ const BadgeListingPage: FC = () => { ] = useState>>([...badgeListingColumns]) - const gameBadgeDataHandler: InfinitePageHandler = useGetGameBadgesPage(sort) + const pageHandler: InfinitePageHandler = useGetGameBadgesPage(sort) const navigate: NavigateFunction = useNavigate() function onSortClick(newSort: Sort): void { @@ -39,7 +39,7 @@ const BadgeListingPage: FC = () => { onClick: () => navigate(createBadgeRoute), } - if (!gameBadgeDataHandler.data) { + if (!pageHandler.data) { return } @@ -51,9 +51,9 @@ const BadgeListingPage: FC = () => {