From 092171d27f07398cc4bb8a03f8fc2a695b305fd0 Mon Sep 17 00:00:00 2001 From: Kacper Donat Date: Wed, 18 Nov 2020 23:06:06 +0100 Subject: [PATCH] Add comparators for multilangual fields --- src/management/common/MultilangualCell.tsx | 15 +++++++++++++++ src/management/common/helpers.tsx | 15 +++++++++++++++ src/management/page/list.tsx | 6 ++++-- src/management/type/list.tsx | 18 ++++++------------ 4 files changed, 40 insertions(+), 14 deletions(-) create mode 100644 src/management/common/MultilangualCell.tsx diff --git a/src/management/common/MultilangualCell.tsx b/src/management/common/MultilangualCell.tsx new file mode 100644 index 0000000..cd3346f --- /dev/null +++ b/src/management/common/MultilangualCell.tsx @@ -0,0 +1,15 @@ +import { Multilingual } from "@/data"; +import React from "react"; +import { Chip } from "@material-ui/core"; + +export type MultilingualCellProps = { value: Multilingual } + +export const MultilingualCell = ({ value }: MultilingualCellProps) => { + return <> + { Object.keys(value).map(language =>
+ + { value[language as keyof Multilingual] } +
) } + +} + diff --git a/src/management/common/helpers.tsx b/src/management/common/helpers.tsx index f8dfcfe..cf2d6e5 100644 --- a/src/management/common/helpers.tsx +++ b/src/management/common/helpers.tsx @@ -2,6 +2,7 @@ import React from "react"; import { Column } from "material-table"; import { Actions } from "@/components"; import { Trans } from "react-i18next"; +import { Multilingual } from "@/data"; export function actionsColumn(render: (value: T) => React.ReactNode): Column { return { @@ -18,3 +19,17 @@ export function actionsColumn(render: (value: T) => React.Reac export function createBoundComponent(Component: React.ComponentType, bound: Pick) { return (props: Omit) => ; } + +export type Comparator = (a: T, b: T) => number; +export type MultilingualComparator = Comparator>; + +export function createMultilingualComparator(comparator: Comparator): MultilingualComparator { + return (a, b) => comparator(a.pl, b.pl); +} + +export const multilingualStringComparator = createMultilingualComparator((a, b) => a && b ? a.localeCompare(b) : 0) +export const multilingualNumberComparator = createMultilingualComparator((a, b) => a - b) + +export function fieldComparator(field: K, comparator: Comparator): Comparator { + return (a, b) => comparator(a[field], b[field]) +} diff --git a/src/management/page/list.tsx b/src/management/page/list.tsx index 095e295..4a9a8e1 100644 --- a/src/management/page/list.tsx +++ b/src/management/page/list.tsx @@ -20,8 +20,9 @@ import { Confirm } from "@/components/confirm"; import useTheme from "@material-ui/core/styles/useTheme"; import { BulkActions } from "@/management/common/BulkActions"; import { MaterialTableTitle } from "@/management/common/MaterialTableTitle"; -import { actionsColumn } from "@/management/common/helpers"; +import { actionsColumn, fieldComparator, multilingualStringComparator } from "@/management/common/helpers"; import { createDeleteAction } from "@/management/common/DeleteResourceAction"; +import { MultilingualCell } from "@/management/common/MultilangualCell"; const label = (page: StaticPage) => page.title.pl; @@ -93,8 +94,9 @@ export const StaticPageManagement = () => { const columns: Column[] = [ { - render: page => page.title.pl, + render: page => , title: t("page.field.title"), + customSort: fieldComparator("title", multilingualStringComparator), }, { field: "slug", diff --git a/src/management/type/list.tsx b/src/management/type/list.tsx index 7855fab..aad97a3 100644 --- a/src/management/type/list.tsx +++ b/src/management/type/list.tsx @@ -2,32 +2,24 @@ import { Page } from "@/pages/base"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { useAsyncState } from "@/hooks"; -import { InternshipType, Multilingual } from "@/data"; +import { InternshipType } from "@/data"; import api from "@/management/api"; import { Management } from "@/management/main"; -import { Button, Chip, Container, Tooltip, Typography } from "@material-ui/core"; +import { Button, Container, Tooltip, Typography } from "@material-ui/core"; import { Async } from "@/components/async"; import MaterialTable, { Column } from "material-table"; import { MaterialTableTitle } from "@/management/common/MaterialTableTitle"; -import { actionsColumn } from "@/management/common/helpers"; +import { actionsColumn, fieldComparator, multilingualStringComparator } from "@/management/common/helpers"; import { AccountCheck, Delete, Refresh, ShieldCheck } from "mdi-material-ui"; import { OneOrMany } from "@/helpers"; import { createDeleteAction } from "@/management/common/DeleteResourceAction"; import { BulkActions } from "@/management/common/BulkActions"; import { useSpacing } from "@/styles"; import { Actions } from "@/components"; +import { MultilingualCell } from "@/management/common/MultilangualCell"; const title = "type.index.title"; -const MultilingualCell = ({ value }: { value: Multilingual }) => { - return <> - { Object.keys(value).map(language =>
- - { value[language as keyof Multilingual] } -
) } - -} - const label = (type: InternshipType) => type?.label?.pl; export const InternshipTypeManagement = () => { @@ -60,10 +52,12 @@ export const InternshipTypeManagement = () => { { title: t("type.field.label"), render: type => , + customSort: fieldComparator("label", multilingualStringComparator), }, { title: t("type.field.description"), render: type => type.description && , + sorting: false, }, { title: t("type.field.flags"),