File

libs/core/src/lib/debugger/building-block-debugger/building-block-debugger.ts

Description

A component that helps visualizing how a component acts as a Building Block. Output ID, Features & Complete Status. Access State.

Implements

OnInit

Metadata

Index

Properties
Methods
Inputs
Accessors

Constructor

constructor(detectedBuildingBlock: AbstractBuildingBlock<T | U>)
Parameters :
Name Type Optional
detectedBuildingBlock AbstractBuildingBlock<T | U> No

Inputs

buildingBlock
Type : AbstractBuildingBlock<T, U>
exampleResources
Type : U
Default value : {} as U
exampleState
Type : T
Default value : {} as T

Methods

clear
clear()
Returns : void
commitCompletion
commitCompletion()
Returns : void
logState
logState()
Returns : void
revertCompletion
revertCompletion()
Returns : void
setExampleResources
setExampleResources()
Returns : void
setExampleState
setExampleState(evt?: Event)
Parameters :
Name Type Optional
evt Event Yes
Returns : void

Properties

Public debuggerOpened
Default value : false

Accessors

buildingBlock
getbuildingBlock()
setbuildingBlock(value: AbstractBuildingBlock<T | U>)
Parameters :
Name Type Optional
value AbstractBuildingBlock<T | U> No
Returns : void
buildingBlockId
getbuildingBlockId()
completion$
getcompletion$()
import { Component, Input, OnInit, Optional, SkipSelf } from '@angular/core';
import {
  AbstractBuildingBlock,
  RecordObjectLike,
  NoArray
} from '../../building-block/abstract-building-block';

/**
 * A component that helps visualizing how a component acts as a Building Block.
 * Output ID, Features & Complete Status. Access State.
 */
@Component({
  selector: 'building-block-debugger',
  templateUrl: 'building-block-debugger.html',
  styleUrls: ['building-block-debugger.scss'],
  standalone: false
})
// eslint-disable-next-line @angular-eslint/component-class-suffix
export class BuildingBlockDebugger<T extends RecordObjectLike | undefined, U> implements OnInit {
  public debuggerOpened = false;

  private _buildingBlock!: AbstractBuildingBlock<T, U>;
  @Input() exampleState = {} as T;
  @Input() exampleResources = {} as U;

  @Input()
  set buildingBlock(value: AbstractBuildingBlock<T, U>) {
    this._buildingBlock = value;
  }
  get buildingBlock() {
    return this._buildingBlock;
  }

  constructor(@Optional() @SkipSelf() detectedBuildingBlock: AbstractBuildingBlock<T, U>) {
    this.buildingBlock = detectedBuildingBlock;
  }

  get buildingBlockId() {
    return this.buildingBlock.id ? this.buildingBlock.id : 'N/A';
  }

  get completion$() {
    return this.buildingBlock.completion$;
  }

  setExampleState(evt?: Event) {
    console.log(
      `Forward Example State to Building Block '${this.buildingBlock.id}' with value`,
      this.exampleState
    );
    this.buildingBlock.setState(this.exampleState as NoArray<T>);
    if (evt) {
      evt.stopPropagation();
    }
  }

  setExampleResources() {
    this.buildingBlock.setResources(this.exampleResources);
  }

  revertCompletion() {
    this.buildingBlock.revertCompletion();
  }

  commitCompletion() {
    this.buildingBlock.commitCompletion();
  }

  clear() {
    this.buildingBlock.setState({} as NoArray<T>);
    this.buildingBlock.setResources({} as U);
  }

  logState() {
    console.log(this.buildingBlock.getState());
  }

  ngOnInit() {
    if (!this.buildingBlock) {
      throw new Error(
        'You used the Building Block Debugger without providing a Building Block ([buildingBlock]) or using it insides a given Building Block'
      );
    }
  }
}
<button
  class="debug-opener {{ debuggerOpened ? 'debug-opener--opened' : '' }}"
  (click)="debuggerOpened = !debuggerOpened"
>
  <svg
    class="debug-opener--svg"
    *ngIf="(completion$ | async) === false"
    name="waiting"
    width="30"
    height="30"
    viewBox="0 0 24 24"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
  >
    <path
      fill-rule="evenodd"
      clip-rule="evenodd"
      d="M6.75 12C6.75 9.10051 9.10051 6.75 12 6.75C14.8995 6.75 17.25 9.10051 17.25 12C17.25 14.8995 14.8995 17.25 12 17.25C9.10051 17.25 6.75 14.8995 6.75 12ZM12 5.25C8.27208 5.25 5.25 8.27208 5.25 12C5.25 15.7279 8.27208 18.75 12 18.75C15.7279 18.75 18.75 15.7279 18.75 12C18.75 8.27208 15.7279 5.25 12 5.25ZM11.25 8V12C11.25 12.1989 11.329 12.3897 11.4697 12.5303L13.4697 14.5303L14.5303 13.4697L12.75 11.6893V8H11.25Z"
      fill="#C4C4C4"
    />
  </svg>
  <svg
    class="debug-opener--svg"
    *ngIf="(completion$ | async)"
    name="check"
    width="30"
    height="30"
    viewBox="0 0 24 24"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
  >
    <circle cx="12" cy="12" r="8" fill="#75F0C7" />
    <path
      fill-rule="evenodd"
      clip-rule="evenodd"
      d="M16.6002 9.44999L12.1002 15.45C11.9768 15.6145 11.7914 15.7211 11.5872 15.7449C11.383 15.7688 11.1779 15.7078 11.02 15.5762L8.02002 13.0762L8.9803 11.9238L11.3738 13.9184L15.4002 8.54999L16.6002 9.44999Z"
      fill="#202840"
    />
  </svg>
  {{buildingBlockId}}
  <button
    *ngIf="exampleState"
    class="debug-opener-button"
    (click)="setExampleState($event)"
    title="Set example state data"
  >
    Set State
  </button>
  <span class="triangle"
    ><span class="{{ debuggerOpened ? 'triangle-up' : 'triangle-down' }}"></span
  ></span>
</button>

<div class="debug-content" *ngIf="debuggerOpened">
  <div>Actions</div>
  <div class="debug-actions">
    <button
      class="debug-pill-btn"
      *ngIf="(completion$ | async) === false"
      (click)="commitCompletion()"
    >
      Complete
    </button>
    <button class="debug-pill-btn" *ngIf="(completion$ | async)" (click)="revertCompletion()">
      Reset Completion
    </button>
    <button class="debug-pill-btn" (click)="clear()">Clear State</button>
    <button class="debug-pill-btn" (click)="logState()">Log State</button>
    <button class="debug-pill-btn" *ngIf="exampleResources" (click)="setExampleResources()">
      Set Resources (Example)
    </button>
    <button class="debug-pill-btn" *ngIf="exampleState" (click)="setExampleState()">
      Set State (Example)
    </button>
  </div>
  <div class="debug-status">
    <div class="text-waiting" *ngIf="(completion$ | async) === false">
      Waiting &nbsp;
      <svg
        name="waiting"
        class="waiting"
        width="24"
        height="24"
        viewBox="0 0 24 24"
        fill="none"
        xmlns="http://www.w3.org/2000/svg"
      >
        <path
          fill-rule="evenodd"
          clip-rule="evenodd"
          d="M6.75 12C6.75 9.10051 9.10051 6.75 12 6.75C14.8995 6.75 17.25 9.10051 17.25 12C17.25 14.8995 14.8995 17.25 12 17.25C9.10051 17.25 6.75 14.8995 6.75 12ZM12 5.25C8.27208 5.25 5.25 8.27208 5.25 12C5.25 15.7279 8.27208 18.75 12 18.75C15.7279 18.75 18.75 15.7279 18.75 12C18.75 8.27208 15.7279 5.25 12 5.25ZM11.25 8V12C11.25 12.1989 11.329 12.3897 11.4697 12.5303L13.4697 14.5303L14.5303 13.4697L12.75 11.6893V8H11.25Z"
          fill="#C4C4C4"
        />
      </svg>
    </div>
    <div class="text-success" *ngIf="(completion$ | async)">
      Complete
      <svg
        name="complete"
        class="complete"
        width="30"
        height="30"
        viewBox="0 0 24 24"
        fill="none"
        xmlns="http://www.w3.org/2000/svg"
      >
        <path
          fill-rule="evenodd"
          clip-rule="evenodd"
          d="M16.1002 9.44999L11.6002 15.45C11.4768 15.6145 11.2914 15.7211 11.0872 15.7449C10.883 15.7688 10.6779 15.7078 10.52 15.5762L7.52002 13.0762L8.4803 11.9238L10.8738 13.9184L14.9002 8.54999L16.1002 9.44999Z"
          fill="#75F0C7"
        />
      </svg>
    </div>
  </div>
  <!--
    Allow to output additional content that might be given
    through ng-content (like additional building-block-debugger interactions with the BB).
    That content would be included in the
    open/closing panel and provides a nice building-block-debugger experience on top
  -->
  <ng-content></ng-content>
</div>

building-block-debugger.scss

@use './debugger-shared.scss' as *;

:host {
  display: inline-block;
  padding-bottom: 10px;
}

.debug-opener {
  width: 100%;
  display: flex;
  border: none;
  align-items: center;
}

.debug-opener-button {
  font-size: 15px;
  line-height: 24px;
  padding: 1px 8px;
  margin: 0 10px;
  background: $debug-color-cta;
  border: 1px solid $debug-color-cta;
  color: #fff;
  border-radius: 3px;
  display: inline-block;
  transition: border-color 0.3s ease;
  cursor: pointer;
  &:hover,
  &:focus {
    border-color: $debug-color-border-hover;
  }
}

.debug-opener--svg {
  margin-right: 4px;
}

.debug-actions {
  margin: 8px 0;
}
.debug-pill-btn {
  color: #fff;
  background-color: $debug-color-dark;
  border-radius: 3px;
  padding: 5px 7px;
  margin-right: 5px;
  font-weight: 700;
  border: 1px solid $debug-color-dark;
  cursor: pointer;
  transition: border-color 0.3s ease;

  &:last-child {
    margin-right: 0;
  }
  &:hover,
  &:focus {
    border-color: $debug-color-border-hover;
  }
}
.debug-status {
  margin-top: 16px;
  font-weight: 700;
}
.debug-status > * {
  display: inline-block;
}
.debug-status .waiting {
  margin-bottom: -8px;
}
.debug-status .complete {
  margin-bottom: -10px;
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""