From e9c70298a5c425b4e1c9833a78db9161d5c6089c Mon Sep 17 00:00:00 2001
From: Yagnik Hingrajiya <50392803+Yagnik56@users.noreply.github.com>
Date: Wed, 10 Jul 2024 02:40:50 +0530
Subject: [PATCH] common import container (#1734)
* common import container
* added comment for example use
* resolved review cmts
---------
Co-authored-by: danoswaltCL <97542869+danoswaltCL@users.noreply.github.com>
---
.../import-feature-flag-modal.component.html | 31 ++------
.../import-feature-flag-modal.component.scss | 46 +----------
.../import-feature-flag-modal.component.ts | 53 +++----------
.../common-import-container.component.html | 14 ++++
.../common-import-container.component.scss | 29 +++++++
.../common-import-container.component.ts | 79 +++++++++++++++++++
.../common-modal.component.spec.ts | 22 ------
.../common-modal/common-modal.component.ts | 1 -
.../shared/services/common-dialog.service.ts | 2 +-
types/src/Experiment/enums.ts | 5 ++
types/src/index.ts | 1 +
11 files changed, 151 insertions(+), 132 deletions(-)
create mode 100644 frontend/projects/upgrade/src/app/shared-standalone-component-lib/components/common-import-container/common-import-container.component.html
create mode 100644 frontend/projects/upgrade/src/app/shared-standalone-component-lib/components/common-import-container/common-import-container.component.scss
create mode 100644 frontend/projects/upgrade/src/app/shared-standalone-component-lib/components/common-import-container/common-import-container.component.ts
delete mode 100644 frontend/projects/upgrade/src/app/shared-standalone-component-lib/components/common-modal/common-modal.component.spec.ts
diff --git a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.html b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.html
index 259e49ebe8..6632f185b8 100644
--- a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.html
+++ b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.html
@@ -5,32 +5,17 @@
[primaryActionBtnLabel]="data.primaryActionBtnLabel"
[primaryActionBtnColor]="data.primaryActionBtnColor"
[primaryActionBtnDisabled]="isImportActionBtnDisabled | async"
+ (primaryActionBtnClicked)="importFiles()"
>
-
-
+
+
{{ 'feature-flags.import-feature-flag.message.text' | translate }}
Learn More
diff --git a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.scss b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.scss
index 8ee757f43a..0a13fbb9a7 100644
--- a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.scss
+++ b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.scss
@@ -7,52 +7,14 @@
height: 100%;
color: grey;
- mat-icon {
- height: 70px;
- width: 70px;
- font-size: 70px;
- color: grey;
+ .full-width {
+ width: 100%;
}
}
-.input-container {
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- border: 1px dashed grey;
- border-radius: 4px;
- height: 206px;
- width: 592px;
- position: relative;
-
- button {
- font-size: 14px;
- }
-}
-
-.input-container-header {
- position: absolute;
- top: 5px;
- right: 5px;
-
- mat-icon {
- height: 24px;
- width: 24px;
- font-size: 24px;
- }
-}
-
-.input-container-content {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
-}
-
-p {
+.import-message {
+ margin-top: 5px;
color: grey;
- font-size: 12px;
}
a {
diff --git a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts
index e9cb49b01a..fced0d1298 100644
--- a/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts
+++ b/frontend/projects/upgrade/src/app/features/dashboard/feature-flags/modals/import-feature-flag-modal/import-feature-flag-modal.component.ts
@@ -2,25 +2,22 @@ import { ChangeDetectionStrategy, Component, ElementRef, Inject, OnInit, ViewChi
import { CommonModalComponent } from '../../../../../shared-standalone-component-lib/components';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { CommonModalConfig } from '../../../../../shared-standalone-component-lib/components/common-modal/common-modal-config';
-import { FeatureFlagsService } from '../../../../../core/feature-flags/feature-flags.service';
import { BehaviorSubject } from 'rxjs';
import { CommonModule } from '@angular/common';
import { SharedModule } from '../../../../../shared/shared.module';
+import { CommonImportContainerComponent } from '../../../../../shared-standalone-component-lib/components/common-import-container/common-import-container.component';
@Component({
selector: 'app-import-feature-flag-modal',
standalone: true,
- imports: [CommonModalComponent, CommonModule, SharedModule],
+ imports: [CommonModalComponent, CommonModule, SharedModule, CommonImportContainerComponent],
templateUrl: './import-feature-flag-modal.component.html',
styleUrls: ['./import-feature-flag-modal.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ImportFeatureFlagModalComponent {
- @ViewChild('fileInput') fileInput: ElementRef
;
isImportActionBtnDisabled = new BehaviorSubject(true);
- isDragOver = new BehaviorSubject(false);
- fileName = new BehaviorSubject(null);
constructor(
@Inject(MAT_DIALOG_DATA)
@@ -29,46 +26,12 @@ export class ImportFeatureFlagModalComponent {
public dialogRef: MatDialogRef
) {}
- onDragOver(event: DragEvent) {
- event.preventDefault();
- event.stopPropagation();
- this.isDragOver.next(true);
- }
-
- onDragLeave(event: DragEvent) {
- event.preventDefault();
- event.stopPropagation();
- this.isDragOver.next(false);
- }
-
- onDrop(event: DragEvent) {
- event.preventDefault();
- event.stopPropagation();
- this.isDragOver.next(false);
-
- const files = event.dataTransfer?.files;
- if (files && files.length > 0) {
- this.processFile(files[0]);
- }
- }
-
- onFileSelected(event: Event) {
- const input = event.target as HTMLInputElement;
- if (input.files && input.files.length > 0) {
- this.processFile(input.files[0]);
- }
- }
-
- processFile(file: File) {
- if (file.type === 'application/json') {
- this.fileName.next(file.name);
+ handleFilesSelected(files: File[]) {
+ if(files.length>0) {
this.isImportActionBtnDisabled.next(false);
- this.handleFileInput(file);
- } else {
- alert('Please upload a valid JSON file.');
- this.fileName.next(null);
- this.isImportActionBtnDisabled.next(true);
}
+ console.log('Selected files:', files);
+ //Send files to validation endpoint to receive data for table
}
handleFileInput(file: File) {
@@ -80,6 +43,10 @@ export class ImportFeatureFlagModalComponent {
reader.readAsText(file);
}
+ importFiles() {
+ console.log('Import feature flags');
+ }
+
closeModal() {
this.dialogRef.close();
}
diff --git a/frontend/projects/upgrade/src/app/shared-standalone-component-lib/components/common-import-container/common-import-container.component.html b/frontend/projects/upgrade/src/app/shared-standalone-component-lib/components/common-import-container/common-import-container.component.html
new file mode 100644
index 0000000000..c23e8623c5
--- /dev/null
+++ b/frontend/projects/upgrade/src/app/shared-standalone-component-lib/components/common-import-container/common-import-container.component.html
@@ -0,0 +1,14 @@
+
\ No newline at end of file
diff --git a/frontend/projects/upgrade/src/app/shared-standalone-component-lib/components/common-import-container/common-import-container.component.scss b/frontend/projects/upgrade/src/app/shared-standalone-component-lib/components/common-import-container/common-import-container.component.scss
new file mode 100644
index 0000000000..744ffe9850
--- /dev/null
+++ b/frontend/projects/upgrade/src/app/shared-standalone-component-lib/components/common-import-container/common-import-container.component.scss
@@ -0,0 +1,29 @@
+.input-container {
+ /* Add your styles here */
+ height: 210px;
+ width: 592px;
+ border: 2px dashed #ccc;
+ padding: 20px;
+ text-align: center;
+ border-radius: 10px;
+ transition: background-color 0.3s;
+
+ &.drag-over {
+ background-color: #f0f0f0;
+ }
+
+ .drag-text {
+ margin-bottom: 0.7rem;
+ }
+
+ mat-icon {
+ height: 70px;
+ width: 70px;
+ font-size: 70px;
+ color: grey;
+ }
+
+ button {
+ font-size: 14px;
+ }
+}
\ No newline at end of file
diff --git a/frontend/projects/upgrade/src/app/shared-standalone-component-lib/components/common-import-container/common-import-container.component.ts b/frontend/projects/upgrade/src/app/shared-standalone-component-lib/components/common-import-container/common-import-container.component.ts
new file mode 100644
index 0000000000..250566b484
--- /dev/null
+++ b/frontend/projects/upgrade/src/app/shared-standalone-component-lib/components/common-import-container/common-import-container.component.ts
@@ -0,0 +1,79 @@
+import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { SharedModule } from '../../../shared/shared.module';
+import { CommonModalComponent } from '../common-modal/common-modal.component';
+import { BehaviorSubject } from 'rxjs';
+import { FILE_TYPE } from 'upgrade_types';
+
+/**
+ * A reusable component for drag-and-drop file import functionality.
+ * This component allows users to drag and drop files or select them via a file input.
+ * It supports specifying a file type and emits the selected files to the parent component.
+ *
+ * The component accepts the following inputs:
+ * - `fileType`: A string representing the accepted file type (e.g., '.json'). Only files with this extension can be selected or dropped.
+ * - `buttonLabel`: A string representing the label text of the button. Defaults to 'Upload File'.
+ *
+ * The component emits the following outputs:
+ * - `filesSelected`: An event that emits the selected files as an array of `File` objects.
+ *
+ * Example usage:
+ *
+ * ```
+ *
+ * ```
+ */
+@Component({
+ selector: 'app-common-import-container',
+ standalone: true,
+ imports: [CommonModalComponent, CommonModule, SharedModule],
+ templateUrl: './common-import-container.component.html',
+ styleUrls: ['./common-import-container.component.scss'],
+ changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class CommonImportContainerComponent {
+ @Input() fileType!: FILE_TYPE;
+ @Input() buttonLabel!: string;
+ @Output() filesSelected = new EventEmitter();
+
+ isDragOver = new BehaviorSubject(false);
+
+ onDragOver(event: DragEvent) {
+ this.handleDragState(event, true);
+ }
+
+ onDragLeave(event: DragEvent) {
+ this.handleDragState(event, false);
+ }
+
+ onDrop(event: DragEvent) {
+ this.handleDragState(event, false);
+ this.handleFileSelection(event.dataTransfer?.files);
+ }
+
+ private handleDragState(event: DragEvent, isOver: boolean) {
+ event.preventDefault();
+ event.stopPropagation();
+ this.isDragOver.next(isOver);
+ }
+
+ onFileSelected(event: Event) {
+ const input = event.target as HTMLInputElement;
+ this.handleFileSelection(input.files);
+ }
+
+ private handleFileSelection(files: FileList | null) {
+ if (files && files.length > 0) {
+ const validFiles = Array.from(files).filter(file => file.name.endsWith(this.fileType));
+ if (validFiles.length > 0) {
+ this.filesSelected.emit(validFiles);
+ } else {
+ console.error('Invalid file types...');
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/frontend/projects/upgrade/src/app/shared-standalone-component-lib/components/common-modal/common-modal.component.spec.ts b/frontend/projects/upgrade/src/app/shared-standalone-component-lib/components/common-modal/common-modal.component.spec.ts
deleted file mode 100644
index 7323254d65..0000000000
--- a/frontend/projects/upgrade/src/app/shared-standalone-component-lib/components/common-modal/common-modal.component.spec.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { CommonModalComponent } from './common-modal.component';
-
-xdescribe('CommonDialogComponent', () => {
- let component: CommonModalComponent;
- let fixture: ComponentFixture;
-
- beforeEach(async () => {
- await TestBed.configureTestingModule({
- imports: [CommonModalComponent],
- }).compileComponents();
-
- fixture = TestBed.createComponent(CommonModalComponent);
- component = fixture.componentInstance;
- fixture.detectChanges();
- });
-
- it('should create', () => {
- expect(component).toBeTruthy();
- });
-});
diff --git a/frontend/projects/upgrade/src/app/shared-standalone-component-lib/components/common-modal/common-modal.component.ts b/frontend/projects/upgrade/src/app/shared-standalone-component-lib/components/common-modal/common-modal.component.ts
index 94e8feaac3..1fded529d5 100644
--- a/frontend/projects/upgrade/src/app/shared-standalone-component-lib/components/common-modal/common-modal.component.ts
+++ b/frontend/projects/upgrade/src/app/shared-standalone-component-lib/components/common-modal/common-modal.component.ts
@@ -7,7 +7,6 @@ import { MatButtonModule } from '@angular/material/button';
import { MatDialogActions, MatDialogClose, MatDialogContent, MatDialogTitle } from '@angular/material/dialog';
import { CommonModule, NgTemplateOutlet } from '@angular/common';
import { MatIcon } from '@angular/material/icon';
-import { Observable } from 'rxjs';
@Component({
selector: 'app-common-dialog',
diff --git a/frontend/projects/upgrade/src/app/shared/services/common-dialog.service.ts b/frontend/projects/upgrade/src/app/shared/services/common-dialog.service.ts
index 51ea502f5f..9d3b1ea15c 100644
--- a/frontend/projects/upgrade/src/app/shared/services/common-dialog.service.ts
+++ b/frontend/projects/upgrade/src/app/shared/services/common-dialog.service.ts
@@ -114,7 +114,7 @@ export class DialogService {
const config: MatDialogConfig = {
data: commonModalConfig,
width: '670px',
- height: '450px',
+ height: '460px',
autoFocus: 'input',
disableClose: true,
};
diff --git a/types/src/Experiment/enums.ts b/types/src/Experiment/enums.ts
index 2e026925b1..d666c63f4c 100644
--- a/types/src/Experiment/enums.ts
+++ b/types/src/Experiment/enums.ts
@@ -270,3 +270,8 @@ export enum FEATURE_FLAG_PARTICIPANT_LIST_KEY {
INCLUDE = 'featureFlagSegmentInclusion',
EXCLUDE = 'featureFlagSegmentExclusion',
}
+
+export enum FILE_TYPE {
+ JSON = '.json',
+ CSV = '.csv',
+}
diff --git a/types/src/index.ts b/types/src/index.ts
index 56f95714d2..2d92cf032e 100644
--- a/types/src/index.ts
+++ b/types/src/index.ts
@@ -34,6 +34,7 @@ export {
FLAG_SEARCH_KEY,
FEATURE_FLAG_STATUS,
STATUS_INDICATOR_CHIP_TYPE,
+ FILE_TYPE,
} from './Experiment/enums';
export {
IEnrollmentCompleteCondition,