travopti/frontend/src/app/components/search-input/search-input.component.ts
2020-06-25 22:18:21 +02:00

198 lines
5.9 KiB
TypeScript

import {Component, OnInit} from '@angular/core';
import {Router} from '@angular/router';
import {Query} from '../../interfaces/search-request.interface';
import {objToBase64} from '../../utils/base64conversion';
import {PresetService} from '../../services/preset.service';
import {Preset} from '../../interfaces/preset.interface';
import {formatDate} from '@angular/common';
import {SearchService} from '../../services/search.service';
import {toMinMaxArray} from '../../utils/toMinMaxArray';
@Component({
selector: 'app-search-input',
templateUrl: './search-input.component.html',
styleUrls: ['./search-input.component.scss']
})
export class SearchInputComponent implements OnInit {
selectedTab = 0;
presets: Preset[];
singlePresets: Preset[];
multiPresets: Map<string, Preset[]>;
multiPresetsKeys: string[];
selectedTags: string[] = [];
tags: string[];
from: string;
to: string;
// Guided Search
singlePresetSelection = {};
multiPresetSelection = {};
// Advanced Search
textFilter = '';
fullText = false;
temperatureMeanMax: number;
precipitation: number;
rainDays: number;
sunHours: number;
accommodation: number;
costPerDay: number;
entertainment: number;
localTransport: number;
readonly today = this.from = formatDate(new Date(), 'yyyy-MM-dd', 'en-GB');
constructor(private router: Router, private ps: PresetService, private ss: SearchService) {
const from = new Date();
const to = new Date();
to.setDate(from.getDate() + 7);
this.from = formatDate(from, 'yyyy-MM-dd', 'en-GB');
this.to = formatDate(to, 'yyyy-MM-dd', 'en-GB');
}
async ngOnInit() {
await this.ps.initialize();
this.presets = this.ps.presets;
this.singlePresets = this.ps.singlePresets;
this.multiPresets = this.ps.multiPresets;
this.multiPresetsKeys = [...this.multiPresets.keys()];
this.tags = await this.ss.getAvailableTags();
this.loadSearch();
}
async onSearch(isAdvanced: boolean) {
this.saveSearch(isAdvanced);
const query = isAdvanced ? this.getQueryFromAdvanced() : this.getQueryFromGuided();
console.log(query);
await this.router.navigate(['/search'], {queryParams: {q: objToBase64(query)}});
}
/**
* Handles a (multi) preset click.
* @param preset The clicked preset
* @return If the button is selected
*/
onMultiPresetSelect(preset: Preset) {
if (this.multiPresetSelection[preset.parameter] === preset.preset_id) {
this.multiPresetSelection[preset.parameter] = undefined;
return false;
} else {
this.multiPresetSelection[preset.parameter] = preset.preset_id;
return true;
}
}
checkDates() {
const fromDate = new Date(this.from);
const toDate = new Date(this.to);
if (toDate <= fromDate) {
const newToDate = new Date(this.from);
newToDate.setDate(fromDate.getDate() + 1);
this.to = formatDate(newToDate, 'yyyy-MM-dd', 'en-GB');
}
}
private getQueryFromGuided(): Query {
const query: Query = {
from: new Date(this.from).getTime(),
to: new Date(this.to).getTime(),
tags: this.selectedTags
};
for (const preset of this.singlePresets) {
if (this.singlePresetSelection[preset.preset_id]) {
query[preset.parameter] = preset.value;
}
}
for (const key of this.multiPresetsKeys) {
if (this.multiPresetSelection[key]) {
query[key] = this.presets.find(preset => preset.preset_id === this.multiPresetSelection[key]).value;
}
}
return query;
}
private getQueryFromAdvanced(): Query {
const query: Query = {
from: new Date(this.from).getTime(),
to: new Date(this.to).getTime(),
tags: this.selectedTags
};
if (this.textFilter.length > 0) {
query.fulltext = this.fullText;
query.textfilter = this.textFilter;
}
query.temperature_mean_max = toMinMaxArray(this.temperatureMeanMax);
query.precipitation = toMinMaxArray(this.precipitation);
query.sun_hours = toMinMaxArray(this.sunHours);
query.rain_days = toMinMaxArray(this.rainDays);
query.average_per_day_costs = toMinMaxArray(this.costPerDay);
query.accommodation_costs = toMinMaxArray(this.accommodation);
query.entertainment_costs = toMinMaxArray(this.entertainment);
query.local_transportation_costs = toMinMaxArray(this.localTransport);
return query;
}
private saveSearch(isAdvanced: boolean) {
this.ss.saveSearchInput({
wasAdvanced: isAdvanced,
from: this.from,
to: this.to,
singlePresetSelection: this.singlePresetSelection,
multiPresetSelection: this.multiPresetSelection,
tags: this.selectedTags,
fullText: this.fullText,
textFiler: this.textFilter,
tempMeanMax: this.temperatureMeanMax,
precipitation: this.precipitation,
rain_days: this.rainDays,
sun_hours: this.sunHours,
average_per_day_costs: this.costPerDay,
accommodation: this.accommodation,
entertainment_costs: this.entertainment,
local_transportation_costs: this.localTransport,
});
}
private loadSearch() {
const prevInput = this.ss.loadSearchInput();
if (prevInput) {
this.from = prevInput.from;
this.to = prevInput.to;
this.singlePresetSelection = prevInput.singlePresetSelection;
this.multiPresetSelection = prevInput.multiPresetSelection;
this.selectedTags = prevInput.tags;
this.textFilter = prevInput.textFiler;
this.fullText = prevInput.fullText;
this.selectedTab = prevInput.wasAdvanced ? 1 : 0;
this.temperatureMeanMax = prevInput.tempMeanMax;
this.precipitation = prevInput.precipitation;
this.rainDays = prevInput.rain_days;
this.sunHours = prevInput.sun_hours;
this.costPerDay = prevInput.average_per_day_costs;
this.accommodation = prevInput.accommodation;
this.entertainment = prevInput.entertainment_costs;
this.localTransport = prevInput.local_transportation_costs;
}
}
}