Skip to content

Commit

Permalink
fix(DHIS2-13915): show spinner when an app is being installed
Browse files Browse the repository at this point in the history
  • Loading branch information
kabaros committed Dec 14, 2023
1 parent 25af502 commit e03a200
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 41 deletions.
4 changes: 4 additions & 0 deletions src/components/AppDetails/AppDetails.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,7 @@
.downloadLink {
text-decoration: none;
}

.tableActions {
display: flex;
}
35 changes: 24 additions & 11 deletions src/components/AppDetails/ManageInstalledVersion.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useAlert, useConfig } from '@dhis2/app-runtime'
import i18n from '@dhis2/d2-i18n'
import PropTypes from 'prop-types'
import { Button, CircularLoader } from '@dhis2/ui'

Check failure on line 4 in src/components/AppDetails/ManageInstalledVersion.js

View workflow job for this annotation

GitHub Actions / lint

`@dhis2/ui` import should occur before import of `prop-types`
import React from 'react'
import React, { useState } from 'react'
import semver from 'semver'
import { useApi } from '../../api.js'
import { getLatestVersion } from '../../get-latest-version.js'
Expand Down Expand Up @@ -41,8 +41,12 @@ export const ManageInstalledVersion = ({
const { installVersion, uninstallApp } = useApi()
const successAlert = useAlert(({ message }) => message, { success: true })
const errorAlert = useAlert(({ message }) => message, { critical: true })

const [isInstalling, setIsInstalling] = useState(false)

const handleInstall = async () => {
try {
setIsInstalling(true)
await installVersion(latestVersion.id)
successAlert.show({
message: canUpdate
Expand All @@ -54,14 +58,16 @@ export const ManageInstalledVersion = ({
errorAlert.show({
message: canUpdate
? i18n.t('Failed to update app: {{errorMessage}}', {
errorMessage: error.message,
nsSeparator: '-:-',
})
errorMessage: error.message,
nsSeparator: '-:-',
})
: i18n.t('Failed to install app: {{errorMessage}}', {
errorMessage: error.message,
nsSeparator: '-:-',
}),
errorMessage: error.message,
nsSeparator: '-:-',
}),
})
} finally {
setIsInstalling(false)
}
}
const handleUninstall = async () => {
Expand All @@ -81,6 +87,10 @@ export const ManageInstalledVersion = ({
}
}

const installButtonText = isInstalling ? i18n.t('Installing...') : canUpdate
? i18n.t('Update to latest version')
: i18n.t('Install')

return (
<div className={styles.manageInstalledVersion}>
{!hasCompatibleVersions && (
Expand All @@ -92,10 +102,13 @@ export const ManageInstalledVersion = ({
)}
{hasCompatibleVersions && canInstall && (
<>
<Button primary onClick={handleInstall}>
{canUpdate
? i18n.t('Update to latest version')
: i18n.t('Install')}
<Button
primary
onClick={handleInstall}
disabled={isInstalling}
icon={isInstalling ? <CircularLoader small /> : null}
>
{installButtonText}
</Button>
<span className={styles.manageInstalledVersionDescription}>
{i18n.t('{{channel}} release {{version}}', {
Expand Down
55 changes: 25 additions & 30 deletions src/components/AppDetails/Versions.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ const VersionsTable = ({
<TableBody>
{versions.map((version) => {
const isVersionInstalling = versionBeingInstalled === version.id
const installButtonText = isVersionInstalling ? i18n.t('Installing...')
: version.version === installedVersion
? i18n.t('Installed')
: i18n.t('Install')
return (
<TableRow key={version.id} dataTest="versions-table-row">
<TableCell>{version.version}</TableCell>
Expand All @@ -120,37 +124,28 @@ const VersionsTable = ({
{moment(version.created).format('ll')}
</TableCell>
<TableCell>
<Button
small
secondary
className={styles.installBtn}
disabled={
version.version === installedVersion ||
versionBeingInstalled
}
onClick={() => onVersionInstall(version)}
>
{isVersionInstalling && (
<>
{i18n.t('Installing...')}
<CircularLoader small />
</>
)}
{!isVersionInstalling
? version.version === installedVersion
? i18n.t('Installed')
: i18n.t('Install')
: ''}
</Button>
<a
download
href={version.downloadUrl}
className={styles.downloadLink}
>
<Button small secondary>
{i18n.t('Download')}
<div className={styles.tableActions}>
<Button
small
secondary
className={styles.installBtn}
disabled={version.version === installedVersion ||
!!versionBeingInstalled}
onClick={() => onVersionInstall(version)}
icon={isVersionInstalling ? <CircularLoader small /> : null}
>
{installButtonText}
</Button>
</a>
<a
download
href={version.downloadUrl}
className={styles.downloadLink}
>
<Button small secondary>
{i18n.t('Download')}
</Button>
</a>
</div>
</TableCell>
</TableRow>
)
Expand Down
4 changes: 4 additions & 0 deletions src/pages/AppHubApp/AppHubApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ export const AppHubApp = ({ match }) => {
</NoticeBox>
)
}

// ToDo: This check here is the cause of the bug https://dhis2.atlassian.net/browse/DHIS2-15586
// custom apps seem to not have an app_hub_id, when these are surfaced then this should be resolved
// otherwise we need to find a different way to match the app ( || app.name === appHubApp.name would work but not reliable)
const installedApp = installedApps.find(
(app) => app.app_hub_id === appHubId
)
Expand Down

0 comments on commit e03a200

Please sign in to comment.