<h1 class="kategorie">{{@titel}}</h1> | |||||
<div class="kategorie"> | |||||
{{yield}} | |||||
</div> | |||||
<article class="kategorie"> | |||||
<image src={{@produkt.bild}} alt="Ein Bild von {{@produkt.titel}}"/> | |||||
<div class="details"> | |||||
<h3>{{@produkt.titel}}</h3> | |||||
<div class="detail owner"> | |||||
<span>Menge:</span> {{@produkt.menge}}{{@produkt.einheit}} | |||||
</div> | |||||
</div> | |||||
</article> |
import Ember from 'ember'; | |||||
export function compare(params) { | |||||
if(params[3]){ //handle case insensitive conditions if 4 param is passed. | |||||
params[0]= params[0].toLowerCase(); | |||||
params[2]= params[2].toLowerCase(); | |||||
} | |||||
let v1 = params[0]; | |||||
let operator = params[1]; | |||||
let v2 = params[2]; | |||||
switch (operator) { | |||||
case '==': | |||||
return (v1 == v2); | |||||
case '!=': | |||||
return (v1 != v2); | |||||
case '===': | |||||
return (v1 === v2); | |||||
case '<': | |||||
return (v1 < v2); | |||||
case '<=': | |||||
return (v1 <= v2); | |||||
case '>': | |||||
return (v1 > v2); | |||||
case '>=': | |||||
return (v1 >= v2); | |||||
case '&&': | |||||
return !!(v1 && v2); | |||||
case '||': | |||||
return !!(v1 || v2); | |||||
default: | |||||
return false; | |||||
} | |||||
} | |||||
export default Ember.Helper.helper(compare); |
import Route from '@ember/routing/route'; | |||||
const PRODUKT_KATEGORIEN = [ | |||||
'Pasta', | |||||
'Gemüse', | |||||
'Milchprodukte', | |||||
'Fleisch' | |||||
]; | |||||
export default class IndexRoute extends Route { | |||||
async model() { | |||||
let response = await fetch('/api/produkte.json'); | |||||
let { data } = await response.json(); | |||||
return data.map(model => { | |||||
let { attributes } = model; | |||||
let kategorie; | |||||
if (PRODUKT_KATEGORIEN.includes(attributes.kategorie)) { | |||||
kategorie = attributes.kategorie; | |||||
} | |||||
else | |||||
{ | |||||
kategorie = 'Sonstiges'; | |||||
} | |||||
return { kategorie, ...attributes }; | |||||
}); | |||||
} | |||||
} |
bottom: 5px; | bottom: 5px; | ||||
} | } | ||||
.zettel label span { | |||||
.kategorie label span { | |||||
font-size: 140%; | font-size: 140%; | ||||
margin: 50px auto 20px; | margin: 50px auto 20px; | ||||
display: block; | display: block; | ||||
font-style: italic; | font-style: italic; | ||||
} | } | ||||
.zettel input { | |||||
.kategorie input { | |||||
padding: 11px; | padding: 11px; | ||||
font-size: 18px; | font-size: 18px; | ||||
width: 500px; | width: 500px; | ||||
} | } | ||||
/** | /** | ||||
* Individual zettel Listing | |||||
* Individual kategorie Listing | |||||
*/ | */ | ||||
.zettel { | |||||
.kategorie { | |||||
margin-top: 15px; | margin-top: 15px; | ||||
background-color: #f6f6f6; | background-color: #f6f6f6; | ||||
padding: 20px 25px; | padding: 20px 25px; | ||||
flex-wrap: wrap; | flex-wrap: wrap; | ||||
} | } | ||||
.zettel:hover { | |||||
.kategorie:hover { | |||||
background-color: #f3f3f3; | background-color: #f3f3f3; | ||||
} | } | ||||
.zettel img { | |||||
.kategorie img { | |||||
border-radius: 5px; | border-radius: 5px; | ||||
} | } | ||||
.zettel .image { | |||||
.kategorie .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; | ||||
} | } | ||||
.zettel button.image { | |||||
.kategorie button.image { | |||||
position: relative; | position: relative; | ||||
cursor: pointer; | cursor: pointer; | ||||
border: none; | border: none; | ||||
z-index: 1; | z-index: 1; | ||||
} | } | ||||
.zettel button.image:focus { | |||||
.kategorie button.image:focus { | |||||
outline: none; | outline: none; | ||||
} | } | ||||
.zettel button.image:after { | |||||
.kategorie button.image:after { | |||||
content: ""; | content: ""; | ||||
position: absolute; | position: absolute; | ||||
top: 0; | top: 0; | ||||
transition: opacity 0.25s ease-in-out; | transition: opacity 0.25s ease-in-out; | ||||
} | } | ||||
.zettel button.image:focus:after, .zettel button.image:hover:after { | |||||
.kategorie button.image:focus:after, .kategorie button.image:hover:after { | |||||
opacity: 0.1; | opacity: 0.1; | ||||
} | } | ||||
.zettel .image img { | |||||
.kategorie .image img { | |||||
max-width: 100%; | max-width: 100%; | ||||
} | } | ||||
.zettel .image.large { | |||||
.kategorie .image.large { | |||||
margin: 30px 25px 50px 25px; | margin: 30px 25px 50px 25px; | ||||
flex-basis: 100%; | flex-basis: 100%; | ||||
} | } | ||||
.zettel .image small { | |||||
.kategorie .image small { | |||||
display: block; | display: block; | ||||
margin-top: 5px; | margin-top: 5px; | ||||
margin-bottom: -15px; | margin-bottom: -15px; | ||||
position: relative; | position: relative; | ||||
} | } | ||||
.zettel .image.large small { | |||||
.kategorie .image.large small { | |||||
margin-top: 10px; | margin-top: 10px; | ||||
margin-bottom: 0px; | margin-bottom: 0px; | ||||
font-size: 110%; | font-size: 110%; | ||||
} | } | ||||
.zettel .details { | |||||
.kategorie .details { | |||||
flex-basis: 50%; | flex-basis: 50%; | ||||
flex-grow: 2; | flex-grow: 2; | ||||
display: flex; | display: flex; | ||||
align-content: space-around; | align-content: space-around; | ||||
} | } | ||||
.zettel h3 { | |||||
.kategorie h3 { | |||||
flex-basis: 100%; | flex-basis: 100%; | ||||
} | } | ||||
.zettel h3 a { | |||||
.kategorie h3 a { | |||||
display: inline; | display: inline; | ||||
} | } | ||||
.zettel .detail { | |||||
.kategorie .detail { | |||||
flex-basis: 50%; | flex-basis: 50%; | ||||
font-weight: 300; | font-weight: 300; | ||||
font-style: italic; | font-style: italic; | ||||
white-space: nowrap; | white-space: nowrap; | ||||
} | } | ||||
.zettel .detail span { | |||||
.kategorie .detail span { | |||||
font-weight: 400; | font-weight: 400; | ||||
font-style: normal; | font-style: normal; | ||||
} | } | ||||
.zettel .map { | |||||
.kategorie .map { | |||||
flex-grow: 0; | flex-grow: 0; | ||||
flex-basis: 150px; | flex-basis: 150px; | ||||
font-size: 0; | font-size: 0; | ||||
margin: 0px 25px; | margin: 0px 25px; | ||||
} | } | ||||
.zettel .map img { | |||||
.kategorie .map img { | |||||
width: 150px; | width: 150px; | ||||
height: 150px; | height: 150px; | ||||
} | } | ||||
.zettel.detailed { | |||||
.kategorie.detailed { | |||||
background: none; | background: none; | ||||
align-items: flex-start; | align-items: flex-start; | ||||
} | } | ||||
.zettel.detailed .image { | |||||
.kategorie.detailed .image { | |||||
flex-basis: 320px; | flex-basis: 320px; | ||||
} | } | ||||
.zettel.detailed .image.large { | |||||
.kategorie.detailed .image.large { | |||||
margin: 30px 25px 50px 25px; | margin: 30px 25px 50px 25px; | ||||
flex-basis: 100%; | flex-basis: 100%; | ||||
} | } | ||||
.zettel.detailed .details { | |||||
.kategorie.detailed .details { | |||||
height: auto; | height: auto; | ||||
} | } | ||||
.zettel.detailed h3 { | |||||
.kategorie.detailed h3 { | |||||
font-size: 200%; | font-size: 200%; | ||||
margin-bottom: 10px; | margin-bottom: 10px; | ||||
} | } | ||||
.zettel.detailed .detail { | |||||
.kategorie.detailed .detail { | |||||
margin: 5px 0px; | margin: 5px 0px; | ||||
flex-basis: 100%; | flex-basis: 100%; | ||||
flex-shrink: 2; | flex-shrink: 2; | ||||
} | } | ||||
.zettel.detailed .description { | |||||
.kategorie.detailed .description { | |||||
white-space: normal; | white-space: normal; | ||||
flex-basis: 100%; | flex-basis: 100%; | ||||
flex-shrink: 1; | flex-shrink: 1; | ||||
} | } | ||||
.zettel.detailed .map { | |||||
.kategorie.detailed .map { | |||||
flex-basis: 100%; | flex-basis: 100%; | ||||
margin: 50px 25px 25px 25px; | margin: 50px 25px 25px 25px; | ||||
} | } | ||||
.zettel.detailed .map img { | |||||
.kategorie.detailed .map img { | |||||
width: 100%; | width: 100%; | ||||
height: auto; | height: auto; | ||||
} | } | ||||
@media only screen and (max-width: 919px) { | @media only screen and (max-width: 919px) { | ||||
.zettel.detailed .image, .zettel.detailed .image.large { | |||||
.kategorie.detailed .image, .kategorie.detailed .image.large { | |||||
margin: 30px 25px 25px 25px; | margin: 30px 25px 25px 25px; | ||||
flex-basis: 100%; | flex-basis: 100%; | ||||
cursor: default; | cursor: default; | ||||
} | } | ||||
.zettel.detailed .image:hover { | |||||
.kategorie.detailed .image:hover { | |||||
flex-basis: 100%; | flex-basis: 100%; | ||||
cursor: default; | cursor: default; | ||||
} | } | ||||
.zettel.detailed .image small { | |||||
.kategorie.detailed .image small { | |||||
display: none; | display: none; | ||||
} | } | ||||
.zettel.detailed button.image:hover:after { | |||||
.kategorie.detailed button.image:hover:after { | |||||
opacity: 0; | opacity: 0; | ||||
} | } | ||||
.zettel.detailed button.image:focus:after { | |||||
.kategorie.detailed button.image:focus:after { | |||||
opacity: 0.1; | opacity: 0.1; | ||||
} | } | ||||
.zettel.detailed .map { | |||||
.kategorie.detailed .map { | |||||
margin-top: 25px; | margin-top: 25px; | ||||
} | } | ||||
} | } |
<Jumbo> | <Jumbo> | ||||
<h2>Produkte</h2> | |||||
<h2>deine Produkte</h2> | |||||
<p>Hier kannst du aus deinen Produkten wählen oder neue Produkte hinzufügen!</p> | <p>Hier kannst du aus deinen Produkten wählen oder neue Produkte hinzufügen!</p> | ||||
<LinkTo @route="produkte" class="button">Produkte bearbeiten</LinkTo> | <LinkTo @route="produkte" class="button">Produkte bearbeiten</LinkTo> | ||||
</Jumbo> | </Jumbo> | ||||
<div class="zettel"> | |||||
{{yield}} | |||||
</div> | |||||
<Kategorie @titel={{"Gemüse"}}> | |||||
<div class="rentals"> | |||||
<ul class="results"> | |||||
{{#each @model as |produkt|}} | |||||
{{#if (compare produkt.titel '===' 'Gemüse')}} | |||||
<li><Produkt @produkt={{produkt}} /></li> | |||||
{{/if}} | |||||
<li><Produkt @produkt={{produkt}} /></li> | |||||
{{/each}} | |||||
</ul> | |||||
</div> | |||||
</Kategorie> |
<Jumbo> | <Jumbo> | ||||
<h2>Rezepte</h2> | |||||
<h2>deine Rezepte</h2> | |||||
<p>Hier kannst du aus deinen Rezepten wählen oder neue Rezepte hinzufügen!</p> | <p>Hier kannst du aus deinen Rezepten wählen oder neue Rezepte hinzufügen!</p> | ||||
<LinkTo @route="rezepte" class="button">Rezepte bearbeiten</LinkTo> | <LinkTo @route="rezepte" class="button">Rezepte bearbeiten</LinkTo> | ||||
</Jumbo> | </Jumbo> | ||||
<div class="zettel"> | |||||
<div class="kategorie"> | |||||
<h2>Pasta</h2> | |||||
{{yield}} | |||||
</div> | |||||
<div class="kategorie"> | |||||
<h2>Gemüse</h2> | |||||
{{yield}} | |||||
</div> | |||||
<div class="kategorie"> | |||||
<h2>Geflügel</h2> | |||||
{{yield}} | |||||
</div> | |||||
<div class="kategorie"> | |||||
<h2>Rind</h2> | |||||
{{yield}} | |||||
</div> | |||||
<div class="kategorie"> | |||||
<h2>Schwein</h2> | |||||
{{yield}} | |||||
</div> | |||||
<div class="kategorie"> | |||||
<h2>Nachspeise</h2> | |||||
{{yield}} | |||||
</div> | |||||
<div class="kategorie"> | |||||
<h2>Backen</h2> | |||||
{{yield}} | {{yield}} | ||||
</div> | </div> | ||||
{ | |||||
"data": [ | |||||
{ | |||||
"type": "produkt", | |||||
"id": "spaghetti", | |||||
"attributes": { | |||||
"titel": "Spaghetti", | |||||
"kategorie": "Pasta", | |||||
"menge": 500, | |||||
"einheit": "Gramm", | |||||
"bild": "https://www.pastaweb.de/wp-content/uploads/2016/02/spaghetti.jpg" | |||||
} | |||||
}, | |||||
{ | |||||
"type": "produkt", | |||||
"id": "salat", | |||||
"attributes": { | |||||
"titel": "Salat", | |||||
"kategorie": "Gemüse", | |||||
"menge": 1, | |||||
"einheit": "Kopf", | |||||
"bild": "https://napolipizza-spiez.ch/WebRoot/Store2/Shops/178389/5BD1/5BA4/85F2/ACB6/97E9/D91A/30FA/F35F/gruener-salat-2464087.jpg" | |||||
} | |||||
}, | |||||
{ | |||||
"type": "produkt", | |||||
"id": "milch", | |||||
"attributes": { | |||||
"titel": "Milch", | |||||
"kategorie": "Milchprodukte", | |||||
"menge": 1, | |||||
"einheit": "Liter", | |||||
"bild": "https://lebensmittel-warenkunde.de/assets/images/milch-milchprodukte.jpg" | |||||
} | |||||
}, | |||||
{ | |||||
"type": "produkt", | |||||
"id": "kaese", | |||||
"attributes": { | |||||
"titel": "Käse", | |||||
"kategorie": "Milchprodukte", | |||||
"menge": 200, | |||||
"einheit": "Gramm", | |||||
"bild": "https://www.der-bank-blog.de/wp-content/uploads/2016/04/banking-schweizer-kaese.jpg" | |||||
} | |||||
} | |||||
] | |||||
} | |||||
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'); | ||||
assert.dom('.jumbo a.h2').hasText('deine Zettel'); | |||||
assert.dom('.jumbo h2').hasText('deine Zettel'); | |||||
assert.dom('.jumbo a.button').hasText('Zettel aktualisieren'); | assert.dom('.jumbo a.button').hasText('Zettel aktualisieren'); | ||||
await click('.jumbo a.button'); | await click('.jumbo a.button'); | ||||
assert.equal(currentURL(), '/zettel'); | assert.equal(currentURL(), '/zettel'); | ||||
}); | }); | ||||
test('visiting /produkte', async function(assert) { | |||||
await visit('/produkte'); | |||||
assert.dom('nav').exists(); | |||||
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'); | |||||
assert.dom('.jumbo h2').hasText('deine Produkte'); | |||||
assert.dom('.jumbo a.button').hasText('Produkte bearbeiten'); | |||||
await click('.jumbo a.button'); | |||||
assert.equal(currentURL(), '/produkte'); | |||||
}); | |||||
test('visiting /rezepte', async function(assert) { | |||||
await visit('/rezepte'); | |||||
assert.dom('nav').exists(); | |||||
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'); | |||||
assert.dom('.jumbo h2').hasText('deine Rezepte'); | |||||
assert.dom('.jumbo a.button').hasText('Rezepte bearbeiten'); | |||||
await click('.jumbo a.button'); | |||||
assert.equal(currentURL(), '/rezepte'); | |||||
}); | |||||
}); | }); |
import { render } from '@ember/test-helpers'; | import { render } from '@ember/test-helpers'; | ||||
import { hbs } from 'ember-cli-htmlbars'; | import { hbs } from 'ember-cli-htmlbars'; | ||||
module('Integration | Component | zettel', function(hooks) { | |||||
module('Integration | Component | kategorie', function(hooks) { | |||||
setupRenderingTest(hooks); | setupRenderingTest(hooks); | ||||
test('it renders', async function(assert) { | test('it renders', async function(assert) { | ||||
// Set any properties with this.set('myProperty', 'value'); | // Set any properties with this.set('myProperty', 'value'); | ||||
// Handle any actions with this.set('myAction', function(val) { ... }); | // Handle any actions with this.set('myAction', function(val) { ... }); | ||||
await render(hbs`<Zettel />`); | |||||
await render(hbs`<Kategorie />`); | |||||
assert.equal(this.element.textContent.trim(), ''); | assert.equal(this.element.textContent.trim(), ''); | ||||
// Template block usage: | // Template block usage: | ||||
await render(hbs` | await render(hbs` | ||||
<Zettel> | |||||
<Kategorie> | |||||
template block text | template block text | ||||
</Zettel> | |||||
</Kategorie> | |||||
`); | `); | ||||
assert.equal(this.element.textContent.trim(), 'template block text'); | assert.equal(this.element.textContent.trim(), 'template block text'); |
import { render } from '@ember/test-helpers'; | import { render } from '@ember/test-helpers'; | ||||
import { hbs } from 'ember-cli-htmlbars'; | import { hbs } from 'ember-cli-htmlbars'; | ||||
module('Integration | Component | rezepte', function(hooks) { | |||||
module('Integration | Component | produkt', function(hooks) { | |||||
setupRenderingTest(hooks); | setupRenderingTest(hooks); | ||||
test('it renders', async function(assert) { | test('it renders', async function(assert) { | ||||
// Set any properties with this.set('myProperty', 'value'); | // Set any properties with this.set('myProperty', 'value'); | ||||
// Handle any actions with this.set('myAction', function(val) { ... }); | // Handle any actions with this.set('myAction', function(val) { ... }); | ||||
await render(hbs`<Rezepte />`); | |||||
await render(hbs`<Produkt />`); | |||||
assert.equal(this.element.textContent.trim(), ''); | assert.equal(this.element.textContent.trim(), ''); | ||||
// Template block usage: | // Template block usage: | ||||
await render(hbs` | await render(hbs` | ||||
<Rezepte> | |||||
<Produkt> | |||||
template block text | template block text | ||||
</Rezepte> | |||||
</Produkt> | |||||
`); | `); | ||||
assert.equal(this.element.textContent.trim(), 'template block text'); | assert.equal(this.element.textContent.trim(), 'template block text'); |
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 | produkte', 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`<Produkte />`); | |||||
assert.equal(this.element.textContent.trim(), ''); | |||||
// Template block usage: | |||||
await render(hbs` | |||||
<Produkte> | |||||
template block text | |||||
</Produkte> | |||||
`); | |||||
assert.equal(this.element.textContent.trim(), 'template block text'); | |||||
}); | |||||
}); |