mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-10 11:33:04 +00:00
68346: initial Drag-And-Drop pagination component + paginated custom-order support in field-updates store - Intermediate commit
This commit is contained in:
@@ -13,7 +13,7 @@
|
|||||||
.row-element {
|
.row-element {
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
padding: 0.75em;
|
padding: 0.75em;
|
||||||
border-top: $table-border-width solid $table-border-color;
|
border-bottom: $table-border-width solid $table-border-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.drag-handle {
|
.drag-handle {
|
||||||
|
@@ -17,7 +17,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div [id]="bundle.id" class="bundle-bitstreams-list" *ngVar="((updates$ | async) | dsObjectValues) as updateValues" cdkDropList (cdkDropListDropped)="drop($event)">
|
<ds-pagination-drag-and-drop [paginationOptions]="bitstreamsOptions"
|
||||||
|
[paginatedList]="(bitstreamsRD$ | async)?.payload"
|
||||||
|
[hideGear]="true"
|
||||||
|
[hidePaginationDetail]="true"
|
||||||
|
[disableRouteParameterUpdate]="true"
|
||||||
|
(pageChange)="switchPage($event)">
|
||||||
|
<div [id]="bundle.id" class="bundle-bitstreams-list"
|
||||||
|
[ngClass]="{'mb-3': (bitstreamsRD$ | async)?.payload?.totalElements > batchSize}"
|
||||||
|
*ngVar="((updates$ | async) | dsObjectValues) as updateValues" cdkDropList (cdkDropListDropped)="drop($event)">
|
||||||
<div class="row bitstream-row" *ngFor="let updateValue of updateValues" cdkDrag
|
<div class="row bitstream-row" *ngFor="let updateValue of updateValues" cdkDrag
|
||||||
[ngClass]="{
|
[ngClass]="{
|
||||||
'table-warning': updateValue.changeType === 0,
|
'table-warning': updateValue.changeType === 0,
|
||||||
@@ -30,22 +38,6 @@
|
|||||||
<ds-item-edit-bitstream-drag-handle slot="drag-handle"></ds-item-edit-bitstream-drag-handle>
|
<ds-item-edit-bitstream-drag-handle slot="drag-handle"></ds-item-edit-bitstream-drag-handle>
|
||||||
</ds-item-edit-bitstream>
|
</ds-item-edit-bitstream>
|
||||||
</div>
|
</div>
|
||||||
<ng-container *ngVar="(bitstreamsRD$ | async) as bitstreamsRD">
|
|
||||||
<div class="row" *ngIf="bitstreamsRD?.payload?.elementsPerPage < bitstreamsRD?.payload?.totalElements">
|
|
||||||
<ng-container *ngVar="(isLoadingMore$ | async) as loading">
|
|
||||||
<div class="col-6 col-sm-7 col-md-8 col-lg-9 row-element" *ngIf="!loading">
|
|
||||||
<span class="font-italic">{{'item.edit.bitstreams.bundle.displaying' | translate:{ amount: bitstreamsRD?.payload?.elementsPerPage, total: bitstreamsRD?.payload?.totalElements } }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="col-6 col-sm-5 col-md-4 col-lg-3 row-element text-center" *ngIf="!loading">
|
|
||||||
<a [routerLink]="[]" (click)="loadMore()">{{'item.edit.bitstreams.bundle.load.more' | translate}}</a>
|
|
||||||
<span> | </span>
|
|
||||||
<a [routerLink]="[]" (click)="loadAll()">{{'item.edit.bitstreams.bundle.load.all' | translate:{ total: bitstreamsRD?.payload?.totalElements } }}</a>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 row-element text-center" *ngIf="loading">
|
|
||||||
<span class="font-italic">{{'loading.bitstreams' | translate}}</span>
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
|
||||||
</div>
|
</div>
|
||||||
|
</ds-pagination-drag-and-drop>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
@@ -13,8 +13,9 @@ import { PaginatedList } from '../../../../core/data/paginated-list';
|
|||||||
import { BundleDataService } from '../../../../core/data/bundle-data.service';
|
import { BundleDataService } from '../../../../core/data/bundle-data.service';
|
||||||
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
||||||
import { combineLatest as observableCombineLatest } from 'rxjs';
|
import { combineLatest as observableCombineLatest } from 'rxjs';
|
||||||
import { hasNoValue } from '../../../../shared/empty.util';
|
import { hasNoValue, isEmpty } from '../../../../shared/empty.util';
|
||||||
import { PaginatedSearchOptions } from '../../../../shared/search/paginated-search-options.model';
|
import { PaginatedSearchOptions } from '../../../../shared/search/paginated-search-options.model';
|
||||||
|
import { PaginationComponentOptions } from '../../../../shared/pagination/pagination-component-options.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-item-edit-bitstream-bundle',
|
selector: 'ds-item-edit-bitstream-bundle',
|
||||||
@@ -55,33 +56,26 @@ export class ItemEditBitstreamBundleComponent implements OnInit {
|
|||||||
* The amount of one bitstreams one "batch" resembles
|
* The amount of one bitstreams one "batch" resembles
|
||||||
* The user is able to increase the amount of bitstreams displayed per bundle by this batch size until all are shown
|
* The user is able to increase the amount of bitstreams displayed per bundle by this batch size until all are shown
|
||||||
*/
|
*/
|
||||||
batchSize = 10;
|
batchSize = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The page options to use for fetching the bitstreams
|
* The page options to use for fetching the bitstreams
|
||||||
*/
|
*/
|
||||||
bitstreamsOptions = {
|
bitstreamsOptions = Object.assign(new PaginationComponentOptions(),{
|
||||||
id: 'bitstreams-pagination-options',
|
id: 'bitstreams-pagination-options',
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
pageSize: this.batchSize
|
pageSize: this.batchSize
|
||||||
} as any;
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current amount of bitstreams to display for this bundle
|
* The current page we're displaying for this bundle
|
||||||
* Starts off with just one batch
|
|
||||||
*/
|
*/
|
||||||
currentSize$ = new BehaviorSubject<number>(this.batchSize);
|
currentPage$ = new BehaviorSubject<number>(1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Are we currently loading more bitstreams?
|
* A list of pages that have been initialized in the field-update store
|
||||||
*/
|
*/
|
||||||
isLoadingMore$: Observable<boolean>;
|
initializedPages: number[] = [];
|
||||||
|
|
||||||
/**
|
|
||||||
* What size were the object updates last initialized with?
|
|
||||||
* Used to check if the object updates need to be re-initialized when loading more bitstreams
|
|
||||||
*/
|
|
||||||
lastInitializedWithSize: number;
|
|
||||||
|
|
||||||
constructor(private objectUpdatesService: ObjectUpdatesService,
|
constructor(private objectUpdatesService: ObjectUpdatesService,
|
||||||
private bundleService: BundleDataService,
|
private bundleService: BundleDataService,
|
||||||
@@ -89,27 +83,39 @@ export class ItemEditBitstreamBundleComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.bitstreamsRD$ = this.currentSize$.pipe(
|
this.bitstreamsRD$ = this.currentPage$.pipe(
|
||||||
switchMap((size: number) => this.bundleService.getBitstreams(this.bundle.id,
|
switchMap((page: number) => this.bundleService.getBitstreams(this.bundle.id,
|
||||||
new PaginatedSearchOptions({pagination: Object.assign({}, this.bitstreamsOptions, { pageSize: size })})))
|
new PaginatedSearchOptions({pagination: Object.assign({}, this.bitstreamsOptions, { currentPage: page })})))
|
||||||
);
|
);
|
||||||
this.updates$ = this.bitstreamsRD$.pipe(
|
this.updates$ = this.bitstreamsRD$.pipe(
|
||||||
toBitstreamsArray(),
|
toBitstreamsArray(),
|
||||||
tap((bitstreams: Bitstream[]) => {
|
tap((bitstreams: Bitstream[]) => {
|
||||||
if (hasNoValue(this.lastInitializedWithSize) || this.currentSize$.value !== this.lastInitializedWithSize) {
|
// Pages in the field-update store are indexed starting at 0 (because they're stored in an array of pages)
|
||||||
this.objectUpdatesService.initialize(this.bundle.self, bitstreams, new Date(), true);
|
const updatesPage = this.currentPage$.value - 1;
|
||||||
this.lastInitializedWithSize = this.currentSize$.value;
|
if (isEmpty(this.initializedPages)) {
|
||||||
|
// No updates have been initialized yet for this bundle, initialize the first page
|
||||||
|
this.objectUpdatesService.initializeWithCustomOrder(this.bundle.self, bitstreams, new Date(), this.batchSize, updatesPage);
|
||||||
|
this.initializedPages.push(updatesPage);
|
||||||
|
} else if (this.initializedPages.indexOf(this.currentPage$.value) < 0) {
|
||||||
|
// Updates were initialized for this bundle, but not the page we're on. Add the current page to the field-update store for this bundle
|
||||||
|
this.objectUpdatesService.addPageToCustomOrder(this.bundle.self, bitstreams, updatesPage);
|
||||||
|
this.initializedPages.push(updatesPage);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
switchMap((bitstreams: Bitstream[]) => this.objectUpdatesService.getFieldUpdatesByCustomOrder(this.bundle.self, bitstreams))
|
switchMap((bitstreams: Bitstream[]) => this.objectUpdatesService.getFieldUpdatesByCustomOrder(this.bundle.self, bitstreams, this.currentPage$.value - 1))
|
||||||
);
|
|
||||||
this.isLoadingMore$ = observableCombineLatest(this.currentSize$, this.bitstreamsRD$).pipe(
|
|
||||||
map(([size, bitstreamsRD]: [number, RemoteData<PaginatedList<Bitstream>>]) => size > bitstreamsRD.payload.page.length)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
this.viewContainerRef.createEmbeddedView(this.bundleView);
|
this.viewContainerRef.createEmbeddedView(this.bundleView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the current page
|
||||||
|
* @param page
|
||||||
|
*/
|
||||||
|
switchPage(page: number) {
|
||||||
|
this.currentPage$.next(page);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A bitstream was moved, send updates to the store
|
* A bitstream was moved, send updates to the store
|
||||||
* @param event
|
* @param event
|
||||||
@@ -117,18 +123,4 @@ export class ItemEditBitstreamBundleComponent implements OnInit {
|
|||||||
drop(event: CdkDragDrop<any>) {
|
drop(event: CdkDragDrop<any>) {
|
||||||
this.objectUpdatesService.saveMoveFieldUpdate(this.bundle.self, event.previousIndex, event.currentIndex);
|
this.objectUpdatesService.saveMoveFieldUpdate(this.bundle.self, event.previousIndex, event.currentIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Load more bitstreams (current size + batchSize)
|
|
||||||
*/
|
|
||||||
loadMore() {
|
|
||||||
this.currentSize$.next(this.currentSize$.value + this.batchSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load all bitstreams
|
|
||||||
*/
|
|
||||||
loadAll() {
|
|
||||||
this.currentSize$.next(9999);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,7 @@ import { Injectable } from '@angular/core';
|
|||||||
import { CacheableObject } from '../cache/object-cache.reducer';
|
import { CacheableObject } from '../cache/object-cache.reducer';
|
||||||
import { NormalizedObject } from '../cache/models/normalized-object.model';
|
import { NormalizedObject } from '../cache/models/normalized-object.model';
|
||||||
import { moveItemInArray } from '@angular/cdk/drag-drop';
|
import { moveItemInArray } from '@angular/cdk/drag-drop';
|
||||||
|
import { hasValue } from '../../shared/empty.util';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class to determine move operations between two arrays
|
* A class to determine move operations between two arrays
|
||||||
@@ -22,6 +23,7 @@ export class ArrayMoveChangeAnalyzer<T> {
|
|||||||
const result = [];
|
const result = [];
|
||||||
const moved = [...array1];
|
const moved = [...array1];
|
||||||
array1.forEach((value: T, index: number) => {
|
array1.forEach((value: T, index: number) => {
|
||||||
|
if (hasValue(value)) {
|
||||||
const otherIndex = array2.indexOf(value);
|
const otherIndex = array2.indexOf(value);
|
||||||
const movedIndex = moved.indexOf(value);
|
const movedIndex = moved.indexOf(value);
|
||||||
if (index !== otherIndex && movedIndex !== otherIndex) {
|
if (index !== otherIndex && movedIndex !== otherIndex) {
|
||||||
@@ -32,6 +34,7 @@ export class ArrayMoveChangeAnalyzer<T> {
|
|||||||
path: '/' + otherIndex
|
path: '/' + otherIndex
|
||||||
}) as MoveOperation)
|
}) as MoveOperation)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@ import { INotification } from '../../../shared/notifications/models/notification
|
|||||||
*/
|
*/
|
||||||
export const ObjectUpdatesActionTypes = {
|
export const ObjectUpdatesActionTypes = {
|
||||||
INITIALIZE_FIELDS: type('dspace/core/cache/object-updates/INITIALIZE_FIELDS'),
|
INITIALIZE_FIELDS: type('dspace/core/cache/object-updates/INITIALIZE_FIELDS'),
|
||||||
|
ADD_PAGE_TO_CUSTOM_ORDER: type('dspace/core/cache/object-updates/ADD_PAGE_TO_CUSTOM_ORDER'),
|
||||||
SET_EDITABLE_FIELD: type('dspace/core/cache/object-updates/SET_EDITABLE_FIELD'),
|
SET_EDITABLE_FIELD: type('dspace/core/cache/object-updates/SET_EDITABLE_FIELD'),
|
||||||
SET_VALID_FIELD: type('dspace/core/cache/object-updates/SET_VALID_FIELD'),
|
SET_VALID_FIELD: type('dspace/core/cache/object-updates/SET_VALID_FIELD'),
|
||||||
ADD_FIELD: type('dspace/core/cache/object-updates/ADD_FIELD'),
|
ADD_FIELD: type('dspace/core/cache/object-updates/ADD_FIELD'),
|
||||||
@@ -39,7 +40,9 @@ export class InitializeFieldsAction implements Action {
|
|||||||
url: string,
|
url: string,
|
||||||
fields: Identifiable[],
|
fields: Identifiable[],
|
||||||
lastModified: Date,
|
lastModified: Date,
|
||||||
order: string[]
|
order: string[],
|
||||||
|
pageSize: number,
|
||||||
|
page: number
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,14 +53,48 @@ export class InitializeFieldsAction implements Action {
|
|||||||
* @param fields The identifiable fields of which the updates are kept track of
|
* @param fields The identifiable fields of which the updates are kept track of
|
||||||
* @param lastModified The last modified date of the object that belongs to the page
|
* @param lastModified The last modified date of the object that belongs to the page
|
||||||
* @param order A custom order to keep track of objects moving around
|
* @param order A custom order to keep track of objects moving around
|
||||||
|
* @param pageSize The page size used to fill empty pages for the custom order
|
||||||
|
* @param page The first page to populate in the custom order
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
url: string,
|
url: string,
|
||||||
fields: Identifiable[],
|
fields: Identifiable[],
|
||||||
lastModified: Date,
|
lastModified: Date,
|
||||||
order: string[] = []
|
order: string[] = [],
|
||||||
|
pageSize: number = 9999,
|
||||||
|
page: number = 0
|
||||||
) {
|
) {
|
||||||
this.payload = { url, fields, lastModified, order };
|
this.payload = { url, fields, lastModified, order, pageSize, page };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ngrx action to initialize a new page's fields in the ObjectUpdates state
|
||||||
|
*/
|
||||||
|
export class AddPageToCustomOrderAction implements Action {
|
||||||
|
type = ObjectUpdatesActionTypes.ADD_PAGE_TO_CUSTOM_ORDER;
|
||||||
|
payload: {
|
||||||
|
url: string,
|
||||||
|
fields: Identifiable[],
|
||||||
|
order: string[],
|
||||||
|
page: number
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new AddPageToCustomOrderAction
|
||||||
|
*
|
||||||
|
* @param url The unique url of the page for which the fields are being added
|
||||||
|
* @param fields The identifiable fields of which the updates are kept track of
|
||||||
|
* @param order A custom order to keep track of objects moving around
|
||||||
|
* @param page The page to populate in the custom order
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
url: string,
|
||||||
|
fields: Identifiable[],
|
||||||
|
order: string[] = [],
|
||||||
|
page: number = 0
|
||||||
|
) {
|
||||||
|
this.payload = { url, fields, order, page };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +291,9 @@ export class MoveFieldUpdateAction implements Action {
|
|||||||
payload: {
|
payload: {
|
||||||
url: string,
|
url: string,
|
||||||
from: number,
|
from: number,
|
||||||
to: number
|
to: number,
|
||||||
|
fromPage: number,
|
||||||
|
toPage: number
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -264,13 +303,17 @@ export class MoveFieldUpdateAction implements Action {
|
|||||||
* the unique url of the page for which a field's change should be removed
|
* the unique url of the page for which a field's change should be removed
|
||||||
* @param from The index of the object to move
|
* @param from The index of the object to move
|
||||||
* @param to The index to move the object to
|
* @param to The index to move the object to
|
||||||
|
* @param fromPage The page to move the object from
|
||||||
|
* @param toPage The page to move the object to
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
url: string,
|
url: string,
|
||||||
from: number,
|
from: number,
|
||||||
to: number
|
to: number,
|
||||||
|
fromPage: number,
|
||||||
|
toPage: number
|
||||||
) {
|
) {
|
||||||
this.payload = { url, from, to };
|
this.payload = { url, from, to, fromPage, toPage };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,4 +329,5 @@ export type ObjectUpdatesAction
|
|||||||
| ReinstateObjectUpdatesAction
|
| ReinstateObjectUpdatesAction
|
||||||
| RemoveObjectUpdatesAction
|
| RemoveObjectUpdatesAction
|
||||||
| RemoveFieldUpdateAction
|
| RemoveFieldUpdateAction
|
||||||
| MoveFieldUpdateAction;
|
| MoveFieldUpdateAction
|
||||||
|
| AddPageToCustomOrderAction;
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
AddFieldUpdateAction,
|
AddFieldUpdateAction, AddPageToCustomOrderAction,
|
||||||
DiscardObjectUpdatesAction,
|
DiscardObjectUpdatesAction,
|
||||||
FieldChangeType,
|
FieldChangeType,
|
||||||
InitializeFieldsAction, MoveFieldUpdateAction,
|
InitializeFieldsAction, MoveFieldUpdateAction,
|
||||||
@@ -9,8 +9,9 @@ import {
|
|||||||
RemoveFieldUpdateAction,
|
RemoveFieldUpdateAction,
|
||||||
RemoveObjectUpdatesAction, SetEditableFieldUpdateAction, SetValidFieldUpdateAction
|
RemoveObjectUpdatesAction, SetEditableFieldUpdateAction, SetValidFieldUpdateAction
|
||||||
} from './object-updates.actions';
|
} from './object-updates.actions';
|
||||||
import { hasNoValue, hasValue, isNotEmpty } from '../../../shared/empty.util';
|
import { hasNoValue, hasValue, isEmpty, isNotEmpty } from '../../../shared/empty.util';
|
||||||
import { moveItemInArray } from '@angular/cdk/drag-drop';
|
import { moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';
|
||||||
|
import { from } from 'rxjs/internal/observable/from';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Path where discarded objects are saved
|
* Path where discarded objects are saved
|
||||||
@@ -59,11 +60,16 @@ export interface FieldUpdates {
|
|||||||
* A custom order given to the list of objects
|
* A custom order given to the list of objects
|
||||||
*/
|
*/
|
||||||
export interface CustomOrder {
|
export interface CustomOrder {
|
||||||
initialOrder: string[],
|
initialOrderPages: OrderPage[],
|
||||||
newOrder: string[],
|
newOrderPages: OrderPage[],
|
||||||
|
pageSize: number;
|
||||||
changed: boolean
|
changed: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface OrderPage {
|
||||||
|
order: string[]
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The updated state of a single page
|
* The updated state of a single page
|
||||||
*/
|
*/
|
||||||
@@ -104,6 +110,9 @@ export function objectUpdatesReducer(state = initialState, action: ObjectUpdates
|
|||||||
case ObjectUpdatesActionTypes.INITIALIZE_FIELDS: {
|
case ObjectUpdatesActionTypes.INITIALIZE_FIELDS: {
|
||||||
return initializeFieldsUpdate(state, action as InitializeFieldsAction);
|
return initializeFieldsUpdate(state, action as InitializeFieldsAction);
|
||||||
}
|
}
|
||||||
|
case ObjectUpdatesActionTypes.ADD_PAGE_TO_CUSTOM_ORDER: {
|
||||||
|
return addPageToCustomOrder(state, action as AddPageToCustomOrderAction);
|
||||||
|
}
|
||||||
case ObjectUpdatesActionTypes.ADD_FIELD: {
|
case ObjectUpdatesActionTypes.ADD_FIELD: {
|
||||||
return addFieldUpdate(state, action as AddFieldUpdateAction);
|
return addFieldUpdate(state, action as AddFieldUpdateAction);
|
||||||
}
|
}
|
||||||
@@ -147,18 +156,47 @@ function initializeFieldsUpdate(state: any, action: InitializeFieldsAction) {
|
|||||||
const fields: Identifiable[] = action.payload.fields;
|
const fields: Identifiable[] = action.payload.fields;
|
||||||
const lastModifiedServer: Date = action.payload.lastModified;
|
const lastModifiedServer: Date = action.payload.lastModified;
|
||||||
const order = action.payload.order;
|
const order = action.payload.order;
|
||||||
|
const pageSize = action.payload.pageSize;
|
||||||
|
const page = action.payload.page;
|
||||||
const fieldStates = createInitialFieldStates(fields);
|
const fieldStates = createInitialFieldStates(fields);
|
||||||
|
const initialOrderPages = addOrderToPages([], order, pageSize, page);
|
||||||
const newPageState = Object.assign(
|
const newPageState = Object.assign(
|
||||||
{},
|
{},
|
||||||
state[url],
|
state[url],
|
||||||
{ fieldStates: fieldStates },
|
{ fieldStates: fieldStates },
|
||||||
{ fieldUpdates: {} },
|
{ fieldUpdates: {} },
|
||||||
{ lastModified: lastModifiedServer },
|
{ lastModified: lastModifiedServer },
|
||||||
{ customOrder: { initialOrder: order, newOrder: order, changed: false } }
|
{ customOrder: {
|
||||||
|
initialOrderPages: initialOrderPages,
|
||||||
|
newOrderPages: initialOrderPages,
|
||||||
|
pageSize: 9999,
|
||||||
|
changed: false }
|
||||||
|
}
|
||||||
);
|
);
|
||||||
return Object.assign({}, state, { [url]: newPageState });
|
return Object.assign({}, state, { [url]: newPageState });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a page of objects to the state of a specific url and update a specific page of the custom order
|
||||||
|
* @param state The current state
|
||||||
|
* @param action The action to perform on the current state
|
||||||
|
*/
|
||||||
|
function addPageToCustomOrder(state: any, action: AddPageToCustomOrderAction) {
|
||||||
|
const url: string = action.payload.url;
|
||||||
|
const fields: Identifiable[] = action.payload.fields;
|
||||||
|
const order = action.payload.order;
|
||||||
|
const page = action.payload.page;
|
||||||
|
const pageState: ObjectUpdatesEntry = state[url] || {};
|
||||||
|
const newPageState = Object.assign({}, pageState, {
|
||||||
|
fieldStates: Object.assign({}, pageState.fieldStates, fields),
|
||||||
|
customOrder: Object.assign({}, pageState.customOrder, {
|
||||||
|
newOrderPages: addOrderToPages(pageState.customOrder.newOrderPages, order, pageState.customOrder.pageSize, page),
|
||||||
|
initialOrderPages: addOrderToPages(pageState.customOrder.initialOrderPages, order, pageState.customOrder.pageSize, page)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
return Object.assign({}, state, { [url]: newPageState });
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new update for a specific field to the store
|
* Add a new update for a specific field to the store
|
||||||
* @param state The current state
|
* @param state The current state
|
||||||
@@ -224,9 +262,9 @@ function discardObjectUpdatesFor(url: string, state: any) {
|
|||||||
|
|
||||||
const newCustomOrder = Object.assign({}, pageState.customOrder);
|
const newCustomOrder = Object.assign({}, pageState.customOrder);
|
||||||
if (pageState.customOrder.changed) {
|
if (pageState.customOrder.changed) {
|
||||||
const initialOrder = pageState.customOrder.initialOrder;
|
const initialOrder = pageState.customOrder.initialOrderPages;
|
||||||
if (isNotEmpty(initialOrder)) {
|
if (isNotEmpty(initialOrder)) {
|
||||||
newCustomOrder.newOrder = initialOrder;
|
newCustomOrder.newOrderPages = initialOrder;
|
||||||
newCustomOrder.changed = false;
|
newCustomOrder.changed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -389,6 +427,17 @@ function createInitialFieldStates(fields: Identifiable[]) {
|
|||||||
return fieldStates;
|
return fieldStates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to add a list of objects to an existing FieldStates object
|
||||||
|
* @param fieldStates FieldStates to add states to
|
||||||
|
* @param fields Identifiable objects The list of objects to add to the FieldStates
|
||||||
|
*/
|
||||||
|
function addFieldStates(fieldStates: FieldStates, fields: Identifiable[]) {
|
||||||
|
const uuids = fields.map((field: Identifiable) => field.uuid);
|
||||||
|
uuids.forEach((uuid: string) => fieldStates[uuid] = initialFieldState);
|
||||||
|
return fieldStates;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move an object within the custom order of a page state
|
* Move an object within the custom order of a page state
|
||||||
* @param state The current state
|
* @param state The current state
|
||||||
@@ -396,23 +445,64 @@ function createInitialFieldStates(fields: Identifiable[]) {
|
|||||||
*/
|
*/
|
||||||
function moveFieldUpdate(state: any, action: MoveFieldUpdateAction) {
|
function moveFieldUpdate(state: any, action: MoveFieldUpdateAction) {
|
||||||
const url = action.payload.url;
|
const url = action.payload.url;
|
||||||
const from = action.payload.from;
|
const fromIndex = action.payload.from;
|
||||||
const to = action.payload.to;
|
const toIndex = action.payload.to;
|
||||||
|
const fromPage = action.payload.fromPage;
|
||||||
|
const toPage = action.payload.toPage;
|
||||||
|
|
||||||
const pageState: ObjectUpdatesEntry = state[url];
|
const pageState: ObjectUpdatesEntry = state[url];
|
||||||
const initialOrder = pageState.customOrder.initialOrder;
|
const initialOrderPages = pageState.customOrder.initialOrderPages;
|
||||||
const customOrder = [...pageState.customOrder.newOrder];
|
const customOrderPages = [...pageState.customOrder.newOrderPages];
|
||||||
if (isNotEmpty(customOrder) && isNotEmpty(customOrder[from]) && isNotEmpty(customOrder[to])) {
|
if (fromPage === toPage) {
|
||||||
moveItemInArray(customOrder, from, to);
|
if (isNotEmpty(customOrderPages[fromPage]) && isNotEmpty(customOrderPages[fromPage].order[fromIndex]) && isNotEmpty(customOrderPages[fromPage].order[toIndex])) {
|
||||||
|
moveItemInArray(customOrderPages[fromPage].order, fromIndex, toIndex);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isNotEmpty(customOrderPages[fromPage]) && isNotEmpty(customOrderPages[toPage]) && isNotEmpty(customOrderPages[fromPage].order[fromIndex]) && isNotEmpty(customOrderPages[toPage].order[toIndex])) {
|
||||||
|
transferArrayItem(customOrderPages[fromPage].order, customOrderPages[toPage].order, fromIndex, toIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let changed = false;
|
let changed = false;
|
||||||
initialOrder.forEach((id: string, index: number) => {
|
initialOrderPages.forEach((orderPage: OrderPage, page: number) => {
|
||||||
if (id !== customOrder[index]) {
|
if (isNotEmpty(orderPage) && isNotEmpty(orderPage.order) && isNotEmpty(customOrderPages[page]) && isNotEmpty(customOrderPages[page].order)) {
|
||||||
|
orderPage.order.forEach((id: string, index: number) => {
|
||||||
|
if (id !== customOrderPages[page].order[index]) {
|
||||||
changed = true;
|
changed = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (changed) {
|
||||||
return Object.assign({}, state, { [url]: Object.assign({}, pageState, { customOrder: Object.assign({}, pageState.customOrder, { newOrder: customOrder, changed: changed }) }) })
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return Object.assign({}, state, { [url]: Object.assign({}, pageState, { customOrder: Object.assign({}, pageState.customOrder, { newOrderPages: customOrderPages, changed: changed }) }) })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a custom order page by providing the list of all pages, a list of UUIDs, pageSize and the page to populate
|
||||||
|
* @param initialPages The initial list of OrderPage objects
|
||||||
|
* @param order The list of UUIDs to create a page for
|
||||||
|
* @param pageSize The pageSize used to populate empty spacer pages
|
||||||
|
* @param page The index of the page to add
|
||||||
|
*/
|
||||||
|
function addOrderToPages(initialPages: OrderPage[], order: string[], pageSize: number, page: number): OrderPage[] {
|
||||||
|
const result = [...initialPages];
|
||||||
|
const orderPage: OrderPage = { order: order };
|
||||||
|
if (page < result.length) {
|
||||||
|
// The page we're trying to add already exists in the list. Overwrite it.
|
||||||
|
result[page] = orderPage;
|
||||||
|
} else if (page === result.length) {
|
||||||
|
// The page we're trying to add is the next page in the list, add it.
|
||||||
|
result.push(orderPage);
|
||||||
|
} else {
|
||||||
|
// The page we're trying to add is at least one page ahead of the list, fill the list with empty pages before adding the page.
|
||||||
|
const emptyOrderPage: OrderPage = { order: [] };
|
||||||
|
emptyOrderPage.order.fill(undefined, 0, pageSize);
|
||||||
|
result.fill(emptyOrderPage, result.length, page - 1);
|
||||||
|
result.push(orderPage);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
@@ -8,11 +8,11 @@ import {
|
|||||||
Identifiable,
|
Identifiable,
|
||||||
OBJECT_UPDATES_TRASH_PATH,
|
OBJECT_UPDATES_TRASH_PATH,
|
||||||
ObjectUpdatesEntry,
|
ObjectUpdatesEntry,
|
||||||
ObjectUpdatesState
|
ObjectUpdatesState, OrderPage
|
||||||
} from './object-updates.reducer';
|
} from './object-updates.reducer';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import {
|
import {
|
||||||
AddFieldUpdateAction,
|
AddFieldUpdateAction, AddPageToCustomOrderAction,
|
||||||
DiscardObjectUpdatesAction,
|
DiscardObjectUpdatesAction,
|
||||||
FieldChangeType,
|
FieldChangeType,
|
||||||
InitializeFieldsAction,
|
InitializeFieldsAction,
|
||||||
@@ -28,6 +28,7 @@ import { INotification } from '../../../shared/notifications/models/notification
|
|||||||
import { Operation } from 'fast-json-patch';
|
import { Operation } from 'fast-json-patch';
|
||||||
import { ArrayMoveChangeAnalyzer } from '../array-move-change-analyzer.service';
|
import { ArrayMoveChangeAnalyzer } from '../array-move-change-analyzer.service';
|
||||||
import { MoveOperation } from 'fast-json-patch/lib/core';
|
import { MoveOperation } from 'fast-json-patch/lib/core';
|
||||||
|
import { flatten } from '@angular/compiler';
|
||||||
|
|
||||||
function objectUpdatesStateSelector(): MemoizedSelector<CoreState, ObjectUpdatesState> {
|
function objectUpdatesStateSelector(): MemoizedSelector<CoreState, ObjectUpdatesState> {
|
||||||
return createSelector(coreSelector, (state: CoreState) => state['cache/object-updates']);
|
return createSelector(coreSelector, (state: CoreState) => state['cache/object-updates']);
|
||||||
@@ -56,10 +57,25 @@ export class ObjectUpdatesService {
|
|||||||
* @param url The page's URL for which the changes are being mapped
|
* @param url The page's URL for which the changes are being mapped
|
||||||
* @param fields The initial fields for the page's object
|
* @param fields The initial fields for the page's object
|
||||||
* @param lastModified The date the object was last modified
|
* @param lastModified The date the object was last modified
|
||||||
* @param addCustomOrder Add a custom order list to track move changes
|
|
||||||
*/
|
*/
|
||||||
initialize(url, fields: Identifiable[], lastModified: Date, addCustomOrder?: boolean): void {
|
initialize(url, fields: Identifiable[], lastModified: Date): void {
|
||||||
this.store.dispatch(new InitializeFieldsAction(url, fields, lastModified, addCustomOrder ? fields.map((field) => field.uuid) : []));
|
this.store.dispatch(new InitializeFieldsAction(url, fields, lastModified));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to dispatch an InitializeFieldsAction to the store and keeping track of the order objects are stored
|
||||||
|
* @param url The page's URL for which the changes are being mapped
|
||||||
|
* @param fields The initial fields for the page's object
|
||||||
|
* @param lastModified The date the object was last modified
|
||||||
|
* @param pageSize The page size to use for adding pages to the custom order
|
||||||
|
* @param page The first page to populate the custom order with
|
||||||
|
*/
|
||||||
|
initializeWithCustomOrder(url, fields: Identifiable[], lastModified: Date, pageSize = 9999, page = 0): void {
|
||||||
|
this.store.dispatch(new InitializeFieldsAction(url, fields, lastModified, fields.map((field) => field.uuid), pageSize, page));
|
||||||
|
}
|
||||||
|
|
||||||
|
addPageToCustomOrder(url, fields: Identifiable[], page: number): void {
|
||||||
|
this.store.dispatch(new AddPageToCustomOrderAction(url, fields, fields.map((field) => field.uuid), page));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -140,13 +156,14 @@ export class ObjectUpdatesService {
|
|||||||
* sorted by their custom order to create a FieldUpdates object
|
* sorted by their custom order to create a FieldUpdates object
|
||||||
* @param url The URL of the page for which the FieldUpdates should be requested
|
* @param url The URL of the page for which the FieldUpdates should be requested
|
||||||
* @param initialFields The initial values of the fields
|
* @param initialFields The initial values of the fields
|
||||||
|
* @param page The page to retrieve
|
||||||
*/
|
*/
|
||||||
getFieldUpdatesByCustomOrder(url: string, initialFields: Identifiable[]): Observable<FieldUpdates> {
|
getFieldUpdatesByCustomOrder(url: string, initialFields: Identifiable[], page = 0): Observable<FieldUpdates> {
|
||||||
const objectUpdates = this.getObjectEntry(url);
|
const objectUpdates = this.getObjectEntry(url);
|
||||||
return objectUpdates.pipe(map((objectEntry) => {
|
return objectUpdates.pipe(map((objectEntry) => {
|
||||||
const fieldUpdates: FieldUpdates = {};
|
const fieldUpdates: FieldUpdates = {};
|
||||||
if (hasValue(objectEntry)) {
|
if (hasValue(objectEntry)) {
|
||||||
for (const uuid of objectEntry.customOrder.newOrder) {
|
for (const uuid of objectEntry.customOrder.newOrderPages[page].order) {
|
||||||
let fieldUpdate = objectEntry.fieldUpdates[uuid];
|
let fieldUpdate = objectEntry.fieldUpdates[uuid];
|
||||||
if (isEmpty(fieldUpdate)) {
|
if (isEmpty(fieldUpdate)) {
|
||||||
const identifiable = initialFields.find((object: Identifiable) => object.uuid === uuid);
|
const identifiable = initialFields.find((object: Identifiable) => object.uuid === uuid);
|
||||||
@@ -233,9 +250,11 @@ export class ObjectUpdatesService {
|
|||||||
* @param url The page's URL for which the changes are saved
|
* @param url The page's URL for which the changes are saved
|
||||||
* @param from The index of the object to move
|
* @param from The index of the object to move
|
||||||
* @param to The index to move the object to
|
* @param to The index to move the object to
|
||||||
|
* @param fromPage The page to move the object from
|
||||||
|
* @param toPage The page to move the object to
|
||||||
*/
|
*/
|
||||||
saveMoveFieldUpdate(url: string, from: number, to: number) {
|
saveMoveFieldUpdate(url: string, from: number, to: number, fromPage = 0, toPage = 0) {
|
||||||
this.store.dispatch(new MoveFieldUpdateAction(url, from, to));
|
this.store.dispatch(new MoveFieldUpdateAction(url, from, to, fromPage, toPage));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -350,7 +369,10 @@ export class ObjectUpdatesService {
|
|||||||
getMoveOperations(url: string): Observable<MoveOperation[]> {
|
getMoveOperations(url: string): Observable<MoveOperation[]> {
|
||||||
return this.getObjectEntry(url).pipe(
|
return this.getObjectEntry(url).pipe(
|
||||||
map((objectEntry) => objectEntry.customOrder),
|
map((objectEntry) => objectEntry.customOrder),
|
||||||
map((customOrder) => this.comparator.diff(customOrder.initialOrder, customOrder.newOrder))
|
map((customOrder) => this.comparator.diff(
|
||||||
|
flatten(customOrder.initialOrderPages.map((orderPage: OrderPage) => orderPage.order)),
|
||||||
|
flatten(customOrder.newOrderPages.map((orderPage: OrderPage) => orderPage.order)))
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,11 @@
|
|||||||
|
<ds-pagination *ngIf="paginatedList"
|
||||||
|
[hideGear]="hideGear"
|
||||||
|
[hidePagerWhenSinglePage]="hidePagerWhenSinglePage"
|
||||||
|
[hidePaginationDetail]="hidePaginationDetail"
|
||||||
|
[paginationOptions]="paginationOptions"
|
||||||
|
[pageInfoState]="paginatedList"
|
||||||
|
[collectionSize]="paginatedList?.totalElements"
|
||||||
|
[disableRouteParameterUpdate]="disableRouteParameterUpdate"
|
||||||
|
(pageChange)="switchPage($event)">
|
||||||
|
<ng-content></ng-content>
|
||||||
|
</ds-pagination>
|
@@ -0,0 +1,55 @@
|
|||||||
|
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||||
|
import { PaginationComponentOptions } from '../pagination/pagination-component-options.model';
|
||||||
|
import { PaginatedList } from '../../core/data/paginated-list';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-pagination-drag-and-drop',
|
||||||
|
templateUrl: './pagination-drag-and-drop.component.html',
|
||||||
|
})
|
||||||
|
export class PaginationDragAndDropComponent {
|
||||||
|
/**
|
||||||
|
* Configuration for the NgbPagination component.
|
||||||
|
*/
|
||||||
|
@Input() paginationOptions: PaginationComponentOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The paginated list being displayed
|
||||||
|
*/
|
||||||
|
@Input() paginatedList: PaginatedList<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Option for hiding the pagination detail
|
||||||
|
*/
|
||||||
|
@Input() public hidePaginationDetail = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Option for hiding the gear
|
||||||
|
*/
|
||||||
|
@Input() public hideGear = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Option for hiding the pager when there is less than 2 pages
|
||||||
|
*/
|
||||||
|
@Input() public hidePagerWhenSinglePage = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Option for disabling updating and reading route parameters on pagination changes
|
||||||
|
* In other words, changing pagination won't add or update the url parameters on the current page, and the url
|
||||||
|
* parameters won't affect the pagination of this component
|
||||||
|
*/
|
||||||
|
@Input() public disableRouteParameterUpdate = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An event fired when the page is changed.
|
||||||
|
* Event's payload equals to the newly selected page.
|
||||||
|
*/
|
||||||
|
@Output() pageChange: EventEmitter<number> = new EventEmitter<number>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Switch to a different page
|
||||||
|
* @param page Page to switch to
|
||||||
|
*/
|
||||||
|
switchPage(page: number) {
|
||||||
|
this.pageChange.emit(page);
|
||||||
|
}
|
||||||
|
}
|
@@ -99,6 +99,13 @@ export class PaginationComponent implements OnDestroy, OnInit {
|
|||||||
*/
|
*/
|
||||||
@Input() public hidePagerWhenSinglePage = true;
|
@Input() public hidePagerWhenSinglePage = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Option for disabling updating and reading route parameters on pagination changes
|
||||||
|
* In other words, changing pagination won't add or update the url parameters on the current page, and the url
|
||||||
|
* parameters won't affect the pagination of this component
|
||||||
|
*/
|
||||||
|
@Input() public disableRouteParameterUpdate = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current page.
|
* Current page.
|
||||||
*/
|
*/
|
||||||
@@ -173,20 +180,35 @@ export class PaginationComponent implements OnDestroy, OnInit {
|
|||||||
this.checkConfig(this.paginationOptions);
|
this.checkConfig(this.paginationOptions);
|
||||||
this.initializeConfig();
|
this.initializeConfig();
|
||||||
// Listen to changes
|
// Listen to changes
|
||||||
|
if (!this.disableRouteParameterUpdate) {
|
||||||
this.subs.push(this.route.queryParams
|
this.subs.push(this.route.queryParams
|
||||||
.subscribe((queryParams) => {
|
.subscribe((queryParams) => {
|
||||||
if (this.isEmptyPaginationParams(queryParams)) {
|
this.initializeParams(queryParams);
|
||||||
this.initializeConfig(queryParams);
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the route and current parameters
|
||||||
|
* This method will fix any invalid or missing parameters
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
private initializeParams(params) {
|
||||||
|
if (this.isEmptyPaginationParams(params)) {
|
||||||
|
this.initializeConfig(params);
|
||||||
} else {
|
} else {
|
||||||
this.currentQueryParams = queryParams;
|
this.currentQueryParams = params;
|
||||||
const fixedProperties = this.validateParams(queryParams);
|
const fixedProperties = this.validateParams(params);
|
||||||
if (isNotEmpty(fixedProperties)) {
|
if (isNotEmpty(fixedProperties)) {
|
||||||
|
if (!this.disableRouteParameterUpdate) {
|
||||||
this.fixRoute(fixedProperties);
|
this.fixRoute(fixedProperties);
|
||||||
|
} else {
|
||||||
|
this.initializeParams(fixedProperties);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.setFields();
|
this.setFields();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fixRoute(fixedProperties) {
|
private fixRoute(fixedProperties) {
|
||||||
@@ -247,7 +269,7 @@ export class PaginationComponent implements OnDestroy, OnInit {
|
|||||||
* The page being navigated to.
|
* The page being navigated to.
|
||||||
*/
|
*/
|
||||||
public doPageChange(page: number) {
|
public doPageChange(page: number) {
|
||||||
this.updateRoute({ pageId: this.id, page: page.toString() });
|
this.updateParams(Object.assign({}, this.currentQueryParams, { pageId: this.id, page: page.toString() }));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -257,7 +279,7 @@ export class PaginationComponent implements OnDestroy, OnInit {
|
|||||||
* The page size being navigated to.
|
* The page size being navigated to.
|
||||||
*/
|
*/
|
||||||
public doPageSizeChange(pageSize: number) {
|
public doPageSizeChange(pageSize: number) {
|
||||||
this.updateRoute({ pageId: this.id, page: 1, pageSize: pageSize });
|
this.updateParams(Object.assign({}, this.currentQueryParams,{ pageId: this.id, page: 1, pageSize: pageSize }));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -267,7 +289,7 @@ export class PaginationComponent implements OnDestroy, OnInit {
|
|||||||
* The sort direction being navigated to.
|
* The sort direction being navigated to.
|
||||||
*/
|
*/
|
||||||
public doSortDirectionChange(sortDirection: SortDirection) {
|
public doSortDirectionChange(sortDirection: SortDirection) {
|
||||||
this.updateRoute({ pageId: this.id, page: 1, sortDirection: sortDirection });
|
this.updateParams(Object.assign({}, this.currentQueryParams,{ pageId: this.id, page: 1, sortDirection: sortDirection }));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -277,7 +299,7 @@ export class PaginationComponent implements OnDestroy, OnInit {
|
|||||||
* The sort field being navigated to.
|
* The sort field being navigated to.
|
||||||
*/
|
*/
|
||||||
public doSortFieldChange(field: string) {
|
public doSortFieldChange(field: string) {
|
||||||
this.updateRoute({ pageId: this.id, page: 1, sortField: field });
|
this.updateParams(Object.assign(this.currentQueryParams,{ pageId: this.id, page: 1, sortField: field }));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -347,6 +369,20 @@ export class PaginationComponent implements OnDestroy, OnInit {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the current query params and optionally update the route
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
private updateParams(params: {}) {
|
||||||
|
if (isNotEmpty(difference(params, this.currentQueryParams))) {
|
||||||
|
if (!this.disableRouteParameterUpdate) {
|
||||||
|
this.updateRoute(params);
|
||||||
|
} else {
|
||||||
|
this.initializeParams(params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to update the route parameters
|
* Method to update the route parameters
|
||||||
*/
|
*/
|
||||||
|
@@ -178,6 +178,7 @@ import { ImportableListItemControlComponent } from './object-collection/shared/i
|
|||||||
import { DragDropModule } from '@angular/cdk/drag-drop';
|
import { DragDropModule } from '@angular/cdk/drag-drop';
|
||||||
import { ExistingMetadataListElementComponent } from './form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component';
|
import { ExistingMetadataListElementComponent } from './form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component';
|
||||||
import { CustomSwitchComponent } from './form/builder/ds-dynamic-form-ui/models/custom-switch/custom-switch.component';
|
import { CustomSwitchComponent } from './form/builder/ds-dynamic-form-ui/models/custom-switch/custom-switch.component';
|
||||||
|
import { PaginationDragAndDropComponent } from './pagination-drag-and-drop/pagination-drag-and-drop.component';
|
||||||
|
|
||||||
const MODULES = [
|
const MODULES = [
|
||||||
// Do NOT include UniversalModule, HttpModule, or JsonpModule here
|
// Do NOT include UniversalModule, HttpModule, or JsonpModule here
|
||||||
@@ -263,6 +264,7 @@ const COMPONENTS = [
|
|||||||
AbstractListableElementComponent,
|
AbstractListableElementComponent,
|
||||||
ObjectCollectionComponent,
|
ObjectCollectionComponent,
|
||||||
PaginationComponent,
|
PaginationComponent,
|
||||||
|
PaginationDragAndDropComponent,
|
||||||
SearchFormComponent,
|
SearchFormComponent,
|
||||||
PageWithSidebarComponent,
|
PageWithSidebarComponent,
|
||||||
SidebarDropdownComponent,
|
SidebarDropdownComponent,
|
||||||
|
Reference in New Issue
Block a user