Compare commits
4 Commits
713af307cd
...
2022.05
Author | SHA1 | Date | |
---|---|---|---|
a3a09507a6 | |||
9bbde64147 | |||
0c4259d72e | |||
|
57e0a37c78 |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "farmmaps-lib-app",
|
||||
"version": "2.0.4",
|
||||
"version": "2.0.5",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
|
@@ -1,3 +1,11 @@
|
||||
<div class="tags">
|
||||
<span class="tag rounded bg-primary text-white" *ngFor="let tag of tags;"><span>{{tag}}</span> <i (click)="handleDeleteTag(tag)" class="fal fa-times" aria-hidden="true"></i></span><input type="text" #taginput (blur)="handleAddTag($event)" (keyup)="handleCheckAddTag($event)" [(ngModel)]="tag" [ngbTypeahead]="findTag" (selectItem)="handleSelect($event)" placeholder="New tag"/>
|
||||
</div>
|
||||
<div class="tags">
|
||||
<span class="tag rounded bg-primary text-white" *ngFor="let tag of tags;"><span>{{tag}}</span> <i
|
||||
(click)="handleDeleteTag(tag)" class="fal fa-times" aria-hidden="true"></i></span><input
|
||||
type="text" #tagInputElement
|
||||
(blur)="handleBlur($event, false)"
|
||||
(keyup)="handleKeyUp($event)"
|
||||
[(ngModel)]="tag"
|
||||
[ngbTypeahead]="findTag"
|
||||
(selectItem)="handleSelect($event)"
|
||||
placeholder="New tag"/>
|
||||
</div>
|
||||
|
@@ -1,104 +1,122 @@
|
||||
import { Component, Input, forwardRef,ElementRef,ViewChild } from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR,NgModel } from '@angular/forms';
|
||||
import { Observable,of } from 'rxjs';
|
||||
import { tap,catchError,debounceTime,distinctUntilChanged,switchMap } from 'rxjs/operators'
|
||||
import { TypeaheadService } from '../../services/typeahead.service';
|
||||
|
||||
@Component({
|
||||
selector: 'fm-tag-input',
|
||||
templateUrl: 'tag-input.component.html',
|
||||
styleUrls: ['tag-input.component.scss'],
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: forwardRef(() => TagInputComponent),
|
||||
multi: true
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
export class TagInputComponent implements ControlValueAccessor {
|
||||
@Input() tags: string[]
|
||||
@ViewChild('taginput', { static: true }) tagInputElement: ElementRef;
|
||||
public tag: string;
|
||||
searching = false;
|
||||
searchFailed = false;
|
||||
|
||||
constructor(private typeaheadService: TypeaheadService) {
|
||||
}
|
||||
|
||||
tagExists(tag) {
|
||||
if (tag.length == 0) return true;
|
||||
for (let t of this.tags) {
|
||||
if (t.toLowerCase() == tag.toLowerCase()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
handleDeleteTag(tag) {
|
||||
let tags = [];
|
||||
for (let t of this.tags) {
|
||||
if (t != tag) tags.push(t);
|
||||
}
|
||||
this.tags = tags;
|
||||
this.propagateChange(tags);
|
||||
}
|
||||
|
||||
handleAddTag(event) {
|
||||
if (!this.tagExists(this.tag)) {
|
||||
this.tags.push(this.tag);
|
||||
this.propagateChange(this.tags);
|
||||
}
|
||||
this.tag = "";
|
||||
this.tagInputElement.nativeElement.focus();
|
||||
}
|
||||
|
||||
handleCheckAddTag(event: KeyboardEvent) {
|
||||
if (event.keyCode == 188) {
|
||||
let tag = this.tag.substr(0, this.tag.length - 1); // strip ,
|
||||
if (!this.tagExists(tag)) {
|
||||
this.tags.push(tag);
|
||||
this.propagateChange(this.tags);
|
||||
}
|
||||
this.tag = "";
|
||||
}
|
||||
}
|
||||
|
||||
handleSelect(event) {
|
||||
if (!this.tagExists(event.item)) {
|
||||
this.tags.push(event.item);
|
||||
this.propagateChange(this.tags);
|
||||
}
|
||||
event.preventDefault();
|
||||
this.tag = "";
|
||||
}
|
||||
|
||||
propagateChange = (_: any) => { };
|
||||
|
||||
registerOnChange(fn) {
|
||||
this.propagateChange = fn;
|
||||
}
|
||||
|
||||
findTag = (text$: Observable<string>) =>
|
||||
text$.pipe(
|
||||
debounceTime(200),
|
||||
distinctUntilChanged(),
|
||||
tap(() => this.searching = true),
|
||||
switchMap(term => term.length < 1 ? of([]) :
|
||||
this.typeaheadService.getTagTypeaheadItems(term).pipe(
|
||||
tap(() => this.searchFailed = false),
|
||||
catchError(() => {
|
||||
this.searchFailed = true;
|
||||
return of([]);
|
||||
}))
|
||||
),
|
||||
tap(() => this.searching = false)
|
||||
);
|
||||
|
||||
writeValue(value: any) {
|
||||
this.tags = value;
|
||||
this.tag = "";
|
||||
}
|
||||
|
||||
registerOnTouched() { }
|
||||
}
|
||||
import {Component, ElementRef, forwardRef, Input, ViewChild} from '@angular/core';
|
||||
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
|
||||
import {Observable, of} from 'rxjs';
|
||||
import {catchError, debounceTime, distinctUntilChanged, switchMap, tap} from 'rxjs/operators';
|
||||
import {TypeaheadService} from '../../services/typeahead.service';
|
||||
import {NgbTypeahead} from '@ng-bootstrap/ng-bootstrap';
|
||||
|
||||
@Component({
|
||||
selector: 'fm-tag-input',
|
||||
templateUrl: 'tag-input.component.html',
|
||||
styleUrls: ['tag-input.component.scss'],
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: forwardRef(() => TagInputComponent),
|
||||
multi: true
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
export class TagInputComponent implements ControlValueAccessor {
|
||||
@Input() tags: string[] = [];
|
||||
@ViewChild('tagInputElement', {static: true}) tagInputElement: ElementRef;
|
||||
@ViewChild(NgbTypeahead, {static: true}) typeahead: NgbTypeahead;
|
||||
|
||||
public tag: string;
|
||||
searching = false;
|
||||
searchFailed = false;
|
||||
|
||||
constructor(private typeaheadService: TypeaheadService) {
|
||||
}
|
||||
|
||||
tagExists(tag) {
|
||||
if (tag.length === 0) {
|
||||
return true;
|
||||
}
|
||||
for (const t of this.tags) {
|
||||
if (t.toLowerCase() === tag.toLowerCase()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
addTag(tag, keepFocus = true) {
|
||||
if (!this.tagExists(tag)) {
|
||||
this.tags.push(tag);
|
||||
this.propagateChange(this.tags);
|
||||
}
|
||||
this.tag = '';
|
||||
|
||||
if (keepFocus) {
|
||||
this.tagInputElement.nativeElement.focus();
|
||||
}
|
||||
}
|
||||
|
||||
handleDeleteTag(tag) {
|
||||
const tags = [];
|
||||
for (const t of this.tags) {
|
||||
if (t !== tag) {
|
||||
tags.push(t);
|
||||
}
|
||||
}
|
||||
this.tags = tags;
|
||||
this.propagateChange(tags);
|
||||
}
|
||||
|
||||
handleBlur(event, keepFocus = true) {
|
||||
if (!this.typeahead.isPopupOpen()) {
|
||||
this.addTag(this.tag, keepFocus);
|
||||
} else {
|
||||
this.tag = '';
|
||||
}
|
||||
}
|
||||
|
||||
handleKeyUp(event: KeyboardEvent) {
|
||||
if (event.keyCode === 188) {
|
||||
const tag = this.tag.substr(0, this.tag.length - 1); // strip ,
|
||||
this.addTag(tag);
|
||||
}
|
||||
}
|
||||
|
||||
handleSelect(event) {
|
||||
if (!this.tagExists(event.item)) {
|
||||
this.tags.push(event.item);
|
||||
this.propagateChange(this.tags);
|
||||
}
|
||||
event.preventDefault();
|
||||
this.tag = '';
|
||||
}
|
||||
|
||||
propagateChange = (_: any) => {
|
||||
};
|
||||
|
||||
registerOnChange(fn) {
|
||||
this.propagateChange = fn;
|
||||
}
|
||||
|
||||
findTag = (text$: Observable<string>) =>
|
||||
text$.pipe(
|
||||
distinctUntilChanged(),
|
||||
debounceTime(200),
|
||||
tap(() => this.searching = true),
|
||||
switchMap(term => term.length < 1 ? of([]) :
|
||||
this.typeaheadService.getTagTypeaheadItems(term).pipe(
|
||||
tap(() => this.searchFailed = false),
|
||||
catchError(() => {
|
||||
this.searchFailed = true;
|
||||
return of([]);
|
||||
}))
|
||||
),
|
||||
tap(() => this.searching = false)
|
||||
);
|
||||
|
||||
writeValue(value: any) {
|
||||
this.tags = value;
|
||||
this.tag = '';
|
||||
}
|
||||
|
||||
registerOnTouched() {
|
||||
}
|
||||
}
|
||||
|
@@ -7,7 +7,8 @@ import {IItem} from '../models/item';
|
||||
import {IItemTask} from '../models/itemTask';
|
||||
import {HttpClient} from '@angular/common/http';
|
||||
import {AppConfig} from '../shared/app.config';
|
||||
import {Observable} from 'rxjs';
|
||||
import {Observable,iif,of} from 'rxjs';
|
||||
import {switchMap} from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@@ -16,12 +17,13 @@ import {Observable} from 'rxjs';
|
||||
export class PackageService {
|
||||
private userPackages: { [key: string]: IPackage } = {};
|
||||
private packages: { [key: string]: IPackage } = {};
|
||||
private packagesObservable = this.store$.select(appCommonReducer.SelectGetPackages);
|
||||
|
||||
constructor(private store$: Store<appCommonReducer.State>, public httpClient: HttpClient, public appConfig: AppConfig) {
|
||||
store$.select(appCommonReducer.SelectGetValidUserPackages).subscribe((packages) => {
|
||||
this.userPackages = packages;
|
||||
});
|
||||
store$.select(appCommonReducer.SelectGetPackages).subscribe((packages) => {
|
||||
this.packagesObservable.subscribe((packages) => {
|
||||
this.packages = packages;
|
||||
});
|
||||
}
|
||||
@@ -41,6 +43,14 @@ export class PackageService {
|
||||
postItemPackageTask(item: IItem, task: IItemTask): Observable<IItemTask> {
|
||||
return this.httpClient.post<IItemTask>(`${this.ApiEndpoint()}/api/v1/items/${item.code}/packagetasks`, task);
|
||||
}
|
||||
|
||||
ifPackageListExists<Type>(packageList: Array<string>, ifTrue:Observable<Type>,ifFalse:Observable<Type>):Observable<Type> {
|
||||
return this.packagesObservable.pipe(switchMap(packages =>
|
||||
iif(( )=> Object.keys(packages).some(id => packageList.includes(id)),
|
||||
ifTrue,
|
||||
ifFalse)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
export function getValidPackages(packageMap: IPackages): {[key: string]: IPackage} {
|
||||
|
Reference in New Issue
Block a user