From 1de6b649d4582b5e42f2e40d7ba9a8eed314eb79 Mon Sep 17 00:00:00 2001 From: andt Date: Fri, 29 May 2020 10:51:44 +0700 Subject: [PATCH 1/3] feat: #1127 As a developer, I should be able to see a preview of my app --- .../src/actions/__tests__/developer.ts | 5 ++ packages/marketplace/src/actions/developer.ts | 1 + .../client-app-detail/client-app-detail.tsx | 36 ++++++++++++-- .../developer-submit-app.test.tsx.snap | 15 ++++++ .../developer-submit-app.tsx | 33 +++++++++++++ .../marketplace/src/constants/action-types.ts | 1 + packages/marketplace/src/constants/routes.ts | 1 + .../__tests__/__snapshots__/router.tsx.snap | 13 +++++ packages/marketplace/src/core/router.tsx | 1 + .../src/sagas/apps/__test__/apps.test.ts | 48 ++++++++++++++++++- packages/marketplace/src/sagas/apps/apps.ts | 23 ++++++++- .../src/selector/client-app-detail.ts | 4 ++ .../src/tests/badges/badge-branches.svg | 2 +- .../src/tests/badges/badge-functions.svg | 2 +- .../src/tests/badges/badge-lines.svg | 2 +- .../src/tests/badges/badge-statements.svg | 2 +- 16 files changed, 180 insertions(+), 9 deletions(-) diff --git a/packages/marketplace/src/actions/__tests__/developer.ts b/packages/marketplace/src/actions/__tests__/developer.ts index bee0a44634..871cbc6c3c 100644 --- a/packages/marketplace/src/actions/__tests__/developer.ts +++ b/packages/marketplace/src/actions/__tests__/developer.ts @@ -13,6 +13,7 @@ import { fetchMonthlyBillingFailure, developerWebhookPing, developerSetWebhookPingStatus, + developerApplyAppDetails, } from '../developer' import ActionTypes from '../../constants/action-types' import { appsDataStub } from '../../sagas/__stubs__/apps' @@ -112,4 +113,8 @@ describe('developer actions', () => { expect(developerSetWebhookPingStatus.type).toEqual(ActionTypes.DEVELOPER_SET_PING_WEBHOOK_STATUS) expect(developerSetWebhookPingStatus('SUCCESS').data).toEqual('SUCCESS') }) + it('should create a developerApplyAppDetails action', () => { + expect(developerApplyAppDetails.type).toEqual(ActionTypes.DEVELOPER_APPLY_APP_DETAIL) + expect(developerApplyAppDetails({}).data).toEqual({}) + }) }) diff --git a/packages/marketplace/src/actions/developer.ts b/packages/marketplace/src/actions/developer.ts index 3cbeb0b0c8..22550767f4 100644 --- a/packages/marketplace/src/actions/developer.ts +++ b/packages/marketplace/src/actions/developer.ts @@ -45,3 +45,4 @@ export const developerWebhookPing = actionCreator(Action export const developerSetWebhookPingStatus = actionCreator( ActionTypes.DEVELOPER_SET_PING_WEBHOOK_STATUS, ) +export const developerApplyAppDetails = actionCreator(ActionTypes.DEVELOPER_APPLY_APP_DETAIL) diff --git a/packages/marketplace/src/components/pages/client-app-detail/client-app-detail.tsx b/packages/marketplace/src/components/pages/client-app-detail/client-app-detail.tsx index 60de73bfb5..1e569bec52 100644 --- a/packages/marketplace/src/components/pages/client-app-detail/client-app-detail.tsx +++ b/packages/marketplace/src/components/pages/client-app-detail/client-app-detail.tsx @@ -7,15 +7,19 @@ import ClientAppUninstallConfirmation from '@/components/ui/client-app-detail/cl import { DesktopIntegrationTypeModel } from '@/actions/app-integration-types' import { AppDetailDataNotNull } from '@/reducers/client/app-detail' import { selectIntegrationTypes } from '@/selector/integration-types' -import { useSelector } from 'react-redux' -import { selectAppDetailData, selectAppDetailLoading } from '@/selector/client-app-detail' +import { useSelector, useDispatch } from 'react-redux' +import { selectAppDetailData, selectAppDetailLoading, selectAppDetailError } from '@/selector/client-app-detail' import { selectLoginType, selectIsAdmin } from '@/selector/auth' import AppHeader from '@/components/ui/standalone-app-detail/app-header' import AppContent from './app-content' -import { Loader, Button } from '@reapit/elements' +import { Loader, Button, Alert } from '@reapit/elements' import clientAppDetailStyles from '@/styles/pages/client-app-detail.scss?mod' import ClientAppInstallConfirmation from '@/components/ui/client-app-detail/client-app-install-confirmation' import { Aside } from './aside' +import { clientFetchAppDetailFailed } from '@/actions/client' +import { developerApplyAppDetails } from '@/actions/developer' +import { useParams } from 'react-router' +import { Dispatch } from 'redux' export type ClientAppDetailProps = {} @@ -31,6 +35,24 @@ export const handleInstallAppButtonClick = (setIsVisibleInstallConfirmation: (is } } +export const handleApplyAppDetailsFromLocalStorage = (dispatch: Dispatch, appid?: string) => () => { + try { + const appDataString = localStorage.getItem('developer-preview-app') + if (!appDataString) { + throw 'No app preview' + } + + const appData = JSON.parse(appDataString) + if (appData.id !== appid) { + throw 'No app preview' + } + + dispatch(developerApplyAppDetails(appData)) + } catch (err) { + dispatch(clientFetchAppDetailFailed(err)) + } +} + export const renderAppHeaderButtonGroup = ( id: string, installedOn: string, @@ -70,6 +92,9 @@ export const renderAppHeaderButtonGroup = ( } const ClientAppDetail: React.FC = () => { + const dispatch = useDispatch() + const { id: appid } = useParams() + const [isVisibleInstallConfirmation, setIsVisibleInstallConfirmation] = React.useState(false) const [isVisibleUninstallConfirmation, setIsVisibleUninstallConfirmation] = React.useState(false) const closeUninstallConfirmationModal = React.useCallback( @@ -92,11 +117,16 @@ const ClientAppDetail: React.FC = () => { const isLoadingAppDetail = useSelector(selectAppDetailLoading) const loginType = useSelector(selectLoginType) const isAdmin = useSelector(selectIsAdmin) + const error = useSelector(selectAppDetailError) + const isInstallBtnHidden = loginType === 'CLIENT' && !isAdmin // selector selectAppDetailData return {} if not data const unfetched = Object.keys(appDetailData).length === 0 const { id = '', installedOn = '' } = appDetailData + React.useEffect(handleApplyAppDetailsFromLocalStorage(dispatch, appid), [dispatch]) + + if (error) return if (isLoadingAppDetail || unfetched) { return } diff --git a/packages/marketplace/src/components/pages/developer-submit-app/__test__/__snapshots__/developer-submit-app.test.tsx.snap b/packages/marketplace/src/components/pages/developer-submit-app/__test__/__snapshots__/developer-submit-app.test.tsx.snap index 882c3a1c04..6e34f8e478 100644 --- a/packages/marketplace/src/components/pages/developer-submit-app/__test__/__snapshots__/developer-submit-app.test.tsx.snap +++ b/packages/marketplace/src/components/pages/developer-submit-app/__test__/__snapshots__/developer-submit-app.test.tsx.snap @@ -1933,6 +1933,21 @@ exports[`DeveloperSubmitApp should match a snapshot 1`] = `
+ + + { } } +export type HandleOpenAppPreview = { + scopes: ScopeModel[] + values: FormikValues + appid?: string + appDetails?: AppDetailModel & { apiKey?: string } +} + +export const handleOpenAppPreview = ({ appDetails, values, scopes, appid }: HandleOpenAppPreview) => () => { + const appDetailState = { + ...appDetails, + ...values, + scopes: scopes.filter(scope => values.scopes.includes(scope.name)), + } + + const url = `developer/apps/${appid}/preview` + localStorage.setItem('developer-preview-app', JSON.stringify(appDetailState)) + window.open(url, '_blank') +} + export const DeveloperSubmitApp: React.FC = () => { let initialValues let formState @@ -377,6 +398,18 @@ export const DeveloperSubmitApp: React.FC = () => { + {!isSubmitApp && ( diff --git a/packages/marketplace/src/tests/badges/badge-branches.svg b/packages/marketplace/src/tests/badges/badge-branches.svg index 18c4a2f64b..7fb9823d7f 100644 --- a/packages/marketplace/src/tests/badges/badge-branches.svg +++ b/packages/marketplace/src/tests/badges/badge-branches.svg @@ -1 +1 @@ -Coverage:branchesCoverage:branches70.94%70.94% \ No newline at end of file +Coverage:branchesCoverage:branches70.93%70.93% \ No newline at end of file diff --git a/packages/marketplace/src/tests/badges/badge-functions.svg b/packages/marketplace/src/tests/badges/badge-functions.svg index 2c5848725e..73a070cff0 100644 --- a/packages/marketplace/src/tests/badges/badge-functions.svg +++ b/packages/marketplace/src/tests/badges/badge-functions.svg @@ -1 +1 @@ -Coverage:functionsCoverage:functions79.05%79.05% \ No newline at end of file +Coverage:functionsCoverage:functions78.99%78.99% \ No newline at end of file diff --git a/packages/marketplace/src/tests/badges/badge-lines.svg b/packages/marketplace/src/tests/badges/badge-lines.svg index d753f47d89..ba860674d4 100644 --- a/packages/marketplace/src/tests/badges/badge-lines.svg +++ b/packages/marketplace/src/tests/badges/badge-lines.svg @@ -1 +1 @@ -Coverage:linesCoverage:lines90.81%90.81% \ No newline at end of file +Coverage:linesCoverage:lines90.75%90.75% \ No newline at end of file diff --git a/packages/marketplace/src/tests/badges/badge-statements.svg b/packages/marketplace/src/tests/badges/badge-statements.svg index 02edc30f9d..d9aa04ef1c 100644 --- a/packages/marketplace/src/tests/badges/badge-statements.svg +++ b/packages/marketplace/src/tests/badges/badge-statements.svg @@ -1 +1 @@ -Coverage:statementsCoverage:statements89.82%89.82% \ No newline at end of file +Coverage:statementsCoverage:statements89.76%89.76% \ No newline at end of file