max tags
This commit is contained in:
parent
979324ccc8
commit
c1ea8948fc
@ -31,7 +31,8 @@
|
|||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<ui-tagspicker [(model)]="entry.tags" placeholder="{{'submission.tags' | i18n}}"></ui-tagspicker>
|
<ui-tagspicker [(model)]="entry.tags" placeholder="{{'submission.tags' | i18n}}" [max]="settings.maxTags">
|
||||||
|
</ui-tagspicker>
|
||||||
|
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
<mat-card-actions>
|
<mat-card-actions>
|
||||||
|
@ -7,6 +7,7 @@ import { distinctUntilChanged, debounceTime } from 'rxjs/operators';
|
|||||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||||
import { MatChipInputEvent } from '@angular/material/chips';
|
import { MatChipInputEvent } from '@angular/material/chips';
|
||||||
import { TagsService } from 'src/app/services/tags.service';
|
import { TagsService } from 'src/app/services/tags.service';
|
||||||
|
import { SettingsService } from 'src/app/services/settings.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'page-entry-edit',
|
selector: 'page-entry-edit',
|
||||||
@ -23,11 +24,13 @@ export class PageEntryEdit implements OnInit {
|
|||||||
working: boolean = false;
|
working: boolean = false;
|
||||||
success: boolean = false;
|
success: boolean = false;
|
||||||
form: FormGroup;
|
form: FormGroup;
|
||||||
|
settings: any;
|
||||||
readonly tagsSeparatorKeysCodes = [ ENTER, COMMA, SPACE ] as const;
|
readonly tagsSeparatorKeysCodes = [ ENTER, COMMA, SPACE ] as const;
|
||||||
@ViewChild('formDirective') private formDirective: NgForm;
|
@ViewChild('formDirective') private formDirective: NgForm;
|
||||||
|
|
||||||
constructor(private entriesService: EntriesService,
|
constructor(private entriesService: EntriesService,
|
||||||
private tagsService: TagsService,
|
private tagsService: TagsService,
|
||||||
|
private settingsService: SettingsService,
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private snackBar: MatSnackBar) { }
|
private snackBar: MatSnackBar) { }
|
||||||
@ -40,6 +43,10 @@ export class PageEntryEdit implements OnInit {
|
|||||||
text: [ '', Validators.nullValidator ],
|
text: [ '', Validators.nullValidator ],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.settingsService.settings.subscribe((settings) => {
|
||||||
|
this.settings = settings;
|
||||||
|
});
|
||||||
|
|
||||||
this.form.get('entryType').disable();
|
this.form.get('entryType').disable();
|
||||||
|
|
||||||
this.form.get('entryType').valueChanges.subscribe((value) => {
|
this.form.get('entryType').valueChanges.subscribe((value) => {
|
||||||
|
@ -38,7 +38,8 @@
|
|||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<ui-tagspicker [(model)]="tags" placeholder="{{'submission.tags' | i18n}}"></ui-tagspicker>
|
<ui-tagspicker [(model)]="tags" placeholder="{{'submission.tags' | i18n}}" [max]="settings.maxTags">
|
||||||
|
</ui-tagspicker>
|
||||||
|
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
<mat-card-actions>
|
<mat-card-actions>
|
||||||
|
@ -5,6 +5,7 @@ import { FormBuilder, FormGroup, Validators, NgForm } from '@angular/forms';
|
|||||||
import { COMMA, ENTER, SPACE } from '@angular/cdk/keycodes';
|
import { COMMA, ENTER, SPACE } from '@angular/cdk/keycodes';
|
||||||
import { distinctUntilChanged, debounceTime } from 'rxjs/operators';
|
import { distinctUntilChanged, debounceTime } from 'rxjs/operators';
|
||||||
import { MatChipInputEvent } from '@angular/material/chips';
|
import { MatChipInputEvent } from '@angular/material/chips';
|
||||||
|
import { SettingsService } from 'src/app/services/settings.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'page-submission',
|
selector: 'page-submission',
|
||||||
@ -19,9 +20,11 @@ export class PageSubmission implements OnInit {
|
|||||||
form: FormGroup;
|
form: FormGroup;
|
||||||
readonly tagsSeparatorKeysCodes = [ ENTER, COMMA, SPACE ] as const;
|
readonly tagsSeparatorKeysCodes = [ ENTER, COMMA, SPACE ] as const;
|
||||||
tags: string[] = [];
|
tags: string[] = [];
|
||||||
|
settings: any;
|
||||||
@ViewChild('formDirective') private formDirective: NgForm;
|
@ViewChild('formDirective') private formDirective: NgForm;
|
||||||
|
|
||||||
constructor(private entriesService: EntriesService,
|
constructor(private entriesService: EntriesService,
|
||||||
|
private settingsService: SettingsService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private formBuilder: FormBuilder) { }
|
private formBuilder: FormBuilder) { }
|
||||||
|
|
||||||
@ -33,6 +36,10 @@ export class PageSubmission implements OnInit {
|
|||||||
text: [ '', Validators.nullValidator ],
|
text: [ '', Validators.nullValidator ],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.settingsService.settings.subscribe((settings) => {
|
||||||
|
this.settings = settings;
|
||||||
|
});
|
||||||
|
|
||||||
this.form.get('entryType').setValue(this.entryType);
|
this.form.get('entryType').setValue(this.entryType);
|
||||||
|
|
||||||
this.form.get('entryType').valueChanges.subscribe((value) => {
|
this.form.get('entryType').valueChanges.subscribe((value) => {
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
<mat-icon>filter_alt</mat-icon>
|
<mat-icon>filter_alt</mat-icon>
|
||||||
</a>
|
</a>
|
||||||
<div *ngIf="filterOpen">
|
<div *ngIf="filterOpen">
|
||||||
<ui-tagspicker [(model)]="entries.filter.tag" singleton="true" placeholder="{{'entries.filter.tag' | i18n}}" [change]="boundTagspickerChange"></ui-tagspicker>
|
<ui-tagspicker [(model)]="entries.filter.tag" max="1" placeholder="{{'entries.filter.tag' | i18n}}" [change]="boundTagspickerChange"></ui-tagspicker>
|
||||||
|
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<input matInput [matDatepicker]="picker" [value]="entries && entries.filter && entries.filter.date"
|
<input matInput [matDatepicker]="picker" [value]="entries && entries.filter && entries.filter.date"
|
||||||
|
@ -27,4 +27,8 @@ mat-chip mat-icon.mat-icon-inline {
|
|||||||
|
|
||||||
.mat-option .mat-icon {
|
.mat-option .mat-icon {
|
||||||
margin-right: -2px;
|
margin-right: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui-tagspicker {
|
||||||
|
display: inline-block;
|
||||||
}
|
}
|
@ -23,21 +23,13 @@ export class UiEntries implements OnInit {
|
|||||||
searchTags: Observable<Object>;
|
searchTags: Observable<Object>;
|
||||||
boundTagspickerChange: Function;
|
boundTagspickerChange: Function;
|
||||||
|
|
||||||
searchFormControl = new FormControl();
|
|
||||||
|
|
||||||
readonly separatorKeysCodes = [ ENTER, COMMA, SPACE ] as const;
|
|
||||||
|
|
||||||
constructor(private tagsService: TagsService) { }
|
constructor(private tagsService: TagsService) { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.checkFilterOpen();
|
this.checkFilterOpen();
|
||||||
this.boundTagspickerChange = this.tagspickerChange.bind(this);
|
this.boundTagspickerChange = this.tagspickerChange.bind(this);
|
||||||
this.searchTags = this.searchFormControl
|
|
||||||
.valueChanges
|
|
||||||
.pipe(
|
|
||||||
debounceTime(300),
|
|
||||||
switchMap(value => this.tagsService.search(value))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
checkFilterOpen() {
|
checkFilterOpen() {
|
||||||
@ -54,7 +46,7 @@ export class UiEntries implements OnInit {
|
|||||||
|
|
||||||
tagspickerChange(value: any) {
|
tagspickerChange(value: any) {
|
||||||
console.log("change", value);
|
console.log("change", value);
|
||||||
this.setFilter('tag', value);
|
this.setFilter('tag', value[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
setFilter(key: string, value) {
|
setFilter(key: string, value) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<mat-form-field [ngClass]="singleton ? 'singleton' : ''">
|
<mat-form-field>
|
||||||
<mat-chip-list #tagList>
|
<mat-chip-list #tagList>
|
||||||
<mat-chip *ngFor="let tag of tags" [removable]="true" (removed)="removeTag(tag)">
|
<mat-chip *ngFor="let tag of tags" [removable]="true" (removed)="removeTag(tag)">
|
||||||
<mat-icon inline="true">tag</mat-icon>{{tag}}
|
<mat-icon inline="true">tag</mat-icon>{{tag}}
|
||||||
@ -6,9 +6,10 @@
|
|||||||
<mat-icon>cancel</mat-icon>
|
<mat-icon>cancel</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</mat-chip>
|
</mat-chip>
|
||||||
<input *ngIf="!singleton || !tags || tags.length < 1" #tagsInput placeholder="{{placeholder}}"
|
<input *ngIf="max == 0 || !tags || tags.length < max" #tagsInput placeholder="{{placeholder}}"
|
||||||
[formControl]="searchFormControl" [matAutocomplete]="auto" [matChipInputFor]="tagList"
|
[formControl]="searchFormControl" [matAutocomplete]="auto" [matChipInputFor]="tagList"
|
||||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes" (matChipInputTokenEnd)="addInputTag($event)">
|
[matChipInputSeparatorKeyCodes]="separatorKeysCodes" (matChipInputTokenEnd)="addInputTag($event)">
|
||||||
|
<mat-hint *ngIf="max > 1" align="end">{{tags && tags.length || 0}}/{{max}}</mat-hint>
|
||||||
</mat-chip-list>
|
</mat-chip-list>
|
||||||
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="addOptionTag($event)">
|
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="addOptionTag($event)">
|
||||||
<mat-option *ngFor="let option of searchTags | async" [value]="option">
|
<mat-option *ngFor="let option of searchTags | async" [value]="option">
|
||||||
|
@ -18,7 +18,7 @@ export class UiTagsPicker implements OnInit {
|
|||||||
@Input() change: Function;
|
@Input() change: Function;
|
||||||
@Input() model: any;
|
@Input() model: any;
|
||||||
@Input() placeholder: string;
|
@Input() placeholder: string;
|
||||||
@Input() singleton: boolean = false;
|
@Input() max: number = 0;
|
||||||
tags: string[] = [];
|
tags: string[] = [];
|
||||||
searchTags: Observable<Object>;
|
searchTags: Observable<Object>;
|
||||||
|
|
||||||
@ -37,13 +37,7 @@ export class UiTagsPicker implements OnInit {
|
|||||||
switchMap(value => this.tagsService.search(value))
|
switchMap(value => this.tagsService.search(value))
|
||||||
);
|
);
|
||||||
|
|
||||||
if (this.singleton) {
|
this.tags = this.model || [];
|
||||||
if (this.model) {
|
|
||||||
this.tags = [ this.model ];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.tags = this.model || [];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addTag(tag: string) {
|
addTag(tag: string) {
|
||||||
@ -51,14 +45,11 @@ export class UiTagsPicker implements OnInit {
|
|||||||
tag = tag.replace('#', '');
|
tag = tag.replace('#', '');
|
||||||
}
|
}
|
||||||
tag = tag.split('#').join('-');
|
tag = tag.split('#').join('-');
|
||||||
if (tag && this.tags.indexOf(tag) == -1) {
|
if (tag && this.tags.indexOf(tag) == -1 && (this.max == 0 || this.tags.length < this.max)) {
|
||||||
this.tags.push(tag);
|
this.tags.push(tag);
|
||||||
}
|
}
|
||||||
if (this.singleton) {
|
|
||||||
this.model = this.tags && this.tags[ 0 ] || undefined;
|
this.model = this.tags;
|
||||||
} else {
|
|
||||||
this.model = this.tags;
|
|
||||||
}
|
|
||||||
if (this.change) {
|
if (this.change) {
|
||||||
this.change(this.model);
|
this.change(this.model);
|
||||||
}
|
}
|
||||||
@ -80,11 +71,7 @@ export class UiTagsPicker implements OnInit {
|
|||||||
this.tags.splice(index, 1);
|
this.tags.splice(index, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.singleton) {
|
this.model = this.tags;
|
||||||
this.model = undefined;
|
|
||||||
} else {
|
|
||||||
this.model = this.tags;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.change) {
|
if (this.change) {
|
||||||
this.change(this.model);
|
this.change(this.model);
|
||||||
|
Loading…
Reference in New Issue
Block a user