From 87562120596cf491afb56e0ec933b735d29dfd0a Mon Sep 17 00:00:00 2001 From: Carlos Date: Wed, 26 Jul 2023 01:02:50 -0500 Subject: [PATCH 1/4] remake exporting to csv filters fetch --- src/server/adminJs/adminJs-types.ts | 3 +- src/server/adminJs/adminJs.ts | 50 ++++++++++---------------- src/server/adminJs/tabs/donationTab.ts | 14 +++++--- src/server/adminJs/tabs/projectsTab.ts | 10 +++--- src/server/bootstrap.ts | 7 +--- 5 files changed, 35 insertions(+), 49 deletions(-) diff --git a/src/server/adminJs/adminJs-types.ts b/src/server/adminJs/adminJs-types.ts index b616d6e93..2d99a0eb1 100644 --- a/src/server/adminJs/adminJs-types.ts +++ b/src/server/adminJs/adminJs-types.ts @@ -28,10 +28,11 @@ export interface AdminJsProjectsQuery { verified?: string; // listed?: string; isImported?: string; - reviewStatus: ReviewStatus; + reviewStatus?: ReviewStatus; } export interface AdminJsDonationsQuery { + id?: string; projectId?: string; contactEmail?: string; referrerWallet?: string; diff --git a/src/server/adminJs/adminJs.ts b/src/server/adminJs/adminJs.ts index 77a5b182c..7e5cac197 100644 --- a/src/server/adminJs/adminJs.ts +++ b/src/server/adminJs/adminJs.ts @@ -1,4 +1,4 @@ -import adminJs, { AdminJSOptions } from 'adminjs'; +import adminJs, { ActionContext, AdminJSOptions } from 'adminjs'; import { User } from '../../entities/user'; import adminJsExpress from '@adminjs/express'; import config from '../../config'; @@ -72,37 +72,25 @@ export const getAdminJsRouter = async () => { ); }; -// Express Middleware to save query of a search -export const adminJsQueryCache = async (req, res, next) => { - if ( - req.url.startsWith('/admin/api/resources/') && - req.headers.cookie.includes('adminbro') - ) { - const admin = await getCurrentAdminJsSession(req); - if (!admin) return next(); // skip saving queries - - const matches = req.url.match(/\/admin\/api\/resources\/(.+?)(\/|$)/); - if (!matches) return next(); // invalid URL - - const resourceName = matches[1]; - const queryStrings = {}; - - // Extract filter names and values from URL query string parameters - for (const key of Object.keys(req.query)) { - const [_, filter] = key.split('.'); - if (!filter) continue; - - queryStrings[filter] = req.query[key]; - } - // Save query strings to Redis hash with an expiration - await redis.hset( - `adminbro:${admin.id}:${resourceName}`, - queryStrings, - 'ex', - 1800, - ); +// Extract Referrer Header Parameter Filter Params +export const extractAdminJsReferrerUrlParams = (req: ActionContext) => { + const queryStrings = {}; + + const refererUrlHeaderIndex = req.rawHeaders.indexOf('Referer'); + if (refererUrlHeaderIndex < 0) return {}; + + const refererUrl = new URL(req.rawHeaders[refererUrlHeaderIndex + 1]); + const searchParams = refererUrl.searchParams; + + // Extract filter names and values from URL query string parameters + for (const [key, value] of searchParams.entries()) { + const [_, filter] = key.split('.'); + if (!filter) continue; + + queryStrings[filter] = value; } - next(); + + return queryStrings; }; // Get CurrentSession for external express middlewares diff --git a/src/server/adminJs/tabs/donationTab.ts b/src/server/adminJs/tabs/donationTab.ts index 41c7a8689..94b355702 100644 --- a/src/server/adminJs/tabs/donationTab.ts +++ b/src/server/adminJs/tabs/donationTab.ts @@ -40,6 +40,8 @@ import { addDonationsSheetToSpreadsheet, } from '../../../services/googleSheets'; import { SelectQueryBuilder } from 'typeorm'; +import { ActionContext } from 'adminjs'; +import { extractAdminJsReferrerUrlParams } from '../adminJs'; export const createDonation = async ( request: AdminJsRequestInterface, @@ -186,6 +188,11 @@ export const buildDonationsQuery = ( .where('donation.amount > 0') .addOrderBy('donation.createdAt', 'DESC'); + if (queryStrings.id) + query.andWhere('donation.id = :id', { + id: queryStrings.id, + }); + if (queryStrings.projectId) query.andWhere('donation.projectId = :projectId', { projectId: queryStrings.projectId, @@ -250,16 +257,13 @@ export const buildDonationsQuery = ( }; export const exportDonationsWithFiltersToCsv = async ( - _request: AdminJsRequestInterface, + _request: ActionContext, _response, context: AdminJsContextInterface, ) => { try { const { records } = context; - const rawQueryStrings = await redis.get( - `adminbro:${context.currentAdmin.id}:Donation`, - ); - const queryStrings = rawQueryStrings ? JSON.parse(rawQueryStrings) : {}; + const queryStrings = extractAdminJsReferrerUrlParams(_request); const projectsQuery = buildDonationsQuery(queryStrings); const projects = await projectsQuery.getMany(); diff --git a/src/server/adminJs/tabs/projectsTab.ts b/src/server/adminJs/tabs/projectsTab.ts index 531f5ad2e..bfd3eb75f 100644 --- a/src/server/adminJs/tabs/projectsTab.ts +++ b/src/server/adminJs/tabs/projectsTab.ts @@ -5,7 +5,7 @@ import { ReviewStatus, RevokeSteps, } from '../../../entities/project'; -import adminJs from 'adminjs'; +import adminJs, { ActionContext } from 'adminjs'; import { canAccessProjectAction, canAccessQfRoundAction, @@ -62,6 +62,7 @@ import { refreshProjectDonationSummaryView, refreshProjectEstimatedMatchingView, } from '../../../services/projectViewsService'; +import { extractAdminJsReferrerUrlParams } from '../adminJs'; // add queries depending on which filters were selected export const buildProjectsQuery = ( @@ -605,16 +606,13 @@ export const listDelist = async ( }; export const exportProjectsWithFiltersToCsv = async ( - _request: AdminJsRequestInterface, + _request: ActionContext, _response, context: AdminJsContextInterface, ) => { try { const { records } = context; - const rawQueryStrings = await redis.get( - `adminbro:${context.currentAdmin.id}:Project`, - ); - const queryStrings = rawQueryStrings ? JSON.parse(rawQueryStrings) : {}; + const queryStrings = extractAdminJsReferrerUrlParams(_request); const projectsQuery = buildProjectsQuery(queryStrings); const projects = await projectsQuery.getMany(); diff --git a/src/server/bootstrap.ts b/src/server/bootstrap.ts index c9c7f6a14..e3d9bd50a 100644 --- a/src/server/bootstrap.ts +++ b/src/server/bootstrap.ts @@ -22,11 +22,7 @@ import { runCheckPendingProjectListingCronJob } from '../services/cronJobs/syncP import { runCheckProjectVerificationStatus } from '../services/cronJobs/checkProjectVerificationStatus'; import { webhookHandler } from '../services/transak/webhookHandler'; -import { - adminJsQueryCache, - adminJsRootPath, - getAdminJsRouter, -} from './adminJs/adminJs'; +import { adminJsRootPath, getAdminJsRouter } from './adminJs/adminJs'; import { redis } from '../redis'; import { logger } from '../utils/logger'; import { runNotifyMissingDonationsCronJob } from '../services/cronJobs/notifyDonationsWithSegment'; @@ -337,7 +333,6 @@ export async function bootstrap() { ); // AdminJs! - app.use(adminJsQueryCache); app.use(adminJsRootPath, await getAdminJsRouter()); if (!isTestEnv) { From 683833ede5796b02413be238bf1bf6a768cd468c Mon Sep 17 00:00:00 2001 From: Carlos Date: Wed, 26 Jul 2023 01:23:54 -0500 Subject: [PATCH 2/4] fix projectsTab adminjs test --- src/server/adminJs/tabs/projectsTab.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/adminJs/tabs/projectsTab.ts b/src/server/adminJs/tabs/projectsTab.ts index bfd3eb75f..988f97405 100644 --- a/src/server/adminJs/tabs/projectsTab.ts +++ b/src/server/adminJs/tabs/projectsTab.ts @@ -606,7 +606,7 @@ export const listDelist = async ( }; export const exportProjectsWithFiltersToCsv = async ( - _request: ActionContext, + _request, _response, context: AdminJsContextInterface, ) => { From f24b7b2c44827a746943d0df8251605b8c0300cc Mon Sep 17 00:00:00 2001 From: Carlos Date: Wed, 26 Jul 2023 02:19:34 -0500 Subject: [PATCH 3/4] add qfround attributes to donation export --- src/server/adminJs/adminJs-types.ts | 3 +++ src/server/adminJs/adminJs.ts | 4 ++-- src/server/adminJs/tabs/donationTab.ts | 29 +++++++++++++++++++++++++- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/server/adminJs/adminJs-types.ts b/src/server/adminJs/adminJs-types.ts index 2d99a0eb1..254890507 100644 --- a/src/server/adminJs/adminJs-types.ts +++ b/src/server/adminJs/adminJs-types.ts @@ -44,6 +44,7 @@ export interface AdminJsDonationsQuery { currency?: string; transactionNetworkId?: string; isProjectVerified?: string; + qfRoundId?: string; } // headers defined by the verification team for exporting @@ -95,4 +96,6 @@ export const donationHeaders = [ 'createdAt', 'referrerWallet', 'isTokenEligibleForGivback', + 'qfRoundId', + 'qfRoundUserScore', ]; diff --git a/src/server/adminJs/adminJs.ts b/src/server/adminJs/adminJs.ts index 7e5cac197..c47e51fa3 100644 --- a/src/server/adminJs/adminJs.ts +++ b/src/server/adminJs/adminJs.ts @@ -76,8 +76,8 @@ export const getAdminJsRouter = async () => { export const extractAdminJsReferrerUrlParams = (req: ActionContext) => { const queryStrings = {}; - const refererUrlHeaderIndex = req.rawHeaders.indexOf('Referer'); - if (refererUrlHeaderIndex < 0) return {}; + const refererUrlHeaderIndex = req?.rawHeaders?.indexOf('Referer'); + if (!refererUrlHeaderIndex || refererUrlHeaderIndex < 0) return {}; const refererUrl = new URL(req.rawHeaders[refererUrlHeaderIndex + 1]); const searchParams = refererUrl.searchParams; diff --git a/src/server/adminJs/tabs/donationTab.ts b/src/server/adminJs/tabs/donationTab.ts index 94b355702..e7e5af86c 100644 --- a/src/server/adminJs/tabs/donationTab.ts +++ b/src/server/adminJs/tabs/donationTab.ts @@ -185,6 +185,7 @@ export const buildDonationsQuery = ( const query = Donation.createQueryBuilder('donation') .leftJoinAndSelect('donation.user', 'user') .leftJoinAndSelect('donation.project', 'project') + .leftJoinAndSelect('donation.qfRound', 'qfRound') .where('donation.amount > 0') .addOrderBy('donation.createdAt', 'DESC'); @@ -198,6 +199,11 @@ export const buildDonationsQuery = ( projectId: queryStrings.projectId, }); + if (queryStrings.qfRoundId) + query.andWhere('donation.qfRoundId = :qfRoundId', { + qfRoundId: queryStrings.qfRoundId, + }); + if (queryStrings.userId) query.andWhere('donation.userId = :userId', { userId: queryStrings.userId, @@ -320,6 +326,8 @@ const sendDonationsToGoogleSheet = async ( createdAt: donation?.createdAt.toISOString(), referrerWallet: donation?.referrerWallet || '', isTokenEligibleForGivback: Boolean(donation?.isTokenEligibleForGivback), + qfRoundId: donation?.qfRound?.id || '', + qfRoundUserScore: donation?.qfRoundUserScore || '', }; }); @@ -343,6 +351,16 @@ export const donationTab = { new: false, }, }, + qfRoundId: { + type: Number, + isVisible: { + list: false, + filter: true, + show: true, + edit: false, + new: false, + }, + }, nonce: { isVisible: false, }, @@ -452,6 +470,15 @@ export const donationTab = { new: false, }, }, + qfRoundUserScore: { + isVisible: { + list: false, + filter: false, + show: true, + edit: false, + new: false, + }, + }, tokenAddress: { isVisible: false, }, @@ -466,7 +493,7 @@ export const donationTab = { }, toWalletAddress: { isVisible: { - list: true, + list: false, filter: true, show: true, edit: false, From 86c3bcb398b9131bfede3852b79699036a03722c Mon Sep 17 00:00:00 2001 From: Carlos Date: Thu, 27 Jul 2023 10:50:57 -0500 Subject: [PATCH 4/4] 1.15.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 60928184f..def684091 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "giveth-graphql-api", - "version": "1.15.1", + "version": "1.15.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "giveth-graphql-api", - "version": "1.15.1", + "version": "1.15.2", "hasInstallScript": true, "license": "ISC", "dependencies": { diff --git a/package.json b/package.json index c407ea079..8c67ecea5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "giveth-graphql-api", - "version": "1.15.1", + "version": "1.15.2", "description": "Backend GraphQL server for Giveth originally forked from Topia", "main": "./dist/index.js", "dependencies": {