Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add data sharing to sharing dialog [LIBS-677] #1629

Merged
merged 8 commits into from
Nov 13, 2024
Merged
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
4 changes: 2 additions & 2 deletions collections/forms/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: 2024-09-09T12:09:30.724Z\n"
"PO-Revision-Date: 2024-09-09T12:09:30.724Z\n"
"POT-Creation-Date: 2024-11-11T07:36:10.587Z\n"
"PO-Revision-Date: 2024-11-11T07:36:10.588Z\n"

msgid "Upload file"
msgstr "Upload file"
Expand Down
9 changes: 2 additions & 7 deletions components/sharing-dialog/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,9 @@ import { SharingDialog } from '@dhis2/ui'
|---|---|---|---|---|
|id|string||*|The id of the object to share|
|type|DIALOG_TYPES_LIST||*|The type of object to share|
|dataSharing|boolean|`false`||Whether to expose the ability to set data sharing (in addition to metadata sharing)|
|dataTest|string|`'dhis2-uicore-sharingdialog'`|||
|initialSharingSettings|{<br/> "allowPublic": "boolean",<br/> "groups": "objectOf",<br/> "name": "string",<br/> "public": "import {\n ACCESS_NONE,\n ACCESS_VIEW_ONLY,\n ACCESS_VIEW_AND_EDIT,\n DIALOG_TYPES_LIST,\n} from './constants.js' │ import {\n ACCESS_NONE,\n ACCESS_VIEW_ONLY,\n ACCESS_VIEW_AND_EDIT,\n DIALOG_TYPES_LIST,\n} from './constants.js' │ import {\n ACCESS_NONE,\n ACCESS_VIEW_ONLY,\n ACCESS_VIEW_AND_EDIT,\n DIALOG_TYPES_LIST,\n} from './constants.js'",<br/> "users": "objectOf"<br/>}|`{
name: '',
allowPublic: true,
public: ACCESS_NONE,
groups: {},
users: {},
}`||Used to seed the component with data to show whilst loading|
|initialSharingSettings|object|{<br/> "allowPublic": "boolean",<br/> "name": "string",<br/> "public": {"data": 'ACCESS_NONE' \| 'ACCESS_VIEW_ONLY' \| 'ACCESS_VIEW_AND_EDIT',"metadata": 'ACCESS_NONE' \| 'ACCESS_VIEW_ONLY' \| 'ACCESS_VIEW_AND_EDIT'},<br/> "groups": "objectOf (see below)",<br/>"users": "objectOf (see below)",<br/>} <br/><br/>users and group objects have format of: <br/> {"name": "string",<br/> "id": "string",<br/> "access": {"data": 'ACCESS_NONE' \| 'ACCESS_VIEW_ONLY' \| 'ACCESS_VIEW_AND_EDIT',"metadata": 'ACCESS_NONE' \| 'ACCESS_VIEW_ONLY' \| 'ACCESS_VIEW_AND_EDIT'}}||Used to seed the component with data to show whilst loading|
|onClose|function|`() => {}`|||
|onError|function|`() => {}`|||
|onSave|function|`() => {}`|||
40 changes: 26 additions & 14 deletions components/sharing-dialog/i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,36 @@ 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: 2021-11-25T09:59:40.995Z\n"
"PO-Revision-Date: 2021-11-25T09:59:40.995Z\n"
"POT-Creation-Date: 2024-11-07T15:20:34.373Z\n"
"PO-Revision-Date: 2024-11-07T15:20:34.375Z\n"

msgid "View only"
msgstr "View only"

msgid "View and edit"
msgstr "View and edit"

msgid "No access"
msgstr "No access"

msgid "Give access to a user or group"
msgstr "Give access to a user or group"

msgid "Access level"
msgstr "Access level"
msgid "Data access level"
msgstr "Data access level"

msgid "Select a level"
msgstr "Select a level"
msgid "Choose a level"
msgstr "Choose a level"

msgid "Not available offline"
msgstr "Not available offline"

msgid "Metadata access level"
msgstr "Metadata access level"

msgid "Access level"
msgstr "Access level"

msgid "Give access"
msgstr "Give access"

Expand All @@ -38,21 +47,24 @@ msgstr "User / Group"
msgid "All users"
msgstr "All users"

msgid "No access"
msgstr "No access"
msgid "Anyone logged in"
msgstr "Anyone logged in"

msgid "Can view"
msgstr "Can view"
msgid "User group"
msgstr "User group"

msgid "Can view and edit"
msgstr "Can view and edit"
msgid "User"
msgstr "User"

msgid "Metadata"
msgstr "Metadata"
msgid "Data"
msgstr "Data"

msgid "Remove access"
msgstr "Remove access"

msgid "Metadata"
msgstr "Metadata"

msgid "User or group"
msgstr "User or group"

Expand Down
166 changes: 131 additions & 35 deletions components/sharing-dialog/src/access-add/access-add.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@ import { SingleSelectField, SingleSelectOption } from '@dhis2-ui/select'
import PropTypes from 'prop-types'
import React, { useState, useContext } from 'react'
import { SharingAutocomplete } from '../autocomplete/index.js'
import { ACCESS_VIEW_ONLY, ACCESS_VIEW_AND_EDIT } from '../constants.js'
import {
ACCESS_NONE,
ACCESS_VIEW_ONLY,
ACCESS_VIEW_AND_EDIT,
} from '../constants.js'
import { FetchingContext } from '../fetching-context/index.js'
import i18n from '../locales/index.js'
import { Title } from '../text/index.js'

export const AccessAdd = ({ onAdd }) => {
export const AccessAdd = ({ onAdd, dataSharing }) => {
const isFetching = useContext(FetchingContext)
const [entity, setEntity] = useState(null)
const [access, setAccess] = useState('')
const [dataAccess, setDataAccess] = useState('')
const [metadataAccess, setMetadataAccess] = useState('')
const { isDisconnected: offline } = useDhis2ConnectionStatus()

const onSubmit = (e) => {
Expand All @@ -23,14 +28,15 @@ export const AccessAdd = ({ onAdd }) => {
type: entity.type,
id: entity.id,
name: entity.displayName || entity.name,
access,
access: { data: dataAccess, metadata: metadataAccess },
})

setEntity(null)
setAccess('')
setDataAccess('')
setMetadataAccess('')
}

const accessOptions = [
const accessOptionsMetadata = [
{
value: ACCESS_VIEW_ONLY,
label: i18n.t('View only'),
Expand All @@ -41,41 +47,109 @@ export const AccessAdd = ({ onAdd }) => {
},
]

const accessOptionsData = [
...accessOptionsMetadata,
{
value: ACCESS_NONE,
label: i18n.t('No access'),
},
]

return (
<>
<Title>{i18n.t('Give access to a user or group')}</Title>
<form onSubmit={onSubmit}>
<SharingAutocomplete
selected={entity?.displayName || entity?.name}
onSelection={setEntity}
/>
<div className="select-wrapper">
<SingleSelectField
label={i18n.t('Access level')}
placeholder={i18n.t('Select a level')}
disabled={offline}
selected={access}
helpText={
offline ? i18n.t('Not available offline') : ''
<div
className={
dataSharing
? 'startWrapperData'
: 'startWrapperMetadata'
}
>
<SharingAutocomplete
selected={entity?.displayName || entity?.name}
onSelection={setEntity}
/>
</div>
<div
className={
dataSharing
? 'endWrapper endWrapperData'
: 'endWrapper endWrapperMetadata'
}
>
{dataSharing && (
<div className="select-wrapper">
<SingleSelectField
label={i18n.t('Data access level')}
placeholder={i18n.t('Choose a level')}
disabled={offline}
selected={dataAccess}
helpText={
offline
? i18n.t('Not available offline')
: ''
}
onChange={({ selected }) =>
setDataAccess(selected)
}
>
{accessOptionsData.map(({ value, label }) => (
<SingleSelectOption
key={value}
label={label}
value={value}
active={value === dataAccess}
/>
))}
</SingleSelectField>
</div>
)}
<div className="select-wrapper">
<SingleSelectField
label={
dataSharing
? i18n.t('Metadata access level')
: i18n.t('Access level')
}
placeholder={i18n.t('Choose a level')}
disabled={offline}
selected={metadataAccess}
helpText={
offline ? i18n.t('Not available offline') : ''
}
onChange={({ selected }) =>
setMetadataAccess(selected)
}
>
{(dataSharing
? accessOptionsData
: accessOptionsMetadata
).map(({ value, label }) => (
<SingleSelectOption
key={value}
label={label}
value={value}
active={value === metadataAccess}
/>
))}
</SingleSelectField>
</div>
<Button
type="submit"
disabled={
offline ||
isFetching ||
!entity ||
(dataSharing && !dataAccess) ||
!metadataAccess ||
(dataAccess === ACCESS_NONE &&
metadataAccess === ACCESS_NONE)
}
onChange={({ selected }) => setAccess(selected)}
>
{accessOptions.map(({ value, label }) => (
<SingleSelectOption
key={value}
label={label}
value={value}
active={value === access}
/>
))}
</SingleSelectField>
{i18n.t('Give access')}
</Button>
</div>
<Button
type="submit"
disabled={offline || isFetching || !entity || !access}
>
{i18n.t('Give access')}
</Button>
</form>
<style jsx>{`
form {
Expand All @@ -86,17 +160,39 @@ export const AccessAdd = ({ onAdd }) => {
border-radius: 5px;
display: flex;
align-items: flex-end;
gap: ${spacers.dp8};
justify-content: space-between;
}

.wrapper {
}

.select-wrapper {
flex: 1;
}
.startWrapperData {
width: 35%;
}
.startWrapperMetadata {
width: 55%;
}
.endWrapper {
margin-inline-start: 8px;
display: flex;
align-items: flex-end;
gap: ${spacers.dp8};
}
.endWrapperMetadata {
width: 45%;
}
.endWrapperData {
width: 65%;
}
`}</style>
</>
)
}

AccessAdd.propTypes = {
onAdd: PropTypes.func.isRequired,
dataSharing: PropTypes.bool,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

types also need updating?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the reminder! I've cleaned up the type definition, which also includes some fixes:

  • I've added in dataSharing on the component level
  • I've updated the users/groups to be arrays of SharingObject
  • I've replaced the import of ModalOnCloseEventHandler with the definition from ui/modal types (the type was exported from modal types and only consumed in this type file, but was imported incorrectly)

I spoke with @Birkbjo and we decided that for the access type, we would just use the new type definition {metadata: 'ACCESS_NONE' | 'VIEW_ONLY' | 'VIEW_AND_EDIT'; data: 'ACCESS_NONE' | 'VIEW_ONLY' | 'VIEW_AND_EDIT'} rather than also advertise the existence of the backwards compatible type. (Note: that none of our DHIS2 repos appear to currently be using the initialSharingSettings prop when consuming component)

}
Loading
Loading