ocket8888 commented on code in PR #7532:
URL: https://github.com/apache/trafficcontrol/pull/7532#discussion_r1212180242


##########
experimental/traffic-portal/src/app/api/profile.service.ts:
##########
@@ -103,4 +103,24 @@ export class ProfileService extends APIService {
                return 
this.delete<ResponseProfile>(`profiles/${id}`).toPromise();
        }
 
+       /**
+        * Exports profile
+        *
+        * @param profileId Id of the profile to export.
+        * @returns profile export object.
+        */
+       public async exportProfile(profileId: number | ResponseProfile): 
Promise<ProfileExport>{

Review Comment:
   passing a `ResponseProfile` to this function is not tested, resulting in an 
uncovered branch.



##########
experimental/traffic-portal/src/app/shared/import-json-edit-txt/import-json-edit-txt.component.html:
##########
@@ -0,0 +1,36 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<h2 mat-dialog-title>{{title}}</h2>
+<mat-dialog-content [ngClass]="{'active':dragOn}">
+       <div class="dropzone" >
+               <div class="text-wrapper">
+                       <div class="label">
+                               Drop your file here!<br>
+                               <small class="hint">*only json and text files 
are allowed to upload.</small>

Review Comment:
   being able to drag-and-drop is all well and good, but not all users have 
such a luxury. On mobile, for example, that notion doesn't exist. Screen reader 
users also can't use it, as it lacks any accessible input. For this reason, you 
need an actual `input[type="file"]`. You could make your own Angular Material 
Form Field Control, but I think it'd be much easier to use 
[`@angular-material-components/file-input`](https://www.npmjs.com/package/@angular-material-components/file-input)
 instead.



##########
experimental/traffic-portal/src/app/shared/import-json-edit-txt/import-json-edit-txt.component.scss:
##########
@@ -0,0 +1,53 @@
+/*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+$backgroundColor: #fafaec;
+
+.dropzone {
+    min-height: 75px;
+    min-width: 400px;
+    margin: 1rem auto;
+    display: table;
+    width: 99%;
+    background-color: $backgroundColor;
+    border: solid 1px rgb(231, 230, 230);
+    text-align: center;
+    color: rgb(133, 132, 132);
+    border-image: initial;
+    border-radius: 5px;
+    box-shadow: 0 .125rem .25rem rgba(0, 0, 0, .075);
+
+    .text-wrapper {
+        display: table-cell;
+        vertical-align: middle;
+
+        .hint {
+            color: rgb(251, 192, 82);
+        }
+    }
+}
+
+.mat-mdc-dialog-content {
+    &.active {
+        background: $backgroundColor;
+    }
+
+}
+
+.mat-mdc-form-field {

Review Comment:
   because you're using an ID, this outer parent selector is purposeless, 
because only one element should exist by a given ID at any one time.



##########
experimental/traffic-portal/src/app/shared/import-json-edit-txt/import-json-edit-txt.component.html:
##########
@@ -0,0 +1,36 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<h2 mat-dialog-title>{{title}}</h2>
+<mat-dialog-content [ngClass]="{'active':dragOn}">
+       <div class="dropzone" >
+               <div class="text-wrapper">
+                       <div class="label">
+                               Drop your file here!<br>
+                               <small class="hint">*only json and text files 
are allowed to upload.</small>
+                       </div>
+               </div>
+       </div>
+
+       <li *ngIf="fileData">{{fileData}}</li>
+
+       <mat-form-field class="w-100" appearance="outline">
+               <textarea matInput id="json-txt-editor"
+                               [value]="inputTxt" required readonly></textarea>
+       </mat-form-field>
+</mat-dialog-content>
+<mat-dialog-actions align="end">
+       <button mat-raised-button color="warn" type="button" 
mat-dialog-close>Cancel</button>
+       <button mat-raised-button type="submit" [mat-dialog-close]="true" 
(click)="submit()">Submit</button>
+</mat-dialog-actions>

Review Comment:
   not using a `form` for this makes it a bit less accessible. The submit 
button doesn't submit anything as far as any screen reader can tell, and it 
won't be able to build an association between the input fields and the button 
that submits them.



##########
experimental/traffic-portal/src/app/shared/file-utils.service.ts:
##########
@@ -153,4 +153,21 @@ export class FileUtilsService {
                this.window.open(url, "_blank");
                URL.revokeObjectURL(url);
        }
+
+       /**
+        * Exports File
+        *
+        * @param json object to be exported
+        * @param fileName name for the download file
+        * @param fileExtension extenstion of export file
+        */
+       public exportFile(json: object, fileName: string, fileExtension: 
string): void {

Review Comment:
   this unnecessary method should be removed, and the `download` method used 
instead.



##########
experimental/traffic-portal/src/styles.scss:
##########
@@ -263,3 +263,11 @@ form mat-hint.mat-mdc-form-field-hint.input-warning {
        font-weight: bold;
        font-size: x-small;
 }
+
+.w-100 {
+       width: 100%;
+}
+
+.h-100 {
+       height: 100%;
+}

Review Comment:
   this has a very "embedding CSS inline into HTML" feel to it. In any case 
where you'd want these, I think a more specific class should probably be 
applied.



##########
experimental/traffic-portal/src/app/shared/import-json-edit-txt/import-json-edit-txt.component.scss:
##########
@@ -0,0 +1,53 @@
+/*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+$backgroundColor: #fafaec;
+
+.dropzone {
+    min-height: 75px;
+    min-width: 400px;
+    margin: 1rem auto;
+    display: table;
+    width: 99%;
+    background-color: $backgroundColor;
+    border: solid 1px rgb(231, 230, 230);
+    text-align: center;
+    color: rgb(133, 132, 132);
+    border-image: initial;
+    border-radius: 5px;
+    box-shadow: 0 .125rem .25rem rgba(0, 0, 0, .075);
+
+    .text-wrapper {
+        display: table-cell;
+        vertical-align: middle;
+
+        .hint {
+            color: rgb(251, 192, 82);
+        }
+    }
+}
+
+.mat-mdc-dialog-content {
+    &.active {
+        background: $backgroundColor;
+    }
+
+}
+
+.mat-mdc-form-field {
+    #json-txt-editor {
+        max-height: 42vh !important;
+        height: 42vh !important;

Review Comment:
   why is `!important` necessary?



##########
experimental/traffic-portal/src/app/shared/import-json-edit-txt/import-json-edit-txt.component.scss:
##########
@@ -0,0 +1,53 @@
+/*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+$backgroundColor: #fafaec;
+
+.dropzone {
+    min-height: 75px;
+    min-width: 400px;
+    margin: 1rem auto;
+    display: table;
+    width: 99%;
+    background-color: $backgroundColor;
+    border: solid 1px rgb(231, 230, 230);
+    text-align: center;
+    color: rgb(133, 132, 132);
+    border-image: initial;
+    border-radius: 5px;
+    box-shadow: 0 .125rem .25rem rgba(0, 0, 0, .075);
+
+    .text-wrapper {
+        display: table-cell;
+        vertical-align: middle;
+
+        .hint {
+            color: rgb(251, 192, 82);
+        }
+    }
+}
+
+.mat-mdc-dialog-content {
+    &.active {
+        background: $backgroundColor;
+    }
+
+}
+
+.mat-mdc-form-field {

Review Comment:
   don't use the internal `.mat-mdc-*` selectors, instead just select the 
component directly e.g. `mat-dialog-content` etc.



##########
experimental/traffic-portal/src/app/shared/import-json-edit-txt/import-json-edit-txt.component.html:
##########
@@ -0,0 +1,36 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<h2 mat-dialog-title>{{title}}</h2>
+<mat-dialog-content [ngClass]="{'active':dragOn}">
+       <div class="dropzone" >
+               <div class="text-wrapper">
+                       <div class="label">
+                               Drop your file here!<br>
+                               <small class="hint">*only json and text files 
are allowed to upload.</small>
+                       </div>
+               </div>
+       </div>
+
+       <li *ngIf="fileData">{{fileData}}</li>
+
+       <mat-form-field class="w-100" appearance="outline">
+               <textarea matInput id="json-txt-editor"
+                               [value]="inputTxt" required readonly></textarea>
+       </mat-form-field>
+</mat-dialog-content>
+<mat-dialog-actions align="end">
+       <button mat-raised-button color="warn" type="button" 
mat-dialog-close>Cancel</button>
+       <button mat-raised-button type="submit" [mat-dialog-close]="true" 
(click)="submit()">Submit</button>

Review Comment:
   a `submit`-type button should not have a click handler.



##########
experimental/traffic-portal/src/app/shared/import-json-edit-txt/import-json-edit-txt.component.ts:
##########
@@ -0,0 +1,125 @@
+/*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+import { DatePipe } from "@angular/common";
+import { Component, HostListener } from "@angular/core";
+import { MatDialogRef } from "@angular/material/dialog";
+import { AlertLevel } from "trafficops-types";
+
+import { AlertService } from "../alert/alert.service";
+
+/**
+ * Component
+ */
+@Component({
+       selector: "tp-import-json-edit-txt",
+       styleUrls: ["./import-json-edit-txt.component.scss"],
+       templateUrl: "./import-json-edit-txt.component.html",
+})
+export class ImportJsonEditTxtComponent {
+
+       /**
+        * Title for the dialog window
+        */
+       public title = "Import Profile";
+
+       /**
+        * Allowed import file types
+        */
+       public allowedType: string[] = ["application/json", "text/plain"];
+
+       /** Text editor value */
+       public inputTxt = "";
+
+       /**  File data imported */
+       public fileData = "";
+
+       /** Monitor whether any file is being drag over the dialog */
+       public dragOn = false;
+
+       /**
+        * Creates an instance of import json edit txt component.
+        *
+        * @param dialogRef Dialog manager
+        * @param alertService Alert service manager
+        * @param datePipe Default angular date pipe for formating date
+        */
+       constructor(
+               private readonly dialogRef: 
MatDialogRef<ImportJsonEditTxtComponent>,
+               private readonly alertService: AlertService,
+               private readonly datePipe: DatePipe) { }
+
+       /**
+        * Emits the json value for import as profile data
+        */
+       public submit(): void {
+               this.dialogRef.close(this.inputTxt);
+       }
+
+       /**
+        * Hosts listener for drag over
+        *
+        * @param evt Drag events data
+        */
+       @HostListener("dragover", ["$event"]) public onDragOver(evt: 
DragEvent): void {
+               evt.preventDefault();
+               evt.stopPropagation();
+
+               this.dragOn = true;
+       }
+
+       /**
+        * Hosts listener for drag leave
+        *
+        * @param evt Drag events data
+        */
+       @HostListener("dragleave", ["$event"]) public onDragLeave(evt: 
DragEvent): void {
+               evt.preventDefault();
+               evt.stopPropagation();
+
+               this.dragOn = false;
+       }
+
+       /**
+        * Hosts listener for drop
+        *
+        * @param evt Drag events data
+        */
+       @HostListener("drop", ["$event"]) public onDrop(evt: DragEvent): void {
+               evt.preventDefault();
+               evt.stopPropagation();
+
+               this.dragOn = false;
+
+               const file = evt.dataTransfer?.files[0];
+
+               if (!file) {
+                       return;
+               }
+
+               /** Check whether expected file is being uploaded  */
+               if (!this.allowedType.find(type => type === file.type)) {

Review Comment:
   using an actual `file`-type `input` will allow you to specify `accept` file 
MIME-types. I think you'll still need to check this here in the drag-and-drop, 
but just want to let you know you won't need to check it again.



##########
experimental/traffic-portal/src/app/shared/import-json-edit-txt/import-json-edit-txt.component.html:
##########
@@ -0,0 +1,36 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<h2 mat-dialog-title>{{title}}</h2>
+<mat-dialog-content [ngClass]="{'active':dragOn}">
+       <div class="dropzone" >
+               <div class="text-wrapper">
+                       <div class="label">
+                               Drop your file here!<br>
+                               <small class="hint">*only json and text files 
are allowed to upload.</small>
+                       </div>
+               </div>
+       </div>
+
+       <li *ngIf="fileData">{{fileData}}</li>

Review Comment:
   the only permitted parents for an `li` tag are `ul`, `ol`, and `menu`.



##########
experimental/traffic-portal/src/app/shared/import-json-edit-txt/import-json-edit-txt.component.html:
##########
@@ -0,0 +1,36 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<h2 mat-dialog-title>{{title}}</h2>
+<mat-dialog-content [ngClass]="{'active':dragOn}">
+       <div class="dropzone" >
+               <div class="text-wrapper">
+                       <div class="label">
+                               Drop your file here!<br>
+                               <small class="hint">*only json and text files 
are allowed to upload.</small>
+                       </div>
+               </div>
+       </div>
+
+       <li *ngIf="fileData">{{fileData}}</li>
+
+       <mat-form-field class="w-100" appearance="outline">
+               <textarea matInput id="json-txt-editor"
+                               [value]="inputTxt" required readonly></textarea>

Review Comment:
   you can leave this `textarea` in if you like, but it's probably not really 
necessary.



##########
experimental/traffic-portal/src/app/shared/import-json-edit-txt/import-json-edit-txt.component.ts:
##########
@@ -0,0 +1,125 @@
+/*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+import { DatePipe } from "@angular/common";
+import { Component, HostListener } from "@angular/core";
+import { MatDialogRef } from "@angular/material/dialog";
+import { AlertLevel } from "trafficops-types";
+
+import { AlertService } from "../alert/alert.service";
+
+/**
+ * Component
+ */
+@Component({
+       selector: "tp-import-json-edit-txt",
+       styleUrls: ["./import-json-edit-txt.component.scss"],
+       templateUrl: "./import-json-edit-txt.component.html",
+})
+export class ImportJsonEditTxtComponent {
+
+       /**
+        * Title for the dialog window
+        */
+       public title = "Import Profile";
+
+       /**
+        * Allowed import file types
+        */
+       public allowedType: string[] = ["application/json", "text/plain"];
+
+       /** Text editor value */
+       public inputTxt = "";
+
+       /**  File data imported */
+       public fileData = "";
+
+       /** Monitor whether any file is being drag over the dialog */
+       public dragOn = false;
+
+       /**
+        * Creates an instance of import json edit txt component.
+        *
+        * @param dialogRef Dialog manager
+        * @param alertService Alert service manager
+        * @param datePipe Default angular date pipe for formating date
+        */
+       constructor(
+               private readonly dialogRef: 
MatDialogRef<ImportJsonEditTxtComponent>,
+               private readonly alertService: AlertService,
+               private readonly datePipe: DatePipe) { }
+
+       /**
+        * Emits the json value for import as profile data
+        */
+       public submit(): void {
+               this.dialogRef.close(this.inputTxt);
+       }
+
+       /**
+        * Hosts listener for drag over
+        *
+        * @param evt Drag events data
+        */
+       @HostListener("dragover", ["$event"]) public onDragOver(evt: 
DragEvent): void {
+               evt.preventDefault();
+               evt.stopPropagation();
+
+               this.dragOn = true;
+       }
+
+       /**
+        * Hosts listener for drag leave
+        *
+        * @param evt Drag events data
+        */
+       @HostListener("dragleave", ["$event"]) public onDragLeave(evt: 
DragEvent): void {
+               evt.preventDefault();
+               evt.stopPropagation();
+
+               this.dragOn = false;
+       }
+
+       /**
+        * Hosts listener for drop
+        *
+        * @param evt Drag events data
+        */
+       @HostListener("drop", ["$event"]) public onDrop(evt: DragEvent): void {
+               evt.preventDefault();
+               evt.stopPropagation();
+
+               this.dragOn = false;
+
+               const file = evt.dataTransfer?.files[0];

Review Comment:
   if `evt.dataTransfer` is `null`, this safe accessor operator (`?.`) will 
allow you to dereference the non-existent property `files` of that `null` 
value, giving back `undefined`. Doing that safely is wasted, though, because if 
that ever happens you will be doing essentially `const file = undefined[0];`, 
which throws a `TypeError` anyway.



##########
experimental/traffic-portal/src/app/shared/import-json-edit-txt/import-json-edit-txt.component.ts:
##########
@@ -0,0 +1,125 @@
+/*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+import { DatePipe } from "@angular/common";
+import { Component, HostListener } from "@angular/core";
+import { MatDialogRef } from "@angular/material/dialog";
+import { AlertLevel } from "trafficops-types";
+
+import { AlertService } from "../alert/alert.service";
+
+/**
+ * Component
+ */
+@Component({
+       selector: "tp-import-json-edit-txt",
+       styleUrls: ["./import-json-edit-txt.component.scss"],
+       templateUrl: "./import-json-edit-txt.component.html",
+})
+export class ImportJsonEditTxtComponent {
+
+       /**
+        * Title for the dialog window
+        */
+       public title = "Import Profile";
+
+       /**
+        * Allowed import file types
+        */
+       public allowedType: string[] = ["application/json", "text/plain"];
+
+       /** Text editor value */
+       public inputTxt = "";
+
+       /**  File data imported */
+       public fileData = "";
+
+       /** Monitor whether any file is being drag over the dialog */
+       public dragOn = false;
+
+       /**
+        * Creates an instance of import json edit txt component.
+        *
+        * @param dialogRef Dialog manager
+        * @param alertService Alert service manager
+        * @param datePipe Default angular date pipe for formating date
+        */
+       constructor(
+               private readonly dialogRef: 
MatDialogRef<ImportJsonEditTxtComponent>,
+               private readonly alertService: AlertService,
+               private readonly datePipe: DatePipe) { }
+
+       /**
+        * Emits the json value for import as profile data
+        */
+       public submit(): void {
+               this.dialogRef.close(this.inputTxt);
+       }
+
+       /**
+        * Hosts listener for drag over
+        *
+        * @param evt Drag events data
+        */
+       @HostListener("dragover", ["$event"]) public onDragOver(evt: 
DragEvent): void {
+               evt.preventDefault();
+               evt.stopPropagation();
+
+               this.dragOn = true;
+       }
+
+       /**
+        * Hosts listener for drag leave
+        *
+        * @param evt Drag events data
+        */
+       @HostListener("dragleave", ["$event"]) public onDragLeave(evt: 
DragEvent): void {
+               evt.preventDefault();
+               evt.stopPropagation();
+
+               this.dragOn = false;
+       }
+
+       /**
+        * Hosts listener for drop
+        *
+        * @param evt Drag events data
+        */
+       @HostListener("drop", ["$event"]) public onDrop(evt: DragEvent): void {
+               evt.preventDefault();
+               evt.stopPropagation();
+
+               this.dragOn = false;
+
+               const file = evt.dataTransfer?.files[0];
+
+               if (!file) {
+                       return;
+               }
+
+               /** Check whether expected file is being uploaded  */
+               if (!this.allowedType.find(type => type === file.type)) {
+                       this.alertService.newAlert({ level: AlertLevel.ERROR, 
text: "Only JSON, text files are allowed to upload." });
+                       return;
+               }
+
+               /** Format text with data from file data and formated date with 
date pipe */
+               this.fileData = `${file.name} - ${file.size} bytes, last 
modified: ${this.datePipe.transform(file.lastModified, "MM-dd-yyyy")}`;
+               const reader = new FileReader();
+               reader.onload = (event): void => {
+                       this.inputTxt = event.target?.result as string;
+               };
+               reader.readAsText(file);

Review Comment:
   this isn't necessary, but it would be neat to listen to the `progress` event 
and update a progress bar accordingly



##########
experimental/traffic-portal/src/app/shared/import-json-edit-txt/import-json-edit-txt.component.ts:
##########
@@ -0,0 +1,125 @@
+/*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+import { DatePipe } from "@angular/common";
+import { Component, HostListener } from "@angular/core";
+import { MatDialogRef } from "@angular/material/dialog";
+import { AlertLevel } from "trafficops-types";
+
+import { AlertService } from "../alert/alert.service";
+
+/**
+ * Component
+ */
+@Component({
+       selector: "tp-import-json-edit-txt",
+       styleUrls: ["./import-json-edit-txt.component.scss"],
+       templateUrl: "./import-json-edit-txt.component.html",
+})
+export class ImportJsonEditTxtComponent {
+
+       /**
+        * Title for the dialog window
+        */
+       public title = "Import Profile";
+
+       /**
+        * Allowed import file types
+        */
+       public allowedType: string[] = ["application/json", "text/plain"];
+
+       /** Text editor value */
+       public inputTxt = "";
+
+       /**  File data imported */
+       public fileData = "";
+
+       /** Monitor whether any file is being drag over the dialog */
+       public dragOn = false;
+
+       /**
+        * Creates an instance of import json edit txt component.
+        *
+        * @param dialogRef Dialog manager
+        * @param alertService Alert service manager
+        * @param datePipe Default angular date pipe for formating date
+        */
+       constructor(
+               private readonly dialogRef: 
MatDialogRef<ImportJsonEditTxtComponent>,
+               private readonly alertService: AlertService,
+               private readonly datePipe: DatePipe) { }
+
+       /**
+        * Emits the json value for import as profile data
+        */
+       public submit(): void {
+               this.dialogRef.close(this.inputTxt);
+       }
+
+       /**
+        * Hosts listener for drag over
+        *
+        * @param evt Drag events data
+        */
+       @HostListener("dragover", ["$event"]) public onDragOver(evt: 
DragEvent): void {
+               evt.preventDefault();
+               evt.stopPropagation();
+
+               this.dragOn = true;
+       }
+
+       /**
+        * Hosts listener for drag leave
+        *
+        * @param evt Drag events data
+        */
+       @HostListener("dragleave", ["$event"]) public onDragLeave(evt: 
DragEvent): void {
+               evt.preventDefault();
+               evt.stopPropagation();
+
+               this.dragOn = false;
+       }
+
+       /**
+        * Hosts listener for drop
+        *
+        * @param evt Drag events data
+        */
+       @HostListener("drop", ["$event"]) public onDrop(evt: DragEvent): void {
+               evt.preventDefault();
+               evt.stopPropagation();
+
+               this.dragOn = false;
+
+               const file = evt.dataTransfer?.files[0];
+
+               if (!file) {
+                       return;
+               }
+
+               /** Check whether expected file is being uploaded  */
+               if (!this.allowedType.find(type => type === file.type)) {
+                       this.alertService.newAlert({ level: AlertLevel.ERROR, 
text: "Only JSON, text files are allowed to upload." });

Review Comment:
   grammar:
   > Only JSON<del>,</del> <ins>or</ins> text files are allowed<del> to 
upload.</del>.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to