Skip to content

Commit

Permalink
added add tags menu action
Browse files Browse the repository at this point in the history
  • Loading branch information
ErykKul committed Jun 27, 2024
1 parent 2058851 commit 5efb5d2
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 16 deletions.
10 changes: 9 additions & 1 deletion public/locales/en/uploadDatasetFiles.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@
"filesUploaded_one": "{{count}} file uploaded",
"filesUploaded_other": "{{count}} files uploaded",
"filesSelected_one": "{{count}} file selected",
"filesSelected_other": "{{count}} files selected"
"filesSelected_other": "{{count}} files selected",
"deleteSelected": "Delete selected",
"addTagsToSelected": "Add tags to selected",
"addTags": "Add tags"
},
"addTags": {
"title": "Add tags to selected files",
"saveChanges": "Save Changes",
"cancelChanges": "Cancel changes"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { TagOptionsModal } from './tag-options-modal/TagOptionsModal'
import { FilesHeader } from './files-header/FilesHeader'
import { RestrictionModal, RestrictionModalResult } from './restriction-modal/RestrictionModal'
import { useTranslation } from 'react-i18next'
import { AddTagsModal, AddTagsModalResult } from './add-tags-modal/AddTagsModal'

interface DatasetFilesProps {
fileUploadState: FileUploadState[]
Expand All @@ -30,11 +31,12 @@ export function UploadedFiles({
const { t } = useTranslation('uploadDatasetFiles')
const [selected, setSelected] = useState(new Set<FileUploadState>())
const [filesToRestrict, setFilesToRestrict] = useState<FileUploadState[]>([])
const [tags, setTagOptions] = useState([t('tags.documentation'), t('tags.data'), t('tags.code')])
const [tagOptions, setTagOptions] = useState([t('tags.documentation'), t('tags.data'), t('tags.code')])

Check failure on line 34 in src/sections/upload-dataset-files/uploaded-files-list/UploadedFiles.tsx

View workflow job for this annotation

GitHub Actions / lint

Replace `t('tags.documentation'),·t('tags.data'),·t('tags.code')` with `⏎····t('tags.documentation'),⏎····t('tags.data'),⏎····t('tags.code')⏎··`

Check failure on line 34 in src/sections/upload-dataset-files/uploaded-files-list/UploadedFiles.tsx

View workflow job for this annotation

GitHub Actions / lint

Replace `t('tags.documentation'),·t('tags.data'),·t('tags.code')` with `⏎····t('tags.documentation'),⏎····t('tags.data'),⏎····t('tags.code')⏎··`
const [terms, setTerms] = useState('')
const [requestAccess, setRequestAccess] = useState(true)
const [showRestrictionModal, setShowRestrictionModal] = useState(false)
const [showTagOptionsModal, setShowTagOptionsModal] = useState(false)
const [showAddTagsModal, setShowAddTagsModal] = useState(false)
const ignoreClasses = new Set<string>([
'form-control',
'btn',
Expand All @@ -61,6 +63,19 @@ export function UploadedFiles({
}
setShowRestrictionModal(false)
}
const addTags = (res: AddTagsModalResult) => {
if (res.saved) {
const filesToAddTagsTo = Array.from(selected).map((file) => {
const newTags = [...file.tags]
res.tags.forEach((t) => { if (!file.tags.some((x) => x === t)) newTags.push(t) })

Check failure on line 70 in src/sections/upload-dataset-files/uploaded-files-list/UploadedFiles.tsx

View workflow job for this annotation

GitHub Actions / lint

Replace `·if·(!file.tags.some((x)·=>·x·===·t))·newTags.push(t)` with `⏎··········if·(!file.tags.some((x)·=>·x·===·t))·newTags.push(t)⏎·······`

Check failure on line 70 in src/sections/upload-dataset-files/uploaded-files-list/UploadedFiles.tsx

View workflow job for this annotation

GitHub Actions / lint

Replace `·if·(!file.tags.some((x)·=>·x·===·t))·newTags.push(t)` with `⏎··········if·(!file.tags.some((x)·=>·x·===·t))·newTags.push(t)⏎·······`
file.tags = newTags
return file
})
console.log(filesToAddTagsTo)
updateFiles(filesToAddTagsTo)
}
setShowAddTagsModal(false)
}
const deleteFile = (file: FileUploadState) => {
file.removed = true
setSelected((x) => {
Expand Down Expand Up @@ -101,7 +116,7 @@ export function UploadedFiles({
<>
<div className={styles.forms}>
<TagOptionsModal
tags={tags}
availableTags={[...tagOptions]}
setTagOptions={setTagOptions}
show={showTagOptionsModal}
hide={() => setShowTagOptionsModal(false)}
Expand All @@ -112,6 +127,12 @@ export function UploadedFiles({
show={showRestrictionModal}
update={restrict}
/>
<AddTagsModal
show={showAddTagsModal}
availableTags={[...tagOptions]}
setTagOptions={setTagOptions}
update={addTags}
/>
</div>
<div hidden={fileUploadState.length === 0}>
<Card>
Expand All @@ -124,6 +145,7 @@ export function UploadedFiles({
selected={selected}
setSelected={setSelected}
updateFilesRestricted={updateFilesRestricted}
showAddTagsModal={() => setShowAddTagsModal(true)}
/>
<Card.Body>
<div>
Expand All @@ -147,7 +169,7 @@ export function UploadedFiles({
<FileForm
file={file}
updateFiles={updateFiles}
tags={tags}
availableTags={[...tagOptions]}
editTagOptions={() => setShowTagOptionsModal(true)}
/>
<div className={styles.file_size} title={t('uploadedFileSize')}>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
@import "node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/colors.module";

.add_tags_form {
padding-top: 0.5em;
padding-bottom: 0.5em;
}

.tags {
display: flex;
}

.tags_select{
width: 100%;
}

.tag_options {
padding-top: 0.5em;
padding-bottom: 0.5em;
}

.tag_info {
padding-top: 0.5em;
padding-bottom: 0.5em;
color: $dv-subtext-color;
}

.apply_button {
height: 2.4rem;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { Button, Col, Form, Modal, SelectMultiple } from '@iqss/dataverse-design-system'
import styles from './AddTagsModal.module.scss'
import { FormEvent, useState, KeyboardEvent } from 'react'
import { useTranslation } from 'react-i18next'

interface AddTagsModalProps {
show: boolean
availableTags: string[]
setTagOptions: (newTags: string[]) => void
update: (res: AddTagsModalResult) => void
}

export interface AddTagsModalResult {
saved: boolean
tags: string[]
}

export function AddTagsModal({

Check failure on line 18 in src/sections/upload-dataset-files/uploaded-files-list/add-tags-modal/AddTagsModal.tsx

View workflow job for this annotation

GitHub Actions / lint

Replace `⏎··show,⏎··availableTags,⏎··setTagOptions,⏎··update⏎` with `·show,·availableTags,·setTagOptions,·update·`

Check failure on line 18 in src/sections/upload-dataset-files/uploaded-files-list/add-tags-modal/AddTagsModal.tsx

View workflow job for this annotation

GitHub Actions / lint

Replace `⏎··show,⏎··availableTags,⏎··setTagOptions,⏎··update⏎` with `·show,·availableTags,·setTagOptions,·update·`
show,
availableTags,
setTagOptions,
update
}: AddTagsModalProps) {
const { t } = useTranslation('uploadDatasetFiles')
const [tagsToAdd, setTagsToAdd] = useState<string[]>([])
const [tag, setTag] = useState('')
const handleClose = (saved: boolean) =>

Check failure on line 27 in src/sections/upload-dataset-files/uploaded-files-list/add-tags-modal/AddTagsModal.tsx

View workflow job for this annotation

GitHub Actions / lint

Delete `⏎···`

Check failure on line 27 in src/sections/upload-dataset-files/uploaded-files-list/add-tags-modal/AddTagsModal.tsx

View workflow job for this annotation

GitHub Actions / lint

Delete `⏎···`
update({ saved: saved, tags: tagsToAdd })
const addTagOption = () => {
if (tag && !availableTags.includes(tag)) {
setTagOptions([...availableTags, tag])
setTag('')
}
}
const handleEnter = (event: KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'Enter') {
addTagOption()
event.preventDefault()
}
}

Check failure on line 40 in src/sections/upload-dataset-files/uploaded-files-list/add-tags-modal/AddTagsModal.tsx

View workflow job for this annotation

GitHub Actions / lint

Delete `⏎`

Check failure on line 40 in src/sections/upload-dataset-files/uploaded-files-list/add-tags-modal/AddTagsModal.tsx

View workflow job for this annotation

GitHub Actions / lint

Delete `⏎`


return (
<Modal show={show} onHide={() => handleClose(false)} size="lg">
<Modal.Header>
<Modal.Title>{t('addTags.title')}</Modal.Title>
</Modal.Header>
<Modal.Body>
<div className={styles.add_tags_form}>
<Form>
<Form.Group>
<Form.Group.Label column sm={3}>
{t('fileForm.tags')}
</Form.Group.Label>
<Col sm={9} className={styles.tags}>
<div className={styles.tags_select} title={t('fileForm.selectTags')}>
<SelectMultiple
options={availableTags}
onChange={(newTags) => setTagsToAdd(newTags)}></SelectMultiple>
</div>
</Col>
</Form.Group>
<Form.Group>
<Form.Group.Label column sm={3}>
{t('tags.customFileTag')}
</Form.Group.Label>
<Col sm={9}>
<div className={styles.tag_info}>{t('tags.creatingNewTag')}</div>
<div className="input-group mb-3" onKeyDown={handleEnter} >

Check failure on line 69 in src/sections/upload-dataset-files/uploaded-files-list/add-tags-modal/AddTagsModal.tsx

View workflow job for this annotation

GitHub Actions / lint

Delete `·`

Check failure on line 69 in src/sections/upload-dataset-files/uploaded-files-list/add-tags-modal/AddTagsModal.tsx

View workflow job for this annotation

GitHub Actions / lint

Delete `·`
<Form.Group.Input
type="text"
placeholder={t('tags.addNewTag')}
value={tag}
onChange={(event: FormEvent<HTMLInputElement>) =>
setTag(event.currentTarget.value)
}
/>
<Button
className={styles.apply_button}
variant="secondary"
type="button"
{...{ size: 'sm' }}
withSpacing
onClick={addTagOption}>
{t('tags.apply')}
</Button>
</div>
<div className={styles.tag_info}>
{t('tags.availableTagOptions')}
{availableTags.join(', ')}
</div>
</Col>
</Form.Group>
</Form>
</div>
</Modal.Body>
<Modal.Footer>
<Button
variant="primary"
onClick={() => handleClose(true)}
disabled={tagsToAdd.length === 0}>
{t('addTags.saveChanges')}
</Button>
<Button
variant="secondary"
onClick={() => handleClose(false)}
title={t('addTags.cancelChanges')}>
{t('cancel')}
</Button>
</Modal.Footer>
</Modal>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import { useTranslation } from 'react-i18next'
interface FileFormProps {
file: FileUploadState
updateFiles: (file: FileUploadState[]) => void
tags: string[]
availableTags: string[]
editTagOptions: () => void
}

export function FileForm({ file, updateFiles, tags, editTagOptions }: FileFormProps) {
export function FileForm({ file, updateFiles, availableTags, editTagOptions }: FileFormProps) {
const { t } = useTranslation('uploadDatasetFiles')
const updateFileName = (file: FileUploadState, updated: string) => {
file.fileName = updated
Expand All @@ -26,8 +26,8 @@ export function FileForm({ file, updateFiles, tags, editTagOptions }: FileFormPr
file.description = updated
updateFiles([file])
}
const setTags = (file: FileUploadState, tags: string[]) => {
file.tags = tags
const setTags = (file: FileUploadState, newTags: string[]) => {
file.tags = [...newTags]
updateFiles([file])
}

Expand Down Expand Up @@ -84,7 +84,8 @@ export function FileForm({ file, updateFiles, tags, editTagOptions }: FileFormPr
<Col sm={9} className={styles.tags}>
<div className={styles.tags_select} title={t('fileForm.selectTags')}>
<SelectMultiple
options={tags}
options={availableTags}
defaultValue={file.tags}
onChange={(newTags) => setTags(file, newTags)}></SelectMultiple>
</div>
<Button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ interface FilesHeaderProps {
cleanup: () => void
addFiles: (fileUploadState: FileUploadState[]) => void
updateFilesRestricted: (fileUploadState: FileUploadState[], restricted: boolean) => void
showAddTagsModal: () => void
}

export function FilesHeader({
Expand All @@ -30,7 +31,8 @@ export function FilesHeader({
updateFiles,
cleanup,
addFiles,
updateFilesRestricted
updateFilesRestricted,
showAddTagsModal
}: FilesHeaderProps) {
const { t } = useTranslation('uploadDatasetFiles')
const [saving, setSaving] = useState(false)
Expand Down Expand Up @@ -93,13 +95,16 @@ export function FilesHeader({
icon={<PencilFill className={styles.icon_pencil} />}
id={'edit-files'}
title={t('filesHeader.editFiles')}>
<DropdownButtonItem onClick={showAddTagsModal} title={t('filesHeader.addTagsToSelected')}>
{t('filesHeader.addTags')}
</DropdownButtonItem>
<DropdownButtonItem onClick={() => updateRestriction(true)}>
{t('filesHeader.restrict')}
</DropdownButtonItem>
<DropdownButtonItem onClick={() => updateRestriction(false)}>
{t('filesHeader.unrestrict')}
</DropdownButtonItem>
<DropdownButtonItem onClick={deleteSelected} title="Delete selected">
<DropdownButtonItem onClick={deleteSelected} title={t('filesHeader.deleteSelected')}>
{t('delete')}
</DropdownButtonItem>
</DropdownButton>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ import { FormEvent, useState, KeyboardEvent } from 'react'
import { useTranslation } from 'react-i18next'

interface TagOptionsModalProps {
tags: string[]
availableTags: string[]
setTagOptions: (newTags: string[]) => void
show: boolean
hide: () => void
}

export function TagOptionsModal({ tags, setTagOptions, show, hide }: TagOptionsModalProps) {
export function TagOptionsModal({ availableTags, setTagOptions, show, hide }: TagOptionsModalProps) {

Check failure on line 13 in src/sections/upload-dataset-files/uploaded-files-list/tag-options-modal/TagOptionsModal.tsx

View workflow job for this annotation

GitHub Actions / lint

Replace `·availableTags,·setTagOptions,·show,·hide·` with `⏎··availableTags,⏎··setTagOptions,⏎··show,⏎··hide⏎`

Check failure on line 13 in src/sections/upload-dataset-files/uploaded-files-list/tag-options-modal/TagOptionsModal.tsx

View workflow job for this annotation

GitHub Actions / lint

Replace `·availableTags,·setTagOptions,·show,·hide·` with `⏎··availableTags,⏎··setTagOptions,⏎··show,⏎··hide⏎`
const { t } = useTranslation('uploadDatasetFiles')
const [tag, setTag] = useState('')
const addTagOption = () => {
if (tag && !tags.includes(tag)) {
setTagOptions([...tags, tag])
if (tag && !availableTags.includes(tag)) {
setTagOptions([...availableTags, tag])
setTag('')
}
}
Expand Down Expand Up @@ -61,7 +61,7 @@ export function TagOptionsModal({ tags, setTagOptions, show, hide }: TagOptionsM
</div>
<div className={styles.tag_info}>
{t('tags.availableTagOptions')}
{tags.join(', ')}
{availableTags.join(', ')}
</div>
</Col>
</Form.Group>
Expand Down

0 comments on commit 5efb5d2

Please sign in to comment.