Skip to content

Commit

Permalink
feat: #1125: Update developer app detail behavior flows
Browse files Browse the repository at this point in the history
  • Loading branch information
nphivu414 committed May 11, 2020
1 parent f4917e4 commit 64c6709
Show file tree
Hide file tree
Showing 14 changed files with 136 additions and 54 deletions.
8 changes: 2 additions & 6 deletions packages/marketplace/src/actions/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@ import { actionCreator } from '../utils/actions'
import ActionTypes from '../constants/action-types'
import { ClientAppSummary, ClientAppSummaryParams } from '../reducers/client/app-summary'
import { AppDetailData } from '@/reducers/client/app-detail'

export interface ClientAppDetailParams {
id: string
clientId?: string
}
import { FetchAppDetailParams } from '@/services/apps'

export const clientAppSummaryRequestData = actionCreator<ClientAppSummaryParams>(
ActionTypes.CLIENT_APP_SUMMARY_REQUEST_DATA,
Expand All @@ -18,6 +14,6 @@ export const clientAppSummaryRequestDataFailure = actionCreator<string>(ActionTy
export const clientAppSummaryClearData = actionCreator<null>(ActionTypes.CLIENT_APP_SUMMARY_CLEAR_DATA)

// Client App Detail
export const clientFetchAppDetail = actionCreator<ClientAppDetailParams>(ActionTypes.CLIENT_FETCH_APP_DETAIL)
export const clientFetchAppDetail = actionCreator<FetchAppDetailParams>(ActionTypes.CLIENT_FETCH_APP_DETAIL)
export const clientFetchAppDetailSuccess = actionCreator<AppDetailData>(ActionTypes.CLIENT_FETCH_APP_DETAIL_SUCCESS)
export const clientFetchAppDetailFailed = actionCreator<string>(ActionTypes.CLIENT_FETCH_APP_DETAIL_FAILED)
10 changes: 9 additions & 1 deletion packages/marketplace/src/actions/developer.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
// TODO: WILL MOVE ALL DEVELOPER ACTIONS TO HERE
import { actionCreator } from '../utils/actions'
import ActionTypes from '../constants/action-types'
import { DeveloperItem, DeveloperRequestParams, Billing } from '../reducers/developer'
import { DeveloperItem, DeveloperRequestParams, Billing, AppDetailData } from '../reducers/developer'
import { CreateDeveloperModel, DeveloperModel } from '@reapit/foundations-ts-definitions'
import { FormState } from '@/types/core'
import { FetchBillingParams } from '@/sagas/api'
import { FetchAppDetailParams } from '@/services/apps'

// Developer App Detail
export const developerFetchAppDetail = actionCreator<FetchAppDetailParams>(ActionTypes.DEVELOPER_FETCH_APP_DETAIL)
export const developerFetchAppDetailSuccess = actionCreator<AppDetailData>(
ActionTypes.DEVELOPER_FETCH_APP_DETAIL_SUCCESS,
)
export const developerFetchAppDetailFailed = actionCreator<string>(ActionTypes.DEVELOPER_FETCH_APP_DETAIL_FAILED)

export const developerRequestData = actionCreator<DeveloperRequestParams>(ActionTypes.DEVELOPER_REQUEST_DATA)
export const developerRequestDataFailure = actionCreator<void>(ActionTypes.DEVELOPER_REQUEST_DATA_FAILURE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,6 @@ describe('Client', () => {
},
appDetail: {
data: appDetailDataStub.data,
appDetailAuthCode: '',
isAppDetailAuthCodeLoading: false,
isAppDetailLoading: false,
error: '',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ describe('DeveloperHome', () => {
isServiceChartLoading: false,
loading: false,
isVisible: false,
developerAppDetail: {
data: null,
isAppDetailLoading: false,
},
developerData: {
...appsDataStub,
scopes: appPermissionStub,
Expand Down Expand Up @@ -70,6 +74,10 @@ describe('DeveloperHome', () => {
},
loading: false,
isVisible: true,
developerAppDetail: {
data: null,
isAppDetailLoading: false,
},
developerData: {
...appsDataStub,
scopes: appPermissionStub,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,20 @@ import * as React from 'react'
import { useSelector } from 'react-redux'
import { selectAppDetailState, selectAppDetailData, selectAppDetailLoading } from '@/selector/developer-app-detail'
import { selectLoginType } from '@/selector/auth'
import { LoginType } from '@reapit/cognito-auth'
import { AppDetailModel } from '@reapit/foundations-ts-definitions'
import AppHeader from '@/components/ui/app-detail/app-header'
import AppContent from '@/components/ui/app-detail/app-content'
import DeveloperAppDetailButtonGroup from '@/components/ui/developer-app-detail/developer-app-detail-button-group'

import { Loader } from '@reapit/elements'
import { AppDetailState } from '@/reducers/app-detail'
import styles from '@/styles/pages/developer-app-detail.scss?mod'

export type DeveloperAppDetailProps = {}
export type MapState = {
appDetailState: AppDetailState
appDetailData: AppDetailModel & {
apiKey?: string | undefined
}
isLoadingAppDetail: boolean
loginType: LoginType
}

export const mapState = (useSelector): MapState => {
return {
appDetailState: useSelector(selectAppDetailState),
appDetailData: useSelector(selectAppDetailData),
isLoadingAppDetail: useSelector(selectAppDetailLoading),
loginType: useSelector(selectLoginType),
}
}

const DeveloperAppDetail: React.FC<DeveloperAppDetailProps> = () => {
const { appDetailState, appDetailData, isLoadingAppDetail, loginType } = mapState(useSelector)
const appDetailState = useSelector(selectAppDetailState)
const appDetailData = useSelector(selectAppDetailData)
const isLoadingAppDetail = useSelector(selectAppDetailLoading)
const loginType = useSelector(selectLoginType)

if (!appDetailData.id || isLoadingAppDetail) {
return <Loader />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import DeveloperAppRevisionModal from '@/components/ui/developer-app-revision-mo

import { Grid, GridItem, Button } from '@reapit/elements'
import routes from '@/constants/routes'
import { AppDetailState } from '@/reducers/app-detail'
import { DeveloperAppDetailState } from '@/reducers/developer'

export type DeveloperAppDetailButtonGroupProps = {
appDetailState: AppDetailState
appDetailState: DeveloperAppDetailState
}

export const handleEditDetailButtonClick = (history, dispatch: Dispatch<any>, id?: string) => {
Expand Down Expand Up @@ -45,10 +45,10 @@ export const handleInstallationButtonClick = (setIsInstallationsModalOpen: (isMo
}

const DeveloperAppDetailButtonGroup: React.FC<DeveloperAppDetailButtonGroupProps> = ({ appDetailState }) => {
const { appDetailData } = appDetailState
const appId = appDetailData?.data.id || ''
const appName = appDetailData?.data.name || ''
const pendingRevisions = appDetailData?.data.pendingRevisions
const { data } = appDetailState
const appId = data?.id || ''
const appName = data?.name || ''
const pendingRevisions = data?.pendingRevisions

const history = useHistory()
const dispatch = useDispatch()
Expand Down Expand Up @@ -119,12 +119,12 @@ const DeveloperAppDetailButtonGroup: React.FC<DeveloperAppDetailButtonGroupProps
}}
/>

<DeveloperAppRevisionModal
{/* <DeveloperAppRevisionModal
visible={isAppRevisionComparisionModalOpen}
appId={appId || ''}
appDetailState={appDetailState}
afterClose={() => setIsAppRevisionComparisionModalOpen(false)}
/>
/> */}
</>
)
}
Expand Down
5 changes: 5 additions & 0 deletions packages/marketplace/src/constants/action-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ const ActionTypes = {
DEVELOPER_SET_FORM_STATE: 'DEVELOPER_SET_FORM_STATE',
DEVELOPER_SHOW_MODAL: 'DEVELOPER_SHOW_MODAL',

// Client App Detail
DEVELOPER_FETCH_APP_DETAIL: 'DEVELOPER_FETCH_APP_DETAIL',
DEVELOPER_FETCH_APP_DETAIL_FAILED: 'DEVELOPER_FETCH_APP_DETAIL_FAILED',
DEVELOPER_FETCH_APP_DETAIL_SUCCESS: 'DEVELOPER_FETCH_APP_DETAIL_SUCCESS',

// App Detail actions
APP_DETAIL_REQUEST_DATA: 'APP_DETAIL_REQUEST_DATA',
APP_DETAIL_LOADING: 'APP_DETAIL_LOADING',
Expand Down
4 changes: 0 additions & 4 deletions packages/marketplace/src/reducers/client/app-detail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,14 @@ export type AppDetailData = (AppDetailModel & { apiKey?: string }) | null

export interface ClientAppDetailState {
data: AppDetailData
appDetailAuthCode: string | null
isAppDetailLoading: boolean
isAppDetailAuthCodeLoading: boolean
error?: string | null
}

export const defaultState: ClientAppDetailState = {
error: null,
data: null,
appDetailAuthCode: null,
isAppDetailLoading: false,
isAppDetailAuthCodeLoading: false,
}

const appDetailReducer = (state: ClientAppDetailState = defaultState, action: Action<any>): ClientAppDetailState => {
Expand Down
56 changes: 55 additions & 1 deletion packages/marketplace/src/reducers/developer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,16 @@ import {
fetchBilling,
fetchBillingSuccess,
fetchBillingFailure,
developerFetchAppDetail,
developerFetchAppDetailSuccess,
developerFetchAppDetailFailed,
} from '@/actions/developer'
import { PagedResultAppSummaryModel_, ScopeModel, DeveloperModel } from '@reapit/foundations-ts-definitions'
import {
PagedResultAppSummaryModel_,
ScopeModel,
DeveloperModel,
AppDetailModel,
} from '@reapit/foundations-ts-definitions'
import { developerAppShowModal } from '@/actions/developer-app-modal'

export interface DeveloperRequestParams {
Expand Down Expand Up @@ -43,6 +51,7 @@ export type Billing = {

export interface DeveloperState {
loading: boolean
developerAppDetail: DeveloperAppDetailState
developerData: DeveloperItem | null
formState: FormState
isVisible: boolean
Expand All @@ -52,8 +61,21 @@ export interface DeveloperState {
error: unknown
}

export type AppDetailData = (AppDetailModel & { apiKey?: string }) | null

export interface DeveloperAppDetailState {
data: AppDetailData
isAppDetailLoading: boolean
error?: string | null
}

export const defaultState: DeveloperState = {
loading: false,
developerAppDetail: {
error: null,
data: null,
isAppDetailLoading: false,
},
developerData: null,
formState: 'PENDING',
isVisible: false,
Expand All @@ -64,6 +86,38 @@ export const defaultState: DeveloperState = {
}

const developerReducer = (state: DeveloperState = defaultState, action: Action<any>): DeveloperState => {
if (isType(action, developerFetchAppDetail)) {
return {
...state,
developerAppDetail: {
...state.developerAppDetail,
isAppDetailLoading: true,
},
}
}

if (isType(action, developerFetchAppDetailSuccess)) {
return {
...state,
developerAppDetail: {
...state.developerAppDetail,
data: action.data,
isAppDetailLoading: false,
},
}
}

if (isType(action, developerFetchAppDetailFailed)) {
return {
...state,
developerAppDetail: {
...state.developerAppDetail,
isAppDetailLoading: false,
error: action.data,
},
}
}

if (isType(action, developerLoading)) {
return {
...state,
Expand Down
5 changes: 5 additions & 0 deletions packages/marketplace/src/sagas/__stubs__/developer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { DeveloperState } from '@/reducers/developer'
import { developerIdentity } from './developer-identity'
import { billing } from './billing'
import { appDetailDataStub } from './app-detail'

export const developerStub = {
id: '7a96e6b2-3778-4118-9c9b-6450851e5608',
Expand All @@ -17,6 +18,10 @@ export const developerStub = {
export const developerState: DeveloperState = {
loading: false,
error: null,
developerAppDetail: {
data: appDetailDataStub.data,
isAppDetailLoading: false,
},
developerData: {
data: {
data: [
Expand Down
36 changes: 30 additions & 6 deletions packages/marketplace/src/sagas/apps/apps.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { ClientAppDetailParams, clientFetchAppDetailSuccess, clientFetchAppDetailFailed } from '@/actions/client'
import { clientFetchAppDetailSuccess, clientFetchAppDetailFailed } from '@/actions/client'
import { put, call, fork, takeLatest, all } from '@redux-saga/core/effects'
import ActionTypes from '@/constants/action-types'
import { errorThrownServer } from '@/actions/error'
import errorMessages from '@/constants/error-messages'
import { Action } from '@/types/core'
import { logger } from 'logger'
import { fetchAppApiKey, fetchAppDetail } from '@/services/apps'
import { fetchAppApiKey, fetchAppDetail, FetchAppDetailParams } from '@/services/apps'
import { developerFetchAppDetailSuccess, developerFetchAppDetailFailed } from '@/actions/developer'

export const fetchAppDetailSaga = function*({ data }: Action<ClientAppDetailParams>) {
export const fetchClientAppDetailSaga = function*({ data }: Action<FetchAppDetailParams>) {
try {
const appDetailResponse = yield call(fetchAppDetail, { clientId: data.clientId, id: data.id })
console.log('appDetailResponse', appDetailResponse)
if (appDetailResponse?.isWebComponent && appDetailResponse?.installationId) {
const apiKeyResponse = yield call(fetchAppApiKey, { installationId: appDetailResponse.installationId })
appDetailResponse.apiKey = apiKeyResponse?.apiKey || ''
Expand All @@ -28,12 +28,36 @@ export const fetchAppDetailSaga = function*({ data }: Action<ClientAppDetailPara
}
}

export const fetchDeveloperAppDetailSaga = function*({ data }: Action<FetchAppDetailParams>) {
try {
const appDetailResponse = yield call(fetchAppDetail, { clientId: data.clientId, id: data.id })
if (appDetailResponse?.isWebComponent && appDetailResponse?.installationId) {
const apiKeyResponse = yield call(fetchAppApiKey, { installationId: appDetailResponse.installationId })
appDetailResponse.apiKey = apiKeyResponse?.apiKey || ''
}
yield put(developerFetchAppDetailSuccess(appDetailResponse))
} catch (err) {
logger(err)
yield put(developerFetchAppDetailFailed(err.message))
yield put(
errorThrownServer({
type: 'SERVER',
message: errorMessages.DEFAULT_SERVER_ERROR,
}),
)
}
}

export const clientAppDetailDataListen = function*() {
yield takeLatest<Action<ClientAppDetailParams>>(ActionTypes.CLIENT_FETCH_APP_DETAIL, fetchAppDetailSaga)
yield takeLatest<Action<FetchAppDetailParams>>(ActionTypes.CLIENT_FETCH_APP_DETAIL, fetchClientAppDetailSaga)
}

export const developerAppDetailDataListen = function*() {
yield takeLatest<Action<FetchAppDetailParams>>(ActionTypes.DEVELOPER_FETCH_APP_DETAIL, fetchDeveloperAppDetailSaga)
}

const appDetailSagas = function*() {
yield all([fork(clientAppDetailDataListen)])
yield all([fork(clientAppDetailDataListen), fork(developerAppDetailDataListen)])
}

export default appDetailSagas
6 changes: 3 additions & 3 deletions packages/marketplace/src/selector/developer-app-detail.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { ReduxState } from '@/types/core'

export const selectAppDetailState = (state: ReduxState) => {
return state.appDetail || {}
return state.developer.developerAppDetail || {}
}

export const selectAppDetailData = (state: ReduxState) => {
return state.appDetail.appDetailData?.data || {}
return state.developer.developerAppDetail.data || {}
}

export const selectAppDetailAuthentication = (state: ReduxState) => {
return state.appDetail.authentication
}

export const selectAppDetailLoading = (state: ReduxState) => {
return state.appDetail.loading
return state.developer.developerAppDetail.isAppDetailLoading
}
5 changes: 5 additions & 0 deletions packages/marketplace/src/services/apps.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { fetcher } from '@reapit/elements'
import { URLS, generateHeader } from '../constants/api'

export interface FetchAppDetailParams {
id: string
clientId?: string
}

export const fetchAppDetail = async ({ clientId, id }) => {
const response = await fetcher({
url: clientId ? `${URLS.apps}/${id}?clientId=${clientId}` : `${URLS.apps}/${id}`,
Expand Down
Loading

0 comments on commit 64c6709

Please sign in to comment.