From b277b3e085d10034c882494fc0484d5f24f0ec61 Mon Sep 17 00:00:00 2001 From: Daniel Pettersson <danpe975@student.liu.se> Date: Tue, 16 Apr 2024 14:01:40 +0200 Subject: [PATCH] MultiSelectText component added offering adaptable selection views depending on input prop, three of those are currently utilised as an example. Also starting to let map reqion selection control the value of the autocomplete search component in the search, currently a WIP as of now --- .../src/Components/Search/MultiSelectText.jsx | 31 ++++- .../Components/Search/MultiSelectText2.jsx | 50 ------- frontend/src/Components/Search/Searchbar.jsx | 128 +++++++++++------- .../src/{Components/Search => Css}/Search.css | 2 +- frontend/src/Pages/Dashboard/Dashboard.jsx | 2 +- frontend/src/Pages/Dashboard/Map.jsx | 4 +- 6 files changed, 109 insertions(+), 108 deletions(-) delete mode 100644 frontend/src/Components/Search/MultiSelectText2.jsx rename frontend/src/{Components/Search => Css}/Search.css (85%) diff --git a/frontend/src/Components/Search/MultiSelectText.jsx b/frontend/src/Components/Search/MultiSelectText.jsx index 281307c..1933298 100644 --- a/frontend/src/Components/Search/MultiSelectText.jsx +++ b/frontend/src/Components/Search/MultiSelectText.jsx @@ -1,23 +1,36 @@ import { styled } from '@mui/material/styles'; import Typography from '@mui/material/Typography'; import React from 'react'; - +import * as MUI from '@mui/material'; const Wrapper = styled('div')(({ theme }) => ({ display: 'flex', flexDirection: 'column', alignItems: 'flex-start', gap: theme.spacing(1), cursor: 'pointer', // Make the entire area clickable + maxHeight: '130px', // Set a fixed height + overflowY: 'auto', // Make the content scrollable + border: `2px solid black`, // Solid border })); const SelectedText = styled(Typography)(({ theme, selected }) => ({ - color: selected ? theme.palette.primary.main : theme.palette.text.primary, + width: '100%', // Make Typography span the whole width + color: selected ? 'black' : theme.palette.text.primary, // Set text color to black for selected options fontWeight: selected ? 'bold' : 'normal', + backgroundColor: selected ? theme.palette.grey[400] : 'transparent', // Darker grey background when clicked for non-selected options + '&:hover': { + backgroundColor: selected ? theme.palette.grey[400] : theme.palette.grey[200], // Grey background on hover for non-selected options + }, + '&:focus': { + backgroundColor: theme.palette.grey[400], // Darker grey background when clicked + color: 'black', // Set text color to black when clicked + }, })); -const options = ['Antal nominerade', 'Andel nominerade', 'Antal valda', 'Andel valda', 'Antal ej valda']; +function MultiSelectText({ selection }) { + const options = selection.options; + const title = selection.title; -function MultiSelectText() { const [selectedValues, setSelectedValues] = React.useState([]); const handleClick = (option) => { @@ -34,8 +47,12 @@ function MultiSelectText() { }; return ( + <div> + <MUI.Typography variant='h6' fontWeight={'bold'}> + {title} +</MUI.Typography> <Wrapper> - {options.map((option) => ( + {options.slice(0, 5).map((option) => ( <SelectedText key={option} onClick={() => handleClick(option)} @@ -45,6 +62,8 @@ function MultiSelectText() { </SelectedText> ))} </Wrapper> + </div> ); } -export default MultiSelectText; \ No newline at end of file + +export default MultiSelectText; diff --git a/frontend/src/Components/Search/MultiSelectText2.jsx b/frontend/src/Components/Search/MultiSelectText2.jsx deleted file mode 100644 index afe3824..0000000 --- a/frontend/src/Components/Search/MultiSelectText2.jsx +++ /dev/null @@ -1,50 +0,0 @@ -import { styled } from '@mui/material/styles'; -import Typography from '@mui/material/Typography'; -import React from 'react'; - -const Wrapper = styled('div')(({ theme }) => ({ - display: 'flex', - flexDirection: 'column', - alignItems: 'flex-start', - gap: theme.spacing(1), - cursor: 'pointer', // Make the entire area clickable -})); - -const SelectedText = styled(Typography)(({ theme, selected }) => ({ - color: selected ? theme.palette.primary.main : theme.palette.text.primary, - fontWeight: selected ? 'bold' : 'normal', -})); - -const options = ['män', 'kvinnor', 'totalt']; - -function MultiSelectText2() { - const [selectedValues, setSelectedValues] = React.useState([]); - - const handleClick = (option) => { - const currentIndex = selectedValues.indexOf(option); - const newSelectedValues = [...selectedValues]; - - if (currentIndex === -1) { - newSelectedValues.push(option); - } else { - newSelectedValues.splice(currentIndex, 1); - } - - setSelectedValues(newSelectedValues); - }; - - return ( - <Wrapper> - {options.map((option) => ( - <SelectedText - key={option} - onClick={() => handleClick(option)} - selected={selectedValues.includes(option)} - > - {option} - </SelectedText> - ))} - </Wrapper> - ); -} -export default MultiSelectText2; \ No newline at end of file diff --git a/frontend/src/Components/Search/Searchbar.jsx b/frontend/src/Components/Search/Searchbar.jsx index aabf99e..4b10f3c 100644 --- a/frontend/src/Components/Search/Searchbar.jsx +++ b/frontend/src/Components/Search/Searchbar.jsx @@ -1,57 +1,89 @@ -import React from 'react' +import React, { useState, useEffect, useMemo } from 'react'; import * as MUI from '@mui/material'; -import MultiSelectText from './MultiSelectText' -import MultiSelectText2 from './MultiSelectText2'; -import "./Search.css" -export const Searchbar = () => { - - - const provinceOptions = [ - { label: 'Stockholm', id: 1 }, - { label: 'Uppsala', id: 3 }, - { label: 'Södermanland', id: 4 }, - { label: 'Östergötland', id: 5 }, - { label: 'Jönköping', id: 6 }, - { label: 'Kronobergs', id: 7 }, - { label: 'Kalmar', id: 8 }, - { label: 'Gotland', id: 9 }, - { label: 'Blekinge', id: 10 }, - { label: 'Skåne', id: 12 }, - { label: 'Halland', id: 13 }, - { label: 'Västra Götaland', id: 14 }, - { label: 'Värmland', id: 17 }, - { label: 'Örebro', id: 18 }, - { label: 'Västmanland', id: 19 }, - { label: 'Dalarna', id: 20 }, - { label: 'Gävleborg', id: 21 }, - { label: 'Västernorrland', id: 22 }, - { label: 'Jämtland', id: 23 }, - { label: 'Västerbotten', id: 24 }, - { label: 'Norrbotten', id: 25 } - ]; - const optionsAntal = ['Antal nominerade', 'Andel nominerade', 'Antal valda', 'Andel valda', 'Antal ej valda']; - const optionsKön = ['män', 'kvinnor', 'totalt']; +import MultiSelectText from './MultiSelectText'; +import "../../Css/Search.css"; + +export const Searchbar = ({ data }) => { + + const [selectedProvince, setSelectedProvince] = useState(null); + + useEffect(() => { + if (data) { + const selected = provinceOptions.find(option => option.label === data.label && option.id === data.id); + if (selected) { + setSelectedProvince(selected); + } else { + setSelectedProvince(null); // Reset to null if the province doesn't exist in the options + } + } + }, [data]); + + const selection1 = { + title: "Tabellinnehåll", + options: ['Antal nominerade', 'Andel nominerade', 'Antal valda', 'Andel valda', 'Antal ej valda'] + }; + + const selection2 = { + title: "Kön", + options: ['män', 'kvinnor', 'totalt'] + }; + + const selection3 = { + title: "Valår", + options: ['1995', '1999', '2004', '2009', '2014', '2019'] + }; + + const provinceOptions = [ + { label: 'Stockholm', id: 1 }, + { label: 'Uppsala', id: 3 }, + { label: 'Södermanland', id: 4 }, + { label: 'Östergötland', id: 5 }, + { label: 'Jönköping', id: 6 }, + { label: 'Kronobergs', id: 7 }, + { label: 'Kalmar', id: 8 }, + { label: 'Gotland', id: 9 }, + { label: 'Blekinge', id: 10 }, + { label: 'Skåne', id: 12 }, + { label: 'Halland', id: 13 }, + { label: 'Västra Götaland', id: 14 }, + { label: 'Värmland', id: 17 }, + { label: 'Örebro', id: 18 }, + { label: 'Västmanland', id: 19 }, + { label: 'Dalarna', id: 20 }, + { label: 'Gävleborg', id: 21 }, + { label: 'Västernorrland', id: 22 }, + { label: 'Jämtland', id: 23 }, + { label: 'Västerbotten', id: 24 }, + { label: 'Norrbotten', id: 25 } + ]; + + const handleProvinceChange = (event, newValue) => { + setSelectedProvince(newValue); + }; + + const isOptionEqualToValue = (option, value) => option.label === value.label && option.id === value.id; + + const memoizedProvince = useMemo(() => selectedProvince, [selectedProvince]); + return ( <div> - <MUI.Autocomplete + <MUI.Autocomplete disablePortal id="combo-box-demo" options={provinceOptions} + value={memoizedProvince} + onChange={handleProvinceChange} + getOptionLabel={(option) => option.label} + getOptionSelected={isOptionEqualToValue} // Custom equality test sx={{ width: 300 }} - renderInput={(params) => <MUI.TextField {...params} label="Län" />}> - - </MUI.Autocomplete> - <MUI.Typography variant='h6' fontWeight={'bold'}> - Tabellinnehål - </MUI.Typography> - <div className='multi_select'><MultiSelectText/></div> - <MUI.Typography variant='h6' fontWeight={'bold'}> - Kön - </MUI.Typography> - <div className='multi_select'><MultiSelectText2 /></div> - - + renderInput={(params) => <MUI.TextField {...params} label="Län" />} + /> + + <div className='multi_select'><MultiSelectText selection={selection1} /></div> + <div className='multi_select'><MultiSelectText selection={selection2} /></div> + <div className='multi_select'><MultiSelectText selection={selection3} /></div> </div> + ); +}; - ) -} +export default Searchbar; diff --git a/frontend/src/Components/Search/Search.css b/frontend/src/Css/Search.css similarity index 85% rename from frontend/src/Components/Search/Search.css rename to frontend/src/Css/Search.css index 52f2c3a..f87be40 100644 --- a/frontend/src/Components/Search/Search.css +++ b/frontend/src/Css/Search.css @@ -5,7 +5,7 @@ .multi_select{ margin: 5px; margin-top: 20px; - border-style: solid; + padding: 2px; } \ No newline at end of file diff --git a/frontend/src/Pages/Dashboard/Dashboard.jsx b/frontend/src/Pages/Dashboard/Dashboard.jsx index 9e6856d..d34c41b 100644 --- a/frontend/src/Pages/Dashboard/Dashboard.jsx +++ b/frontend/src/Pages/Dashboard/Dashboard.jsx @@ -20,7 +20,7 @@ export const Dashboard = () => { </div> <div className='search_container'> - <Searchbar/> + <Searchbar data={data}/> </div> <div className='table_container'> diff --git a/frontend/src/Pages/Dashboard/Map.jsx b/frontend/src/Pages/Dashboard/Map.jsx index 3daa106..f689b78 100644 --- a/frontend/src/Pages/Dashboard/Map.jsx +++ b/frontend/src/Pages/Dashboard/Map.jsx @@ -49,10 +49,10 @@ const Map = ({handlerFunction}) => { .attr('stroke', 'black') .on('click', function(event, d){ //OnClick event handler // Handle the click event here - const data = {province: d.properties.name, id: d.properties.l_id}; + const data = {label: d.properties.name, id: d.properties.l_id}; handlerFunction(data); - console.log("province: " + data.province +' id: '+data.id); + console.log("province: " + data.label +' id: '+data.id); }).on('mouseenter', function(event, d) {//OnMouseEnter event handler // Update region state -- GitLab