diff --git a/packages/marketplace/src/components/pages/__tests__/__snapshots__/admin-apps.tsx.snap b/packages/marketplace/src/components/pages/__tests__/__snapshots__/admin-apps.tsx.snap deleted file mode 100644 index 952da840cd..0000000000 --- a/packages/marketplace/src/components/pages/__tests__/__snapshots__/admin-apps.tsx.snap +++ /dev/null @@ -1,406 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`AdminApps renderForm should return correctly 1`] = ` -
- - - - Admin Apps Filter Form - - - Filter the result by App, Developer and Company - - - - - - - - - - - - - - - - - - - - - - Search - - - Refresh - - - - - - -`; - -exports[`AdminApps should match a snapshot when LOADING false 1`] = ` - - -
- - App Management - - - - -
-
- - - Total apps: - 6 - - -
- -
-
- - - -
-`; - -exports[`AdminApps should match a snapshot when LOADING true 1`] = ` - - -
- -
-
- - App Management - - - - -
-
- - - Total apps: - 6 - - -
- -
-
- - - -
-`; diff --git a/packages/marketplace/src/components/pages/__tests__/admin-apps.tsx b/packages/marketplace/src/components/pages/__tests__/admin-apps.tsx deleted file mode 100644 index df9d0f0815..0000000000 --- a/packages/marketplace/src/components/pages/__tests__/admin-apps.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import * as React from 'react' -import { shallow } from 'enzyme' -import { appsDataStub } from '@/sagas/__stubs__/apps' -import { ReduxState } from '@/types/core' -import { - AdminApps, - AdminAppsProps, - mapStateToProps, - mapDispatchToProps, - renderForm, - handleCloseAppDeleteModal, -} from '../admin-apps' -import { RouteComponentProps, StaticContext } from 'react-router' - -const routerProps = { - match: { - params: { - page: '2', - }, - }, - location: { - search: 'page=1', - }, -} as RouteComponentProps - -const props = (loading: boolean): AdminAppsProps => ({ - adminAppsState: { - loading: loading, - formState: 'PENDING', - adminAppsData: appsDataStub.data, - }, - onChangeFeatured: jest.fn(), - ...routerProps, -}) - -describe('AdminApps', () => { - it('should match a snapshot when LOADING false', () => { - expect(shallow()).toMatchSnapshot() - }) - - it('should match a snapshot when LOADING true', () => { - expect(shallow()).toMatchSnapshot() - }) - - describe('mapStateToProps', () => { - it('should return correctly', () => { - const mockState = { - adminApps: appsDataStub.data, - } as ReduxState - const output = { - adminAppsState: mockState.adminApps, - ...routerProps, - } - const result = mapStateToProps(mockState, routerProps) - expect(result).toEqual(output) - }) - }) - - describe('mapDispatchToProps', () => { - it('should call dispatch correctly', () => { - const mockDispatch = jest.fn() - const { onChangeFeatured } = mapDispatchToProps(mockDispatch) - onChangeFeatured({ id: '1', isFeatured: true }) - expect(mockDispatch).toBeCalled() - }) - }) - - describe('renderForm', () => { - it('should return correctly', () => { - const setFilter = jest.fn() - const fn = renderForm(setFilter)({ values: {}, resetForm: jest.fn() }) - expect(fn).toMatchSnapshot() - }) - }) - - describe('handleCloseAppDeleteModal', () => { - it('should return correctly', () => { - const mockProps = { - setDeleteModal: jest.fn(), - } - handleCloseAppDeleteModal(mockProps)() - expect(mockProps.setDeleteModal).toBeCalled() - }) - }) -}) diff --git a/packages/marketplace/src/components/pages/admin-apps.tsx b/packages/marketplace/src/components/pages/admin-apps.tsx deleted file mode 100644 index e88f7d4394..0000000000 --- a/packages/marketplace/src/components/pages/admin-apps.tsx +++ /dev/null @@ -1,300 +0,0 @@ -import React from 'react' -import { connect } from 'react-redux' -import { withRouter, RouteComponentProps } from 'react-router' -import { ReduxState } from '@/types/core' -import { - Loader, - Pagination, - Table, - Button, - Alert, - Input, - H3, - Grid, - GridItem, - Formik, - Form, - FormSection, - FormHeading, - FormSubHeading, - Content, - FlexContainerBasic, - DatePicker, - toLocalTime, -} from '@reapit/elements' -import ErrorBoundary from '@/components/hocs/error-boundary' -import { AdminAppsState } from '@/reducers/admin-apps' -import styles from '@/styles/pages/admin-apps.scss?mod' -import { selectAdminAppsState } from '@/selector/admin' -import { Dispatch, compose } from 'redux' -import { adminAppsRequestFeatured, AdminAppsFeaturedParams } from '@/actions/admin-apps' -import AppDeleteModal from '../ui/app-delete' -import { addQuery, stringifyObjectIntoQueryString, getParamsFromPath } from '@/utils/client-url-params' - -export const generateColumns = ({ onChangeFeatured, setDeleteModal, deleteModal }) => () => { - const FeaturedCell = ({ row, cell }) => { - const { id } = row.original - const { value } = cell - return ( -
- onChangeFeatured({ id, isFeatured: evt.target.checked })} - /> - -
- ) - } - const DeleteCell = ({ row }) => ( - - ) - const CreatedCell = ({ cell: { value } }) => { - return

{toLocalTime(value)}

- } - return [ - { - Header: 'AppID', - accessor: 'id', - }, - { - Header: 'App Name', - accessor: 'name', - }, - { - Header: 'App Summary', - accessor: 'summary', - }, - { - Header: 'Developer Name', - accessor: 'developer', - }, - { - Header: 'Is Listed', - accessor: 'isListed', - }, - { - Header: 'Pending Revisions', - accessor: 'pendingRevisions', - }, - { - Header: 'Direct API', - accessor: 'isDirectApi', - }, - { - Header: 'Created', - accessor: 'created', - Cell: CreatedCell, - }, - { - Header: 'Featured', - accessor: 'isFeatured', - Cell: FeaturedCell, - }, - { - id: 'Delete', - Cell: DeleteCell, - }, - ] -} - -export const refreshForm = (onSubmit, resetForm) => () => { - resetForm() - onSubmit({ appName: '', companyName: '', developerName: '' }) -} - -export const renderForm = onSubmit => ({ values, resetForm }) => { - const disabled = - !values.appName && !values.companyName && !values.developerName && !values.RegisteredFrom && !values.RegisteredTo - - const startDate = values.RegisteredFrom ? new Date(values.RegisteredFrom) : '' - const endDate = values.RegisteredTo ? new Date(values.RegisteredTo) : '' - - return ( -
- - - Admin Apps Filter Form - Filter the result by App, Developer and Company - - - - - - - - - - - - - - - - - - - - - - - - - -
- ) -} - -export const handleCloseAppDeleteModal = ({ setDeleteModal }) => () => { - setDeleteModal({ visible: false, appId: '', appName: '' }) -} - -export type FormValues = { - appName: string - companyName: string - developerName: string - RegisteredFrom: string - RegisteredTo: string -} - -export const handleOnSubmit = (history, pageNumber: number) => (formValues: FormValues) => { - const submitValues = Object.keys(formValues).reduce((newObj, key) => { - const value = formValues[key] - if (value) { - newObj[key] = value - } - return newObj - }, {}) - const queryString = stringifyObjectIntoQueryString({ ...submitValues, pageNumber }) - history.push(`apps?${queryString}`) -} - -export const handleChangePageNumber = history => (pageNumber: number) => { - history.push(addQuery({ pageNumber })) -} - -export type AdminAppsProps = DispatchProps & StateProps - -export const AdminApps: React.FunctionComponent = ({ - adminAppsState, - onChangeFeatured, - history, - location, -}) => { - const queryParams = getParamsFromPath(location.search) as any - const pageNumber = parseInt(queryParams.pageNumber, 10) || 1 - const unfetched = !adminAppsState.adminAppsData - const { loading } = adminAppsState - const { data = [], totalCount, pageSize } = adminAppsState.adminAppsData || {} - const [deleteModal, setDeleteModal] = React.useState({ visible: false, appId: '', appName: '', developerName: '' }) - const columns = React.useMemo(generateColumns({ onChangeFeatured, setDeleteModal, deleteModal }), [data]) - - const formInitValues = { - ...queryParams, - RegisteredFrom: queryParams.RegisteredFrom || '', - RegisteredTo: queryParams.RegisteredTo || '', - } - - if (unfetched) { - return - } - - return ( - - - {loading && ( -
- -
- )} -
-

App Management

- - {renderForm(handleOnSubmit(history, pageNumber))} - -
-
- - Total apps: {totalCount} - - - {!loading && !data.length ? ( - - ) : ( -
- - - )} - - - - - - ) -} - -export type StateProps = RouteComponentProps & { - adminAppsState: AdminAppsState -} - -export const mapStateToProps = (state: ReduxState, ownProps: RouteComponentProps): StateProps => ({ - adminAppsState: selectAdminAppsState(state), - ...ownProps, -}) - -export type DispatchProps = { - onChangeFeatured: (params: AdminAppsFeaturedParams) => void -} - -export const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => ({ - onChangeFeatured: (params: AdminAppsFeaturedParams) => dispatch(adminAppsRequestFeatured(params)), -}) - -export const withRedux = connect(mapStateToProps, mapDispatchToProps) - -export default compose(withRouter, withRedux)(AdminApps) as React.LazyExoticComponent diff --git a/packages/marketplace/src/components/pages/admin-apps/__tests__/__snapshots__/admin-apps.test.tsx.snap b/packages/marketplace/src/components/pages/admin-apps/__tests__/__snapshots__/admin-apps.test.tsx.snap new file mode 100644 index 0000000000..bcb4c68db6 --- /dev/null +++ b/packages/marketplace/src/components/pages/admin-apps/__tests__/__snapshots__/admin-apps.test.tsx.snap @@ -0,0 +1,3182 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` 1`] = ` +
+
+ +
+
+`; + +exports[`admin-apps AdminApprovals should match a snapshot 1`] = ` + + + + +
+ +
+
+ +

+ App Management +

+
+ +
+ + +
+ +
+ +
+ Admin Apps Filter Form +
+
+ +
+ Filter the result by App, Developer and Company +
+
+ +
+ +
+ + +
+
+ + +
+
+
+
+
+
+ +
+ + +
+
+ + +
+
+
+
+
+
+ +
+ + +
+
+ + +
+
+
+
+
+
+
+
+ +
+ +
+ + +
+
+ + + } + customTimeInput={null} + dateFormat="MM/dd/yyyy" + dateFormatCalendar="LLLL yyyy" + disabled={false} + disabledKeyboardNavigation={false} + dropdownMode="scroll" + enableTabLoop={true} + endDate="" + excludeScrollbar={true} + id="registeredFrom" + inlineFocusSelectedMonth={false} + monthsShown={1} + name="registeredFrom" + nextMonthButtonLabel="Next Month" + nextYearButtonLabel="Next Year" + onBlur={[Function]} + onCalendarClose={[Function]} + onCalendarOpen={[Function]} + onChange={[Function]} + onClickOutside={[Function]} + onFocus={[Function]} + onInputClick={[Function]} + onInputError={[Function]} + onKeyDown={[Function]} + onMonthChange={[Function]} + onSelect={[Function]} + onYearChange={[Function]} + preventOpenOnFocus={false} + previousMonthButtonLabel="Previous Month" + previousYearButtonLabel="Previous Year" + readOnly={false} + renderDayContents={[Function]} + selectsStart={true} + shouldCloseOnSelect={true} + showMonthYearPicker={false} + showPopperArrow={true} + showPreviousMonths={false} + showQuarterYearPicker={false} + showTimeInput={false} + showTimeSelect={false} + startDate="" + strictParsing={false} + timeCaption="Time" + timeInputLabel="Time" + timeIntervals={30} + value="" + withPortal={false} + > + + +
+ } + > + + + +
+
+ + + +
+
+
+
+
+ + +
+
+ +
+
+
+ +
+ + +
+
+ + + } + customTimeInput={null} + dateFormat="MM/dd/yyyy" + dateFormatCalendar="LLLL yyyy" + disabled={false} + disabledKeyboardNavigation={false} + dropdownMode="scroll" + enableTabLoop={true} + endDate="" + excludeScrollbar={true} + id="registeredTo" + inlineFocusSelectedMonth={false} + minDate="" + monthsShown={1} + name="registeredTo" + nextMonthButtonLabel="Next Month" + nextYearButtonLabel="Next Year" + onBlur={[Function]} + onCalendarClose={[Function]} + onCalendarOpen={[Function]} + onChange={[Function]} + onClickOutside={[Function]} + onFocus={[Function]} + onInputClick={[Function]} + onInputError={[Function]} + onKeyDown={[Function]} + onMonthChange={[Function]} + onSelect={[Function]} + onYearChange={[Function]} + preventOpenOnFocus={false} + previousMonthButtonLabel="Previous Month" + previousYearButtonLabel="Previous Year" + readOnly={false} + renderDayContents={[Function]} + selectsEnd={true} + shouldCloseOnSelect={true} + showMonthYearPicker={false} + showPopperArrow={true} + showPreviousMonths={false} + showQuarterYearPicker={false} + showTimeInput={false} + showTimeSelect={false} + startDate="" + strictParsing={false} + timeCaption="Time" + timeInputLabel="Time" + timeIntervals={30} + value="" + withPortal={false} + > + + +
+ } + > + + + +
+
+ + + +
+
+
+
+
+ + +
+
+ +
+
+
+ +
+ + + + + + +
+
+
+
+
+ +
+
+ + + +
+
+ +
+ + Total apps: + 0 + +
+
+
+ +
+
+
+ + + + + + + + + + + + + + + +
+ AppID + + App Name + + App Summary + + Company Name + + Is Listed + + Pending Revisions + + Direct API + + Created + + Featured + +
+   +
+
+
+
+ + + + + + + + + + + + + + + + + + +`; + +exports[`admin-apps generateColumns should match snapshot 1`] = ` +
+ + + + + + + + + + +
+`; + +exports[`admin-apps renderCreatedAt should match snapshot 1`] = ` +
+

+ 01 Jan 2020 00:00 +

+
+`; + +exports[`admin-apps renderDeleteAction should call delete action 1`] = ` +
+ + + +
+`; + +exports[`admin-apps renderDeleteAction should render DeleteActions 1`] = ` +
+ + Delete + +
+`; + +exports[`admin-apps renderForm should return correctly 1`] = ` +
+ + + + Admin Apps Filter Form + + + Filter the result by App, Developer and Company + + + + + + + + + + + + + + + + + + + + + + Search + + + Refresh + + + + + + +`; + +exports[`admin-apps renderIsFeature should run correctly 1`] = ` +
+ +
+`; diff --git a/packages/marketplace/src/components/pages/admin-apps/__tests__/admin-apps.test.tsx b/packages/marketplace/src/components/pages/admin-apps/__tests__/admin-apps.test.tsx new file mode 100644 index 0000000000..28257156a9 --- /dev/null +++ b/packages/marketplace/src/components/pages/admin-apps/__tests__/admin-apps.test.tsx @@ -0,0 +1,215 @@ +import * as React from 'react' +import { shallow, mount } from 'enzyme' +import configureStore from 'redux-mock-store' +import * as ReactRedux from 'react-redux' +import { MemoryRouter } from 'react-router' +import { getMockRouterProps } from '@/utils/mock-helper' +import { appsDataStub } from '@/sagas/__stubs__/apps' +import { + renderIsFeature, + renderForm, + handleCloseAppDeleteModal, + generateColumns, + renderCreatedAt, + renderDeleteAction, + refreshForm, + handleOnSubmit, + handleChangePage, + renderContent, + AdminApps, +} from '../admin-apps' +import Routes from '@/constants/routes' +import appState from '@/reducers/__stubs__/app-state' + +describe('admin-apps', () => { + describe('renderIsFeature', () => { + it('should run correctly', () => { + const mockDispatch = jest.fn() + const fn = renderIsFeature(mockDispatch) + const row = { original: { id: '123' } } + const cell = { value: '123' } + const wrapper = fn({ row, cell }) + expect(wrapper).toMatchSnapshot() + }) + }) + + describe('renderCreatedAt', () => { + it('should match snapshot', () => { + const cell = { value: '2020-01-01T00:00:00Z' } + const wrapper = shallow(
{renderCreatedAt({ cell })}
) + expect(wrapper).toMatchSnapshot() + }) + }) + + describe('renderDeleteAction', () => { + it('should render DeleteActions', () => { + const setDataDeleteModal = jest.fn() + const deleteModalData = { + visible: true, + appId: '123', + appName: '123', + developerName: '123', + } + const fn = renderDeleteAction({ deleteModalData, setDataDeleteModal }) + const row = { + original: { + id: '123', + appName: 'mockAppName', + }, + } + const wrapper = shallow(
{fn({ row })}
) + expect(wrapper).toMatchSnapshot() + }) + + it('should call delete action', () => { + const setDataDeleteModal = jest.fn() + const deleteModalData = { + visible: true, + appId: '123', + appName: '123', + developerName: '123', + } + const fn = renderDeleteAction({ deleteModalData, setDataDeleteModal }) + const row = { + original: { + id: '123', + appName: 'mockAppName', + }, + } + const wrapper = mount(
{fn({ row })}
) + const button = wrapper.find('button') + button.simulate('click') + expect(setDataDeleteModal).toBeCalled() + expect(wrapper).toMatchSnapshot() + }) + }) + + describe('generateColumns', () => { + it('should match snapshot', () => { + const dispatch = jest.fn() + const setDataDeleteModal = jest.fn() + const deleteModalData = { + visible: true, + appId: '123', + appName: '123', + developerName: '123', + } + const fn = generateColumns({ dispatch, setDataDeleteModal, deleteModalData }) + const wrapper = shallow(
{fn()}
) + expect(wrapper).toMatchSnapshot() + }) + }) + + describe('refreshForm', () => { + it('should return correctly', () => { + const onSubmit = jest.fn() + const resetForm = jest.fn() + const fn = refreshForm(onSubmit, resetForm) + fn() + expect(resetForm).toBeCalled() + expect(onSubmit).toBeCalled() + }) + }) + + describe('renderForm', () => { + it('should return correctly', () => { + const setFilter = jest.fn() + const fn = renderForm(setFilter)({ values: {}, resetForm: jest.fn() }) + expect(fn).toMatchSnapshot() + }) + }) + + describe('handleCloseAppDeleteModal', () => { + it('should return correctly', () => { + const mockProps = { + setDataDeleteModal: jest.fn(), + } + handleCloseAppDeleteModal(mockProps)() + expect(mockProps.setDataDeleteModal).toBeCalled() + }) + }) + + describe('handleOnSubmit', () => { + it('should run correctly', () => { + const mockRouter = getMockRouterProps({}) + const fn = handleOnSubmit(mockRouter.history, 1) + fn({ + appName: 'mockAppName', + companyName: 'mockCompanyName', + developerName: 'mockDeveloperName', + registeredFrom: '2020-10-01T00:00:00Z', + registeredTo: '2020-10-01T10:00:00Z', + }) + expect(mockRouter.history.push).toBeCalled() + }) + }) + + describe('handleChangePage', () => { + const mockRouter = getMockRouterProps({}) + const fn = handleChangePage(mockRouter.history) + fn(1) + expect(mockRouter.history.push).toBeCalled() + }) + + describe('renderContent', () => { + const mockProps = { + adminAppsData: appsDataStub, + columns: [ + { + Header: 'AppID', + accessor: 'id', + }, + { + Header: 'App Name', + accessor: 'name', + }, + { + Header: 'App Summary', + accessor: 'summary', + }, + { + Header: 'Developer Name', + accessor: 'developer', + }, + { + Header: 'Is Listed', + accessor: 'isListed', + }, + { + Header: 'Pending Revisions', + accessor: 'pendingRevisions', + }, + { + Header: 'Direct API', + accessor: 'isDirectApi', + }, + { + Header: 'Created', + accessor: 'created', + Cell: renderCreatedAt, + }, + ], + } + const wrapper = shallow(
{renderContent(mockProps)}
) + expect(wrapper).toMatchSnapshot() + }) + + describe('AdminApprovals', () => { + let store + beforeEach(() => { + const mockStore = configureStore() + store = mockStore(appState) + }) + it('should match a snapshot', () => { + expect( + mount( + + + + + , + ), + ).toMatchSnapshot() + }) + }) +}) diff --git a/packages/marketplace/src/components/pages/admin-apps/admin-apps.tsx b/packages/marketplace/src/components/pages/admin-apps/admin-apps.tsx new file mode 100644 index 0000000000..e4469b88d0 --- /dev/null +++ b/packages/marketplace/src/components/pages/admin-apps/admin-apps.tsx @@ -0,0 +1,297 @@ +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { useHistory, useLocation } from 'react-router' +import { Dispatch } from 'redux' +import { + Loader, + Pagination, + Table, + Button, + Alert, + Input, + H3, + Grid, + GridItem, + Formik, + Form, + FormSection, + FormHeading, + FormSubHeading, + Content, + FlexContainerBasic, + DatePicker, + toLocalTime, +} from '@reapit/elements' +import { selectAdminAppsData, selectAdminAppsLoading } from '@/selector/admin' +import { adminAppsRequestFeatured } from '@/actions/admin-apps' +import AppDeleteModal from '@/components/ui/app-delete' +import { addQuery, stringifyObjectIntoQueryString, getParamsFromPath } from '@/utils/client-url-params' +import styles from '@/styles/pages/admin-apps.scss?mod' + +export type DeleteModalData = { + visible: boolean + appId: string + appName: string + developerName: string +} + +export const renderIsFeature = (dispatch: Dispatch) => ({ row, cell }) => { + const { id } = row.original + const { value } = cell + return ( +
+ dispatch(adminAppsRequestFeatured({ id, isFeatured: evt.target.checked }))} + /> + +
+ ) +} + +export const renderCreatedAt = ({ cell: { value } }) => { + return

{toLocalTime(value)}

+} + +export type RenderDeleteActionParams = { + setDataDeleteModal: React.Dispatch> + deleteModalData: DeleteModalData +} + +export const renderDeleteAction = ({ setDataDeleteModal, deleteModalData }: RenderDeleteActionParams) => ({ row }) => ( + +) + +export type GenerateColumnsParams = RenderDeleteActionParams & { + dispatch: Dispatch +} + +export const generateColumns = ({ dispatch, setDataDeleteModal, deleteModalData }: GenerateColumnsParams) => () => { + return [ + { + Header: 'AppID', + accessor: 'id', + }, + { + Header: 'App Name', + accessor: 'name', + }, + { + Header: 'App Summary', + accessor: 'summary', + }, + { + Header: 'Company Name', + accessor: 'developer', + }, + { + Header: 'Is Listed', + accessor: 'isListed', + }, + { + Header: 'Pending Revisions', + accessor: 'pendingRevisions', + }, + { + Header: 'Direct API', + accessor: 'isDirectApi', + }, + { + Header: 'Created', + accessor: 'created', + Cell: renderCreatedAt, + }, + { + Header: 'Featured', + accessor: 'isFeatured', + Cell: renderIsFeature(dispatch), + }, + { + id: 'Delete', + Cell: renderDeleteAction({ setDataDeleteModal, deleteModalData }), + }, + ] +} + +export const refreshForm = (onSubmit: Function, resetForm: Function) => () => { + resetForm() + onSubmit({ appName: '', companyName: '', developerName: '' }) +} + +export const renderForm = onSubmit => ({ values, resetForm }) => { + const isDisabledSubmitButton = + !values.appName && !values.companyName && !values.developerName && !values.registeredFrom && !values.registeredTo + + const startDate = values.registeredFrom ? new Date(values.registeredFrom) : '' + const endDate = values.registeredTo ? new Date(values.registeredTo) : '' + + return ( +
+ + + Admin Apps Filter Form + Filter the result by App, Developer and Company + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ) +} + +export const handleCloseAppDeleteModal = ({ setDataDeleteModal }) => () => { + setDataDeleteModal({ visible: false, appId: '', appName: '' }) +} + +export type FormValues = { + appName: string + companyName: string + developerName: string + registeredFrom: string + registeredTo: string +} + +export const handleOnSubmit = (history, page: number) => (formValues: FormValues) => { + const submitValues = Object.keys(formValues).reduce((newObj, key) => { + const value = formValues[key] + if (value) { + newObj[key] = value + } + return newObj + }, {}) + const queryString = stringifyObjectIntoQueryString({ ...submitValues, page }) + history.push(`apps?${queryString}`) +} + +export const handleChangePage = history => (page: number) => { + history.push(addQuery({ page })) +} + +export const renderContent = ({ adminAppsData, columns }) => { + if (adminAppsData?.data && adminAppsData?.data?.length < 1) { + return + } + return ( +
+ + + ) +} + +export const AdminApps: React.FC = () => { + const [deleteModalData, setDataDeleteModal] = React.useState({ + visible: false, + appId: '', + appName: '', + developerName: '', + }) + const history = useHistory() + const location = useLocation() + const dispatch = useDispatch() + const loading = useSelector(selectAdminAppsLoading) + const adminAppsData = useSelector(selectAdminAppsData) + const queryParams = getParamsFromPath(location.search) as any + const page = parseInt(queryParams.page, 10) || 1 + const columns = React.useMemo(generateColumns({ dispatch, setDataDeleteModal, deleteModalData }), [ + adminAppsData?.data, + ]) + const formInitValues = { + ...queryParams, + registeredFrom: queryParams.registeredFrom || '', + registeredTo: queryParams.registeredTo || '', + } + + if (loading) { + return + } + + return ( +
+ +
+

App Management

+ + {renderForm(handleOnSubmit(history, page))} + +
+
+ + Total apps: {adminAppsData?.totalCount || 0} + + {renderContent({ adminAppsData, columns })} +
+ +
+ +
+ ) +} + +export default AdminApps diff --git a/packages/marketplace/src/components/pages/admin-apps/index.ts b/packages/marketplace/src/components/pages/admin-apps/index.ts new file mode 100644 index 0000000000..6278469365 --- /dev/null +++ b/packages/marketplace/src/components/pages/admin-apps/index.ts @@ -0,0 +1,3 @@ +import AdminApps from './admin-apps' + +export default AdminApps diff --git a/packages/marketplace/src/selector/__tests__/admin.ts b/packages/marketplace/src/selector/__tests__/admin.ts index 16cf294050..72b7945dd1 100644 --- a/packages/marketplace/src/selector/__tests__/admin.ts +++ b/packages/marketplace/src/selector/__tests__/admin.ts @@ -28,10 +28,10 @@ describe('admin', () => { expect(result).toEqual({ adminAppsData: appsDataStub.data, loading: false }) }) - it('should run correctly and return undefined', () => { + it('should run correctly and return {}', () => { const input = {} as ReduxState const result = selectAdminAppsState(input) - expect(result).toEqual(undefined) + expect(result).toEqual({}) }) }) @@ -40,10 +40,10 @@ describe('admin', () => { const result = selectAdminAppsData(mockState) expect(result).toEqual(mockState.adminApps.adminAppsData) }) - it('should run correctly and return undefined', () => { + it('should run correctly and return {}', () => { const input = {} as ReduxState const result = selectAdminAppsState(input) - expect(result).toEqual(undefined) + expect(result).toEqual({}) }) }) diff --git a/packages/marketplace/src/selector/admin.ts b/packages/marketplace/src/selector/admin.ts index 70c9197d6d..159e5c14a6 100644 --- a/packages/marketplace/src/selector/admin.ts +++ b/packages/marketplace/src/selector/admin.ts @@ -1,9 +1,14 @@ import { ReduxState } from '@/types/core' import { AdminApprovalsState } from '@/reducers/admin-approvals' import { PagedResultApprovalModel_ } from '@reapit/foundations-ts-definitions' +import { AdminAppsState } from '@/reducers/admin-apps' -export const selectAdminAppsState = (state: ReduxState) => { - return state.adminApps +export const selectAdminAppsState = (state: ReduxState): AdminAppsState => { + return state?.adminApps || {} +} + +export const selectAdminAppsLoading = (state: ReduxState): boolean => { + return !!state?.adminApps?.loading } export const selectAdminAppsData = (state: ReduxState) => {