Compare commits
3 Commits
2f3993bb9e
...
02bdbf0f2c
| Author | SHA1 | Date | |
|---|---|---|---|
| 02bdbf0f2c | |||
| 45029b87d2 | |||
| ccb178ae5a |
@@ -76,8 +76,19 @@ mod api {
|
||||
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")]
|
||||
pub fn one_solution(conn: CookbookDbConn) -> Json<String> {
|
||||
pub fn one_solution(conn: CookbookDbConn) -> Json<TemplateObject> {
|
||||
use planner::{
|
||||
template,
|
||||
solver::{Domain, Problem}
|
||||
@@ -93,8 +104,18 @@ mod api {
|
||||
.add_constraint(|_| true)
|
||||
.finish();
|
||||
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"/>
|
||||
<section class="section" id="recipes-view">
|
||||
<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>
|
||||
<div class="container">
|
||||
<keep-alive>
|
||||
@@ -31,7 +31,6 @@ import RecipeList from './components/RecipeList.vue'
|
||||
import Planner from './components/Planner.vue'
|
||||
|
||||
|
||||
|
||||
export default {
|
||||
name: 'app',
|
||||
components: {
|
||||
@@ -96,12 +95,4 @@ export default {
|
||||
</script>
|
||||
|
||||
<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>
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
<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>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -1,17 +1,57 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<h2 class="subtitle">Week</h2>
|
||||
<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>
|
||||
</template>
|
||||
|
||||
<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 {
|
||||
name: 'Planner',
|
||||
data () {
|
||||
return {
|
||||
template: "",
|
||||
template: null,
|
||||
};},
|
||||
methods: {
|
||||
fetchSolution: function() {
|
||||
@@ -19,6 +59,21 @@ export default {
|
||||
.then((res) => res.json())
|
||||
.then((data) => this.template = data)
|
||||
.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>
|
||||
<div class="container">
|
||||
<div v-if="active_category == -1" class="columns">
|
||||
<div v-for="c in categories" :key="c.id" class="column">
|
||||
<div v-if="active_category == -1" class="columns is-multiline is-mobile">
|
||||
<div v-for="c in categories" :key="c.id" class="column is-one-quarter-desktop is-half-tablet">
|
||||
<button @click="setActiveCategory(c.id)"
|
||||
class="button is-large is-primary has-text-dark button-block">
|
||||
{{ c.name }}</button>
|
||||
|
||||
Reference in New Issue
Block a user