Skip to content

Commit

Permalink
Add product search route and logic
Browse files Browse the repository at this point in the history
  • Loading branch information
janwerkhoven committed Sep 10, 2023
1 parent ab0682f commit d5f5293
Show file tree
Hide file tree
Showing 19 changed files with 247 additions and 57 deletions.
31 changes: 31 additions & 0 deletions app/helpers/mark.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { helper } from '@ember/component/helper';
import { htmlSafe } from '@ember/template';

// <p>{{mark this.search.value label}}</p>

export default helper(function mark(params) {
let phrase = params[1];

if (!phrase) {
return '';
}

let wordToMark = params[0];

if (!wordToMark) {
return phrase;
}

// Akward things happen when search ends with a space
wordToMark = wordToMark.trim();

if (typeof phrase === 'object' && phrase.string) {
phrase = phrase.string;
}

const regex = new RegExp(wordToMark, 'gi');

phrase = phrase.replace(regex, '<mark>$&</mark>');

return htmlSafe(phrase);
});
6 changes: 6 additions & 0 deletions app/helpers/span-each-word.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import { htmlSafe } from '@ember/template';

export function spanEachWord(params) {
const phrase = params[0];

if (!phrase) {
console.warn('no phrase');
return;
}

const words = phrase.split(' ');

const html = `<span>${words.join('</span><span>&nbsp;</span><span>')}</span>`;
Expand Down
2 changes: 1 addition & 1 deletion app/pods/components/product-list/featured/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Component from '@glimmer/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';

export default class ProductGroupPageFeaturedComponent extends Component {
export default class ProductListFeaturedComponent extends Component {
@tracked show = false;

@action
Expand Down
2 changes: 1 addition & 1 deletion app/pods/components/product-list/hidden/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Component from '@glimmer/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';

export default class ProductGroupPageHiddenComponent extends Component {
export default class ProductListHiddenComponent extends Component {
@tracked expanded = false;

@action
Expand Down
27 changes: 26 additions & 1 deletion app/pods/components/product-list/row/component.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,34 @@
import Component from '@glimmer/component';
import { inject as service } from '@ember/service';

export default class ProductGroupPageProductComponent extends Component {
export default class ProductListRowomponent extends Component {
// @arg product
// @arg search

@service media;

get classes() {
return [
'row',
this.args.product.get('status'),
this.args.layout,
this.searchMatch ? 'match' : 'hide'
].join(' ');
}

get searchMatch() {
if (!this.args.search) {
return true;
}

const search = this.args.search.toLowerCase();
const product = this.args.product;
const name = product.name.toLowerCase();
const pitch = product.pitch ? product.pitch.toLowerCase() : '';

return name.includes(search) || pitch.includes(search);
}

get features() {
const { product } = this.args;

Expand Down
21 changes: 20 additions & 1 deletion app/pods/components/product-list/row/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,21 @@
padding: 1.2vw 4vw 0.6vw;
border-radius: 0.5vw;
}
mark {
background-color: transparent;
color: white;
display: inline-block;
position: relative;
&:after {
content: '';
position: absolute;
left: 0;
bottom: 2px; // TODO: make responsive
height: 3px; // TODO: make responsive
width: 100%;
background-color: yellow;
}
}
}
.tags {
display: flex;
Expand Down Expand Up @@ -207,7 +222,7 @@
font-family: $semibold;
}
&.grey {
background: $grey-3;
background: $grey-5;
}
&.red {
background: $red-1;
Expand Down Expand Up @@ -271,6 +286,10 @@
height: calc(5vw * 1.8);
}
}
mark {
background-color: yellow;
color: $grey-7;
}
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions app/pods/components/product-list/row/template.hbs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<li id={{@product.id}} class='row {{@product.status}} {{@layout}}'>
<li id={{@product.id}} class={{this.classes}}>
<a href={{href-to 'product' @product.id}}>
<div class='left'>
{{#if @product.avatarPath}}
Expand Down Expand Up @@ -33,7 +33,7 @@
</div>

<div class='center'>
<h3>{{@product.name}}</h3>
<h3>{{mark @search @product.name}}</h3>
<div class='tags'>
{{#if @product.familyLabel}}
<h4 class='blue'>
Expand Down Expand Up @@ -72,7 +72,7 @@
</div>
{{#if @product.pitch}}
<div class='pitch'>
{{markdown (t @product.pitch 'product.2' @product.id)}}
{{mark @search (markdown (t @product.pitch 'product.2' @product.id))}}
</div>
{{/if}}
{{!-- {{#if (and this.features this.media.isDesktopWidescreen)}}
Expand Down
10 changes: 10 additions & 0 deletions app/pods/components/product-list/search/component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Component from '@glimmer/component';

export default class ProductListSearchComponent extends Component {
// @arg products
// @arg search

get products() {
return this.args.products.sortBy('statusRank', 'name');
}
}
5 changes: 5 additions & 0 deletions app/pods/components/product-list/search/template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<ol class='product-search'>
{{#each this.products as |product|}}
<ProductList::Row @product={{product}} @search={{@search}} />
{{/each}}
</ol>
24 changes: 15 additions & 9 deletions app/pods/components/product-list/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@
{{#if @loading}}
<Shimmer::ProductRows::Desktop />
{{else}}
{{#each this.groups as |group|}}
<section>
{{#if group.title}}
<h2>{{group.title}}</h2>
{{/if}}
<ProductList::Featured @products={{group.featured}} />
<ProductList::Hidden @products={{group.hidden}} />
</section>
{{/each}}
{{#if @search}}
<ProductList::Search @products={{@products}} @search={{@search}} />
{{else}}
{{#each this.groups as |group|}}
<section>
{{#if group.title}}
<h2>{{group.title}}</h2>
{{/if}}

<ProductList::Featured @products={{group.featured}} />
<ProductList::Hidden @products={{group.hidden}} />
</section>
{{/each}}
{{/if}}

{{/if}}
</div>
37 changes: 26 additions & 11 deletions app/pods/products/controller.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
import Controller from '@ember/controller';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';

export default class ProductsController extends Controller {
@service page;
@service router;

// VIEW
// SEARCH BY NAME

// TODO: build
// @tracked layout = 'list'; // list, grid
queryParams = ['search'];

// TODO: review
get stickyMenu() {
return this.router.currentRouteName !== 'products.index';
@tracked search = null;

@action
onKeyUp(event) {
const input = event.target;
this.search = input.value;
}

// FAMILY

@tracked selectedFamilyId; // set by child routes
@tracked mainFamiliesSubset; // set by child routes
@tracked familiesSubset; // set by child routes
@tracked familiesLoading;

get allMainFamilies() {
return this.model.families.filterBy('isMainFamily');
}

get familyOptions() {
const families =
this.selectedUseId && this.mainFamiliesSubset
? this.mainFamiliesSubset
this.selectedUseId && this.familiesSubset
? this.familiesSubset
: this.allMainFamilies;

return families.sortBy('rank').map((family) => {
Expand Down Expand Up @@ -66,8 +70,9 @@ export default class ProductsController extends Controller {

// USE

@tracked selectedUseId; // set by child routes
@tracked usesSubset; // set by child routes
@tracked selectedUseId;
@tracked usesSubset;
@tracked usesLoading;

get allUses() {
return this.model.uses;
Expand Down Expand Up @@ -109,4 +114,14 @@ export default class ProductsController extends Controller {
get selectedUseOption() {
return this.useOptions.find((option) => option.selected);
}

// VIEW

// TODO: build
// @tracked layout = 'list'; // list, grid

// TODO: review
get stickyMenu() {
return this.router.currentRouteName !== 'products.index' || this.search;
}
}
2 changes: 1 addition & 1 deletion app/pods/products/family/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default class ProductsFamilyController extends Controller {
return 'alloy';
}

if (id === 'auxiliaries') {
if (id === 'fluxing-systems') {
return 'none';
}

Expand Down
17 changes: 15 additions & 2 deletions app/pods/products/family/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export default class ProductsFamilyRoute extends BaseRoute {
const family = this.store.peekRecord('product-family', slug);

this.controllerFor('products').selectedFamilyId = slug;
this.controllerFor('products').usesSubset = null;
this.controllerFor('products').usesLoading = true;
this.controllerFor('products.familyLoading').title = family
? family.get('label')
: 'Loading';
Expand All @@ -30,15 +32,26 @@ export default class ProductsFamilyRoute extends BaseRoute {
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').usesLoading = false;
this.controllerFor('products.family').family = family;

// TODO
// this.headData.update(this.seo.products);
this.page.update({
id: 'products-family',
mainClasses: 'products'
// title: 'Products', // TODO: translate
// backRoute: 'index',
// crumbs: [{ label: 'Interflux', route: 'index' }, { label: 'Products' }]
});
}

@action
willTransition() {
this.controllerFor('products').selectedFamilyId = null;
this.controllerFor('products').mainFamiliesSubset = null;
this.controllerFor('products').usesSubset = null;
this.controllerFor('products').usesLoading = false;
}
}
15 changes: 9 additions & 6 deletions app/pods/products/index/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@ export default class ProductsIndexRoute extends BaseRoute {
beforeModel() {
super.activate();

this.controllerFor('products').selectedFamily = null;
this.controllerFor('products').selectedUse = null;
this.controllerFor('products').selectedFamilyId = null;
this.controllerFor('products').selectedUseId = null;
this.controllerFor('products').usesLoading = false;
this.controllerFor('products').familiesLoading = false;
this.controllerFor('products.indexLoading').title = 'All products';

// TODO
this.headData.update(this.seo.products);
this.page.update({
id: 'products-index',
title: 'Products', // TODO: translate
mainClasses: 'products',
backRoute: 'index',
crumbs: [{ label: 'Interflux', route: 'index' }, { label: 'Products' }]
mainClasses: 'products'
// title: 'Products', // TODO: translate
// backRoute: 'index',
// crumbs: [{ label: 'Interflux', route: 'index' }, { label: 'Products' }]
});
}

Expand Down
12 changes: 11 additions & 1 deletion app/pods/products/mix/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,21 @@ export default class ProductsMixRoute extends BaseRoute {

this.controllerFor('products').selectedFamilyId = familyId;
this.controllerFor('products').selectedUseId = useId;
this.controllerFor('products').mainFamiliesSubset = null;
this.controllerFor('products').familiesSubset = null;
this.controllerFor('products').usesSubset = null;
this.controllerFor('products.mixLoading').title = family
? `${family.get('label')} for ${use.get('name')}`
: 'Loading';

// TODO
// this.headData.update(this.seo.products);
this.page.update({
id: 'products-mix',
mainClasses: 'products'
// title: 'Products', // TODO: translate
// backRoute: 'index',
// crumbs: [{ label: 'Interflux', route: 'index' }, { label: 'Products' }]
});
}

model(params) {
Expand Down
Loading

0 comments on commit d5f5293

Please sign in to comment.