mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-07-09 03:04:19 -04:00
Filtering Done (#2222)
* Replaced normal dropdowns with select2 (which will eventually replace our custom typeaheads). Still needs styling. * More css * Styling. Fixed preloading typeahead with multiple options on load. * Styling to align with typeahead tag badges. * Done with filtering story. * Fixed a bug with switching between filters. * Fixed some extra } from localization
This commit is contained in:
parent
680f3d78d2
commit
c2375efe21
27
UI/Web/package-lock.json
generated
27
UI/Web/package-lock.json
generated
@ -37,6 +37,7 @@
|
|||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"lazysizes": "^5.3.2",
|
"lazysizes": "^5.3.2",
|
||||||
"ng-circle-progress": "^1.7.1",
|
"ng-circle-progress": "^1.7.1",
|
||||||
|
"ng-select2-component": "^13.0.2",
|
||||||
"ngx-color-picker": "^14.0.0",
|
"ngx-color-picker": "^14.0.0",
|
||||||
"ngx-extended-pdf-viewer": "^16.2.16",
|
"ngx-extended-pdf-viewer": "^16.2.16",
|
||||||
"ngx-file-drop": "^16.0.0",
|
"ngx-file-drop": "^16.0.0",
|
||||||
@ -10556,6 +10557,20 @@
|
|||||||
"rxjs": ">=6.4.0"
|
"rxjs": ">=6.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ng-select2-component": {
|
||||||
|
"version": "13.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ng-select2-component/-/ng-select2-component-13.0.2.tgz",
|
||||||
|
"integrity": "sha512-8Tms5p0V/0J0vCWOf2Vrk6tJlwbaf3D3As3iigcjRncYlfXN130agniBcZ007C3zK2KyLXJJRkEWzlCls8/TVQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"ngx-infinite-scroll": ">=16.0.0",
|
||||||
|
"tslib": "^2.3.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@angular/cdk": ">=16.1.0",
|
||||||
|
"@angular/common": ">=16.1.0",
|
||||||
|
"@angular/core": ">=16.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ngx-color-picker": {
|
"node_modules/ngx-color-picker": {
|
||||||
"version": "14.0.0",
|
"version": "14.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/ngx-color-picker/-/ngx-color-picker-14.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ngx-color-picker/-/ngx-color-picker-14.0.0.tgz",
|
||||||
@ -10598,6 +10613,18 @@
|
|||||||
"@angular/core": ">=14.0.0"
|
"@angular/core": ">=14.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ngx-infinite-scroll": {
|
||||||
|
"version": "16.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ngx-infinite-scroll/-/ngx-infinite-scroll-16.0.0.tgz",
|
||||||
|
"integrity": "sha512-bzyNYd+wVlUUxcopRVr2DAa81eEc8vITtKVvb+c7R1uy8hWPTlxOEXf3L1qA4FMwTEzCQ9b37TXzlJji3qBy+A==",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.3.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@angular/common": ">=16.0.0 <17.0.0",
|
||||||
|
"@angular/core": ">=16.0.0 <17.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ngx-slider-v2": {
|
"node_modules/ngx-slider-v2": {
|
||||||
"version": "16.0.2",
|
"version": "16.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/ngx-slider-v2/-/ngx-slider-v2-16.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/ngx-slider-v2/-/ngx-slider-v2-16.0.2.tgz",
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"lazysizes": "^5.3.2",
|
"lazysizes": "^5.3.2",
|
||||||
"ng-circle-progress": "^1.7.1",
|
"ng-circle-progress": "^1.7.1",
|
||||||
|
"ng-select2-component": "^13.0.2",
|
||||||
"ngx-color-picker": "^14.0.0",
|
"ngx-color-picker": "^14.0.0",
|
||||||
"ngx-extended-pdf-viewer": "^16.2.16",
|
"ngx-extended-pdf-viewer": "^16.2.16",
|
||||||
"ngx-file-drop": "^16.0.0",
|
"ngx-file-drop": "^16.0.0",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<ng-container *transloco="let t; read: 'personal-table-of-contents'">
|
<ng-container *transloco="let t; read: 'personal-table-of-contents'">
|
||||||
<div class="table-of-contents">
|
<div class="table-of-contents">
|
||||||
<div *ngIf="Pages.length === 0">
|
<div *ngIf="Pages.length === 0">
|
||||||
<em>{{t('no-data')}}}</em>
|
<em>{{t('no-data')}}</em>
|
||||||
</div>
|
</div>
|
||||||
<ul>
|
<ul>
|
||||||
<li *ngFor="let page of Pages">
|
<li *ngFor="let page of Pages">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<ng-container *transloco="let t; read: 'table-of-contents'">
|
<ng-container *transloco="let t; read: 'table-of-contents'">
|
||||||
<div class="table-of-contents">
|
<div class="table-of-contents">
|
||||||
<div *ngIf="chapters.length === 0">
|
<div *ngIf="chapters.length === 0">
|
||||||
<em>{{t('no-data')}}}</em>
|
<em>{{t('no-data')}}</em>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="chapters.length === 1; else nestedChildren">
|
<div *ngIf="chapters.length === 1; else nestedChildren">
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
<div class="col-md-2 col-1">
|
<div class="col-md-2 col-1">
|
||||||
<button class="btn btn-icon" (click)="addFilter()" [ngbTooltip]="t('add-rule')">
|
<button class="btn btn-icon" (click)="addFilter()" [ngbTooltip]="t('add-rule')">
|
||||||
<i class="fa fa-solid fa-plus" aria-hidden="true"></i>
|
<i class="fa fa-solid fa-plus" aria-hidden="true"></i>
|
||||||
<span class="visually-hidden" aria-hidden="true">{{t('add-rule')}}}</span>
|
<span class="visually-hidden" aria-hidden="true">{{t('add-rule')}}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -25,9 +25,17 @@
|
|||||||
<input type="number" inputmode="numeric" class="form-control me-2" formControlName="filterValue">
|
<input type="number" inputmode="numeric" class="form-control me-2" formControlName="filterValue">
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngSwitchCase="PredicateType.Dropdown">
|
<ng-container *ngSwitchCase="PredicateType.Dropdown">
|
||||||
<select class="col-auto form-select me-2" formControlName="filterValue">
|
<ng-container *ngIf="dropdownOptions$ | async as opts">
|
||||||
<option *ngFor="let option of dropdownOptions$ | async" [value]="option.value">{{option.title}}</option>
|
<ng-container *ngTemplateOutlet="dropdown; context: { options: opts, multipleAllowed: MultipleDropdownAllowed }"></ng-container>
|
||||||
</select>
|
<ng-template #dropdown let-options="options" let-multipleAllowed="multipleAllowed">
|
||||||
|
<select2 [data]="options"
|
||||||
|
formControlName="filterValue"
|
||||||
|
[multiple]="multipleAllowed"
|
||||||
|
[infiniteScroll]="true"
|
||||||
|
[resettable]="true">
|
||||||
|
</select2>
|
||||||
|
</ng-template>
|
||||||
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
::ng-deep .select2-selection__rendered {
|
||||||
|
padding-top: 4px !important;
|
||||||
|
}
|
@ -19,10 +19,12 @@ import {LibraryService} from 'src/app/_services/library.service';
|
|||||||
import {CollectionTagService} from 'src/app/_services/collection-tag.service';
|
import {CollectionTagService} from 'src/app/_services/collection-tag.service';
|
||||||
import {FilterComparison} from 'src/app/_models/metadata/v2/filter-comparison';
|
import {FilterComparison} from 'src/app/_models/metadata/v2/filter-comparison';
|
||||||
import {allFields, FilterField} from 'src/app/_models/metadata/v2/filter-field';
|
import {allFields, FilterField} from 'src/app/_models/metadata/v2/filter-field';
|
||||||
import {AsyncPipe, NgForOf, NgIf, NgSwitch, NgSwitchCase} from "@angular/common";
|
import {AsyncPipe, NgForOf, NgIf, NgSwitch, NgSwitchCase, NgTemplateOutlet} from "@angular/common";
|
||||||
import {FilterFieldPipe} from "../../_pipes/filter-field.pipe";
|
import {FilterFieldPipe} from "../../_pipes/filter-field.pipe";
|
||||||
import {FilterComparisonPipe} from "../../_pipes/filter-comparison.pipe";
|
import {FilterComparisonPipe} from "../../_pipes/filter-comparison.pipe";
|
||||||
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
|
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
|
||||||
|
import {Select2Module, Select2Option} from "ng-select2-component";
|
||||||
|
import {TagBadgeComponent} from "../../../shared/tag-badge/tag-badge.component";
|
||||||
|
|
||||||
enum PredicateType {
|
enum PredicateType {
|
||||||
Text = 1,
|
Text = 1,
|
||||||
@ -70,12 +72,18 @@ const DropdownComparisons = [FilterComparison.Equal,
|
|||||||
NgSwitch,
|
NgSwitch,
|
||||||
NgSwitchCase,
|
NgSwitchCase,
|
||||||
NgForOf,
|
NgForOf,
|
||||||
NgIf
|
NgIf,
|
||||||
|
Select2Module,
|
||||||
|
NgTemplateOutlet,
|
||||||
|
TagBadgeComponent
|
||||||
],
|
],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class MetadataFilterRowComponent implements OnInit {
|
export class MetadataFilterRowComponent implements OnInit {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Slightly misleading as this is the initial state and will be updated on the filterStatement event emitter
|
||||||
|
*/
|
||||||
@Input() preset!: FilterStatement;
|
@Input() preset!: FilterStatement;
|
||||||
@Input() availableFields: Array<FilterField> = allFields;
|
@Input() availableFields: Array<FilterField> = allFields;
|
||||||
@Output() filterStatement = new EventEmitter<FilterStatement>();
|
@Output() filterStatement = new EventEmitter<FilterStatement>();
|
||||||
@ -89,14 +97,18 @@ export class MetadataFilterRowComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
validComparisons$: BehaviorSubject<FilterComparison[]> = new BehaviorSubject([FilterComparison.Equal] as FilterComparison[]);
|
validComparisons$: BehaviorSubject<FilterComparison[]> = new BehaviorSubject([FilterComparison.Equal] as FilterComparison[]);
|
||||||
predicateType$: BehaviorSubject<PredicateType> = new BehaviorSubject(PredicateType.Text as PredicateType);
|
predicateType$: BehaviorSubject<PredicateType> = new BehaviorSubject(PredicateType.Text as PredicateType);
|
||||||
dropdownOptions$ = of<{value: number, title: string}[]>([]);
|
dropdownOptions$ = of<Select2Option[]>([]);
|
||||||
|
|
||||||
|
|
||||||
loaded: boolean = false;
|
loaded: boolean = false;
|
||||||
|
|
||||||
|
|
||||||
get PredicateType() { return PredicateType };
|
get PredicateType() { return PredicateType };
|
||||||
|
|
||||||
|
get MultipleDropdownAllowed() {
|
||||||
|
const comp = parseInt(this.formGroup.get('comparison')?.value, 10) as FilterComparison;
|
||||||
|
return comp === FilterComparison.Contains || comp === FilterComparison.NotContains;
|
||||||
|
}
|
||||||
|
|
||||||
constructor(private readonly metadataService: MetadataService, private readonly libraryService: LibraryService,
|
constructor(private readonly metadataService: MetadataService, private readonly libraryService: LibraryService,
|
||||||
private readonly collectionTagService: CollectionTagService) {}
|
private readonly collectionTagService: CollectionTagService) {}
|
||||||
|
|
||||||
@ -106,26 +118,27 @@ export class MetadataFilterRowComponent implements OnInit {
|
|||||||
this.formGroup.get('input')?.valueChanges.subscribe((val: string) => this.handleFieldChange(val));
|
this.formGroup.get('input')?.valueChanges.subscribe((val: string) => this.handleFieldChange(val));
|
||||||
this.populateFromPreset();
|
this.populateFromPreset();
|
||||||
|
|
||||||
this.buildDisabledList();
|
|
||||||
|
|
||||||
|
|
||||||
// Dropdown dynamic option selection
|
// Dropdown dynamic option selection
|
||||||
this.dropdownOptions$ = this.formGroup.get('input')!.valueChanges.pipe(
|
this.dropdownOptions$ = this.formGroup.get('input')!.valueChanges.pipe(
|
||||||
startWith(this.preset.value),
|
startWith(this.preset.value),
|
||||||
switchMap((_) => this.getDropdownObservable()),
|
switchMap((_) => this.getDropdownObservable()),
|
||||||
tap((opts) => {
|
tap((opts) => {
|
||||||
const filterField = parseInt(this.formGroup.get('input')?.value, 10) as FilterField;
|
if (!this.formGroup.get('filterValue')?.value) {
|
||||||
const filterComparison = parseInt(this.formGroup.get('comparison')?.value, 10) as FilterComparison;
|
this. populateFromPreset();
|
||||||
if (this.preset.field === filterField && this.preset.comparison === filterComparison) {
|
|
||||||
//console.log('using preset value for dropdown option')
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.MultipleDropdownAllowed) {
|
||||||
|
this.formGroup.get('filterValue')?.setValue((opts[0].value + '').split(','));
|
||||||
|
} else {
|
||||||
this.formGroup.get('filterValue')?.setValue(opts[0].value);
|
this.formGroup.get('filterValue')?.setValue(opts[0].value);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
takeUntilDestroyed(this.destroyRef)
|
takeUntilDestroyed(this.destroyRef)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
this.formGroup.valueChanges.pipe(distinctUntilChanged(), takeUntilDestroyed(this.destroyRef)).subscribe(_ => {
|
this.formGroup.valueChanges.pipe(distinctUntilChanged(), takeUntilDestroyed(this.destroyRef)).subscribe(_ => {
|
||||||
this.filterStatement.emit({
|
this.filterStatement.emit({
|
||||||
comparison: parseInt(this.formGroup.get('comparison')?.value, 10) as FilterComparison,
|
comparison: parseInt(this.formGroup.get('comparison')?.value, 10) as FilterComparison,
|
||||||
@ -138,13 +151,20 @@ export class MetadataFilterRowComponent implements OnInit {
|
|||||||
this.cdRef.markForCheck();
|
this.cdRef.markForCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
buildDisabledList() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
populateFromPreset() {
|
populateFromPreset() {
|
||||||
if (StringFields.includes(this.preset.field)) {
|
if (StringFields.includes(this.preset.field)) {
|
||||||
this.formGroup.get('filterValue')?.patchValue(this.preset.value);
|
this.formGroup.get('filterValue')?.patchValue(this.preset.value);
|
||||||
|
} else if (DropdownFields.includes(this.preset.field)) {
|
||||||
|
if (this.MultipleDropdownAllowed) {
|
||||||
|
this.formGroup.get('filterValue')?.setValue(this.preset.value.split(','));
|
||||||
|
} else {
|
||||||
|
if (this.preset.field === FilterField.Languages) {
|
||||||
|
this.formGroup.get('filterValue')?.setValue(this.preset.value);
|
||||||
|
} else {
|
||||||
|
this.formGroup.get('filterValue')?.setValue(parseInt(this.preset.value, 10));
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.formGroup.get('filterValue')?.patchValue(parseInt(this.preset.value, 10));
|
this.formGroup.get('filterValue')?.patchValue(parseInt(this.preset.value, 10));
|
||||||
}
|
}
|
||||||
@ -154,40 +174,40 @@ export class MetadataFilterRowComponent implements OnInit {
|
|||||||
this.cdRef.markForCheck();
|
this.cdRef.markForCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
getDropdownObservable(): Observable<{value: any, title: string}[]> {
|
getDropdownObservable(): Observable<Select2Option[]> {
|
||||||
const filterField = parseInt(this.formGroup.get('input')?.value, 10) as FilterField;
|
const filterField = parseInt(this.formGroup.get('input')?.value, 10) as FilterField;
|
||||||
switch (filterField) {
|
switch (filterField) {
|
||||||
case FilterField.PublicationStatus:
|
case FilterField.PublicationStatus:
|
||||||
return this.metadataService.getAllPublicationStatus().pipe(map(pubs => pubs.map(pub => {
|
return this.metadataService.getAllPublicationStatus().pipe(map(pubs => pubs.map(pub => {
|
||||||
return {value: pub.value, title: pub.title}
|
return {value: pub.value, label: pub.title}
|
||||||
})));
|
})));
|
||||||
case FilterField.AgeRating:
|
case FilterField.AgeRating:
|
||||||
return this.metadataService.getAllAgeRatings().pipe(map(ratings => ratings.map(rating => {
|
return this.metadataService.getAllAgeRatings().pipe(map(ratings => ratings.map(rating => {
|
||||||
return {value: rating.value, title: rating.title}
|
return {value: rating.value, label: rating.title}
|
||||||
})));
|
})));
|
||||||
case FilterField.Genres:
|
case FilterField.Genres:
|
||||||
return this.metadataService.getAllGenres().pipe(map(genres => genres.map(genre => {
|
return this.metadataService.getAllGenres().pipe(map(genres => genres.map(genre => {
|
||||||
return {value: genre.id, title: genre.title}
|
return {value: genre.id, label: genre.title}
|
||||||
})));
|
})));
|
||||||
case FilterField.Languages:
|
case FilterField.Languages:
|
||||||
return this.metadataService.getAllLanguages().pipe(map(statuses => statuses.map(status => {
|
return this.metadataService.getAllLanguages().pipe(map(statuses => statuses.map(status => {
|
||||||
return {value: status.isoCode, title: status.title + ` (${status.isoCode})`}
|
return {value: status.isoCode, label: status.title + ` (${status.isoCode})`}
|
||||||
})));
|
})));
|
||||||
case FilterField.Formats:
|
case FilterField.Formats:
|
||||||
return of(mangaFormatFilters).pipe(map(statuses => statuses.map(status => {
|
return of(mangaFormatFilters).pipe(map(statuses => statuses.map(status => {
|
||||||
return {value: status.value, title: status.title}
|
return {value: status.value, label: status.title}
|
||||||
})));
|
})));
|
||||||
case FilterField.Libraries:
|
case FilterField.Libraries:
|
||||||
return this.libraryService.getLibraries().pipe(map(libs => libs.map(lib => {
|
return this.libraryService.getLibraries().pipe(map(libs => libs.map(lib => {
|
||||||
return {value: lib.id, title: lib.name}
|
return {value: lib.id, label: lib.name}
|
||||||
})));
|
})));
|
||||||
case FilterField.Tags:
|
case FilterField.Tags:
|
||||||
return this.metadataService.getAllTags().pipe(map(statuses => statuses.map(status => {
|
return this.metadataService.getAllTags().pipe(map(statuses => statuses.map(status => {
|
||||||
return {value: status.id, title: status.title}
|
return {value: status.id, label: status.title}
|
||||||
})));
|
})));
|
||||||
case FilterField.CollectionTags:
|
case FilterField.CollectionTags:
|
||||||
return this.collectionTagService.allTags().pipe(map(statuses => statuses.map(status => {
|
return this.collectionTagService.allTags().pipe(map(statuses => statuses.map(status => {
|
||||||
return {value: status.id, title: status.title}
|
return {value: status.id, label: status.title}
|
||||||
})));
|
})));
|
||||||
case FilterField.Characters: return this.getPersonOptions(PersonRole.Character);
|
case FilterField.Characters: return this.getPersonOptions(PersonRole.Character);
|
||||||
case FilterField.Colorist: return this.getPersonOptions(PersonRole.Colorist);
|
case FilterField.Colorist: return this.getPersonOptions(PersonRole.Colorist);
|
||||||
@ -205,7 +225,7 @@ export class MetadataFilterRowComponent implements OnInit {
|
|||||||
|
|
||||||
getPersonOptions(role: PersonRole) {
|
getPersonOptions(role: PersonRole) {
|
||||||
return this.metadataService.getAllPeople().pipe(map(people => people.filter(p2 => p2.role === role).map(person => {
|
return this.metadataService.getAllPeople().pipe(map(people => people.filter(p2 => p2.role === role).map(person => {
|
||||||
return {value: person.id, title: person.name}
|
return {value: person.id, label: person.name}
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +238,6 @@ export class MetadataFilterRowComponent implements OnInit {
|
|||||||
|
|
||||||
this.predicateType$.next(PredicateType.Text);
|
this.predicateType$.next(PredicateType.Text);
|
||||||
if (this.loaded) this.formGroup.get('filterValue')?.setValue('');
|
if (this.loaded) this.formGroup.get('filterValue')?.setValue('');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
@import './theme/components/offcanvas';
|
@import './theme/components/offcanvas';
|
||||||
@import './theme/components/table';
|
@import './theme/components/table';
|
||||||
@import './theme/components/alerts';
|
@import './theme/components/alerts';
|
||||||
|
@import './theme/components/typeahead';
|
||||||
|
|
||||||
|
|
||||||
@import './theme/utilities/utilities';
|
@import './theme/utilities/utilities';
|
||||||
|
72
UI/Web/src/theme/components/_typeahead.scss
Normal file
72
UI/Web/src/theme/components/_typeahead.scss
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
:root {
|
||||||
|
/* size */
|
||||||
|
--select2-single-height: 36px;
|
||||||
|
--select2-multiple-height: 36px;
|
||||||
|
|
||||||
|
/* label */
|
||||||
|
--select2-label-text-color: #000;
|
||||||
|
--select2-required-color: red;
|
||||||
|
|
||||||
|
/* selection */
|
||||||
|
--select2-selection-border-radius: 4px;
|
||||||
|
--select2-selection-background: var(--input-bg-readonly-color);
|
||||||
|
--select2-selection-disabled-background: #eee;
|
||||||
|
--select2-selection-border-color: var(--input-border-color);
|
||||||
|
--select2-selection-focus-border-color: var(--input-focus-boxshadow-color);
|
||||||
|
--select2-selection-text-color: var(--input-text-color);
|
||||||
|
|
||||||
|
/* selection: choice item (multiple) */
|
||||||
|
--select2-selection-choice-background: var(--tagbadge-filled-bg-color);
|
||||||
|
--select2-selection-choice-text-color: var(--tagbadge-filled-text-color);
|
||||||
|
--select2-selection-choice-border-color: var(--tagbadge-border-color);
|
||||||
|
--select2-selection-choice-close-color: var(--tagbadge-filled-text-color);
|
||||||
|
--select2-selection-choice-hover-close-color: var(--tagbadge-filled-text-color);
|
||||||
|
|
||||||
|
/* placeholder */
|
||||||
|
--select2-placeholder-color: #999;
|
||||||
|
--select2-placeholder-overflow: ellipsis;
|
||||||
|
|
||||||
|
/* no result message */
|
||||||
|
--select2-no-result-color: #888;
|
||||||
|
--select2-no-result-font-style: italic;
|
||||||
|
|
||||||
|
/* no result message */
|
||||||
|
--select2-too-much-result-color: #888;
|
||||||
|
--select2-too-much-result-style: italic;
|
||||||
|
|
||||||
|
/* reset */
|
||||||
|
--select2-reset-color: #999;
|
||||||
|
|
||||||
|
/* arrow */
|
||||||
|
--select2-arrow-color: #ccc;
|
||||||
|
|
||||||
|
/* dropdown panel */
|
||||||
|
--select2-dropdown-background: var(--input-bg-readonly-color);
|
||||||
|
--select2-dropdown-border-color: var(--input-border-color);
|
||||||
|
|
||||||
|
/* overlay */
|
||||||
|
--select2-overlay-backdrop: transparent;
|
||||||
|
|
||||||
|
/* search field */
|
||||||
|
--select2-search-border-color: var(--input-border-color);
|
||||||
|
--select2-search-background: var(--input-bg-readonly-color);
|
||||||
|
--select2-search-border-radius: 0px;
|
||||||
|
|
||||||
|
/* dropdown option */
|
||||||
|
--select2-option-text-color: var(--body-text-color);
|
||||||
|
--select2-option-disabled-text-color: #999;
|
||||||
|
--select2-option-disabled-background: transparent;
|
||||||
|
--select2-option-selected-text-color: lightgrey;
|
||||||
|
--select2-option-selected-background: var(--btn-disabled-bg-color);
|
||||||
|
--select2-option-highlighted-text-color: #fff;
|
||||||
|
--select2-option-highlighted-background: #5897fb; // TODO: This needs to be done correctly and applied throughout the app
|
||||||
|
--select2-option-group-text-color: var(--body-text-color);
|
||||||
|
--select2-option-group-background: transparent;
|
||||||
|
|
||||||
|
/* hint */
|
||||||
|
--select2-hint-text-color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
//.select2-selection__rendered {
|
||||||
|
// padding-top: 4px;
|
||||||
|
//}
|
@ -7,7 +7,7 @@
|
|||||||
"name": "GPL-3.0",
|
"name": "GPL-3.0",
|
||||||
"url": "https://github.com/Kareadita/Kavita/blob/develop/LICENSE"
|
"url": "https://github.com/Kareadita/Kavita/blob/develop/LICENSE"
|
||||||
},
|
},
|
||||||
"version": "0.7.7.10"
|
"version": "0.7.7.11"
|
||||||
},
|
},
|
||||||
"servers": [
|
"servers": [
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user