Skip to content

Commit

Permalink
BITMAKER-3277: Fix parsing items in estela-web job detail page (#192)
Browse files Browse the repository at this point in the history
* Add a recursive definition of Item to render general items and requests
* Add a tooltip with the data type on the field keys

---------

Co-authored-by: mgonnav <mateo@emegona.com>
  • Loading branch information
reqhiem and mgonnav committed Jun 19, 2023
1 parent ef3ead9 commit 7ee30f3
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 81 deletions.
161 changes: 80 additions & 81 deletions estela-web/src/pages/JobDataPage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState, useEffect } from "react";
import { Layout, Row, Col, Typography, Button, Dropdown, Modal, Pagination, Card, Input } from "antd";
import { Layout, Row, Col, Typography, Button, Dropdown, Modal, Pagination, Card, Input, Tooltip } from "antd";
import { resourceNotAllowedNotification, dataDeletedNotification, Spin, PaginationItem } from "../../shared";

import Export from "../../assets/icons/export.svg";
Expand All @@ -14,6 +14,8 @@ import {
} from "../../services/api";
import { ApiService } from "../../services";

import "./styles.scss";

const { Content } = Layout;
const { Text, Paragraph } = Typography;

Expand Down Expand Up @@ -78,20 +80,79 @@ const getData = async (
);
};

type ItemDictionary = { [key: string]: ItemDictionary } | ArrayLike<ItemDictionary>;

type ItemProps = {
data: ItemDictionary;
};

function ItemHeaderWithTooltip(title: string, key: string) {
return (
<Tooltip title={title} showArrow={true} overlayClassName="tooltip">
<Text className="font-bold" style={{ cursor: "pointer" }}>
{key}
</Text>
</Tooltip>
);
}

function Item({ data }: ItemProps) {
return (
<Col>
{Object.entries(data).map(([itemPropKey, itemProp], index: number) => {
let itemHeader: JSX.Element = <></>;
let itemContent: JSX.Element = <></>;

if (typeof itemProp === "string") {
itemHeader = ItemHeaderWithTooltip("string", itemPropKey);
if (itemProp.length <= 300) {
itemContent = <Text className="text-estela-black-medium">{itemProp}</Text>;
} else if (itemProp.length > 300) {
itemContent = (
<Paragraph
className="text-estela-black-medium"
ellipsis={{ rows: 3, expandable: true, symbol: "more" }}
>
{itemProp}
</Paragraph>
);
}
} else if (typeof itemProp === "number" || typeof itemProp === "boolean") {
itemHeader = ItemHeaderWithTooltip(typeof itemProp, itemPropKey);
itemContent = <Text className="text-estela-black-medium">{itemProp.toString()}</Text>;
} else if (typeof itemProp === "object" && itemProp !== null) {
itemHeader = ItemHeaderWithTooltip(Array.isArray(itemProp) ? "list" : "dict", itemPropKey);
itemContent = <Item data={itemProp} />;
} else if (itemProp === null) {
itemHeader = ItemHeaderWithTooltip("null", itemPropKey);
itemContent = <Text className="text-estela-black-medium">null</Text>;
}

return (
<Row key={index} className={`py-1 ${index % 2 ? "rounded-lg bg-estela-blue-low" : "bg-white"}`}>
<Col className="flex flex-col w-2/12">{itemHeader}</Col>
<Col className="flex flex-col w-10/12">{itemContent}</Col>
</Row>
);
})}
</Col>
);
}

export function JobItemsData({ projectId, spiderId, jobId }: JobsDataProps) {
const [openModal, setOpenModal] = useState(false);
const [loadedButton, setLoadedButton] = useState(false);
const [current, setCurrent] = useState(0);
const [count, setCount] = useState(0);
const [loaded, setLoaded] = useState(false);
const [items, setItems] = useState<Dictionary[]>([]);
const [items, setItems] = useState<ItemDictionary[]>([]);

useEffect(() => {
getData("items", 1, projectId, spiderId, jobId).then((response) => {
let data: Dictionary[] = [];
let data: ItemDictionary[] = [];
if (response.results?.length) {
const safe_data: unknown[] = response.results ?? [];
data = safe_data as Dictionary[];
data = safe_data as ItemDictionary[];
setItems(data);
setCurrent(1);
setCount(response.count);
Expand All @@ -104,10 +165,10 @@ export function JobItemsData({ projectId, spiderId, jobId }: JobsDataProps) {
const onItemsPageChange = async (page: number): Promise<void> => {
setLoaded(false);
await getData("items", page, projectId, spiderId, jobId).then((response) => {
let data: Dictionary[] = [];
let data: ItemDictionary[] = [];
if (response.results?.length) {
const safe_data: unknown[] = response.results ?? [];
data = safe_data as Dictionary[];
data = safe_data as ItemDictionary[];
setItems(data);
setCurrent(page);
setCount(response.count);
Expand Down Expand Up @@ -217,7 +278,7 @@ export function JobItemsData({ projectId, spiderId, jobId }: JobsDataProps) {
</Button>
</Col>
</Row>
{items.map((item: Dictionary, index: number) => {
{items.map((item: ItemDictionary, index: number) => {
return (
<Card key={index} className="w-full mt-2" style={{ borderRadius: "8px" }} bordered={false}>
<Row className="flow-root mx-1 my-2 w-full space-x-4" align="middle">
Expand All @@ -237,39 +298,9 @@ export function JobItemsData({ projectId, spiderId, jobId }: JobsDataProps) {
</Button>
</Col>
</Row>
<>
{Object.entries(item).map(([itemPropKey, itemProp], index: number) => {
let itemContent = (
<Text className="text-estela-black-medium px-4">{itemProp}</Text>
);
if (itemProp === null) {
itemContent = <Text className="text-estela-black-medium px-4">null</Text>;
} else if (itemProp.length > 300) {
itemContent = (
<Paragraph
className="text-estela-black-medium px-4"
ellipsis={{ rows: 3, expandable: true, symbol: "more" }}
>
{itemProp}
</Paragraph>
);
}
return (
<Row
key={index}
align="middle"
className={`grid grid-cols-8 py-1 px-2 ${
index % 2 ? "rounded-lg bg-estela-blue-low" : ""
}`}
>
<Col className="col-span-2">
<Text className="font-bold">{itemPropKey}</Text>
</Col>
<Col className="col-span-6">{itemContent}</Col>
</Row>
);
})}
</>
<Col>
<Item data={item} />
</Col>
</Card>
);
})}
Expand Down Expand Up @@ -298,14 +329,14 @@ export function JobRequestsData({ projectId, spiderId, jobId }: JobsDataProps) {
const [current, setCurrent] = useState(0);
const [count, setCount] = useState(0);
const [loaded, setLoaded] = useState(false);
const [requests, setRequests] = useState<Dictionary[]>([]);
const [requests, setRequests] = useState<ItemDictionary[]>([]);

useEffect(() => {
getData("requests", 1, projectId, spiderId, jobId).then((response) => {
let data: Dictionary[] = [];
let data: ItemDictionary[] = [];
if (response.results?.length) {
const safe_data: unknown[] = response.results ?? [];
data = safe_data as Dictionary[];
data = safe_data as ItemDictionary[];
setRequests(data);
setLoaded(true);
setCurrent(1);
Expand All @@ -318,10 +349,10 @@ export function JobRequestsData({ projectId, spiderId, jobId }: JobsDataProps) {
const onRequestsPageChange = async (page: number): Promise<void> => {
setLoaded(false);
await getData("requests", page, projectId, spiderId, jobId).then((response) => {
let data: Dictionary[] = [];
let data: ItemDictionary[] = [];
if (response.results?.length) {
const safe_data: unknown[] = response.results ?? [];
data = safe_data as Dictionary[];
data = safe_data as ItemDictionary[];
setRequests(data);
setLoaded(true);
setCurrent(page);
Expand Down Expand Up @@ -431,7 +462,7 @@ export function JobRequestsData({ projectId, spiderId, jobId }: JobsDataProps) {
</Button>
</Col>
</Row>
{requests.map((request: Dictionary, index: number) => {
{requests.map((request: ItemDictionary, index: number) => {
return (
<Card key={index} className="w-full mt-2" style={{ borderRadius: "8px" }} bordered={false}>
<Row className="flow-root mx-1 my-2 w-full space-x-4" align="middle">
Expand All @@ -451,41 +482,9 @@ export function JobRequestsData({ projectId, spiderId, jobId }: JobsDataProps) {
</Button>
</Col>
</Row>
<>
{Object.entries(request).map(([requestPropKey, requestProp], index: number) => {
let requestContent = (
<Text className="text-estela-black-medium px-4">{requestProp}</Text>
);
if (requestProp === null) {
requestContent = (
<Text className="text-estela-black-medium px-4">null</Text>
);
} else if (requestProp.length > 300) {
requestContent = (
<Paragraph
className="text-estela-black-medium px-4"
ellipsis={{ rows: 3, expandable: true, symbol: "more" }}
>
{requestProp}
</Paragraph>
);
}
return (
<Row
key={index}
align="middle"
className={`grid grid-cols-8 py-1 px-2 ${
index % 2 ? "rounded-lg bg-estela-blue-low" : ""
}`}
>
<Col className="col-span-2">
<Text className="font-bold">{requestPropKey}</Text>
</Col>
<Col className="col-span-6">{requestContent}</Col>
</Row>
);
})}
</>
<Col>
<Item data={request} />
</Col>
</Card>
);
})}
Expand Down
24 changes: 24 additions & 0 deletions estela-web/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,21 @@
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63"
integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==

"@babel/helper-string-parser@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f"
integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==

"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1":
version "7.19.1"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2"
integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==

"@babel/helper-validator-identifier@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193"
integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==

"@babel/helper-validator-option@^7.18.6", "@babel/helper-validator-option@^7.21.0":
version "7.21.0"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz#8224c7e13ace4bafdc4004da2cf064ef42673180"
Expand Down Expand Up @@ -319,6 +329,11 @@
chalk "^2.0.0"
js-tokens "^4.0.0"

"@babel/parser@^7.18.10":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.5.tgz#721fd042f3ce1896238cf1b341c77eb7dee7dbea"
integrity sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==

"@babel/parser@^7.20.7", "@babel/parser@^7.21.4":
version "7.21.4"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.4.tgz#94003fdfc520bbe2875d4ae557b43ddb6d880f17"
Expand Down Expand Up @@ -1110,6 +1125,15 @@
debug "^4.1.0"
globals "^11.1.0"

"@babel/types@^7.18.10":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.5.tgz#cd93eeaab025880a3a47ec881f4b096a5b786fbe"
integrity sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==
dependencies:
"@babel/helper-string-parser" "^7.22.5"
"@babel/helper-validator-identifier" "^7.22.5"
to-fast-properties "^2.0.0"

"@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.5", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.21.2", "@babel/types@^7.21.4", "@babel/types@^7.4.4":
version "7.21.4"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.4.tgz#2d5d6bb7908699b3b416409ffd3b5daa25b030d4"
Expand Down

0 comments on commit 7ee30f3

Please sign in to comment.