Compare commits

...

3 Commits

Author SHA1 Message Date
02bdbf0f2c work in progress on Planner component 2019-02-11 14:49:53 +01:00
45029b87d2 small fix 2019-02-10 21:42:37 +01:00
ccb178ae5a Adds Planner component 2019-02-10 21:29:48 +01:00
5 changed files with 96 additions and 18 deletions

View File

@@ -76,8 +76,19 @@ mod api {
Json( recipes::delete(&conn, id) ) Json( recipes::delete(&conn, id) )
} }
#[derive(Serialize)]
pub struct TemplateItems {
key: (String, String),
value: Option<RecipeObject>,
}
#[derive(Serialize)]
pub struct TemplateObject {
items: Vec<TemplateItems>
}
#[get("/solver/one")] #[get("/solver/one")]
pub fn one_solution(conn: CookbookDbConn) -> Json<String> { pub fn one_solution(conn: CookbookDbConn) -> Json<TemplateObject> {
use planner::{ use planner::{
template, template,
solver::{Domain, Problem} solver::{Domain, Problem}
@@ -93,8 +104,18 @@ mod api {
.add_constraint(|_| true) .add_constraint(|_| true)
.finish(); .finish();
let results = problem.solve_all(); let results = problem.solve_all();
let one_result = results.first().unwrap();
Json(format!("{:?}", results.first().unwrap())) Json(TemplateObject {
items: one_result
.into_iter()
.map(|(k,v)| {
TemplateItems {
key: (format!("{}", k.0), format!("{:?}", k.1)),
value: v.map(|r| RecipeObject::from(&conn, r.clone())),
}})
.collect(),
})
} }
} }

View File

@@ -3,7 +3,7 @@
<Heading msg="Cook-Assistant"/> <Heading msg="Cook-Assistant"/>
<section class="section" id="recipes-view"> <section class="section" id="recipes-view">
<p v-if="status.loading">Loading...</p> <p v-if="status.loading">Loading...</p>
<div v-if="status.error">Error</div> <div v-if="status.error" class="notification is-danger">Error: {{ status.error_msg }}</div>
<h2 v-else class="subtitle">Livre de recettes</h2> <h2 v-else class="subtitle">Livre de recettes</h2>
<div class="container"> <div class="container">
<keep-alive> <keep-alive>
@@ -31,7 +31,6 @@ import RecipeList from './components/RecipeList.vue'
import Planner from './components/Planner.vue' import Planner from './components/Planner.vue'
export default { export default {
name: 'app', name: 'app',
components: { components: {
@@ -96,12 +95,4 @@ export default {
</script> </script>
<style> <style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style> </style>

View File

@@ -1,5 +1,16 @@
<template> <template>
<h1 class="title">{{ msg }}</h1> <nav class="navbar" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item" href="#">
{{ msg }}
</a>
<a role="button" class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
</nav>
</template> </template>
<script> <script>

View File

@@ -1,17 +1,57 @@
<template> <template>
<div class="box"> <div class="box">
<h2 class="subtitle">Week</h2>
<button @click="fetchSolution" class="button is-primary">FetchSolution</button> <button @click="fetchSolution" class="button is-primary">FetchSolution</button>
<p>{{ template }}</p> <hr />
<div v-if="template">
<div class="columns is-desktop is-vcentered">
<div v-for="day_meals in itemsGroupedByDay"
class="column">
<strong> {{ day_meals[0] }}</strong>
<div v-for="meal in day_meals[1]">
<div v-if="meal.value" class="tags has-addons">
<span class="tag is-info">{{ meal.value.title }}</span>
<a @click="unsetMeal(meal.key)"
class="tag is-delete"></a>
</div>
<div v-else class="tag is-warning">Empty</div>
</div>
</div>
</div>
</div>
</div> </div>
</template> </template>
<script> <script>
const groupBy = function(items, keyGetter) {
const map = new Map();
items.forEach((item) => {
const key = keyGetter(item);
const collection = map.get(key);
if (!collection) {
map.set(key, [item]);
} else {
collection.push(item);
}
});
return map;
};
const DAYS = ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"];
const compareWeekDay = function(entryA, entryB) {
return DAYS.indexOf(entryA[0]) - DAYS.indexOf(entryB[0]);
}
const MEALS = ["Breakfast", "Lunch", "Dinner"];
const compareMealType = function(mealA, mealB) {
return MEALS.indexOf(mealA.key[1]) - MEALS.indexOf(mealB.key[1]);
}
export default { export default {
name: 'Planner', name: 'Planner',
data () { data () {
return { return {
template: "", template: null,
};}, };},
methods: { methods: {
fetchSolution: function() { fetchSolution: function() {
@@ -19,6 +59,21 @@ export default {
.then((res) => res.json()) .then((res) => res.json())
.then((data) => this.template = data) .then((data) => this.template = data)
.catch((err) => console.log(err)); .catch((err) => console.log(err));
},
unsetMeal: function(mealKey) {
console.log("Try unsetting " + mealKey);
let idx = this.template.items.findIndex((item) => {
return item.key == mealKey;
});
this.template.items[idx].value = null;
}
},
computed: {
itemsGroupedByDay: function() {
let grouped = groupBy(this.template.items, item => item.key[0]);
let sorted = new Map([...grouped.entries()].sort(compareWeekDay));
sorted.forEach((meals) => meals.sort(compareMealType));
return sorted;
} }
} }
} }

View File

@@ -1,7 +1,7 @@
<template> <template>
<div class="container"> <div class="container">
<div v-if="active_category == -1" class="columns"> <div v-if="active_category == -1" class="columns is-multiline is-mobile">
<div v-for="c in categories" :key="c.id" class="column"> <div v-for="c in categories" :key="c.id" class="column is-one-quarter-desktop is-half-tablet">
<button @click="setActiveCategory(c.id)" <button @click="setActiveCategory(c.id)"
class="button is-large is-primary has-text-dark button-block"> class="button is-large is-primary has-text-dark button-block">
{{ c.name }}</button> {{ c.name }}</button>