File

app/dxa/dxa-entity/views/related-info-views/related-info-main/related-info-main.component.ts

Implements

OnInit OnDestroy

Metadata

changeDetection ChangeDetectionStrategy.OnPush
selector div[related-info-main]
styleUrls ./related-info-main.component.scss
templateUrl ./related-info-main.component.html

Index

Properties
Methods
Inputs
HostBindings

Constructor

constructor(util: UtilService, linkService: ComponentLinkService, idGenerator: IdGeneratorService, resizer: ResizeContentService, constants: ConstantsService, changeDetector: ChangeDetectorRef, doc)
Parameters :
Name Type Optional
util UtilService No
linkService ComponentLinkService No
idGenerator IdGeneratorService No
resizer ResizeContentService No
constants ConstantsService No
changeDetector ChangeDetectorRef No
doc No

Inputs

entity

HostBindings

class

Methods

actOnResize
actOnResize()
Returns : void
inDesktopView
inDesktopView(width: number)
Parameters :
Name Type Optional
width number No
Returns : boolean
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
Public resolveColumn
resolveColumn(column, CtaTitle, CtaLinkTarget)

Resolves a column to a uniform format

Parameters :
Name Optional
column No
CtaTitle No
CtaLinkTarget No
Public resolveDescription
resolveDescription(description: string)
Parameters :
Name Type Optional
description string No
Returns : boolean
Public setUpFields
setUpFields()
Returns : void
Public videoLoad
videoLoad(e, index)
Parameters :
Name Optional
e No
index No
Returns : void

Properties

Public accordionId
Default value : this.idGenerator.getId()
Public columns
Type : []
Default value : []
Private componentId
Default value : this.idGenerator.getId()
Public desktopView
Type : boolean
isLoading
Default value : false
Public title
Type : string
windowWidth
Type : any
import { Component, OnDestroy, Input, ChangeDetectionStrategy, Inject, ChangeDetectorRef, HostBinding, OnInit } from '@angular/core';
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 { DOCUMENT } from '@angular/common';
import { IdGeneratorService } from 'src/app/core/services/id-generator.service';
import { ResizeContentService } from 'src/app/core/services/resize-service/resize-content.service';
import { ConstantsService } from 'src/app/shared/constants/constants.service';
@Component({
	selector: 'div[related-info-main]',
	templateUrl: './related-info-main.component.html',
	styleUrls: ['./related-info-main.component.scss'],
	changeDetection: ChangeDetectionStrategy.OnPush
})
export class RelatedInfoMainComponent implements OnInit, OnDestroy {

	@Input() entity;
	isLoading = false;
	public columns = [];
	public title: string;
	public desktopView: boolean;
	public accordionId = this.idGenerator.getId();
	windowWidth: any;
	private componentId = this.idGenerator.getId();

	@HostBinding('class') get class() {
		const template = this.util.extract(this.entity, 'MvcData', 'ViewName');
		if (template === 'RelatedInfoLightGreyMain') {
			return 'col-md-12 space-between bg-off-white';
		} else {
			return 'col-md-12 space-between';
		}
	}

	constructor(
		private util: UtilService,
		private linkService: ComponentLinkService,
		private idGenerator: IdGeneratorService,
		private resizer: ResizeContentService,
		private constants: ConstantsService,
		private changeDetector: ChangeDetectorRef,
		@Inject(DOCUMENT) private doc) { }


	public videoLoad(e, index) {
		const v = e.srcElement.duration;
		// Assuming that title has loaded since that the video tag has loaded
		const a = new Date(null);
		a.setSeconds(v);
		const time = a.toISOString().substr(11, 8).replace(/^0+/, '').replace(/^:+/, '');

		this.columns[index].linkToVideo.linkTitle += ' (' + time + ')';
	}

	ngOnInit(): void {
		const width = (window.innerWidth || this.doc.documentElement.clientWidth);
		this.desktopView = this.inDesktopView(width);
		this.resizer.registerCallback(this.componentId, () => this.actOnResize());
		
		this.setUpFields();
	}

	ngOnDestroy(): void {
		this.resizer.destroyCallback(this.componentId);
	}

	actOnResize(): void {
		const width = (window.innerWidth || this.doc.documentElement.clientWidth);
		this.desktopView = this.inDesktopView(width);
		this.changeDetector.detectChanges();
	}

	public setUpFields() {
		const id = this.util.extract(this.entity, 'Id');
		this.title = this.util.extract(this.entity, 'Title') || '';
		const columnOne = this.util.extract(this.entity, 'ColumnOne') || '';
		const columnOneCtaTitle = this.util.extract(this.entity, 'ColumnOneCtaTitle') || '';
		const columnOneCtaLinkTarget = this.util.extract(this.entity, 'ColumnOneCtaLinkTarget') || {};
		const columnTwo = this.util.extract(this.entity, 'ColumnTwo') || '';
		const columnTwoCtaTitle = this.util.extract(this.entity, 'ColumnTwoCtaTitle') || '';
		const columnTwoCtaLinkTarget = this.util.extract(this.entity, 'ColumnTwoCtaLinkTarget') || {};
		const columnThree = this.util.extract(this.entity, 'ColumnThree') || '';
		const columnThreeCtaTitle = this.util.extract(this.entity, 'ColumnThreeCtaTitle') || '';
		const columnThreeCtaLinkTarget = this.util.extract(this.entity, 'ColumnThreeCtaLinkTarget') || {};

		const content = this.resolveColumn(columnOne, columnOneCtaTitle, columnOneCtaLinkTarget);
		const content2 = this.resolveColumn(columnTwo, columnTwoCtaTitle, columnTwoCtaLinkTarget);
		const content3 = this.resolveColumn(columnThree, columnThreeCtaTitle, columnThreeCtaLinkTarget);

		// Need these for the mobile view, add box at the start since ids need to start with a letter
		content['boxId'] = `box-${this.idGenerator.getId()}`;
		content2['boxId'] = `box-${this.idGenerator.getId()}`;
		content3['boxId'] = `box-${this.idGenerator.getId()}`;

		this.columns = [content, content2, content3];
		this.changeDetector.detectChanges();
	}

	/** Resolves a column to a uniform format */
	public resolveColumn(column, CtaTitle, CtaLinkTarget) {

		const links = column.LinkTarget || [];
		const videojson = this.util.extract(column, 'Video');

		const resolved = {
			videojson: videojson,
			Icon: this.util.extract(column, 'Icon'),
			Title: this.util.extract(column, 'Title'),
			Description: this.util.extract(column, 'Description'),
			links: links.map(link => this.linkService.parseLink(link)),
			CtaButtonTitle: CtaTitle,
			CtaButtonLinkTarget: CtaLinkTarget,
			hasVideo: !!this.util.extract(column, 'Video')
		};

		return resolved;

	}

	public resolveDescription(description: string): boolean {
		return description === 'With description';

	}

	inDesktopView(width: number): boolean {
		return width > this.constants.BOOTSTRAP_BREAKPOINTS.LG;
	}
}
<div class="container">
  <h2 *ngIf="title" class="title">{{title}}</h2>
  <div class="accordion" [id]="'accordion-' + accordionId" *ngIf="!desktopView">
    <div class="card" [id]="'card-' + col.boxId + '-' + accordionId" *ngFor="let col of columns; let i = index;">
      <div class="card-header" [id]="'heading-' + accordionId">
        <h5 class="mb-0">
          <a class="toggler" data-toggle="collapse" [href]="'#' + col.boxId + '-' + accordionId"
            [attr.aria-expanded]="i === 0" [attr.aria-controls]="col.boxId + '-' + accordionId">
            <i class="card-header-icon" [ngClass]="col.Icon"></i>
            <span *ngIf="!col.hasVideo">{{col.Title}}</span>
            <span *ngIf="col.hasVideo">{{col.Icon}}</span>
            <i class="card-header-chevron icon-chevronDown"></i>
            <i class="card-header-chevron icon-chevronUp"></i>
          </a>
        </h5>
      </div>
      <div [id]="col.boxId + '-' + accordionId" [ngClass]="{'collapse': true, 'show': i === 0}"
        [attr.aria-labelledby]="'heading-' + accordionId" [attr.data-parent]="'#accordion-' + accordionId">
        <div class="card-body">
          <div class="card-text">     
            <div *ngIf="col.hasVideo" video-player [videoJSON]="col.videojson">
            </div>
          </div>

          <ng-container *ngIf="!col.hasVideo">
            <div class="list-group list-group-flush" *ngIf="col.links && !col.Description">
              <a class="comp-link" component-link [linkObject]="link.linkObject"
                class="list-group-item list-group-item-action" *ngFor="let link of col.links">
                <div class="link-group-title">
                    <i *ngIf="link.linkObject?.LinkModelTarget?.MimeType === 'application/pdf' " class="icon-related-pdf"></i>
                    <i *ngIf="link.linkObject?.LinkModelTarget?.MimeType === 'application/zip' " class="icon-link-download"></i>
                    {{link.title}}
                    <span *ngIf="link.linkObject?.LinkModelTarget?.MimeType === 'application/pdf'">{{link.fileSize}} </span>
                  <i *ngIf="link.newWindow" class="icon-link-openNewWindow"></i>
                </div>
                <p class="mb-0" *ngIf="link.useDescription">
                  {{link.description}}
                </p>
              </a>
            </div>

            <p *ngIf="col.Description">
              {{col.Description}}
            </p>
          </ng-container>
        </div>

        <div class="card-footer" *ngIf="col.CtaButtonTitle">
          <a component-link [linkObject]="col.CtaButtonLinkTarget" class="btn btn-cool-grey button-link">
            {{col.CtaButtonTitle}}
          </a>
        </div>
      </div>
    </div>
  </div>

  <div class="card-group" [id]="accordionId" *ngIf="desktopView">
    <ng-container *ngFor="let col of columns; let i = index;">
      <div class="card">
        <div class="card-header">
          <h5 class="mb-0 d-inline-flex">
            <i class="card-header-icon" [ngClass]="col.Icon"></i>
            <span *ngIf="col.Title">{{col.Title}}</span>
          </h5>
        </div>

        <div class="card-body">
          <div class="card-text">

            <div *ngIf="col.hasVideo" video-player [videoJSON]="col.videojson" [videoDescription]="col.Description"></div>

            <ng-container *ngIf="!col.hasVideo">
              <div class="list-group list-group-flush" *ngIf="col.links && !col.Description">
                <a class="comp-link" component-link [linkObject]="c.linkObject"
                  class="list-group-item list-group-item-action" *ngFor="let c of col.links">
                  <div class="link-group-title">
                    <i *ngIf="c.linkObject?.LinkModelTarget?.MimeType === 'application/pdf' " class="icon-related-pdf"></i>
                    <i *ngIf="c.linkObject?.LinkModelTarget?.MimeType === 'application/zip' " class="icon-link-download"></i>
                    {{c.title}}
                    <span *ngIf="c.linkObject?.LinkModelTarget?.MimeType === 'application/pdf'"> {{c.fileSize}} </span>
                    <i *ngIf="c.openInNewWindow" class="icon-link-openNewWindow"></i>
                  </div>
                  <p class="mb-0" *ngIf="c.useDescription">{{c.description}}</p>
                </a>
              </div>

              <p *ngIf="col.Description">{{col.Description}}</p>
            </ng-container>
          </div>
        </div>

        <div class="card-footer" *ngIf="col.CtaButtonTitle">
          <a component-link [linkObject]="col.CtaButtonLinkTarget" class="btn btn-cool-grey button-link">
            {{col.CtaButtonTitle}}
          </a>
        </div>

      </div>
    </ng-container>
  </div>

./related-info-main.component.scss

@import "src/app/styles/helpers";
//@import "~bootstrap/scss/card";
//@import "~bootstrap/scss/list-group";

.title {
    padding-left: calc-rem(40);
    padding-bottom: calc-rem(35);
}

.accordion {
    border: 2px solid $slate;
}

.card-group {
    border: 2px solid $slate;
    padding-bottom: 0;
}

.card {
    
    :host-context(.bg-off-white) {
        background-color: $off-white;
    }

    &-header,
    &-body,
    &-footer {
        background-color: $white;

        ::ng-deep .bg-off-white & {
            background-color: $off-white;
        }
    }

    &-body {

        .video-description-text {
            color: $blue;
            @include font-scale(16, medium);
        }

        .list-group {
            &-item {
                border-bottom: 1px solid $slate !important;
                padding: calc-rem(10) 0;
                color: $blue;
                background-color: transparent;

                &:after {
                    content: none;
                }

                p {
                    color: $cool-grey;
                    @include font-size(16);
                }

                &:hover {
                    background-color: $blue;
                    padding-left: calc-rem(8);
                    color: $white;

                    &:hover {
                        text-decoration: none;
                    }

                    p {
                        color: $white;
                    }
                }
            }

            .comp-link:last-child {
                .list-group-item {
                    border-bottom: none !important;
                }
            }
        }
    }

    &-footer {
        .button-link {
            width: 100%;
        }
    }

    .accordion & {
        margin-left: calc-rem(30);
        margin-right: calc-rem(30);
        border: none;

        &:first-of-type,
        &:not(:first-of-type):not(:last-of-type) {
            border-bottom: 2px solid $slate;
        }

        &-header {
            position: relative;
            padding: calc-rem(30) 0;
            border-bottom: none;

            &-icon {
                padding-right: calc-rem(25);
            }

            &-chevron {
                text-align: right;
                position: absolute;
                top: 45%;
                right: calc-rem(12);
                @include font-size(12);
                color: $blue;
                font-style: normal;
            }

            .toggler {
                color: $cool-grey;
                display: block;
                text-decoration: none;

                &[aria-expanded=true] .icon-chevronDown {
                    display: none;
                }

                &[aria-expanded=false] .icon-chevronUp {
                    display: none;
                }
            }
        }

        &-body {
            padding-left: 0;
            padding-right: 0;
        }

        &-footer {
            border: none;
            text-align: center;
            padding-bottom: calc-rem(60);
        }
    }

    .card-group & {
        border-bottom: none;
        border-right: 2px solid $slate;
    
        &:last-child {
            border-right: none;
        }

        &-header {
            padding: calc-rem(40) calc-rem(40) calc-rem(20) calc-rem(70);
            border: none;
            @include font-scale(20, bold);
    
            &-icon {
                position: absolute;
                font-size: calc-rem(30);
                transform: translate(-45px, -7px);
            }
        }

        &-body {
            padding-left: calc-rem(70);
            padding-right: calc-rem(50);
        }

        &-footer {
            border: none;
            text-align: center;
            padding-bottom: calc-rem(60);
            padding-left: calc-rem(70);
            padding-right: calc-rem(50);
        }
    }    
}
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""