File

app/dxa/dxa-entity/views/related-link-views/related-links-sequence-main/related-links-sequence-main.component.ts

Implements

OnInit

Metadata

selector div[related-links-sequence]
styleUrls ./related-links-sequence-main.component.scss
templateUrl ./related-links-sequence-main.component.html

Index

Properties
Methods
Inputs
HostBindings

Constructor

constructor(doc, constants: ConstantsService, util: UtilService, linkService: ComponentLinkService, activatedRoute: ActivatedRoute)
Parameters :
Name Type Optional
doc No
constants ConstantsService No
util UtilService No
linkService ComponentLinkService No
activatedRoute ActivatedRoute No

Inputs

entity

HostBindings

class

Methods

getDirectionClass
getDirectionClass(index, rowNumber)

Get class for direction of arrow

Parameters :
Name Optional
index No
rowNumber No
Returns : string
getOrder
getOrder(index)

Get the position of a component based on its index. Used to switch placement in mobile view

Parameters :
Name Optional
index No
Returns : string
inDesktopView
inDesktopView()

Check if on desktop screen width

Returns : boolean
inMobileView
inMobileView()

Check if on mobile screen width

Returns : boolean
ngOnInit
ngOnInit()
Returns : void
Private resolveSequence
resolveSequence(sequence)
Parameters :
Name Optional
sequence No
Returns : RelatedSequence

Properties

sequences
Type : []
Default value : []
import { Component, Input, OnInit, Inject, HostBinding } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { ConstantsService } from 'src/app/shared/constants/constants.service';
import { UtilService } from 'src/app/core/services/util-service/util.service';
import { ComponentLinkService } from 'src/app/core/services/component-link-service/component-link.service';
import { Router, ActivatedRoute } from '@angular/router';

interface RelatedSequence {
	title: string;
	icon: string;
	linkObject: any;
	linkTitle: string;
	readMoreTitle: string;
	active: boolean;
}

@Component({
	selector: 'div[related-links-sequence]',
	templateUrl: './related-links-sequence-main.component.html',
	styleUrls: ['./related-links-sequence-main.component.scss']
})
export class RelatedLinksSequenceMainComponent implements OnInit {

	@Input() entity;

	sequences = [];

	@HostBinding('class') get class() { return 'col-md-12 space-between'; }

	constructor(
		@Inject(DOCUMENT) private doc,
		private constants: ConstantsService,
		private util: UtilService,
		private linkService: ComponentLinkService,
		private activatedRoute: ActivatedRoute
	) { }

	ngOnInit(): void {
		const entities = this.util.extract(this.entity, 'Entities');
		this.sequences = (entities ? entities : []).map(seq => this.resolveSequence(seq));
	}

	/** Get the position of a component based on its index. Used to switch placement in mobile view */
	getOrder(index): string {
		let classString = '';
		// No classes on desktop view
		if (this.inDesktopView()) {
			return classString;
		}
		if (index <= 1) {	// Regular order for first 2 elements
			const direction = this.getDirectionClass(index, 0);
			classString = `order-${index} ${direction}`;
		} else {
			const rowNumber = Math.floor(index / 2);
			const direction = this.getDirectionClass(index, rowNumber);

			const evenIndex = index % 2 === 0;
			const evenRow = rowNumber % 2 === 0;
			const oddAmountOfLinks = this.sequences.length % 2 !== 0;

			/**	Flip order of elements on odd rows
			 *  Even index + odd row number -> increase order by 1
			 *  Odd index + odd row number -> decrease order by 1
			 */
			if (index > 1 && evenIndex && !evenRow) {
				classString = `order-${index + 1} ${direction}`;
			} else if (index > 1 && !evenIndex && !evenRow) {
				classString = `order-${index - 1} ${direction}`;
			} else {
				classString = `order-${index} ${direction}`;
			}

			// Set last item to 100% width if there are odd number of links
			if (index === this.sequences.length - 1 && oddAmountOfLinks) {
				classString += ' w-100';
			}
		}

		return classString;
	}

	/** Get class for direction of arrow */
	getDirectionClass(index, rowNumber): string {
		// Last item should have no arrow
		if (index === this.sequences.length - 1) { return ''; }

		const evenIndex = index % 2 === 0;
		const evenRow = rowNumber % 2 === 0;

		/**
		 *  Even index + even row number -> right arrow.
		 *  Even index + odd row number -> left arrow.
		 *  Odd index + even row number -> right down arrow
		 * 	Odd index + odd row number -> left down arrow
		 */
		if (evenIndex) {
			return evenRow ? 'right-arrow' : 'left-arrow';
		} else {
			return evenRow ? 'right-down-arrow' : 'left-down-arrow';
		}
	}

	private resolveSequence(sequence): RelatedSequence {
		const linkObject = this.util.extract(sequence, 'LinkTargets', [0]);
		const linkUrl = this.linkService.getUrl(linkObject);

		return {
			title: this.util.extract(sequence, 'Title'),
			icon: this.util.extract(sequence, 'Icon'),
			linkObject: linkObject,
			linkTitle: this.linkService.getTitle(linkObject),
			readMoreTitle: this.util.extract(sequence, 'ReadMoreLinkTitle'),
			active: linkUrl === `/${this.activatedRoute.snapshot.url.join('/')}`
		};
	}

	/** Check if on desktop screen width */
	inDesktopView(): boolean {
		return (window.innerWidth || this.doc.documentElement.clientWidth) > this.constants.BOOTSTRAP_BREAKPOINTS.LG;
	}

	/** Check if on mobile screen width */
	inMobileView(): boolean {
		return (window.innerWidth || this.doc.documentElement.clientWidth) < this.constants.BOOTSTRAP_BREAKPOINTS.MD;
	}
}
<div class="related-sequence">
    <h5 class="mb-4 title" *ngIf="sequences[0].readMoreTitle">{{sequences[0].readMoreTitle | uppercase }}</h5>
    <div class="card-group">
        <a component-link [ngClass]="['card', getOrder(i), sequence.active ? 'active' : '']" [linkObject]="sequence.linkObject" [ngStyle]="{'z-index': sequences.length - i}" *ngFor="let sequence of sequences; let i=index">
            <div class="card-body">
                <i *ngIf="!inMobileView() && sequence.icon" [class]="sequence.icon"></i>
                <div>
                    <div class="card-title">
                        <i *ngIf="inMobileView()" [ngClass]="[sequence.icon ? sequence.icon : '', 'link-icon' ]"></i>
                        <span>{{sequence.title | uppercase}}</span>
                        <i class="icon-chevronLarge-next chevron" *ngIf="!sequence.active"></i>
                    </div>
                    <div class="card-text">
                        <i *ngIf="sequence.linkObject?.LinkModelTarget?.MimeType === 'application/zip' " class="icon-link-download"></i>
                        {{sequence.linkTitle}}
                    </div>
                </div>
            </div>
        </a>
    </div>
</div>

./related-links-sequence-main.component.scss

@import "src/app/styles/helpers";

.related-sequence {
    padding: calc-rem(30) 0;

    .title {
        @include font-scale(14, uppercase);
    }

    .card-group {
        >.card {
            flex: unset;
            @include media-breakpoint-up(lg) {
                flex: 1 0 0%;
            }

        }

        @include media-breakpoint-down(lg) {
            flex-direction: row;
            flex-wrap: wrap;
        }

    }

    .card {
        width: 50%;
        margin-bottom: 0;
        border: none;   // remove default card border
        position: relative;
        background: $cool-grey;
        border: 2px solid white;

        &[target=_blank]:after {
            content: none;
            margin: 0;
        }

        &.active {
            background: $dark-blue;
        }

        &-body {
            padding-left: calc-rem(25);

            @include media-breakpoint-down(md) {
                display: flex;
            }

            i {
                align-self: center;
                color: $light-blue;
                @include font-size(25);

                @include media-breakpoint-up(sm) { margin-right: calc-rem(10); }
            }
        }

        &-title {
            display: flex;
            align-items: center;
            margin-bottom: 0;
            color: $light-blue;
            @include font-size(14);

            .link-icon {
                @include font-size(20);
                margin-right: calc-rem(5);
            }
            
            .chevron {
                @include font-size(13);
            }
        }
        &-text {
            color: white;
            @include font-size(14);

            .icon-link-download {
                @include font-size(14);
                margin-right: calc-rem(5);
            }
        }
        
        &:not(:last-child) {
            &:after, &:before {
                border: solid transparent;
                content: " ";
                height: 0;
                width: 0;
                position: absolute;
                pointer-events: none;
            }
            &:after {
                border-color: rgba(72, 90, 100, 0); // White color for arrow
                border-width: calc-rem(16);
            }
            &:before {
                border-color: rgba(194, 225, 245, 0);   // White color for arrow
                border-width: calc-rem(22);
            }
        }
        
        &.right-arrow {
            &:after, &:before {
                left: 100%;
                top: 50%;
            }
            &:after {
                border-left-color: $cool-grey;
                margin-top: calc-rem(-14);
            }
            &:before {
                border-left-color: white;
                margin-top: calc-rem(-20);
            }

            &:hover {
                &:after {
                    border-left-color: $blue;
                }
            }

            &.active {
                &:after {
                    border-left-color: $dark-blue;
                }
                &:hover {
                    &:after { border-left-color: $blue; }
                }
            }
        }

        &.left-arrow {
            &:after, &:before {
                right: 100%;
                top: 50%;
            }
            &:after {
                border-right-color: $cool-grey;
                margin-top: calc-rem(-14);
            }
            &:before {
                border-right-color: white;
                margin-top: calc-rem(-20);
            }
            &:hover {
                &:after {
                    border-right-color: $blue;
                }
            }

            &.active {
                &:after {
                    border-right-color: $dark-blue;
                }
                &:hover { 
                    &:after { border-right-color: $blue; }
                } 
            }
        }

        &.right-down-arrow {
            &:after, &:before {
                top: 100%;
                right: 20%;
            }
            &:after {
                border-top-color: $cool-grey;
                margin-right: calc-rem(-14);
            }
            &:before {
                border-top-color: white;
                margin-right: calc-rem(-20);
            }
            &:hover {
                &:after {
                    border-top-color: $blue;
                }
            }

            &.active {
                &:after {
                    border-top-color: $dark-blue;
                }
                &:hover {
                    &:after {
                        border-top-color: $blue;
                    }
                }
            }
        }

        &.left-down-arrow {
            &:after, &:before {
                top: 100%;
                left: 20%;
            }
            &:after {
                border-top-color: $cool-grey;
                margin-left: calc-rem(-14);
            }
            &:before {
                border-top-color: white;
                margin-left: calc-rem(-20);
            }
            &:hover {
                &:after {
                    border-top-color: $blue;
                }
            }

            &.active {
                &:after {
                    border-top-color: $dark-blue;
                }
                &:hover {
                    &:after {
                        border-top-color: $blue;
                    }
                }
            }
        }

        // Desktop view
        @include media-breakpoint-up(lg) {
            width: calc(12.5% - calc-rem(10));

            &:not(:last-child) {
                &:after, &:before {
                    right: unset;
                    left: 100%;
                    top: 50%;
                }
                &:after {
                    // Reset style from mobile view
                    border-color: unset;
                    margin: 0;

                    border-color: rgba(72, 90, 100, 0); // White color for arrow
                    border-left-color: $cool-grey;
                    margin-top: calc-rem(-14);
                }
                &:before {
                    // Reset style from mobile view
                    border-color: unset;
                    margin: 0;

                    border-color: rgba(72, 90, 100, 0); // White color for arrow
                    border-left-color: white;
                    margin-top: calc-rem(-20);
                }

                &.active {
                    &:after {
                        border-left-color: $dark-blue;
                    }
                    &:hover { 
                        &:after {
                            border-left-color: $blue;
                        }
                    }
                }
            }

            &:hover {
                &:after { border-left-color: $blue; }
            }
        }

        &:hover {
            background: $blue;
            text-decoration: none;
        }
    }
}
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""