File

src/app/components/upload/upload.component.ts

Implements

OnInit

Metadata

Index

Properties
Methods
Outputs

Constructor

constructor(fb: FormBuilder)
Parameters :
Name Type Optional
fb FormBuilder No

Outputs

uploadForm
Type : EventEmitter

Methods

atLeastOnePhoneRequired
atLeastOnePhoneRequired(group: FormGroup)
Parameters :
Name Type Optional
group FormGroup No
Returns : literal type | null
checkLinkFormat
checkLinkFormat(url: string)
Parameters :
Name Type Optional
url string No
Returns : { sheetID: any; gid: any; csvUrl: string; }
submitData
submitData()
Returns : void
upload
upload(fileFormDataEvent: FormData)
Parameters :
Name Type Optional
fileFormDataEvent FormData No
Returns : void

Properties

Public fb
Type : FormBuilder
formGroup
Type : FormGroup
formValid
Default value : true
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms';
import { UploadForm } from '../../models/sheet.model';

@Component({
  selector: 'app-upload',
  templateUrl: './upload.component.html',
  styleUrls: ['./upload.component.scss'],
})
export class UploadComponent implements OnInit {
  @Output() uploadForm = new EventEmitter<UploadForm>();

  formGroup!: FormGroup;
  formValid = true;

  constructor(public fb: FormBuilder) {}

  ngOnInit(): void {
    this.formGroup = new FormGroup(
      {
        link: new FormControl('', [
          Validators.required,
          Validators.compose([Validators.pattern(/\/([\w-_]{15,})\/(.*?gid=(\d+))?|\w*csv$/)]) as ValidatorFn,
        ]),
        formData: new FormControl(''),
        fileName: new FormControl(''),
      },
      { validators: [this.atLeastOnePhoneRequired as ValidatorFn] },
    );

    this.formGroup.valueChanges.subscribe((x) => {
      if (!(x.fileName === null || x.fileName === '')) {
        this.formGroup.get('link')?.clearValidators();
        this.formGroup.get('link')?.updateValueAndValidity({ emitEvent: false });
      }
      this.formValid = this.formGroup.status === 'VALID';
    });
  }

  atLeastOnePhoneRequired(group: FormGroup): { [s: string]: boolean } | null {
    if (group) {
      if (group.controls['link'].value || group.controls['fileName'].value) {
        return null;
      }
    }
    return { error: true };
  }

  upload(fileFormDataEvent: FormData) {
    this.formGroup.patchValue({ formData: fileFormDataEvent });
  }

  submitData() {
    this.formValid = this.formGroup.status === 'VALID';
    if (this.formGroup.status !== 'VALID') {
      return;
    }
    const sheet = this.formGroup.value;
    const sheetId = this.checkLinkFormat(sheet.link)?.sheetID ?? '';

    const data: UploadForm = {
      link: sheet.link,
      formData: sheet.formData,
      fileName: sheet.fileName,
      sheetId,
      gid: this.checkLinkFormat(sheet.link)?.gid ?? '',
      csvUrl: this.checkLinkFormat(sheet.link)?.csvUrl ?? '',
    };
    // ga call handled in the playground module component

    this.uploadForm.emit(data);
  }

  checkLinkFormat(url: string) {
    if (url.startsWith('https://docs.google.com/spreadsheets/d/')) {
      const splitUrl = url.split('/');
      if (splitUrl.length === 7) {
        return {
          sheetID: splitUrl[5],
          gid: splitUrl[6].split('=')[1],
          csvUrl: '',
        };
      }
    }

    return {
      sheetID: '0',
      gid: '0',
      csvUrl: url,
    };
  }
}
<div class="">
  <mat-expansion-panel [expanded]="true">
    <mat-expansion-panel-header>
      <mat-panel-title>
        <div class="instruction-title">Instructions</div>
      </mat-panel-title>
    </mat-expansion-panel-header>

    <div class="mt-1 text-muted">
      <ul class="pl-3">
        <li class="text-justify">
          Through this feature, you can upload your own data (ASCT+B to ASCT+B, ASCT+B to experimental data, or ASCT+B
          to OMAP) by pasting the Browser URL address for the Google sheet of your data in the fields mentioned below.
        </li>
        <li class="text-justify">
          In order to successfully link your sheet, make sure the sheet has public access by selecting Share --> Get
          link --> selecting "Anyone with the link" option and "Viewer" privileges, select "Done" to save.
        </li>

        <li class="text-justify">
          Please make sure your data follows the appropriate data format:
          <ul class="pl-3">
            <li class="text-justify">
              <a
                href="https://docs.google.com/spreadsheets/d/1smQ8_3F-KSRlY7bmozsoM1EonQL4ahNaXP7zeQFf3Ko/edit#gid=0"
                target="_blank"
                >ASCT+B Table template</a
              >
            </li>
            <li class="text-justify">
              <a
                href="https://docs.google.com/spreadsheets/d/1DE4Bh2PI7mgaMciMOky2OTduNwYNRU-DyYQPT8szJ-Y/edit#gid=0"
                target="_blank"
                >OMAP compare template</a
              >
            </li>
          </ul>
        </li>
      </ul>
    </div>
    <hr />
    <div class="optional-info">
      <div class="rounded-blob">New</div>
      <div>Organ Mapping Antibody Panel files (CSV) are now supported!</div>
    </div>
  </mat-expansion-panel>
</div>

<div class="content">
  <span class="required-field-disclaimer">* required field</span>

  <form [formGroup]="formGroup" class="mt-4 px-2">
    <div class="data-upload-title">
      Data
      <p class="required">* &nbsp;</p>
      <span class="data-disclaimer-text"> (Add a link to data or upload a CSV/XLSX file)</span>
    </div>

    <div class="w-100 sheet-link-container">
      <div class="w-100 flex-container">
        <p>
          <mat-form-field appearance="fill" class="w-75">
            <mat-label>Google Sheet (or CSV) Link</mat-label>
            <input class="w-100" matInput placeholder="Enter link..." formControlName="link" />
            <mat-hint>Enter Browser URL address for your public Google Sheet (or CSV)</mat-hint>
          </mat-form-field>
        </p>
      </div>

      <div class="title-sheet-sub-container">
        <div class="w-100">
          <p>
            <app-file-upload formControlName="fileName" (fileFormDataEvent)="upload($event)"></app-file-upload>
          </p>
        </div>
      </div>
    </div>
    <hr />
  </form>
</div>

<div footer class="footer">
  <div class="mt-2" class="button-container">
    <button
      mat-flat-button
      color="primary"
      (click)="submitData()"
      class="submit-button"
      [ngClass]="{ 'submit-button-color': !formValid }"
    >
      Submit
    </button>
  </div>
</div>

./upload.component.scss

:host {
  border-style: solid;
  border-width: 0.03rem;
  border: #e4e4e4;
  width: 100%;
  background-color: white;
  margin-left: 1rem;
  font-size: 0.85rem;

  a {
    text-decoration: none;
  }

  a:hover {
    text-decoration: underline;
  }

  .link-input-field {
    width: 100%;
  }

  input[type='color'] {
    border: none;
    outline: none;
  }

  ::ng-deep input[type='color']::-webkit-color-swatch-wrapper {
    padding: 0;
  }

  input[type='color']::-webkit-color-swatch {
    border: none;
  }

  .content {
    flex: 1 1;
    overflow: auto;
  }

  .mat-expansion-panel:not([class*='mat-elevation-z']) {
    box-shadow: none;
  }

  .mat-expansion-panel-header:not(.compare) {
    background: rgb(228, 228, 228) !important;
  }

  ::ng-deep mat-expansion-panel-header {
    background: rgb(228, 228, 228);
  }

  .mat-expansion-panel-header:hover {
    opacity: 0.85 !important;
  }

  .instruction-title {
    font-weight: 600;
    font-size: 10pt;
  }

  .required-field-disclaimer {
    font-size: 0.625rem;
    color: #f44336;
    padding-left: 1.5rem;
  }

  .title-sheet-container {
    display: flex;
    align-items: center;
    justify-content: space-between;
  }

  .title-sheet-sub-container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex: 0.5;
    font-size: medium;
  }

  .flex-container {
    flex: 0.5;
    background-color: white;
    mat-hint {
      color: #757575;
      margin-left: -0.8rem;
    }

    ::ng-deep .mdc-text-field--filled {
      background-color: white;
    }
  }

  .file-upload {
    color: #757575;
  }

  .sheet-link-container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-left: 1rem;
  }

  .button-container {
    margin-left: 1.4rem;
  }

  .submit-button {
    border-radius: 0.5rem !important;
  }

  .submit-button-color {
    background-color: #f44336 !important;
  }

  .required {
    color: red;
    display: inline;
  }

  .data-upload-title {
    margin-top: 1.5rem !important;
    color: #444a65;
    padding-left: 1rem;

    .data-disclaimer-text {
      font-size: 0.625rem;
      color: #757575;
    }
  }

  .optional-info {
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    grid-gap: 0.625rem;
  }

  .rounded-blob {
    align-items: center;
    height: 1.5rem;
    width: 2.5rem;
    background-color: #c2cae5;
    border-radius: 6.25rem;
    text-align: center;
  }

  .footer {
    height: 3rem;
  }
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""