Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GUI related modification[Implemented Filter, Sorting and Loader widget, Fixed Scrollbar alignment issue and SVG image related issue] and removed cmf server related functions from public api doc #205

Merged
merged 20 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
22b3323
Added loader, filter and sorting functionality inside GUI
AyeshaSanadi Aug 22, 2024
0fc8382
Merge branch 'HewlettPackard:master' into gui_changes
AyeshaSanadi Aug 23, 2024
f252e0d
Fixed scroll bar issue
AyeshaSanadi Aug 23, 2024
2dbb514
Fixed loader issue inside lineage section
AyeshaSanadi Aug 23, 2024
fb22d96
Merge branch 'HewlettPackard:master' into gui_changes
AyeshaSanadi Aug 30, 2024
f70f423
Removing server side API's from cmf.md
AyeshaSanadi Aug 30, 2024
f284605
Merge branch 'HewlettPackard:master' into gui_changes
AyeshaSanadi Sep 12, 2024
9c370ac
Modified css for loader component
AyeshaSanadi Sep 13, 2024
135e36e
Fixed svg related lineage image for artifact and execution tree
AyeshaSanadi Sep 13, 2024
ee5a836
Merge branch 'HewlettPackard:master' into gui_changes
AyeshaSanadi Oct 4, 2024
b8fa122
Added loader, filter and sorting functionality inside GUI
AyeshaSanadi Aug 22, 2024
170385a
Fixed scroll bar issue
AyeshaSanadi Aug 23, 2024
04fe79c
Fixed loader issue inside lineage section
AyeshaSanadi Aug 23, 2024
3a58b9d
Removing server side API's from cmf.md
AyeshaSanadi Aug 30, 2024
316f749
Modified css for loader component
AyeshaSanadi Sep 13, 2024
9c0c7ab
Fixed svg related lineage image for artifact and execution tree
AyeshaSanadi Sep 13, 2024
034fc7f
Merge remote-tracking branch 'origin/gui_changes' into gui_changes
AyeshaSanadi Oct 8, 2024
da172e7
sync api to async api changes added
AyeshaSanadi Oct 8, 2024
5baf96a
Resolved sorting arrow related issue
AyeshaSanadi Oct 9, 2024
ae6b0c2
Changed css related sorting arrow
AyeshaSanadi Oct 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions docs/api/public/cmf.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,12 @@
members:
- __init__
- create_context
- merge_created_context
- create_execution
- update_execution
- merge_created__execution
- log_dataset
- log_dataset_with_version
- log_model
- log_model_with_version
- log_execution_metrics_from_client
- log_execution_metrics
- log_metric
- commit_existing_metrics
- create_dataslice
- update_dataslice

Expand Down
2 changes: 1 addition & 1 deletion ui/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<div id="root" style="overflow-x: hidden; overflow-y: scroll;"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
Expand Down
62 changes: 32 additions & 30 deletions ui/src/components/ArtifactTable/index.jsx
Copy link
Collaborator

@shreyas-kulkarni09 shreyas-kulkarni09 Oct 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestions for Artifact page

  1. Sorting Arrow Visibility
    Currently, the sorting arrow appears only after clicking on the field. It may enhance user experience to display the sorting arrow beforehand, allowing users to recognize that sorting functionality is available.

  2. Sorting and searching Functionality
    Currently, sorting and searching is enabled solely on the "Name" field. We can think about expanding this functionality to other fields too.

  3. Artifact Organization
    We could consider implementing a dedicated tab that displays all artifacts, complemented by side filters for specific artifact types.

  4. Filter Behavior
    Clicking twice on any of the filters causes the table to disappear. We need to investigate this behavior.

5 Search Behavior
Search is limited to particular pagination

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created Bug for Sorting Arrow Visibility. Will consider Sorting and searching Functionality and Artifact Organization for future enhancements.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Filter Behaviour
    We have faced this bug before and have already fixed it in sync_api_to_async_api PR
    ui/src/pages/artifacts/ArtifactTypeSidebar.jsx
    PR - master...varkha-d-sharma:cmf:sync_api_to_async_api

Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,11 @@ import config from "../../config";

const client = new FastAPIClient(config);

const ArtifactTable = ({ artifacts, ArtifactType, onSort, onFilter }) => {
const ArtifactTable = ({ artifacts, ArtifactType, onSort }) => {

// Default sorting order
const [sortOrder, setSortOrder] = useState("Context_Type");

// Local filter value state
const [filterValue, setFilterValue] = useState("");
const [sortOrder, setSortOrder] = useState(onSort);
const [sortedData, setSortedData] = useState([]);

const [expandedRow, setExpandedRow] = useState(null);
const [showPopup, setShowPopup] = useState(false);
Expand All @@ -41,20 +39,25 @@ const ArtifactTable = ({ artifacts, ArtifactType, onSort, onFilter }) => {

useEffect(() => {
// Set initial sorting order when component mounts
setSortOrder("asc");
}, []);
setSortedData([...artifacts]);
}, [artifacts]);

const handleSort = () => {
const newSortOrder = sortOrder === "asc" ? "desc" : "asc";
// Initially all data is in mixed format
// After the data is in asc order
// then it is in desc order
const newSortOrder = sortOrder === "desc" ? "asc" : sortOrder === "asc" ? "desc" : "asc";
setSortOrder(newSortOrder);
onSort("name", newSortOrder); // Notify parent component about sorting change
const sorted = [...artifacts].sort((a, b) => {
if(newSortOrder === "asc"){
return a.name.localeCompare(b.name);
}else{
return b.name.localeCompare(a.name);
}
});
setSortedData(sorted); // Notify parent component about sorting change
};

const handleFilterChange = (event) => {
const value = event.target.value;
setFilterValue(value);
onFilter("name", value); // Notify parent component about filter change
};

const toggleRow = (rowId) => {
if (expandedRow === rowId) {
Expand All @@ -75,19 +78,19 @@ const ArtifactTable = ({ artifacts, ArtifactType, onSort, onFilter }) => {
const handleClosePopup = () => {
setShowPopup(false);
};


const renderArrow = () => {
if (sortOrder === "desc"){
return <span className="text-2xl cursor-pointer">&#8595;</span> //data is in desc order ---> ↓
} else if (sortOrder === "asc"){
return <span className="text-2xl cursor-pointer">&#8593;</span> //data is in asc order ----> ↑
} else{
return <span className="text-2xl cursor-pointer">&#8597;</span> //data is in initial order -----------> ↕
}
}

return (
<div className="container flex flex-col mx-auto p-6 mr-4">
<div className="flex flex-col items-end m-1">
<input
type="text"
value={filterValue}
onChange={handleFilterChange}
placeholder="Filter by Name"
className="w-64 px-1 border-2 border-gray"
/>
</div>
<div className="container flex flex-col">
<div className="overflow-x-auto">
<div className="p-1.5 w-full inline-block align-middle">
<table className="min-w-full divide-y divide-gray-200 border-4">
Expand All @@ -102,8 +105,7 @@ const ArtifactTable = ({ artifacts, ArtifactType, onSort, onFilter }) => {
onClick={handleSort}
className="name px-6 py-3"
>
name {sortOrder === "asc" && <span className="arrow">&#8593;</span>}
{sortOrder === "desc" && <span className="arrow">&#8595;</span>}
name&nbsp; {renderArrow()}
</th>
{ArtifactType === "Model" && (
<th scope="col" className="model_card px-6 py-3">
Expand All @@ -129,13 +131,13 @@ const ArtifactTable = ({ artifacts, ArtifactType, onSort, onFilter }) => {
</tr>
</thead>
<tbody className="body divide-y divide-gray-200">
{artifacts.length > 0 && artifacts.map((data, index) => (
{sortedData.length > 0 && sortedData.map((data, index) => (
<React.Fragment key={index}>
<tr
key={index}
className="text-sm font-medium text-gray-800"
>
<td className="px-6 py-4" onClick={() => toggleRow(index)}>
<td className="px-6 py-4 cursor-pointer" onClick={() => toggleRow(index)}>
{expandedRow === index ? "-" : "+"}
</td>
<td className="px-6 py-4">{data.id}</td>
Expand Down Expand Up @@ -190,4 +192,4 @@ const ArtifactTable = ({ artifacts, ArtifactType, onSort, onFilter }) => {
);
};

export default ArtifactTable;
export default ArtifactTable;
47 changes: 32 additions & 15 deletions ui/src/components/ExecutionTable/index.jsx
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestions for Execution Page

  1. Sorting Arrow Visibility
    Currently, the sorting arrow appears only after clicking on the field. It may enhance user experience to display the sorting arrow beforehand, allowing users to recognize that sorting functionality is available.

  2. Sorting and searching Functionality
    Currently, sorting and searching is enabled solely on the "Name" field. We can think about expanding this functionality to other fields too.

  3. Search Behavior
    Search is limited to particular pagination.

Copy link
Collaborator

@varkha-d-sharma varkha-d-sharma Oct 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created Bug for Sorting Arrow Visibility. Will consider Sorting and searching Functionality for future enhancements.

Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,34 @@
import React, { useState, useEffect } from "react";
import "./index.css";

const ExecutionTable = ({ executions, onSort, onFilter }) => {

// Default sorting order
const [sortOrder, setSortOrder] = useState("Context_Type");
const ExecutionTable = ({ executions, onSort, onFilter}) => {

// Default sorting order
const [sortOrder, setSortOrder] = useState(onSort);
const [sortedData, setSortedData] = useState([]);
// Local filter value state
const [filterValue, setFilterValue] = useState("");

const [expandedRow, setExpandedRow] = useState(null);

const consistentColumns = [];

useEffect(() => {
// Set initial sorting order when component mounts
setSortOrder("asc");
}, []);
setSortedData([...executions]);
}, [executions]);


const handleSort = () => {
const newSortOrder = sortOrder === "asc" ? "desc" : "asc";
const newSortOrder = sortOrder === "desc" ? "asc" : sortOrder === "asc" ? "desc" : "asc";
setSortOrder(newSortOrder);
onSort("Context_Type", newSortOrder); // Notify parent component about sorting change
const sorted = [...executions].sort((a, b) => {
if(newSortOrder === "asc"){
return a.Context_Type.localeCompare(b.Context_Type);
}else{
return b.Context_Type.localeCompare(a.Context_Type);
}
});
setSortedData(sorted); // Notify parent component about sorting change
};

const handleFilterChange = (event) => {
Expand All @@ -56,13 +63,24 @@ const ExecutionTable = ({ executions, onSort, onFilter }) => {
}
};

const renderArrow = () => {
if (sortOrder === "desc"){
return <span className="text-2xl cursor-pointer">&#8595;</span> //data is in desc order ---> ↓
} else if (sortOrder === "asc"){
return <span className="text-2xl cursor-pointer">&#8593;</span> //data is in asc order ----> ↑
} else{
return <span className="text-2xl cursor-pointer">&#8597;</span> //data is in initial order -----------> ↕
}
}

return (
<div className="flex flex-col">
<div
style={{
display: "flex",
justifyContent: "flex-end",
marginBottom: "1rem",
marginBottom: "0.5rem",
marginTop: "0.5rem",
}}
>
<input
Expand All @@ -88,8 +106,7 @@ const ExecutionTable = ({ executions, onSort, onFilter }) => {
onClick={handleSort}
className="px-6 py-3 Context_Type"
>
Context_Type {sortOrder === "asc" && <span className="arrow">&#8593;</span>}
{sortOrder === "desc" && <span className="arrow">&#8595;</span>}
Context_Type&nbsp; {renderArrow()}
</th>
<th scope="col" className="px-6 py-3 Execution">
Execution
Expand All @@ -106,14 +123,14 @@ const ExecutionTable = ({ executions, onSort, onFilter }) => {
</tr>
</thead>
<tbody className="body divide-y divide-gray-200">
{executions.map((data, index) => (
{sortedData.map((data, index) => (
<React.Fragment key={index}>
<tr
key={index}
onClick={() => toggleRow(index)}
className="text-sm font-medium text-gray-800"
>
<td classname="px-6 py-4">
<td className="px-6 py-4 cursor-pointer">
{expandedRow === index ? "-" : "+"}
</td>
<td className="px-6 py-4">{data.Context_Type}</td>
Expand Down Expand Up @@ -160,4 +177,4 @@ const ExecutionTable = ({ executions, onSort, onFilter }) => {
);
};

export default ExecutionTable;
export default ExecutionTable;
3 changes: 1 addition & 2 deletions ui/src/components/ExecutionTree/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ const constructTangleLayout = (levels, options = {}) => {
l.xt = l.target.x;
l.yt = l.target.y + l.target.bundles_index[l.bundle.id].i * metro_d - (l.target.bundles.length * metro_d) / 2 + metro_d / 2;
l.xb = l.bundle.x;
l.yb = l.bundle.y;
l.xs = l.source.x;
l.ys = l.source.y;
});
Expand All @@ -130,7 +129,7 @@ const constructTangleLayout = (levels, options = {}) => {
links.forEach(l => {
l.yt = l.target.y + l.target.bundles_index[l.bundle.id].i * metro_d - (l.target.bundles.length * metro_d) / 2 + metro_d / 2;
l.ys = l.source.y;
l.c1 = l.source.level - l.target.level > 1 ? Math.min(options.bigc, l.xb - l.xt, l.yb - l.yt) - c : c;
l.c1 = c;
l.c2 = c;
});

Expand Down
29 changes: 29 additions & 0 deletions ui/src/components/Loader/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.loader-container {
position: relative; /* Relative positioning for the loader to be placed absolutely inside */
width: 100%;
height: 100%; /* Ensure it takes the full height of its parent */
}

/* Loader is absolutely positioned within the loader-container */
.loader {
position: absolute;
top: 100%;
left: 50%;
transform: translate(-50%, -50%); /* Center the loader */
border: 8px solid #f3f3f3;
border-top: 8px solid #3498db;
border-radius: 50%;
width: 100px; /* Size of the loader */
height: 100px; /* Size of the loader */
animation: spin 1.5s linear infinite;
z-index: 9999; /* Ensure it appears on top */
}

@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
21 changes: 8 additions & 13 deletions ui/src/components/Loader/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,14 @@
***/


import React from "react";
import React from 'react';
import './index.css';

function Loader() {
return (
<div className="flex justify-center items-center h-screen w-screen bg-white">
<img
src="https://thumbs.gfycat.com/HugeDeliciousArchaeocete-max-1mb.gif"
alt="Test data"
width={"auto"}
height={"auto"}
/>
</div>
);
}
const Loader = () => (
<div className="loader-container">
<div className="loader"></div>
</div>
);

export default Loader;

10 changes: 6 additions & 4 deletions ui/src/components/TangledTree/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,12 @@ const constructTangleLayout = (levels, options = {}) => {
i += l.length;
});

// establish the basic structure and position
links.forEach(l => {
l.xt = l.target.x;
l.yt = l.target.y + l.target.bundles_index[l.bundle.id].i * metro_d - (l.target.bundles.length * metro_d) / 2 + metro_d / 2;
l.xb = l.bundle.x;
l.yb = l.bundle.y;
l.xs = l.source.x;
l.ys = l.source.y;
});

var y_negative_offset = 0;
Expand All @@ -127,10 +126,11 @@ const constructTangleLayout = (levels, options = {}) => {
l.forEach(n => (n.y -= y_negative_offset));
});

// Fine tune the visual appearance of link (how the links need to display in svg)
links.forEach(l => {
l.yt = l.target.y + l.target.bundles_index[l.bundle.id].i * metro_d - (l.target.bundles.length * metro_d) / 2 + metro_d / 2;
l.ys = l.source.y;
l.c1 = l.source.level - l.target.level > 1 ? Math.min(options.bigc, l.xb - l.xt, l.yb - l.yt) - c : c;
l.c1 = c;
l.c2 = c;
});

Expand All @@ -151,10 +151,12 @@ const renderChart = (data, options = {}) => {
options.background_color ||= 'white'; // Default background color

const tangleLayout = constructTangleLayout(_.cloneDeep(data), options);

tangled_width = tangleLayout.layout.width;
tangled_height = tangleLayout.layout.height;
const textPadding = 12;
const labelOffset = 4;
const svg_width = (tangled_width + textPadding * 10) < 1000 ? `${tangled_width + textPadding * 50}` : `${tangled_width + textPadding * 10}`;
return (
<>
<style>
Expand All @@ -171,7 +173,7 @@ const renderChart = (data, options = {}) => {
}
`}
</style>
<svg width={tangled_width + textPadding * 10} height={tangled_height + textPadding * 10}>
<svg width={svg_width} height={tangled_height + textPadding * 10}>
{tangleLayout.bundles.map((b, i) => {
let d = b.links
.map(
Expand Down
Loading