diff options
author | Suchita Lad | 2025-01-27 17:47:48 +0530 |
---|---|---|
committer | Suchita Lad | 2025-01-30 16:37:12 +0530 |
commit | f6abdca3bdd11f1b663cd9f110fd95f97fc39bfe (patch) | |
tree | e1e4d0851ef565289e07c3290169b294be848198 | |
parent | 934018a67ed0e2034527dc40b8409c1edf581b6d (diff) | |
download | Common-Interface-Project-f6abdca3bdd11f1b663cd9f110fd95f97fc39bfe.tar.gz Common-Interface-Project-f6abdca3bdd11f1b663cd9f110fd95f97fc39bfe.tar.bz2 Common-Interface-Project-f6abdca3bdd11f1b663cd9f110fd95f97fc39bfe.zip |
Added Search logic and gallery data is updated from backend
-rw-r--r-- | blocks/eda-frontend/src/components/SchematicEditor/ToolbarExtension.js | 10 | ||||
-rw-r--r-- | blocks/eda-frontend/src/pages/Gallery.js | 122 | ||||
-rw-r--r-- | blocks/eda-frontend/src/redux/actions/actions.js | 2 | ||||
-rw-r--r-- | blocks/eda-frontend/src/redux/actions/dashboardActions.js | 13 | ||||
-rw-r--r-- | blocks/eda-frontend/src/redux/actions/saveSchematicActions.js | 10 | ||||
-rw-r--r-- | blocks/eda-frontend/src/redux/reducers/dashboardReducer.js | 10 | ||||
-rw-r--r-- | blocks/update_media.py | 146 |
7 files changed, 203 insertions, 110 deletions
diff --git a/blocks/eda-frontend/src/components/SchematicEditor/ToolbarExtension.js b/blocks/eda-frontend/src/components/SchematicEditor/ToolbarExtension.js index 6c08e03c..39e4c9ce 100644 --- a/blocks/eda-frontend/src/components/SchematicEditor/ToolbarExtension.js +++ b/blocks/eda-frontend/src/components/SchematicEditor/ToolbarExtension.js @@ -1,4 +1,4 @@ -import React, { forwardRef, useState } from 'react' +import React, { forwardRef, useState, useEffect } from 'react' import PropTypes from 'prop-types' import { AppBar, @@ -34,8 +34,7 @@ import { import { makeStyles } from '@material-ui/core/styles' import CloseIcon from '@material-ui/icons/Close' import { useSelector, useDispatch } from 'react-redux' -import { fetchSchematics, fetchSchematic, loadGallery } from '../../redux/actions/index' -import GallerySchSample from '../../utils/GallerySchSample' +import { fetchSchematics, fetchSchematic, loadGallery, fetchGallery } from '../../redux/actions/index' import { blue } from '@material-ui/core/colors' import { getDateTime as getDate } from '../../utils/GalleryUtils' @@ -388,9 +387,14 @@ export function OpenSchDialog (props) { const isAuthenticated = useSelector(state => state.authReducer.isAuthenticated) const user = useSelector(state => state.authReducer.user) const schematics = useSelector(state => state.dashboardReducer.schematics) + const GallerySchSample = useSelector(state => state.dashboardReducer.gallery) const dispatch = useDispatch() + useEffect(() => { + dispatch(fetchGallery()) + }, []) + const title = 'Open ' + process.env.REACT_APP_DIAGRAM_NAME const typography1 = "You don't have any saved " + process.env.REACT_APP_SMALL_DIAGRAMS_NAME + '...' return ( diff --git a/blocks/eda-frontend/src/pages/Gallery.js b/blocks/eda-frontend/src/pages/Gallery.js index 92bcfff9..a316c5a3 100644 --- a/blocks/eda-frontend/src/pages/Gallery.js +++ b/blocks/eda-frontend/src/pages/Gallery.js @@ -4,7 +4,8 @@ import PropTypes from 'prop-types' import { Button, Card, CardActionArea, CardActions, CardContent, CardMedia, Container, CssBaseline, Grid, Typography, FormControl, InputLabel, Select, MenuItem, Input } from '@material-ui/core' import { makeStyles } from '@material-ui/core/styles' import { Link as RouterLink } from 'react-router-dom' -import GallerySchSample from '../utils/GallerySchSample' +import { useDispatch, useSelector } from 'react-redux' +import { fetchGallery } from '../redux/actions/index' const useStyles = makeStyles((theme) => ({ mainHead: { @@ -47,7 +48,7 @@ function SchematicCard ({ sch }) { <Card> <CardActionArea> <CardMedia - component="img" + component='img' className={classes.media} image={imageName} title={sch.name} @@ -132,18 +133,17 @@ const BookDropdown = ({ onBookChange }) => { } return ( - <Grid container spacing={2} alignItems="center"> - <Grid item sm={6} xs={12}> + <Grid container spacing={2} alignItems='center'> + <Grid item xs={12}> <FormControl fullWidth> - <InputLabel id="book-label">Book</InputLabel> + <InputLabel id='book-label'>Book</InputLabel> <Select - labelId="book-label" + labelId='book-label' value={selectedBook} onChange={handleChange} - label="Book" + label='Book' > - {/* Option for All Books */} - <MenuItem key="all-books" value="all"> + <MenuItem key='all-books' value='all'> All Books ({books?.reduce((total, book) => total + (book.example_count || 0), 0)}) </MenuItem> {/* Render dynamic book options */} @@ -155,13 +155,48 @@ const BookDropdown = ({ onBookChange }) => { </Select> </FormControl> </Grid> - <Grid item sm={6} xs={12}> + </Grid> + ) +} + +BookDropdown.propTypes = { + onBookChange: PropTypes.func.isRequired +} + +const SearchComponent = ({ onSearch }) => { + const [searchTerm, setSearchTerm] = useState('') + const [setFilteredResults] = useState([]) + const [data] = useState([]) + + const handleSearch = (event) => { + const value = event.target.value.toLowerCase() + setSearchTerm(value) + onSearch(value) + + // Filter results + if (value) { + const results = data.filter( + (item) => + item.name.toLowerCase().includes(value) || + item.description.toLowerCase().includes(value) + ) + setFilteredResults(results) + } else { + setFilteredResults([]) + } + } + + return ( + <Grid container spacing={2}> + <Grid item xs={12}> <FormControl fullWidth> - <InputLabel htmlFor="search-input">Search</InputLabel> + <InputLabel htmlFor='search-input'>Search</InputLabel> <Input - id="search-input" - type="text" - placeholder="Search books, examples..." + id='search-input' + type='text' + placeholder='Search books, examples...' + value={searchTerm} + onChange={handleSearch} /> </FormControl> </Grid> @@ -169,51 +204,76 @@ const BookDropdown = ({ onBookChange }) => { ) } -BookDropdown.propTypes = { - onBookChange: PropTypes.func.isRequired // This defines the expected type for the prop +SearchComponent.propTypes = { + onSearch: PropTypes.func.isRequired } export default function Gallery () { const classes = useStyles() + const GallerySchSample = useSelector(state => state.dashboardReducer.gallery) // State to store the selected book ID - const [selectedBookId, setSelectedBookId] = useState('') // Default is empty for no selection + const [selectedBookId, setSelectedBookId] = useState('') + const [searchTerm, setSearchTerm] = useState('') + + const dispatch = useDispatch() + + useEffect(() => { + dispatch(fetchGallery()) + }, []) // Handle dropdown selection change const handleBookChange = (bookId) => { setSelectedBookId(bookId) } - // Filter schematics based on the selected book ID + // Handle search term change + const handleSearch = (term) => { + setSearchTerm(term) + } + const filteredSchematics = + // Filter based on selected book ID first selectedBookId === '' // If no book is selected, show nothing ? [] : selectedBookId === 'all' - ? GallerySchSample // Show all schematics for "All Books" + ? GallerySchSample // Show all schematics for 'All Books' : GallerySchSample.filter((sch) => sch.book_id === parseInt(selectedBookId)) + // Then, filter based on the search term (independent from book selection) + const finalfilteredSchematics = filteredSchematics.filter((sch) => { + return ( + sch.name.toLowerCase().includes(searchTerm.toLowerCase()) || + sch.description.toLowerCase().includes(searchTerm.toLowerCase()) + ) + }) + return ( <div className={classes.root}> <CssBaseline /> - <Container maxWidth="lg" className={classes.header}> - <Grid - container - direction="row" - justifyContent="flex-start" - alignItems="flex-start" - alignContent="center" - spacing={3} - > + <Container maxWidth='lg' className={classes.header}> + <Grid container direction='row' justifyContent='flex-start' alignItems='flex-start' alignContent='center' spacing={3}> {/* Gallery Header */} <Grid item xs={12}> <MainCard /> </Grid> - {/* Book Dropdown */} - <BookDropdown onBookChange={handleBookChange} /> + <Grid item xs={12}> + <Grid container spacing={2}> + {/* BookDropdown */} + <Grid item xs={12} md={6}> + <BookDropdown onBookChange={handleBookChange} /> + </Grid> + + {/* SearchComponent */} + <Grid item xs={12} md={6}> + <SearchComponent onSearch={handleSearch} /> + </Grid> + </Grid> + </Grid> {/* Display a message or blank gallery */} - {filteredSchematics.length === 0 ? (<Grid item xs={12}><Typography variant="h6" align="center" color="textSecondary">No schematics to display. Please select a book.</Typography></Grid>) : (filteredSchematics.map((sch) => (<Grid item xs={12} sm={6} lg={4} key={sch.save_id}><SchematicCard sch={sch} /></Grid>)))}</Grid> + {finalfilteredSchematics.length === 0 ? (<Grid item xs={12}><Typography variant='h6' align='center' color='textSecondary'>No schematics to display. Please select a book.</Typography></Grid>) : (finalfilteredSchematics.map((sch) => (<Grid item xs={12} sm={6} lg={4} key={sch.save_id}><SchematicCard sch={sch} /></Grid>)))}</Grid> </Container> </div> ) diff --git a/blocks/eda-frontend/src/redux/actions/actions.js b/blocks/eda-frontend/src/redux/actions/actions.js index a51e4bcc..fe603645 100644 --- a/blocks/eda-frontend/src/redux/actions/actions.js +++ b/blocks/eda-frontend/src/redux/actions/actions.js @@ -48,3 +48,5 @@ export const LOAD_GALLERY = 'LOAD_GALLERY' // Action for fetching on-cloud saved schematics for authenticated user to display in dashboard export const FETCH_SCHEMATICS = 'FETCH_SCHEMATICS' +export const FETCH_GALLERY = 'FETCH_GALLERY' +export const FETCH_DIAGRAM = 'FETCH_DIAGRAM' diff --git a/blocks/eda-frontend/src/redux/actions/dashboardActions.js b/blocks/eda-frontend/src/redux/actions/dashboardActions.js index 789a55c1..210c1a74 100644 --- a/blocks/eda-frontend/src/redux/actions/dashboardActions.js +++ b/blocks/eda-frontend/src/redux/actions/dashboardActions.js @@ -27,6 +27,19 @@ export const fetchSchematics = () => (dispatch, getState) => { .catch((err) => { console.error(err) }) } +export const fetchGallery = () => (dispatch) => { + api.get('save/gallery') + .then( + (res) => { + dispatch({ + type: actions.FETCH_GALLERY, + payload: res.data + }) + } + ) + .catch((err) => { console.error(err) }) +} + // Api call for deleting saved schematic export const deleteSchematic = (saveId) => (dispatch, getState) => { const token = getState().authReducer.token diff --git a/blocks/eda-frontend/src/redux/actions/saveSchematicActions.js b/blocks/eda-frontend/src/redux/actions/saveSchematicActions.js index 53c67034..81a61737 100644 --- a/blocks/eda-frontend/src/redux/actions/saveSchematicActions.js +++ b/blocks/eda-frontend/src/redux/actions/saveSchematicActions.js @@ -1,10 +1,11 @@ +import { useEffect } from 'react' import * as actions from './actions' import queryString from 'query-string' import api from '../../utils/Api' -import GallerySchSample from '../../utils/GallerySchSample' import { renderGalleryXML } from '../../components/SchematicEditor/Helper/ToolbarTools' -import { setTitle } from './index' +import { setTitle, fetchGallery } from './index' import { transformXcos } from '../../utils/GalleryUtils' +import { useSelector } from 'react-redux' export const setLoadingDiagram = (isLoading) => (dispatch) => { dispatch({ @@ -166,6 +167,11 @@ export const setSchShared = (share) => (dispatch, getState) => { // Action for Loading Gallery schematics export const loadGallery = (saveId) => (dispatch) => { + const GallerySchSample = useSelector(state => state.dashboardReducer.gallery) + + useEffect(() => { + dispatch(fetchGallery()) + }, []) // Find the gallery schematic that matches the given save_id const data = GallerySchSample.find(sample => sample.save_id === saveId) diff --git a/blocks/eda-frontend/src/redux/reducers/dashboardReducer.js b/blocks/eda-frontend/src/redux/reducers/dashboardReducer.js index ce52b52e..b347f8da 100644 --- a/blocks/eda-frontend/src/redux/reducers/dashboardReducer.js +++ b/blocks/eda-frontend/src/redux/reducers/dashboardReducer.js @@ -1,7 +1,8 @@ import * as actions from '../actions/actions' const InitialState = { - schematics: [] + schematics: [], + gallery: [] } export default function dashboardReducer (state = InitialState, action) { @@ -13,6 +14,13 @@ export default function dashboardReducer (state = InitialState, action) { } } + case actions.FETCH_GALLERY: { + return { + ...state, + gallery: action.payload + } + } + default: return state } diff --git a/blocks/update_media.py b/blocks/update_media.py index 5523d964..90894628 100644 --- a/blocks/update_media.py +++ b/blocks/update_media.py @@ -5,95 +5,95 @@ import shutil import sqlite3 -def empty_table(db_path, table_name): - """ - Empties all rows in the specified table. - """ - try: - # Connect to the database - conn = sqlite3.connect(db_path) - cursor = conn.cursor() +# def empty_table(db_path, table_name): +# """ +# Empties all rows in the specified table. +# """ +# try: +# # Connect to the database +# conn = sqlite3.connect(db_path) +# cursor = conn.cursor() - # Validate table name to avoid SQL injection - if not table_name.isidentifier(): - raise ValueError(f"Invalid table name: {table_name}") +# # Validate table name to avoid SQL injection +# if not table_name.isidentifier(): +# raise ValueError(f"Invalid table name: {table_name}") - # SQL to delete all rows from the table - sql = f"DELETE FROM {table_name};" +# # SQL to delete all rows from the table +# sql = f"DELETE FROM {table_name};" - # Execute the query - cursor.execute(sql) +# # Execute the query +# cursor.execute(sql) - # Commit the changes - conn.commit() - print(f"Table '{table_name}' has been emptied successfully.") +# # Commit the changes +# conn.commit() +# print(f"Table '{table_name}' has been emptied successfully.") - except sqlite3.Error as e: - print(f"Database error while emptying the table: {e}") +# except sqlite3.Error as e: +# print(f"Database error while emptying the table: {e}") - except ValueError as ve: - print(ve) +# except ValueError as ve: +# print(ve) - finally: - # Close the database connection - if conn: - conn.close() +# finally: +# # Close the database connection +# if conn: +# conn.close() -def populate_table(db_path, table_name, json_path): - """ - Populates the specified table with data from a JSON file. - """ - conn = None - try: - # Load data from JSON file - with open(json_path, 'r') as json_file: - data = json.load(json_file) +# def populate_table(db_path, table_name, json_path): +# """ +# Populates the specified table with data from a JSON file. +# """ +# conn = None +# try: +# # Load data from JSON file +# with open(json_path, 'r') as json_file: +# data = json.load(json_file) - # Connect to the database - conn = sqlite3.connect(db_path) - cursor = conn.cursor() +# # Connect to the database +# conn = sqlite3.connect(db_path) +# cursor = conn.cursor() - # Validate table name to avoid SQL injection - if not table_name.isidentifier(): - raise ValueError(f"Invalid table name: {table_name}") +# # Validate table name to avoid SQL injection +# if not table_name.isidentifier(): +# raise ValueError(f"Invalid table name: {table_name}") - # Insert data into the table - for record in data: - if not isinstance(record, dict): - print(f"Skipping invalid record: {record}") - continue +# # Insert data into the table +# for record in data: +# if not isinstance(record, dict): +# print(f"Skipping invalid record: {record}") +# continue - # Add save_time if not present - if 'save_time' not in record: - record['save_time'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") +# # Add save_time if not present +# if 'save_time' not in record: +# record['save_time'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - columns = ", ".join(record.keys()) - placeholders = ", ".join("?" for _ in record.values()) - sql = f"INSERT INTO {table_name} ({columns}) VALUES ({placeholders})" +# columns = ", ".join(record.keys()) +# placeholders = ", ".join("?" for _ in record.values()) +# sql = f"INSERT INTO {table_name} ({columns}) VALUES ({placeholders})" - try: - cursor.execute(sql, tuple(record.values())) - except sqlite3.Error as e: - print(f"Failed to insert record {record}: {e}") +# try: +# cursor.execute(sql, tuple(record.values())) +# except sqlite3.Error as e: +# print(f"Failed to insert record {record}: {e}") - # Commit the changes - conn.commit() - print(f"Table '{table_name}' has been populated successfully.") +# # Commit the changes +# conn.commit() +# print(f"Table '{table_name}' has been populated successfully.") - except sqlite3.Error as e: - print(f"Database error while populating the table: {e}") +# except sqlite3.Error as e: +# print(f"Database error while populating the table: {e}") - except FileNotFoundError: - print(f"JSON file '{json_path}' not found.") +# except FileNotFoundError: +# print(f"JSON file '{json_path}' not found.") - except ValueError as ve: - print(ve) +# except ValueError as ve: +# print(ve) - finally: - # Close the database connection - if conn: - conn.close() +# finally: +# # Close the database connection +# if conn: +# conn.close() def update_media_column(db_path, table_name): @@ -179,13 +179,13 @@ if __name__ == "__main__": statesave_table = "saveAPI_statesave" # Path to the JSON file containing the data - json_file_path = "eda-frontend/src/utils/GallerySchSample.json" + # json_file_path = "eda-frontend/src/utils/GallerySchSample.json" # Empty the table first - empty_table(database_path, table_name) + # empty_table(database_path, table_name) - # Populate the table with JSON data - populate_table(database_path, table_name, json_file_path) + # # Populate the table with JSON data + # populate_table(database_path, table_name, json_file_path) update_media_column(database_path, table_name) |