Skip to content

Commit

Permalink
feat: #2123 Browse App preview feature (#2167)
Browse files Browse the repository at this point in the history
  • Loading branch information
Cuong Vu authored Jul 24, 2020
1 parent e8cf6e6 commit f87214f
Show file tree
Hide file tree
Showing 13 changed files with 108 additions and 31 deletions.
4 changes: 3 additions & 1 deletion packages/marketplace/config.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@
"cognitoUserPoolId": "",
"chatbotAppId": "",
"marketplaceUrl": "",
"cypressBaseUrl": "http://localhost:8080"
"cypressBaseUrl": "http://localhost:8080",
"previewExternalAppIds": [],
"previewFeaturedExternalAppIds": []
}
9 changes: 6 additions & 3 deletions packages/marketplace/src/components/pages/apps/apps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import Routes from '@/constants/routes'
import InfiniteScroll from 'react-infinite-scroller'
import { clientFetchAppSummary } from '@/actions/client'
import styles from '@/styles/pages/apps.scss?mod'
import qs from 'query-string'

export const handleAfterClose = ({ setVisible }) => () => setVisible(false)
export const handleOnChange = history => (page: number) => {
Expand All @@ -36,8 +37,8 @@ export const handleOnCardClick = (history: History) => (app: AppSummaryModel) =>
history.push(`${Routes.APPS}/${app.id}`)
}

export const handleLoadMore = (dispatch: Dispatch) => (page: number) => {
dispatch(clientFetchAppSummary({ page }))
export const handleLoadMore = ({ dispatch, preview }: { dispatch: Dispatch; preview: boolean }) => (page: number) => {
dispatch(clientFetchAppSummary({ page, preview }))
}

export const Apps: React.FunctionComponent = () => {
Expand All @@ -51,6 +52,8 @@ export const Apps: React.FunctionComponent = () => {
const apps = appSummaryState?.data?.apps?.data || []
const featuredApps = appSummaryState?.data?.featuredApps || []
const { totalCount = 0, pageNumber = 1 } = appSummaryState?.data?.apps || {}
const { preview: previewString } = qs.parse(location.search)
const preview = !!previewString

const totalPage = totalCount / pageNumber
/**
Expand All @@ -73,7 +76,7 @@ export const Apps: React.FunctionComponent = () => {
<InfiniteScroll
useWindow={false}
pageStart={1}
loadMore={handleLoadMore(dispatch)}
loadMore={handleLoadMore({ dispatch, preview })}
hasMore={hasMore}
loader={<Loader key="infiniteScrollLoader" />}
initialLoad={false}
Expand Down
2 changes: 2 additions & 0 deletions packages/marketplace/src/core/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ window.reapit = {
apiDocDesktop: '',
developerPortalUrl: '',
adminPortalUrl: '',
previewExternalAppIds: [],
previewFeaturedExternalAppIds: [],
},
}

Expand Down
1 change: 1 addition & 0 deletions packages/marketplace/src/reducers/client/app-summary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface ClientAppSummaryParams {
search?: string
searchBy?: string
category?: string
preview?: boolean
}

export interface ClientAppSummaryState {
Expand Down
41 changes: 41 additions & 0 deletions packages/marketplace/src/sagas/__tests__/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,47 @@ describe('clientDataFetch', () => {
expect(clone.next().value).toEqual(put(categoriesReceiveData(response[2] as PagedResultCategoryModel_)))
expect(clone.next().done).toBe(true)
})

it('should work when ?preview=true ', () => {
;(global as any).window.reapit.config = {
previewExternalAppIds: ['id1'],
previewFeaturedExternalAppIds: ['id2'],
}
const gen = cloneableGenerator(clientDataFetch as any)({
data: {
...params.data,
preview: true,
},
})
const clone = gen.clone()
expect(clone.next().value).toEqual(select(selectClientId))
expect(clone.next(clientId).value).toEqual(select(selectCategories))
expect(clone.next(appCategorieStub.data).value).toEqual(select(selectFeaturedApps))
expect(clone.next(featuredAppsDataStub.data).value).toEqual(select(selectDeveloperEditionId))

const response = [appsDataStub.data, featuredAppsDataStub.data, appCategorieStub]
expect(clone.next(developerId).value).toEqual(
all([
call(fetchAppsList, {
pageNumber: params.data.page,
pageSize: BROWSE_APPS_PER_PAGE,
externalAppId: ['id1'],
}),
featuredAppsDataStub.data,
appCategorieStub.data,
]),
)
expect(clone.next(response).value).toEqual(
put(
clientFetchAppSummarySuccess({
apps: response[0] as PagedResultAppSummaryModel_,
featuredApps: response[1].data as AppSummaryModel[],
}),
),
)
expect(clone.next().value).toEqual(put(categoriesReceiveData(response[2] as PagedResultCategoryModel_)))
expect(clone.next().done).toBe(true)
})
})

describe('client fetch data error', () => {
Expand Down
66 changes: 45 additions & 21 deletions packages/marketplace/src/sagas/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ import { fetchAppsList } from '@/services/apps'
import { fetchCategoriesList } from '@/services/categories'

const DEFAULT_CATEGORY_LENGTH = 1
const DEFAULT_FEATURED_APP_PAGE_NUMBER = 1

export const clientDataFetch = function*({ data }) {
try {
const { page, search, category, searchBy } = data
const { page, search, category, searchBy, preview: isPreview } = data
const clientId = yield select(selectClientId)
if (!clientId) {
return
Expand All @@ -30,29 +31,52 @@ export const clientDataFetch = function*({ data }) {
// we will have to manually check it here
// TODO: have the endpoint return a category id for Direct API apps as well
const isFilteringForDirectApiApps = category === 'DIRECT_API_APPS_FILTER'
const shouldNotFetchFeaturedApps = !!search || !!category
const shouldNotFetchCategories = currentCategories.length > DEFAULT_CATEGORY_LENGTH

// PREVIEW APPS FEATURE when ?preview=true
const appsExternalAppIds = isPreview ? window.reapit.config.previewExternalAppIds : undefined
const featuredAppsExternalAppIds = isPreview ? window.reapit.config.previewFeaturedExternalAppIds : undefined

const appsFetchParams = isPreview
? {
pageNumber: page,
pageSize: BROWSE_APPS_PER_PAGE,
externalAppId: appsExternalAppIds,
}
: {
clientId,
developerId: developerId ? [developerId] : [],
category: isFilteringForDirectApiApps ? undefined : category,
[searchBy]: search,
pageNumber: page,
pageSize: BROWSE_APPS_PER_PAGE,
isFeatured: isFilteringForDirectApiApps ? undefined : false,
isDirectApi: isFilteringForDirectApiApps ? true : undefined,
}

const featuredAppsFetchParams = isPreview
? {
pageNumber: DEFAULT_FEATURED_APP_PAGE_NUMBER,
pageSize: FEATURED_APPS,
externalAppId: featuredAppsExternalAppIds,
}
: {
clientId,
developerId: developerId ? [developerId] : [],
pageNumber: DEFAULT_FEATURED_APP_PAGE_NUMBER,
pageSize: FEATURED_APPS,
isFeatured: true,
}

const [apps, featuredApps, categories] = yield all([
call(fetchAppsList, {
clientId,
developerId: developerId ? [developerId] : [],
category: isFilteringForDirectApiApps ? undefined : category,
[searchBy]: search,
pageNumber: page,
pageSize: BROWSE_APPS_PER_PAGE,
isFeatured: isFilteringForDirectApiApps ? undefined : false,
isDirectApi: isFilteringForDirectApiApps ? true : undefined,
}),
!!search || !!category
? currentFeaturedApps
: call(fetchAppsList, {
clientId,
developerId: developerId ? [developerId] : [],
pageNumber: 1,
pageSize: FEATURED_APPS,
isFeatured: true,
}),
currentCategories.length > DEFAULT_CATEGORY_LENGTH ? currentCategories : call(fetchCategoriesList, {}),
call(fetchAppsList, appsFetchParams),

shouldNotFetchFeaturedApps ? currentFeaturedApps : call(fetchAppsList, featuredAppsFetchParams),

shouldNotFetchCategories ? currentCategories : call(fetchCategoriesList, {}),
])

const clientItem: ClientAppSummary = { apps: apps, featuredApps: featuredApps?.data }
yield put(clientFetchAppSummarySuccess(clientItem))
yield put(categoriesReceiveData(categories))
Expand Down
2 changes: 1 addition & 1 deletion packages/marketplace/src/tests/badges/badge-branches.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion packages/marketplace/src/tests/badges/badge-functions.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion packages/marketplace/src/tests/badges/badge-lines.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion packages/marketplace/src/tests/badges/badge-statements.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions packages/marketplace/src/types/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export type Config = {
apiDocDesktop: string
developerPortalUrl: string
adminPortalUrl: string
previewExternalAppIds: string[]
previewFeaturedExternalAppIds: string[]
}

declare global {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jest.mock('../../sagas/client')
describe('routeDispatcher', () => {
it('should dispatch to clientFetchAppSummaryclientFetchAppSummary for the client route', async () => {
await routeDispatcher(Routes.APPS as RouteValue)
expect(store.dispatch).toHaveBeenCalledWith(clientFetchAppSummary({ page: 1 }))
expect(store.dispatch).toHaveBeenCalledWith(clientFetchAppSummary({ page: 1, preview: false }))
})

it('should dispatch to installedAppsRequestData for the installed-apps route', async () => {
Expand Down
4 changes: 3 additions & 1 deletion packages/marketplace/src/utils/route-dispatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ const routeDispatcher = async (route: RouteValue, params?: StringMap, search?: s
const id = params && params.appid ? params.appid : ''
const queryParams = new URLSearchParams(search)
const page = queryParams.get('page') ? Number(queryParams.get('page')) : 1
// preview apps feature
const preview = queryParams.get('preview') ? true : false

switch (route) {
case Routes.APPS:
store.dispatch(clientFetchAppSummary({ page: 1 }))
store.dispatch(clientFetchAppSummary({ page: 1, preview }))
break
case Routes.APP_DETAIL: {
if (id) {
Expand Down

0 comments on commit f87214f

Please sign in to comment.