From 6bf51b5f165edb22c2ff507fa48dd9ee8891b4b2 Mon Sep 17 00:00:00 2001 From: Leszek Date: Mon, 24 Jun 2024 18:48:15 +0200 Subject: [PATCH 01/12] create AttachmentActionsDropdown component WIP --- jsapp/js/components/common/koboDropdown.tsx | 14 +-- .../attachmentActionsDropdown.component.tsx | 114 ++++++++++++++++++ .../submissions/submissionDataTable.tsx | 3 + 3 files changed, 123 insertions(+), 8 deletions(-) create mode 100644 jsapp/js/components/submissions/attachmentActionsDropdown.component.tsx diff --git a/jsapp/js/components/common/koboDropdown.tsx b/jsapp/js/components/common/koboDropdown.tsx index af10e029f1..28b2732ded 100644 --- a/jsapp/js/components/common/koboDropdown.tsx +++ b/jsapp/js/components/common/koboDropdown.tsx @@ -27,8 +27,8 @@ interface KoboDropdownProps { /** The content of dropdown, anything's allowed. */ menuContent: React.ReactNode; /** - * Optional name value useful for styling and `menuVisibilityChange` action, - * ends up in `data-name` attribut.e + * Name useful for styling and `menuVisibilityChange` action, it ends up in + * the `data-name` attribute. */ name: string; 'data-cy'?: string; @@ -41,7 +41,7 @@ interface KoboDropdownState { } interface AdditionalWrapperAttributes { - 'data-name'?: string; + 'data-name': string; 'data-cy'?: string; } @@ -229,12 +229,10 @@ export default class KoboDropdown extends React.Component< } render() { - const additionalWrapperAttributes: AdditionalWrapperAttributes = {}; - - if (this.props.name) { + const additionalWrapperAttributes: AdditionalWrapperAttributes = { // We use `data-name` attribute to allow any character in the name. - additionalWrapperAttributes['data-name'] = this.props.name; - } + ['data-name']: this.props.name, + }; if (this.props['data-cy']) { additionalWrapperAttributes['data-cy'] = this.props['data-cy']; diff --git a/jsapp/js/components/submissions/attachmentActionsDropdown.component.tsx b/jsapp/js/components/submissions/attachmentActionsDropdown.component.tsx new file mode 100644 index 0000000000..db27cdc9fd --- /dev/null +++ b/jsapp/js/components/submissions/attachmentActionsDropdown.component.tsx @@ -0,0 +1,114 @@ +// Libraries +import React, {useState} from 'react'; + +// Components +import Icon from 'js/components/common/icon'; +import Button from 'js/components/common/button'; +import KoboDropdown from 'js/components/common/koboDropdown'; +import KoboModal from 'js/components/modals/koboModal'; +import KoboModalHeader from 'js/components/modals/koboModalHeader'; +import KoboModalContent from 'js/components/modals/koboModalContent'; +import KoboModalFooter from 'js/components/modals/koboModalFooter'; +import bem from 'js/bem'; + +// Utilities +import {generateUuid, notify} from 'js/utils'; + +// Types +import type {SubmissionAttachment} from 'js/dataInterface'; + +// Styles +// import styles from './attachmentActionsDropdown.module.scss'; + +interface AttachmentActionsDropdownProps { + attachment: SubmissionAttachment; +} + +export default function AttachmentActionsDropdown( + props: AttachmentActionsDropdownProps +) { + const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); + const [isDeletePending, setIsDeletePending] = useState(false); + + const toggleDeleteModal = () => { + setIsDeleteModalOpen(!isDeleteModalOpen); + }; + + function confirmDelete() { + console.log('confirmDelete'); + + setIsDeletePending(true); + + setTimeout(() => { + setIsDeletePending(false); + toggleDeleteModal(); + notify(t('##Attachment_type## deleted').replace('##Attachment_type##', t('Image'))); + }, 2000); + } + + function requestDownloadFile() { + console.log('requestDownloadFile', props.attachment); + } + + const uniqueDropdownName = `attachment-actions-${generateUuid()}`; + + return ( + <> + + } + menuContent={ + + + + + + + + + + + + } + /> + + + + {t('Delete ##attachment_type##').replace('##attachment_type##', t('image'))} + + + +

{t('Are you sure you want to delete this ##attachment_type##?').replace('##attachment_type##', t('image'))}

+
+ + +