Skip to content

Commit

Permalink
feat: use chip layout for custom categories on software page
Browse files Browse the repository at this point in the history
refactor: show modal after loading to avoid form resizing
  • Loading branch information
dmijatovic committed Feb 3, 2025
1 parent 9702aee commit 004f6c1
Show file tree
Hide file tree
Showing 21 changed files with 175 additions and 177 deletions.
9 changes: 6 additions & 3 deletions frontend/components/category/CategoriesDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-FileCopyrightText: 2024 Dusan Mijatovic (Netherlands eScience Center)
// SPDX-FileCopyrightText: 2024 Netherlands eScience Center
// SPDX-FileCopyrightText: 2024 - 2025 Dusan Mijatovic (Netherlands eScience Center)
// SPDX-FileCopyrightText: 2024 - 2025 Netherlands eScience Center
//
// SPDX-License-Identifier: Apache-2.0

Expand Down Expand Up @@ -53,7 +53,10 @@ export default function CategoriesDialog({
}

return (
<Dialog open fullScreen={smallScreen}>
<Dialog
open = {state !== 'loading'}
fullScreen={smallScreen}
>
<DialogTitle sx={{
fontSize: '1.5rem',
borderBottom: '1px solid',
Expand Down
6 changes: 3 additions & 3 deletions frontend/components/category/CategoriesDialogBody.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
// SPDX-FileCopyrightText: 2024 Dusan Mijatovic (Netherlands eScience Center)
// SPDX-FileCopyrightText: 2024 Netherlands eScience Center
// SPDX-FileCopyrightText: 2024 - 2025 Dusan Mijatovic (Netherlands eScience Center)
// SPDX-FileCopyrightText: 2024 - 2025 Netherlands eScience Center
//
// SPDX-License-Identifier: Apache-2.0

import Alert from '@mui/material/Alert'
import List from '@mui/material/List'
import {CategoryEntry} from '~/types/Category'
import {TreeNode} from '~/types/TreeNode'
import ContentLoader from '../layout/ContentLoader'
import {CategoryList} from './CategoryList'
import List from '@mui/material/List'

type CategoriesDialogBodyProps=Readonly<{
categories: TreeNode<CategoryEntry>[],
Expand Down
33 changes: 0 additions & 33 deletions frontend/components/category/CategoriesWithHeadlines.tsx

This file was deleted.

33 changes: 33 additions & 0 deletions frontend/components/category/CategoryIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-FileCopyrightText: 2025 Dusan Mijatovic (Netherlands eScience Center)
// SPDX-FileCopyrightText: 2025 Netherlands eScience Center
//
// SPDX-License-Identifier: Apache-2.0

import MuiCategoryIcon from '@mui/icons-material/Category'
import MuiQuestionMarkIcon from '@mui/icons-material/QuestionMark'
import MuiScienceIcon from '@mui/icons-material/Science'

/**
* Use lower case name of the icon import. For example '@mui/icons-material/QuestionMark' name is questionmark.
* Additional icons can be added here by importing them from library and extending MuiIconName type.
*/
export type MuiIconName = 'questionmark'|'category'|'science' | 'none'

export default function CategoryIcon({name}:Readonly<{name?:MuiIconName}>) {
// default is category icon
if (!name) return <MuiCategoryIcon />

// select based on name
switch(name.toLocaleLowerCase()){
case 'category':
return <MuiCategoryIcon />
case 'science':
return <MuiScienceIcon />
case 'questionmark':
return <MuiQuestionMarkIcon />
case 'none':
return null
default:
return <MuiCategoryIcon />
}
}
52 changes: 29 additions & 23 deletions frontend/components/category/CategoryTree.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-FileCopyrightText: 2023 - 2024 Felix Mühlbauer (GFZ) <[email protected]>
// SPDX-FileCopyrightText: 2023 - 2024 Helmholtz Centre Potsdam - GFZ German Research Centre for Geosciences
// SPDX-FileCopyrightText: 2024 Dusan Mijatovic (Netherlands eScience Center)
// SPDX-FileCopyrightText: 2024 - 2025 Dusan Mijatovic (Netherlands eScience Center)
// SPDX-FileCopyrightText: 2024 - 2025 Netherlands eScience Center
// SPDX-FileCopyrightText: 2024 Ewan Cahen (Netherlands eScience Center) <[email protected]>
// SPDX-FileCopyrightText: 2024 Netherlands eScience Center
//
// SPDX-License-Identifier: Apache-2.0

Expand Down Expand Up @@ -35,25 +35,31 @@ type TreeLevelProps = {
onRemoveHandler? : (event: React.MouseEvent<HTMLElement>) => void
}
const TreeLevel = ({items, showLongNames, onRemoveHandler}: TreeLevelProps) => {
return <ul className={'list-disc list-outside pl-6'}>
{items.map((item) => {
const category = item.getValue()

const children = item.children()
return (
<li key={category.id}>
<div className='flex flex-row justify-between items-start'>
<Tooltip title={showLongNames ? category.short_name : category.name} placement='left'>
<span className='pb-1'>{showLongNames ? category.name : category.short_name}</span>
</Tooltip>
{onRemoveHandler && children.length === 0 &&
<IconButton sx={{top: '-0.25rem'}} data-id={category.id} size='small'
onClick={onRemoveHandler}><CancelIcon fontSize='small'/></IconButton>}
</div>
{children.length > 0 &&
<TreeLevel items={children} showLongNames={showLongNames} onRemoveHandler={onRemoveHandler}/>}
</li>
)
})}
</ul>
return (
<ul className={'list-disc list-outside pl-6'}>
{items.map((item) => {
const category = item.getValue()
const children = item.children()
return (
<li key={category.id}>
<div className='flex flex-row justify-between items-start'>
<Tooltip title={showLongNames ? category.short_name : category.name} placement='left'>
<span className='pb-1'>{showLongNames ? category.name : category.short_name}</span>
</Tooltip>
{ onRemoveHandler && children.length === 0 ?
<IconButton sx={{top: '-0.25rem'}} data-id={category.id} size='small'onClick={onRemoveHandler}>
<CancelIcon fontSize='small'/>
</IconButton>
:null
}
</div>
{children.length > 0 ?
<TreeLevel items={children} showLongNames={showLongNames} onRemoveHandler={onRemoveHandler}/>
: null
}
</li>
)
})}
</ul>
)
}
17 changes: 9 additions & 8 deletions frontend/components/category/apiCategories.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// SPDX-FileCopyrightText: 2024 - 2025 Netherlands eScience Center
// SPDX-FileCopyrightText: 2024 Ewan Cahen (Netherlands eScience Center) <[email protected]>
// SPDX-FileCopyrightText: 2024 Netherlands eScience Center
// SPDX-FileCopyrightText: 2025 Dusan Mijatovic (Netherlands eScience Center)
//
// SPDX-License-Identifier: Apache-2.0

Expand All @@ -9,13 +10,13 @@ import {TreeNode} from '~/types/TreeNode'
import {shuffle} from '~/utils/jest/utils'

it('generates the category tree correctly', () => {
const grandChild1: CategoryEntry = {id: 'grandChild1', parent: 'child1', short_name: '', name: '', community: null, provenance_iri: null, properties: {}}
const grandChild2: CategoryEntry = {id: 'grandChild2', parent: 'child1', short_name: '', name: '', community: null, provenance_iri: null, properties: {}}
const grandChild3: CategoryEntry = {id: 'grandChild3', parent: 'child2', short_name: '', name: '', community: null, provenance_iri: null, properties: {}}
const grandChild4: CategoryEntry = {id: 'grandChild4', parent: 'child2', short_name: '', name: '', community: null, provenance_iri: null, properties: {}}
const child1: CategoryEntry = {id: 'child1', parent: 'parent', short_name: '', name: '', community: null, provenance_iri: null, properties: {}}
const child2: CategoryEntry = {id: 'child2', parent: 'parent', short_name: '', name: '', community: null, provenance_iri: null, properties: {}}
const parent: CategoryEntry = {id: 'parent', parent: null, short_name: '', name: '', community: null, provenance_iri: null, properties: {}}
const grandChild1: CategoryEntry = {id: 'grandChild1', parent: 'child1', short_name: '', name: '', community: null, provenance_iri: null, organisation: null, allow_projects: false, allow_software:false, properties: {}}
const grandChild2: CategoryEntry = {id: 'grandChild2', parent: 'child1', short_name: '', name: '', community: null, provenance_iri: null, organisation: null, allow_projects: false, allow_software:false, properties: {}}
const grandChild3: CategoryEntry = {id: 'grandChild3', parent: 'child2', short_name: '', name: '', community: null, provenance_iri: null, organisation: null, allow_projects: false, allow_software:false, properties: {}}
const grandChild4: CategoryEntry = {id: 'grandChild4', parent: 'child2', short_name: '', name: '', community: null, provenance_iri: null, organisation: null, allow_projects: false, allow_software:false, properties: {}}
const child1: CategoryEntry = {id: 'child1', parent: 'parent', short_name: '', name: '', community: null, provenance_iri: null, organisation: null, allow_projects: false, allow_software:false, properties: {}}
const child2: CategoryEntry = {id: 'child2', parent: 'parent', short_name: '', name: '', community: null, provenance_iri: null, organisation: null, allow_projects: false, allow_software:false, properties: {}}
const parent: CategoryEntry = {id: 'parent', parent: null, short_name: '', name: '', community: null, provenance_iri: null, organisation: null, allow_projects: false, allow_software:false, properties: {}}

const entries = [
parent,
Expand Down
4 changes: 2 additions & 2 deletions frontend/components/layout/TagChipFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import Chip from '@mui/material/Chip'
import SearchIcon from '@mui/icons-material/Search'
import Link from 'next/link'

type TagChipFilterProps={
type TagChipFilterProps=Readonly<{
label: string,
url?:string ,
title?: string
capitalize?: boolean
}
}>

export default function TagChipFilter({
url, label,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ describe('frontend/components/projects/edit/organisations/index.tsx', () => {
fireEvent.click(categoriesBtn)

// get organisation categories modal
const modal = screen.getByRole('dialog')
const modal = await screen.findByRole('dialog')

// close modal
const cancelBtn = within(modal).getByRole('button', {
Expand Down
10 changes: 5 additions & 5 deletions frontend/components/software/AboutLanguages.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-FileCopyrightText: 2022 - 2023 Dusan Mijatovic (dv4all)
// SPDX-FileCopyrightText: 2022 - 2023 dv4all
// SPDX-FileCopyrightText: 2022 - 2024 Netherlands eScience Center
// SPDX-FileCopyrightText: 2022 - 2025 Netherlands eScience Center
// SPDX-FileCopyrightText: 2022 Ewan Cahen (Netherlands eScience Center) <[email protected]>
// SPDX-FileCopyrightText: 2023 - 2024 Dusan Mijatovic (Netherlands eScience Center)
// SPDX-FileCopyrightText: 2023 - 2025 Dusan Mijatovic (Netherlands eScience Center)
// SPDX-FileCopyrightText: 2023 Christian Meeßen (GFZ) <[email protected]>
// SPDX-FileCopyrightText: 2023 Dusan Mijatovic (dv4all) (dv4all)
// SPDX-FileCopyrightText: 2023 Helmholtz Centre Potsdam - GFZ German Research Centre for Geosciences
Expand Down Expand Up @@ -92,8 +92,8 @@ export default function AboutLanguages({languages, platform}:
}

return (
<>
<div className="pt-8 pb-2">
<div>
<div className="pb-2">
<Code color="primary" />
<span className="text-primary pl-2">{label}</span>
</div>
Expand All @@ -103,6 +103,6 @@ export default function AboutLanguages({languages, platform}:
return <AboutLanguageItem key={props.language} {...props} />
})}
</ul>
</>
</div>
)
}
10 changes: 5 additions & 5 deletions frontend/components/software/AboutLicense.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2022 Dusan Mijatovic (dv4all)
// SPDX-FileCopyrightText: 2022 dv4all
// SPDX-FileCopyrightText: 2024 Dusan Mijatovic (Netherlands eScience Center)
// SPDX-FileCopyrightText: 2024 Netherlands eScience Center
// SPDX-FileCopyrightText: 2024 - 2025 Dusan Mijatovic (Netherlands eScience Center)
// SPDX-FileCopyrightText: 2024 - 2025 Netherlands eScience Center
//
// SPDX-License-Identifier: Apache-2.0

Expand All @@ -12,8 +12,8 @@ import {LicenseForSoftware} from '~/types/SoftwareTypes'
export default function AboutLicense({licenses}:{licenses:LicenseForSoftware[]}) {
// console.log('AboutLicense...', licenses)
return (
<>
<div className="pt-8 pb-2">
<div>
<div className="pb-2">
<AttachFileIcon color="primary" sx={{transform:'rotate(45deg)'}} />
<span className="text-primary pl-2">License</span>
</div>
Expand Down Expand Up @@ -42,6 +42,6 @@ export default function AboutLicense({licenses}:{licenses:LicenseForSoftware[]})
})}
</ul>
}
</>
</div>
)
}
6 changes: 3 additions & 3 deletions frontend/components/software/AboutPackageManagers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ function PackageManagerItem({item}:{item:PackageManager}){
export default function AboutPackageManagers({packages}:AboutPackageManagersProps) {
if (packages?.length > 0){
return (
<>
<div className="pt-8 pb-2">
<div>
<div className="pb-2">
<span className="font-bold text-primary">
<WidgetsIcon />
</span>
Expand All @@ -55,7 +55,7 @@ export default function AboutPackageManagers({packages}:AboutPackageManagersProp
<div className="flex gap-4 flex-wrap py-2">
{packages.map(item=><PackageManagerItem key={item.id} item={item} />)}
</div>
</>
</div>
)
}
// do not show section if no package managers
Expand Down
43 changes: 22 additions & 21 deletions frontend/components/software/AboutSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// SPDX-FileCopyrightText: 2021 - 2023 dv4all
// SPDX-FileCopyrightText: 2022 - 2023 Helmholtz Centre Potsdam - GFZ German Research Centre for Geosciences
// SPDX-FileCopyrightText: 2022 Christian Meeßen (GFZ) <[email protected]>
// SPDX-FileCopyrightText: 2023 - 2024 Dusan Mijatovic (Netherlands eScience Center)
// SPDX-FileCopyrightText: 2023 - 2024 Netherlands eScience Center
// SPDX-FileCopyrightText: 2023 - 2025 Dusan Mijatovic (Netherlands eScience Center)
// SPDX-FileCopyrightText: 2023 - 2025 Netherlands eScience Center
// SPDX-FileCopyrightText: 2023 Felix Mühlbauer (GFZ) <[email protected]>
//
// SPDX-License-Identifier: Apache-2.0
Expand All @@ -12,9 +12,10 @@ import {
ProgramingLanguages,
CodePlatform, KeywordForSoftware,
CategoriesForSoftware,
LicenseForSoftware} from '~/types/SoftwareTypes'
import {CategoriesWithHeadlines} from '~/components/category/CategoriesWithHeadlines'
LicenseForSoftware
} from '~/types/SoftwareTypes'
import PageContainer from '~/components/layout/PageContainer'
import CategoriesSidebar from '~/components/software/CategoriesSidebar'
import {PackageManager} from './edit/package-managers/apiPackageManager'
import AboutStatement from './AboutStatement'
import SoftwareKeywords from './SoftwareKeywords'
Expand Down Expand Up @@ -44,40 +45,40 @@ export default function AboutSection(props:AboutSectionType) {
repository, languages, platform, description_type = 'markdown',
image_id, packages
} = props
if (brand_name==='') return null

// extract only license text
// const license = licenses?.map(item => item.license)

function getSoftwareLogo() {
if (image_id !== null) {
return (
<SoftwareLogo image_id={image_id} brand_name={brand_name} />
)
}
return null
}
if (brand_name==='') return null

return (
<PageContainer className="flex flex-col px-4 py-12 lg:flex-row lg:pt-0 lg:pb-12">
<div className="flex-[3] 2xl:flex-[4] md:pr-12 overflow-hidden">
<PageContainer className="flex flex-col px-4 py-12 lg:flex-row lg:gap-12 lg:pb-12">
<div className="flex-[3] overflow-hidden md:pb-12">
<AboutStatement
brand_name={brand_name}
description={description}
description_type={description_type}
/>
</div>
<div className="flex-1">
{getSoftwareLogo()}
<CategoriesWithHeadlines categories={categories} />

{/* SIDEBAR */}
<div className="flex-1 flex flex-col gap-8">
{
image_id ?
<SoftwareLogo image_id={image_id} brand_name={brand_name} />
: null
}

<SoftwareKeywords keywords={keywords || []} />

<AboutLanguages languages={languages} platform={platform} />

<AboutLicense licenses={licenses || []} />

<AboutSourceCode
repository={repository ?? null}
platform={platform}
/>
<AboutPackageManagers packages={packages} />

<CategoriesSidebar categories={categories} />
</div>
</PageContainer>
)
Expand Down
Loading

0 comments on commit 004f6c1

Please sign in to comment.