diff --git a/src/pages/pegase/home/components/StudiesPagination.tsx b/src/pages/pegase/home/components/StudiesPagination.tsx
index 91938ca..750dfe3 100644
--- a/src/pages/pegase/home/components/StudiesPagination.tsx
+++ b/src/pages/pegase/home/components/StudiesPagination.tsx
@@ -12,7 +12,7 @@ type StudiesPaginationProps = StdTablePaginationProps;
const StudiesPagination = ({ count, intervalSize, current, onChange }: StudiesPaginationProps) => {
return (
-
+
);
diff --git a/src/pages/pegase/home/components/StudyTableDisplay.tsx b/src/pages/pegase/home/components/StudyTableDisplay.tsx
index cf7e054..29c1419 100644
--- a/src/pages/pegase/home/components/StudyTableDisplay.tsx
+++ b/src/pages/pegase/home/components/StudyTableDisplay.tsx
@@ -3,155 +3,107 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
-import StdAvatar from '@/components/common/layout/stdAvatar/StdAvatar';
import StdSimpleTable from '@/components/common/data/stdSimpleTable/StdSimpleTable';
-import { createColumnHelper } from '@tanstack/react-table';
import { useState } from 'react';
-import { useTranslation } from 'react-i18next';
import { StudyDTO } from '@/shared/types/index';
-import { StdIconId } from '@/shared/utils/common/mappings/iconMaps';
-import StdIcon from '@common/base/stdIcon/StdIcon';
+import getStudyTableHeaders from './StudyTableHeaders';
+import { addSortColumn } from './StudyTableUtils';
import StudiesPagination from './StudiesPagination';
-import StdTagList from '@common/base/StdTagList/StdTagList';
-import StdRadioButton from '@/components/common/forms/stdRadioButton/StdRadioButton';
+import { RowSelectionState } from '@tanstack/react-table';
+import StdButton from '@/components/common/base/stdButton/StdButton';
+import { StudyStatus } from '@/shared/types/common/StudyStatus.type';
import { useStudyTableDisplay } from './useStudyTableDisplay';
-const columnHelper = createColumnHelper
();
-
interface StudyTableDisplayProps {
searchStudy: string | undefined;
projectId?: string;
}
const StudyTableDisplay = ({ searchStudy, projectId }: StudyTableDisplayProps) => {
- const { t } = useTranslation();
- const [sortBy, setSortBy] = useState<{ [key: string]: 'asc' | 'desc' }>({});
+ const [sortByState, setSortByState] = useState<{ [key: string]: 'asc' | 'desc' }>({});
+ const [rowSelection, setRowSelection] = useState({});
+ const [sortedColumn, setSortedColumn] = useState('status');
+ const [isHeaderHovered, setIsHeaderHovered] = useState(false);
const handleSort = (column: string) => {
- const newSortOrder = sortBy[column] === 'asc' ? 'desc' : 'asc';
- setSortBy({ [column]: newSortOrder });
+ const newSortOrder = sortByState[column] === 'asc' ? 'desc' : 'asc';
+ setSortByState({ [column]: newSortOrder });
setSortedColumn(column);
};
- const [sortedColumn, setSortedColumn] = useState('status');
+ const handleHeaderHover = (hovered: boolean) => {
+ setIsHeaderHovered(hovered);
+ };
- const headers = [
- columnHelper.display({
- id: 'radioColumn',
- header: ({ table }) => (
- table.toggleAllRowsSelected()}
- name="headerRadio"
- />
- ),
- cell: ({ row }) => (
- e.stopPropagation()}
- className={`${row.getIsSelected() ? 'block' : 'hidden group-hover:block'}`}
- >
-
-
- ),
- }),
+ const headers = getStudyTableHeaders();
+ console.log('Original Headers:', headers);
- columnHelper.accessor('name', {
- header: t('home.@study_name'),
- cell: ({ getValue, row }) => {
- const status = row.original.status;
- const textClass = status === 'GENERATED' ? 'text-primary-900' : 'group-hover:text-green-500';
+ const sortedHeaders = addSortColumn(
+ headers,
+ handleSort,
+ sortByState,
+ sortedColumn,
+ handleHeaderHover,
+ isHeaderHovered,
+ );
- return {getValue()};
- },
- }),
+ console.log('Sorted Headers:', sortedHeaders);
- columnHelper.accessor('createdBy', {
- header: t('home.@user_name'),
- cell: ({ getValue }: { getValue: () => string }) => (
-
- ),
- }),
- columnHelper.accessor('project', { header: t('home.@project') }),
- columnHelper.accessor('status', { header: t('home.@status') }),
- columnHelper.accessor('horizon', { header: t('home.@horizon') }),
- columnHelper.accessor('keywords', {
- header: 'keywords',
- minSize: 500,
- size: 500,
- cell: ({ getValue, row }) => (
-
-
-
- ),
- }),
- columnHelper.accessor('creationDate', { header: t('home.@creation_date') }),
- ];
+ const { rows, count, intervalSize, current, setPage } = useStudyTableDisplay({
+ searchStudy,
+ projectId,
+ sortBy: sortByState,
+ });
- const [isHeaderHovered, setIsHeaderHovered] = useState(false);
+ const selectedRowId = Object.keys(rowSelection)[0];
- const handleHeaderHover = (hovered: boolean) => {
- setIsHeaderHovered(hovered);
- };
+ const selectedStatus = rows[Number.parseInt(selectedRowId || '-1')]?.status?.toUpperCase();
- function addSortColumn(headers: any[]) {
- return headers.map((column) => {
- const isSortable = column.accessorKey !== 'keywords' && column.id !== 'radioColumn';
- return {
- ...column,
- header: (
- isSortable && handleHeaderHover(true)}
- onMouseLeave={() => isSortable && handleHeaderHover(false)}
- onClick={() => {
- if (isSortable) {
- handleHeaderHover(false);
- handleSort(column.accessorKey as string);
- }
- }}
- >
-
{column.header}
- {isSortable && (
-
- {sortBy[column.accessorKey as string] && sortedColumn === column.accessorKey ? (
- sortBy[column.accessorKey as string] === 'asc' ? (
-
-
-
- ) : (
-
-
-
- )
- ) : (
-
-
-
- )}
-
- )}
-
- ),
- };
- });
- }
- const { rows, count, intervalSize, current, setPage } = useStudyTableDisplay({ searchStudy, projectId, sortBy });
+ const isDuplicateActive = selectedStatus === StudyStatus.GENERATED;
+ const isDeleteActive = selectedStatus === StudyStatus.ERROR || selectedStatus === StudyStatus.IN_PROGRESS;
return (
-
+ RowSelectionState),
+ ) => {
+ if (typeof updaterOrValue === 'function') {
+ setRowSelection((prev: RowSelectionState) => updaterOrValue(prev));
+ } else {
+ setRowSelection(updaterOrValue);
+ }
+ }}
+ />
-
+
+
+ {selectedRowId !== undefined ? (
+ <>
+ console.log('duplicate')}
+ variant="outlined"
+ disabled={!isDuplicateActive}
+ />
+ console.log('Delete')}
+ variant="outlined"
+ color="danger"
+ disabled={!isDeleteActive}
+ />
+ >
+ ) : (
+ console.log('NewStudy')} />
+ )}
+
diff --git a/src/pages/pegase/home/components/StudyTableHeaders.tsx b/src/pages/pegase/home/components/StudyTableHeaders.tsx
new file mode 100644
index 0000000..69c0db3
--- /dev/null
+++ b/src/pages/pegase/home/components/StudyTableHeaders.tsx
@@ -0,0 +1,81 @@
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+import StdTagList from '@/components/common/base/StdTagList/StdTagList';
+import StdRadioButton from '@/components/common/forms/stdRadioButton/StdRadioButton';
+import StdAvatar from '@/components/common/layout/stdAvatar/StdAvatar';
+import { StudyStatus } from '@/shared/types/common/StudyStatus.type';
+import { StudyDTO } from '@/shared/types/pegase/study';
+import { createColumnHelper } from '@tanstack/react-table';
+import { useTranslation } from 'react-i18next';
+
+const columnHelper = createColumnHelper
();
+
+const getStudyTableHeaders = () => {
+ const { t } = useTranslation();
+ return [
+ columnHelper.display({
+ id: 'radioColumn',
+ header: () => <>>,
+ cell: ({ row }) => (
+
+
+
+ ),
+ }),
+
+ columnHelper.accessor('name', {
+ header: t('home.@study_name'),
+ cell: ({ getValue, row }) => {
+ const status = row.original.status;
+ const textClass = status === StudyStatus.GENERATED ? 'text-primary-900' : 'group-hover:text-green-500';
+ return {getValue()};
+ },
+ }),
+
+ columnHelper.accessor('createdBy', {
+ header: t('home.@user_name'),
+ cell: ({ getValue }) => (
+
+ ),
+ }),
+
+ columnHelper.accessor('project', {
+ header: t('home.@project'),
+ }),
+
+ columnHelper.accessor('status', {
+ header: t('home.@status'),
+ }),
+
+ columnHelper.accessor('horizon', {
+ header: t('home.@horizon'),
+ }),
+
+ columnHelper.accessor('keywords', {
+ header: t('home.@keywords'),
+ minSize: 500,
+ size: 500,
+ cell: ({ getValue, row }) => (
+
+
+
+ ),
+ }),
+
+ columnHelper.accessor('creationDate', {
+ header: t('home.@creation_date'),
+ }),
+ ];
+};
+
+export default getStudyTableHeaders;
diff --git a/src/pages/pegase/home/components/StudyTableUtils.tsx b/src/pages/pegase/home/components/StudyTableUtils.tsx
new file mode 100644
index 0000000..928f6d9
--- /dev/null
+++ b/src/pages/pegase/home/components/StudyTableUtils.tsx
@@ -0,0 +1,62 @@
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+import StdIcon from '@/components/common/base/stdIcon/StdIcon';
+import { StdIconId } from '@/shared/utils/common/mappings/iconMaps';
+
+export function addSortColumn(
+ headers: any[],
+ handleSort: (column: string) => void,
+ sortBy: { [key: string]: 'asc' | 'desc' },
+ sortedColumn: string | null,
+ handleHeaderHover: (hovered: boolean) => void,
+ isHeaderHovered: boolean,
+) {
+ return headers.map((column) => {
+ const isSortable = column.accessorKey !== 'keywords' && column.id !== 'radioColumn';
+ return {
+ ...column,
+ header: (
+ isSortable && handleHeaderHover(true)}
+ onMouseLeave={() => isSortable && handleHeaderHover(false)}
+ onClick={() => {
+ if (isSortable) {
+ handleHeaderHover(false);
+ handleSort(column.accessorKey as string);
+ }
+ }}
+ >
+
{column.header}
+ {isSortable && (
+
+ {sortBy[column.accessorKey as string] && sortedColumn === column.accessorKey ? (
+ sortBy[column.accessorKey as string] === 'asc' ? (
+
+
+
+ ) : (
+
+
+
+ )
+ ) : (
+
+
+
+ )}
+
+ )}
+
+ ),
+ };
+ });
+}
diff --git a/src/shared/types/common/StudyStatus.type.ts b/src/shared/types/common/StudyStatus.type.ts
new file mode 100644
index 0000000..09d7d6d
--- /dev/null
+++ b/src/shared/types/common/StudyStatus.type.ts
@@ -0,0 +1,13 @@
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+export enum StudyStatus {
+ IN_PROGRESS = 'IN_PROGRESS',
+ GENERATED = 'GENERATED',
+ ERROR = 'ERROR',
+ CLOSED = 'CLOSED',
+ DELETED = 'DELETED',
+}
diff --git a/vite.config.js b/vite.config.js
index 3160a3f..e7a3899 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -32,6 +32,11 @@ export default defineConfig({
globals: true,
environment: 'jsdom',
setupFiles: './src/testSetup.ts',
+ coverage: {
+ provider: 'v8',
+ reporter: ['lcov', 'text'],
+ exclude: ['src/*.test.ts', 'src/shared/**', 'src/components/common/**'],
+ },
},
server: {
port: DEFAULT_PORT,