Skip to content

Commit

Permalink
Merge branch '3214-links-repository-per-cycle' into 3214-links-reposi…
Browse files Browse the repository at this point in the history
…tory-per-cycle_api-delete-repository-item
  • Loading branch information
mergify[bot] authored Feb 2, 2024
2 parents 3542ec8 + 5514dc0 commit 497924f
Show file tree
Hide file tree
Showing 44 changed files with 319 additions and 174 deletions.
22 changes: 18 additions & 4 deletions src/client/components/Buttons/ButtonEdit/ButtonEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,31 @@ import { Link } from 'react-router-dom'

import Icon from 'client/components/Icon'

type Props = {
type LinkProps = {
url: string
}

type ButtonProps = {
onClick: () => void
}

type Props = LinkProps | ButtonProps

const ButtonEdit: React.FC<Props> = (props) => {
const { url } = props
if ('url' in props) {
const { url } = props
return (
<Link to={url} type="button" className="btn-s btn-link btn-edit">
<Icon name="pencil" />
</Link>
)
}

const { onClick } = props
return (
<Link to={url} type="button" className="btn-s btn-link btn-edit">
<button className="btn-s btn-link btn-edit" onClick={onClick} type="button">
<Icon name="pencil" />
</Link>
</button>
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@ import React, { createContext, Dispatch, SetStateAction, useContext, useMemo, us

import { AssessmentFile } from 'meta/cycleData'

/**
* @deprecated
*/
type SelectedFilesContextType = {
selectedFiles: AssessmentFile[]
setSelectedFiles: Dispatch<SetStateAction<AssessmentFile[]>>
}

/**
* @deprecated
*/
const SelectedFilesContext = createContext<SelectedFilesContextType | undefined>(undefined)

/**
* @deprecated
*/
export const SelectedFilesProvider: React.FC<React.PropsWithChildren> = ({ children }) => {
const [selectedFiles, setSelectedFiles] = useState<Array<AssessmentFile>>([])

Expand All @@ -17,4 +25,7 @@ export const SelectedFilesProvider: React.FC<React.PropsWithChildren> = ({ child
return <SelectedFilesContext.Provider value={value}>{children}</SelectedFilesContext.Provider>
}

/**
* @deprecated
*/
export const useSelectedFileContext = (): SelectedFilesContextType => useContext(SelectedFilesContext)
18 changes: 18 additions & 0 deletions src/client/components/FileUpload/FileUploadProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React, { createContext, Dispatch, SetStateAction, useContext, useMemo, useState } from 'react'

type FileUploadContextType = {
files: FileList
setFiles: Dispatch<SetStateAction<FileList>>
}

const FileUploadContext = createContext<FileUploadContextType | undefined>(undefined)

export const FileUploadProvider: React.FC<React.PropsWithChildren> = ({ children }) => {
const [files, setFiles] = useState<FileList | null>(null)

const value = useMemo<FileUploadContextType>(() => ({ files, setFiles }), [files])

return <FileUploadContext.Provider value={value}>{children}</FileUploadContext.Provider>
}

export const useFileUploadContext = (): FileUploadContextType => useContext(FileUploadContext)
1 change: 1 addition & 0 deletions src/client/components/FileUpload/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { FileUploadProvider, useFileUploadContext } from './FileUploadProvider'
2 changes: 1 addition & 1 deletion src/client/components/MessageCenter/Topic/Topic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ const Topic: React.FC<TopicProps> = (props) => {
onClick={postMessage}
type="submit"
>
{i18n.t<string>('review.add')}
{i18n.t<string>('common.add')}
</button>
</DataCell>
</DataGrid>
Expand Down
1 change: 1 addition & 0 deletions src/client/components/SlidingPanel/SlidingPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Icon from 'client/components/Icon'

type Props = {
openPanel: boolean
// TODO: Rename this to closePanel
setOpenPanel: (isOpen: boolean) => void
}

Expand Down
46 changes: 19 additions & 27 deletions src/client/pages/CountryHome/Repository/Actions/Actions.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,28 @@
import './Actions.scss'
import React from 'react'
import { useTranslation } from 'react-i18next'

import Icon from 'client/components/Icon'
import SlidingPanel from 'client/components/SlidingPanel'
import { RepositoryItem } from 'meta/cycleData'

const Actions: React.FC = () => {
const { t } = useTranslation()
const [openPanel, setOpenPanel] = React.useState(false)
import { useAppDispatch } from 'client/store'
import { RepositoryActions } from 'client/store/ui/repository'
import ButtonEdit from 'client/components/Buttons/ButtonEdit'

type Props = {
repositoryItem: RepositoryItem
}

const Actions: React.FC<Props> = (props) => {
const { repositoryItem } = props
const dispatch = useAppDispatch()

return (
<>
<div className="repository-actions">
<button
className="btn-s btn-link btn-edit"
onClick={() => {
setOpenPanel(!openPanel)
}}
type="button"
>
<Icon name="pencil" />
</button>
</div>
<SlidingPanel openPanel={openPanel} setOpenPanel={setOpenPanel}>
<button onClick={() => setOpenPanel(false)} className="btn btn-destructive" type="button">
{t('common.delete')}
</button>
<button onClick={() => setOpenPanel(false)} className="btn btn-secondary" type="button">
{t('common.cancel')}
</button>
</SlidingPanel>
</>
<div className="repository-actions">
<ButtonEdit
onClick={() => {
dispatch(RepositoryActions.setRepositoryItem(repositoryItem))
}}
/>
</div>
)
}

Expand Down
17 changes: 6 additions & 11 deletions src/client/pages/CountryHome/Repository/EditForm/EditForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,19 @@ import { useTranslation } from 'react-i18next'
import Icon from 'client/components/Icon'
import Panel from 'client/pages/CountryHome/Repository/Panel'

import { useOpenPanel } from '../hooks/useOpenPanel'

const EditForm: React.FC = () => {
const { t } = useTranslation()
const [openPanel, setOpenPanel] = React.useState(false)
const openPanel = useOpenPanel()

return (
<div className="repository__edit-form">
<button
className="btn-s btn-primary"
onClick={() => {
setOpenPanel(!openPanel)
}}
type="button"
>
<button className="btn-s btn-primary" onClick={openPanel} type="button">
<Icon className="icon-sub icon-white" name="small-add" />
{t('review.add')}
{t('common.add')}
</button>

<Panel openPanel={openPanel} setOpenPanel={setOpenPanel} />
<Panel />
</div>
)
}
Expand Down
30 changes: 21 additions & 9 deletions src/client/pages/CountryHome/Repository/Panel/Actions/Actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,43 @@ import React from 'react'
import { useTranslation } from 'react-i18next'

import classNames from 'classnames'
import { Objects } from 'utils/objects'

import { useIsRepositoryLoading } from 'client/store/ui/repository/hooks'
import { useIsRepositoryLoading, useRepositoryItem } from 'client/store/ui/repository/hooks'

type Props = {
setOpenPanel: (open: boolean) => void
onSave: () => void
}
import { useClosePanel } from '../../hooks/useClosePanel'
import { useUpsertRepositoryItem } from './hooks/useUpsertRepositoryItem'

const Actions: React.FC<Props> = (props: Props) => {
const { setOpenPanel, onSave } = props
const Actions: React.FC = () => {
const { t } = useTranslation()
const repositoryItem = useRepositoryItem()

const upsertRepositoryItem = useUpsertRepositoryItem()

const closePanel = useClosePanel()
const disabled = useIsRepositoryLoading()

if (!repositoryItem) return null
const showDelete = !Objects.isEmpty(repositoryItem.uuid)

return (
<div className="repository-form__actions">
<button
disabled={disabled}
onClick={onSave}
onClick={upsertRepositoryItem}
className={classNames('btn btn-primary', { disabled })}
type="button"
>
{t('common.done')}
</button>
<button className="btn btn-secondary" type="button" onClick={() => setOpenPanel(false)}>

{showDelete && (
<button className="btn btn-destructive" type="button">
{t('common.delete')}
</button>
)}

<button className="btn btn-secondary" type="button" onClick={closePanel}>
{t('common.cancel')}
</button>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,21 @@ import { CountryIso } from 'meta/area'
import { useAppDispatch } from 'client/store'
import { RepositoryActions } from 'client/store/ui/repository'
import { useCountryRouteParams } from 'client/hooks/useRouteParams'
import { RepositoryEdit } from 'client/pages/CountryHome/Repository/Panel/repositoryEdit'
import { useFileUploadContext } from 'client/components/FileUpload'

type Returned = () => Promise<void>
type Returned = () => void

export const useOnSaveFile = (file: RepositoryEdit | null, setOpenPanel: (open: boolean) => void): Returned => {
export const useUpsertRepositoryItem = (): Returned => {
const dispatch = useAppDispatch()
const { assessmentName, cycleName, countryIso } = useCountryRouteParams<CountryIso>()
const { files, setFiles } = useFileUploadContext()

return useCallback<Returned>(async () => {
const saveParams = { assessmentName, cycleName, countryIso, file }
dispatch(RepositoryActions.save(saveParams))
const saveParams = { assessmentName, cycleName, countryIso, file: files?.[0] }
dispatch(RepositoryActions.upsertRepositoryItem(saveParams))
.unwrap()
.then(() => {
setOpenPanel(false)
setFiles(null)
})
}, [assessmentName, cycleName, countryIso, file, dispatch, setOpenPanel])
}, [assessmentName, cycleName, countryIso, dispatch, files, setFiles])
}
Original file line number Diff line number Diff line change
@@ -1,37 +1,33 @@
import './InputField.scss'
import React from 'react'
import React, { useCallback } from 'react'
import { useTranslation } from 'react-i18next'

type Props = {
className?: string
label: string
name: string
onChange: (name: string, value: File | string) => void
type: string
onChange: (name: string, value: string) => void
value: string
}

const InputField: React.FC<Props> = (props: Props) => {
const { label, name, type, className, onChange } = props
const { label, name, onChange, value = '' } = props
const { t } = useTranslation()

const _onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
if (name === 'file') {
onChange(name, event.target.files[0])
return
}
onChange(name, event.target.value)
}
const _onChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => onChange(name, event.target.value),
[name, onChange]
)

const id = `repository_edit-input-${name}`

return (
<div className={`repository-form__input-field ${className}`}>
<div className="repository-form__label">{t(label)}</div>
<input onChange={_onChange} className="repository-form__input" name={name} type={type} />
<div className="repository-form__input-field">
<label htmlFor={id} className="repository-form__label">
{t(label)}
</label>
<input id={id} value={value} onChange={_onChange} className="repository-form__input" name={name} type="text" />
</div>
)
}

InputField.defaultProps = {
className: '',
}

export default InputField
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react'
import { useTranslation } from 'react-i18next'

import { useFileUploadContext } from 'client/components/FileUpload'

const FileInputField: React.FC = () => {
const { t } = useTranslation()

const { setFiles } = useFileUploadContext()

const _onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setFiles(event.target.files)
}

const label = `common.file`
const id = `repository_form-input-file`

return (
<div className="repository-form__input-field">
<label htmlFor={id} className="repository-form__label">
{t(label)}
</label>
<input id={id} onChange={_onChange} className="repository-form__input" name="file" type="file" />
</div>
)
}

export default FileInputField
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './InputFieldFile'
Loading

0 comments on commit 497924f

Please sign in to comment.