From 87ea767267fe86b22da9082fc2f6c6b017c391bc Mon Sep 17 00:00:00 2001 From: Paulo Amorim Date: Tue, 22 Oct 2024 14:49:31 -0300 Subject: [PATCH 1/5] add queries and be mock --- jsapp/js/query/queries/activityLogs.query.ts | 67 ++++++++++++++++++++ jsapp/js/query/queryKeys.ts | 1 + 2 files changed, 68 insertions(+) diff --git a/jsapp/js/query/queries/activityLogs.query.ts b/jsapp/js/query/queries/activityLogs.query.ts index c71561527f..386eb1bbac 100644 --- a/jsapp/js/query/queries/activityLogs.query.ts +++ b/jsapp/js/query/queries/activityLogs.query.ts @@ -12,6 +12,10 @@ export interface ActivityLogsItem { date: string; } +export interface ExportStatus { + status: 'in_progress' | 'done' | 'not_started'; +} + // MOCK DATA GENERATION const mockOptions: KoboSelectOption[] = [ {value: '1', label: 'Option 1'}, @@ -39,6 +43,16 @@ const mockData: ActivityLogsItem[] = Array.from({length: 150}, (_, index) => { date: moment(curDate).format('YYYY-MM-DD HH:mm:ss'), }; }); + +const exportData: { + startTime?: number; + endTime?: number; + data?: ActivityLogsItem[]; +} = { + startTime: undefined, + endTime: undefined, + data: undefined, +}; // END OF MOCK GENERATION /** @@ -70,6 +84,40 @@ const getFilterOptions = async () => setTimeout(() => resolve(mockOptions), 1000); }); +/** + * Starts the exporting process of the activity logs. + * @returns {Promise} The promise that starts the export + */ +const startActivityLogsExport = async () => { + // Simulates backend export process. + // Here we just start it and get a feedback if it's done. + exportData.startTime = Date.now(); + exportData.endTime = undefined; + exportData.data = undefined; + setTimeout(() => { + exportData.endTime = Date.now(); + exportData.data = mockData; + }, 10000); +}; + +/** + * Fetches the export status of the activity logs. + * @returns {Promise} The export status + */ +const getExportStatus = async (): Promise => { + // Simulates backend export process. + // Here we just start it and get a feedback if it's done. + if (exportData.startTime && !exportData.endTime) { + return {status: 'in_progress'}; + } + + if (exportData.startTime && exportData.endTime) { + return {status: 'done'}; + } + + return {status: 'not_started'}; +}; + /** * * This is a hook that fetches activity logs from the server. @@ -94,3 +142,22 @@ export const useActivityLogsFilterOptionsQuery = () => queryKey: [QueryKeys.activityLogsFilter], queryFn: () => getFilterOptions(), }); + +/** + * This is a hook to fetch the export status of the activity logs. + * @returns {UseQueryResult} The react query result + */ +export const useExportStatusQuery = (isInProgress: boolean) => + useQuery({ + queryKey: [QueryKeys.activityLogsExportStatus], + queryFn: getExportStatus, + refetchInterval: 2500, + enabled: isInProgress, + }); + +/** + * This is a hook to start the exporting process of the activity logs. + * To follow up the export status, use the {@link useExportStatusQuery} hook. + * @returns {() => void} The function to start the export + */ +export const useExportActivityLogs = () => startActivityLogsExport; diff --git a/jsapp/js/query/queryKeys.ts b/jsapp/js/query/queryKeys.ts index 62be7732a6..1f1ffbe306 100644 --- a/jsapp/js/query/queryKeys.ts +++ b/jsapp/js/query/queryKeys.ts @@ -7,5 +7,6 @@ export enum QueryKeys { accessLogs = 'accessLogs', activityLogs = 'activityLogs', + activityLogsExportStatus = 'activityLogsExportStatus', activityLogsFilter = 'activityLogsFilter', } From e51f67583748dc9f1f0b37236206b5ace0ea70f0 Mon Sep 17 00:00:00 2001 From: Paulo Amorim Date: Wed, 23 Oct 2024 17:59:31 -0300 Subject: [PATCH 2/5] Fix export button behavior --- jsapp/js/components/activity/formActivity.tsx | 12 ++-- .../exportButton/exportButton.component.tsx | 61 +++++++++++++++++++ jsapp/js/query/queries/activityLogs.query.ts | 57 ++++------------- 3 files changed, 77 insertions(+), 53 deletions(-) create mode 100644 jsapp/js/components/exportButton/exportButton.component.tsx diff --git a/jsapp/js/components/activity/formActivity.tsx b/jsapp/js/components/activity/formActivity.tsx index f55ae3454a..282c7317df 100644 --- a/jsapp/js/components/activity/formActivity.tsx +++ b/jsapp/js/components/activity/formActivity.tsx @@ -4,17 +4,18 @@ import '../../../scss/components/_kobo.form-view.scss'; import type {KoboSelectOption} from '../common/koboSelect'; import KoboSelect from '../common/koboSelect'; import type {UniversalTableColumn} from 'jsapp/js/universalTable/universalTable.component'; -import Button from '../common/button'; import PaginatedQueryUniversalTable from 'jsapp/js/universalTable/paginatedQueryUniversalTable.component'; import type {ActivityLogsItem} from 'jsapp/js/query/queries/activityLogs.query'; import { useActivityLogsFilterOptionsQuery, useActivityLogsQuery, + useExportActivityLogs, } from 'jsapp/js/query/queries/activityLogs.query'; import styles from './formActivity.module.scss'; import cx from 'classnames'; import {formatTime} from 'jsapp/js/utils'; import Avatar from '../common/avatar'; +import ExportButton from '../exportButton/exportButton.component'; const EventDescription = ({ who, @@ -56,6 +57,8 @@ export default function FormActivity() { const [selectedFilterOption, setSelectedFilterOption] = useState(null); + const exportData = useExportActivityLogs(); + const handleFilterChange = (value: string | null) => { setSelectedFilterOption( filterOptions?.find((option) => option.value === value) || null @@ -78,12 +81,7 @@ export default function FormActivity() { placeholder={t('Filter by')} options={filterOptions || []} /> -