diff --git a/ui/src/app/app.module.ts b/ui/src/app/app.module.ts index 2ca69f979..745219af9 100644 --- a/ui/src/app/app.module.ts +++ b/ui/src/app/app.module.ts @@ -9,7 +9,7 @@ import {RichSkillsLibraryComponent} from "./richskill/library/rich-skills-librar import {RichSkillPublicComponent} from "./richskill/detail/rich-skill-public/rich-skill-public.component" import {AppConfig} from "./app.config" import {RichSkillFormComponent} from "./richskill/form/rich-skill-form.component" -import {ReactiveFormsModule} from "@angular/forms" +import {FormsModule, ReactiveFormsModule} from "@angular/forms" import {LoadingObservablesDirective} from "./loading/loading-observables.directive" import {LoadingComponent} from "./loading/loading.component" import {HeaderComponent} from "./navigation/header.component" @@ -94,7 +94,8 @@ import {MyWorkspaceComponent} from "./my-workspace/my-workspace.component" import {CollectionPipe} from "./pipes" import { ConvertToCollectionComponent } from "./my-workspace/convert-to-collection/convert-to-collection.component" import {SharedModule} from "@shared/shared.module" -import {FormModule} from "./form/form.module" +import {OsmtFormModule} from "./form/osmt-form.module" +import { SizePaginationComponent } from "./table/skills-library-table/size-pagination/size-pagination.component" export function initializeApp( appConfig: AppConfig, @@ -201,6 +202,7 @@ export function initializeApp( MyWorkspaceComponent, CollectionPipe, ConvertToCollectionComponent, + SizePaginationComponent, ], imports: [ NgIdleKeepaliveModule.forRoot(), @@ -210,7 +212,8 @@ export function initializeApp( ReactiveFormsModule, CommonModule, SharedModule, - FormModule + OsmtFormModule, + FormsModule ], providers: [ EnvironmentService, diff --git a/ui/src/app/collection/collection-skill-search.component.html b/ui/src/app/collection/collection-skill-search.component.html index 3da166d55..dd51f7bb5 100644 --- a/ui/src/app/collection/collection-skill-search.component.html +++ b/ui/src/app/collection/collection-skill-search.component.html @@ -33,6 +33,8 @@

Add RSDs to {{collect diff --git a/ui/src/app/collection/detail/collection-public/collection-public.component.html b/ui/src/app/collection/detail/collection-public/collection-public.component.html index 1f3a3ea33..cfe7d2ba9 100644 --- a/ui/src/app/collection/detail/collection-public/collection-public.component.html +++ b/ui/src/app/collection/detail/collection-public/collection-public.component.html @@ -27,6 +27,13 @@
+ + + +

Select one or more RSDs in the table, or select all in the table heading, then use the action menu to publish, archive, unarchive, or add the selected RSDs to a collection.

diff --git a/ui/src/app/collection/detail/collection-public/collection-public.component.spec.ts b/ui/src/app/collection/detail/collection-public/collection-public.component.spec.ts index b0288f121..8a6e68a4a 100644 --- a/ui/src/app/collection/detail/collection-public/collection-public.component.spec.ts +++ b/ui/src/app/collection/detail/collection-public/collection-public.component.spec.ts @@ -164,4 +164,17 @@ describe("CollectionPublicComponent", () => { expect(component.from).toEqual((13 - 1) * 50) expect(component.results).toEqual(expected) }) + + describe( "sizeChange", () => { + it("Should set size of page, from and call handlePageClicked", () => { + const size = 100 + spyOn(component, "handlePageClicked").withArgs(1).and.callThrough() + + component.sizeChange(size) + + expect(component.from).toEqual(0) + expect(component.size).toEqual(size) + expect(component.handlePageClicked).toHaveBeenCalledTimes(1) + }) + }) }) diff --git a/ui/src/app/collection/detail/collection-public/collection-public.component.ts b/ui/src/app/collection/detail/collection-public/collection-public.component.ts index 821cdd8a1..61c674dd1 100644 --- a/ui/src/app/collection/detail/collection-public/collection-public.component.ts +++ b/ui/src/app/collection/detail/collection-public/collection-public.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit} from "@angular/core" +import {Component, OnInit, ViewChild} from "@angular/core" import {ApiSearch, PaginatedSkills} from "../../../richskill/service/rich-skill-search.service" import {RichSkillService} from "../../../richskill/service/rich-skill.service" import {ActivatedRoute, Router} from "@angular/router" @@ -10,6 +10,8 @@ import {PublishStatus} from "../../../PublishStatus" import {ApiCollection} from "../../ApiCollection" import {Title} from "@angular/platform-browser"; import {Whitelabelled} from "../../../../whitelabel"; +import {FormControl} from "@angular/forms" +import {SizePaginationComponent} from "../../../table/skills-library-table/size-pagination/size-pagination.component" @Component({ selector: "app-collection-public", @@ -17,6 +19,7 @@ import {Whitelabelled} from "../../../../whitelabel"; }) export class CollectionPublicComponent extends Whitelabelled implements OnInit { + @ViewChild(SizePaginationComponent) sizePagination!: SizePaginationComponent title = "Collection" uuidParam: string | null collection: ApiCollection | undefined @@ -30,6 +33,7 @@ export class CollectionPublicComponent extends Whitelabelled implements OnInit { columnSort: ApiSortOrder = ApiSortOrder.NameAsc showLibraryEmptyMessage = false + sizeControl: FormControl = new FormControl(this.size) constructor(protected router: Router, protected skillService: RichSkillService, @@ -39,6 +43,7 @@ export class CollectionPublicComponent extends Whitelabelled implements OnInit { protected titleService: Title ) { super() + this.sizeControl.valueChanges.subscribe(value => this.sizeChange(value)) this.uuidParam = this.route.snapshot.paramMap.get("uuid") } @@ -117,4 +122,15 @@ export class CollectionPublicComponent extends Whitelabelled implements OnInit { this.from = (newPageNo - 1) * this.size this.loadNextPage() } + + sizeChange(size: number): void { + this.size = size + this.from = 0 + this.handlePageClicked(1) + } + + get isSizePaginationVisible(): () => boolean { + return () => this.totalCount > this.sizePagination?.values[0] + } + } diff --git a/ui/src/app/collection/detail/manage-collection.component.html b/ui/src/app/collection/detail/manage-collection.component.html index cb051a084..24149889a 100644 --- a/ui/src/app/collection/detail/manage-collection.component.html +++ b/ui/src/app/collection/detail/manage-collection.component.html @@ -47,6 +47,9 @@
{ ] expect(component["addToWorkspaceVisible"]()).toBeTrue() }) + + describe( "sizeChange", () => { + it("Should set size of page, from and call handlePageClicked", () => { + const size = 100 + spyOn(component, "handlePageClicked").withArgs(1).and.callThrough() + + component.sizeChange(size) + + expect(component.from).toEqual(0) + expect(component.size).toEqual(size) + expect(component.handlePageClicked).toHaveBeenCalledTimes(1) + }) + }) }) diff --git a/ui/src/app/richskill/list/skills-list.component.ts b/ui/src/app/richskill/list/skills-list.component.ts index 29dc84849..1b36cf731 100644 --- a/ui/src/app/richskill/list/skills-list.component.ts +++ b/ui/src/app/richskill/list/skills-list.component.ts @@ -18,6 +18,7 @@ import {CollectionService} from "../../collection/service/collection.service" import {ApiCollection} from "../../collection/ApiCollection" import {CollectionPipe} from "../../pipes" import {FilterDropdown} from "../../models/filter-dropdown.model" +import {FilterControlsComponent} from "../../table/filter-controls/filter-controls.component" @Component({ selector: "app-skills-list", @@ -32,6 +33,7 @@ export class SkillsListComponent extends QuickLinksHelper { @ViewChild("titleHeading") titleElement!: ElementRef @ViewChild(TableActionBarComponent) tableActionBar!: TableActionBarComponent + @ViewChild(FilterControlsComponent) filterControlsComponent!: FilterControlsComponent resultsLoaded: Observable | undefined @@ -442,6 +444,12 @@ export class SkillsListComponent extends QuickLinksHelper { this.loadNextPage() } + sizeChange(size: number): void { + this.size = size + this.from = 0 + this.handlePageClicked(1) + } + get selectedKeywords(): any { const a: any = {} const b: any = this.keywords @@ -453,4 +461,8 @@ export class SkillsListComponent extends QuickLinksHelper { return a } + get isSizePaginationVisible(): () => boolean { + return () => this.totalCount > this.filterControlsComponent?.sizePagination?.values[0] + } + } diff --git a/ui/src/app/table/filter-controls/filter-controls.component.html b/ui/src/app/table/filter-controls/filter-controls.component.html index 2792af4e9..f926c889b 100644 --- a/ui/src/app/table/filter-controls/filter-controls.component.html +++ b/ui/src/app/table/filter-controls/filter-controls.component.html @@ -19,6 +19,8 @@

Filters

(filterChanged)="onFilterChangeArchived($event)" >
+ +
diff --git a/ui/src/app/table/filter-controls/filter-controls.component.ts b/ui/src/app/table/filter-controls/filter-controls.component.ts index 4e6dab6f2..a6f615425 100644 --- a/ui/src/app/table/filter-controls/filter-controls.component.ts +++ b/ui/src/app/table/filter-controls/filter-controls.component.ts @@ -1,7 +1,8 @@ -import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges} from "@angular/core" +import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild} from "@angular/core" import {PublishStatus} from "../../PublishStatus"; import {FilterDropdown} from "../../models/filter-dropdown.model" -import {FormBuilder, FormGroup} from "@angular/forms" +import {FormBuilder, FormControl, FormGroup} from "@angular/forms" +import {SizePaginationComponent} from "../skills-library-table/size-pagination/size-pagination.component" @Component({ selector: "app-filter-controls", @@ -9,6 +10,8 @@ import {FormBuilder, FormGroup} from "@angular/forms" styleUrls: ["./filter-controls.component.scss"] }) export class FilterControlsComponent implements OnInit, OnChanges { + + @ViewChild(SizePaginationComponent) sizePagination!: SizePaginationComponent @Input() selectedFilters: Set = new Set() @Output() keywordsChanged: EventEmitter = new EventEmitter() @Output() filtersChanged: EventEmitter> = new EventEmitter>() @@ -17,11 +20,20 @@ export class FilterControlsComponent implements OnInit, OnChanges { filterFg: FormGroup @Input() showAdvancedFilteredSearch?: boolean + @Output() + changeValue: EventEmitter = new EventEmitter() + sizeControl?: FormControl + @Input() + currentSize = 50 + @Input() + isSizePaginationVisible: () => boolean = () => false constructor( protected formBuilder: FormBuilder ) { this.filterFg = this.configureFilterFg() + this.sizeControl = new FormControl(this.currentSize) + this.sizeControl.valueChanges.subscribe(value => this.changeValue.emit(value)) } ngOnInit(): void { diff --git a/ui/src/app/table/skills-library-table/size-pagination/size-pagination.component.html b/ui/src/app/table/skills-library-table/size-pagination/size-pagination.component.html new file mode 100644 index 000000000..c157a3619 --- /dev/null +++ b/ui/src/app/table/skills-library-table/size-pagination/size-pagination.component.html @@ -0,0 +1,10 @@ +
+ + +
diff --git a/ui/src/app/table/skills-library-table/size-pagination/size-pagination.component.scss b/ui/src/app/table/skills-library-table/size-pagination/size-pagination.component.scss new file mode 100644 index 000000000..5a1fc1e34 --- /dev/null +++ b/ui/src/app/table/skills-library-table/size-pagination/size-pagination.component.scss @@ -0,0 +1,19 @@ +select { + width: fit-content; + margin-left: 20px; + border-radius: 8px; + -webkit-box-sizing: border-box; + background-color: var(--color-background300); + border: 1px solid var(--color-background500); + outline: 2px solid transparent; + outline-offset: 4px; + box-sizing: border-box; + padding: 1px 8px; + -webkit-appearance: menulist; + transition: outline var(--t-transition),outline-offset var(--t-transition),border-radius var(--t-transition),border-color var(--t-transition),background-color var(--t-transition),box-shadow var(--t-transition); +} + +.size-pagination-container { + display: flex; + margin-bottom: 20px; +} diff --git a/ui/src/app/table/skills-library-table/size-pagination/size-pagination.component.spec.ts b/ui/src/app/table/skills-library-table/size-pagination/size-pagination.component.spec.ts new file mode 100644 index 000000000..17d9c34b8 --- /dev/null +++ b/ui/src/app/table/skills-library-table/size-pagination/size-pagination.component.spec.ts @@ -0,0 +1,36 @@ +import { ComponentFixture, TestBed } from "@angular/core/testing" + +import { SizePaginationComponent } from "./size-pagination.component" + +describe("SizePaginationComponent", () => { + let component: SizePaginationComponent + let fixture: ComponentFixture + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ SizePaginationComponent ] + }) + .compileComponents() + }) + + beforeEach(() => { + fixture = TestBed.createComponent(SizePaginationComponent) + component = fixture.componentInstance + fixture.detectChanges() + }) + + it("should create", () => { + expect(component).toBeTruthy() + }) + + it("Should call onValueChange with a param of type number", () => { + const param = 100 + const onValueChangeSpy = spyOn(component, "onValueChange").withArgs(param).and.callThrough() + + component.onValueChange(100); + + expect(component.values).toContain(param) + expect(onValueChangeSpy).toHaveBeenCalled() + expect(typeof param).toEqual('number') + }) +}) diff --git a/ui/src/app/table/skills-library-table/size-pagination/size-pagination.component.ts b/ui/src/app/table/skills-library-table/size-pagination/size-pagination.component.ts new file mode 100644 index 000000000..3fd8a953f --- /dev/null +++ b/ui/src/app/table/skills-library-table/size-pagination/size-pagination.component.ts @@ -0,0 +1,23 @@ +import {Component, Input} from "@angular/core" +import {FormControl} from "@angular/forms" + +@Component({ + selector: "app-size-pagination", + templateUrl: "./size-pagination.component.html", + styleUrls: ["./size-pagination.component.scss"] +}) +export class SizePaginationComponent { + + readonly values: number[] = [50, 100, 150] + @Input() + control?: FormControl + @Input() + currentSize = 50 + @Input() + isVisible: () => boolean = () => false + + onValueChange(value: number): void { + this.control?.patchValue(value) + } + +}