|
|
@@ -16,7 +16,7 @@ import { MatNativeDateModule } from '@angular/material/core'; // 🧩 For native
|
|
|
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
|
|
import { ReactiveFormsModule, FormControl } from '@angular/forms';
|
|
|
import { combineLatest, startWith } from 'rxjs';
|
|
|
-import { Activity } from './activity.interface';
|
|
|
+import { Activity, Output, Resource, Target } from './activity.interface';
|
|
|
import { CalculateDialogComponent } from '../components/calculate-dialog/calculate-dialog.component';
|
|
|
|
|
|
@Component({
|
|
|
@@ -46,11 +46,18 @@ export class ActivityComponent implements OnInit {
|
|
|
private http = inject(HttpClient);
|
|
|
private dialog = inject(MatDialog);
|
|
|
searchControl = new FormControl('');
|
|
|
+ typeControl = new FormControl('');
|
|
|
dataSource: Activity[] = [];
|
|
|
filteredActivities: Activity[] = [];
|
|
|
+
|
|
|
uniqueActivityNames: string[] = [];
|
|
|
+ uniqueResourceTypes: string[] = [];
|
|
|
+ uniqueOutputTypes: string[] = [];
|
|
|
+ uniqueTargetTypes: string[] = [];
|
|
|
uniqueTypes: string[] = [];
|
|
|
- typeControl = new FormControl('');
|
|
|
+ resourceTypeControl = new FormControl('');
|
|
|
+ outputTypeControl = new FormControl('');
|
|
|
+ targetTypeControl = new FormControl('');
|
|
|
startDateControl = new FormControl<Date | null>(null);
|
|
|
endDateControl = new FormControl<Date | null>(null);
|
|
|
|
|
|
@@ -73,9 +80,13 @@ export class ActivityComponent implements OnInit {
|
|
|
combineLatest([
|
|
|
this.searchControl.valueChanges.pipe(startWith(this.searchControl.value)),
|
|
|
this.typeControl.valueChanges.pipe(startWith(this.typeControl.value)),
|
|
|
+ this.resourceTypeControl.valueChanges.pipe(startWith(this.resourceTypeControl.value)),
|
|
|
+ this.outputTypeControl.valueChanges.pipe(startWith(this.outputTypeControl.value)),
|
|
|
+ this.targetTypeControl.valueChanges.pipe(startWith(this.targetTypeControl.value)),
|
|
|
this.startDateControl.valueChanges.pipe(startWith(this.startDateControl.value)),
|
|
|
this.endDateControl.valueChanges.pipe(startWith(this.endDateControl.value)),
|
|
|
]).subscribe(() => this.applyCombinedFilters());
|
|
|
+
|
|
|
}
|
|
|
|
|
|
refresh() {
|
|
|
@@ -114,6 +125,29 @@ export class ActivityComponent implements OnInit {
|
|
|
|
|
|
this.filteredActivities = [...this.dataSource];
|
|
|
this.uniqueTypes = [...new Set(data.map((a) => a.type))];
|
|
|
+ this.uniqueResourceTypes = [
|
|
|
+ ...new Set(
|
|
|
+ data.flatMap((a: Activity) =>
|
|
|
+ a.resources?.map((r: Resource) => r.type) || []
|
|
|
+ )
|
|
|
+ ),
|
|
|
+ ];
|
|
|
+
|
|
|
+ this.uniqueOutputTypes = [
|
|
|
+ ...new Set(
|
|
|
+ data.flatMap((a: Activity) =>
|
|
|
+ a.outputs?.map((o: Output) => o.type) || []
|
|
|
+ )
|
|
|
+ ),
|
|
|
+ ];
|
|
|
+
|
|
|
+ this.uniqueTargetTypes = [
|
|
|
+ ...new Set(
|
|
|
+ data.flatMap((a: Activity) =>
|
|
|
+ a.targets?.map((t: Target) => t.type) || []
|
|
|
+ )
|
|
|
+ ),
|
|
|
+ ];
|
|
|
this.loading = false;
|
|
|
this.applyCombinedFilters();
|
|
|
},
|
|
|
@@ -127,46 +161,72 @@ export class ActivityComponent implements OnInit {
|
|
|
|
|
|
|
|
|
applyCombinedFilters() {
|
|
|
- const keyword = (this.searchControl.value || '').toLowerCase();
|
|
|
- const selectedType = this.typeControl.value;
|
|
|
+ const keyword = (this.searchControl.value || '').toLowerCase().trim();
|
|
|
+ const selectedActivityType = this.typeControl.value;
|
|
|
+ const selectedResourceType = this.resourceTypeControl.value;
|
|
|
+ const selectedOutputType = this.outputTypeControl.value;
|
|
|
+ const selectedTargetType = this.targetTypeControl.value;
|
|
|
const startDate = this.startDateControl.value;
|
|
|
const endDate = this.endDateControl.value;
|
|
|
|
|
|
this.filteredActivities = this.dataSource.filter((activity) => {
|
|
|
- // 1️⃣ Check activity name
|
|
|
- const matchesName = activity.name.toLowerCase().includes(keyword);
|
|
|
-
|
|
|
- // 2️⃣ Check resource names
|
|
|
+ // 1️⃣ Keyword matches
|
|
|
+ const matchesName = activity.name?.toLowerCase().includes(keyword);
|
|
|
const matchesResource = activity.resources?.some(res =>
|
|
|
- res.name.toLowerCase().includes(keyword)
|
|
|
+ res.name?.toLowerCase().includes(keyword)
|
|
|
+ ) ?? false;
|
|
|
+ const matchesOutput = activity.outputs?.some(out =>
|
|
|
+ out.name?.toLowerCase().includes(keyword)
|
|
|
+ ) ?? false;
|
|
|
+ const matchesTarget = activity.targets?.some(tgt =>
|
|
|
+ tgt.name?.toLowerCase().includes(keyword)
|
|
|
) ?? false;
|
|
|
|
|
|
- const matchesKeyword = matchesName || matchesResource;
|
|
|
-
|
|
|
- // 3️⃣ Type filter
|
|
|
- const matchesType = selectedType ? activity.type === selectedType : true;
|
|
|
-
|
|
|
- // 4️⃣ Date range filter
|
|
|
+ const matchesKeyword = !keyword || matchesName || matchesResource || matchesOutput || matchesTarget;
|
|
|
+
|
|
|
+ // 2️⃣ Type filters
|
|
|
+ const matchesActivityType = selectedActivityType ? activity.type === selectedActivityType : true;
|
|
|
+ const matchesResourceType = selectedResourceType
|
|
|
+ ? activity.resources?.some(res => res.type === selectedResourceType)
|
|
|
+ : true;
|
|
|
+ const matchesOutputType = selectedOutputType
|
|
|
+ ? activity.outputs?.some(out => out.type === selectedOutputType)
|
|
|
+ : true;
|
|
|
+ const matchesTargetType = selectedTargetType
|
|
|
+ ? activity.targets?.some(tgt => tgt.type === selectedTargetType)
|
|
|
+ : true;
|
|
|
+
|
|
|
+ // 3️⃣ Date range filter
|
|
|
const activityStart = new Date(activity.dateStart);
|
|
|
const activityEnd = new Date(activity.dateEnd);
|
|
|
const matchesDateRange =
|
|
|
(!startDate || activityStart >= startDate) &&
|
|
|
(!endDate || activityEnd <= endDate);
|
|
|
|
|
|
- return matchesKeyword && matchesType && matchesDateRange;
|
|
|
+ return (
|
|
|
+ matchesKeyword &&
|
|
|
+ matchesActivityType &&
|
|
|
+ matchesResourceType &&
|
|
|
+ matchesOutputType &&
|
|
|
+ matchesTargetType &&
|
|
|
+ matchesDateRange
|
|
|
+ );
|
|
|
});
|
|
|
}
|
|
|
|
|
|
-
|
|
|
resetFilters() {
|
|
|
this.searchControl.setValue('');
|
|
|
this.typeControl.setValue('');
|
|
|
+ this.resourceTypeControl.setValue('');
|
|
|
+ this.outputTypeControl.setValue('');
|
|
|
+ this.targetTypeControl.setValue('');
|
|
|
this.startDateControl.setValue(null);
|
|
|
this.endDateControl.setValue(null);
|
|
|
this.filteredActivities = [...this.dataSource];
|
|
|
}
|
|
|
|
|
|
|
|
|
+
|
|
|
applyFilter(value: string) {
|
|
|
const filterValue = value.toLowerCase();
|
|
|
this.filteredActivities = this.dataSource.filter((activity) =>
|