From 478e49cf1c4d7a1fbc15000f827e6a46caf3b19e Mon Sep 17 00:00:00 2001 From: An Duong Date: Fri, 22 May 2020 00:07:29 +0700 Subject: [PATCH 1/7] feat: #1033 configure my web component installations in the Marketplace --- .../__tests__/__snapshots__/index.tsx.snap | 2 +- .../src/components/Checkbox/index.tsx | 5 +- .../RadioSelect/__tests__/index.tsx | 2 +- .../src/components/RadioSelect/index.tsx | 11 +- .../src/styles/components/checkbox.scss | 15 +- .../src/styles/components/layout.scss | 5 +- .../src/tests/badges/badge-branches.svg | 2 +- .../src/tests/badges/badge-functions.svg | 2 +- .../elements/src/tests/badges/badge-lines.svg | 2 +- .../src/tests/badges/badge-statements.svg | 2 +- .../src/actions/__tests__/client.ts | 21 + packages/marketplace/src/actions/client.ts | 17 + .../client-app-detail-manage.test.tsx.snap | 30 + .../client-app-detail.test.tsx.snap | 30 + .../developer-app-detail.test.tsx.snap | 30 + .../__snapshots__/app-header.test.tsx.snap | 155 ++- .../app-header/__test__/app-header.test.tsx | 26 +- .../ui/app-detail/app-header/app-header.tsx | 39 +- .../config-modal-inner.test.tsx.snap | 1024 +++++++++++++++++ .../__snapshots__/config-modal.test.tsx.snap | 19 + .../__test__/config-modal-inner.test.tsx | 98 ++ .../__test__/config-modal.test.tsx | 15 + .../config-modal-inner.tsx | 127 ++ .../config-modal.tsx | 32 + .../ui/web-component-config-modal/index.tsx | 1 + .../marketplace/src/constants/action-types.ts | 7 + packages/marketplace/src/core/store.ts | 2 + .../src/reducers/__stubs__/app-state.ts | 6 + .../client/__test__/web-component.test.ts | 73 ++ .../marketplace/src/reducers/client/index.ts | 3 + .../src/reducers/client/web-component.ts | 64 ++ .../src/sagas/__tests__/web-component.ts | 127 ++ .../marketplace/src/sagas/web-component.ts | 61 + .../src/selector/__tests__/auth.ts | 10 +- .../src/selector/__tests__/client.ts | 58 +- packages/marketplace/src/selector/auth.ts | 4 + packages/marketplace/src/selector/client.ts | 16 + .../marketplace/src/services/web-component.ts | 62 + .../src/styles/elements/radioselect.scss | 3 + .../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 +- 43 files changed, 2171 insertions(+), 45 deletions(-) create mode 100644 packages/marketplace/src/components/ui/web-component-config-modal/__test__/__snapshots__/config-modal-inner.test.tsx.snap create mode 100644 packages/marketplace/src/components/ui/web-component-config-modal/__test__/__snapshots__/config-modal.test.tsx.snap create mode 100644 packages/marketplace/src/components/ui/web-component-config-modal/__test__/config-modal-inner.test.tsx create mode 100644 packages/marketplace/src/components/ui/web-component-config-modal/__test__/config-modal.test.tsx create mode 100644 packages/marketplace/src/components/ui/web-component-config-modal/config-modal-inner.tsx create mode 100644 packages/marketplace/src/components/ui/web-component-config-modal/config-modal.tsx create mode 100644 packages/marketplace/src/components/ui/web-component-config-modal/index.tsx create mode 100644 packages/marketplace/src/reducers/client/__test__/web-component.test.ts create mode 100644 packages/marketplace/src/reducers/client/web-component.ts create mode 100644 packages/marketplace/src/sagas/__tests__/web-component.ts create mode 100644 packages/marketplace/src/sagas/web-component.ts create mode 100644 packages/marketplace/src/services/web-component.ts create mode 100644 packages/marketplace/src/styles/elements/radioselect.scss diff --git a/packages/elements/src/components/Checkbox/__tests__/__snapshots__/index.tsx.snap b/packages/elements/src/components/Checkbox/__tests__/__snapshots__/index.tsx.snap index 5e9add694f..16f532c396 100644 --- a/packages/elements/src/components/Checkbox/__tests__/__snapshots__/index.tsx.snap +++ b/packages/elements/src/components/Checkbox/__tests__/__snapshots__/index.tsx.snap @@ -2,7 +2,7 @@ exports[`Checkbox should match a snapshot 1`] = `
{ +export const Checkbox = ({ name, labelText, id, dataTest = '', value = '', className = '' }: CheckboxProps) => { return ( -
+
{({ field }: FieldProps) => { diff --git a/packages/elements/src/components/RadioSelect/__tests__/index.tsx b/packages/elements/src/components/RadioSelect/__tests__/index.tsx index 6585442166..b96d748a14 100644 --- a/packages/elements/src/components/RadioSelect/__tests__/index.tsx +++ b/packages/elements/src/components/RadioSelect/__tests__/index.tsx @@ -39,7 +39,7 @@ describe('RadioSelect', () => { )} , ) - expect(wrapper.find('label')).toHaveLength(3) + expect(wrapper.find('label')).toHaveLength(4) expect(wrapper.find('input')).toHaveLength(2) }) }) diff --git a/packages/elements/src/components/RadioSelect/index.tsx b/packages/elements/src/components/RadioSelect/index.tsx index 692a9b668c..1b0d1189bc 100644 --- a/packages/elements/src/components/RadioSelect/index.tsx +++ b/packages/elements/src/components/RadioSelect/index.tsx @@ -10,38 +10,43 @@ export type RadioSelectOption = { export type RadioSelectProps = { name: string labelText?: string + subText?: string id: string dataTest?: string options: RadioSelectOption[] setFieldValue: (field: string, value: any, shouldValidate?: boolean) => void state: any disabled?: boolean + className?: string } export const RadioSelect: React.FC = ({ name, labelText, + subText, id, dataTest, options, setFieldValue, state, disabled = false, + className, }) => { return ( {({ meta }: FieldProps) => { const hasError = checkError(meta) return ( -
+
+ {options.map(({ label, value }: RadioSelectOption, index: number) => (
= ({ disabled={disabled} onChange={() => setFieldValue(name, value)} /> - +
))}
diff --git a/packages/elements/src/styles/components/checkbox.scss b/packages/elements/src/styles/components/checkbox.scss index f082ca1759..42f4c37efb 100644 --- a/packages/elements/src/styles/components/checkbox.scss +++ b/packages/elements/src/styles/components/checkbox.scss @@ -1,7 +1,6 @@ @import '../base/colors.scss'; .field { - .checkbox { position: absolute; width: 0; @@ -79,7 +78,19 @@ margin-bottom: 4px; } - + .control { + .subtext { + font-style: italic; + display: block; + } + } + + &.checkbox-inline { + .radio-wrap { + display: inline-block; + margin-right: 1rem; + } + } } .field-checkbox { diff --git a/packages/elements/src/styles/components/layout.scss b/packages/elements/src/styles/components/layout.scss index 96144b684d..a713f8fd54 100644 --- a/packages/elements/src/styles/components/layout.scss +++ b/packages/elements/src/styles/components/layout.scss @@ -44,5 +44,8 @@ &.has-background { background-color: $white; } -} + &.flex-wrap { + flex-wrap: wrap; + } +} diff --git a/packages/elements/src/tests/badges/badge-branches.svg b/packages/elements/src/tests/badges/badge-branches.svg index b39bbc2dc8..981914f5a0 100644 --- a/packages/elements/src/tests/badges/badge-branches.svg +++ b/packages/elements/src/tests/badges/badge-branches.svg @@ -1 +1 @@ -Coverage:branchesCoverage:branches77.14%77.14% \ No newline at end of file +Coverage:branchesCoverage:branches76.68%76.68% \ No newline at end of file diff --git a/packages/elements/src/tests/badges/badge-functions.svg b/packages/elements/src/tests/badges/badge-functions.svg index dedfb0e83a..b946feb75d 100644 --- a/packages/elements/src/tests/badges/badge-functions.svg +++ b/packages/elements/src/tests/badges/badge-functions.svg @@ -1 +1 @@ -Coverage:functionsCoverage:functions95.32%95.32% \ No newline at end of file +Coverage:functionsCoverage:functions94.67%94.67% \ No newline at end of file diff --git a/packages/elements/src/tests/badges/badge-lines.svg b/packages/elements/src/tests/badges/badge-lines.svg index c17252992a..7fd5278264 100644 --- a/packages/elements/src/tests/badges/badge-lines.svg +++ b/packages/elements/src/tests/badges/badge-lines.svg @@ -1 +1 @@ -Coverage:linesCoverage:lines96.05%96.05% \ No newline at end of file +Coverage:linesCoverage:lines95.58%95.58% \ No newline at end of file diff --git a/packages/elements/src/tests/badges/badge-statements.svg b/packages/elements/src/tests/badges/badge-statements.svg index 467cca33b6..5f9a9c6d66 100644 --- a/packages/elements/src/tests/badges/badge-statements.svg +++ b/packages/elements/src/tests/badges/badge-statements.svg @@ -1 +1 @@ -Coverage:statementsCoverage:statements95.94%95.94% \ No newline at end of file +Coverage:statementsCoverage:statements95.49%95.49% \ No newline at end of file diff --git a/packages/marketplace/src/actions/__tests__/client.ts b/packages/marketplace/src/actions/__tests__/client.ts index 47493d9942..a8b040e668 100644 --- a/packages/marketplace/src/actions/__tests__/client.ts +++ b/packages/marketplace/src/actions/__tests__/client.ts @@ -3,6 +3,11 @@ import { clientFetchAppSummarySuccess, clientFetchAppSummaryFailed, clientClearAppSummary, + clientOpenWebComponentConfig, + clientCloseWebComponentConfig, + clientFetchWebComponentConfig, + clientFetchWebComponentConfigSuccess, + clientPutWebComponentConfig, } from '../client' import ActionTypes from '../../constants/action-types' import { appsDataStub, featuredAppsDataStub } from '../../sagas/__stubs__/apps' @@ -29,4 +34,20 @@ describe('client actions', () => { expect(clientClearAppSummary.type).toEqual(ActionTypes.CLIENT_CLEAR_APP_SUMMARY) expect(clientClearAppSummary(null).data).toEqual(null) }) + it('should create a clientOpenWebComponentConfig action', () => { + expect(clientOpenWebComponentConfig.type).toEqual(ActionTypes.CLIENT_WEB_COMPONENT_CONFIG_OPEN) + }) + it('should create a clientCloseWebComponentConfig action', () => { + expect(clientCloseWebComponentConfig.type).toEqual(ActionTypes.CLIENT_WEB_COMPONENT_CONFIG_CLOSE) + }) + it('should create a clientFetchWebComponentConfig action', () => { + expect(clientFetchWebComponentConfig.type).toEqual(ActionTypes.CLIENT_FETCH_WEB_COMPONENT_CONFIG) + expect(clientFetchWebComponentConfig({ customerId: 'DXX' }).data).toEqual({ customerId: 'DXX' }) + }) + it('should create a clientFetchWebComponentConfigSuccess action', () => { + expect(clientFetchWebComponentConfigSuccess.type).toEqual(ActionTypes.CLIENT_FETCH_WEB_COMPONENT_CONFIG_SUCCESS) + }) + it('should create a clientPutWebComponentConfig action', () => { + expect(clientPutWebComponentConfig.type).toEqual(ActionTypes.CLIENT_PUT_WEB_COMPONENT_CONFIG) + }) }) diff --git a/packages/marketplace/src/actions/client.ts b/packages/marketplace/src/actions/client.ts index 5928bd3add..ed9d7abff6 100644 --- a/packages/marketplace/src/actions/client.ts +++ b/packages/marketplace/src/actions/client.ts @@ -3,6 +3,11 @@ import ActionTypes from '@/constants/action-types' import { ClientAppSummary, ClientAppSummaryParams } from '@/reducers/client/app-summary' import { AppDetailData } from '@/reducers/client/app-detail' import { FetchAppByIdParams } from '@/services/apps' +import { + PutWebComponentConfigParams, + FetchWebComponentConfigParams, + WebComponentConfigResult, +} from '@/services/web-component' export const clientFetchAppSummary = actionCreator(ActionTypes.CLIENT_FETCH_APP_SUMMARY) export const clientFetchAppSummarySuccess = actionCreator( @@ -15,3 +20,15 @@ export const clientClearAppSummary = actionCreator(ActionTypes.CLIENT_CLEA export const clientFetchAppDetail = actionCreator(ActionTypes.CLIENT_FETCH_APP_DETAIL) export const clientFetchAppDetailSuccess = actionCreator(ActionTypes.CLIENT_FETCH_APP_DETAIL_SUCCESS) export const clientFetchAppDetailFailed = actionCreator(ActionTypes.CLIENT_FETCH_APP_DETAIL_FAILED) + +export const clientOpenWebComponentConfig = actionCreator(ActionTypes.CLIENT_WEB_COMPONENT_CONFIG_OPEN) +export const clientCloseWebComponentConfig = actionCreator(ActionTypes.CLIENT_WEB_COMPONENT_CONFIG_CLOSE) +export const clientFetchWebComponentConfig = actionCreator( + ActionTypes.CLIENT_FETCH_WEB_COMPONENT_CONFIG, +) +export const clientFetchWebComponentConfigSuccess = actionCreator( + ActionTypes.CLIENT_FETCH_WEB_COMPONENT_CONFIG_SUCCESS, +) +export const clientPutWebComponentConfig = actionCreator( + ActionTypes.CLIENT_PUT_WEB_COMPONENT_CONFIG, +) diff --git a/packages/marketplace/src/components/pages/client-app-detail-manage/__test__/__snapshots__/client-app-detail-manage.test.tsx.snap b/packages/marketplace/src/components/pages/client-app-detail-manage/__test__/__snapshots__/client-app-detail-manage.test.tsx.snap index 29a83e64a5..942a133cd1 100644 --- a/packages/marketplace/src/components/pages/client-app-detail-manage/__test__/__snapshots__/client-app-detail-manage.test.tsx.snap +++ b/packages/marketplace/src/components/pages/client-app-detail-manage/__test__/__snapshots__/client-app-detail-manage.test.tsx.snap @@ -96,6 +96,36 @@ exports[`ClientAppDetailManage should match a snapshot 1`] = ` src="https://bulma.io/images/placeholders/48x48.png" />
+ +
+ +
+ Settings +
+
+ + + +
+
+ +
+ +
+ Settings +
+
+ + + +
+
+ +
+ +
+ Settings +
+
+ + + +
+
- + -
- Peter's Properties +
+ +
+
+ Peter's Properties +
+ +
+ +
+ Settings +
+
+ + + +
+
+ + + +
+
+ +
+ +

+ Peter's Properties +

+
+
+
- - - Peter's Properties - - - - + + `; diff --git a/packages/marketplace/src/components/ui/app-detail/app-header/__test__/app-header.test.tsx b/packages/marketplace/src/components/ui/app-detail/app-header/__test__/app-header.test.tsx index 2ed1dd3ffc..95404a8253 100644 --- a/packages/marketplace/src/components/ui/app-detail/app-header/__test__/app-header.test.tsx +++ b/packages/marketplace/src/components/ui/app-detail/app-header/__test__/app-header.test.tsx @@ -1,8 +1,10 @@ import * as React from 'react' -import { shallow } from 'enzyme' import { appDetailDataStub } from '@/sagas/__stubs__/app-detail' import AppHeader, { AppHeaderProps } from '../app-header' - +import { mount } from 'enzyme' +import configureStore from 'redux-mock-store' +import { ReduxState } from '@/types/core' +import { Provider } from 'react-redux' const mockProps: AppHeaderProps = { appDetailData: { ...appDetailDataStub.data, @@ -12,6 +14,24 @@ const mockProps: AppHeaderProps = { describe('AppContent', () => { it('should match a snapshot', () => { - expect(shallow()).toMatchSnapshot() + const mockState = { + client: { + webComponent: { + loading: false, + updating: false, + data: null, + isShowModal: true, + }, + }, + } as ReduxState + const mockStore = configureStore() + const store = mockStore(mockState) + expect( + mount( + + + , + ), + ).toMatchSnapshot() }) }) diff --git a/packages/marketplace/src/components/ui/app-detail/app-header/app-header.tsx b/packages/marketplace/src/components/ui/app-detail/app-header/app-header.tsx index 1076d3129e..c41c744cb1 100644 --- a/packages/marketplace/src/components/ui/app-detail/app-header/app-header.tsx +++ b/packages/marketplace/src/components/ui/app-detail/app-header/app-header.tsx @@ -1,8 +1,20 @@ import * as React from 'react' -import { Grid, GridItem, H3 } from '@reapit/elements' +import { Grid, GridItem, H3, Button, H6 } from '@reapit/elements' import styles from '@/styles/pages/developer-app-detail.scss?mod' import { AppDetailModel } from '@reapit/foundations-ts-definitions' +import { useDispatch, useSelector } from 'react-redux' +import { selectIsWebComponentOpen } from '@/selector/client' +import WebComponentModal from '../../web-component-config-modal' +import { clientCloseWebComponentConfig, clientOpenWebComponentConfig } from '@/actions/client' +import { Dispatch } from 'redux' + +export const toggleWebComponentModal = (dispatch: Dispatch) => () => { + dispatch(clientOpenWebComponentConfig()) +} +export const closeWebComponentModal = (dispatch: Dispatch) => () => { + dispatch(clientCloseWebComponentConfig()) +} export type AppHeaderProps = { appDetailData: AppDetailModel & { @@ -12,9 +24,13 @@ export type AppHeaderProps = { } const AppHeader: React.FC = ({ appDetailData, buttonGroup }) => { - const { media, name } = appDetailData - const appIcon = media?.filter(({ type }) => type === 'icon')[0] + const dispatch = useDispatch() + const isWebComponentOpen = useSelector(selectIsWebComponentOpen) + const handleToggleWebComponentModal = toggleWebComponentModal(dispatch) + const handleCloseWebComponentModal = closeWebComponentModal(dispatch) + const { media, name, isWebComponent } = appDetailData + const appIcon = media?.filter(({ type }) => type === 'icon')[0] return ( <> @@ -26,6 +42,23 @@ const AppHeader: React.FC = ({ appDetailData, buttonGroup }) => alt={name} />
+ {!isWebComponent && ( + <> + +
Settings
+ +
+ {isWebComponentOpen && ( + + )} + + )}

{name}

diff --git a/packages/marketplace/src/components/ui/web-component-config-modal/__test__/__snapshots__/config-modal-inner.test.tsx.snap b/packages/marketplace/src/components/ui/web-component-config-modal/__test__/__snapshots__/config-modal-inner.test.tsx.snap new file mode 100644 index 0000000000..71ace5cb03 --- /dev/null +++ b/packages/marketplace/src/components/ui/web-component-config-modal/__test__/__snapshots__/config-modal-inner.test.tsx.snap @@ -0,0 +1,1024 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Config-modal-inner should WebComponentConfigModalBody match a snapshot 1`] = ` + +

+ abc +

+ + +
+
+ + +
+ + + + + + + +
+
+
+
+`; + +exports[`Config-modal-inner should WebComponentConfigModalFooter match a snapshot 1`] = ` + + + + + + + + + + +`; + +exports[`Config-modal-inner should WebComponentConfigModalInner match a snapshot 1`] = ` + + + +
+ + +
+

+ Book a Viewing Configuration +

+
+
+ + } + > +
+ +

+ Please use the following form to configure your diary settings for your ‘Book a Viewing’ widget on your website +

+ + +
+
+ + +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+ + +
+
+ + +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+
+
+ + +
+ +
+
+ +
+ + +
+
+
+
+
+ +
+
+ +
+ + +
+
+
+
+
+ +
+
+ +
+ + +
+
+
+
+
+ +
+
+ +
+ + +
+
+
+
+
+ +
+
+ +
+ + +
+
+
+
+
+ +
+
+ +
+ + +
+
+
+
+
+ +
+
+ +
+ + +
+
+
+
+
+
+
+
+
+
+
+ + } + > +
+ + + + + + + + +
+
+
+ +
+
+
+`; diff --git a/packages/marketplace/src/components/ui/web-component-config-modal/__test__/__snapshots__/config-modal.test.tsx.snap b/packages/marketplace/src/components/ui/web-component-config-modal/__test__/__snapshots__/config-modal.test.tsx.snap new file mode 100644 index 0000000000..b6ba57ae65 --- /dev/null +++ b/packages/marketplace/src/components/ui/web-component-config-modal/__test__/__snapshots__/config-modal.test.tsx.snap @@ -0,0 +1,19 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Config-modal should match snapshot 1`] = ` + + + +`; diff --git a/packages/marketplace/src/components/ui/web-component-config-modal/__test__/config-modal-inner.test.tsx b/packages/marketplace/src/components/ui/web-component-config-modal/__test__/config-modal-inner.test.tsx new file mode 100644 index 0000000000..817cbf6b00 --- /dev/null +++ b/packages/marketplace/src/components/ui/web-component-config-modal/__test__/config-modal-inner.test.tsx @@ -0,0 +1,98 @@ +import React from 'react' +import { + updateWebComponentConfig, + handleFetchWebComponentConfig, + WebComponentConfigModalBody, + WebComponentConfigModalFooter, + WebComponentConfigModalInner, +} from '../config-modal-inner' +import { shallow, mount } from 'enzyme' +import configureStore from 'redux-mock-store' +import { ReduxState } from '@/types/core' +import { Provider } from 'react-redux' +import { BOOK_VIEWING_CONSTANT } from '../config-modal' +import { PutWebComponentConfigParams } from '@/services/web-component' +import { clientPutWebComponentConfig, clientFetchWebComponentConfig } from '@/actions/client' + +const params = { + appointmentLength: 1, + appointmentTimeGap: 1, + customerId: 'string', + daysOfWeek: [1, 2], + negotiatorIds: ['1', '2'], +} as PutWebComponentConfigParams + +describe('Config-modal-inner', () => { + const mockState = { + client: { + webComponent: { + loading: false, + updating: false, + data: null, + isShowModal: true, + }, + }, + } as ReduxState + const mockStore = configureStore() + const store = mockStore(mockState) + + it('should WebComponentConfigModalBody match a snapshot', () => { + const mockProps = { + subtext: 'abc', + formikProps: { values: params }, + } + expect(shallow()).toMatchSnapshot() + }) + + it('should WebComponentConfigModalFooter match a snapshot', () => { + const mockProps = { + closeModal: jest.fn(), + } + expect( + mount( + + + , + ), + ).toMatchSnapshot() + }) + + it('should WebComponentConfigModalInner match a snapshot', () => { + const mockState = { + client: { + webComponent: { + loading: false, + updating: false, + data: null, + isShowModal: true, + }, + }, + } as ReduxState + const mockStore = configureStore() + const store = mockStore(mockState) + expect( + mount( + + + , + ), + ).toMatchSnapshot() + }) + + it('should updateWebComponentConfig run correctly', () => { + const dispatch = jest.fn() + + const fn = updateWebComponentConfig(dispatch) + fn(params) + expect(dispatch).toBeCalledWith(clientPutWebComponentConfig(params)) + }) + + it('should handleFetchWebComponentConfig run correctly', () => { + const dispatch = jest.fn() + const customerId = 'string' + + const fn = handleFetchWebComponentConfig(dispatch, customerId) + fn() + expect(dispatch).toBeCalledWith(clientFetchWebComponentConfig({ customerId })) + }) +}) diff --git a/packages/marketplace/src/components/ui/web-component-config-modal/__test__/config-modal.test.tsx b/packages/marketplace/src/components/ui/web-component-config-modal/__test__/config-modal.test.tsx new file mode 100644 index 0000000000..b696c59bd9 --- /dev/null +++ b/packages/marketplace/src/components/ui/web-component-config-modal/__test__/config-modal.test.tsx @@ -0,0 +1,15 @@ +import { WebComponentModal, WebComponentModalProps } from '../config-modal' +import React from 'react' +import { shallow } from 'enzyme' + +describe('Config-modal', () => { + it('should match snapshot', () => { + const mockProps = { + type: 'BOOK_VIEWING', + afterClose: jest.fn(), + closeModal: jest.fn(), + } as WebComponentModalProps + + expect(shallow()).toMatchSnapshot() + }) +}) diff --git a/packages/marketplace/src/components/ui/web-component-config-modal/config-modal-inner.tsx b/packages/marketplace/src/components/ui/web-component-config-modal/config-modal-inner.tsx new file mode 100644 index 0000000000..a103897c50 --- /dev/null +++ b/packages/marketplace/src/components/ui/web-component-config-modal/config-modal-inner.tsx @@ -0,0 +1,127 @@ +import React, { useEffect } from 'react' +import { + ModalHeader, + ModalBody, + ModalFooter, + Button, + Formik, + RadioSelect, + Checkbox, + Form, + Loader, + FormikValues, +} from '@reapit/elements' +import styles from '@/styles/elements/radioselect.scss?mod' +import { useDispatch, useSelector } from 'react-redux' +import { clientFetchWebComponentConfig, clientPutWebComponentConfig } from '@/actions/client' +import { selectIsWebComponentData, selectIsWebComponentLoading, selectIsWebComponentUpdating } from '@/selector/client' +import { PutWebComponentConfigParams } from '@/services/web-component' +import { selectClientId } from '@/selector/auth' +import { Dispatch } from 'redux' + +export const updateWebComponentConfig = (dispatch: Dispatch) => (params: FormikValues) => { + dispatch(clientPutWebComponentConfig(params as PutWebComponentConfigParams)) +} + +export const handleFetchWebComponentConfig = (dispatch: Dispatch, customerId?: string) => () => { + customerId && dispatch(clientFetchWebComponentConfig({ customerId })) +} + +export const WebComponentConfigModalBody = ({ subtext, formikProps }) => { + const { values, setFieldValue } = formikProps + return ( + <> +

{subtext}

+ + +
+
+ + +
+ + + + + + + +
+
+
+ + ) +} + +export const WebComponentConfigModalFooter = ({ closeModal }) => { + const updating = useSelector(selectIsWebComponentUpdating) + return ( + <> + + + + ) +} + +export const WebComponentConfigModalInner = ({ config, closeModal }) => { + const dispatch = useDispatch() + const handleUpdateWebComponentConfig = updateWebComponentConfig(dispatch) + const webComponentData = useSelector(selectIsWebComponentData) + const loading = useSelector(selectIsWebComponentLoading) + const clientId = useSelector(selectClientId) || '' + + const initialFormValues = + webComponentData || + ({ + appointmentLength: 30, + appointmentTimeGap: 30, + daysOfWeek: ['1', '2', '3', '4', '5', '6'], + } as FormikValues) + + useEffect(handleFetchWebComponentConfig(dispatch, clientId), []) + + if (loading) return + return ( + + {formikProps => ( +
+ + } /> + } /> + + )} +
+ ) +} diff --git a/packages/marketplace/src/components/ui/web-component-config-modal/config-modal.tsx b/packages/marketplace/src/components/ui/web-component-config-modal/config-modal.tsx new file mode 100644 index 0000000000..9b6784319b --- /dev/null +++ b/packages/marketplace/src/components/ui/web-component-config-modal/config-modal.tsx @@ -0,0 +1,32 @@ +import * as React from 'react' +import { Modal } from '@reapit/elements' +import { WebComponentConfigModalInner } from './config-modal-inner' + +export const BOOK_VIEWING_CONSTANT = { + title: 'Book a Viewing Configuration', + subtext: + 'Please use the following form to configure your diary settings for your ‘Book a Viewing’ widget on your website', +} + +export const BOOK_VALUATION_CONSTANT = { + title: 'Book a Valuation Configuration', + subtext: + 'Please use the following form to configure your diary settings for your ‘Book a Valuation’ widget on your website', +} + +export type WebComponentModalProps = { + type: 'BOOK_VIEWING' | 'BOOK_VALUATION' + afterClose: () => void + closeModal: () => void +} + +export const WebComponentModal = ({ type, afterClose, closeModal }: WebComponentModalProps) => { + const config = type === 'BOOK_VIEWING' ? BOOK_VIEWING_CONSTANT : BOOK_VALUATION_CONSTANT + + return ( + + + + ) +} +export default WebComponentModal diff --git a/packages/marketplace/src/components/ui/web-component-config-modal/index.tsx b/packages/marketplace/src/components/ui/web-component-config-modal/index.tsx new file mode 100644 index 0000000000..0e6aeee889 --- /dev/null +++ b/packages/marketplace/src/components/ui/web-component-config-modal/index.tsx @@ -0,0 +1 @@ +export { default } from './config-modal' diff --git a/packages/marketplace/src/constants/action-types.ts b/packages/marketplace/src/constants/action-types.ts index 83b5e73dc4..cbf942523a 100644 --- a/packages/marketplace/src/constants/action-types.ts +++ b/packages/marketplace/src/constants/action-types.ts @@ -71,6 +71,13 @@ const ActionTypes = { CLIENT_FETCH_APP_DETAIL_FAILED: 'CLIENT_FETCH_APP_DETAIL_FAILED', CLIENT_FETCH_APP_DETAIL_SUCCESS: 'CLIENT_FETCH_APP_DETAIL_SUCCESS', + // Client Web Component Config + CLIENT_WEB_COMPONENT_CONFIG_OPEN: 'CLIENT_WEB_COMPONENT_CONFIG_OPEN', + CLIENT_WEB_COMPONENT_CONFIG_CLOSE: 'CLIENT_WEB_COMPONENT_CONFIG_CLOSE', + CLIENT_FETCH_WEB_COMPONENT_CONFIG: 'CLIENT_FETCH_WEB_COMPONENT_CONFIG', + CLIENT_FETCH_WEB_COMPONENT_CONFIG_SUCCESS: 'CLIENT_FETCH_WEB_COMPONENT_CONFIG_SUCCESS', + CLIENT_PUT_WEB_COMPONENT_CONFIG: 'CLIENT_PUT_WEB_COMPONENT_CONFIG', + // Installed apps actions INSTALLED_APPS_REQUEST_DATA: 'INSTALLED_APPS_REQUEST_DATA', INSTALLED_APPS_LOADING: 'INSTALLED_APPS_LOADING', diff --git a/packages/marketplace/src/core/store.ts b/packages/marketplace/src/core/store.ts index 1cfb2437c7..985897ae3c 100644 --- a/packages/marketplace/src/core/store.ts +++ b/packages/marketplace/src/core/store.ts @@ -53,6 +53,7 @@ import adminStatsSaga from '@/sagas/admin-stats' import webhookSubscriptionsSagas from '@/sagas/webhook-subscriptions' import { injectSwitchModeToWindow } from '@reapit/elements' import webhookEditSagas from '../sagas/webhook-edit-modal' +import webComponentSagas from '../sagas/web-component' export class Store { static _instance: Store @@ -124,6 +125,7 @@ export class Store { fork(appHttpTrafficEventSagas), fork(webhookEditSagas), fork(webhookSubscriptionsSagas), + fork(webComponentSagas), ]) } diff --git a/packages/marketplace/src/reducers/__stubs__/app-state.ts b/packages/marketplace/src/reducers/__stubs__/app-state.ts index 805cecb4d4..cbfe4059fb 100644 --- a/packages/marketplace/src/reducers/__stubs__/app-state.ts +++ b/packages/marketplace/src/reducers/__stubs__/app-state.ts @@ -12,6 +12,12 @@ const appState: ReduxState = { data: null, isAppDetailLoading: false, }, + webComponent: { + isShowModal: false, + data: null, + updating: false, + loading: false, + }, }, installedApps: { loading: false, diff --git a/packages/marketplace/src/reducers/client/__test__/web-component.test.ts b/packages/marketplace/src/reducers/client/__test__/web-component.test.ts new file mode 100644 index 0000000000..a2ef7d484f --- /dev/null +++ b/packages/marketplace/src/reducers/client/__test__/web-component.test.ts @@ -0,0 +1,73 @@ +import webComponentReducer, { defaultState } from '../web-component' +import { ActionType } from '../../../types/core' +import ActionTypes from '../../../constants/action-types' + +describe('client app detail reducer', () => { + it('should return default state if action not matched', () => { + const newState = webComponentReducer(undefined, { type: 'UNKNOWN' as ActionType, data: undefined }) + expect(newState).toEqual(defaultState) + }) + + it('should set isModalOpen to true when CLIENT_WEB_COMPONENT_CONFIG_OPEN action is called', () => { + const newState = webComponentReducer(undefined, { + type: ActionTypes.CLIENT_WEB_COMPONENT_CONFIG_OPEN as ActionType, + data: true, + }) + const expected = { + ...defaultState, + isShowModal: true, + loading: true, + } + expect(newState).toEqual(expected) + }) + + it('should set isModalOpen to false when CLIENT_WEB_COMPONENT_CONFIG_CLOSE action is called', () => { + const newState = webComponentReducer(undefined, { + type: ActionTypes.CLIENT_WEB_COMPONENT_CONFIG_CLOSE as ActionType, + data: true, + }) + const expected = { + ...defaultState, + isShowModal: false, + } + expect(newState).toEqual(expected) + }) + + it('should set loading to true when CLIENT_FETCH_WEB_COMPONENT_CONFIG action is called', () => { + const newState = webComponentReducer(undefined, { + type: ActionTypes.CLIENT_FETCH_WEB_COMPONENT_CONFIG as ActionType, + data: true, + }) + const expected = { + ...defaultState, + loading: true, + } + expect(newState).toEqual(expected) + }) + + it('should set updating to true when CLIENT_PUT_WEB_COMPONENT_CONFIG action is called', () => { + const newState = webComponentReducer(undefined, { + type: ActionTypes.CLIENT_PUT_WEB_COMPONENT_CONFIG as ActionType, + data: true, + }) + const expected = { + ...defaultState, + updating: true, + } + expect(newState).toEqual(expected) + }) + + it('should set updating to true when CLIENT_FETCH_WEB_COMPONENT_CONFIG_SUCCESS action is called', () => { + const newState = webComponentReducer(undefined, { + type: ActionTypes.CLIENT_FETCH_WEB_COMPONENT_CONFIG_SUCCESS as ActionType, + data: {}, + }) + const expected = { + ...defaultState, + data: {}, + loading: false, + updating: false, + } + expect(newState).toEqual(expected) + }) +}) diff --git a/packages/marketplace/src/reducers/client/index.ts b/packages/marketplace/src/reducers/client/index.ts index e6181a20ce..97cecbafc9 100644 --- a/packages/marketplace/src/reducers/client/index.ts +++ b/packages/marketplace/src/reducers/client/index.ts @@ -1,13 +1,16 @@ import { combineReducers } from 'redux' import appDetailReducer, { ClientAppDetailState } from './app-detail' import clientReducer, { ClientAppSummaryState } from './app-summary' +import webComponentReducer, { WebComponentState } from './web-component' export interface ClientRootState { appSummary: ClientAppSummaryState appDetail: ClientAppDetailState + webComponent: WebComponentState } export default combineReducers({ appSummary: clientReducer, appDetail: appDetailReducer, + webComponent: webComponentReducer, }) diff --git a/packages/marketplace/src/reducers/client/web-component.ts b/packages/marketplace/src/reducers/client/web-component.ts new file mode 100644 index 0000000000..8d98939d06 --- /dev/null +++ b/packages/marketplace/src/reducers/client/web-component.ts @@ -0,0 +1,64 @@ +import { Action } from '@/types/core' +import { isType } from '@/utils/actions' +import { + clientOpenWebComponentConfig, + clientCloseWebComponentConfig, + clientFetchWebComponentConfig, + clientPutWebComponentConfig, + clientFetchWebComponentConfigSuccess, +} from '@/actions/client' +import { WebComponentConfigResult } from '@/services/web-component' + +export interface WebComponentState { + isShowModal: boolean + data: WebComponentConfigResult + loading: boolean + updating: boolean +} +export const defaultState: WebComponentState = { + isShowModal: false, + data: null, + loading: true, + updating: false, +} + +const webComponentReducer = (state: WebComponentState = defaultState, action: Action): WebComponentState => { + if (isType(action, clientOpenWebComponentConfig)) { + return { + ...state, + isShowModal: true, + loading: true, + } + } + if (isType(action, clientCloseWebComponentConfig)) { + return { + ...state, + isShowModal: false, + } + } + + if (isType(action, clientFetchWebComponentConfig)) { + return { + ...state, + loading: true, + } + } + if (isType(action, clientPutWebComponentConfig)) { + return { + ...state, + updating: true, + } + } + if (isType(action, clientFetchWebComponentConfigSuccess)) { + return { + ...state, + data: action.data, + loading: false, + updating: false, + } + } + + return state +} + +export default webComponentReducer diff --git a/packages/marketplace/src/sagas/__tests__/web-component.ts b/packages/marketplace/src/sagas/__tests__/web-component.ts new file mode 100644 index 0000000000..0cc4b2506e --- /dev/null +++ b/packages/marketplace/src/sagas/__tests__/web-component.ts @@ -0,0 +1,127 @@ +import webComponentSagas, { + putWebComponentConfigListen, + fetchWebComponentConfigListen, + putWebComponentConfigSaga, + fetchWebComponentConfigSaga, +} from '../web-component' +import { call, put, all, fork, takeLatest } from '@redux-saga/core/effects' +import { Action } from '@/types/core' +import { + PutWebComponentConfigParams, + FetchWebComponentConfigParams, + putWebComponentConfig, + fetchWebComponentConfig, + WebComponentConfigResult, +} from '@/services/web-component' +import ActionTypes from '@/constants/action-types' +import { cloneableGenerator } from '@redux-saga/testing-utils' +import { clientFetchWebComponentConfigSuccess, clientCloseWebComponentConfig } from '@/actions/client' +import { errorThrownServer } from '@/actions/error' +import errorMessages from '../../../../elements/src/utils/validators/error-messages' + +describe('webComponentSagas', () => { + it('should listen request data', () => { + const gen = webComponentSagas() + + expect(gen.next().value).toEqual(all([fork(fetchWebComponentConfigListen), fork(putWebComponentConfigListen)])) + + expect(gen.next().done).toBe(true) + }) +}) + +describe('putWebComponentConfigListen', () => { + it('should editWebhook when called', () => { + const gen = putWebComponentConfigListen() + expect(gen.next().value).toEqual( + takeLatest>( + ActionTypes.CLIENT_PUT_WEB_COMPONENT_CONFIG, + putWebComponentConfigSaga, + ), + ) + expect(gen.next().done).toBe(true) + }) +}) + +describe('fetchWebComponentConfigListen', () => { + it('should editWebhook when called', () => { + const gen = fetchWebComponentConfigListen() + expect(gen.next().value).toEqual( + takeLatest>( + ActionTypes.CLIENT_FETCH_WEB_COMPONENT_CONFIG, + fetchWebComponentConfigSaga, + ), + ) + expect(gen.next().done).toBe(true) + }) +}) + +describe('putWebComponentConfigSaga', () => { + const params = { + appointmentLength: 12, + appointmentTimeGap: 21, + customerId: 'string', + daysOfWeek: [1], + negotiatorIds: ['1'], + } as PutWebComponentConfigParams + + const gen = cloneableGenerator(putWebComponentConfigSaga as any)({ data: params }) + expect(gen.next().value).toEqual(call(putWebComponentConfig, params)) + + it('api call success', () => { + const clone = gen.clone() + expect(clone.next(params as any).value).toEqual(put(clientFetchWebComponentConfigSuccess(params))) + expect(clone.next().done).toBe(true) + }) + + test('api call fail', () => { + const clone = gen.clone() + // @ts-ignore + expect(clone.throw(new Error('Call API Failed')).value).toEqual( + put( + errorThrownServer({ + type: 'SERVER', + message: errorMessages.DEFAULT_SERVER_ERROR, + }), + ), + ) + expect(clone.next().done).toBe(true) + }) +}) + +describe('fetchWebComponentConfigSaga', () => { + const params = { + customerId: 'string', + } as FetchWebComponentConfigParams + + const respone = { + appointmentLength: 12, + appointmentTimeGap: 21, + customerId: 'string', + daysOfWeek: [1], + negotiatorIds: ['1'], + } as WebComponentConfigResult + + const gen = cloneableGenerator(fetchWebComponentConfigSaga as any)({ data: params }) + expect(gen.next().value).toEqual(call(fetchWebComponentConfig, params)) + + it('api call success', () => { + const clone = gen.clone() + expect(clone.next(respone as any).value).toEqual(put(clientFetchWebComponentConfigSuccess(respone))) + expect(clone.next().done).toBe(true) + }) + + test('api call fail', () => { + const clone = gen.clone() + // @ts-ignore + expect(clone.throw(new Error('Call API Failed')).value).toEqual(put(clientCloseWebComponentConfig())) + expect(clone.next().value).toEqual( + put( + errorThrownServer({ + type: 'SERVER', + message: errorMessages.DEFAULT_SERVER_ERROR, + }), + ), + ) + expect(clone.next().done).toBe(true) + }) +}) diff --git a/packages/marketplace/src/sagas/web-component.ts b/packages/marketplace/src/sagas/web-component.ts new file mode 100644 index 0000000000..e8ce8e33bb --- /dev/null +++ b/packages/marketplace/src/sagas/web-component.ts @@ -0,0 +1,61 @@ +import { put, fork, takeLatest, all, call } from '@redux-saga/core/effects' +import { Action } from '../types/core' +import ActionTypes from '../constants/action-types' +import { + fetchWebComponentConfig, + FetchWebComponentConfigParams, + PutWebComponentConfigParams, + putWebComponentConfig, +} from '@/services/web-component' +import errorMessages from '../../../elements/src/utils/validators/error-messages' +import { errorThrownServer } from '@/actions/error' +import { clientFetchWebComponentConfigSuccess, clientCloseWebComponentConfig } from '@/actions/client' + +export const fetchWebComponentConfigSaga = function*({ data }: Action) { + try { + const respone = yield call(fetchWebComponentConfig, data) + if (respone.message) throw Error(respone.message) + yield put(clientFetchWebComponentConfigSuccess(respone)) + } catch (err) { + yield put(clientCloseWebComponentConfig()) + yield put( + errorThrownServer({ + type: 'SERVER', + message: errorMessages.DEFAULT_SERVER_ERROR, + }), + ) + } +} + +export const putWebComponentConfigSaga = function*({ data }: Action) { + try { + const respone = yield call(putWebComponentConfig, data) + yield put(clientFetchWebComponentConfigSuccess(respone)) + } catch (err) { + yield put( + errorThrownServer({ + type: 'SERVER', + message: errorMessages.DEFAULT_SERVER_ERROR, + }), + ) + } +} + +export const fetchWebComponentConfigListen = function*() { + yield takeLatest>( + ActionTypes.CLIENT_FETCH_WEB_COMPONENT_CONFIG, + fetchWebComponentConfigSaga, + ) +} +export const putWebComponentConfigListen = function*() { + yield takeLatest>( + ActionTypes.CLIENT_PUT_WEB_COMPONENT_CONFIG, + putWebComponentConfigSaga, + ) +} + +const webComponentSagas = function*() { + yield all([fork(fetchWebComponentConfigListen), fork(putWebComponentConfigListen)]) +} + +export default webComponentSagas diff --git a/packages/marketplace/src/selector/__tests__/auth.ts b/packages/marketplace/src/selector/__tests__/auth.ts index f09d828386..48840777f7 100644 --- a/packages/marketplace/src/selector/__tests__/auth.ts +++ b/packages/marketplace/src/selector/__tests__/auth.ts @@ -1,5 +1,5 @@ import { ReduxState } from '@/types/core' -import { selectLoginType, selectIsAdmin, selectLoginIdentity, selectLoginSession } from '../auth' +import { selectLoginType, selectIsAdmin, selectLoginIdentity, selectLoginSession, selectClientId } from '../auth' const mockState = { auth: { @@ -7,6 +7,7 @@ const mockState = { loginSession: { loginIdentity: { isAdmin: true, + clientId: 'DCX', }, }, }, @@ -39,3 +40,10 @@ describe('selectLoginSession', () => { expect(result).toEqual(mockState.auth.loginSession) }) }) + +describe('selectClientId', () => { + it('should run correctly', () => { + const result = selectClientId(mockState) + expect(result).toEqual(mockState.auth.loginSession?.loginIdentity?.clientId) + }) +}) diff --git a/packages/marketplace/src/selector/__tests__/client.ts b/packages/marketplace/src/selector/__tests__/client.ts index 5d3a7c3353..87ed181316 100644 --- a/packages/marketplace/src/selector/__tests__/client.ts +++ b/packages/marketplace/src/selector/__tests__/client.ts @@ -1,5 +1,13 @@ import { ReduxState } from '@/types/core' -import { selectClientId, selectLoggedUserEmail, selectFeaturedApps } from '../client' +import { + selectClientId, + selectLoggedUserEmail, + selectFeaturedApps, + selectIsWebComponentOpen, + selectIsWebComponentData, + selectIsWebComponentLoading, + selectIsWebComponentUpdating, +} from '../client' import { featuredAppsDataStub } from '@/sagas/__stubs__/apps' describe('selectClientId', () => { @@ -74,4 +82,52 @@ describe('selectFeaturedApps', () => { const result = selectFeaturedApps(input) expect(result).toEqual([]) }) + + it('should selectIsWebComponentOpen run correctly and return true', () => { + const input = { + client: { + webComponent: { + isShowModal: true, + }, + }, + } as ReduxState + const result = selectIsWebComponentOpen(input) + expect(result).toEqual(true) + }) + + it('should selectIsWebComponentData run correctly and return {}', () => { + const input = { + client: { + webComponent: { + data: {}, + }, + }, + } as ReduxState + const result = selectIsWebComponentData(input) + expect(result).toEqual({}) + }) + + it('should selectIsWebComponentLoading run correctly and return true', () => { + const input = { + client: { + webComponent: { + loading: true, + }, + }, + } as ReduxState + const result = selectIsWebComponentLoading(input) + expect(result).toEqual(true) + }) + + it('should selectIsWebComponentUpdating run correctly and return true', () => { + const input = { + client: { + webComponent: { + updating: true, + }, + }, + } as ReduxState + const result = selectIsWebComponentUpdating(input) + expect(result).toEqual(true) + }) }) diff --git a/packages/marketplace/src/selector/auth.ts b/packages/marketplace/src/selector/auth.ts index 0dac32570b..115d3f0d44 100644 --- a/packages/marketplace/src/selector/auth.ts +++ b/packages/marketplace/src/selector/auth.ts @@ -15,3 +15,7 @@ export const selectLoginIdentity = (state: ReduxState) => { export const selectLoginSession = (state: ReduxState) => { return state.auth?.loginSession } + +export const selectClientId = (state: ReduxState) => { + return state.auth?.loginSession?.loginIdentity?.clientId +} diff --git a/packages/marketplace/src/selector/client.ts b/packages/marketplace/src/selector/client.ts index 90d70e11e7..2bfb2d5d7d 100644 --- a/packages/marketplace/src/selector/client.ts +++ b/packages/marketplace/src/selector/client.ts @@ -15,3 +15,19 @@ export const selectAppSummary = (state: ReduxState) => { export const selectFeaturedApps = (state: ReduxState) => { return state?.client.appSummary.data?.featuredApps || [] } + +export const selectIsWebComponentOpen = (state: ReduxState) => { + return state?.client.webComponent?.isShowModal +} + +export const selectIsWebComponentData = (state: ReduxState) => { + return state?.client.webComponent?.data +} + +export const selectIsWebComponentLoading = (state: ReduxState) => { + return state?.client.webComponent?.loading +} + +export const selectIsWebComponentUpdating = (state: ReduxState) => { + return state?.client.webComponent?.updating +} diff --git a/packages/marketplace/src/services/web-component.ts b/packages/marketplace/src/services/web-component.ts new file mode 100644 index 0000000000..95ef4d63ee --- /dev/null +++ b/packages/marketplace/src/services/web-component.ts @@ -0,0 +1,62 @@ +import { fetcher } from '@reapit/elements' +import { generateHeader } from './utils' +import { logger } from 'logger' + +export interface FetchWebComponentConfigParams { + customerId: string +} + +export interface PutWebComponentConfigParams { + appointmentLength: number + appointmentTimeGap: number + appointmentTypes: any + customerId: string + daysOfWeek: number[] + negotiatorIds: string[] +} + +export type WebComponentConfigResult = { + appointmentLength: number + appointmentTimeGap: number + appointmentTypes: any + customerId: string + daysOfWeek: number[] + negotiatorIds: string[] +} | null + +const API = '/dev/v1/web-components-config' + +export const fetchWebComponentConfig = async ( + params: FetchWebComponentConfigParams, +): Promise => { + try { + const { customerId } = params + const response = await fetcher({ + url: `${API}/${customerId}`, + api: 'http://localhost:3000', + method: 'GET', + headers: generateHeader(window.reapit.config.marketplaceApiKey), + }) + return response + } catch (error) { + logger(error) + throw new Error(error) + } +} + +export const putWebComponentConfig = async (params: PutWebComponentConfigParams) => { + try { + const { customerId = 'DXX', ...rest } = params + const response = await fetcher({ + url: `${API}/${customerId}`, + api: 'http://localhost:3000', + method: 'PATCH', + headers: generateHeader(window.reapit.config.marketplaceApiKey), + body: rest, + }) + return response + } catch (error) { + logger(error) + throw new Error(error) + } +} diff --git a/packages/marketplace/src/styles/elements/radioselect.scss b/packages/marketplace/src/styles/elements/radioselect.scss new file mode 100644 index 0000000000..82e02b3318 --- /dev/null +++ b/packages/marketplace/src/styles/elements/radioselect.scss @@ -0,0 +1,3 @@ +.radioselect { + margin-top: 0.5em; +} diff --git a/packages/marketplace/src/tests/badges/badge-branches.svg b/packages/marketplace/src/tests/badges/badge-branches.svg index 27f77ced28..7ce51f6372 100644 --- a/packages/marketplace/src/tests/badges/badge-branches.svg +++ b/packages/marketplace/src/tests/badges/badge-branches.svg @@ -1 +1 @@ -Coverage:branchesCoverage:branches69.19%69.19% \ No newline at end of file +Coverage:branchesCoverage:branches69.53%69.53% \ 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 163abe6863..2bbb3fc8a1 100644 --- a/packages/marketplace/src/tests/badges/badge-functions.svg +++ b/packages/marketplace/src/tests/badges/badge-functions.svg @@ -1 +1 @@ -Coverage:functionsCoverage:functions76.29%76.29% \ No newline at end of file +Coverage:functionsCoverage:functions76.58%76.58% \ 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 28f152bf6d..1730635bec 100644 --- a/packages/marketplace/src/tests/badges/badge-lines.svg +++ b/packages/marketplace/src/tests/badges/badge-lines.svg @@ -1 +1 @@ -Coverage:linesCoverage:lines89.74%89.74% \ No newline at end of file +Coverage:linesCoverage:lines89.91%89.91% \ 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 529e100f44..0ff47bb5c6 100644 --- a/packages/marketplace/src/tests/badges/badge-statements.svg +++ b/packages/marketplace/src/tests/badges/badge-statements.svg @@ -1 +1 @@ -Coverage:statementsCoverage:statements88.9%88.9% \ No newline at end of file +Coverage:statementsCoverage:statements89.05%89.05% \ No newline at end of file From 5acedaa0aa8802331aabd659244f9279643594d5 Mon Sep 17 00:00:00 2001 From: An Duong Date: Fri, 22 May 2020 08:27:51 +0700 Subject: [PATCH 2/7] chore: #1033 add negotiators dropdown --- .../src/components/DropdownSelect/index.tsx | 3 + .../config-modal-inner.test.tsx.snap | 470 ++++++++++++++++++ .../__test__/config-modal-inner.test.tsx | 2 +- .../config-modal-inner.tsx | 37 +- .../src/sagas/__tests__/web-component.ts | 4 +- .../marketplace/src/services/web-component.ts | 25 +- .../src/tests/badges/badge-functions.svg | 2 +- .../src/tests/badges/badge-statements.svg | 2 +- 8 files changed, 530 insertions(+), 15 deletions(-) diff --git a/packages/elements/src/components/DropdownSelect/index.tsx b/packages/elements/src/components/DropdownSelect/index.tsx index 45748fda8b..e4ea61acff 100644 --- a/packages/elements/src/components/DropdownSelect/index.tsx +++ b/packages/elements/src/components/DropdownSelect/index.tsx @@ -13,6 +13,7 @@ export interface DropdownSelectProps extends SelectProps { placeholder?: string options: SelectOption[] required?: boolean + subText?: string } export interface SelectOption { @@ -29,6 +30,7 @@ export const DropdownSelect: React.FC = ({ placeholder, options, required = false, + subText, ...restProps }) => { const handleRenderTags = (props: CustomTagProps) => { @@ -54,6 +56,7 @@ export const DropdownSelect: React.FC = ({ return (
+ + +
+ + } + prefixCls="rc-select" + > + + +
+ } + popupAlign={Object {}} + popupClassName="" + popupPlacement="bottomLeft" + popupStyle={ + Object { + "minWidth": null, + "width": null, + } + } + prefixCls="rc-select-dropdown" + showAction={Array []} + > + + + + + + +
, + } + } + id="negotiatorIds" + inputElement={null} + key="trigger" + mode="tags" + multiple={true} + onBlur={[Function]} + onChange={[Function]} + onSearch={[Function]} + onSelect={[Function]} + onToggleOpen={[Function]} + prefixCls="rc-select" + searchValue="" + showSearch={true} + tagRender={[Function]} + value={Array []} + values={Array []} + > +
+ + + + + + +
, + } + } + id="negotiatorIds" + inputElement={null} + inputRef={ + Object { + "current": , + } + } + mode="tags" + multiple={true} + onBlur={[Function]} + onChange={[Function]} + onInputChange={[Function]} + onInputKeyDown={[Function]} + onInputMouseDown={[Function]} + onSearch={[Function]} + onSelect={[Function]} + onToggleOpen={[Function]} + prefixCls="rc-select" + searchValue="" + showSearch={true} + tagRender={[Function]} + value={Array []} + values={Array []} + > + + + + + + +   + + + + +
+ + + + + + + + + + + diff --git a/packages/marketplace/src/components/ui/web-component-config-modal/__test__/config-modal-inner.test.tsx b/packages/marketplace/src/components/ui/web-component-config-modal/__test__/config-modal-inner.test.tsx index 817cbf6b00..d85d022746 100644 --- a/packages/marketplace/src/components/ui/web-component-config-modal/__test__/config-modal-inner.test.tsx +++ b/packages/marketplace/src/components/ui/web-component-config-modal/__test__/config-modal-inner.test.tsx @@ -18,7 +18,7 @@ const params = { appointmentLength: 1, appointmentTimeGap: 1, customerId: 'string', - daysOfWeek: [1, 2], + daysOfWeek: ['1', '2'], negotiatorIds: ['1', '2'], } as PutWebComponentConfigParams diff --git a/packages/marketplace/src/components/ui/web-component-config-modal/config-modal-inner.tsx b/packages/marketplace/src/components/ui/web-component-config-modal/config-modal-inner.tsx index a103897c50..f01a108fa8 100644 --- a/packages/marketplace/src/components/ui/web-component-config-modal/config-modal-inner.tsx +++ b/packages/marketplace/src/components/ui/web-component-config-modal/config-modal-inner.tsx @@ -10,6 +10,8 @@ import { Form, Loader, FormikValues, + DropdownSelect, + SelectOption, } from '@reapit/elements' import styles from '@/styles/elements/radioselect.scss?mod' import { useDispatch, useSelector } from 'react-redux' @@ -27,6 +29,22 @@ export const handleFetchWebComponentConfig = (dispatch: Dispatch, customerId?: s customerId && dispatch(clientFetchWebComponentConfig({ customerId })) } +export const genarateNegotiatorOptions = (): SelectOption[] => { + //MUST CHANGE WHEN API READY + return [ + { + label: 'Joe Smith', + value: '1', + description: 'Joe Smith', + }, + { + label: 'Jack', + value: '2', + description: 'Jack', + }, + ] as SelectOption[] +} + export const WebComponentConfigModalBody = ({ subtext, formikProps }) => { const { values, setFieldValue } = formikProps return ( @@ -77,6 +95,13 @@ export const WebComponentConfigModalBody = ({ subtext, formikProps }) => { + ) } @@ -102,13 +127,11 @@ export const WebComponentConfigModalInner = ({ config, closeModal }) => { const loading = useSelector(selectIsWebComponentLoading) const clientId = useSelector(selectClientId) || '' - const initialFormValues = - webComponentData || - ({ - appointmentLength: 30, - appointmentTimeGap: 30, - daysOfWeek: ['1', '2', '3', '4', '5', '6'], - } as FormikValues) + const initialFormValues = (webComponentData || { + appointmentLength: 30, + appointmentTimeGap: 30, + daysOfWeek: ['1', '2', '3', '4', '5', '6'], + }) as FormikValues useEffect(handleFetchWebComponentConfig(dispatch, clientId), []) diff --git a/packages/marketplace/src/sagas/__tests__/web-component.ts b/packages/marketplace/src/sagas/__tests__/web-component.ts index 0cc4b2506e..75b4c8b0a2 100644 --- a/packages/marketplace/src/sagas/__tests__/web-component.ts +++ b/packages/marketplace/src/sagas/__tests__/web-component.ts @@ -60,7 +60,7 @@ describe('putWebComponentConfigSaga', () => { appointmentLength: 12, appointmentTimeGap: 21, customerId: 'string', - daysOfWeek: [1], + daysOfWeek: ['1'], negotiatorIds: ['1'], } as PutWebComponentConfigParams @@ -97,7 +97,7 @@ describe('fetchWebComponentConfigSaga', () => { appointmentLength: 12, appointmentTimeGap: 21, customerId: 'string', - daysOfWeek: [1], + daysOfWeek: ['1'], negotiatorIds: ['1'], } as WebComponentConfigResult diff --git a/packages/marketplace/src/services/web-component.ts b/packages/marketplace/src/services/web-component.ts index 95ef4d63ee..539f3ad81b 100644 --- a/packages/marketplace/src/services/web-component.ts +++ b/packages/marketplace/src/services/web-component.ts @@ -11,7 +11,7 @@ export interface PutWebComponentConfigParams { appointmentTimeGap: number appointmentTypes: any customerId: string - daysOfWeek: number[] + daysOfWeek: string[] negotiatorIds: string[] } @@ -20,7 +20,7 @@ export type WebComponentConfigResult = { appointmentTimeGap: number appointmentTypes: any customerId: string - daysOfWeek: number[] + daysOfWeek: string[] negotiatorIds: string[] } | null @@ -29,6 +29,7 @@ const API = '/dev/v1/web-components-config' export const fetchWebComponentConfig = async ( params: FetchWebComponentConfigParams, ): Promise => { + return sampleRespone() //SHOULD REMOVE WHEN API READY try { const { customerId } = params const response = await fetcher({ @@ -44,7 +45,8 @@ export const fetchWebComponentConfig = async ( } } -export const putWebComponentConfig = async (params: PutWebComponentConfigParams) => { +export const putWebComponentConfig = async (params: PutWebComponentConfigParams): Promise => { + return sampleRespone() //SHOULD REMOVE WHEN API READY try { const { customerId = 'DXX', ...rest } = params const response = await fetcher({ @@ -60,3 +62,20 @@ export const putWebComponentConfig = async (params: PutWebComponentConfigParams) throw new Error(error) } } + +//SHOULD REMOVE WHEN API READY +function sampleRespone(): Promise { + return new Promise(res => { + setTimeout(() => { + const data = { + appointmentLength: 15, + appointmentTimeGap: 60, + appointmentTypes: [{ value: 'value1', id: 'id1' }], + customerId: 'DXX', + daysOfWeek: ['1', '2', '3', '5', '6'], + negotiatorIds: ['1', '2'], + } as WebComponentConfigResult + res(data) + }, 1000) + }) +} diff --git a/packages/marketplace/src/tests/badges/badge-functions.svg b/packages/marketplace/src/tests/badges/badge-functions.svg index 2bbb3fc8a1..8a1d81ec02 100644 --- a/packages/marketplace/src/tests/badges/badge-functions.svg +++ b/packages/marketplace/src/tests/badges/badge-functions.svg @@ -1 +1 @@ -Coverage:functionsCoverage:functions76.58%76.58% \ No newline at end of file +Coverage:functionsCoverage:functions76.6%76.6% \ 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 0ff47bb5c6..a6535cebfa 100644 --- a/packages/marketplace/src/tests/badges/badge-statements.svg +++ b/packages/marketplace/src/tests/badges/badge-statements.svg @@ -1 +1 @@ -Coverage:statementsCoverage:statements89.05%89.05% \ No newline at end of file +Coverage:statementsCoverage:statements89.06%89.06% \ No newline at end of file From aca8c06964b6291ce9298abb187415e67a32ec37 Mon Sep 17 00:00:00 2001 From: An Duong Date: Fri, 22 May 2020 11:53:29 +0700 Subject: [PATCH 3/7] chore: #1033 update app header, update snapshot --- .../client-app-detail-manage.test.tsx.snap | 30 --- .../client-app-detail.test.tsx.snap | 39 +--- .../developer-app-detail.test.tsx.snap | 176 +----------------- .../__snapshots__/app-header.test.tsx.snap | 41 ---- .../ui/app-detail/app-header/app-header.tsx | 2 +- .../__test__/config-modal-inner.test.tsx | 7 + .../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 +- 10 files changed, 24 insertions(+), 279 deletions(-) diff --git a/packages/marketplace/src/components/pages/client-app-detail-manage/__test__/__snapshots__/client-app-detail-manage.test.tsx.snap b/packages/marketplace/src/components/pages/client-app-detail-manage/__test__/__snapshots__/client-app-detail-manage.test.tsx.snap index 942a133cd1..29a83e64a5 100644 --- a/packages/marketplace/src/components/pages/client-app-detail-manage/__test__/__snapshots__/client-app-detail-manage.test.tsx.snap +++ b/packages/marketplace/src/components/pages/client-app-detail-manage/__test__/__snapshots__/client-app-detail-manage.test.tsx.snap @@ -96,36 +96,6 @@ exports[`ClientAppDetailManage should match a snapshot 1`] = ` src="https://bulma.io/images/placeholders/48x48.png" /> - -
- -
- Settings -
-
- - - -
-
-
- -
-
- -
- Settings -
-
- - - -
+ Developer +
+ TBC
diff --git a/packages/marketplace/src/components/pages/developer-app-detail/__test__/__snapshots__/developer-app-detail.test.tsx.snap b/packages/marketplace/src/components/pages/developer-app-detail/__test__/__snapshots__/developer-app-detail.test.tsx.snap index 4e797f5aa5..7c9497c6fa 100644 --- a/packages/marketplace/src/components/pages/developer-app-detail/__test__/__snapshots__/developer-app-detail.test.tsx.snap +++ b/packages/marketplace/src/components/pages/developer-app-detail/__test__/__snapshots__/developer-app-detail.test.tsx.snap @@ -78,176 +78,12 @@ exports[`DeveloperAppDetail should match a snapshot 1`] = ` className="loader-spinner body" data-test="" > - -
- -
-
- -
- -
- -
- Settings -
-
- - - -
-
-
-
- -
- -

- -

-
-
-
- - - -
- -
-
-

- Developer: -

-

-

-
-

- Client ID: -

-

-

-
-

- Status: -

-

- Not listed -

- - - - - - - -
-
-
- -
- - -
- - -
-
- -
- -
-
-
-
- -
+
+
+
+
+
+ diff --git a/packages/marketplace/src/components/ui/app-detail/app-header/__test__/__snapshots__/app-header.test.tsx.snap b/packages/marketplace/src/components/ui/app-detail/app-header/__test__/__snapshots__/app-header.test.tsx.snap index f48968f883..25ef8f91b9 100644 --- a/packages/marketplace/src/components/ui/app-detail/app-header/__test__/__snapshots__/app-header.test.tsx.snap +++ b/packages/marketplace/src/components/ui/app-detail/app-header/__test__/__snapshots__/app-header.test.tsx.snap @@ -79,47 +79,6 @@ exports[`AppContent should match a snapshot 1`] = ` src="https://reapit-app-store-app-media.s3.eu-west-2.amazonaws.com/7d88729f-2366-4561-9d5c-282615f3946b.jpeg" />
- -
- -
- Settings -
-
- - - -
-
- - -
= ({ appDetailData, buttonGroup }) => alt={name} />
- {!isWebComponent && ( + {isWebComponent && ( <>
Settings
diff --git a/packages/marketplace/src/components/ui/web-component-config-modal/__test__/config-modal-inner.test.tsx b/packages/marketplace/src/components/ui/web-component-config-modal/__test__/config-modal-inner.test.tsx index d85d022746..2a4e51d1b6 100644 --- a/packages/marketplace/src/components/ui/web-component-config-modal/__test__/config-modal-inner.test.tsx +++ b/packages/marketplace/src/components/ui/web-component-config-modal/__test__/config-modal-inner.test.tsx @@ -67,6 +67,13 @@ describe('Config-modal-inner', () => { isShowModal: true, }, }, + auth: { + loginSession: { + loginIdentity: { + clientId: 'DXX', + }, + }, + }, } as ReduxState const mockStore = configureStore() const store = mockStore(mockState) diff --git a/packages/marketplace/src/tests/badges/badge-branches.svg b/packages/marketplace/src/tests/badges/badge-branches.svg index 9669cc0c86..08eada36ea 100644 --- a/packages/marketplace/src/tests/badges/badge-branches.svg +++ b/packages/marketplace/src/tests/badges/badge-branches.svg @@ -1 +1 @@ -Coverage:branchesCoverage:branches69.25%69.25% +Coverage:branchesCoverage:branches69.06%69.06% \ 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 8a1d81ec02..b616173e24 100644 --- a/packages/marketplace/src/tests/badges/badge-functions.svg +++ b/packages/marketplace/src/tests/badges/badge-functions.svg @@ -1 +1 @@ -Coverage:functionsCoverage:functions76.6%76.6% \ No newline at end of file +Coverage:functionsCoverage:functions77.33%77.33% \ 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 394194ca12..ec1287724d 100644 --- a/packages/marketplace/src/tests/badges/badge-lines.svg +++ b/packages/marketplace/src/tests/badges/badge-lines.svg @@ -1 +1 @@ -Coverage:linesCoverage:lines89.73%89.73% \ No newline at end of file +Coverage:linesCoverage:lines90.02%90.02% \ 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 f7927a0411..25dd324ce3 100644 --- a/packages/marketplace/src/tests/badges/badge-statements.svg +++ b/packages/marketplace/src/tests/badges/badge-statements.svg @@ -1 +1 @@ -Coverage:statementsCoverage:statements88.89%88.89% +Coverage:statementsCoverage:statements89.19%89.19% \ No newline at end of file From 12d00e12eff24d37ae306c38d1a50d91c2e0eca1 Mon Sep 17 00:00:00 2001 From: An Duong Date: Fri, 22 May 2020 16:51:16 +0700 Subject: [PATCH 4/7] chore: #1033 fetch negotiators list --- .../src/actions/__tests__/client.ts | 4 + packages/marketplace/src/actions/client.ts | 5 + .../__snapshots__/aside.test.tsx.snap | 59 ++++ .../client-app-detail/__test__/aside.test.tsx | 30 +- .../pages/client-app-detail/aside.tsx | 41 ++- .../__snapshots__/app-header.test.tsx.snap | 114 ++----- .../app-header/__test__/app-header.test.tsx | 26 +- .../ui/app-detail/app-header/app-header.tsx | 39 +-- .../config-modal-inner.test.tsx.snap | 280 +++--------------- .../__test__/config-modal-inner.test.tsx | 40 ++- .../config-modal-inner.tsx | 37 ++- .../marketplace/src/constants/action-types.ts | 3 + .../src/reducers/__stubs__/app-state.ts | 1 + .../client/__test__/web-component.test.ts | 12 + .../src/reducers/client/web-component.ts | 11 + .../src/sagas/__tests__/web-component.ts | 37 ++- .../marketplace/src/sagas/web-component.ts | 18 +- .../src/selector/__tests__/client.ts | 14 + packages/marketplace/src/selector/client.ts | 4 + .../marketplace/src/services/constants.ts | 3 +- .../marketplace/src/services/negotiators.ts | 52 ++++ .../marketplace/src/services/web-component.ts | 2 +- .../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 +- 26 files changed, 401 insertions(+), 439 deletions(-) create mode 100644 packages/marketplace/src/services/negotiators.ts diff --git a/packages/marketplace/src/actions/__tests__/client.ts b/packages/marketplace/src/actions/__tests__/client.ts index a8b040e668..0db1ef2c8f 100644 --- a/packages/marketplace/src/actions/__tests__/client.ts +++ b/packages/marketplace/src/actions/__tests__/client.ts @@ -8,6 +8,7 @@ import { clientFetchWebComponentConfig, clientFetchWebComponentConfigSuccess, clientPutWebComponentConfig, + clientFetchNegotiatorsSuccess, } from '../client' import ActionTypes from '../../constants/action-types' import { appsDataStub, featuredAppsDataStub } from '../../sagas/__stubs__/apps' @@ -50,4 +51,7 @@ describe('client actions', () => { it('should create a clientPutWebComponentConfig action', () => { expect(clientPutWebComponentConfig.type).toEqual(ActionTypes.CLIENT_PUT_WEB_COMPONENT_CONFIG) }) + it('should create a clientPutWebComponentConfig action', () => { + expect(clientFetchNegotiatorsSuccess.type).toEqual(ActionTypes.CLIENT_FETCH_NEGOTIATORS_SUCCESS) + }) }) diff --git a/packages/marketplace/src/actions/client.ts b/packages/marketplace/src/actions/client.ts index ed9d7abff6..1fcfd6aeb7 100644 --- a/packages/marketplace/src/actions/client.ts +++ b/packages/marketplace/src/actions/client.ts @@ -8,6 +8,7 @@ import { FetchWebComponentConfigParams, WebComponentConfigResult, } from '@/services/web-component' +import { NegotiatorsResult } from '@/services/negotiators' export const clientFetchAppSummary = actionCreator(ActionTypes.CLIENT_FETCH_APP_SUMMARY) export const clientFetchAppSummarySuccess = actionCreator( @@ -32,3 +33,7 @@ export const clientFetchWebComponentConfigSuccess = actionCreator( ActionTypes.CLIENT_PUT_WEB_COMPONENT_CONFIG, ) + +export const clientFetchNegotiatorsSuccess = actionCreator( + ActionTypes.CLIENT_FETCH_NEGOTIATORS_SUCCESS, +) diff --git a/packages/marketplace/src/components/pages/client-app-detail/__test__/__snapshots__/aside.test.tsx.snap b/packages/marketplace/src/components/pages/client-app-detail/__test__/__snapshots__/aside.test.tsx.snap index dd8988e4e2..5440f46392 100644 --- a/packages/marketplace/src/components/pages/client-app-detail/__test__/__snapshots__/aside.test.tsx.snap +++ b/packages/marketplace/src/components/pages/client-app-detail/__test__/__snapshots__/aside.test.tsx.snap @@ -50,3 +50,62 @@ exports[`Aside Aside - should match snapshot 1`] = `
`; + +exports[`WebComponentConfig Should match snapshot 1`] = ` + + + +
+ +
+ Settings +
+
+ + + +
+
+ + + + +
+`; diff --git a/packages/marketplace/src/components/pages/client-app-detail/__test__/aside.test.tsx b/packages/marketplace/src/components/pages/client-app-detail/__test__/aside.test.tsx index fe23b31329..1df2a01de5 100644 --- a/packages/marketplace/src/components/pages/client-app-detail/__test__/aside.test.tsx +++ b/packages/marketplace/src/components/pages/client-app-detail/__test__/aside.test.tsx @@ -1,10 +1,14 @@ import React from 'react' import { Aside } from '../aside' -import { shallow } from 'enzyme' +import { shallow, mount } from 'enzyme' import { integrationTypesStub } from '@/sagas/__stubs__/integration-types' import { appDetailDataStub } from '@/sagas/__stubs__/app-detail' import { AppDetailDataNotNull } from '@/reducers/client/app-detail' import { DesktopIntegrationTypeModel } from '@/actions/app-integration-types' +import configureStore from 'redux-mock-store' +import { ReduxState } from '@/types/core' +import { Provider } from 'react-redux' +import { WebComponentConfig } from '../aside' describe('Aside', () => { test('Aside - should match snapshot', () => { @@ -18,3 +22,27 @@ describe('Aside', () => { ).toMatchSnapshot() }) }) + +describe('WebComponentConfig', () => { + const mockState = { + client: { + webComponent: { + loading: false, + updating: false, + data: null, + isShowModal: true, + }, + }, + } as ReduxState + const mockStore = configureStore() + const store = mockStore(mockState) + it('Should match snapshot', () => { + expect( + mount( + + + , + ), + ).toMatchSnapshot() + }) +}) diff --git a/packages/marketplace/src/components/pages/client-app-detail/aside.tsx b/packages/marketplace/src/components/pages/client-app-detail/aside.tsx index 16f9c75b8b..dd41a48e24 100644 --- a/packages/marketplace/src/components/pages/client-app-detail/aside.tsx +++ b/packages/marketplace/src/components/pages/client-app-detail/aside.tsx @@ -4,6 +4,12 @@ import standAloneAppDetailStyles from '@/styles/blocks/standalone-app-detail.scs import { renderCategory, renderDesktopIntegrationTypes } from '../client-app-detail/app-content' import { DesktopIntegrationTypeModel } from '@reapit/foundations-ts-definitions' import { AppDetailDataNotNull } from '@/reducers/client/app-detail' +import { GridItem, Button, H6 } from '@reapit/elements' +import { useDispatch, useSelector } from 'react-redux' +import { selectIsWebComponentOpen } from '@/selector/client' +import { clientCloseWebComponentConfig, clientOpenWebComponentConfig } from '@/actions/client' +import { Dispatch } from 'redux' +import WebComponentModal from '@/components/ui/web-component-config-modal' interface AsideProps { appDetailData: AppDetailDataNotNull @@ -11,7 +17,7 @@ interface AsideProps { } export const Aside: React.FC = ({ desktopIntegrationTypes, appDetailData }) => { - const { category } = appDetailData + const { category, isWebComponent } = appDetailData return (
@@ -22,6 +28,39 @@ export const Aside: React.FC = ({ desktopIntegrationTypes, appDetail
{renderDesktopIntegrationTypes(desktopIntegrationTypes)}
+ {isWebComponent && }
) } + +export const toggleWebComponentModal = (dispatch: Dispatch) => () => { + dispatch(clientOpenWebComponentConfig()) +} + +export const closeWebComponentModal = (dispatch: Dispatch) => () => { + dispatch(clientCloseWebComponentConfig()) +} + +export const WebComponentConfig = () => { + const dispatch = useDispatch() + const isWebComponentOpen = useSelector(selectIsWebComponentOpen) + const handleToggleWebComponentModal = toggleWebComponentModal(dispatch) + const handleCloseWebComponentModal = closeWebComponentModal(dispatch) + return ( + <> + +
Settings
+ +
+ {isWebComponentOpen && ( + + )} + + ) +} diff --git a/packages/marketplace/src/components/ui/app-detail/app-header/__test__/__snapshots__/app-header.test.tsx.snap b/packages/marketplace/src/components/ui/app-detail/app-header/__test__/__snapshots__/app-header.test.tsx.snap index 25ef8f91b9..8935525f50 100644 --- a/packages/marketplace/src/components/ui/app-detail/app-header/__test__/__snapshots__/app-header.test.tsx.snap +++ b/packages/marketplace/src/components/ui/app-detail/app-header/__test__/__snapshots__/app-header.test.tsx.snap @@ -1,104 +1,28 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`AppContent should match a snapshot 1`] = ` - - + -
- -
-
- Peter's Properties -
-
-
- -
- -

- Peter's Properties -

-
-
-
+
+ Peter's Properties
- - + + + Peter's Properties + + + + `; diff --git a/packages/marketplace/src/components/ui/app-detail/app-header/__test__/app-header.test.tsx b/packages/marketplace/src/components/ui/app-detail/app-header/__test__/app-header.test.tsx index 95404a8253..6d416f9ce9 100644 --- a/packages/marketplace/src/components/ui/app-detail/app-header/__test__/app-header.test.tsx +++ b/packages/marketplace/src/components/ui/app-detail/app-header/__test__/app-header.test.tsx @@ -1,10 +1,8 @@ import * as React from 'react' import { appDetailDataStub } from '@/sagas/__stubs__/app-detail' import AppHeader, { AppHeaderProps } from '../app-header' -import { mount } from 'enzyme' -import configureStore from 'redux-mock-store' -import { ReduxState } from '@/types/core' -import { Provider } from 'react-redux' +import { shallow } from 'enzyme' + const mockProps: AppHeaderProps = { appDetailData: { ...appDetailDataStub.data, @@ -14,24 +12,6 @@ const mockProps: AppHeaderProps = { describe('AppContent', () => { it('should match a snapshot', () => { - const mockState = { - client: { - webComponent: { - loading: false, - updating: false, - data: null, - isShowModal: true, - }, - }, - } as ReduxState - const mockStore = configureStore() - const store = mockStore(mockState) - expect( - mount( - - - , - ), - ).toMatchSnapshot() + expect(shallow()).toMatchSnapshot() }) }) diff --git a/packages/marketplace/src/components/ui/app-detail/app-header/app-header.tsx b/packages/marketplace/src/components/ui/app-detail/app-header/app-header.tsx index e771350b51..0a8c3eb0c9 100644 --- a/packages/marketplace/src/components/ui/app-detail/app-header/app-header.tsx +++ b/packages/marketplace/src/components/ui/app-detail/app-header/app-header.tsx @@ -1,20 +1,7 @@ import * as React from 'react' -import { Grid, GridItem, H3, Button, H6 } from '@reapit/elements' - +import { Grid, GridItem, H3 } from '@reapit/elements' import styles from '@/styles/pages/developer-app-detail.scss?mod' import { AppDetailModel } from '@reapit/foundations-ts-definitions' -import { useDispatch, useSelector } from 'react-redux' -import { selectIsWebComponentOpen } from '@/selector/client' -import WebComponentModal from '../../web-component-config-modal' -import { clientCloseWebComponentConfig, clientOpenWebComponentConfig } from '@/actions/client' -import { Dispatch } from 'redux' - -export const toggleWebComponentModal = (dispatch: Dispatch) => () => { - dispatch(clientOpenWebComponentConfig()) -} -export const closeWebComponentModal = (dispatch: Dispatch) => () => { - dispatch(clientCloseWebComponentConfig()) -} export type AppHeaderProps = { appDetailData: AppDetailModel & { @@ -24,12 +11,7 @@ export type AppHeaderProps = { } const AppHeader: React.FC = ({ appDetailData, buttonGroup }) => { - const dispatch = useDispatch() - const isWebComponentOpen = useSelector(selectIsWebComponentOpen) - const handleToggleWebComponentModal = toggleWebComponentModal(dispatch) - const handleCloseWebComponentModal = closeWebComponentModal(dispatch) - - const { media, name, isWebComponent } = appDetailData + const { media, name } = appDetailData const appIcon = media?.filter(({ type }) => type === 'icon')[0] return ( <> @@ -42,23 +24,6 @@ const AppHeader: React.FC = ({ appDetailData, buttonGroup }) => alt={name} />
- {isWebComponent && ( - <> - -
Settings
- -
- {isWebComponentOpen && ( - - )} - - )}

{name}

diff --git a/packages/marketplace/src/components/ui/web-component-config-modal/__test__/__snapshots__/config-modal-inner.test.tsx.snap b/packages/marketplace/src/components/ui/web-component-config-modal/__test__/__snapshots__/config-modal-inner.test.tsx.snap index 628b4a39cb..3f9e4a2af2 100644 --- a/packages/marketplace/src/components/ui/web-component-config-modal/__test__/__snapshots__/config-modal-inner.test.tsx.snap +++ b/packages/marketplace/src/components/ui/web-component-config-modal/__test__/__snapshots__/config-modal-inner.test.tsx.snap @@ -1,159 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Config-modal-inner should WebComponentConfigModalBody match a snapshot 1`] = ` - -

- abc -

- - -
-
- - -
- - - - - - - -
-
-
- -
-`; - exports[`Config-modal-inner should WebComponentConfigModalFooter match a snapshot 1`] = `
= ({ disabled={disabled} onChange={() => setFieldValue(name, value)} /> - +
))} diff --git a/packages/marketplace/src/components/ui/web-component-config-modal/__test__/__snapshots__/config-modal-inner.test.tsx.snap b/packages/marketplace/src/components/ui/web-component-config-modal/__test__/__snapshots__/config-modal-inner.test.tsx.snap index 3f9e4a2af2..986b71f5c0 100644 --- a/packages/marketplace/src/components/ui/web-component-config-modal/__test__/__snapshots__/config-modal-inner.test.tsx.snap +++ b/packages/marketplace/src/components/ui/web-component-config-modal/__test__/__snapshots__/config-modal-inner.test.tsx.snap @@ -69,7 +69,8 @@ exports[`Config-modal-inner should WebComponentConfigModalInner match a snapshot closeModal={[MockFunction]} config={ Object { - "subtext": "Please use the following form to configure your diary settings for your ‘Book a Viewing’ widget on your website", + "subtext": "Please use the following form to configure your diary settings for your + ‘Book a Viewing’ widget on your website", "title": "Book a Viewing Configuration", } } @@ -177,7 +178,8 @@ exports[`Config-modal-inner should WebComponentConfigModalInner match a snapshot }, } } - subtext="Please use the following form to configure your diary settings for your ‘Book a Viewing’ widget on your website" + subtext="Please use the following form to configure your diary settings for your + ‘Book a Viewing’ widget on your website" /> } > @@ -249,10 +251,12 @@ exports[`Config-modal-inner should WebComponentConfigModalInner match a snapshot }, } } - subtext="Please use the following form to configure your diary settings for your ‘Book a Viewing’ widget on your website" + subtext="Please use the following form to configure your diary settings for your + ‘Book a Viewing’ widget on your website" >

- Please use the following form to configure your diary settings for your ‘Book a Viewing’ widget on your website + Please use the following form to configure your diary settings for your + ‘Book a Viewing’ widget on your website

{ expect( mount( - + , ), ).toMatchSnapshot() diff --git a/packages/marketplace/src/components/ui/web-component-config-modal/config-modal.tsx b/packages/marketplace/src/components/ui/web-component-config-modal/config-modal.tsx index 9b6784319b..d840214ba5 100644 --- a/packages/marketplace/src/components/ui/web-component-config-modal/config-modal.tsx +++ b/packages/marketplace/src/components/ui/web-component-config-modal/config-modal.tsx @@ -2,30 +2,29 @@ import * as React from 'react' import { Modal } from '@reapit/elements' import { WebComponentConfigModalInner } from './config-modal-inner' -export const BOOK_VIEWING_CONSTANT = { - title: 'Book a Viewing Configuration', - subtext: - 'Please use the following form to configure your diary settings for your ‘Book a Viewing’ widget on your website', -} - -export const BOOK_VALUATION_CONSTANT = { - title: 'Book a Valuation Configuration', - subtext: - 'Please use the following form to configure your diary settings for your ‘Book a Valuation’ widget on your website', -} - export type WebComponentModalProps = { type: 'BOOK_VIEWING' | 'BOOK_VALUATION' afterClose: () => void closeModal: () => void } -export const WebComponentModal = ({ type, afterClose, closeModal }: WebComponentModalProps) => { - const config = type === 'BOOK_VIEWING' ? BOOK_VIEWING_CONSTANT : BOOK_VALUATION_CONSTANT +export const WEB_COMPONENT_TYPES = { + BOOK_VALUATION: { + title: 'Book a Valuation Configuration', + subtext: `Please use the following form to configure your diary settings for your + ‘Book a Valuation’ widget on your website`, + }, + BOOK_VIEWING: { + title: 'Book a Viewing Configuration', + subtext: `Please use the following form to configure your diary settings for your + ‘Book a Viewing’ widget on your website`, + }, +} +export const WebComponentModal = ({ type, afterClose, closeModal }: WebComponentModalProps) => { return ( - + ) } diff --git a/packages/marketplace/src/core/index.tsx b/packages/marketplace/src/core/index.tsx index 4d79a3c677..0b64c7801d 100644 --- a/packages/marketplace/src/core/index.tsx +++ b/packages/marketplace/src/core/index.tsx @@ -27,6 +27,7 @@ window.reapit = { chatbotAppId: '', marketplaceUrl: '', platformApiUrl: '', + webComponentConfigApiUrl: '', }, } diff --git a/packages/marketplace/src/services/constants.ts b/packages/marketplace/src/services/constants.ts index d8d8dee199..6d3313d958 100644 --- a/packages/marketplace/src/services/constants.ts +++ b/packages/marketplace/src/services/constants.ts @@ -18,4 +18,5 @@ export const URLS = { trafficEventBilling: '/trafficevents/billing', trafficEventStatistics: '/trafficevents/trafficStatistics', negotiators: '/negotiators', + webComponentConfig: '/v1/web-components-config', } diff --git a/packages/marketplace/src/services/web-component.ts b/packages/marketplace/src/services/web-component.ts index 2d383cb9be..6661941b85 100644 --- a/packages/marketplace/src/services/web-component.ts +++ b/packages/marketplace/src/services/web-component.ts @@ -1,6 +1,7 @@ import { fetcher } from '@reapit/elements' import { generateHeader } from './utils' import { logger } from 'logger' +import { URLS } from './constants' export interface FetchWebComponentConfigParams { customerId: string @@ -24,17 +25,14 @@ export type WebComponentConfigResult = { negotiatorIds: string[] } | null -const API = '/dev/v1/web-components-config' - export const fetchWebComponentConfig = async ( params: FetchWebComponentConfigParams, ): Promise => { - return sampleRespone() //SHOULD REMOVE WHEN API READY try { const { customerId } = params const response = await fetcher({ - url: `${API}/${customerId}`, - api: 'http://localhost:3000', + url: `${URLS.webComponentConfig}/${customerId}`, + api: window.reapit.config.webComponentConfigApiUrl, method: 'GET', headers: generateHeader(window.reapit.config.marketplaceApiKey), }) @@ -46,12 +44,11 @@ export const fetchWebComponentConfig = async ( } export const putWebComponentConfig = async (params: PutWebComponentConfigParams): Promise => { - return sampleRespone() //SHOULD REMOVE WHEN API READY try { const { customerId = 'DXX', ...rest } = params const response = await fetcher({ - url: `${API}/${customerId}`, - api: 'http://localhost:3000', + url: `${URLS.webComponentConfig}/${customerId}`, + api: window.reapit.config.webComponentConfigApiUrl, method: 'PATCH', headers: generateHeader(window.reapit.config.marketplaceApiKey), body: rest, @@ -62,20 +59,3 @@ export const putWebComponentConfig = async (params: PutWebComponentConfigParams) throw new Error(error) } } - -//SHOULD REMOVE WHEN API READY -function sampleRespone(): Promise { - return new Promise(res => { - setTimeout(() => { - const data = { - appointmentLength: 15, - appointmentTimeGap: 60, - appointmentTypes: [{ value: 'value1', id: 'id1' }], - customerId: 'DXX', - daysOfWeek: ['1', '2', '3', '5', '6'], - negotiatorIds: ['AACC', 'AAAN'], - } as WebComponentConfigResult - res(data) - }, 1000) - }) -} diff --git a/packages/marketplace/src/tests/badges/badge-branches.svg b/packages/marketplace/src/tests/badges/badge-branches.svg index 7a8f303567..27f77ced28 100644 --- a/packages/marketplace/src/tests/badges/badge-branches.svg +++ b/packages/marketplace/src/tests/badges/badge-branches.svg @@ -1 +1 @@ -Coverage:branchesCoverage:branches69.18%69.18% \ No newline at end of file +Coverage:branchesCoverage:branches69.19%69.19% \ 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 173e33e04c..1eb02ff54c 100644 --- a/packages/marketplace/src/tests/badges/badge-lines.svg +++ b/packages/marketplace/src/tests/badges/badge-lines.svg @@ -1 +1 @@ -Coverage:linesCoverage:lines90.05%90.05% \ No newline at end of file +Coverage:linesCoverage:lines90.04%90.04% \ No newline at end of file diff --git a/packages/marketplace/src/types/global.d.ts b/packages/marketplace/src/types/global.d.ts index 4b2d93e9f7..88792cb2c0 100644 --- a/packages/marketplace/src/types/global.d.ts +++ b/packages/marketplace/src/types/global.d.ts @@ -13,6 +13,7 @@ export type Config = { chatbotAppId: string marketplaceUrl: string platformApiUrl: string + webComponentConfigApiUrl: string } declare global { From f253e18705cb96bfac0cc40a0a274f1ba5e0dd47 Mon Sep 17 00:00:00 2001 From: andt Date: Tue, 26 May 2020 16:03:38 +0700 Subject: [PATCH 6/7] chore: #1033 update follow PR cmts --- .../src/tests/badges/badge-lines.svg | 2 +- .../src/tests/badges/badge-statements.svg | 2 +- .../src/components/DropdownSelect/index.tsx | 2 +- .../RadioSelect/__tests__/index.tsx | 2 +- .../src/components/RadioSelect/index.tsx | 2 +- .../src/tests/badges/badge-branches.svg | 2 +- .../src/tests/badges/badge-functions.svg | 2 +- .../elements/src/tests/badges/badge-lines.svg | 2 +- .../src/tests/badges/badge-statements.svg | 2 +- .../client-app-detail/__test__/aside.test.tsx | 16 +++---- .../__stubs__/web-component-config.ts | 14 ++++++ .../config-modal-inner.test.tsx.snap | 2 - .../__test__/config-modal-inner.test.tsx | 44 +++++-------------- .../config-modal-inner.tsx | 22 ++++++++-- .../config-modal.tsx | 5 +++ .../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 +- 19 files changed, 67 insertions(+), 62 deletions(-) create mode 100644 packages/marketplace/src/components/ui/web-component-config-modal/__stubs__/web-component-config.ts diff --git a/packages/aml-checklist/src/tests/badges/badge-lines.svg b/packages/aml-checklist/src/tests/badges/badge-lines.svg index 881161a55f..960cfbaa26 100644 --- a/packages/aml-checklist/src/tests/badges/badge-lines.svg +++ b/packages/aml-checklist/src/tests/badges/badge-lines.svg @@ -1 +1 @@ -Coverage:linesCoverage:lines85.48%85.48% \ No newline at end of file +Coverage:linesCoverage:lines85.47%85.47% \ No newline at end of file diff --git a/packages/aml-checklist/src/tests/badges/badge-statements.svg b/packages/aml-checklist/src/tests/badges/badge-statements.svg index 4233cd98d0..53a25de9d2 100644 --- a/packages/aml-checklist/src/tests/badges/badge-statements.svg +++ b/packages/aml-checklist/src/tests/badges/badge-statements.svg @@ -1 +1 @@ -Coverage:statementsCoverage:statements85.28%85.28% \ No newline at end of file +Coverage:statementsCoverage:statements85.27%85.27% \ No newline at end of file diff --git a/packages/elements/src/components/DropdownSelect/index.tsx b/packages/elements/src/components/DropdownSelect/index.tsx index e4ea61acff..da975422af 100644 --- a/packages/elements/src/components/DropdownSelect/index.tsx +++ b/packages/elements/src/components/DropdownSelect/index.tsx @@ -56,7 +56,7 @@ export const DropdownSelect: React.FC = ({ return (
- + {subText && } Coverage:branchesCoverage:branches76.68%76.68% \ No newline at end of file +Coverage:branchesCoverage:branches75.69%75.69% \ No newline at end of file diff --git a/packages/elements/src/tests/badges/badge-functions.svg b/packages/elements/src/tests/badges/badge-functions.svg index b946feb75d..fa28fecf26 100644 --- a/packages/elements/src/tests/badges/badge-functions.svg +++ b/packages/elements/src/tests/badges/badge-functions.svg @@ -1 +1 @@ -Coverage:functionsCoverage:functions94.67%94.67% \ No newline at end of file +Coverage:functionsCoverage:functions94.62%94.62% \ No newline at end of file diff --git a/packages/elements/src/tests/badges/badge-lines.svg b/packages/elements/src/tests/badges/badge-lines.svg index 7fd5278264..bc5897cf91 100644 --- a/packages/elements/src/tests/badges/badge-lines.svg +++ b/packages/elements/src/tests/badges/badge-lines.svg @@ -1 +1 @@ -Coverage:linesCoverage:lines95.58%95.58% \ No newline at end of file +Coverage:linesCoverage:lines95.3%95.3% \ No newline at end of file diff --git a/packages/elements/src/tests/badges/badge-statements.svg b/packages/elements/src/tests/badges/badge-statements.svg index 5f9a9c6d66..6291eb9c59 100644 --- a/packages/elements/src/tests/badges/badge-statements.svg +++ b/packages/elements/src/tests/badges/badge-statements.svg @@ -1 +1 @@ -Coverage:statementsCoverage:statements95.49%95.49% \ No newline at end of file +Coverage:statementsCoverage:statements95.04%95.04% \ No newline at end of file diff --git a/packages/marketplace/src/components/pages/client-app-detail/__test__/aside.test.tsx b/packages/marketplace/src/components/pages/client-app-detail/__test__/aside.test.tsx index 1df2a01de5..4c174ea250 100644 --- a/packages/marketplace/src/components/pages/client-app-detail/__test__/aside.test.tsx +++ b/packages/marketplace/src/components/pages/client-app-detail/__test__/aside.test.tsx @@ -6,9 +6,9 @@ import { appDetailDataStub } from '@/sagas/__stubs__/app-detail' import { AppDetailDataNotNull } from '@/reducers/client/app-detail' import { DesktopIntegrationTypeModel } from '@/actions/app-integration-types' import configureStore from 'redux-mock-store' -import { ReduxState } from '@/types/core' import { Provider } from 'react-redux' import { WebComponentConfig } from '../aside' +import appState from '@/reducers/__stubs__/app-state' describe('Aside', () => { test('Aside - should match snapshot', () => { @@ -24,18 +24,14 @@ describe('Aside', () => { }) describe('WebComponentConfig', () => { - const mockState = { + const extendStore = { + ...appState, client: { - webComponent: { - loading: false, - updating: false, - data: null, - isShowModal: true, - }, + webComponent: { isShowModal: true }, }, - } as ReduxState + } const mockStore = configureStore() - const store = mockStore(mockState) + const store = mockStore(extendStore) it('Should match snapshot', () => { expect( mount( diff --git a/packages/marketplace/src/components/ui/web-component-config-modal/__stubs__/web-component-config.ts b/packages/marketplace/src/components/ui/web-component-config-modal/__stubs__/web-component-config.ts new file mode 100644 index 0000000000..23f869ff87 --- /dev/null +++ b/packages/marketplace/src/components/ui/web-component-config-modal/__stubs__/web-component-config.ts @@ -0,0 +1,14 @@ +import { ReduxState } from '@/types/core' + +export const webComponentStub = { + client: { + webComponent: { loading: false, updating: false, data: null, isShowModal: true, negotiators: {} }, + }, + auth: { + loginSession: { + loginIdentity: { + clientId: 'DXX', + }, + }, + }, +} as ReduxState diff --git a/packages/marketplace/src/components/ui/web-component-config-modal/__test__/__snapshots__/config-modal-inner.test.tsx.snap b/packages/marketplace/src/components/ui/web-component-config-modal/__test__/__snapshots__/config-modal-inner.test.tsx.snap index 986b71f5c0..8f3f7e628c 100644 --- a/packages/marketplace/src/components/ui/web-component-config-modal/__test__/__snapshots__/config-modal-inner.test.tsx.snap +++ b/packages/marketplace/src/components/ui/web-component-config-modal/__test__/__snapshots__/config-modal-inner.test.tsx.snap @@ -35,7 +35,6 @@ exports[`Config-modal-inner should WebComponentConfigModalFooter match a snapsho @@ -1270,7 +1269,6 @@ exports[`Config-modal-inner should WebComponentConfigModalInner match a snapshot diff --git a/packages/marketplace/src/components/ui/web-component-config-modal/__test__/config-modal-inner.test.tsx b/packages/marketplace/src/components/ui/web-component-config-modal/__test__/config-modal-inner.test.tsx index f21a30da9e..4452100888 100644 --- a/packages/marketplace/src/components/ui/web-component-config-modal/__test__/config-modal-inner.test.tsx +++ b/packages/marketplace/src/components/ui/web-component-config-modal/__test__/config-modal-inner.test.tsx @@ -8,35 +8,30 @@ import { } from '../config-modal-inner' import { mount } from 'enzyme' import configureStore from 'redux-mock-store' -import { ReduxState } from '@/types/core' import { Provider } from 'react-redux' import { WEB_COMPONENT_TYPES } from '../config-modal' import { PutWebComponentConfigParams } from '@/services/web-component' import { clientPutWebComponentConfig, clientFetchWebComponentConfig } from '@/actions/client' +import { webComponentStub } from '../__stubs__/web-component-config' +import appState from '@/reducers/__stubs__/app-state' const params = { appointmentLength: 1, appointmentTimeGap: 1, customerId: 'string', daysOfWeek: ['1', '2'], - // negotiatorIds: , } as PutWebComponentConfigParams -describe('Config-modal-inner', () => { - const mockState = { - client: { - webComponent: { - loading: false, - updating: false, - data: null, - isShowModal: true, - negotiators: {}, - }, - }, - } as ReduxState +const extendAppState = webComponent => { + return { + ...appState, + client: { ...appState.client, webComponent }, + } +} +describe('Config-modal-inner', () => { const mockStore = configureStore() - const store = mockStore(mockState) + const store = mockStore(extendAppState(webComponentStub)) it('should WebComponentConfigModalFooter match a snapshot', () => { const mockProps = { @@ -52,25 +47,8 @@ describe('Config-modal-inner', () => { }) it('should WebComponentConfigModalInner match a snapshot', () => { - const mockState = { - client: { - webComponent: { - loading: false, - updating: false, - data: null, - isShowModal: true, - }, - }, - auth: { - loginSession: { - loginIdentity: { - clientId: 'DXX', - }, - }, - }, - } as ReduxState const mockStore = configureStore() - const store = mockStore(mockState) + const store = mockStore(extendAppState(webComponentStub)) expect( mount( diff --git a/packages/marketplace/src/components/ui/web-component-config-modal/config-modal-inner.tsx b/packages/marketplace/src/components/ui/web-component-config-modal/config-modal-inner.tsx index d34ae7deda..a870cfe28c 100644 --- a/packages/marketplace/src/components/ui/web-component-config-modal/config-modal-inner.tsx +++ b/packages/marketplace/src/components/ui/web-component-config-modal/config-modal-inner.tsx @@ -12,6 +12,7 @@ import { FormikValues, DropdownSelect, SelectOption, + FormikProps, } from '@reapit/elements' import styles from '@/styles/elements/radioselect.scss?mod' import { useDispatch, useSelector } from 'react-redux' @@ -26,6 +27,7 @@ import { PutWebComponentConfigParams } from '@/services/web-component' import { selectClientId } from '@/selector/auth' import { Dispatch } from 'redux' import { NegotiatorItem } from '@/services/negotiators' +import { WebComponentType } from './config-modal' export const updateWebComponentConfig = (dispatch: Dispatch) => (params: FormikValues) => { dispatch(clientPutWebComponentConfig(params as PutWebComponentConfigParams)) @@ -45,8 +47,11 @@ export const genarateNegotiatorOptions = (negotiators: NegotiatorItem[]): Select } as SelectOption), ) } - -export const WebComponentConfigModalBody = ({ subtext, formikProps }) => { +export type WebComponentConfigModalBodyProps = { + subtext: string + formikProps: FormikProps +} +export const WebComponentConfigModalBody = ({ subtext, formikProps }: WebComponentConfigModalBodyProps) => { const { values, setFieldValue } = formikProps const negotiators = useSelector(selectIsWebComponentNegotiators) const negotiatorOptions = genarateNegotiatorOptions(negotiators) @@ -111,7 +116,11 @@ export const WebComponentConfigModalBody = ({ subtext, formikProps }) => { ) } -export const WebComponentConfigModalFooter = ({ closeModal }) => { +export type WebComponentConfigModalFooterProps = { + closeModal: () => void +} + +export const WebComponentConfigModalFooter = ({ closeModal }: WebComponentConfigModalFooterProps) => { const updating = useSelector(selectIsWebComponentUpdating) return ( <> @@ -125,7 +134,12 @@ export const WebComponentConfigModalFooter = ({ closeModal }) => { ) } -export const WebComponentConfigModalInner = ({ config, closeModal }) => { +export type WebComponentConfigModalInnerProps = { + config: WebComponentType + closeModal: () => void +} + +export const WebComponentConfigModalInner = ({ config, closeModal }: WebComponentConfigModalInnerProps) => { const dispatch = useDispatch() const handleUpdateWebComponentConfig = updateWebComponentConfig(dispatch) const webComponentData = useSelector(selectIsWebComponentData) diff --git a/packages/marketplace/src/components/ui/web-component-config-modal/config-modal.tsx b/packages/marketplace/src/components/ui/web-component-config-modal/config-modal.tsx index d840214ba5..8bde662474 100644 --- a/packages/marketplace/src/components/ui/web-component-config-modal/config-modal.tsx +++ b/packages/marketplace/src/components/ui/web-component-config-modal/config-modal.tsx @@ -8,6 +8,11 @@ export type WebComponentModalProps = { closeModal: () => void } +export type WebComponentType = { + title: string + subtext: string +} + export const WEB_COMPONENT_TYPES = { BOOK_VALUATION: { title: 'Book a Valuation Configuration', diff --git a/packages/marketplace/src/tests/badges/badge-branches.svg b/packages/marketplace/src/tests/badges/badge-branches.svg index bd173d0493..97a916f3b1 100644 --- a/packages/marketplace/src/tests/badges/badge-branches.svg +++ b/packages/marketplace/src/tests/badges/badge-branches.svg @@ -1 +1 @@ -Coverage:branchesCoverage:branches68.99%68.99% +Coverage:branchesCoverage:branches69.11%69.11% \ 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 492e50e762..81b5903fbe 100644 --- a/packages/marketplace/src/tests/badges/badge-functions.svg +++ b/packages/marketplace/src/tests/badges/badge-functions.svg @@ -1 +1 @@ -Coverage:functionsCoverage:functions77.6%77.6% +Coverage:functionsCoverage:functions77.92%77.92% \ 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 07fc6a6d34..56d068d1db 100644 --- a/packages/marketplace/src/tests/badges/badge-lines.svg +++ b/packages/marketplace/src/tests/badges/badge-lines.svg @@ -1 +1 @@ -Coverage:linesCoverage:lines90.05%90.05% +Coverage:linesCoverage:lines90.16%90.16% \ 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 55bd07162c..2aa55b4094 100644 --- a/packages/marketplace/src/tests/badges/badge-statements.svg +++ b/packages/marketplace/src/tests/badges/badge-statements.svg @@ -1 +1 @@ -Coverage:statementsCoverage:statements89.23%89.23% \ No newline at end of file +Coverage:statementsCoverage:statements89.35%89.35% \ No newline at end of file From 7c65cfefd17820cd1cfb4d601b33010264706494 Mon Sep 17 00:00:00 2001 From: andt Date: Tue, 26 May 2020 21:30:02 +0700 Subject: [PATCH 7/7] chore: #1033 fix test fail --- .../src/components/RadioSelect/index.tsx | 2 +- .../__snapshots__/client.test.tsx.snap | 40 +++++++++---------- .../src/selector/__tests__/client.ts | 2 +- packages/marketplace/src/selector/client.ts | 2 +- .../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 +- 8 files changed, 27 insertions(+), 27 deletions(-) diff --git a/packages/elements/src/components/RadioSelect/index.tsx b/packages/elements/src/components/RadioSelect/index.tsx index 064c955729..8e0f8c14ad 100644 --- a/packages/elements/src/components/RadioSelect/index.tsx +++ b/packages/elements/src/components/RadioSelect/index.tsx @@ -30,7 +30,7 @@ export const RadioSelect: React.FC = ({ setFieldValue, state, disabled = false, - className, + className = '', }) => { return ( diff --git a/packages/marketplace/src/components/pages/client/__tests__/__snapshots__/client.test.tsx.snap b/packages/marketplace/src/components/pages/client/__tests__/__snapshots__/client.test.tsx.snap index 31c81e6491..67e4d849d5 100644 --- a/packages/marketplace/src/components/pages/client/__tests__/__snapshots__/client.test.tsx.snap +++ b/packages/marketplace/src/components/pages/client/__tests__/__snapshots__/client.test.tsx.snap @@ -352,7 +352,7 @@ exports[`Client should match a snapshot when LOADING false 1`] = ` type="radio" >
@@ -390,7 +390,7 @@ exports[`Client should match a snapshot when LOADING false 1`] = ` checked={false} className="checkbox " disabled={false} - id="By Company" + id="searchByBy Company" key="companyName" name="searchBy" onChange={[Function]} @@ -398,7 +398,7 @@ exports[`Client should match a snapshot when LOADING false 1`] = ` value="companyName" /> @@ -869,7 +869,7 @@ exports[`Client should match a snapshot when LOADING false 2`] = ` type="radio" >
@@ -907,7 +907,7 @@ exports[`Client should match a snapshot when LOADING false 2`] = ` checked={false} className="checkbox " disabled={false} - id="By Company" + id="searchByBy Company" key="companyName" name="searchBy" onChange={[Function]} @@ -915,7 +915,7 @@ exports[`Client should match a snapshot when LOADING false 2`] = ` value="companyName" /> @@ -1386,7 +1386,7 @@ exports[`Client should match a snapshot when featured apps is empty [] 1`] = ` type="radio" >
@@ -1424,7 +1424,7 @@ exports[`Client should match a snapshot when featured apps is empty [] 1`] = ` checked={false} className="checkbox " disabled={false} - id="By Company" + id="searchByBy Company" key="companyName" name="searchBy" onChange={[Function]} @@ -1432,7 +1432,7 @@ exports[`Client should match a snapshot when featured apps is empty [] 1`] = ` value="companyName" /> @@ -1991,7 +1991,7 @@ exports[`Client should match a snapshot when featured apps is undefined 1`] = ` type="radio" >
@@ -2029,7 +2029,7 @@ exports[`Client should match a snapshot when featured apps is undefined 1`] = ` checked={false} className="checkbox " disabled={false} - id="By Company" + id="searchByBy Company" key="companyName" name="searchBy" onChange={[Function]} @@ -2037,7 +2037,7 @@ exports[`Client should match a snapshot when featured apps is undefined 1`] = ` value="companyName" /> diff --git a/packages/marketplace/src/selector/__tests__/client.ts b/packages/marketplace/src/selector/__tests__/client.ts index c0b63983bd..0a0bbb2f20 100644 --- a/packages/marketplace/src/selector/__tests__/client.ts +++ b/packages/marketplace/src/selector/__tests__/client.ts @@ -8,7 +8,7 @@ import { selectIsWebComponentLoading, selectIsWebComponentUpdating, selectIsWebComponentNegotiators, - selectAppDetail + selectAppDetail, } from '../client' import { featuredAppsDataStub } from '@/sagas/__stubs__/apps' diff --git a/packages/marketplace/src/selector/client.ts b/packages/marketplace/src/selector/client.ts index a4e163c2e3..08a6929928 100644 --- a/packages/marketplace/src/selector/client.ts +++ b/packages/marketplace/src/selector/client.ts @@ -35,7 +35,7 @@ export const selectIsWebComponentUpdating = (state: ReduxState) => { export const selectIsWebComponentNegotiators = (state: ReduxState) => { return state?.client.webComponent?.negotiators?._embedded || [] } - + export const selectAppDetail = (state: ReduxState) => { return state.appDetail } diff --git a/packages/marketplace/src/tests/badges/badge-branches.svg b/packages/marketplace/src/tests/badges/badge-branches.svg index 92faf57963..7f87cbcc42 100644 --- a/packages/marketplace/src/tests/badges/badge-branches.svg +++ b/packages/marketplace/src/tests/badges/badge-branches.svg @@ -1 +1 @@ -Coverage:branchesCoverage:branches71.48%71.48% +Coverage:branchesCoverage:branches71.72%71.72% \ 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 740b37d533..f24ba06679 100644 --- a/packages/marketplace/src/tests/badges/badge-functions.svg +++ b/packages/marketplace/src/tests/badges/badge-functions.svg @@ -1 +1 @@ -Coverage:functionsCoverage:functions78.55%78.55% +Coverage:functionsCoverage:functions78.8%78.8% \ 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 8797d72721..b282a98b03 100644 --- a/packages/marketplace/src/tests/badges/badge-lines.svg +++ b/packages/marketplace/src/tests/badges/badge-lines.svg @@ -1 +1 @@ -Coverage:linesCoverage:lines90.37%90.37% +Coverage:linesCoverage:lines90.46%90.46% \ 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 f0fc5fe7cd..32a1fa1ead 100644 --- a/packages/marketplace/src/tests/badges/badge-statements.svg +++ b/packages/marketplace/src/tests/badges/badge-statements.svg @@ -1 +1 @@ -Coverage:statementsCoverage:statements89.58%89.58% +Coverage:statementsCoverage:statements89.67%89.67% \ No newline at end of file