Browse Source

presentation version

master
Felix Diemar 3 years ago
parent
commit
1855f50d0d

+ 9
- 0
app/adapters/application.js 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
- 0
app/components/bild.hbs View File

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

+ 18
- 0
app/components/bild.js 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
}
}

+ 2
- 4
app/components/kategorie.hbs View File

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


</div>

+ 11
- 10
app/components/produkt.hbs View File

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

+ 77
- 0
app/components/produkt.js 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
- 0
app/components/rezept.hbs 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
- 0
app/components/rezept.js 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;
}
}

+ 4
- 0
app/components/services/store.js View File

@@ -0,0 +1,4 @@
import DS from 'ember-data';

export default DS.Store.extend({
});

+ 16
- 0
app/models/produkt.js 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
- 0
app/models/rezept.js 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}`
}
}


+ 10
- 2
app/routes/produkte.js View File

@@ -1,4 +1,5 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';

const PRODUKT_KATEGORIEN = [
'Pasta',
@@ -7,8 +8,15 @@ const PRODUKT_KATEGORIEN = [
'Fleisch'
];

export default class IndexRoute extends Route {
export default class ProduktRoute extends Route {

@service store;

async model() {
return this.store.findAll('produkt');
}
}
/*async model() {
let response = await fetch('/api/produkte.json');
let { data } = await response.json();

@@ -27,4 +35,4 @@ export default class IndexRoute extends Route {
return { kategorie, ...attributes };
});
}
}
}*/

+ 46
- 0
app/routes/rezepte.js 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
- 0
app/routes/zettel.js 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');
}
}

+ 4
- 0
app/serializers/application.js View File

@@ -0,0 +1,4 @@
import JSONAPISerializer from '@ember-data/serializer/json-api';

export default class ApplicationSerializer extends JSONAPISerializer {
}

+ 364
- 70
app/styles/app.css View File

@@ -174,6 +174,12 @@ p {
margin-top: -10px;
}

.resultsProdukt {
display: flex;
flex-wrap: wrap;
flex-direction: row;
}

.results li {
list-style: none;
padding: 10px 15px;
@@ -196,10 +202,7 @@ p {
.jumbo {
padding: 50px;
background: #f6f6f6;
}

.jumbo:hover {
background-color: #f3f3f3;
}

.jumbo h2 {
@@ -220,76 +223,301 @@ 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;
background-color: #f6f6f6;
background-color: white;
padding: 20px 25px;
display: flex;
justify-content: space-between;
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;
border-width: 5px;
}

.kategorie img {
.rezept img {
border-radius: 5px;
}

.kategorie .image {
.rezept .image {
flex-grow: 0;
flex-basis: 150px;
margin: 20px 25px;
text-align: center;
}

.kategorie button.image {
.rezept .image img {
max-width: 100%;
}

.rezept .image.large {
margin: 30px 25px 50px 25px;
flex-basis: 100%;
}

.rezept .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;
cursor: pointer;
border: none;
background: transparent;
z-index: 1;
}

.kategorie button.image:focus {
outline: none;
.rezept .image.large small {
margin-top: 10px;
margin-bottom: 0px;
font-size: 110%;
}

.kategorie button.image:after {
content: "";
position: absolute;
top: 0;
left: 0;
.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: 100%;
z-index: -1;
margin: -20px;
padding: 20px;
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;
background: #016aba;
opacity: 0;
transition: opacity 0.25s ease-in-out;
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%;
}

.kategorie button.image:focus:after, .kategorie button.image:hover:after {
opacity: 0.1;
.produkt .image {
flex-grow: 0;
flex-basis: 150px;
margin: 20px 25px;
text-align: center;
}

.kategorie .image img {
.produkt .image img {
max-width: 100%;
}

.kategorie .image.large {
.produkt .image.large {
margin: 30px 25px 50px 25px;
flex-basis: 100%;
}

.kategorie .image small {
.produkt .image small {
display: block;
margin-top: 5px;
margin-bottom: -15px;
@@ -300,13 +528,13 @@ p {
position: relative;
}

.kategorie .image.large small {
.produkt .image.large small {
margin-top: 10px;
margin-bottom: 0px;
font-size: 110%;
}

.kategorie .details {
.produkt .details {
flex-basis: 50%;
flex-grow: 2;
display: flex;
@@ -315,114 +543,191 @@ p {
justify-content: space-between;
flex-wrap: wrap;
align-content: space-around;
text-align: center;
align-items: center;
}

.kategorie h3 {
.produkt h3 {
flex-basis: 100%;
}

.kategorie h3 a {
.produkt h3 a {
display: inline;
}

.kategorie .detail {
.produkt .detail {
flex-basis: 50%;
font-weight: 300;
font-style: italic;
white-space: nowrap;
white-space: pre-wrap;
text-align: center;
flex: auto;
list-style-type: none;
}

.kategorie .detail span {
.produkt .detail span {
font-weight: 400;
font-style: normal;
}

.kategorie .map {
.produkt .map {
flex-grow: 0;
flex-basis: 150px;
font-size: 0;
margin: 0px 25px;
}

.kategorie .map img {
.produkt .map img {
width: 150px;
height: 150px;
}

.kategorie.detailed {
.produkt.detailed {
background: none;
align-items: flex-start;
}

.kategorie.detailed .image {
.produkt.detailed .image {
flex-basis: 320px;
}

.kategorie.detailed .image.large {
.produkt.detailed .image.large {
margin: 30px 25px 50px 25px;
flex-basis: 100%;
}

.kategorie.detailed .details {
.produkt.detailed .details {
height: auto;
}

.kategorie.detailed h3 {
.produkt.detailed h3 {
font-size: 200%;
margin-bottom: 10px;
}

.kategorie.detailed .detail {
.produkt.detailed .detail {
margin: 5px 0px;
flex-basis: 100%;
flex-shrink: 2;
}

.kategorie.detailed .description {
.produkt.detailed .description {
white-space: normal;
flex-basis: 100%;
flex-shrink: 1;
}

.kategorie.detailed .map {
.produkt.detailed .map {
flex-basis: 100%;
margin: 50px 25px 25px 25px;
}

.kategorie.detailed .map img {
.produkt.detailed .map img {
width: 100%;
height: auto;
}

@media only screen and (max-width: 919px) {
.kategorie.detailed .image, .kategorie.detailed .image.large {
.produkt.detailed .image, .produkt.detailed .image.large {
margin: 30px 25px 25px 25px;
flex-basis: 100%;
cursor: default;
}

.kategorie.detailed .image:hover {
.produkt.detailed .image:hover {
flex-basis: 100%;
cursor: default;
}

.kategorie.detailed .image small {
.produkt.detailed .image small {
display: none;
}

.kategorie.detailed button.image:hover:after {
.produkt.detailed button.image:hover:after {
opacity: 0;
}

.kategorie.detailed button.image:focus:after {
.produkt.detailed button.image:focus:after {
opacity: 0.1;
}

.kategorie.detailed .map {
.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 {
flex-basis: 50%;
flex-grow: 2;
display: flex;
height: 150px;
margin: 20px 25px;
justify-content: space-between;
flex-wrap: wrap;
align-content: space-around;
}

.kategorie h3 {
flex-basis: 100%;
}

.kategorie h3 a {
display: inline;
}

.kategorie .detail {
flex-basis: 50%;
font-weight: 300;
font-style: italic;
white-space: nowrap;
}

.kategorie .detail span {
font-weight: 400;
font-style: normal;
}

.kategorie.detailed {
background: none;
align-items: flex-start;
}

.kategorie.detailed .details {
height: auto;
}

.kategorie.detailed h3 {
font-size: 200%;
margin-bottom: 10px;
}

.kategorie.detailed .detail {
margin: 5px 0px;
flex-basis: 100%;
flex-shrink: 2;
}

.kategorie.detailed .description {
white-space: normal;
flex-basis: 100%;
flex-shrink: 1;
}

/**
* Utilities
*/
@@ -447,17 +752,6 @@ p {
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{
position: absolute;
overflow: hidden;

+ 38
- 4
app/templates/produkte.hbs View File

@@ -6,14 +6,48 @@

<Kategorie @titel={{"Gemüse"}}>
<div class="rentals">
<ul class="results">
<ul class="resultsProdukt">
{{#each @model as |produkt|}}
{{#if (compare produkt.titel '===' 'Gemüse')}}
<li><Produkt @produkt={{produkt}} /></li>
{{#if (compare produkt.kategorie '===' 'Gemüse')}}
<Produkt @produkt={{produkt}} />
{{/if}}
<li><Produkt @produkt={{produkt}} /></li>
{{/each}}
</ul>
</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>

+ 77
- 29
app/templates/rezepte.hbs View File

@@ -4,38 +4,86 @@
<LinkTo @route="rezepte" class="button">Rezepte bearbeiten</LinkTo>
</Jumbo>

<div class="kategorie">
<h2>Pasta</h2>
{{yield}}
</div>
<Kategorie @titel={{"Pasta"}}>
<div class="rentals">
<ul class="results">
{{#each @model as |rezept|}}
{{#if (compare rezept.kategorie '===' 'Pasta')}}
<li><Rezept class="detail" @rezept={{rezept}} /></li>
{{/if}}
{{/each}}
</ul>
</div>
</Kategorie>

<div class="kategorie">
<h2>Gemüse</h2>
{{yield}}
</div>
<Kategorie @titel={{"Gemüse"}}>
<div class="rentals">
<ul class="results">
{{#each @model as |rezept|}}
{{#if (compare rezept.kategorie '===' 'Gemüse')}}
<li><Rezept @rezept={{rezept}} /></li>
{{/if}}
{{/each}}
</ul>
</div>
</Kategorie>

<div class="kategorie">
<h2>Geflügel</h2>
{{yield}}
</div>
<Kategorie @titel={{"Geflügel"}}>
<div class="rentals">
<ul class="results">
{{#each @model as |rezept|}}
{{#if (compare rezept.kategorie '===' 'Geflügel')}}
<li><Rezept @rezept={{rezept}} /></li>
{{/if}}
{{/each}}
</ul>
</div>
</Kategorie>

<div class="kategorie">
<h2>Rind</h2>
{{yield}}
</div>
<Kategorie @titel={{"Rind"}}>
<div class="rentals">
<ul class="results">
{{#each @model as |rezept|}}
{{#if (compare rezept.kategorie '===' 'Rind')}}
<li><Rezept @rezept={{rezept}} /></li>
{{/if}}
{{/each}}
</ul>
</div>
</Kategorie>

<div class="kategorie">
<h2>Schwein</h2>
{{yield}}
</div>
<Kategorie @titel={{"Schwein"}}>
<div class="rentals">
<ul class="results">
{{#each @model as |rezept|}}
{{#if (compare rezept.kategorie '===' 'Schwein')}}
<li><Rezept @rezept={{rezept}} /></li>
{{/if}}
{{/each}}
</ul>
</div>
</Kategorie>

<div class="kategorie">
<h2>Nachspeise</h2>
{{yield}}
</div>
<Kategorie @titel={{"Nachspeise"}}>
<div class="rentals">
<ul class="results">
{{#each @model as |rezept|}}
{{#if (compare rezept.kategorie '===' 'Nachspeise')}}
<li><Rezept @rezept={{rezept}} /></li>
{{/if}}
{{/each}}
</ul>
</div>
</Kategorie>

<div class="kategorie">
<h2>Backen</h2>
{{yield}}
</div>
<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>

+ 11
- 4
app/templates/zettel.hbs View File

@@ -4,7 +4,14 @@
<LinkTo @route="zettel" class="button">Zettel aktualisieren</LinkTo>
</Jumbo>

<div class="zettel">
{{yield}}
</div>
<Kategorie @titel={{"mein Zettel"}}>
<div class="rentals">
<ul class="results">
{{#each @model as |produkt|}}
{{#if produkt.isSelected}}
<li><Rezept @zettel={{produkt}} /></li>
{{/if}}
{{/each}}
</ul>
</div>
</Kategorie>

+ 6
- 0
jsconfig.json View File

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

+ 190
- 0
package-lock.json View File

@@ -9128,6 +9128,27 @@
"integrity": "sha512-B7wiurPgsxsSGzJuPFkpBWnaeuCu2PGpG2BjyrfA1VcL7//o+5RSnZqiCEY326y7qmxb2GoCgo0ft03KBU0rRw==",
"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": {
"version": "8.0.1",
"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": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/ember-inflector/-/ember-inflector-3.0.1.tgz",
@@ -10270,6 +10313,153 @@
"integrity": "sha512-m9JbwQlT6PjY7x/T8HslnXP7Sz9bx/pz3FrNfNi2NesJnbNISly0Lix6NV1fhfo46572cpq4jrM+/6yYlMefTQ==",
"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": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ember-router-generator/-/ember-router-generator-2.0.0.tgz",

+ 1
- 0
package.json View File

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

public/api/produkte.json → public/api/produkts.json View File


+ 0
- 0
public/api/rezepte.json View File


+ 154
- 0
public/api/rezepts.json 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"
}
]
}

+ 0
- 3
public/robots.txt View File

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

+ 4
- 4
tests/acceptance/einkaufszettel-test.js View File

@@ -10,7 +10,7 @@ module('Acceptance | einkaufszettel', function(hooks) {
assert.equal(currentURL(), '/');
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-produkte').hasText('Produkte');
assert.dom('nav a.menu-rezepte').hasText('Rezepte');
@@ -21,7 +21,7 @@ module('Acceptance | einkaufszettel', function(hooks) {
await visit('/');

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-produkte').hasText('Produkte');
assert.dom('nav a.menu-rezepte').hasText('Rezepte');
@@ -43,7 +43,7 @@ module('Acceptance | einkaufszettel', function(hooks) {
await visit('/zettel');

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-produkte').hasText('Produkte');
assert.dom('nav a.menu-rezepte').hasText('Rezepte');
@@ -59,7 +59,7 @@ module('Acceptance | einkaufszettel', function(hooks) {
await visit('/produkte');

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-produkte').hasText('Produkte');
assert.dom('nav a.menu-rezepte').hasText('Rezepte');

+ 18
- 0
tests/integration/components/bild-test.js 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(), '');

});
});

+ 1
- 9
tests/integration/components/produkt-test.js View File

@@ -12,15 +12,7 @@ module('Integration | Component | produkt', function(hooks) {

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');
});
});

+ 16
- 0
tests/integration/components/rezept-test.js 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:');
});
});

+ 12
- 0
tests/unit/adapters/application-test.js 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);
});
});

+ 12
- 0
tests/unit/models/produkte-test.js 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);
});
});

+ 12
- 0
tests/unit/models/rezepte-test.js 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);
});
});

+ 11
- 0
tests/unit/routes/zettel-test.js 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);
});
});

+ 23
- 0
tests/unit/serializers/application-test.js 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);
});
});

Loading…
Cancel
Save