Skip to content

Commit

Permalink
Added a custom component for engine selection.
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmitriy Borzenko committed Jul 28, 2023
1 parent 99a5684 commit e684b76
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<div class="dropdown" #dropdown (click)="clickInput()">
<div class="preview">
<input
type="text"
placeholder="Dropdown menu"
readonly
#input
[value]="engine"
readonly
/>
<img class="selectedImage" [src]="getLogo(engine)" #selectedImage />
</div>
<div class="option" #option *ngIf="showDropdown">
<ng-container *ngFor="let item of data; let i = index">
<div (click)="clickShowDropdown(item)">
<img [src]="getLogo(item.name)" alt="" />
{{ item.name | uppercase }}
</div>
</ng-container>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
.dropdown
box-sizing: border-box
position: relative
width: 350px
height: 35px
input
position: absolute
top: 0
left: 0
width: 100%
height: 100%
cursor: pointer
outline: none
border-radius: 6px
padding-left: 55px
border: 1px solid #ced4da
&:focus
border: 1px solid #86b7fe
box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25)
.selectedImage
position: absolute
top: 8px
left: 16px
max-width: 30px
&::before
content: ''
position: absolute
width: 6px
height: 6px
border: 2px solid #333
right: 20px
top: 15px
z-index: 1000
border-top: 2px solid #fff
border-right: 2px solid #fff
transform: rotate(-45deg)
transition: 0.5s
pointer-events: none
.option
position: absolute
top: 37px
width: 350px
background: #fff
padding: 6px 10px
border-radius: 5px
overflow: hidden
border: 1px solid #ced4da
div
padding: 10px 10px
cursor: pointer
display: flex
align-items: center
img
margin-right: 10px
max-width: 30px
&:hover
background: #62baea
color: #fff
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ComponentFixture, TestBed } from "@angular/core/testing";
import { EngineSelectComponent } from "./engine-select.component";
import { mockEngines } from "../../../../mock.data";

describe("EngineSelectComponent", () => {
let component: EngineSelectComponent;
let fixture: ComponentFixture<EngineSelectComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [EngineSelectComponent],
}).compileComponents();

fixture = TestBed.createComponent(EngineSelectComponent);
component = fixture.componentInstance;
component.data = mockEngines.data.knownEngines;
component.engine = "Spark";
fixture.detectChanges();
});

it("should create", () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import {
ChangeDetectionStrategy,
Component,
ElementRef,
EventEmitter,
HostListener,
Input,
OnInit,
Output,
Renderer2,
ViewChild,
} from "@angular/core";
import { EngineDesc } from "src/app/api/kamu.graphql.interface";
import { DataHelpers } from "src/app/common/data.helpers";

@Component({
selector: "app-engine-select",
templateUrl: "./engine-select.component.html",
styleUrls: ["./engine-select.component.sass"],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class EngineSelectComponent implements OnInit {
@ViewChild("input", { static: true }) input: ElementRef;
@ViewChild("dropdown", { static: true })
dropdown: ElementRef<HTMLDivElement>;
@ViewChild("selectedImage", { static: true })
selectedImage: ElementRef<HTMLImageElement>;
public showDropdown = false;
@Input() data: EngineDesc[];
@Input() engine: string;
@Output() selectedEngineEmitter = new EventEmitter<string>();

constructor(private render: Renderer2) {}

@HostListener("document:click", ["$event"])
clickout(event: Event) {
if (!this.dropdown.nativeElement.contains(event.target as Element)) {
this.showDropdown = false;
}
}

ngOnInit(): void {
const defaultEngine = this.data.find(
(item: EngineDesc) => item.name === this.engine,
);
if (defaultEngine) {
this.clickShowDropdown(defaultEngine);
}
}

public getLogo(name: string): string {
return (
DataHelpers.descriptionForEngine(name.toLowerCase()).url_logo ?? ""
);
}

public clickShowDropdown(item: EngineDesc): void {
this.render.setAttribute(
this.selectedImage.nativeElement,
"src",
this.getLogo(item.name.toLowerCase()),
);
this.selectedEngineEmitter.emit(item.name.toUpperCase());
}

public clickInput(): void {
this.showDropdown = !this.showDropdown;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,11 @@
<mat-divider class="w-350"></mat-divider>
<div class="mt-4">
<label for="engine-type" class="form-label">Type</label>
<select
class="form-select w-350"
id="engine-type"
[(ngModel)]="selectedEngine"
(change)="onSelectType()"
>
<option
*ngFor="let engine of knownEngines"
[value]="engine.name.toUpperCase()"
>
{{ engine.name }}
</option>
</select>
<app-engine-select
[data]="knownEngines"
[engine]="selectedEngine"
(selectedEngineEmitter)="onSelectType($event)"
></app-engine-select>
</div>
<div class="mt-4">
<label for="engine-image" class="form-label">Image</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { FormsModule } from "@angular/forms";
import { MatDividerModule } from "@angular/material/divider";
import { mockSetPollingSourceEvent } from "src/app/dataset-block/metadata-block/components/event-details/mock.events";
import { SharedTestModule } from "src/app/common/shared-test.module";
import { EngineSelectComponent } from "./components/engine-select/engine-select.component";

describe("EngineSectionComponent", () => {
let component: EngineSectionComponent;
Expand All @@ -23,7 +24,7 @@ describe("EngineSectionComponent", () => {

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [EngineSectionComponent],
declarations: [EngineSectionComponent, EngineSelectComponent],
providers: [Apollo],
imports: [
ApolloModule,
Expand All @@ -48,7 +49,7 @@ describe("EngineSectionComponent", () => {
it("should check init default engine and image", fakeAsync(() => {
component.ngOnInit();
tick();
expect(component.selectedEngine).toBe(
expect(component.selectedEngine.toUpperCase()).toBe(
mockEngines.data.knownEngines[0].name.toUpperCase(),
);
expect(component.selectedImage).toBe(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,20 @@ export class EngineSectionComponent extends BaseComponent implements OnInit {
this.initEngineSection();
}

public onSelectType(): void {
public onSelectType(item: string): void {
this.selectedEngine = item;
if (this.knownEngines) {
const result = this.knownEngines.find(
(item) => item.name.toUpperCase() === this.selectedEngine,
(item) =>
item.name.toUpperCase() ===
this.selectedEngine.toUpperCase(),
);

if (result) {
this.selectedImage = result.latestImage;
this.onEmitSelectedEngine.emit(this.selectedEngine);
this.onEmitSelectedEngine.emit(
this.selectedEngine.toUpperCase(),
);
}
}
}
Expand All @@ -59,12 +65,11 @@ export class EngineSectionComponent extends BaseComponent implements OnInit {
this.engineService.engines().subscribe((result: EnginesQuery) => {
this.knownEngines = result.data.knownEngines;
if (!this.selectedEngine) {
this.selectedEngine =
this.knownEngines[0].name.toUpperCase();
this.selectedEngine = this.knownEngines[0].name;
this.selectedImage = this.knownEngines[0].latestImage;
this.initCurrentEngine();
} else {
this.onSelectType();
this.onSelectType(this.selectedEngine);
}
this.onEmitSelectedEngine.emit(this.selectedEngine);
this.cdr.detectChanges();
Expand All @@ -75,8 +80,8 @@ export class EngineSectionComponent extends BaseComponent implements OnInit {
private initCurrentEngine(): void {
if (this.currentSetTransformEvent?.engine) {
const currentEngine: string = this.currentSetTransformEvent.engine;
this.selectedEngine = currentEngine.toUpperCase();
this.onSelectType();
this.selectedEngine = currentEngine;
this.onSelectType(this.selectedEngine.toUpperCase());
}
}
}
2 changes: 2 additions & 0 deletions src/app/dataset-view/dataset.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import { QueriesSectionComponent } from "./additional-components/metadata-compon
import { PageNotFoundComponent } from "../components/page-not-found/page-not-found.component";
import { AddPollingSourceComponent } from "./additional-components/metadata-component/components/add-polling-source/add-polling-source.component";
import { MatStepperModule } from "@angular/material/stepper";
import { EngineSelectComponent } from "./additional-components/metadata-component/components/set-transform/components/engine-section/components/engine-select/engine-select.component";
@NgModule({
imports: [
CommonModule,
Expand Down Expand Up @@ -144,6 +145,7 @@ import { MatStepperModule } from "@angular/material/stepper";
QueriesSectionComponent,
PageNotFoundComponent,
AddPollingSourceComponent,
EngineSelectComponent,
],
})
export class DatasetModule {
Expand Down

0 comments on commit e684b76

Please sign in to comment.