Skip to content
Open

Day1 #37

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# DHIS2 Web App Development Academy
# DHIS2 Web App Development Academy - Day 1 work testing

This is the repo that you will use during the Web Academy exercises. Please fork it, clone it and run it following the instructions on the workshop site: https://dhis2.github.io/academy-web-app-dev/docs/resources/set_up_fork.

Before participating, make sure you have gone through [the pre-requisites](https://dhis2.github.io/academy-web-app-dev/docs/before-academy/) for the academy.

For more information about the academy and the topics taught, check the website: https://dhis2.github.io/academy-web-app-dev/
For more information about the academy and the topics taught, check the website: https://dhis2.github.io/academy-web-app-dev/

#Pinehas Johannes
#Namibia
48 changes: 48 additions & 0 deletions i18n/en.pot
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
msgid ""
msgstr ""
"Project-Id-Version: i18next-conv\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"POT-Creation-Date: 2024-04-18T06:35:33.165Z\n"
"PO-Revision-Date: 2024-04-18T06:35:33.166Z\n"

msgid "Add an attribute"
msgstr "Add an attribute"

msgid "Attribute name"
msgstr "Attribute name"

msgid "Value Type"
msgstr "Value Type"

msgid "Text"
msgstr "Text"

msgid "Number"
msgstr "Number"

msgid "Save"
msgstr "Save"

msgid "Attributes"
msgstr "Attributes"

msgid "Attributes visible to {{name}} ({{email}})"
msgstr "Attributes visible to {{name}} ({{email}})"

msgid "Name"
msgstr "Name"

msgid "Unique"
msgstr "Unique"

msgid "Yes"
msgstr "Yes"

msgid "No"
msgstr "No"

msgid "DHIS2 Web App Academy 2024!"
msgstr "DHIS2 Web App Academy 2024!"
12 changes: 12 additions & 0 deletions i18n/fr.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
msgid ""
msgstr ""
"Project-Id-Version: i18next-conv\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"POT-Creation-Date: 2024-04-16T16:01:10.180Z\n"
"PO-Revision-Date: 2024-04-16T16:01:10.180Z\n"

msgid "DHIS2 Web App Academy 2024!"
msgstr "frech trans"
1 change: 1 addition & 0 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { HashRouter, Navigate, Route, Routes } from 'react-router-dom'
import styles from './App.module.css'
import { Navigation } from './navigation/index.js'
import { Form, Home, Attributes } from './views/index.js'
import i18n from './locales/index.js'

const MyApp = () => (
<HashRouter
Expand Down
1 change: 1 addition & 0 deletions src/hooks/useGetAttributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ const sleep = (ms) => {

export const useGetAttributes = () => {
const [loading, setLoading] = useState(true)
// const error = new Error('something went wrong')
const error = null
const data = ATTRIBUTES

Expand Down
4 changes: 3 additions & 1 deletion src/navigation/Navigation.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Menu, MenuItem } from '@dhis2/ui'
import PropTypes from 'prop-types'
import React from 'react'

// @TODO: Import the `Menu` and `MenuItem` components
import { useNavigate, useMatch } from 'react-router-dom'

Expand All @@ -17,7 +19,7 @@ const NavigationItem = ({ path, label }) => {
const onClick = () => navigate(path)

// @TODO: Use the `MenuItem` component instead of the `div`
return <div>{label}</div>
return <MenuItem label={label} active={isActive} onClick={onClick} />
}

NavigationItem.propTypes = {
Expand Down
102 changes: 102 additions & 0 deletions src/views/AttributeCreateForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { useAlert, useDataMutation } from '@dhis2/app-runtime'
import i18n from '@dhis2/d2-i18n'
import {
Button,
InputFieldFF,
hasValue,
ReactFinalForm,
SingleSelectFieldFF,
} from '@dhis2/ui'
import React from 'react'
import styles from './Form.module.css'

const { Field, Form: RFForm } = ReactFinalForm

const mutation = {
resource: 'attributes',
type: 'create',
data: (dataValues) => ({ ...dataValues }),
}

const AttributeCreateForm = () => {
const { show } = useAlert(
({ id, error }) => {
if (error) {
return error
}
return `An attribute with ID ${id} was created.`
},
({ error }) => {
if (error) {
return { critical: true }
}
return { success: true }
}
)

const options = {
onComplete: ({ response }) =>
show({
id: response?.uid,
}),
onError: (error) => show({ error }),
}
const [mutate, { called, loading, error, data, refetch }] = useDataMutation(
mutation,
options
)

const onSubmit = async (values) => {
await mutate(values)
// @todo: add the mutation
}

return (
<div>
<h1>{i18n.t('Add an attribute')}</h1>

<RFForm onSubmit={onSubmit}>
{({ handleSubmit }) => (
<form onSubmit={handleSubmit}>
<div className={styles.row}>
<Field
required
name="name"
label={i18n.t('Attribute name')}
component={InputFieldFF}
validate={hasValue}
/>
</div>
<div className={styles.row}>
<Field
name="valueType"
label={i18n.t('Value Type')}
component={SingleSelectFieldFF}
className={styles.title}
initialValue="TEXT"
options={[
{
label: i18n.t('Text'),
value: 'TEXT',
},
{
label: i18n.t('Number'),
value: 'NUMBER',
},
]}
/>
</div>

<div className={styles.row}>
<Button type="submit" primary>
{i18n.t('Save')}
</Button>
</div>
</form>
)}
</RFForm>
</div>
)
}

export default AttributeCreateForm
124 changes: 113 additions & 11 deletions src/views/Attributes.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,126 @@
import { useDataMutation, useDataQuery } from '@dhis2/app-runtime'
import i18n from '@dhis2/d2-i18n'
import {
Button,
CenteredContent,
CircularLoader,
NoticeBox,
Table,
TableBody,
TableCell,
TableCellHead,
TableHead,
TableRow,
TableRowHead,
} from '@dhis2/ui'
import React from 'react'
import { useGetAttributes } from '../hooks/index.js'
import AttributeCreateForm from './AttributeCreateForm.js'
import styles from './Attributes.module.css'

const query = {
myUserInfo: {
resource: 'me',
params: {
fields: ['displayName', 'email'],
},
},
attributes: {
resource: 'attributes',
params: {
order: 'created:desc',
fields: ['displayName', 'code', 'id', 'unique', 'valueType'],
pageSize: 5,
},
},
}

const deleteMutation = {
resource: 'attributes',
type: 'delete',
id: ({ id }) => id,
}

export const Attributes = () => {
// we get the data using a custom hook
// we will update this implementation after learning about app-runtime
const { loading, error, data } = useGetAttributes()
const { loading, error, data, refetch } = useDataQuery(query)
const [deleteAttribute] = useDataMutation(deleteMutation)

if (loading) {
return (
<CenteredContent>
<CircularLoader />
</CenteredContent>
)
}

if (error) {
return <NoticeBox error>{error?.message}</NoticeBox>
}

const {
myUserInfo: { displayName, email },
} = data

const onDeleteAttribute = async (mutationId) => {
await deleteAttribute({ id: mutationId })
refetch()
}

return (
<div>
<h1>Attributes</h1>
<p>loading: {JSON.stringify(loading)}</p>
<p>error message: {error?.message}</p>
<h1>{i18n.t('Attributes')}</h1>
<div className={styles.tableInfo}>
{i18n.t('Attributes visible to {{name}} ({{email}})', {
name: displayName,
email,
})}
</div>
{
// if there is any data available
data?.attributes?.attributes && (
<pre>
{JSON.stringify(data.attributes.attributes, null, 4)}
</pre>
<Table>
<TableHead>
<TableRowHead>
<TableCellHead>{i18n.t('Name')}</TableCellHead>
<TableCellHead>
{i18n.t('Unique')}
</TableCellHead>
<TableCellHead>
{i18n.t('Value Type')}
</TableCellHead>
<TableCellHead>Delete?</TableCellHead>
</TableRowHead>
</TableHead>
<TableBody>
{data.attributes.attributes.map(
({ id, displayName, unique, valueType }) => (
<TableRow key={id}>
<TableCell>{displayName}</TableCell>
<TableCell>
{unique
? i18n.t('Yes')
: i18n.t('No')}
</TableCell>
<TableCell>{valueType}</TableCell>
<TableCell>
<Button
small
destructive
disabled={loading}
onClick={() =>
onDeleteAttribute(id)
}
>
Delete
</Button>
</TableCell>
</TableRow>
)
)}
</TableBody>
</Table>
)
}
<AttributeCreateForm />
</div>
)
}
}
3 changes: 3 additions & 0 deletions src/views/Attributes.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.tableInfo {
margin: 0px 0 16px;
}
Loading