Skip to content
Snippets Groups Projects
Commit dc7a6acc authored by Abbas Jafari's avatar Abbas Jafari :speech_balloon:
Browse files

Merge branch 'trym' into 'master'

Search with filtering

See merge request it2810-h21/team-54/project-3!6
parents 9270eb3c 7ec002ac
No related branches found
No related tags found
No related merge requests found
...@@ -17,13 +17,30 @@ ...@@ -17,13 +17,30 @@
background-color: gray; background-color: gray;
min-height: 5vh; min-height: 5vh;
display: flex; display: flex;
flex-direction: column; flex-direction: row;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: calc(10px + 2vmin); font-size: calc(10px + 2vmin);
color: white; color: white;
font-size: large;
margin: auto;
} }
#textfield1, #textfield2, #checkbox1 {
/* background-color: red; */
margin: 1em;
}
/*
#textfield2 {
background-color: yellow;
}
#checkbox1 {
background-color: green;
} */
.App-link { .App-link {
color: #61dafb; color: #61dafb;
} }
......
...@@ -5,7 +5,9 @@ import { inject, observer } from 'mobx-react'; ...@@ -5,7 +5,9 @@ import { inject, observer } from 'mobx-react';
import * as services from './services'; import * as services from './services';
type MyState = { type MyState = {
input: string inputTitle: string,
inputGenre: string,
checkbox1_checked: boolean
}; };
interface MoviesProps { interface MoviesProps {
...@@ -17,7 +19,9 @@ class Header extends React.Component<MoviesProps, MyState> { ...@@ -17,7 +19,9 @@ class Header extends React.Component<MoviesProps, MyState> {
super(props); super(props);
this.state = { this.state = {
input: '' inputTitle: '',
inputGenre: '',
checkbox1_checked: false
} }
} }
...@@ -25,7 +29,12 @@ class Header extends React.Component<MoviesProps, MyState> { ...@@ -25,7 +29,12 @@ class Header extends React.Component<MoviesProps, MyState> {
render() { render() {
return ( return (
<div className="header"> <div className="header">
<input type="text" placeholder="Search for movies..." onChange={this.handleChange}></input> Movie title:
<input type="text" placeholder="Search for movie titles..." onChange={this.handleChange} id="textfield1"></input>
Movie genre:
<input type="text" placeholder="Filter on genre..." onChange={this.handleChange} id="textfield2"></input>
Order by year:
<input type="checkbox" id="checkbox1" onChange={this.handleChange}></input>
<button onClick={this.search}>Search</button> <button onClick={this.search}>Search</button>
</div> </div>
...@@ -33,21 +42,44 @@ class Header extends React.Component<MoviesProps, MyState> { ...@@ -33,21 +42,44 @@ class Header extends React.Component<MoviesProps, MyState> {
} }
handleChange = (e: any) => { handleChange = (event: any) => {
this.setState({ input: e.target.value }) let element = event.target.id
if (event.keyCode === 13) { // not working
console.log("enter")
this.search()
} }
if (element == 'textfield1') {
this.setState({ inputTitle: event.target.value })
}
if (element == 'textfield2') {
this.setState({ inputGenre: event.target.value })
}
else if (element == 'checkbox1') {
this.setState({ checkbox1_checked: event.target.checked })
}
// else if (element == 'checkbox12') {
// this.setState({ checkbox2_checked: event.target.checked })
// }
}
// TODO mysql ordering not working because of graphql scrambling
search = () => { search = () => {
this.getMovieByColumnType(services.ColumnType.Title, this.state.input, 'id title genre description'); this.getMoviesBySearch('id title genre description', this.state.inputTitle, this.state.inputGenre, this.state.checkbox1_checked);
} }
getMovieByColumnType(columnType : services.ColumnType, value: string, neededData: string) { getMovieByColumnType(columnType : services.ColumnType, value: string, neededData: string) {
services.queryFetch(services.generateQuery(columnType, value, neededData) , 'POST') services.queryFetch(services.generateQuery(columnType, value, neededData))
.then(res => res.json()) .then(res => res.json())
.then(res => this.props.moviesStore.setMovies(res.data.getMovieByColumnType)) .then(res => this.props.moviesStore.setMovies(res.data.getMovieByColumnType))
} }
getMoviesBySearch(neededData: string, title: string, genre: string, order: boolean) {
services.queryFetch(services.generateSearchQuery(neededData, title, genre, order))
.then(res => res.json())
.then(res => this.props.moviesStore.setMovies(res.data.getMoviesBySearch))
}
} }
......
...@@ -3,7 +3,7 @@ import { MoviesStore, MoviesStoreImplementation } from "./MoviesStore"; ...@@ -3,7 +3,7 @@ import { MoviesStore, MoviesStoreImplementation } from "./MoviesStore";
import { inject, observer } from 'mobx-react'; import { inject, observer } from 'mobx-react';
import * as services from './services'; import * as services from './services';
type MyProps = {}; // type MyProps = {};
type MyState = { type MyState = {
movies: any movies: any
}; };
...@@ -27,14 +27,14 @@ class Movies extends React.Component<MoviesProps, MyState> { ...@@ -27,14 +27,14 @@ class Movies extends React.Component<MoviesProps, MyState> {
getAllMovies() { getAllMovies() {
services.queryFetch(services.getAllMoviesQuery, 'POST') services.queryFetch(services.getAllMoviesQuery)
.then(res => res.json()) .then(res => res.json())
.then(res => this.props.moviesStore.setMovies(res.data.getAllMovies)) .then(res => this.props.moviesStore.setMovies(res.data.getAllMovies))
} }
getMovieByColumnType(columnType : services.ColumnType, value: string, neededData: string) { getMovieByColumnType(columnType : services.ColumnType, value: string, neededData: string) {
services.queryFetch(services.generateQuery(columnType, value, neededData) , 'POST') services.queryFetch(services.generateQuery(columnType, value, neededData))
.then(res => res.json()) .then(res => res.json())
.then(res => this.props.moviesStore.setMovies(res)) .then(res => this.props.moviesStore.setMovies(res))
} }
......
export function queryFetch(query: String, method: string) { export function queryFetch(query: String) {
return fetch('/graphql', { return fetch('/graphql', {
method: method, method: 'POST',
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify({ body: JSON.stringify({
query: query, query: query,
...@@ -61,6 +61,17 @@ export function generateQuery(columnType: ColumnType, value: string, neededData: ...@@ -61,6 +61,17 @@ export function generateQuery(columnType: ColumnType, value: string, neededData:
} }
export function generateSearchQuery(neededData: string, title: string, genre: string, order: boolean){
let query = `
query {
getMoviesBySearch(title: "${title}", genre: "${genre}", order: ${order}) {
${neededData}
}
}`;
console.log(query)
return query
}
export const getAllMoviesQuery = ` export const getAllMoviesQuery = `
query { query {
getAllMovies { getAllMovies {
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
}, },
"scripts": { "scripts": {
"start": "nodemon src/server.ts --exec ts-node", "start": "nodemon src/server.ts --exec ts-node",
"build": "react-scripts build", "build": "tsc --build",
"test": "react-scripts test", "test": "react-scripts test",
"eject": "react-scripts eject" "eject": "react-scripts eject"
}, },
......
declare var require: any declare var require: any
// id,title,genre,rating_dice_throw,year,director_first_name,director_last_name,description,cover_image
const movieData = require("../movies_with_image.json")
var express = require('express'); var express = require('express');
var { graphqlHTTP } = require('express-graphql'); var { graphqlHTTP } = require('express-graphql');
var { GraphQLObjectType, GraphQLSchema, buildSchema, GraphQLInt, GraphQLString, GraphQLList } = require('graphql'); var { GraphQLObjectType, GraphQLSchema, buildSchema, GraphQLInt, GraphQLString, GraphQLList, GraphQLBoolean } = require('graphql');
import {connect} from "./database" import {connect} from "./database"
...@@ -32,7 +30,6 @@ const RootQuery = new GraphQLObjectType({ ...@@ -32,7 +30,6 @@ const RootQuery = new GraphQLObjectType({
const connection = await connect(); const connection = await connect();
const response = await connection.query('SELECT * FROM movie'); const response = await connection.query('SELECT * FROM movie');
return response[0]; return response[0];
// return filmControllers.getFilms()
} }
}, },
getMovieByColumnType: { getMovieByColumnType: {
...@@ -59,6 +56,35 @@ const RootQuery = new GraphQLObjectType({ ...@@ -59,6 +56,35 @@ const RootQuery = new GraphQLObjectType({
else if(typeof args.director_last_name!='undefined' && args.director_last_name){query = getQuery('director_last_name' , args.director_last_name)} else if(typeof args.director_last_name!='undefined' && args.director_last_name){query = getQuery('director_last_name' , args.director_last_name)}
else if(typeof args.description!='undefined' && args.description){query = getQuery('description' , args.description)} else if(typeof args.description!='undefined' && args.description){query = getQuery('description' , args.description)}
const response = await connection.query(query);
return response[0];
}
},
getMoviesBySearch: {
type: new GraphQLList(MovieType),
args: {
id: {type: GraphQLInt},
title: { type: GraphQLString },
genre: { type: GraphQLString },
rating_dice_throw: { type: GraphQLInt },
year: { type: GraphQLInt },
description: { type: GraphQLString },
order: {type: GraphQLBoolean}
},
async resolve(parent: any, args: any) {
const connection = await connect();
let query = '';
// if(typeof args.id!='undefined' && args.id){query = getQuery('id' , args.id)}
if(typeof args.title!='undefined' && typeof args.genre!='undefined'){
console.log("resolve")
query = getSearchQuery(args.title, args.genre, args.order)}
// else if(typeof args.genre!='undefined' && args.genre){query = getQuery('genre' , args.genre)}
// else if(typeof args.rating_dice_throw!='undefined' && args.rating_dice_throw){query = getQuery('rating_dice_throw' , args.rating_dice_throw)}
// else if(typeof args.year!='undefined' && args.year){query = getQuery('year' , args.year)}
// else if(typeof args.director_first_name!='undefined' && args.director_first_name){query = getQuery('director_first_name' , args.director_first_name)}
// else if(typeof args.director_last_name!='undefined' && args.director_last_name){query = getQuery('director_last_name' , args.director_last_name)}
// else if(typeof args.description!='undefined' && args.description){query = getQuery('description' , args.description)}
const response = await connection.query(query); const response = await connection.query(query);
return response[0]; return response[0];
} }
...@@ -66,10 +92,31 @@ const RootQuery = new GraphQLObjectType({ ...@@ -66,10 +92,31 @@ const RootQuery = new GraphQLObjectType({
} }
}) })
function getQuery(key: String, value: string){ function getQuery(key: string, value: string){
return 'SELECT * FROM movie WHERE ' + key + ' = "' + value + '"' return 'SELECT * FROM movie WHERE ' + key + ' = "' + value + '"'
} }
function getSearchQuery(title: string, genre: string, order: boolean): string {
let query = 'SELECT * FROM movie'
if (title != '') {
query = query + ' WHERE title LIKE "%' + title + '%"'
}
if (title != '' && genre != '') {
query = query + ' AND'
}
if (title == '' && genre != '') {
query = query + ' WHERE'
}
if (genre != '') {
query = query + ' genre LIKE "%' + genre + '%"'
}
if (order) {
query = query + ' ORDER BY "year"'
}
console.log(query)
return query
}
const Mutation = new GraphQLObjectType({ const Mutation = new GraphQLObjectType({
name: "Mutation", name: "Mutation",
description: 'This is for creating a movie', description: 'This is for creating a movie',
...@@ -122,15 +169,24 @@ const Mutation = new GraphQLObjectType({ ...@@ -122,15 +169,24 @@ const Mutation = new GraphQLObjectType({
const response = await connection.query('UPDATE movie SET title = ?, genre = ?, rating_dice_throw = ?, year = ?, director_first_name = ?, director_last_name = ? , description = ?, cover_image = ? WHERE id = ?', [args.title, args.genre, args.rating_dice_throw, args.year, args.director_first_name, args.director_last_name, args.description, args.cover_image, args.id]); const response = await connection.query('UPDATE movie SET title = ?, genre = ?, rating_dice_throw = ?, year = ?, director_first_name = ?, director_last_name = ? , description = ?, cover_image = ? WHERE id = ?', [args.title, args.genre, args.rating_dice_throw, args.year, args.director_first_name, args.director_last_name, args.description, args.cover_image, args.id]);
return response[0]; return response[0];
} }
},
updateRating: { // TODO test this
type: MovieType,
args: {
id: {type: GraphQLInt},
rating_dice_throw: { type: GraphQLInt }
},
async resolve(parent: any, args: any) {
const connection = await connect();
const response = await connection.query('UPDATE movie SET rating_dice_throw = ? WHERE id = ?', [args.genre, args.id]);
return response[0];
}
} }
} }
}) })
const schema = new GraphQLSchema({query: RootQuery, mutation: Mutation}) const schema = new GraphQLSchema({query: RootQuery, mutation: Mutation})
// var root = { hello: () => 'Hello world!' };
var app = express(); var app = express();
app.use('/graphql', graphqlHTTP({ app.use('/graphql', graphqlHTTP({
schema: schema, schema: schema,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment