presentation version

This commit is contained in:
Felix Diemar 2020-06-10 01:25:47 +02:00
parent 5b9410cf1c
commit 1855f50d0d
35 changed files with 1282 additions and 187 deletions

View File

@ -0,0 +1,9 @@
import JSONAPIAdapter from '@ember-data/adapter/json-api';
export default class ApplicationAdapter extends JSONAPIAdapter {
namespace = 'api';
buildURL(...args) {
return `${super.buildURL(...args)}.json`;
}
}

3
app/components/bild.hbs Normal file
View File

@ -0,0 +1,3 @@
<button type="button">
<img ...attributes>
</button>

18
app/components/bild.js Normal file
View File

@ -0,0 +1,18 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
export default class BildComponent extends Component {
@tracked isLarge = false;
@tracked selected = false;
@action toggleSize() {
this.isLarge = !this.isLarge;
}
@action select()
{
this.selected = !this.selected
}
}

View File

@ -1,6 +1,4 @@
<h1 class="kategorie">{{@titel}}</h1>
<div class="kategorie"> <div class="kategorie">
<h1 class="kategorie">{{@titel}}</h1>
{{yield}} {{yield}}
</div> </div>

View File

@ -1,11 +1,12 @@
<article class="kategorie"> <button type="button" class="produkt {{if this.isSelected "selected"}}" {{on "click" (fn this.toggleSelection @produkt.titel)}}>
<image src={{@produkt.bild}} alt="Ein Bild von {{@produkt.titel}}"/> <img src={{@produkt.bild}} alt="Ein Bild von {{@produkt.titel}}"/>
<div class="details"> <div class="detail">
<h3>{{@produkt.titel}}</h3> <h3>{{@produkt.titel}}</h3>
<div class="detail owner"> <ul class="details">
<span>Menge:</span> {{@produkt.menge}}{{@produkt.einheit}} <li class="detail"><h4>Menge:</h4> {{@produkt.menge}}{{@produkt.einheit}}</li>
</div> <!--<li class="detail"><h4>this.ex:</h4> {{this.ex}}</li>
<li class="detail"><h4>this.prodn:</h4> {{this.prodn}}</li>
<li class="detail"><h4>produkt count:</h4> {{this.count}}</li>-->
</ul>
</div> </div>
</button>
</article>

77
app/components/produkt.js Normal file
View File

@ -0,0 +1,77 @@
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
export default class ProduktController extends Component {
@tracked isLarge = false;
@tracked isSelected = false;
@tracked ex = false;
@tracked isSet = false;
@tracked prodn = "test";
@tracked count = 0;
@service store;
@action toggleSize()
{
this.isLarge = !this.isLarge;
}
@action toggleSelection(produktname)
{
this.isSelected = !this.isSelected;
this.setStatus(produktname);
}
@action getStatus(produktname)
{
this.prodn = produktname;
this.store.findAll('produkt')
.then(function(suchergebnis)
{
suchergebnis.forEach(element => {
if(element.titel==produktname)
{
this.exists = true;
this.isSelected = element.getStatus().isSelected;
this.ex = true;
}
});
if(!this.exists)
{
this.isSelected = false;
}
});
}
setStatus(produktname)
{
//schreibt den aktuellen Zustand in den store
let suchergebnis = this.get('store').query('produkt', {
filter: {
titel: produktname
}});
this.prodn = suchergebnis.titel;
count = suchergebnisse.titel;
this.prodn = element.titel;
suchergebnisse.forEach(element => {
this.prodn = element.titel;
count++;
if(element.titel === produktname)
{
this.prodn = produktname;
element.isSelected = this.isSelected;
this.isSet = !this.isSet;
}
});
}
}

36
app/components/rezept.hbs Normal file
View File

@ -0,0 +1,36 @@
{{#if this.isSelected}}
<button type="button" class="rezept selected" {{on "click" this.toggleSelection}}>
<span><img src={{@rezept.bild}} alt="Ein Bild von {{@rezept.titel}}"/></span>
<span>
<div class="detail">
<h3>{{@rezept.titel}}</h3>
<ul class="details">
<li class="detail"><h4>Zutaten:</h4>{{#each @rezept.produkte as |produkt|}}
{{produkt.attributes.titel}},
{{/each}}Gewürze</li>
<li class="detail"><h4>Personen:</h4>{{@rezept.personen}}</li>
<li class="detail"><h4>Dauer:</h4>{{@rezept.dauer}}</li>
</ul>
</div>
</span>
</button>
{{else}}
<button type="button" class="rezept" {{on "click" this.toggleSelection}}>
<span><img src={{@rezept.bild}} alt="Ein Bild von {{@rezept.titel}}"/></span>
<span>
<div class="detail">
<h3>{{@rezept.titel}}</h3>
<ul class="details">
<li class="detail"><h4>Zutaten:</h4>{{#each @rezept.produkte as |produkt|}}
{{produkt.attributes.titel}},
{{/each}}Gewürze</li>
<li class="detail"><h4>Personen:</h4>{{@rezept.personen}} </li>
<li class="detail"><h4>Dauer:</h4>{{@rezept.dauer}}</li>
</ul>
</div>
</span>
</button>
{{/if}}

18
app/components/rezept.js Normal file
View File

@ -0,0 +1,18 @@
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
export default class RezeptController extends Component {
@tracked isLarge = false;
@tracked isSelected = false;
@action toggleSize()
{
this.isLarge = !this.isLarge;
}
@action toggleSelection()
{
this.isSelected = !this.isSelected;
}
}

View File

@ -0,0 +1,4 @@
import DS from 'ember-data';
export default DS.Store.extend({
});

16
app/models/produkt.js Normal file
View File

@ -0,0 +1,16 @@
import Model, { attr } from '@ember-data/model';
export default class ProduktModel extends Model {
@attr titel;
@attr isSelected;
@attr kategorie;
@attr menge;
@attr einheit;
@attr bild;
get status()
{
return `${this.titel} ${this.IsSelected}`
}
}

19
app/models/rezept.js Normal file
View File

@ -0,0 +1,19 @@
import Model, { attr, hasMany } from '@ember-data/model';
export default class RezeptModel extends Model {
@attr titel;
@attr isSelected;
@attr ('string') beschreibung;
@attr kategorie;
@hasMany('produkt') produkte;
@attr gewuerze;
@attr personen;
@attr dauer;
@attr bild;
get status()
{
return `${this.titel} ${this.IsSelected}`
}
}

View File

@ -1,4 +1,5 @@
import Route from '@ember/routing/route'; import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
const PRODUKT_KATEGORIEN = [ const PRODUKT_KATEGORIEN = [
'Pasta', 'Pasta',
@ -7,8 +8,15 @@ const PRODUKT_KATEGORIEN = [
'Fleisch' 'Fleisch'
]; ];
export default class IndexRoute extends Route { export default class ProduktRoute extends Route {
@service store;
async model() { async model() {
return this.store.findAll('produkt');
}
}
/*async model() {
let response = await fetch('/api/produkte.json'); let response = await fetch('/api/produkte.json');
let { data } = await response.json(); let { data } = await response.json();
@ -27,4 +35,4 @@ export default class IndexRoute extends Route {
return { kategorie, ...attributes }; return { kategorie, ...attributes };
}); });
} }
} }*/

46
app/routes/rezepte.js Normal file
View File

@ -0,0 +1,46 @@
import Route from '@ember/routing/route';
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
import { inject as service } from '@ember/service';
const REZEPT_KATEGORIEN = [
'Pasta',
'Schwein',
'Soße',
'Fleisch',
'Geflügel',
'Rind',
'Nachspeise',
'Backen'
];
export default class RezeptRoute extends Route{
@service store;
async model() {
return this.store.findAll('rezept');
}
}
/*async model() {
let response = await fetch('/api/rezepte.json');
let { data } = await response.json();
return data.map(model => {
let { attributes } = model;
let kategorie;
if (REZEPT_KATEGORIEN.includes(attributes.kategorie)) {
kategorie = attributes.kategorie;
}
else
{
kategorie = 'Sonstiges';
}
return { kategorie, ...attributes };
});
}
}*/

11
app/routes/zettel.js Normal file
View File

@ -0,0 +1,11 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
export default class ProduktRoute extends Route {
@service store;
async model() {
return this.store.findAll('produkt');
}
}

View File

@ -0,0 +1,4 @@
import JSONAPISerializer from '@ember-data/serializer/json-api';
export default class ApplicationSerializer extends JSONAPISerializer {
}

View File

@ -174,6 +174,12 @@ p {
margin-top: -10px; margin-top: -10px;
} }
.resultsProdukt {
display: flex;
flex-wrap: wrap;
flex-direction: row;
}
.results li { .results li {
list-style: none; list-style: none;
padding: 10px 15px; padding: 10px 15px;
@ -196,10 +202,7 @@ p {
.jumbo { .jumbo {
padding: 50px; padding: 50px;
background: #f6f6f6; background: #f6f6f6;
}
.jumbo:hover {
background-color: #f3f3f3;
} }
.jumbo h2 { .jumbo h2 {
@ -220,76 +223,81 @@ p {
} }
/** /**
* Individual kategorie Listing * Individual rezept Listing
*/ */
.rezept label span {
font-size: 140%;
margin: 50px auto 20px;
display: block;
text-align: center;
font-style: italic;
}
.kategorie { .rezept input {
padding: 11px;
font-size: 18px;
width: 500px;
margin: 20px auto 50px;
background-color: rgba(255, 255, 255, 0.75);
border: solid 1px lightgray;
display: block;
}
.rezept {
margin-top: 15px; margin-top: 15px;
background-color: #f6f6f6; background-color: white;
padding: 20px 25px; padding: 20px 25px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
flex-wrap: wrap; text-align: center;
width: 100%;
border: #677ae4;
border-width: 15px;
} }
.kategorie:hover { .rezept.selected{
border: #016aba;
border-width: 7px;
border-style: solid;
border-radius: 5px;
font-size: 100%;
}
.rezept:hover {
border: #016aba;
border-width: 2px;
border-style: solid;
border-radius: 5px;
font-size: 100%;
}
.rezept.selected:hover {
background-color: #f3f3f3; background-color: #f3f3f3;
border-width: 5px;
} }
.kategorie img { .rezept img {
border-radius: 5px; border-radius: 5px;
} }
.kategorie .image { .rezept .image {
flex-grow: 0; flex-grow: 0;
flex-basis: 150px; flex-basis: 150px;
margin: 20px 25px; margin: 20px 25px;
text-align: center; text-align: center;
} }
.kategorie button.image { .rezept .image img {
position: relative;
cursor: pointer;
border: none;
background: transparent;
z-index: 1;
}
.kategorie button.image:focus {
outline: none;
}
.kategorie button.image:after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
margin: -20px;
padding: 20px;
border-radius: 5px;
background: #016aba;
opacity: 0;
transition: opacity 0.25s ease-in-out;
}
.kategorie button.image:focus:after, .kategorie button.image:hover:after {
opacity: 0.1;
}
.kategorie .image img {
max-width: 100%; max-width: 100%;
} }
.kategorie .image.large { .rezept .image.large {
margin: 30px 25px 50px 25px; margin: 30px 25px 50px 25px;
flex-basis: 100%; flex-basis: 100%;
} }
.kategorie .image small { .rezept .image small {
display: block; display: block;
margin-top: 5px; margin-top: 5px;
margin-bottom: -15px; margin-bottom: -15px;
@ -300,12 +308,369 @@ p {
position: relative; position: relative;
} }
.kategorie .image.large small { .rezept .image.large small {
margin-top: 10px; margin-top: 10px;
margin-bottom: 0px; margin-bottom: 0px;
font-size: 110%; font-size: 110%;
} }
.rezept .details {
flex-basis: 50%;
flex-grow: 2;
display: flex;
height: 150px;
margin: 20px 25px;
justify-content: space-between;
flex-wrap: wrap;
align-content: space-around;
text-align: center;
}
.rezept h3 {
flex-basis: 100%;
}
.rezept h3 a {
display: inline;
}
.rezept .detail {
flex-basis: 50%;
font-weight: 300;
font-style: italic;
white-space: pre-wrap ;
text-align: center;
}
.rezept .detail h3 h4{
text-align: center;
}
.rezept .detail span {
font-weight: 400;
font-style: normal;
}
.rezept .bild span {
width: 50;
}
.rezept .map {
flex-grow: 0;
flex-basis: 150px;
font-size: 0;
margin: 0px 25px;
}
.rezept .map img {
width: 150px;
height: 150px;
}
.rezept.detailed {
background: none;
align-items: flex-start;
}
.rezept.detailed .image {
flex-basis: 320px;
}
.rezept.detailed .image.large {
margin: 30px 25px 50px 25px;
flex-basis: 100%;
}
.rezept.detailed .details {
height: auto;
}
.rezept.detailed h3 {
font-size: 200%;
margin-bottom: 10px;
}
.rezept.detailed .detail {
margin: 5px 0px;
flex-basis: 100%;
flex-shrink: 2;
}
.rezept.detailed .description {
white-space: normal;
flex-basis: 100%;
flex-shrink: 1;
}
.rezept.detailed .map {
flex-basis: 100%;
margin: 50px 25px 25px 25px;
}
.rezept.detailed .map img {
width: 100%;
height: auto;
}
@media only screen and (max-width: 919px) {
.rezept.detailed .image, .rezept.detailed .image.large {
margin: 30px 25px 25px 25px;
flex-basis: 100%;
cursor: default;
}
.rezept.detailed .image:hover {
flex-basis: 100%;
cursor: default;
}
.rezept.detailed .image small {
display: none;
}
.rezept.detailed button.image:hover:after {
opacity: 0;
}
.rezept.detailed button.image:focus:after {
opacity: 0.1;
}
.rezept.detailed .map {
margin-top: 25px;
}
}
/**
* Individual produkt Listing
*/
.produkt label span {
font-size: 140%;
margin: 50px auto 20px;
display: block;
text-align: center;
font-style: italic;
}
.produkt input {
padding: 11px;
font-size: 18px;
width: 500px;
margin: 20px auto 50px;
background-color: rgba(255, 255, 255, 0.75);
border: solid 1px lightgray;
display: block;
}
.produkt {
margin: 15px;
background-color: white;
padding: 20px 25px;
display: flex;
justify-content: space-between;
align-items: center;
text-align: center;
flex-wrap: wrap;
width:20%;
border: none;
}
.produkt.selected{
border: #016aba;
border-width: 7px;
border-style: solid;
border-radius: 5px;
font-size: 100%;
}
.produkt:hover {
border: #016aba;
border-width: 2px;
border-style: solid;
border-radius: 5px;
font-size: 100%;
}
.produkt.selected:hover {
background-color: #f3f3f3;
border-width:5px;
}
.produkt img {
border-radius: 5px;
width: 100%;
}
.produkt .image {
flex-grow: 0;
flex-basis: 150px;
margin: 20px 25px;
text-align: center;
}
.produkt .image img {
max-width: 100%;
}
.produkt .image.large {
margin: 30px 25px 50px 25px;
flex-basis: 100%;
}
.produkt .image small {
display: block;
margin-top: 5px;
margin-bottom: -15px;
text-align: center;
color: #016aba;
/* This is needed to fix a safari clipping issue */
position: relative;
}
.produkt .image.large small {
margin-top: 10px;
margin-bottom: 0px;
font-size: 110%;
}
.produkt .details {
flex-basis: 50%;
flex-grow: 2;
display: flex;
height: 150px;
margin: 20px 25px;
justify-content: space-between;
flex-wrap: wrap;
align-content: space-around;
text-align: center;
align-items: center;
}
.produkt h3 {
flex-basis: 100%;
}
.produkt h3 a {
display: inline;
}
.produkt .detail {
flex-basis: 50%;
font-weight: 300;
font-style: italic;
white-space: pre-wrap;
text-align: center;
flex: auto;
list-style-type: none;
}
.produkt .detail span {
font-weight: 400;
font-style: normal;
}
.produkt .map {
flex-grow: 0;
flex-basis: 150px;
font-size: 0;
margin: 0px 25px;
}
.produkt .map img {
width: 150px;
height: 150px;
}
.produkt.detailed {
background: none;
align-items: flex-start;
}
.produkt.detailed .image {
flex-basis: 320px;
}
.produkt.detailed .image.large {
margin: 30px 25px 50px 25px;
flex-basis: 100%;
}
.produkt.detailed .details {
height: auto;
}
.produkt.detailed h3 {
font-size: 200%;
margin-bottom: 10px;
}
.produkt.detailed .detail {
margin: 5px 0px;
flex-basis: 100%;
flex-shrink: 2;
}
.produkt.detailed .description {
white-space: normal;
flex-basis: 100%;
flex-shrink: 1;
}
.produkt.detailed .map {
flex-basis: 100%;
margin: 50px 25px 25px 25px;
}
.produkt.detailed .map img {
width: 100%;
height: auto;
}
@media only screen and (max-width: 919px) {
.produkt.detailed .image, .produkt.detailed .image.large {
margin: 30px 25px 25px 25px;
flex-basis: 100%;
cursor: default;
}
.produkt.detailed .image:hover {
flex-basis: 100%;
cursor: default;
}
.produkt.detailed .image small {
display: none;
}
.produkt.detailed button.image:hover:after {
opacity: 0;
}
.produkt.detailed button.image:focus:after {
opacity: 0.1;
}
.produkt.detailed .map {
margin-top: 25px;
}
}
/**
* Individual kategorie Listing
*/
.kategorie {
margin-top: 15px;
background-color: #f6f6f6;
padding: 20px 25px;
display: flex;
justify-content: space-between;
/**align-items: center;*/
flex-wrap: wrap;
align-items: flex-start;
}
.kategorie .details { .kategorie .details {
flex-basis: 50%; flex-basis: 50%;
flex-grow: 2; flex-grow: 2;
@ -337,32 +702,11 @@ p {
font-style: normal; font-style: normal;
} }
.kategorie .map {
flex-grow: 0;
flex-basis: 150px;
font-size: 0;
margin: 0px 25px;
}
.kategorie .map img {
width: 150px;
height: 150px;
}
.kategorie.detailed { .kategorie.detailed {
background: none; background: none;
align-items: flex-start; align-items: flex-start;
} }
.kategorie.detailed .image {
flex-basis: 320px;
}
.kategorie.detailed .image.large {
margin: 30px 25px 50px 25px;
flex-basis: 100%;
}
.kategorie.detailed .details { .kategorie.detailed .details {
height: auto; height: auto;
} }
@ -384,45 +728,6 @@ p {
flex-shrink: 1; flex-shrink: 1;
} }
.kategorie.detailed .map {
flex-basis: 100%;
margin: 50px 25px 25px 25px;
}
.kategorie.detailed .map img {
width: 100%;
height: auto;
}
@media only screen and (max-width: 919px) {
.kategorie.detailed .image, .kategorie.detailed .image.large {
margin: 30px 25px 25px 25px;
flex-basis: 100%;
cursor: default;
}
.kategorie.detailed .image:hover {
flex-basis: 100%;
cursor: default;
}
.kategorie.detailed .image small {
display: none;
}
.kategorie.detailed button.image:hover:after {
opacity: 0;
}
.kategorie.detailed button.image:focus:after {
opacity: 0.1;
}
.kategorie.detailed .map {
margin-top: 25px;
}
}
/** /**
* Utilities * Utilities
*/ */
@ -447,17 +752,6 @@ p {
position: relative; position: relative;
} }
.tomster {
background: url(../assets/images/teaching-tomster.png);
background-size: contain;
background-repeat: no-repeat;
height: 200px;
width: 200px;
position: relative;
top: -25px;
}
.screen-reader{ .screen-reader{
position: absolute; position: absolute;
overflow: hidden; overflow: hidden;

View File

@ -6,14 +6,48 @@
<Kategorie @titel={{"Gemüse"}}> <Kategorie @titel={{"Gemüse"}}>
<div class="rentals"> <div class="rentals">
<ul class="results"> <ul class="resultsProdukt">
{{#each @model as |produkt|}} {{#each @model as |produkt|}}
{{#if (compare produkt.titel '===' 'Gemüse')}} {{#if (compare produkt.kategorie '===' 'Gemüse')}}
<li><Produkt @produkt={{produkt}} /></li> <Produkt @produkt={{produkt}} />
{{/if}} {{/if}}
<li><Produkt @produkt={{produkt}} /></li>
{{/each}} {{/each}}
</ul> </ul>
</div> </div>
</Kategorie>
<Kategorie @titel={{"Milchprodukte"}}>
<div class="rentals">
<ul class="resultsProdukt">
{{#each @model as |produkt|}}
{{#if (compare produkt.kategorie '===' 'Milchprodukte')}}
<Produkt @produkt={{produkt}} />
{{/if}}
{{/each}}
</ul>
</div>
</Kategorie>
<Kategorie @titel={{"Fleisch"}}>
<div class="rentals">
<ul class="resultsProdukt">
{{#each @model as |produkt|}}
{{#if (compare produkt.kategorie '===' 'Fleisch')}}
<span><Produkt @produkt={{produkt}} /></span>
{{/if}}
{{/each}}
</ul>
</div>
</Kategorie>
<Kategorie @titel={{"Pasta"}}>
<div class="rentals">
<ul class="resultsProdukt">
{{#each @model as |produkt|}}
{{#if (compare produkt.kategorie '===' 'Pasta')}}
<Produkt @produkt={{produkt}} />
{{/if}}
{{/each}}
</ul>
</div>
</Kategorie> </Kategorie>

View File

@ -4,38 +4,86 @@
<LinkTo @route="rezepte" class="button">Rezepte bearbeiten</LinkTo> <LinkTo @route="rezepte" class="button">Rezepte bearbeiten</LinkTo>
</Jumbo> </Jumbo>
<div class="kategorie"> <Kategorie @titel={{"Pasta"}}>
<h2>Pasta</h2> <div class="rentals">
{{yield}} <ul class="results">
</div> {{#each @model as |rezept|}}
{{#if (compare rezept.kategorie '===' 'Pasta')}}
<li><Rezept class="detail" @rezept={{rezept}} /></li>
{{/if}}
{{/each}}
</ul>
</div>
</Kategorie>
<div class="kategorie"> <Kategorie @titel={{"Gemüse"}}>
<h2>Gemüse</h2> <div class="rentals">
{{yield}} <ul class="results">
</div> {{#each @model as |rezept|}}
{{#if (compare rezept.kategorie '===' 'Gemüse')}}
<li><Rezept @rezept={{rezept}} /></li>
{{/if}}
{{/each}}
</ul>
</div>
</Kategorie>
<div class="kategorie"> <Kategorie @titel={{"Geflügel"}}>
<h2>Geflügel</h2> <div class="rentals">
{{yield}} <ul class="results">
</div> {{#each @model as |rezept|}}
{{#if (compare rezept.kategorie '===' 'Geflügel')}}
<li><Rezept @rezept={{rezept}} /></li>
{{/if}}
{{/each}}
</ul>
</div>
</Kategorie>
<div class="kategorie"> <Kategorie @titel={{"Rind"}}>
<h2>Rind</h2> <div class="rentals">
{{yield}} <ul class="results">
</div> {{#each @model as |rezept|}}
{{#if (compare rezept.kategorie '===' 'Rind')}}
<li><Rezept @rezept={{rezept}} /></li>
{{/if}}
{{/each}}
</ul>
</div>
</Kategorie>
<div class="kategorie"> <Kategorie @titel={{"Schwein"}}>
<h2>Schwein</h2> <div class="rentals">
{{yield}} <ul class="results">
</div> {{#each @model as |rezept|}}
{{#if (compare rezept.kategorie '===' 'Schwein')}}
<li><Rezept @rezept={{rezept}} /></li>
{{/if}}
{{/each}}
</ul>
</div>
</Kategorie>
<div class="kategorie"> <Kategorie @titel={{"Nachspeise"}}>
<h2>Nachspeise</h2> <div class="rentals">
{{yield}} <ul class="results">
</div> {{#each @model as |rezept|}}
{{#if (compare rezept.kategorie '===' 'Nachspeise')}}
<div class="kategorie"> <li><Rezept @rezept={{rezept}} /></li>
<h2>Backen</h2> {{/if}}
{{yield}} {{/each}}
</div> </ul>
</div>
</Kategorie>
<Kategorie @titel={{"Backen"}}>
<div class="rentals">
<ul class="results">
{{#each @model as |rezept|}}
{{#if (compare rezept.kategorie '===' 'Backen')}}
<li><Rezept @rezept={{rezept}} /></li>
{{/if}}
{{/each}}
</ul>
</div>
</Kategorie>

View File

@ -4,7 +4,14 @@
<LinkTo @route="zettel" class="button">Zettel aktualisieren</LinkTo> <LinkTo @route="zettel" class="button">Zettel aktualisieren</LinkTo>
</Jumbo> </Jumbo>
<div class="zettel"> <Kategorie @titel={{"mein Zettel"}}>
{{yield}} <div class="rentals">
</div> <ul class="results">
{{#each @model as |produkt|}}
{{#if produkt.isSelected}}
<li><Rezept @zettel={{produkt}} /></li>
{{/if}}
{{/each}}
</ul>
</div>
</Kategorie>

6
jsconfig.json Normal file
View File

@ -0,0 +1,6 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"allowJs": true
}
}

190
package-lock.json generated
View File

@ -9128,6 +9128,27 @@
"integrity": "sha512-B7wiurPgsxsSGzJuPFkpBWnaeuCu2PGpG2BjyrfA1VcL7//o+5RSnZqiCEY326y7qmxb2GoCgo0ft03KBU0rRw==", "integrity": "sha512-B7wiurPgsxsSGzJuPFkpBWnaeuCu2PGpG2BjyrfA1VcL7//o+5RSnZqiCEY326y7qmxb2GoCgo0ft03KBU0rRw==",
"dev": true "dev": true
}, },
"ember-factory-for-polyfill": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/ember-factory-for-polyfill/-/ember-factory-for-polyfill-1.3.1.tgz",
"integrity": "sha512-y3iG2iCzH96lZMTWQw6LWNLAfOmDC4pXKbZP6FxG8lt7GGaNFkZjwsf+Z5GAe7kxfD7UG4lVkF7x37K82rySGA==",
"dev": true,
"requires": {
"ember-cli-version-checker": "^2.1.0"
},
"dependencies": {
"ember-cli-version-checker": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/ember-cli-version-checker/-/ember-cli-version-checker-2.2.0.tgz",
"integrity": "sha512-G+KtYIVlSOWGcNaTFHk76xR4GdzDLzAS4uxZUKdASuFX0KJE43C6DaqL+y3VTpUFLI2FIkAS6HZ4I1YBi+S3hg==",
"dev": true,
"requires": {
"resolve": "^1.3.3",
"semver": "^5.3.0"
}
}
}
},
"ember-fetch": { "ember-fetch": {
"version": "8.0.1", "version": "8.0.1",
"resolved": "https://registry.npmjs.org/ember-fetch/-/ember-fetch-8.0.1.tgz", "resolved": "https://registry.npmjs.org/ember-fetch/-/ember-fetch-8.0.1.tgz",
@ -9522,6 +9543,28 @@
} }
} }
}, },
"ember-getowner-polyfill": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/ember-getowner-polyfill/-/ember-getowner-polyfill-2.2.0.tgz",
"integrity": "sha512-rwGMJgbGzxIAiWYjdpAh04Abvt0s3HuS/VjHzUFhVyVg2pzAuz45B9AzOxYXzkp88vFC7FPaiA4kE8NxNk4A4Q==",
"dev": true,
"requires": {
"ember-cli-version-checker": "^2.1.0",
"ember-factory-for-polyfill": "^1.3.1"
},
"dependencies": {
"ember-cli-version-checker": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/ember-cli-version-checker/-/ember-cli-version-checker-2.2.0.tgz",
"integrity": "sha512-G+KtYIVlSOWGcNaTFHk76xR4GdzDLzAS4uxZUKdASuFX0KJE43C6DaqL+y3VTpUFLI2FIkAS6HZ4I1YBi+S3hg==",
"dev": true,
"requires": {
"resolve": "^1.3.3",
"semver": "^5.3.0"
}
}
}
},
"ember-inflector": { "ember-inflector": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/ember-inflector/-/ember-inflector-3.0.1.tgz", "resolved": "https://registry.npmjs.org/ember-inflector/-/ember-inflector-3.0.1.tgz",
@ -10270,6 +10313,153 @@
"integrity": "sha512-m9JbwQlT6PjY7x/T8HslnXP7Sz9bx/pz3FrNfNi2NesJnbNISly0Lix6NV1fhfo46572cpq4jrM+/6yYlMefTQ==", "integrity": "sha512-m9JbwQlT6PjY7x/T8HslnXP7Sz9bx/pz3FrNfNi2NesJnbNISly0Lix6NV1fhfo46572cpq4jrM+/6yYlMefTQ==",
"dev": true "dev": true
}, },
"ember-route-action-helper": {
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/ember-route-action-helper/-/ember-route-action-helper-2.0.8.tgz",
"integrity": "sha512-V+4uKwqaYveriVt2rl4e+9mzHJiQOr1B8dCPQQ2TS3iAcmi5RD2giRDFGtCK9d2XY9Arb/f9hJh0obP20iyt3A==",
"dev": true,
"requires": {
"ember-cli-babel": "^6.8.1",
"ember-getowner-polyfill": "^2.0.0"
},
"dependencies": {
"amd-name-resolver": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/amd-name-resolver/-/amd-name-resolver-1.2.0.tgz",
"integrity": "sha512-hlSTWGS1t6/xq5YCed7YALg7tKZL3rkl7UwEZ/eCIkn8JxmM6fU6Qs/1hwtjQqfuYxlffuUcgYEm0f5xP4YKaA==",
"dev": true,
"requires": {
"ensure-posix-path": "^1.0.1"
}
},
"babel-plugin-debug-macros": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/babel-plugin-debug-macros/-/babel-plugin-debug-macros-0.2.0.tgz",
"integrity": "sha512-Wpmw4TbhR3Eq2t3W51eBAQSdKlr+uAyF0GI4GtPfMCD12Y4cIdpKC9l0RjNTH/P9isFypSqqewMPm7//fnZlNA==",
"dev": true,
"requires": {
"semver": "^5.3.0"
}
},
"broccoli-babel-transpiler": {
"version": "6.5.1",
"resolved": "https://registry.npmjs.org/broccoli-babel-transpiler/-/broccoli-babel-transpiler-6.5.1.tgz",
"integrity": "sha512-w6GcnkxvHcNCte5FcLGEG1hUdQvlfvSN/6PtGWU/otg69Ugk8rUk51h41R0Ugoc+TNxyeFG1opRt2RlA87XzNw==",
"dev": true,
"requires": {
"babel-core": "^6.26.0",
"broccoli-funnel": "^2.0.1",
"broccoli-merge-trees": "^2.0.0",
"broccoli-persistent-filter": "^1.4.3",
"clone": "^2.0.0",
"hash-for-dep": "^1.2.3",
"heimdalljs-logger": "^0.1.7",
"json-stable-stringify": "^1.0.0",
"rsvp": "^4.8.2",
"workerpool": "^2.3.0"
}
},
"broccoli-merge-trees": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/broccoli-merge-trees/-/broccoli-merge-trees-2.0.1.tgz",
"integrity": "sha512-WjaexJ+I8BxP5V5RNn6um/qDRSmKoiBC/QkRi79FT9ClHfldxRyCDs9mcV7mmoaPlsshmmPaUz5jdtcKA6DClQ==",
"dev": true,
"requires": {
"broccoli-plugin": "^1.3.0",
"merge-trees": "^1.0.1"
}
},
"broccoli-persistent-filter": {
"version": "1.4.6",
"resolved": "https://registry.npmjs.org/broccoli-persistent-filter/-/broccoli-persistent-filter-1.4.6.tgz",
"integrity": "sha512-0RejLwoC95kv4kta8KAa+FmECJCK78Qgm8SRDEK7YyU0N9Cx6KpY3UCDy9WELl3mCXLN8TokNxc7/hp3lL4lfw==",
"dev": true,
"requires": {
"async-disk-cache": "^1.2.1",
"async-promise-queue": "^1.0.3",
"broccoli-plugin": "^1.0.0",
"fs-tree-diff": "^0.5.2",
"hash-for-dep": "^1.0.2",
"heimdalljs": "^0.2.1",
"heimdalljs-logger": "^0.1.7",
"mkdirp": "^0.5.1",
"promise-map-series": "^0.2.1",
"rimraf": "^2.6.1",
"rsvp": "^3.0.18",
"symlink-or-copy": "^1.0.1",
"walk-sync": "^0.3.1"
},
"dependencies": {
"rsvp": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz",
"integrity": "sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw==",
"dev": true
}
}
},
"ember-cli-babel": {
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/ember-cli-babel/-/ember-cli-babel-6.18.0.tgz",
"integrity": "sha512-7ceC8joNYxY2wES16iIBlbPSxwKDBhYwC8drU3ZEvuPDMwVv1KzxCNu1fvxyFEBWhwaRNTUxSCsEVoTd9nosGA==",
"dev": true,
"requires": {
"amd-name-resolver": "1.2.0",
"babel-plugin-debug-macros": "^0.2.0-beta.6",
"babel-plugin-ember-modules-api-polyfill": "^2.6.0",
"babel-plugin-transform-es2015-modules-amd": "^6.24.0",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.7.0",
"broccoli-babel-transpiler": "^6.5.0",
"broccoli-debug": "^0.6.4",
"broccoli-funnel": "^2.0.0",
"broccoli-source": "^1.1.0",
"clone": "^2.0.0",
"ember-cli-version-checker": "^2.1.2",
"semver": "^5.5.0"
}
},
"ember-cli-version-checker": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/ember-cli-version-checker/-/ember-cli-version-checker-2.2.0.tgz",
"integrity": "sha512-G+KtYIVlSOWGcNaTFHk76xR4GdzDLzAS4uxZUKdASuFX0KJE43C6DaqL+y3VTpUFLI2FIkAS6HZ4I1YBi+S3hg==",
"dev": true,
"requires": {
"resolve": "^1.3.3",
"semver": "^5.3.0"
}
},
"merge-trees": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-trees/-/merge-trees-1.0.1.tgz",
"integrity": "sha1-zL5nRWl4f53vF/1G5lJfVwC70j4=",
"dev": true,
"requires": {
"can-symlink": "^1.0.0",
"fs-tree-diff": "^0.5.4",
"heimdalljs": "^0.2.1",
"heimdalljs-logger": "^0.1.7",
"rimraf": "^2.4.3",
"symlink-or-copy": "^1.0.0"
}
},
"rsvp": {
"version": "4.8.5",
"resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz",
"integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==",
"dev": true
},
"workerpool": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-2.3.3.tgz",
"integrity": "sha512-L1ovlYHp6UObYqElXXpbd214GgbEKDED0d3sj7pRdFXjNkb2+un/AUcCkceHizO0IVI6SOGGncrcjozruCkRgA==",
"dev": true,
"requires": {
"object-assign": "4.1.1"
}
}
}
},
"ember-router-generator": { "ember-router-generator": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/ember-router-generator/-/ember-router-generator-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ember-router-generator/-/ember-router-generator-2.0.0.tgz",

View File

@ -41,6 +41,7 @@
"ember-maybe-import-regenerator": "^0.1.6", "ember-maybe-import-regenerator": "^0.1.6",
"ember-qunit": "^4.6.0", "ember-qunit": "^4.6.0",
"ember-resolver": "^8.0.0", "ember-resolver": "^8.0.0",
"ember-route-action-helper": "^2.0.8",
"ember-source": "~3.18.0", "ember-source": "~3.18.0",
"ember-template-lint": "^2.6.0", "ember-template-lint": "^2.6.0",
"ember-welcome-page": "^4.0.0", "ember-welcome-page": "^4.0.0",

154
public/api/rezepts.json Normal file
View File

@ -0,0 +1,154 @@
{
"data": [
{
"type": "rezept",
"id": "NudelnGarneleZucchini",
"attributes": {
"titel": "Nudeln mit Garnelen und Zucchini",
"kategorie": "Pasta",
"beschreibung": "(1) Die Garnelen kalt überbrausen, in wenig Salzwasser kurz aufkochen, abgießen, das Wasser aufbewahren. (2) In einer Pfanne in der heißen Butter die Lauchzwiebeln und den Knoblauch anschwitzen, die Zucchiniwürfel und evtl. die Chilischoten zugeben, mit Salz und Pfeffer abwürzen. Zugedeckt 5 Minuten dünsten. Die Garnelen mit etwas Garnelenwasser unterischen, noch einmal erhitzen. Über die angerichteten Nudeln geben.",
"produkte": [
{
"type": "produkt",
"id": "farfalle",
"attributes": {
"titel": "Farfalle",
"kategorie": "Pasta",
"menge": 400,
"einheit": "Gramm"
}
},
{
"type": "produkt",
"id": "garnelen",
"attributes": {
"titel": "geschälte Garnelen",
"kategorie": "Meeresfrüchte",
"menge": 400,
"einheit": "Gramm"
}
},
{
"type": "produkt",
"id": "butter",
"attributes": {
"titel": "Butter",
"kategorie": "Milchprodukte",
"menge": 50,
"einheit": "Gramm"
}
},
{
"type": "produkt",
"id": "lauchzwiebeln",
"attributes": {
"titel": "Lauchzwiebeln",
"kategorie": "Gemüse",
"menge": 4,
"einheit": "Stück"
}
},
{
"type": "produkt",
"id": "zucchini",
"attributes": {
"titel": "Zucchini",
"kategorie": "Gemüse",
"menge": 400,
"einheit": "Gramm"
}
},
{
"type": "produkt",
"id": "knoblauch",
"attributes": {
"titel": "Knoblauchzehen",
"kategorie": "Gemüse",
"menge": 2,
"einheit": "Stück"
}
}
]},
"gewuerze":[
{
"type": "gewuerz",
"titel": "Salz"
},
{
"type": "gewuerz",
"titel": "Pfeffer"
},
{
"type": "gewuerz",
"titel": "Chilischote"
}
],
"personen": 4,
"dauer": "20",
"bild": "https://www.pastaweb.de/wp-content/uploads/2016/02/spaghetti.jpg"
},
{
"type": "rezept",
"id": "lasagne",
"attributes": {
"titel": "Lasagne Bolognese",
"kategorie": "Pasta",
"beschreibung": "(1) Die Bologneser Sauce und die Bechamelsauce zubereiten. (2) Den Boden einer Auflaufform mit etwas Bechamelsauce bedecken, mit Lasagneblättern auslegen. Einige Löffel Bologneser Sauce darüfergeben, darauf einige Löffel Bechamelsauceverstreichen und mit Parmesan bestreuen. Diesen Vorgang wiederholen, bis alle Zutaten aufgebraucht sind. Die letzte Schicht sind Lasagneblätter, Bechamelsauce und Parmesan. (3) Die Form auf dem Rost in den kalten Backofen schieben und etwa 40 Minuten bei 220°C goldgelb backen. ",
"produkte": [
{
"type": "produkt",
"id": "lasagneplatten",
"attributes": {
"titel": "Lassagneblätter",
"kategorie": "Pasta",
"menge": 250,
"einheit": "Gramm"
}
},
{
"type": "produkt",
"id": "bolognese",
"attributes": {
"titel": "Bologneser Sauce",
"kategorie": "Soßen",
"menge": 1000,
"einheit": "Gramm"
}
},
{
"type": "produkt",
"id": "bechamel",
"attributes": {
"titel": "Bechamelsauce",
"kategorie": "Soßen",
"menge": 500,
"einheit": "Milliliter"
}
},
{
"type": "produkt",
"id": "parmesan",
"attributes": {
"titel": "Parmesan gerieben",
"kategorie": "Milchprodukte",
"menge": 8,
"einheit": "EL"
}
}
]},
"gewuerze":[
{
"type": "gewuerz",
"titel": "Salz"
},
{
"type": "gewuerz",
"titel": "Pfeffer"
}
],
"personen": 4,
"dauer": "80",
"bild": "https://www.pastaweb.de/wp-content/uploads/2016/02/spaghetti.jpg"
}
]
}

View File

@ -1,3 +0,0 @@
# http://www.robotstxt.org
User-agent: *
Disallow:

View File

@ -10,7 +10,7 @@ module('Acceptance | einkaufszettel', function(hooks) {
assert.equal(currentURL(), '/'); assert.equal(currentURL(), '/');
assert.dom('nav').exists(); assert.dom('nav').exists();
assert.dom('nav a.menu-index').hasText('EinkaufsZettel') assert.dom('nav a.menu-index').hasText('EinkaufsZettel');
assert.dom('nav a.menu-zettel').hasText('Zettel'); assert.dom('nav a.menu-zettel').hasText('Zettel');
assert.dom('nav a.menu-produkte').hasText('Produkte'); assert.dom('nav a.menu-produkte').hasText('Produkte');
assert.dom('nav a.menu-rezepte').hasText('Rezepte'); assert.dom('nav a.menu-rezepte').hasText('Rezepte');
@ -21,7 +21,7 @@ module('Acceptance | einkaufszettel', function(hooks) {
await visit('/'); await visit('/');
assert.dom('nav').exists(); assert.dom('nav').exists();
assert.dom('nav a.menu-index').hasText('EinkaufsZettel') assert.dom('nav a.menu-index').hasText('EinkaufsZettel');
assert.dom('nav a.menu-zettel').hasText('Zettel'); assert.dom('nav a.menu-zettel').hasText('Zettel');
assert.dom('nav a.menu-produkte').hasText('Produkte'); assert.dom('nav a.menu-produkte').hasText('Produkte');
assert.dom('nav a.menu-rezepte').hasText('Rezepte'); assert.dom('nav a.menu-rezepte').hasText('Rezepte');
@ -43,7 +43,7 @@ module('Acceptance | einkaufszettel', function(hooks) {
await visit('/zettel'); await visit('/zettel');
assert.dom('nav').exists(); assert.dom('nav').exists();
assert.dom('nav a.menu-index').hasText('EinkaufsZettel') assert.dom('nav a.menu-index').hasText('EinkaufsZettel');
assert.dom('nav a.menu-zettel').hasText('Zettel'); assert.dom('nav a.menu-zettel').hasText('Zettel');
assert.dom('nav a.menu-produkte').hasText('Produkte'); assert.dom('nav a.menu-produkte').hasText('Produkte');
assert.dom('nav a.menu-rezepte').hasText('Rezepte'); assert.dom('nav a.menu-rezepte').hasText('Rezepte');
@ -59,7 +59,7 @@ module('Acceptance | einkaufszettel', function(hooks) {
await visit('/produkte'); await visit('/produkte');
assert.dom('nav').exists(); assert.dom('nav').exists();
assert.dom('nav a.menu-index').hasText('EinkaufsZettel') assert.dom('nav a.menu-index').hasText('EinkaufsZettel');
assert.dom('nav a.menu-zettel').hasText('Zettel'); assert.dom('nav a.menu-zettel').hasText('Zettel');
assert.dom('nav a.menu-produkte').hasText('Produkte'); assert.dom('nav a.menu-produkte').hasText('Produkte');
assert.dom('nav a.menu-rezepte').hasText('Rezepte'); assert.dom('nav a.menu-rezepte').hasText('Rezepte');

View File

@ -0,0 +1,18 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | bild', function(hooks) {
setupRenderingTest(hooks);
test('it renders', async function(assert) {
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.set('myAction', function(val) { ... });
await render(hbs`<Bild />`);
assert.equal(this.element.textContent.trim(), '');
});
});

View File

@ -12,15 +12,7 @@ module('Integration | Component | produkt', function(hooks) {
await render(hbs`<Produkt />`); await render(hbs`<Produkt />`);
assert.equal(this.element.textContent.trim(), ''); assert.dom('.produkt img').isVisible();
// Template block usage:
await render(hbs`
<Produkt>
template block text
</Produkt>
`);
assert.equal(this.element.textContent.trim(), 'template block text');
}); });
}); });

View File

@ -0,0 +1,16 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | rezept', function(hooks) {
setupRenderingTest(hooks);
test('it renders', async function(assert) {
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.set('myAction', function(val) { ... });
await render(hbs`<Rezept />`);
assert.dom('.rezept h4').hasText('Zutaten:');
});
});

View File

@ -0,0 +1,12 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Adapter | application', function(hooks) {
setupTest(hooks);
// Replace this with your real tests.
test('it exists', function(assert) {
let adapter = this.owner.lookup('adapter:application');
assert.ok(adapter);
});
});

View File

@ -0,0 +1,12 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Model | produkte', function(hooks) {
setupTest(hooks);
test('it has the right type', function(assert) {
let store = this.owner.lookup('service:store');
let model = store.createRecord('produkt', {titel: 'Testprodukt'});
assert.ok(model);
});
});

View File

@ -0,0 +1,12 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Model | rezepte', function(hooks) {
setupTest(hooks);
test('it has the right type', function(assert) {
let store = this.owner.lookup('service:store');
let model = store.createRecord('rezept', {titel: 'Testrezept'});
assert.ok(model);
});
});

View File

@ -0,0 +1,11 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Route | zettel', function(hooks) {
setupTest(hooks);
test('it exists', function(assert) {
let route = this.owner.lookup('route:zettel');
assert.ok(route);
});
});

View File

@ -0,0 +1,23 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Serializer | application', function(hooks) {
setupTest(hooks);
// Replace this with your real tests.
test('it exists', function(assert) {
let store = this.owner.lookup('service:store');
let serializer = store.serializerFor('produkt');
assert.ok(serializer);
});
test('it serializes records', function(assert) {
let store = this.owner.lookup('service:store');
let record = store.createRecord('produkt', {});
let serializedRecord = record.serialize();
assert.ok(serializedRecord);
});
});