diff --git a/app/pods/products/controller.js b/app/pods/products/controller.js index 17cd828..f2bba56 100644 --- a/app/pods/products/controller.js +++ b/app/pods/products/controller.js @@ -6,59 +6,107 @@ export default class ProductsController extends Controller { @service page; @service router; - // @tracked process = null; - // @tracked search = null; - @tracked layout = 'list'; // list, grid + // VIEW - // get findByUse() { - // return this.router.currentRouteName.startsWith('products.use'); - // } + // TODO: build + // @tracked layout = 'list'; // list, grid + + // TODO: review + get stickyMenu() { + return this.router.currentRouteName !== 'products.index'; + } // FAMILY - @tracked selectedFamily; + @tracked selectedFamilyId; // set by child routes + @tracked mainFamiliesSubset; // set by child routes - get families() { - if (!this.model) { - return []; - } - return this.model.families; + get allMainFamilies() { + return this.model.families.filterBy('isMainFamily'); } get familyOptions() { - return this.families - .filterBy('isMainFamily') - .sortBy('rank') - .map((mainFamily) => { - const label = mainFamily.label; - const route = 'products.family'; - const model = mainFamily.id; - - return { label, route, model }; - }); + const families = + this.selectedUseId && this.mainFamiliesSubset + ? this.mainFamiliesSubset + : this.allMainFamilies; + + return families.sortBy('rank').map((family) => { + const label = family.get('label'); + const selected = family.get('id') === this.selectedFamilyId; + + let route; + let model; + let models; + + if (this.selectedFamilyId && this.selectedUseId) { + // On the mix route, clicking the selected family button takes you to the use route. + route = 'products.use'; + model = this.selectedUseId; + } else if (this.selectedFamilyId) { + // On the family route, clicking the selected family button takes you the index route. + route = 'products.index'; + } else if (this.selectedUseId) { + // On the use route, clicking a family button takes you the mix route. + route = 'products.mix'; + models = [family.get('id'), this.selectedUseId]; + } else { + // On the index route, clicking a family button takes you to the family route. + route = 'products.family'; + model = family.get('id'); + } + + return { label, route, model, models, selected }; + }); + } + + get selectedFamilyOption() { + return this.familyOptions.find((option) => option.selected); } // USE - @tracked selectedUse; + @tracked selectedUseId; // set by child routes + @tracked usesSubset; // set by child routes - get uses() { + get allUses() { return this.model.uses; } get useOptions() { - return this.uses.sortBy('label').map((use) => { - const label = use.label; - const route = 'products.use'; - const model = use.id; + const uses = + this.selectedFamilyId && this.usesSubset ? this.usesSubset : this.allUses; + + return uses.sortBy('rank').map((use) => { + const label = use.get('label'); + const selected = use.get('id') === this.selectedUseId; + + let route; + let model; + let models; - return { label, route, model }; + if (this.selectedFamilyId && this.selectedUseId) { + // On the mix route, clicking the selected use button takes you to the family route. + route = 'products.family'; + model = this.selectedFamilyId; + } else if (this.selectedFamilyId) { + // On the family route, clicking a use button takes you to the mix route. + route = 'products.mix'; + models = [this.selectedFamilyId, use.get('id')]; + } else if (this.selectedUseId) { + // On the use route, clicking the selected use button takes you to the index route. + route = 'products.index'; + } else { + // On the index route, clicking a use button takes you to the use route. + route = 'products.use'; + model = use.get('id'); + } + + return { label, route, model, models, selected }; }); } - // STICKY - - get stickyMenu() { - return this.router.currentRouteName !== 'products.index'; + get selectedUseOption() { + return this.useOptions.find((option) => option.selected); } } diff --git a/app/pods/products/family/controller.js b/app/pods/products/family/controller.js index 027a957..e01b61b 100644 --- a/app/pods/products/family/controller.js +++ b/app/pods/products/family/controller.js @@ -1,8 +1,11 @@ import Controller from '@ember/controller'; +import { tracked } from '@glimmer/tracking'; export default class ProductsFamilyController extends Controller { + @tracked family; + get groupBy() { - const id = this.model.family.id; + const id = this.family.get('id'); if (id === 'soldering-fluxes' || id === 'auxiliaries') { return 'subFamily'; diff --git a/app/pods/products/family/route.js b/app/pods/products/family/route.js index 1085b4f..fa456f7 100644 --- a/app/pods/products/family/route.js +++ b/app/pods/products/family/route.js @@ -6,58 +6,39 @@ export default class ProductsFamilyRoute extends BaseRoute { beforeModel(transition) { super.activate(); - // const mainFamilyId = transition.to.params.main_family_id; + const slug = transition.to.params.main_family_id; + const family = this.store.peekRecord('product-family', slug); - // 1. Make sure the slug is a valid main family ID - // const family = this.store.peekRecord('product-family', mainFamilyId); - - // if (!family) { - // console.warn(`no family found for "${mainFamilyId}"`); - // this.router.transitionTo('products'); - // } - - // 2. Make sure the family is a "main family" - // if (!family.isMainFamily) { - // console.warn(`family is not main`); - // this.router.transitionTo('products'); - // } - - const selected = this.controllerFor('products').familyOptions.find( - (option) => option.model === transition.to.params.main_family_id - ); - - console.log(selected); - - this.controllerFor('products').selectedFamily = selected; - this.controllerFor('products.familyLoading').title = selected.label; - - // 4. Set SEO tags in the - // this.headData.update(this.seo.productsForFamily(family)); - - // 5. Set mobile UI values - // this.page.update({ - // id: 'products-family', - // // title: family.label, // TODO: translate - // backRoute: 'products' - // }); + this.controllerFor('products').selectedFamilyId = slug; + this.controllerFor('products.familyLoading').title = family + ? family.get('label') + : 'Loading'; } - model() { - const mainFamilyId = this.paramsFor('products.family').main_family_id; - + model(params) { return hash({ - family: this.store.peekRecord('product-family', mainFamilyId), products: this.store.query('product', { - filter: { main_family: mainFamilyId }, - include: ['product_uses', 'uses'].join(','), - reload: true - }), - delay: this.window.delay(2000, true) + filter: { main_family: params.main_family_id }, + include: ['main_family', 'sub_family', 'product_uses', 'uses'].join(',') + }) }); } + afterModel(model) { + super.activate(); + + const family = model.products.mapBy('mainFamily').uniqBy('id')[0]; + const uses = model.products.mapBy('uses').flat().uniqBy('id'); + + this.controllerFor('products').families = [family]; + this.controllerFor('products').selectedFamilyId = family.get('id'); + this.controllerFor('products').usesSubset = uses; + this.controllerFor('products.family').family = family; + } + @action willTransition() { - this.controllerFor('products').selectedFamily = null; + this.controllerFor('products').selectedFamilyId = null; + this.controllerFor('products').mainFamiliesSubset = null; } } diff --git a/app/pods/products/family/template.hbs b/app/pods/products/family/template.hbs index 1f34ce0..e4e1161 100644 --- a/app/pods/products/family/template.hbs +++ b/app/pods/products/family/template.hbs @@ -1,5 +1,5 @@ \ No newline at end of file diff --git a/app/pods/products/mix/controller.js b/app/pods/products/mix/controller.js new file mode 100644 index 0000000..7178130 --- /dev/null +++ b/app/pods/products/mix/controller.js @@ -0,0 +1,7 @@ +import Controller from '@ember/controller'; +import { tracked } from '@glimmer/tracking'; + +export default class ProductsMixController extends Controller { + @tracked title; + @tracked products; +} diff --git a/app/pods/products/mix/route.js b/app/pods/products/mix/route.js new file mode 100644 index 0000000..ef1f81a --- /dev/null +++ b/app/pods/products/mix/route.js @@ -0,0 +1,56 @@ +import BaseRoute from 'interflux/pods/base/route'; +import { hash } from 'rsvp'; +import { action } from '@ember/object'; + +export default class ProductsMixRoute extends BaseRoute { + beforeModel(transition) { + super.activate(); + + const params = transition.to.params; + const familyId = params.main_family_id; + const useId = params.use_id; + const family = this.store.peekRecord('product-family', familyId); + const use = this.store.peekRecord('use', useId); + + this.controllerFor('products').selectedFamilyId = familyId; + this.controllerFor('products').selectedUseId = useId; + this.controllerFor('products').mainFamiliesSubset = null; + this.controllerFor('products').usesSubset = null; + this.controllerFor('products.mixLoading').title = family + ? `${family.get('label')} for ${use.get('name')}` + : 'Loading'; + } + + model(params) { + return hash({ + productUses: this.store.query('product-use', { + filter: { use: params.use_id }, + include: 'product,use' + }) + }); + } + + afterModel(model, transition) { + super.activate(); + + const params = transition.to.params; + const familyId = params.main_family_id; + const useId = params.use_id; + const family = this.store.peekRecord('product-family', familyId); + const use = this.store.peekRecord('use', useId); + const title = `${family.get('label')} for ${use.get('name')}`; + const products = model.productUses + .mapBy('product') + .uniqBy('id') + .filterBy('mainFamily.id', familyId); + + this.controllerFor('products.mix').title = title; + this.controllerFor('products.mix').products = products; + } + + @action + willTransition() { + this.controllerFor('products').selectedFamilyId = null; + this.controllerFor('products').selectedUseId = null; + } +} diff --git a/app/pods/products/mix/template.hbs b/app/pods/products/mix/template.hbs new file mode 100644 index 0000000..afc2b34 --- /dev/null +++ b/app/pods/products/mix/template.hbs @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/app/pods/products/style.scss b/app/pods/products/style.scss index 08d0af5..6834a62 100644 --- a/app/pods/products/style.scss +++ b/app/pods/products/style.scss @@ -35,6 +35,10 @@ } } + input { + width: 220px; + } + fieldset { padding: 0; border: 0; @@ -74,7 +78,8 @@ width: 100%; } } - .button.pill { + .button.pill, + .button.pill.selected span { max-width: 220px; // TODO: make responsive overflow: hidden; text-overflow: ellipsis; diff --git a/app/pods/products/template.hbs b/app/pods/products/template.hbs index b61e19d..8549095 100644 --- a/app/pods/products/template.hbs +++ b/app/pods/products/template.hbs @@ -4,24 +4,27 @@
Search by name - +
- Product families + Product types
- Processes + Suitable for ...
diff --git a/app/pods/products/use-loading/controller.js b/app/pods/products/use-loading/controller.js index 6199d7b..de5d15b 100644 --- a/app/pods/products/use-loading/controller.js +++ b/app/pods/products/use-loading/controller.js @@ -2,5 +2,5 @@ import Controller from '@ember/controller'; import { tracked } from '@glimmer/tracking'; export default class ProductsUseLoadingController extends Controller { - @tracked title = 'Loading ...'; + @tracked title; } diff --git a/app/pods/products/use-loading/route.js b/app/pods/products/use-loading/route.js new file mode 100644 index 0000000..488351e --- /dev/null +++ b/app/pods/products/use-loading/route.js @@ -0,0 +1,3 @@ +import BaseRoute from 'interflux/pods/base/route'; + +export default class ProductsUseLoadingRoute extends BaseRoute {} diff --git a/app/pods/products/use-loading/template.hbs b/app/pods/products/use-loading/template.hbs index ca0af4d..6dd59be 100644 --- a/app/pods/products/use-loading/template.hbs +++ b/app/pods/products/use-loading/template.hbs @@ -1,2 +1 @@ -

{{this.title}}

- \ No newline at end of file + \ No newline at end of file diff --git a/app/pods/products/use/controller.js b/app/pods/products/use/controller.js index 9fb3818..9c55841 100644 --- a/app/pods/products/use/controller.js +++ b/app/pods/products/use/controller.js @@ -1,23 +1,8 @@ import Controller from '@ember/controller'; +import { tracked } from '@glimmer/tracking'; export default class ProductsUseSelectedController extends Controller { - get groups() { - const productsForUse = this.model.use.productsByRank.rejectBy('isOffline'); - const mainFamilies = productsForUse.mapBy('mainFamily'); - const uniqueIDs = Array.from(new Set(mainFamilies.mapBy('id'))); - - return uniqueIDs.map((id) => { - const family = mainFamilies.find((f) => f.get('id') === id); - const products = productsForUse.filterBy( - 'mainFamily.id', - family.get('id') - ); - - return { - title: `${family.get('namePlural')} for ${this.model.use.text}`, - featuredProducts: products.filterBy('isFeatured'), - hiddenProducts: products.filterBy('isHidden') - }; - }); - } + @tracked title; + @tracked products; + @tracked use; } diff --git a/app/pods/products/use/route.js b/app/pods/products/use/route.js index 9b231cc..0e37180 100644 --- a/app/pods/products/use/route.js +++ b/app/pods/products/use/route.js @@ -1,27 +1,46 @@ import BaseRoute from 'interflux/pods/base/route'; import { hash } from 'rsvp'; +import { action } from '@ember/object'; -export default class ProductsUseSelectedRoute extends BaseRoute { - activate() { +export default class ProductsUseRoute extends BaseRoute { + beforeModel(transition) { super.activate(); - this.headData.update(this.seo.products); // TODO - this.page.update({ - id: 'products', - title: 'Products', // TODO - backRoute: 'index' // TODO - }); + + const slug = transition.to.params.use_id; + const use = this.store.peekRecord('use', slug); + + this.controllerFor('products').selectedUseId = slug; + this.controllerFor('products.useLoading').title = use + ? use.get('label') + : 'Loading'; } model(params) { return hash({ - // use: this.store.findRecord('use', params.use_id, { - // // include: 'product_uses', - // include: 'product_uses,products,products.product_family', - // reload: true - // }) - // delay: new Promise((resolve) => { - // setTimeout(resolve, 2000); - // }) + productUses: this.store.query('product-use', { + filter: { use: params.use_id }, + include: 'product,use' + }) }); } + + afterModel(model) { + super.activate(); + + const use = model.productUses.mapBy('use').uniqBy('id')[0]; + const products = model.productUses.mapBy('product'); + const families = products.mapBy('mainFamily').uniqBy('id'); + + this.controllerFor('products').selectedUseId = use.get('id'); + this.controllerFor('products').mainFamiliesSubset = families; + this.controllerFor('products.use').title = use.get('forLabel'); + this.controllerFor('products.use').products = products; + this.controllerFor('products.use').use = use; + } + + @action + willTransition() { + this.controllerFor('products').selectedUseId = null; + this.controllerFor('products').mainFamiliesSubset = null; + } } diff --git a/app/pods/products/use/template.hbs b/app/pods/products/use/template.hbs index 9185059..94429d4 100644 --- a/app/pods/products/use/template.hbs +++ b/app/pods/products/use/template.hbs @@ -1 +1,7 @@ -

For process

\ No newline at end of file + \ No newline at end of file