The pagination issue has been resolved. Now I want to display Filter option beside the search bar which is not currently displaying. Please check the attached screenshot and code
const {
BaseCollection,
BaseDataSource,
} = require(“@forestadmin/datasource-toolkit”);
const Subscriptions = require(“../models/subscriptions”);
class SubscriptionOrders extends BaseCollection {
constructor(dataSource) {
//super(“subscriptionOrders”, dataSource);
super(“subscriptionsOrders”, dataSource, {
capabilities: [“List”, “Count”, “Filter”, “Search”, “Sort”],
});
this.enableCount();
this.enableSearch();
this.addField("id", {
type: "Column",
columnType: "String",
isPrimaryKey: true,
});
this.addField("subscriptionId", { type: "Column", columnType: "String" });
this.addField("customerEmail", { type: "Column", columnType: "String" });
this.addField("deliveryDate", { type: "Column", columnType: "String" });
this.addField("isPlaced", { type: "Column", columnType: "Boolean" });
this.addField("isSkipped", { type: "Column", columnType: "Boolean" });
this.addField("shopifyOrderId", { type: "Column", columnType: "Number" });
this.addField("shopifyOrderNumber", {
type: "Column",
columnType: "String",
});
this.addField("productTitle", { type: "Column", columnType: "String" });
}
async list(caller, filter = {}, projection) {
//console.log(filter, “filter”);
const skip = filter.page?.skip ?? 0;
const limit = filter.page?.limit ?? 15;
const pageNumber = Math.floor(skip / limit) + 1;
const pipeline = [
{ $unwind: { path: "$orders", preserveNullAndEmptyArrays: false } },
{
$project: {
subscriptionId: "$_id",
customerEmail: 1,
productTitle: 1,
deliveryDate: "$orders.deliveryDate",
isPlaced: "$orders.isPlaced",
isSkipped: "$orders.isSkipped",
shopifyOrderId: "$orders.shopifyOrderId",
shopifyOrderNumber: "$orders.shopifyOrderNumber",
},
},
{ $skip: skip },
{ $limit: limit },
];
const results = await Subscriptions.aggregate(pipeline).exec();
const records = results.map((r, idx) => ({
id: `${r.subscriptionId}_${skip + idx}`,
subscriptionId: r.subscriptionId?.toString() || "",
customerEmail: r.customerEmail || "",
//deliveryDate: r.deliveryDate || null,
deliveryDate: r.deliveryDate || "",
isPlaced: !!r.isPlaced,
isSkipped: !!r.isSkipped,
shopifyOrderId: r.shopifyOrderId || null,
shopifyOrderNumber: r.shopifyOrderNumber || "",
productTitle: r.productTitle || "",
}));
//return projection.apply(records);
return projection ? projection.apply(records) : records;
}
async count(caller, filter = {}) {
console.log(“count called with filter:”, filter);
const pipeline = [
{ $unwind: { path: "$orders", preserveNullAndEmptyArrays: false } },
{ $count: "count" },
];
const res = await Subscriptions.aggregate(pipeline).exec();
return res?.[0]?.count ?? 0; // Forest expects just a number
}
async aggregate(caller, filter = {}, aggregation = {}, limit) {
const { operation, fields, groups = } = aggregation || {};
console.log(“aggregate called:”, aggregation);
// Handle COUNT
if (operation === "Count" && groups.length === 0 && !fields) {
const count = await this.count(caller, filter);
console.log(count, "my count result");
//return [{ count }]; // ✅ Forest expects { count: <number> }
return [{ value: count, group: {} }];
}
// Fallback pipeline if needed
const pipeline = [
{ $unwind: { path: "$orders", preserveNullAndEmptyArrays: false } },
{ $count: "count" },
];
const res = await Subscriptions.aggregate(pipeline).exec();
return [{ count: res?.[0]?.count ?? 0 }];
}
}
class SubscriptionOrdersDataSource extends BaseDataSource {
constructor() {
super();
this.addCollection(new SubscriptionOrders(this));
}
}
module.exports = () => new SubscriptionOrdersDataSource();