Skip to content

Commit e9610d5

Browse files
committed
feat: add page for App Hub app
1 parent 9a6d68f commit e9610d5

File tree

8 files changed

+121
-69
lines changed

8 files changed

+121
-69
lines changed

i18n/en.pot

+11-8
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ msgstr ""
55
"Content-Type: text/plain; charset=utf-8\n"
66
"Content-Transfer-Encoding: 8bit\n"
77
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
8-
"POT-Creation-Date: 2021-03-24T20:15:27.415Z\n"
9-
"PO-Revision-Date: 2021-03-24T20:15:27.415Z\n"
8+
"POT-Creation-Date: 2021-03-24T22:33:00.378Z\n"
9+
"PO-Revision-Date: 2021-03-24T22:33:00.378Z\n"
1010

1111
msgid "App uninstalled successfully"
1212
msgstr ""
@@ -101,9 +101,18 @@ msgstr ""
101101
msgid "Manual install"
102102
msgstr ""
103103

104+
msgid "Search AppHub apps"
105+
msgstr ""
106+
104107
msgid "Something went wrong whilst loading App Hub apps"
105108
msgstr ""
106109

110+
msgid "Error loading app"
111+
msgstr ""
112+
113+
msgid "App not found"
114+
msgstr ""
115+
107116
msgid "Something went wrong whilst loading your core apps"
108117
msgstr ""
109118

@@ -128,12 +137,6 @@ msgstr ""
128137
msgid "Search installed custom apps"
129138
msgstr ""
130139

131-
msgid "Error loading app"
132-
msgstr ""
133-
134-
msgid "App not found"
135-
msgstr ""
136-
137140
msgid "Uploading..."
138141
msgstr ""
139142

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"@dhis2/prop-types": "^2.0.3",
4242
"@dhis2/ui": "^6.5.5",
4343
"moment": "2.24",
44-
"query-string": "^7.0.0",
44+
"query-string": "6",
4545
"react-router-dom": "^5.2.0",
4646
"semver": "^7.3.4",
4747
"use-debounce": "^6.0.0",

src/App.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,13 @@ import { QueryParamProvider } from 'use-query-params'
55
import styles from './App.module.css'
66
import { Sidebar } from './components/Sidebar/Sidebar'
77
import { AppHub } from './pages/AppHub/AppHub'
8+
import { AppHubApp } from './pages/AppHubApp/AppHubApp'
89
import { CoreApps } from './pages/CoreApps/CoreApps'
910
import { CustomApps } from './pages/CustomApps/CustomApps'
1011
import { InstalledApp } from './pages/InstalledApp/InstalledApp'
1112
import { ManualInstall } from './pages/ManualInstall/ManualInstall'
1213
import './locales'
1314

14-
// XXX
15-
const AppHubApp = () => null
16-
1715
const App = () => (
1816
<HashRouter>
1917
<QueryParamProvider

src/components/AppCard/AppIcon/AppIcon.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const FallbackIcon = () => (
1717

1818
export const AppIcon = ({ src }) => (
1919
<div className={styles.appIcon}>
20-
{src ? <img src={src} /> : <FallbackIcon />}
20+
{src ? <img src={src} loading="lazy" /> : <FallbackIcon />}
2121
</div>
2222
)
2323

src/components/AppDetails/AppDetails.js

+16-15
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { Versions } from './Versions'
1313

1414
const ManageInstalledVersion = ({
1515
installedApp,
16-
versions,
16+
versions = [],
1717
onVersionInstall,
1818
onUninstall,
1919
}) => {
@@ -56,10 +56,13 @@ const ManageInstalledVersion = ({
5656

5757
return (
5858
<div className={styles.manageInstalledVersion}>
59-
{latestVersion && semverGt(latestVersion, installedApp.version) && (
59+
{latestVersion && (
6060
<>
6161
<Button primary onClick={handleUpdate}>
62-
{i18n.t('Update to latest version')}
62+
{installedApp &&
63+
semverGt(latestVersion, installedApp.version)
64+
? i18n.t('Update to latest version')
65+
: i18n.t('Install')}
6366
</Button>
6467
<span className={styles.manageInstalledVersionDescription}>
6568
{i18n.t('{{channel}} release {{version}}', {
@@ -70,7 +73,7 @@ const ManageInstalledVersion = ({
7073
</span>
7174
</>
7275
)}
73-
{!installedApp.bundled && (
76+
{installedApp && !installedApp.bundled && (
7477
<Button secondary onClick={handleUninstall}>
7578
{i18n.t('Uninstall')}
7679
</Button>
@@ -180,7 +183,7 @@ export const AppDetails = ({
180183
<h1 className={styles.headerName}>{appName}</h1>
181184
{appDeveloper && (
182185
<span className={styles.headerDeveloper}>
183-
{i18n.t('by {{developer}}', {
186+
{i18n.t('by {{- developer}}', {
184187
developer: appDeveloper,
185188
context: 'developer of application',
186189
})}
@@ -206,15 +209,13 @@ export const AppDetails = ({
206209
</div>
207210
)}
208211
<div>
209-
{installedApp && (
210-
<ManageInstalledVersion
211-
installedApp={installedApp}
212-
versions={appHubApp?.versions || []}
213-
onVersionInstall={onVersionInstall}
214-
onUninstall={onUninstall}
215-
/>
216-
)}
217-
{appHubApp && (
212+
<ManageInstalledVersion
213+
installedApp={installedApp}
214+
versions={appHubApp?.versions}
215+
onVersionInstall={onVersionInstall}
216+
onUninstall={onUninstall}
217+
/>
218+
{installedApp && appHubApp && (
218219
<div>
219220
<h2 className={styles.sectionHeader}>
220221
{i18n.t('Additional information')}
@@ -248,7 +249,7 @@ export const AppDetails = ({
248249
)}
249250
</h2>
250251
<Versions
251-
installedVersion={installedApp.version}
252+
installedVersion={installedApp?.version}
252253
versions={appHubApp.versions}
253254
onVersionInstall={onVersionInstall}
254255
/>

src/components/AppDetails/Versions.js

+13-5
Original file line numberDiff line numberDiff line change
@@ -188,11 +188,19 @@ export const Versions = ({ installedVersion, versions, onVersionInstall }) => {
188188
channelsFilter={channelsFilter}
189189
setChannelsFilter={setChannelsFilter}
190190
/>
191-
<VersionsTable
192-
installedVersion={installedVersion}
193-
versions={filteredVersions}
194-
onVersionInstall={handleVersionInstall}
195-
/>
191+
{filteredVersions.length > 0 ? (
192+
<VersionsTable
193+
installedVersion={installedVersion}
194+
versions={filteredVersions}
195+
onVersionInstall={handleVersionInstall}
196+
/>
197+
) : (
198+
<em>
199+
{i18n.t(
200+
'There are no compatible versions matching your criteria'
201+
)}
202+
</em>
203+
)}
196204
</div>
197205
)
198206
}

src/pages/AppHubApp/AppHubApp.js

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { useDataQuery } from '@dhis2/app-runtime'
2+
import i18n from '@dhis2/d2-i18n'
3+
import { PropTypes } from '@dhis2/prop-types'
4+
import { NoticeBox, CenteredContent, CircularLoader } from '@dhis2/ui'
5+
import React from 'react'
6+
import { useHistory } from 'react-router-dom'
7+
import { AppDetails } from '../../components/AppDetails/AppDetails'
8+
import { coreApps } from '../../core-apps'
9+
10+
const query = {
11+
appHubApp: {
12+
resource: 'appHub/v1/apps',
13+
id: ({ appHubId }) => appHubId,
14+
},
15+
installedApps: {
16+
resource: 'apps',
17+
},
18+
}
19+
20+
export const AppHubApp = ({ match }) => {
21+
const { appHubId } = match.params
22+
const history = useHistory()
23+
const { loading, error, data, refetch } = useDataQuery(query, {
24+
variables: { appHubId },
25+
})
26+
27+
if (error) {
28+
return (
29+
<NoticeBox error title={i18n.t('Error loading app')}>
30+
{error.message}
31+
</NoticeBox>
32+
)
33+
}
34+
35+
if (loading) {
36+
return (
37+
<CenteredContent>
38+
<CircularLoader />
39+
</CenteredContent>
40+
)
41+
}
42+
43+
const { appHubApp, installedApps } = data
44+
if (!appHubApp) {
45+
return (
46+
<NoticeBox error title={i18n.t('Error loading app')}>
47+
{i18n.t('App not found')}
48+
</NoticeBox>
49+
)
50+
}
51+
const installedApp = installedApps.find(app => app.app_hub_id === appHubId)
52+
53+
return (
54+
<AppDetails
55+
installedApp={installedApp}
56+
appHubApp={appHubApp}
57+
onVersionInstall={refetch}
58+
onUninstall={() => history.push('/app-hub')}
59+
/>
60+
)
61+
}
62+
63+
AppHubApp.propTypes = {
64+
match: PropTypes.object.isRequired,
65+
}

yarn.lock

+13-36
Original file line numberDiff line numberDiff line change
@@ -1125,14 +1125,7 @@
11251125
dependencies:
11261126
regenerator-runtime "^0.13.4"
11271127

1128-
"@babel/runtime@^7.1.2":
1129-
version "7.12.13"
1130-
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.13.tgz#0a21452352b02542db0ffb928ac2d3ca7cb6d66d"
1131-
integrity sha512-8+3UMPBrjFa/6TtKi/7sehPKqfAm4g6K+YQjyyFOLUTxzOngcRZTlAVY8sc2CORJYqdHQY8gRPHmn+qo15rCBw==
1132-
dependencies:
1133-
regenerator-runtime "^0.13.4"
1134-
1135-
"@babel/runtime@^7.10.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4":
1128+
"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4":
11361129
version "7.13.7"
11371130
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.7.tgz#d494e39d198ee9ca04f4dcb76d25d9d7a1dc961a"
11381131
integrity sha512-h+ilqoX998mRVM5FtB5ijRuHUDVt5l3yfoOi2uh18Z/O3hvyaHQ39NpxVkCIG5yFs+mLq/ewFp8Bss6zmWv6ZA==
@@ -4466,12 +4459,7 @@ core-js@^2.4.0:
44664459
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
44674460
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
44684461

4469-
core-js@^3.6.1:
4470-
version "3.8.3"
4471-
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.8.3.tgz#c21906e1f14f3689f93abcc6e26883550dd92dd0"
4472-
integrity sha512-KPYXeVZYemC2TkNEkX/01I+7yd+nX3KddKwZ1Ww7SKWdI2wQprSgLmrTddT8nw92AjEklTsPBoSdQBhbI1bQ6Q==
4473-
4474-
core-js@^3.6.5:
4462+
core-js@^3.6.1, core-js@^3.6.5:
44754463
version "3.9.0"
44764464
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.9.0.tgz#790b1bb11553a2272b36e2625c7179db345492f8"
44774465
integrity sha512-PyFBJaLq93FlyYdsndE5VaueA9K5cNB7CGzeCj191YYLhkQM0gdZR2SKihM70oF0wdqKSKClv/tEBOpoRmdOVQ==
@@ -8540,11 +8528,6 @@ [email protected]:
85408528
import-local "^3.0.2"
85418529
jest-cli "^26.6.0"
85428530

8543-
js-tokens@^3.0.0:
8544-
version "3.0.2"
8545-
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
8546-
integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=
8547-
85488531
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
85498532
version "4.0.0"
85508533
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@@ -9015,19 +8998,13 @@ loglevel@^1.6.8:
90158998
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197"
90168999
integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==
90179000

9018-
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.4.0:
9001+
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
90199002
version "1.4.0"
90209003
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
90219004
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
90229005
dependencies:
90239006
js-tokens "^3.0.0 || ^4.0.0"
90249007

9025-
loose-envify@^1.3.1:
9026-
version "1.3.1"
9027-
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
9028-
dependencies:
9029-
js-tokens "^3.0.0"
9030-
90319008
lower-case@^2.0.2:
90329009
version "2.0.2"
90339010
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28"
@@ -11207,6 +11184,16 @@ qs@~6.5.2:
1120711184
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
1120811185
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
1120911186

11187+
query-string@6:
11188+
version "6.14.1"
11189+
resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a"
11190+
integrity sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==
11191+
dependencies:
11192+
decode-uri-component "^0.2.0"
11193+
filter-obj "^1.1.0"
11194+
split-on-first "^1.0.0"
11195+
strict-uri-encode "^2.0.0"
11196+
1121011197
query-string@^4.1.0:
1121111198
version "4.3.4"
1121211199
resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb"
@@ -11215,16 +11202,6 @@ query-string@^4.1.0:
1121511202
object-assign "^4.1.0"
1121611203
strict-uri-encode "^1.0.0"
1121711204

11218-
query-string@^7.0.0:
11219-
version "7.0.0"
11220-
resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.0.0.tgz#aaad2c8d5c6a6d0c6afada877fecbd56af79e609"
11221-
integrity sha512-Iy7moLybliR5ZgrK/1R3vjrXq03S13Vz4Rbm5Jg3EFq1LUmQppto0qtXz4vqZ386MSRjZgnTSZ9QC+NZOSd/XA==
11222-
dependencies:
11223-
decode-uri-component "^0.2.0"
11224-
filter-obj "^1.1.0"
11225-
split-on-first "^1.0.0"
11226-
strict-uri-encode "^2.0.0"
11227-
1122811205
querystring-es3@^0.2.0:
1122911206
version "0.2.1"
1123011207
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"

0 commit comments

Comments
 (0)