Gotta start somewhere

This commit is contained in:
shamoon
2024-09-01 00:29:52 -07:00
parent d7ba6d98d3
commit f0157a36fb
9 changed files with 275 additions and 101 deletions

View File

@@ -0,0 +1,44 @@
<div class="btn-group w-100" ngbDropdown role="group" #dropdown="ngbDropdown">
<button class="btn btn-sm btn-outline-primary" id="dropdown_{{name}}" ngbDropdownToggle [disabled]="disabled">
<i-bs name="{{icon}}"></i-bs>
<div class="d-none d-sm-inline">&nbsp;{{title}}</div>
</button>
<div class="dropdown-menu shadow" ngbDropdownMenu attr.aria-labelledby="dropdown_{{name}}">
<button type="button" class="btn btn-sm btn-outline-primary ms-3" (click)="addQuery()" [disabled]="disabled">
<i-bs name="plus"></i-bs>&nbsp;Add query
</button>
<div class="list-group list-group-flush">
@for (query of selectionModel.queries; track query; let i = $index) {
<div class="list-group-item d-flex">
<div class="input-group input-group-sm flex-shrink-1 flex-nowrap">
<ng-select
class="w-50"
[items]="customFields"
[(ngModel)]="query.field"
[disabled]="disabled"
bindLabel="name"
bindValue="id"
></ng-select>
<select class="w-25 form-control" [(ngModel)]="query.operator" [disabled]="disabled">
<option *ngFor="let operator of getOperatorsForField(query.field)" [ngValue]="operator">{{operator}}</option>
</select>
@switch (query.operator) {
@case ('exists') {
<select class="w-25 form-control" [(ngModel)]="query.value" [disabled]="disabled">
<option value="true" i18n>true</option>
<option value="false" i18n>false</option>
</select>
}
@default {
<input class="w-25 form-control" type="text" [(ngModel)]="query.value" [disabled]="disabled">
}
}
</div>
<button class="btn btn-link btn-sm pe-0" type="button" (click)="removeQuery(i)" [disabled]="disabled">
<i-bs name="x"></i-bs>
</button>
</div>
}
</div>
</div>
</div>

View File

@@ -0,0 +1,8 @@
.dropdown-menu {
width: 450px;
}
::ng-deep .ng-select-container {
border-top-right-radius: 0 !important;
border-bottom-right-radius: 0 !important;
}

View File

@@ -0,0 +1,158 @@
import { Component, EventEmitter, Input, Output } from '@angular/core'
import { Subject, first, takeUntil } from 'rxjs'
import { CustomField } from 'src/app/data/custom-field'
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
export class CustomFieldQuery {
public changed = new Subject<CustomFieldQuery>()
private _field: string
set field(value: string) {
this._field = value
this.changed.next(this)
}
get field(): string {
return this._field
}
private _operator: string
set operator(value: string) {
this._operator = value
this.changed.next(this)
}
get operator(): string {
return this._operator
}
private _value: string
set value(value: string) {
this._value = value
this.changed.next(this)
}
get value(): string {
return this._value
}
constructor(
field: string = null,
operator: string = null,
value: string = null
) {
this.field = field
this.operator = operator
this.value = value
}
}
export class CustomFieldQueriesModel {
// matchingModel: MatchingModel
queries: CustomFieldQuery[] = []
changed = new Subject<CustomFieldQueriesModel>()
public clear(fireEvent = true) {
this.queries = []
if (fireEvent) {
this.changed.next(this)
}
}
public addQuery(query: CustomFieldQuery = new CustomFieldQuery()) {
this.queries.push(query)
query.changed.subscribe(() => {
if (query.field && query.operator && query.value) {
this.changed.next(this)
}
})
}
public removeQuery(index: number) {
const query = this.queries.splice(index, 1)[0]
query.changed.complete()
this.changed.next(this)
}
}
@Component({
selector: 'pngx-custom-fields-lookup-dropdown',
templateUrl: './custom-fields-lookup-dropdown.component.html',
styleUrls: ['./custom-fields-lookup-dropdown.component.scss'],
})
export class CustomFieldsLookupDropdownComponent {
@Input()
title: string
@Input()
filterPlaceholder: string = ''
@Input()
icon: string
@Input()
allowSelectNone: boolean = false
@Input()
editing = false
@Input()
applyOnClose = false
get name(): string {
return this.title ? this.title.replace(/\s/g, '_').toLowerCase() : null
}
@Input()
disabled: boolean = false
_selectionModel: CustomFieldQueriesModel = new CustomFieldQueriesModel()
@Input()
set selectionModel(model: CustomFieldQueriesModel) {
model.changed.subscribe((updatedModel) => {
this.selectionModelChange.next(updatedModel)
})
this._selectionModel = model
}
get selectionModel(): CustomFieldQueriesModel {
return this._selectionModel
}
@Output()
selectionModelChange = new EventEmitter<CustomFieldQueriesModel>()
customFields: CustomField[] = []
private unsubscribeNotifier: Subject<any> = new Subject()
constructor(protected customFieldsService: CustomFieldsService) {
this.getFields()
}
ngOnDestroy(): void {
this.unsubscribeNotifier.next(this)
this.unsubscribeNotifier.complete()
}
private getFields() {
this.customFieldsService
.listAll()
.pipe(first(), takeUntil(this.unsubscribeNotifier))
.subscribe((result) => {
this.customFields = result.results
})
}
public addQuery() {
this.selectionModel.addQuery()
}
public removeQuery(index: number) {
this.selectionModel.removeQuery(index)
}
getOperatorsForField(field: CustomField): string[] {
return ['exact', 'in', 'isnull', 'exists']
// TODO: implement this
}
}