Skip to content

Commit

Permalink
refactor: use data store provider and hook
Browse files Browse the repository at this point in the history
  • Loading branch information
edoardo committed Sep 21, 2023
1 parent be99a6f commit 8ca2dcf
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 96 deletions.
4 changes: 2 additions & 2 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"POT-Creation-Date: 2023-09-21T12:59:04.507Z\n"
"PO-Revision-Date: 2023-09-21T12:59:04.507Z\n"
"POT-Creation-Date: 2023-09-21T15:10:01.535Z\n"
"PO-Revision-Date: 2023-09-21T15:10:01.535Z\n"

msgid "Version {{version}} installed"
msgstr "Version {{version}} installed"
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
},
"dependencies": {
"@dhis2/app-runtime": "^3.2.0",
"@dhis2/app-service-datastore": "^1.0.0-beta.3",
"@dhis2/d2-i18n": "^1.1.0",
"@dhis2/prop-types": "^2.0.3",
"@dhis2/ui": "^7.2.0",
Expand Down
11 changes: 9 additions & 2 deletions src/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,18 @@ class Api {
return res
})

installVersion = (versionId, userGroupId) =>
installVersion = (versionId, userGroupId) => {
let url = `appHub/${versionId}`

if (userGroupId) {
url += `?group=${userGroupId}`
}

this.request({
url: `appHub/${versionId}?group=${userGroupId}`,
url,
method: 'post',
})
}

uninstallApp = (appKey) =>
this.request({
Expand Down
194 changes: 110 additions & 84 deletions src/components/AppDetails/Versions.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useAlert, useConfig, useDataQuery } from '@dhis2/app-runtime'
import { useAlert, useConfig } from '@dhis2/app-runtime'
import { useSavedObject } from '@dhis2/app-service-datastore'
import i18n from '@dhis2/d2-i18n'
import { PropTypes } from '@dhis2/prop-types'
import {
Expand Down Expand Up @@ -93,26 +94,13 @@ const VersionsTable = ({
versions,
onVersionInstall,
userGroups,
appId,
userGroupVersionMapFromDS,
}) => {
const [userGroupVersionMap, setUserGroupVersionMap] = useReducer(
(map, newMap) => ({ ...map, ...newMap }),
{}
userGroupVersionMapFromDS
)

const dataStoreQuery = {
groupVersions: {
resource: 'dataStore/app-management/' + appId,

}
};

const { data: { groupVersions: dataStoreGroupVersions = {} } = {}, loading } = useDataQuery(dataStoreQuery);

if (loading) {
return null;
}

return (
<Table>
<TableHead>
Expand All @@ -130,63 +118,75 @@ const VersionsTable = ({
</TableHead>
<TableBody>
{versions.map((version) => {
const versionActiveForUserGroup = Object
.entries(dataStoreGroupVersions)
?.find(([, dataStoreVersion]) => dataStoreVersion === version.version)
?.[0];
const versionActiveForUserGroup = Object.entries(
userGroupVersionMapFromDS || {}
)?.find(
([, dataStoreVersion]) =>
dataStoreVersion === version.version
)?.[0]

return (
<TableRow key={version.id}>
<TableCell>{version.version}</TableCell>
<TableCell>
{channelToDisplayName[version.channel]}
</TableCell>
<TableCell>
{moment(version.created).format('ll')}
</TableCell>
<TableCell>
<UserGroupSelector
userGroups={userGroups}
version={version.version}
onSelect={setUserGroupVersionMap}
versionActiveForUserGroup={versionActiveForUserGroup}
isInstalled={version.version === installedVersion}
/>
</TableCell>
<TableCell>
<Button
small
secondary
className={styles.installBtn}
disabled={version.version === installedVersion || versionActiveForUserGroup}
onClick={() =>
onVersionInstall(
version,
Object.keys(userGroupVersionMap).find(
(userGroupId) =>
userGroupVersionMap[
userGroupId
] === version.version
<TableRow key={version.id}>
<TableCell>{version.version}</TableCell>
<TableCell>
{channelToDisplayName[version.channel]}
</TableCell>
<TableCell>
{moment(version.created).format('ll')}
</TableCell>
<TableCell>
<UserGroupSelector
userGroups={userGroups}
version={version.version}
onSelect={setUserGroupVersionMap}
versionActiveForUserGroup={
versionActiveForUserGroup
}
isInstalled={
version.version === installedVersion
}
/>
</TableCell>
<TableCell>
<Button
small
secondary
className={styles.installBtn}
disabled={
version.version === installedVersion ||
versionActiveForUserGroup
}
onClick={() =>
onVersionInstall(
version,
Object.keys(
userGroupVersionMap
).find(
(userGroupId) =>
userGroupVersionMap[
userGroupId
] === version.version
)
)
)
}
>
{version.version === installedVersion || versionActiveForUserGroup
? i18n.t('Installed')
: i18n.t('Install')}
</Button>
<a
download
href={version.downloadUrl}
className={styles.downloadLink}
>
<Button small secondary>
{i18n.t('Download')}
}
>
{version.version === installedVersion ||
versionActiveForUserGroup
? i18n.t('Installed')
: i18n.t('Install')}
</Button>
</a>
</TableCell>
</TableRow>
)
<a
download
href={version.downloadUrl}
className={styles.downloadLink}
>
<Button small secondary>
{i18n.t('Download')}
</Button>
</a>
</TableCell>
</TableRow>
)
})}
</TableBody>
</Table>
Expand All @@ -198,7 +198,7 @@ VersionsTable.propTypes = {
versions: PropTypes.array.isRequired,
onVersionInstall: PropTypes.func.isRequired,
installedVersion: PropTypes.string,
appId: PropTypes.string,
userGroupVersionMapFromDS: PropTypes.object,
}

export const Versions = ({
Expand All @@ -221,6 +221,9 @@ export const Versions = ({
{ critical: true }
)
const { serverVersion } = useConfig()
const [userGroupVersionMap, { replace }] = useSavedObject(appId, {
global: true,
}) // XXX
const { installVersion } = useApi()
const dhisVersion = semver.coerce(
`${serverVersion.major}.${serverVersion.minor}`
Expand All @@ -245,8 +248,20 @@ export const Versions = ({
.filter(satisfiesDhisVersion)
const handleVersionInstall = async (version, userGroupId) => {
try {
await installVersion(version.id, userGroupId)
await installVersion(
version.id,
userGroupId !== 'all' ? userGroupId : undefined
)
installSuccessAlert.show()

if (userGroupId !== 'all') {
// TODO merge with existing object
replace({
...userGroupVersionMap,
...{ [userGroupId]: version.version },
})
}

onVersionInstall()
} catch (error) {
installErrorAlert.show({ error })
Expand All @@ -266,6 +281,7 @@ export const Versions = ({
versions={filteredVersions}
onVersionInstall={handleVersionInstall}
userGroups={userGroups}
userGroupVersionMapFromDS={userGroupVersionMap}
appId={appId}
/>
) : (
Expand All @@ -280,14 +296,22 @@ export const Versions = ({
}

Versions.propTypes = {
appId: PropTypes.string.isRequired,
userGroups: PropTypes.array.isRequired,
versions: PropTypes.array.isRequired,
onVersionInstall: PropTypes.func.isRequired,
installedVersion: PropTypes.string,
}

const UserGroupSelector = ({ userGroups, version, onSelect, versionActiveForUserGroup, isInstalled }) => {
const [userGroup, setUserGroup] = useState('all')
const UserGroupSelector = ({
userGroups,
version,
onSelect,
versionActiveForUserGroup,
isInstalled,
}) => {
const DEFAULT_USER_GROUP_ID = 'all'
const [userGroup, setUserGroup] = useState(DEFAULT_USER_GROUP_ID)

const onChange = ({ selected }) => {
setUserGroup(selected)
Expand All @@ -296,26 +320,27 @@ const UserGroupSelector = ({ userGroups, version, onSelect, versionActiveForUser
}

if (versionActiveForUserGroup || isInstalled) {
const { displayName, id } = versionActiveForUserGroup ?
userGroups.find(group => group.id === versionActiveForUserGroup) : { displayName: 'All user groups', id: 'ALL' };
const { displayName, id } = versionActiveForUserGroup
? userGroups.find((group) => group.id === versionActiveForUserGroup)
: { displayName: 'All user groups', id: DEFAULT_USER_GROUP_ID }

return (
<SingleSelect dense selected={versionActiveForUserGroup || 'ALL'} disabled>
<SingleSelectOption
dense
label={displayName}
value={id}
/>
<SingleSelect
dense
selected={versionActiveForUserGroup || DEFAULT_USER_GROUP_ID}
disabled
>
<SingleSelectOption dense label={displayName} value={id} />
</SingleSelect>
);
)
}

return (
<SingleSelect dense selected={userGroup} onChange={onChange}>
<SingleSelectOption
dense
label={i18n.t('All user groups')}
value="all"
value={DEFAULT_USER_GROUP_ID}
/>
{userGroups.map((group) => (
<SingleSelectOption
Expand All @@ -332,6 +357,7 @@ const UserGroupSelector = ({ userGroups, version, onSelect, versionActiveForUser
UserGroupSelector.propTypes = {
userGroups: PropTypes.array.isRequired,
version: PropTypes.string.isRequired,
onSelect: PropTypes.func,
isInstalled: PropTypes.bool,
versionActiveForUserGroup: PropTypes.string,
onSelect: PropTypes.func,
}
17 changes: 10 additions & 7 deletions src/pages/AppHubApp/AppHubApp.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useDataQuery } from '@dhis2/app-runtime'
import { DataStoreProvider } from '@dhis2/app-service-datastore'
import i18n from '@dhis2/d2-i18n'
import { PropTypes } from '@dhis2/prop-types'
import { NoticeBox, CenteredContent, CircularLoader } from '@dhis2/ui'
Expand Down Expand Up @@ -55,13 +56,15 @@ export const AppHubApp = ({ match }) => {
)

return (
<AppDetails
installedApp={installedApp}
appHubApp={appHubApp}
userGroups={userGroups.userGroups}
onVersionInstall={refetch}
onUninstall={() => history.push('/app-hub')}
/>
<DataStoreProvider namespace="app-management">
<AppDetails
installedApp={installedApp}
appHubApp={appHubApp}
userGroups={userGroups.userGroups}
onVersionInstall={refetch}
onUninstall={() => history.push('/app-hub')}
/>
</DataStoreProvider>
)
}

Expand Down
15 changes: 14 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2305,6 +2305,19 @@
dependencies:
react-query "^3.13.11"

"@dhis2/app-service-data@^2.1.1":
version "2.12.4"
resolved "https://registry.yarnpkg.com/@dhis2/app-service-data/-/app-service-data-2.12.4.tgz#3445a113592444100f66849f522f5270b9302fbd"
integrity sha512-4DofkrKq3pwDm5me1Sj6X1/RklV0NYzrigwp0dnvF4JmjCmURCBXeVpKnWa1hiKnJ1qOuUclYaYUSswmC2yWug==

"@dhis2/app-service-datastore@^1.0.0-beta.3":
version "1.0.0-beta.3"
resolved "https://registry.yarnpkg.com/@dhis2/app-service-datastore/-/app-service-datastore-1.0.0-beta.3.tgz#22b858c950d16e7813a8eed953d6556802b1ad1f"
integrity sha512-CGXpa9YZvtifwxbyBwYp/ZeWffreQX5G8Jloq34xmiAEFgesYZIM7w5bTvS0XuzOb2p1S6Duh+iPxgBgegGiNA==
dependencies:
"@dhis2/app-service-data" "^2.1.1"
uuid "^8.1.0"

"@dhis2/[email protected]":
version "3.2.0"
resolved "https://registry.yarnpkg.com/@dhis2/app-service-offline/-/app-service-offline-3.2.0.tgz#60561da1229bd696d449e1acb2e42a9f420e45a6"
Expand Down Expand Up @@ -15280,7 +15293,7 @@ uuid@^3.3.2, uuid@^3.4.0:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==

uuid@^8.3.0:
uuid@^8.1.0, uuid@^8.3.0:
version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
Expand Down

0 comments on commit 8ca2dcf

Please sign in to comment.