Takumon/mean-blog

View on GitHub
src/app/drafts/draft-edit/draft-edit.component.html

Summary

Maintainability
Test Coverage
<form
  [formGroup]="form"
  class="article-editor"
  >
  <div class="article-editor__title">
    <input
      type="text"
      id="register-article-title"
      formControlName="title"
      placeholder="タイトル" />
    <div
      *ngIf="messageService.hasError(title, 'required') || messageService.hasError(title, 'maxlength') || messageService.hasErrorWithoutDirty(title, 'remote')"
      class="register-article-title__messages">
      <mat-error *ngIf="messageService.hasError(title, 'required')">
        {{ messageService.get('required',['タイトル']) }}
      </mat-error>
      <mat-error *ngIf="messageService.hasError(title, 'maxlength')">
        {{ messageService.get('maxlength',['タイトル' , title.getError('maxlength').requiredLength]) }}
      </mat-error>
      <mat-error *ngIf="messageService.hasErrorWithoutDirty(title, 'remote')">
        <ng-container *ngFor="let msg of title.getError('remote')">
          {{msg}}<br>
        </ng-container>
      </mat-error>
    </div>
  </div>

  <div class="article-editor__format-operation">
    <mat-checkbox
      formControlName="isMarkdown"
      >Markdonw形式</mat-checkbox>

    <div
      *ngIf="isMarkdown.value"
      class="editor-support">
      <i
      matTooltip="太字"
      matTooltipPosition="above"
      [matTooltipShowDelay]="Constant.TOOL_TIP_SHOW_DELAY"
      (click)='draftEditAreaComponent.insertContentToCaretPosition("**", "**")'
      class="fa fa-fw fa-bold editor-support__icon"
      ></i>
      <i
      matTooltip="斜線"
      matTooltipPosition="above"
      [matTooltipShowDelay]="Constant.TOOL_TIP_SHOW_DELAY"
      (click)='draftEditAreaComponent.insertContentToCaretPosition("_", "_")'
      class="fa fa-fw fa-italic editor-support__icon"
      ></i>
      <i
      matTooltip="取り消し線"
      matTooltipPosition="above"
      [matTooltipShowDelay]="Constant.TOOL_TIP_SHOW_DELAY"
      (click)='draftEditAreaComponent.insertContentToCaretPosition("~~", "~~")'
      class="fa fa-fw fa-strikethrough editor-support__icon"
      ></i>


      <i class="editor-support__separator"></i>

      <i
        matTooltip="ヘッダー"
        matTooltipPosition="above"
        [matTooltipShowDelay]="Constant.TOOL_TIP_SHOW_DELAY"
        [matMenuTriggerFor]="menu"
        class="fa fa-fw fa-header editor-support__icon"
      ></i>

      <mat-menu
        #menu="matMenu"
        [overlapTrigger]="false"
        yPosition="below"
        class="header-menu">
        <button
          mat-menu-item
          (click)='draftEditAreaComponent.insertToLineStart("# ")'
          >
          <span class="header-menu__h1"> H1: Header</span>
        </button>
        <button
          mat-menu-item
          (click)='draftEditAreaComponent.insertToLineStart("## ")'
          >
          <span class="header-menu__h2"> H2: Header</span>
        </button>
        <button
          mat-menu-item
          (click)='draftEditAreaComponent.insertToLineStart("### ")'
          >
          <span class="header-menu__h3"> H3: Header</span>
        </button>
        <button
          mat-menu-item
          (click)='draftEditAreaComponent.insertToLineStart("#### ")'
          >
          <span class="header-menu__h4"> H4: Header</span>
        </button>
        <button
          mat-menu-item
          (click)='draftEditAreaComponent.insertToLineStart("##### ")'
          >
          <span class="header-menu__h5"> H5: Header</span>
        </button>
        <button
          mat-menu-item
          (click)='draftEditAreaComponent.insertToLineStart("###### ")'
          >
          <span class="header-menu__h6"> H6: Header</span>
        </button>

      </mat-menu>

      <i
      matTooltip="リンク"
      matTooltipPosition="above"
      [matTooltipShowDelay]="Constant.TOOL_TIP_SHOW_DELAY"
      (click)='draftEditAreaComponent.insertContentToCaretPosition("[", "](https://)")'
      class="fa fa-fw fa-link editor-support__icon"
      ></i>
      <i
      matTooltip="ソースコード"
      matTooltipPosition="above"
      [matTooltipShowDelay]="Constant.TOOL_TIP_SHOW_DELAY"
      (click)="draftEditAreaComponent.insertCodeWrapper()"
      class="fa fa-fw fa-code editor-support__icon"
      ></i>
      <i
      matTooltip="引用"
        matTooltipPosition="above"
        [matTooltipShowDelay]="Constant.TOOL_TIP_SHOW_DELAY"
        (click)='draftEditAreaComponent.insertToLineStart("> ")'
      class="fa fa-fw fa-quote-left editor-support__icon"
      ></i>

      <i
      matTooltip="水平線"
      matTooltipPosition="above"
      [matTooltipShowDelay]="Constant.TOOL_TIP_SHOW_DELAY"
      (click)='draftEditAreaComponent.insertContentToCaretPosition("", "\n\n---\n")'
      class="fa fa-fw fa-minus editor-support__icon"
      ></i>


      <i class="editor-support__separator"></i>

      <i
      matTooltip="リスト"
      matTooltipPosition="above"
      [matTooltipShowDelay]="Constant.TOOL_TIP_SHOW_DELAY"
      (click)='draftEditAreaComponent.insertToLineStart("* ")'
      class="fa fa-fw fa-list-ul editor-support__icon"
      ></i>
      <i
      matTooltip="順序付きリスト"
      matTooltipPosition="above"
      [matTooltipShowDelay]="Constant.TOOL_TIP_SHOW_DELAY"
      (click)='draftEditAreaComponent.insertToLineStart("1. ")'
      class="fa fa-fw fa-list-ol editor-support__icon"
      ></i>
      <i
      matTooltip="テーブル"
      matTooltipPosition="above"
      [matTooltipShowDelay]="Constant.TOOL_TIP_SHOW_DELAY"
      (click)='draftEditAreaComponent.insertContentToCaretPosition("", "\n\n| Column 1 | Column 2 | Column 3 |\n| -------- | -------- | -------- |\n| Text     | Text     | Text     |\n")'
      class="fa fa-fw fa-table editor-support__icon"
      ></i>
    </div>

    <mat-button-toggle-group
      *ngIf="isMarkdown.value"
      [(ngModel)]="markdonwEditMode"
      [ngModelOptions]="{standalone: true}"
      class="select-format article-editor__select-format">
      <mat-button-toggle
        [value]="MarkdownEditMode[MarkdownEditMode.notPreviewing]"
        matTooltip="エディターのみ表示"
        [matTooltipShowDelay]="Constant.TOOL_TIP_SHOW_DELAY"
        class="select-format__button"
        >
        <i class="fa fa-fw fa-pencil-square-o" aria-hidden="true"></i>
      </mat-button-toggle>
      <mat-button-toggle
        [value]="MarkdownEditMode[MarkdownEditMode.harfPreviewing]"
        matTooltip="両方を表示"
        [matTooltipShowDelay]="Constant.TOOL_TIP_SHOW_DELAY"
        class="select-format__button_icon_twice">
        <i class="fa fa-fw fa-pencil-square-o" aria-hidden="true"></i> | <i class="fa fa-fw fa-eye" aria-hidden="true"></i>
      </mat-button-toggle>
      <mat-button-toggle
        [value]="MarkdownEditMode[MarkdownEditMode.fullPreviewing]"
        matTooltip="プレビューのみ表示"
        [matTooltipShowDelay]="Constant.TOOL_TIP_SHOW_DELAY"
        class="select-format__button">
        <i class="fa fa-fw fa-eye" aria-hidden="true"></i>
      </mat-button-toggle>
    </mat-button-toggle-group>

  </div>



  <div *ngIf="isMarkdown.value; then bodyMarkdown else bodyPlainText"></div>
  <ng-template #bodyMarkdown>
    <div class="article-editor__main markdonw-editor" >
      <div
        appDragAndDrop
        (filesChangeEmiter)="onFilesChange($event)"
        [allowed_extensions]="['png', 'jpg', 'bmp']"
        [ngClass]="['markdonw-editor__row-text', markdonwEditMode]">
        <app-draft-edit-area
          [body]="body"
          (scroll)="onScroll($event)"
          ></app-draft-edit-area>
      </div>


      <div class="image-operation" [class.show]="isImageOperationShow">
        <div class="image-operation__header">
          <button
            *ngIf="imageForDisplayList?.length > 0"
            mat-icon-button
            class="image-operation__header__showhide-btn"
            (click)="isImageOperationShow = !isImageOperationShow"
            >
            <i
              class="fa fa-fw"
              [class.fa-chevron-up]="!isImageOperationShow"
              [class.fa-chevron-down]="isImageOperationShow"
              ></i>
          </button>
          <div
            matRipple
            class="image-operation__header__showhide-btn"
            (click)="imageFile.click()">画像アップロード</div>
          <input
            hidden
            type="file"
            (change)="onFilesChange($event.srcElement.files)" #imageFile>
        </div>

        <div>
          <ng-container
            *ngIf="isImageOperationShow"
            >
            <div
              class="image-operation__image"
              *ngFor="let imageForDisplay of imageForDisplayList">
              <button
                mat-icon-button
                class="image-operation__image__insert-btn"
                (click)="draftEditAreaComponent.insertImageToArticle(imageForDisplay)"
              ><i class="fa fa-fw fa-plus-square"></i></button>
              <div class="image-operation__image__file-name">{{imageForDisplay.fileName}}</div>
              <div class="image-operation__image__spacer"></div>
              <button
                mat-icon-button
                class="image-operation__image__delete-btn"
                (click)="deleteImage(imageForDisplay)"
                ><i class="fa fa-fw fa-trash"></i></button>
            </div>
          </ng-container>
        </div>
      </div>

      <div [ngClass]="['markdonw-editor__preview', markdonwEditMode]" #syncScrollTarget>
        <p [innerHTML]="(body.value | toMarkdown).text" class="markdown-body"></p>
      </div>
    </div>
  </ng-template>
  <ng-template #bodyPlainText>
    <div class="article-editor__main plain-text-editor">
      <div class="plain-text-editor__row-text">
        <textarea
          id="register-article-body"
          formControlName="body"
          placeholder="本文"></textarea>
      </div>
    </div>
  </ng-template>


  <div class="article-editor__operation">
    <button
      mat-raised-button
      type="button"
      id="cancel-btn"
      (click)='cancel(form.dirty)'><i class="fa fa-times"></i>  キャンセル</button>
    <div class="spacer"></div>

    <div
      *ngIf="messageService.hasError(body, 'required') || messageService.hasError(body, 'maxlength') || messageService.hasErrorWithoutDirty(body, 'remote')"
      class="register-article-body__messages">

      <mat-error *ngIf="messageService.hasError(body, 'required')">
        {{ messageService.get('required',['本文']) }}
      </mat-error>
      <mat-error *ngIf="messageService.hasError(body, 'maxlength')">
        {{ messageService.get('maxlength',['本文' , body.getError('maxlength').requiredLength]) }}
      </mat-error>
      <mat-error *ngIf="messageService.hasErrorWithoutDirty(body, 'remote')">
        <ng-container *ngFor="let msg of body.getError('remote')">
          {{msg}}<br>
        </ng-container>
      </mat-error>
    </div>
    <button
      *ngIf="!canRegisterDraft"
      mat-raised-button
      color="accent"
      type="button"
      disabled
      ><i class="fa fa-floppy-o"></i>  下書きは{{Constant.MAX_DRAFT_COUNT}}件以上保存できません</button>
    <button
      *ngIf="canRegisterDraft"
      mat-raised-button
      color="accent"
      type="button"
      [disabled]="!form.valid"
      id="registe-draft-btn"
      (click)="upsertDraft(form)"
      ><i class="fa fa-floppy-o"></i>  下書き保存</button>
    <button
      mat-raised-button
      color="primary"
      type="submit"
      [disabled]="!form.valid"
      (click)="upsertArticle(form)"
      id="registe-article-btn"><i class="fa fa-upload"></i>  {{action}}</button>
  </div>
</form>