diff --git a/frontend/src/components/QueryTable.tsx b/frontend/src/components/QueryTable.tsx index 3b5a261f..876e508d 100644 --- a/frontend/src/components/QueryTable.tsx +++ b/frontend/src/components/QueryTable.tsx @@ -3,7 +3,6 @@ import React, { useState, createContext, useContext } from 'react' import { useIndex } from '../modules/engine' import { Link } from "react-router-dom" import LoadingMessage from './LoadingMessage' -//import Card from './Card' import { Card } from 'react-bootstrap' import {formatDate} from '../modules/dates' @@ -36,7 +35,7 @@ export function useQuery() { return useContext(QueryTableContext) } -export default function QueryTable({ sort, direction, children }:{ +export function QueryTableCard({ sort, direction, children }:{ sort: string, direction?: number, children?: any, @@ -55,22 +54,65 @@ export default function QueryTable({ sort, direction, children }:{ } -export function QueryTableHeaders({ children }) { +export function QueryTableBar({ children }) { return
{children}
} -export function QueryTableBody({ path, headers, getField}:{ +export function QueryTable({ path, headers, getField}:{ path: string, headers: IQueryTableHeader[], getField?: (item: any, field: string) => JSX.Element | string, children?: any, }) { return
- path={path} headers={headers} getField={getField}/> + path={path} headers={headers} getField={getField}> + + + + { headers.map( ({ field, label, enable_sort }) => + + {enable_sort + ? + : label} + + )} + + + +
+ + function renderCells(item) { + return <> + {headers.map(({ field, enable_link }) => + { render(item, field, enable_link) } + )} + + } + + function render(item, field, enable_link) { + const content = getField ? getField(item, field) : defaultGetField(item, field) + if (enable_link) { + return { content } + } else { + return content; + } + } + +} + +export function defaultGetField(item, field:string) { + let value = item + const segments:string[] = field.split('.') + segments.forEach(f => {value = value[f]}) + const last = segments[segments.length - 1] + if (["date_submitted", "date_modified", "date_managed"] + .includes(last)) return formatDate(value) + if (last === 'state') return + return value } export function FilterBadges() { @@ -101,10 +143,33 @@ export function FilterBadges() { } -function Table({ path, headers, getField }: { +const ItemsContext = createContext<{ + items: any[], + selectedIds: string[], + setSelectedIds: React.Dispatch>, +}>({ + items: [], + selectedIds: [], + setSelectedIds: () => {} +}) + +export function useItems() { + return useContext(ItemsContext).items as T[] +} + +export function useSelectedIds() { + return useContext(ItemsContext).selectedIds +} + +export function useSetSelectedIds() { + return useContext(ItemsContext).setSelectedIds +} + +function TableItems({ path, children }: { path:string, headers: IQueryTableHeader[], getField?: (item: any, field: string) => JSX.Element | string, + children?: any, }) { const ctx = useQuery() if (!ctx) return null @@ -118,27 +183,10 @@ function Table({ path, headers, getField }: { const data = indexQuery.data const items = data.items - return <> + return {items.length}/{data.total} elementi mostrati - - - - { headers.map( ({ field, label, enable_sort }) => - - )} - - - + { children }
-
-

{ items.length < data.total @@ -148,9 +196,32 @@ function Table({ path, headers, getField }: { : null }

- +
+ + function increaseLimit(d) { + setQuery(q => { + return {...q, + _limit: q._limit + d + } + }) + } +} + +function SortHeader({ field, label }) { + const { query, setQuery } = useQuery() || {} + + if (query && setQuery) { + return toggleSort(field, setQuery)}> + { label } { + (query._sort === field) + ? (query._direction > 0 ? <>↓ : <>↑) + : ""} + + } else { + return label; + } - function toggleSort(field) { + function toggleSort(field, setQuery) { setQuery(q => { if (q._sort == field) { return { @@ -166,37 +237,14 @@ function Table({ path, headers, getField }: { } }) } +} - function increaseLimit(d) { - setQuery(q => { - return {...q, - _limit: q._limit + d - } - }) - } - - function Header({ field, label, enable_sort }) { - if (enable_sort) { - return toggleSort(field)}> - { label } { - (query._sort === field) - ? (query._direction > 0 ? <>↓ : <>↑) - : ""} - - } else { - return label; - } - } -} - -function TableBody({ path, headers, getField, items, selectedIds, setSelectedIds }:{ - path: string, - headers: IQueryTableHeader[], - getField?: (item: any, field: string) => JSX.Element | string, - items: any[], - selectedIds: string[], - setSelectedIds: React.Dispatch>, +function TableBody({ renderCells }:{ + renderCells: (item: T) => JSX.Element|JSX.Element[], }) { + const items = useItems() + const selectedIds = useSelectedIds() + const setSelectedIds = useSetSelectedIds() return { items.map(item => { const selected = selectedIds.includes(item._id) @@ -204,10 +252,8 @@ function TableBody({ path, headers, getField, items, selectedIds, setSelectedIds key={ item._id } style={ selected ? {background: "lightgray" } : {}}> onToggle(item) }/> - { headers.map(({ field, enable_link }) => - { render(item, field, enable_link) } - )} - + { renderCells(item) } + }) } @@ -221,24 +267,4 @@ function TableBody({ path, headers, getField, items, selectedIds, setSelectedIds } }) } - - function render(item, field, enable_link) { - const content = getField ? getField(item, field) : defaultGetField(item, field) - if (enable_link) { - return { content } - } else { - return content; - } - } } - -export function defaultGetField(item, field:string) { - let value = item - const segments:string[] = field.split('.') - segments.forEach(f => {value = value[f]}) - const last = segments[segments.length - 1] - if (["date_submitted", "date_modified", "date_managed"] - .includes(last)) return formatDate(value) - if (last === 'state') return - return value -} \ No newline at end of file diff --git a/frontend/src/pages/CurriculaPage.tsx b/frontend/src/pages/CurriculaPage.tsx index d334d69b..ae75ee72 100644 --- a/frontend/src/pages/CurriculaPage.tsx +++ b/frontend/src/pages/CurriculaPage.tsx @@ -3,7 +3,7 @@ import { TableTopRightButtons, FilterButton, FilterInput, ItemAddButton, CsvDownloadButton, ExcelDownloadButton, } from '../components/TableElements' -import QueryTable, {QueryTableHeaders, QueryTableBody, FilterBadges} from '../components/QueryTable' +import {QueryTableCard, QueryTableBar, QueryTable, FilterBadges} from '../components/QueryTable' const path = "/curricula/" const headers=[ @@ -26,8 +26,8 @@ const headers=[ export default function CurriculaPage() { return <>

Curricula

- - + + @@ -42,10 +42,10 @@ export default function CurriculaPage() { []}/> - + - - + + } diff --git a/frontend/src/pages/DegreesPage.tsx b/frontend/src/pages/DegreesPage.tsx index f2601e66..9cdd89cd 100644 --- a/frontend/src/pages/DegreesPage.tsx +++ b/frontend/src/pages/DegreesPage.tsx @@ -1,6 +1,6 @@ import React from 'react' -import QueryTable, {QueryTableHeaders, QueryTableBody, FilterBadges} from '../components/QueryTable' +import {QueryTableCard, QueryTableBar, QueryTable, FilterBadges} from '../components/QueryTable' import { TableTopRightButtons, FilterButton, FilterInput, ItemAddButton, CsvDownloadButton, ExcelDownloadButton, @@ -33,8 +33,8 @@ const headers=[ export default function DegreesPage() { return <>

Corsi di Laurea

- - + + @@ -51,10 +51,10 @@ export default function DegreesPage() { []}/> - + - - + + function getField(item, field) { diff --git a/frontend/src/pages/ExamsPage.tsx b/frontend/src/pages/ExamsPage.tsx index def199f9..1c5119c5 100644 --- a/frontend/src/pages/ExamsPage.tsx +++ b/frontend/src/pages/ExamsPage.tsx @@ -3,7 +3,7 @@ import { TableTopRightButtons, FilterButton, FilterInput, ItemAddButton, CsvDownloadButton, ExcelDownloadButton } from '../components/TableElements' -import QueryTable, {QueryTableHeaders, QueryTableBody, FilterBadges} from '../components/QueryTable' +import {QueryTableCard, QueryTableBar, QueryTable, FilterBadges} from '../components/QueryTable' const path="/exams/" const headers=[ @@ -35,8 +35,8 @@ const headers=[ export default function ExamsPage() { return <>

Esami

- - + + @@ -52,10 +52,10 @@ export default function ExamsPage() { []}/> - + - - + + function getField(item, field) { diff --git a/frontend/src/pages/FormTemplatesPage.tsx b/frontend/src/pages/FormTemplatesPage.tsx index be36f9db..2c260b8a 100644 --- a/frontend/src/pages/FormTemplatesPage.tsx +++ b/frontend/src/pages/FormTemplatesPage.tsx @@ -5,7 +5,7 @@ import { FilterCheckbox, ItemAddButton, CsvDownloadButton, ExcelDownloadButton, } from '../components/TableElements' -import QueryTable, {QueryTableHeaders, QueryTableBody, FilterBadges} from '../components/QueryTable' +import {QueryTableCard, QueryTableBar, QueryTable, FilterBadges} from '../components/QueryTable' const path="form_templates/" const headers=[ @@ -23,8 +23,8 @@ const headers=[ export default function FormTemplatesPage() { return <>

Modelli

- - + + @@ -38,10 +38,10 @@ export default function FormTemplatesPage() { []}/> - + - - + + function getField(item, field) { diff --git a/frontend/src/pages/FormsPage.js b/frontend/src/pages/FormsPage.js index 691c69bc..a1400c77 100644 --- a/frontend/src/pages/FormsPage.js +++ b/frontend/src/pages/FormsPage.js @@ -6,7 +6,7 @@ import { TableTopRightButtons, FilterButton, FilterInput, ItemAddButton, CsvDownloadButton, ExcelDownloadButton, } from '../components/TableElements' -import QueryTable, {QueryTableHeaders, QueryTableBody, FilterBadges} from '../components/QueryTable' +import {QueryTableCard, QueryTableBar, QueryTable, FilterBadges} from '../components/QueryTable' const path = 'forms/' const headers = [ @@ -36,8 +36,8 @@ const headers = [ export default function FormsPage() { return <>

Moduli

- - + + @@ -47,10 +47,10 @@ export default function FormsPage() { - + - - + + } diff --git a/frontend/src/pages/ProposalsPage.tsx b/frontend/src/pages/ProposalsPage.tsx index 18cff737..5830b0d6 100644 --- a/frontend/src/pages/ProposalsPage.tsx +++ b/frontend/src/pages/ProposalsPage.tsx @@ -4,7 +4,7 @@ import { TableTopRightButtons, FilterButton, FilterInput, ItemAddButton, CsvDownloadButton, ExcelDownloadButton, FilterSelect, } from '../components/TableElements' -import QueryTable, {QueryTableHeaders, QueryTableBody, FilterBadges} from '../components/QueryTable' +import {QueryTableCard, QueryTableBar, QueryTable, FilterBadges} from '../components/QueryTable' import { ProposalGet } from '../modules/engine' const path = "/proposals/" @@ -43,8 +43,8 @@ const headers = [ export default function ProposalsPage() { return <>

Piani di studio

- - + + @@ -63,10 +63,10 @@ export default function ProposalsPage() { []}/> - + - path={path} headers={headers} /> - + path={path} headers={headers} /> + } diff --git a/frontend/src/pages/UsersPage.tsx b/frontend/src/pages/UsersPage.tsx index 9ee2c100..862dc460 100644 --- a/frontend/src/pages/UsersPage.tsx +++ b/frontend/src/pages/UsersPage.tsx @@ -6,7 +6,7 @@ import { ItemAddButton, CsvDownloadButton, ExcelDownloadButton } from '../components/TableElements' -import QueryTable, {QueryTableHeaders, QueryTableBody, FilterBadges} from '../components/QueryTable' +import {QueryTableCard, QueryTableBar, QueryTable, FilterBadges} from '../components/QueryTable' const path="/users" const headers=[ @@ -42,8 +42,8 @@ const headers=[ export default function UsersPage({engine}) { return <>

Utenti

- - + + @@ -60,10 +60,10 @@ export default function UsersPage({engine}) { []}/> - + - - + + function getField(item, field) {