Compare commits
3 Commits
2f3993bb9e
...
02bdbf0f2c
| Author | SHA1 | Date | |
|---|---|---|---|
| 02bdbf0f2c | |||
| 45029b87d2 | |||
| ccb178ae5a |
@@ -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(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user