Skip to content

Commit

Permalink
Refactor all 5 product routes to first stable version
Browse files Browse the repository at this point in the history
  • Loading branch information
janwerkhoven committed Sep 10, 2023
1 parent 2e25dd9 commit 80c8f51
Show file tree
Hide file tree
Showing 20 changed files with 259 additions and 136 deletions.
114 changes: 81 additions & 33 deletions app/pods/products/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
5 changes: 4 additions & 1 deletion app/pods/products/family/controller.js
Original file line number Diff line number Diff line change
@@ -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';
Expand Down
67 changes: 24 additions & 43 deletions app/pods/products/family/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 <head>
// 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;
}
}
2 changes: 1 addition & 1 deletion app/pods/products/family/template.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<ProductList
@title={{@model.family.label}}
@title={{this.family.label}}
@products={{@model.products}}
@groupBy={{this.groupBy}}
@searchFor={{this.query}}
Expand Down
8 changes: 1 addition & 7 deletions app/pods/products/index/controller.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
import Controller from '@ember/controller';
// import { tracked= } from '@glimmer/tracking';

export default class ProductsIndexController extends Controller {
// @tracked layout = 'list'; // list, grid
// get products() {
// return this.model.products.sortBy('statusRank', 'name');
// }
}
export default class ProductsIndexController extends Controller {}
6 changes: 2 additions & 4 deletions app/pods/products/index/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ export default class ProductsIndexRoute extends BaseRoute {
beforeModel() {
super.activate();

// Show snappy loading state to user
this.controllerFor('products').selectedFamily = null;
this.controllerFor('products').selectedUse = null;
this.controllerFor('products.indexLoading').title = 'All products';

// Show snappy loading state to user
this.headData.update(this.seo.products);
this.page.update({
id: 'products-index',
Expand All @@ -24,8 +22,8 @@ export default class ProductsIndexRoute extends BaseRoute {
model() {
return hash({
products: this.store.findAll('product'),
families: this.modelFor('products').families,
uses: this.modelFor('products').uses
families: this.store.findAll('product-family'),
uses: this.store.findAll('use')
});
}
}
6 changes: 6 additions & 0 deletions app/pods/products/mix-loading/controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Controller from '@ember/controller';
import { tracked } from '@glimmer/tracking';

export default class ProductsMixLoadingController extends Controller {
@tracked title;
}
3 changes: 3 additions & 0 deletions app/pods/products/mix-loading/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import BaseRoute from 'interflux/pods/base/route';

export default class ProductsMixLoadingRoute extends BaseRoute {}
1 change: 1 addition & 0 deletions app/pods/products/mix-loading/template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<ProductList @title={{this.title}} @loading={{true}} />
7 changes: 7 additions & 0 deletions app/pods/products/mix/controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Controller from '@ember/controller';
import { tracked } from '@glimmer/tracking';

export default class ProductsMixController extends Controller {
@tracked title;
@tracked products;
}
56 changes: 56 additions & 0 deletions app/pods/products/mix/route.js
Original file line number Diff line number Diff line change
@@ -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;
}
}
6 changes: 6 additions & 0 deletions app/pods/products/mix/template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<ProductList
@title={{this.title}}
@products={{this.products}}
@groupBy='none'
@searchFor={{this.query}}
/>
7 changes: 6 additions & 1 deletion app/pods/products/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
}
}

input {
width: 220px;
}

fieldset {
padding: 0;
border: 0;
Expand Down Expand Up @@ -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;
Expand Down
Loading

0 comments on commit 80c8f51

Please sign in to comment.