Skip to content

Commit

Permalink
feat: default variables, create attribute dialog [DAT-1403]
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas Zemp committed Jul 29, 2022
1 parent 9e16649 commit c8c1261
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 10 deletions.
23 changes: 21 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: 2022-07-20T16:52:08.431Z\n"
"PO-Revision-Date: 2022-07-20T16:52:08.431Z\n"
"POT-Creation-Date: 2022-07-29T14:31:45.194Z\n"
"PO-Revision-Date: 2022-07-29T14:31:45.194Z\n"

msgid "Search within results"
msgstr "Search within results"
Expand Down Expand Up @@ -77,6 +77,25 @@ msgstr "SQL Views"
msgid "Search for a SQL view"
msgstr "Search for a SQL view"

msgid "Attribute has been created. App will reload shortly."
msgstr "Attribute has been created. App will reload shortly."

msgid "Attribute could not be created."
msgstr "Attribute could not be created."

msgid ""
"Do you want to create an attribute that allows saving default variable "
"values?"
msgstr ""
"Do you want to create an attribute that allows saving default variable "
"values?"

msgid "Cancel"
msgstr "Cancel"

msgid "Create"
msgstr "Create"

msgid "Download CSV"
msgstr "Download CSV"

Expand Down
10 changes: 5 additions & 5 deletions src/components/Data/ViewData.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import {
} from '../../services/extractVariables'
import { useQuery } from '../../services/useQuery'
import { useDataStoreConfig } from '../ConfigProvider'
import { useUserInfo } from '../UserInfoProvider'
import Layout from '../Layout'
import { useUserInfo } from '../UserInfoProvider'
import DataWrapper from './DataWrapper'
import ErrorMessage from './ErrorMessage'
import LinksMenu from './LinksMenu'
Expand Down Expand Up @@ -82,7 +82,7 @@ const BackButton = () => (
const ViewData = ({ match }) => {
const { baseUrl } = useConfig()
const { config, configWaiting } = useDataStoreConfig()
const { userInfo, userWaiting } = useUserInfo()
const { userInfo } = useUserInfo()
const query = useQuery()
const engine = useDataEngine()
const id = match.params.id
Expand Down Expand Up @@ -212,17 +212,17 @@ const ViewData = ({ match }) => {
const filteredAttributeValues = data.sqlView.attributeValues.filter(
av => av.attribute.id !== config?.defaultsAttributeId
)
let newVariables = {
const newVariables = {
attribute: { id: config?.defaultsAttributeId },
value: JSON.stringify(variables),
}
let newSQLView = { ...data.sqlView }
const newSQLView = { ...data.sqlView }
newSQLView.attributeValues = [
...filteredAttributeValues,
newVariables,
]

let response = await engine.mutate(sqlUpdate, {
const response = await engine.mutate(sqlUpdate, {
variables: { id: data.sqlView.id, data: newSQLView },
})
if (
Expand Down
2 changes: 1 addition & 1 deletion src/components/Main.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react'
import { HashRouter as Router, Switch, Route } from 'react-router-dom'
import ConfigProvider from './ConfigProvider'
import UserInfoProvider from './UserInfoProvider'
import ViewData from './Data/ViewData'
import Layout from './Layout'
import SelectQuery from './Selection/SelectQuery'
import UserInfoProvider from './UserInfoProvider'
import '../locales'

const Main = () => {
Expand Down
39 changes: 37 additions & 2 deletions src/components/Selection/SelectQuery.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { DataQuery } from '@dhis2/app-runtime'
import i18n from '@dhis2/d2-i18n'
import { Button, CircularLoader, IconMore24 } from '@dhis2/ui'
import { Button, CircularLoader, IconMore24, IconSettings24 } from '@dhis2/ui'
import PropTypes from 'prop-types'
import React, { createRef, useState } from 'react'
import { Link } from 'react-router-dom'
import { useDataStoreConfig } from '../ConfigProvider'
import LinksMenu from '../Data/LinksMenu'
import CustomTable from '../Table/CustomTable'
import { useUserInfo } from '../UserInfoProvider'
import SettingsModal from './SettingsModal'

const sqlViewsQuery = {
sql: {
Expand Down Expand Up @@ -61,12 +64,37 @@ const SelectQuery = () => {
{ name: 'uid', hidden: true },
]

const { userInfo } = useUserInfo()
const { config } = useDataStoreConfig()
const [settingsModalOpen, setSettingsModalOpen] = useState(false)

return (
<DataQuery query={sqlViewsQuery}>
{({ loading, error, data }) => (
<>
<div className="innerContainer">
<h1 className="titleText">{i18n.t('SQL Views')}</h1>
{settingsModalOpen && (
<SettingsModal
setSettingsModalOpen={setSettingsModalOpen}
/>
)}

<div className="headerContainer">
<h1 className="titleText">{i18n.t('SQL Views')}</h1>
{userInfo?.superuser &&
!config?.defaultsAttributeId && (
<div className="rightButton">
<Button
dataTest="settings-button"
icon={<IconSettings24 />}
small
onClick={() => {
setSettingsModalOpen(true)
}}
/>
</div>
)}
</div>
{loading && <CircularLoader />}
{error && <span>{`Error: ${error.message}`}</span>}
{data && (
Expand Down Expand Up @@ -119,6 +147,13 @@ const SelectQuery = () => {
margin: var(--spacers-dp24) 0 var(--spacers-dp12);
line-height: 20px;
}
.headerContainer {
display: flex;
align-items: center;
}
.rightButton {
margin-left: auto;
}
`}</style>
</>
)}
Expand Down
106 changes: 106 additions & 0 deletions src/components/Selection/SettingsModal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { useAlert, useDataEngine } from '@dhis2/app-runtime'
import i18n from '@dhis2/d2-i18n'
import {
Button,
ButtonStrip,
Modal,
ModalActions,
ModalContent,
} from '@dhis2/ui'
import PropTypes from 'prop-types'
import React from 'react'

const DEFAULT_ATTIBUTE_NAME = 'default-sql-values'

const attributeCreate = {
resource: 'attributes',
type: 'create',
data: ({ data }) => data,
}

const dataStoreCreate = {
resource: 'dataStore/sqlViewer/config',
type: 'create',
data: ({ data }) => data,
}

const SettingsModal = ({ setSettingsModalOpen }) => {
const engine = useDataEngine()
const { show: showAlert } = useAlert(
({ msg }) => msg,
({ options }) => ({ ...options, duration: 3000 })
)

const createAttribute = async () => {
try {
// post to create attribute
const defaultsAttribute = {
name: DEFAULT_ATTIBUTE_NAME,
valueType: 'LONG_TEXT',
sqlViewAttribute: true,
}
const attributeResponse = await engine.mutate(attributeCreate, {
variables: { data: defaultsAttribute },
})

// if successful, post to create datastore (note: assumes datastore does not exist)
const datastoreContent = {
defaultsAttributeId: attributeResponse?.response?.uid,
}
await engine.mutate(dataStoreCreate, {
variables: { data: datastoreContent },
})

showAlert({
msg: i18n.t('Attribute has been created. App will reload shortly.'),
options: { success: true },
})

// here the context should be created, but reloading page is a simpler approach
setTimeout(() => {
location.reload()
}, 3000)
} catch (e) {
showAlert({
msg: i18n.t('Attribute could not be created.'),
options: { warning: true },
})
}
setSettingsModalOpen(false)
}

return (
<Modal
onClose={() => {
setSettingsModalOpen(false)
}}
position="middle"
>
<ModalContent>
{i18n.t(
'Do you want to create an attribute that allows saving default variable values?'
)}
</ModalContent>
<ModalActions>
<ButtonStrip>
<Button
onClick={() => {
setSettingsModalOpen(false)
}}
>
{i18n.t('Cancel')}
</Button>
<Button primary onClick={createAttribute}>
{i18n.t('Create')}
</Button>
</ButtonStrip>
</ModalActions>
</Modal>
)
}

SettingsModal.propTypes = {
setSettingsModalOpen: PropTypes.func,
}

export default SettingsModal

0 comments on commit c8c1261

Please sign in to comment.