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 15, 2023
1 parent e58a863 commit 7e2ae44
Show file tree
Hide file tree
Showing 9 changed files with 4,274 additions and 5,012 deletions.
2 changes: 1 addition & 1 deletion src/components/AppDetails/AppDetails.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import i18n from '@dhis2/d2-i18n'
import PropTypes from 'prop-types'
import { Card, Divider } from '@dhis2/ui'
import moment from 'moment'
import PropTypes from 'prop-types'
import React, { useState } from 'react'
import { getAppIconSrc } from '../../get-app-icon-src.js'
import { getLatestVersion } from '../../get-latest-version.js'
Expand Down
27 changes: 21 additions & 6 deletions src/components/AppDetails/ManageInstalledVersion.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useAlert, useConfig } from '@dhis2/app-runtime'
import i18n from '@dhis2/d2-i18n'
import PropTypes from 'prop-types'
import { Button, CircularLoader } from '@dhis2/ui'
import React from 'react'
import PropTypes from 'prop-types'
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 @@ -62,6 +66,8 @@ export const ManageInstalledVersion = ({
nsSeparator: '-:-',
}),
})
} finally {
setIsInstalling(false)
}
}
const handleUninstall = async () => {
Expand All @@ -81,6 +87,12 @@ 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 +104,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
65 changes: 34 additions & 31 deletions src/components/AppDetails/Versions.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useAlert, useConfig } from '@dhis2/app-runtime'
import i18n from '@dhis2/d2-i18n'
import PropTypes from 'prop-types'
import {
Checkbox,
CircularLoader,
Expand All @@ -12,8 +11,10 @@ import {
TableBody,
TableRow,
TableCell,
ButtonStrip,
} from '@dhis2/ui'
import moment from 'moment'
import PropTypes from 'prop-types'
import React, { useState } from 'react'
import semver from 'semver'
import { useApi } from '../../api.js'
Expand Down Expand Up @@ -110,6 +111,11 @@ 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 +126,34 @@ 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')}
<ButtonStrip>
<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>
</ButtonStrip>
</TableCell>
</TableRow>
)
Expand Down
2 changes: 1 addition & 1 deletion src/components/AppsList/AppsList.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import i18n from '@dhis2/d2-i18n'
import PropTypes from 'prop-types'
import { InputField } from '@dhis2/ui'
import PropTypes from 'prop-types'
import React from 'react'
import { useHistory } from 'react-router-dom'
import { useQueryParam, StringParam, withDefault } from 'use-query-params'
Expand Down
2 changes: 1 addition & 1 deletion src/components/Sidebar/Sidebar.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useConfig } from '@dhis2/app-runtime'
import i18n from '@dhis2/d2-i18n'
import PropTypes from 'prop-types'
import { Menu, MenuItem } from '@dhis2/ui'
import PropTypes from 'prop-types'
import React from 'react'
import { useHistory, useRouteMatch } from 'react-router-dom'
import styles from './Sidebar.module.css'
Expand Down
2 changes: 1 addition & 1 deletion src/pages/AppHub/AppHub.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { useConfig, useDataQuery } from '@dhis2/app-runtime'
import i18n from '@dhis2/d2-i18n'
import PropTypes from 'prop-types'
import {
InputField,
Pagination,
NoticeBox,
CenteredContent,
CircularLoader,
} from '@dhis2/ui'
import PropTypes from 'prop-types'
import React, { useEffect } from 'react'
import { useHistory } from 'react-router-dom'
import { useDebounce } from 'use-debounce'
Expand Down
6 changes: 5 additions & 1 deletion src/pages/AppHubApp/AppHubApp.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useDataQuery } from '@dhis2/app-runtime'
import i18n from '@dhis2/d2-i18n'
import PropTypes from 'prop-types'
import { NoticeBox, CenteredContent, CircularLoader } from '@dhis2/ui'
import PropTypes from 'prop-types'
import React from 'react'
import { useHistory } from 'react-router-dom'
import { AppDetails } from '../../components/AppDetails/AppDetails.js'
Expand Down 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
2 changes: 1 addition & 1 deletion src/pages/InstalledApp/InstalledApp.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useDataQuery } from '@dhis2/app-runtime'
import i18n from '@dhis2/d2-i18n'
import PropTypes from 'prop-types'
import { NoticeBox, CenteredContent, CircularLoader } from '@dhis2/ui'
import PropTypes from 'prop-types'
import React from 'react'
import { useHistory } from 'react-router-dom'
import { AppDetails } from '../../components/AppDetails/AppDetails.js'
Expand Down
Loading

0 comments on commit 7e2ae44

Please sign in to comment.