Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added pagination for user subscriptions #2189

Merged
merged 2 commits into from
Jun 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ export class OperationDetails {

const contentTypeObj = {}
Object.entries(valueObj).forEach(([key, val]) => {
if (typeof val === 'object') return
if (typeof val === "object") return
contentTypeObj[key] = val.toString();
})

Expand Down
14 changes: 13 additions & 1 deletion src/components/users/subscriptions/ko/runtime/subscriptions.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
<div role="columnheader" class="col-1 text-truncate">Action</div>
</div>
</div>
<!-- ko if: working -->
<div class="table-body">
<spinner></spinner>
</div>
<!-- /ko -->
<!-- ko ifnot: working -->
<div role="rowgroup" class="table-body">
<!-- ko if: subscriptions().length === 0 -->
<div role="row" class="table-row">
Expand All @@ -32,7 +38,8 @@

<!-- ko if: $data.isEdit -->
<div class="input-group has-validation">
<input type="text" class="form-control" data-bind="value: editName" aria-required="true" />
<input type="text" class="form-control" data-bind="value: editName"
aria-required="true" />
<span class="invalid-feedback" data-bind="validationMessage: editName"></span>
</div>
<!-- /ko -->
Expand Down Expand Up @@ -145,4 +152,9 @@
<!-- /ko -->
<!-- /ko -->
</div>

<!-- ko if: $component.totalPages() > 1 -->
<pagination params="{ pageNumber: $component.pageNumber, totalPages: $component.totalPages }"></pagination>
<!-- /ko -->
<!-- /ko -->
</div>
47 changes: 38 additions & 9 deletions src/components/users/subscriptions/ko/runtime/subscriptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { EventManager } from "@paperbits/common/events";
import { dispatchErrors, parseAndDispatchError } from "../../../validation-summary/utils";
import { ErrorSources } from "../../../validation-summary/constants";
import { BackendService } from "../../../../../services/backendService";
import { SearchQuery } from "../../../../../contracts/searchQuery";
import * as Constants from "../../../../../constants";

@RuntimeComponent({
selector: "subscriptions-runtime"
Expand All @@ -23,6 +25,10 @@ import { BackendService } from "../../../../../services/backendService";
})
export class Subscriptions {
public readonly subscriptions: ko.ObservableArray<SubscriptionListItem>;
public readonly pageNumber: ko.Observable<number>;
public readonly totalPages: ko.Observable<number>;
public readonly working: ko.Observable<boolean>;
private userId: string;

constructor(
private readonly usersService: UsersService,
Expand All @@ -33,24 +39,47 @@ export class Subscriptions {
private readonly eventManager: EventManager
) {
this.subscriptions = ko.observableArray();
this.pageNumber = ko.observable(1);
this.totalPages = ko.observable(0);
this.working = ko.observable();
}

@OnMounted()
public initialize(): void {
this.loadUser();

this.pageNumber
.subscribe(this.loadSubscriptions.bind(this));
}

private async loadUser(): Promise<void> {
const userId = await this.usersService.ensureSignedIn();

await this.loadSubscriptions(userId);
this.userId = await this.usersService.ensureSignedIn();
await this.loadSubscriptions();
}

private async loadSubscriptions(userId: string): Promise<void> {
const models = await this.productService.getUserSubscriptionsWithProductName(userId);
const subscriptions = models.map(item => new SubscriptionListItem(item, this.eventManager));
private async loadSubscriptions(): Promise<void> {
try {
this.working(true);
const pageNumber = this.pageNumber() - 1;

const query: SearchQuery = {
skip: pageNumber * Constants.defaultPageSize,
take: Constants.defaultPageSize
};

const subscriptionsPage = await this.productService.getUserSubscriptionsWithProductName(this.userId, query);
const subscriptions = subscriptionsPage.value.map(item => new SubscriptionListItem(item, this.eventManager));

this.subscriptions(subscriptions);
const totalItems = subscriptionsPage.count;
this.totalPages(Math.ceil(totalItems / Constants.defaultPageSize));

this.subscriptions(subscriptions);
} catch (error) {
throw new Error(`Unable to load subscriptions. Error: ${error.message}`);
}
finally {
this.working(false);
}
}

public timeToString(date: Date): string {
Expand Down Expand Up @@ -101,7 +130,7 @@ export class Subscriptions {
}

private syncSubscriptionLabelState(subscription: SubscriptionListItem, updatedVM: SubscriptionListItem): void {
if(updatedVM.model.productName === undefined) {
if (updatedVM.model.productName === undefined) {
updatedVM.model.productName = subscription.model.productName;
}

Expand Down Expand Up @@ -144,7 +173,7 @@ export class Subscriptions {
const isDelegationEnabled = await this.tenantService.isSubscriptionDelegationEnabled();
if (isDelegationEnabled) {
const delegationParam = {};
delegationParam[DelegationParameters.SubscriptionId] = Utils.getResourceName("subscriptions", subscriptionId);
delegationParam[DelegationParameters.SubscriptionId] = Utils.getResourceName("subscriptions", subscriptionId);
const delegationUrl = await this.backendService.getDelegationString(DelegationAction.unsubscribe, delegationParam);
if (delegationUrl) {
location.assign(delegationUrl);
Expand Down
2 changes: 1 addition & 1 deletion src/models/console/consoleOperation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export class ConsoleOperation {
}

let requestUrl = this.urlTemplate;
let parameters = this.templateParameters().concat(this.request.queryParameters());
const parameters = this.templateParameters().concat(this.request.queryParameters());

const wildcardName = "{*}"
requestUrl = requestUrl.replace("*", wildcardName);
Expand Down
17 changes: 13 additions & 4 deletions src/services/productService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,25 @@ export class ProductService {
* Returns user subscriptions with product name.
* @param userId {string} User unique identifier.
*/
public async getUserSubscriptionsWithProductName(userId: string): Promise<Subscription[]> {
public async getUserSubscriptionsWithProductName(userId: string, searchRequest?: SearchQuery): Promise<Page<Subscription>> {
if (!userId) {
throw new Error(`Parameter "userId" not specified.`);
}

const skip = searchRequest && searchRequest.skip || 0;
const take = searchRequest && searchRequest.take || Constants.defaultPageSize;
const query = `${userId}/subscriptions?$top=${take}&$skip=${skip}`;

const result = [];
const pageOfSubscriptions = await this.mapiClient.get<Page<SubscriptionContract>>(`${userId}/subscriptions`, [await this.mapiClient.getPortalHeader("getUserSubscriptions")]);
const pageOfSubscriptions = await this.mapiClient.get<Page<SubscriptionContract>>(query, [await this.mapiClient.getPortalHeader("getUserSubscriptions")]);

const page = new Page<Subscription>();
page.count = pageOfSubscriptions.count;
page.nextLink = pageOfSubscriptions.nextLink;
page.value = result;

if (!pageOfSubscriptions?.value) {
return result;
return page;
}

const subscriptions = pageOfSubscriptions.value;
Expand Down Expand Up @@ -159,7 +168,7 @@ export class ProductService {

await Promise.all(promises);

return result;
return page;
}

/**
Expand Down