Skip to content

Commit

Permalink
Geo attribute: added download button (#3653)
Browse files Browse the repository at this point in the history
* layout adjustmnets

* code cleanup

---------

Co-authored-by: Stefano Ricci <[email protected]>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Nov 15, 2024
1 parent 51760e6 commit 8347189
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 14 deletions.
4 changes: 2 additions & 2 deletions webapp/components/buttons/ButtonDelete.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import classNames from 'classnames'
import { Button } from './Button'

export const ButtonDelete = (props) => {
const { label = 'common.delete' } = props
const { className, label = 'common.delete' } = props
return (
<Button
{...props}
className={classNames('btn-danger btn-delete', props.className)}
className={classNames('btn-danger btn-delete', className)}
iconClassName="icon-bin2 icon-12px"
label={label}
variant="text"
Expand Down
3 changes: 3 additions & 0 deletions webapp/components/form/uploadButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const UploadButton = (props) => {
onChange = null,
showLabel = true,
showIcon = true,
variant = 'contained',
} = props

const fileInput = useRef(null)
Expand Down Expand Up @@ -55,6 +56,7 @@ const UploadButton = (props) => {
}}
showLabel={showLabel}
showIcon={showIcon}
variant={variant}
/>
</>
)
Expand All @@ -70,6 +72,7 @@ UploadButton.propTypes = {
onChange: PropTypes.func,
showIcon: PropTypes.bool,
showLabel: PropTypes.bool,
variant: PropTypes.oneOf(['contained', 'outlined', 'text']),
}

export default UploadButton
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import * as NodeDefLayout from '@core/survey/nodeDefLayout'

import { RecordState } from '@webapp/store/ui/record'

import { Button, ButtonIconDelete, ExpansionPanel, Map, PanelRight } from '@webapp/components'
import { Button, ButtonDownload, ButtonIconDelete, ExpansionPanel, Map, PanelRight } from '@webapp/components'
import { UploadButton } from '@webapp/components/form'
import { Input } from '@webapp/components/form/Input'
import { GeoPolygonInfo } from '@webapp/components/geo/GeoPolygonInfo'
Expand All @@ -21,6 +21,7 @@ import { useSurveyPreferredLang } from '@webapp/store/survey'
import { NotificationActions } from '@webapp/store/ui'
import { useAuthCanUseMap } from '@webapp/store/user/hooks'

import { downloadTextToFile } from '@webapp/utils/domUtils'
import { FileUtils } from '@webapp/utils/fileUtils'
import { GeoJsonUtils } from '@webapp/utils/geoJsonUtils'

Expand Down Expand Up @@ -56,6 +57,7 @@ const NodeDefGeo = (props) => {
const value = Node.getValue(node, NodeDefUiProps.getDefaultValue(nodeDef))
const valueText = value ? JSON.stringify(value) : ''

const nodeDefName = NodeDef.getName(nodeDef)
const nodeDefLabel = NodeDef.getLabel(nodeDef, lang)

const toggleShowMap = useCallback(() => setShowMap(!showMap), [showMap])
Expand All @@ -75,6 +77,10 @@ const NodeDefGeo = (props) => {
[dispatch, node, nodeDef, updateNode]
)

const onDownloadClick = useCallback(() => {
downloadTextToFile(valueText, `${nodeDefName}.geojson`)
}, [nodeDefName, valueText])

const onClearValueClick = useCallback(async () => {
if (await confirm({ key: 'surveyForm.nodeDefGeo.confirmDelete' })) {
updateNode(nodeDef, node, null)
Expand Down Expand Up @@ -130,16 +136,23 @@ const NodeDefGeo = (props) => {
</div>
<div className="action-buttons">
{valueText && (
<>
<div className="row">
{mapTriggerButton}
<ButtonDownload className="btn-s" onClick={onDownloadClick} showLabel={false} variant="contained" />
{mapPanelRight}
</>
</div>
)}
{!entryDisabled && (
<>
<UploadButton className="btn-s" showLabel={false} onChange={onFilesChange} maxSize={maxFileSize} />
<div className="row">
<UploadButton
className="btn-s"
showLabel={false}
onChange={onFilesChange}
maxSize={maxFileSize}
variant="outlined"
/>
{valueText && <ButtonIconDelete onClick={onClearValueClick} />}
</>
</div>
)}
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
display: flex;
flex-direction: column;
gap: 1rem;

.row {
display: flex;
flex-direction: row;
gap: 1rem;
}
}

.info-panel {
Expand Down
22 changes: 16 additions & 6 deletions webapp/utils/domUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,21 @@ export const copyToClipboard = async (text) => {
}
}

export const downloadToFile = (url, outputFileName) => {
const link = document.createElement('a')
link.href = url
link.download = outputFileName
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}

export const downloadTextToFile = (text, outputFileName) => {
const blob = new Blob([text], { type: 'text/plain' })
const url = URL.createObjectURL(blob)
downloadToFile(url, outputFileName)
}

export const downloadSvgToPng = (svgElement) => {
const serializer = new XMLSerializer()
const svgString = serializer.serializeToString(svgElement)
Expand All @@ -67,12 +82,7 @@ export const downloadSvgToPng = (svgElement) => {

// Create a download link for the canvas image
const pngUrl = canvas.toDataURL('image/png')
const downloadLink = document.createElement('a')
downloadLink.href = pngUrl
downloadLink.download = 'chart.png'
document.body.appendChild(downloadLink)
downloadLink.click()
document.body.removeChild(downloadLink)
downloadToFile(pngUrl, 'chart.png')
URL.revokeObjectURL(url)
}
}

0 comments on commit 8347189

Please sign in to comment.