Skip to content

Commit

Permalink
feat: #9933 admin portal app installs (#10487)
Browse files Browse the repository at this point in the history
* feat: added uninstall modal for uninstalling apps from admin portal

* feat: update snapshots

* feat: improved functionality of uninstall method

---------

Co-authored-by: Will McVay <[email protected]>
  • Loading branch information
bashleigh and willmcvay authored Jan 8, 2024
1 parent 50622cf commit 0520176
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,7 @@ exports[`Installations should render component with data 1`] = `
"
data-has-call-to-action="false"
data-has-expandable-action="true"
data-num-columns-excl-action-col="8"
data-num-columns-excl-action-col="9"
>
<mock-styled.div>
<mock-styled.div>
Expand All @@ -849,6 +849,9 @@ exports[`Installations should render component with data 1`] = `
<mock-styled.div>
Date Installed
</mock-styled.div>
<mock-styled.div>
Uninstall
</mock-styled.div>
<mock-styled.div>
Installed By
</mock-styled.div>
Expand Down Expand Up @@ -933,6 +936,18 @@ exports[`Installations should render component with data 1`] = `
23-03-2022
</mock-styled.div>
</mock-styled.div>
<mock-styled.div
classname="mock-css."
>
<mock-styled.div>
<mock-styled.button
classname="mock-css."
>
<mock-styled.div />
Uninstall
</mock-styled.button>
</mock-styled.div>
</mock-styled.div>
<mock-styled.div
classname="mock-css."
>
Expand Down Expand Up @@ -1280,7 +1295,7 @@ exports[`Installations should render component with data 1`] = `
"
data-has-call-to-action="false"
data-has-expandable-action="true"
data-num-columns-excl-action-col="8"
data-num-columns-excl-action-col="9"
>
<mock-styled.div>
<mock-styled.div>
Expand All @@ -1298,6 +1313,9 @@ exports[`Installations should render component with data 1`] = `
<mock-styled.div>
Date Installed
</mock-styled.div>
<mock-styled.div>
Uninstall
</mock-styled.div>
<mock-styled.div>
Installed By
</mock-styled.div>
Expand Down Expand Up @@ -1382,6 +1400,18 @@ exports[`Installations should render component with data 1`] = `
23-03-2022
</mock-styled.div>
</mock-styled.div>
<mock-styled.div
classname="mock-css."
>
<mock-styled.div>
<mock-styled.button
classname="mock-css."
>
<mock-styled.div />
Uninstall
</mock-styled.button>
</mock-styled.div>
</mock-styled.div>
<mock-styled.div
classname="mock-css."
>
Expand Down
35 changes: 35 additions & 0 deletions packages/admin-portal/src/components/installations/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { fetchCustomersList } from '../../services/customers'
import { usePermissionsState } from '../../core/use-permissions-state'
import { ToggleConsumption } from './toggle-consumption'
import debounce from 'just-debounce-it'
import { UninstallModal } from './uninstall-modal'

export interface InstallationFilters {
installedDateFrom?: string
Expand Down Expand Up @@ -87,6 +88,12 @@ export const Installations: FC = () => {
const [pageNumber, setPageNumber] = useState<number>(1)
const [pageSize, setPageSize] = useState<number>(12)
const [installIdConsumption, setInstallIdConsumption] = useState<string | null>(null)
const [selectedInstallation, setSelectedInstallation] = useState<
{ appId: string; installationId: string } | { appId: undefined; installationId: undefined }
>({
appId: undefined,
installationId: undefined,
})

const {
register,
Expand Down Expand Up @@ -213,6 +220,7 @@ export const Installations: FC = () => {
terminatesOn,
appName,
id,
appId,
}) => ({
cells: [
{
Expand Down Expand Up @@ -254,6 +262,22 @@ export const Installations: FC = () => {
showLabel: true,
},
},
{
label: 'Uninstall',
children: (
<Button
onClick={() =>
setSelectedInstallation({
installationId: id as string,
appId: appId as string,
})
}
intent="danger"
>
Uninstall
</Button>
),
},
{
label: 'Installed By',
value: installedBy,
Expand Down Expand Up @@ -308,6 +332,17 @@ export const Installations: FC = () => {
/>
</>
)}
<UninstallModal
appId={selectedInstallation.appId}
installationId={selectedInstallation.installationId}
onClose={() =>
setSelectedInstallation({
appId: undefined,
installationId: undefined,
})
}
installationRefresh={installationsRefresh}
/>
</PageContainer>
)
}
Expand Down
106 changes: 106 additions & 0 deletions packages/admin-portal/src/components/installations/uninstall-modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import React, { FC, useState } from 'react'
import { BodyText, Button, ButtonGroup, FormLayout, InputGroup, InputWrapFull, Modal } from '@reapit/elements'
import { useForm } from 'react-hook-form'
import { UpdateActionNames, updateActions, useReapitUpdate } from '@reapit/use-reapit-data'
import { reapitConnectBrowserSession } from '../../core/connect-session'
import { TerminateInstallationModel } from '@reapit/foundations-ts-definitions'
import { useReapitConnect } from '@reapit/connect-session'
import { SchemaOf, object, string } from 'yup'
import { hasSpecialChars } from '@reapit/utils-common'
import { yupResolver } from '@hookform/resolvers/yup'

const uninstallAppSchema: SchemaOf<Pick<TerminateInstallationModel, 'terminatedReason'>> = object().shape({
terminatedReason: string()
.trim()
.required('Required')
.min(10, 'Must be a minimum of 10 characters')
.test({
name: 'hasNoSpecialChars',
message: 'Special characters are not permitted',
test: (value?: string) => {
if (!value) return true
return !hasSpecialChars(value)
},
}),
})

export const UninstallModal: FC<{
installationId: string | undefined
appId: string | undefined
onClose: () => void
installationRefresh: () => void
}> = ({ installationId, appId, onClose, installationRefresh }) => {
const [uninstalling, setUninstalling] = useState<boolean>(false)
const { connectSession } = useReapitConnect(reapitConnectBrowserSession)

const [, , uninstallApp] = useReapitUpdate<TerminateInstallationModel, null>({
reapitConnectBrowserSession,
action: updateActions[UpdateActionNames.terminateInstallation],
uriParams: {
installationId,
},
})

const uninstallAction = async ({ terminatedReason }: { terminatedReason: string }) => {
setUninstalling(true)
const result = await uninstallApp({
appId: appId as string,
terminatedBy: connectSession?.loginIdentity.email,
terminatedReason,
terminatesOn: new Date().toISOString(),
})
setUninstalling(false)

console.log('result', result)

if (result) {
installationRefresh()
onClose()
}
}

const {
handleSubmit,
formState: { errors },
register,
reset,
} = useForm({
resolver: yupResolver(uninstallAppSchema),
defaultValues: {
terminatedReason: '',
},
})

return (
<Modal
isOpen={appId !== undefined && installationId !== undefined}
onModalClose={() => {
if (!uninstalling) {
reset()
onClose()
}
}}
title="Confirm Uninstallation"
>
<BodyText>Please provide a reason for terminating this installation</BodyText>
<form onSubmit={handleSubmit(uninstallAction)}>
<FormLayout hasMargin>
<InputWrapFull>
<InputGroup
label="Uninstallation Reason"
type="text"
{...register('terminatedReason')}
inputAddOnText={errors.terminatedReason?.message}
intent="danger"
/>
</InputWrapFull>
</FormLayout>
<ButtonGroup alignment="right">
<Button disabled={uninstalling} loading={uninstalling} intent="danger" type="submit">
Uninstall
</Button>
</ButtonGroup>
</form>
</Modal>
)
}

0 comments on commit 0520176

Please sign in to comment.