Skip to content

Commit

Permalink
Merge pull request #3257 from BIZFactoryGmbH/feat/previewMain
Browse files Browse the repository at this point in the history
Feat/preview main
  • Loading branch information
fabian-bizfactory authored Dec 22, 2023
2 parents a1c52b2 + 73a62fd commit 7e59dd1
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 44 deletions.
16 changes: 10 additions & 6 deletions frontend/src/js/button/PreviewButton.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import styled from "@emotion/styled";
import { useTranslation } from "react-i18next";
import { useDispatch } from "react-redux";
import { useDispatch, useSelector } from "react-redux";

import type { ColumnDescription } from "../api/types";
import { useGetAuthorizedUrl } from "../authorization/useAuthorizedUrl";
import { openPreview, useLoadPreviewData } from "../preview/actions";

import { StateT } from "../app/reducers";
import { openPreview, useLoadPreviewData } from "../preview-v2/actions";
import { TransparentButton } from "./TransparentButton";

const Button = styled(TransparentButton)`
Expand All @@ -25,13 +25,17 @@ const PreviewButton = ({
const dispatch = useDispatch();

const loadPreviewData = useLoadPreviewData();
const getAuthorizedUrl = useGetAuthorizedUrl();
const queryId = useSelector<StateT, string | null>(
(state) => state.preview.lastQuery,
);

return (
<Button
onClick={async () => {
await loadPreviewData(getAuthorizedUrl(url), columns);
dispatch(openPreview());
if (queryId) {
await loadPreviewData(queryId);
dispatch(openPreview());
}
}}
{...restProps}
>
Expand Down
20 changes: 1 addition & 19 deletions frontend/src/js/header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import styled from "@emotion/styled";
import { faStar } from "@fortawesome/free-solid-svg-icons";
import { FC } from "react";
import { useTranslation } from "react-i18next";
import { useDispatch, useSelector } from "react-redux";
import { useSelector } from "react-redux";

import type { StateT } from "../app/reducers";
import { HistoryButton } from "../button/HistoryButton";
import IconButton from "../button/IconButton";
import DatasetSelector from "../dataset/DatasetSelector";
import { openPreview, useLoadPreviewData } from "../preview-v2/actions";
import { canViewEntityPreview, useHideLogoutButton } from "../user/selectors";

import { HelpMenu } from "./HelpMenu";
Expand Down Expand Up @@ -80,28 +77,13 @@ const Header: FC = () => {
StateT["startup"]["config"]
>((state) => state.startup.config);

const dispatch = useDispatch();
const loadPreviewData = useLoadPreviewData();
const queryId = useSelector<StateT, string | null>(
(state) => state.preview.lastQuery,
);

return (
<Root>
<OverflowHidden>
<Logo />
<Spacer />
<Headline>{t("headline")}</Headline>
</OverflowHidden>
{queryId && (
<IconButton
icon={faStar}
onClick={async () => {
await loadPreviewData(queryId);
dispatch(openPreview());
}}
/>
)}
<Right>
<DatasetSelector />
{canViewHistory && <HistoryButton />}
Expand Down
83 changes: 65 additions & 18 deletions frontend/src/js/preview-v2/Table.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import styled from "@emotion/styled";
import { Table as ArrowTable } from "apache-arrow";
import { Table as ArrowTable, Vector } from "apache-arrow";
import RcTable from "rc-table";
import { ReactNode, useEffect, useRef, useState } from "react";
import { GetQueryResponseDoneT, GetQueryResponseT } from "../api/types";
import { useSelector } from "react-redux";
import {
CurrencyConfigT,
GetQueryResponseDoneT,
GetQueryResponseT,
} from "../api/types";
import { StateT } from "../app/reducers";
import { NUMBER_TYPES, formatDate, formatNumber } from "./util";

interface Props {
Expand Down Expand Up @@ -42,34 +48,74 @@ export default function Table({ data, queryData }: Props) {
table: StyledTable,
};

const getRenderFunction = (
const currencyConfig = useSelector<StateT, CurrencyConfigT>(
(state) => state.startup.config.currency,
);

function getRenderFunction(
cellType: string,
): ((value: string | Vector) => ReactNode) | undefined {
if (cellType.indexOf("LIST") == 0) {
const listType = cellType.match(/LIST\[(?<listtype>.*)\]/)?.groups?.[
"listtype"
];
if (listType) {
const listTypeRenderFunction = getRenderFunction(listType);
return (value) =>
(value as Vector)
.toArray()
.map((listItem: string) =>
listTypeRenderFunction
? listTypeRenderFunction(listItem)
: listItem,
)
.join(", ");
}
} else if (NUMBER_TYPES.includes(cellType)) {
return (value) => {
const num = parseFloat(value as string);
return isNaN(num) ? value : formatNumber(num);
};
} else if (cellType == "DATE") {
return (value) => formatDate(value as string);
} else if (cellType == "DATE_RANGE") {
return (value) => {
const dateRange = (value as Vector).toJSON() as unknown as {
min: Date;
max: Date;
};
const min = dateRange.min.toLocaleDateString("de-de");
const max = dateRange.max.toLocaleDateString("de-de");
return min == max ? min : `${min} - ${max}`;
};
} else if (cellType == "MONEY") {
return (value) => {
const num = parseFloat(value as string);
return isNaN(num)
? value
: `${formatNumber(num)} ${currencyConfig.unit}`;
};
} else if (cellType == "BOOLEAN") {
return (value) => (value ? "1" : "0");
}
}

const getRenderFunctionByFieldName = (
fieldName: string,
): ((value: string) => ReactNode) | undefined => {
): ((value: string | Vector) => ReactNode) | undefined => {
const cellType = (
queryData as GetQueryResponseDoneT
).columnDescriptions?.find((x) => x.label == fieldName)?.type;
if (cellType) {
if (NUMBER_TYPES.includes(cellType)) {
return (value) => {
const num = parseFloat(value);
return isNaN(num) ? value : formatNumber(num);
};
} else if (cellType == "DATE") {
return (value) => formatDate(value);
} else if (cellType == "MONEY") {
return (value) => {
const num = parseFloat(value);
return isNaN(num) ? value : formatNumber(num, 2) + " €";
};
}
return getRenderFunction(cellType);
}
};

const columns = data.schema.fields.map((field) => ({
title: field.name.charAt(0).toUpperCase() + field.name.slice(1),
dataIndex: field.name,
key: field.name,
render: getRenderFunction(field.name),
render: getRenderFunctionByFieldName(field.name),
}));

const rootRef = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -106,6 +152,7 @@ export default function Table({ data, queryData }: Props) {
data={tableData.slice(0, loadingAmount)}
rowKey={(_, index) => `row_${index}`}
components={components}
scroll={{ x: true }}
/>
</Root>
);
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/js/preview-v2/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const NUMBER_TYPES = ["NUMBER", "INTEGER", "REAL", "DECIMAL"];

export const NUMBER_STATISTICS_TYPES = [...NUMBER_TYPES, "MONEY"];

export function formatNumber(num: number, precision = 3): string {
export function formatNumber(num: number, precision = 2): string {
const precisionMultiplier = 10 * precision;
return (
Math.round(num * precisionMultiplier) / precisionMultiplier
Expand Down

0 comments on commit 7e59dd1

Please sign in to comment.