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

[UI]: implement test sets main view #2102

Merged
merged 17 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions agenta-backend/agenta_backend/models/api/testset_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class TestSetOutputResponse(BaseModel):
id: str = Field(..., alias="_id")
name: str
created_at: str
updated_at: str

class Config:
allow_population_by_field_name = True
4 changes: 3 additions & 1 deletion agenta-backend/agenta_backend/routers/testset_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import logging
import requests
from typing import Optional, List

from datetime import datetime, timezone
from pydantic import ValidationError

from fastapi.responses import JSONResponse
Expand Down Expand Up @@ -298,6 +298,7 @@ async def update_testset(
testset_update = {
"name": csvdata.name,
"csvdata": csvdata.csvdata,
"updated_at": datetime.now(timezone.utc),
}
await db_manager.update_testset(
testset_id=str(testset.id), values_to_update=testset_update
Expand Down Expand Up @@ -351,6 +352,7 @@ async def get_testsets(
_id=str(testset.id), # type: ignore
name=testset.name,
created_at=str(testset.created_at),
updated_at=str(testset.updated_at),
)
for testset in testsets
]
Expand Down
1 change: 0 additions & 1 deletion agenta-web/cypress/e2e/single-model-test-evaluation.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ describe("Single Model Test workflow", () => {
cy.visit(`/apps/${app_id}/testsets`)
cy.url().should("include", "/testsets")
cy.get('[data-cy="app-testset-list"]').as("table")
cy.get("@table").get(".ant-table-pagination li a").last().click()
cy.get("@table").contains(saved_testset_name).as("tempTestSet").should("be.visible")
})
})
Expand Down
29 changes: 14 additions & 15 deletions agenta-web/cypress/e2e/testset.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,19 @@ describe("Testsets crud and UI functionality", () => {
context("Testing creation process of testset", () => {
beforeEach(() => {
// navigate to the new testset page
cy.visit(`/apps/${app_id}/testsets/new/manual`)
})

it("Should navigates successfully to the new testset page", () => {
cy.url().should("include", "/testsets/new/manual")
})

it("Should not allow creation of a testset without a name", () => {
cy.get('[data-cy="testset-save-button"]').click()
cy.get('[data-cy="testset-name-reqd-error"]').should("be.visible")
cy.visit(`/apps/${app_id}/testsets`)
})

it("Should successfully creates the testset and navigates to the list", () => {
cy.url().should("include", "/testsets")
cy.get('[data-cy="create-testset-modal-button"]').click()
cy.get(".ant-modal-content").should("exist")
cy.get('[data-cy="create-testset-from-scratch"]').click()

const testsetName = randString(8)
cy.get('[data-cy="testset-name-input"]').type(testsetName)
cy.clickLinkAndWait('[data-cy="create-new-testset-button"]')

cy.get(".ag-row").should("have.length", 3)
countries.forEach((country, index) => {
cy.get(`.ag-center-cols-container .ag-row[row-index="${index}"]`).within(() => {
Expand All @@ -51,7 +49,6 @@ describe("Testsets crud and UI functionality", () => {

// validate that the new testset is in the list
cy.get('[data-cy="app-testset-list"]').as("table")
cy.get("@table").get(".ant-table-pagination li a").last().click()
cy.get("@table").contains(testsetName).as("tempTestSet").should("be.visible")
})
})
Expand All @@ -64,19 +61,21 @@ describe("Testsets crud and UI functionality", () => {

it("Should successfully upload a testset", () => {
cy.url().should("include", "/testsets")
cy.clickLinkAndWait('[data-cy="testset-new-upload-link"]')
cy.url().should("include", "/testsets/new/upload")

cy.get('[data-cy="create-testset-modal-button"]').click()
cy.get(".ant-modal-content").should("exist")
cy.get('[data-cy="upload-testset"]').click()

cy.get('[data-cy="upload-testset-file-name"]').type(testset_name)
cy.get('[type="file"]').selectFile("cypress/data/countries-genders.csv", {force: true})
cy.wait(1000)
cy.contains("countries-genders.csv").should("be.visible")
cy.get('[data-cy="testset-upload-button"]').click()
cy.clickLinkAndWait('[data-cy="testset-upload-button"]')
})

it("Should check the uploaded testset is present", () => {
cy.url().should("include", "/testsets")
cy.get('[data-cy="app-testset-list"]').as("table")
cy.get("@table").get(".ant-table-pagination li a").last().click()
cy.get("@table").contains(testset_name).as("tempTestSet").should("be.visible")
})
})
Expand Down
8 changes: 5 additions & 3 deletions agenta-web/cypress/support/commands/evaluations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@ Cypress.Commands.add("createVariantsAndTestsets", () => {
cy.createVariant()

cy.clickLinkAndWait('[data-cy="app-testsets-link"]')
cy.get('[data-cy="app-testsets-link"]').trigger("mouseout")
cy.clickLinkAndWait('[data-cy="testset-new-manual-link"]')
const testsetName = randString(5)
cy.get('[data-cy="create-testset-modal-button"]').click()
cy.get(".ant-modal-content").should("exist")
cy.get('[data-cy="create-testset-from-scratch"]').click()

const testsetName = randString(5)
cy.get('[data-cy="testset-name-input"]').type(testsetName)
cy.clickLinkAndWait('[data-cy="create-new-testset-button"]')
cy.wrap(testsetName).as("testsetName")

cy.get(".ag-row").should("have.length", 3)
Expand Down
Binary file added agenta-web/public/assets/not-found.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion agenta-web/src/components/DynamicCodeBlock/CodeBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const CodeBlock: FC<CodeBlockProps> = ({language, value}) => {
language={language}
style={appTheme === "dark" ? darcula : coy}
showLineNumbers
wrapLongLines={true}
wrapLongLines={false}
>
{value}
</SyntaxHighlighter>
Expand Down
37 changes: 37 additions & 0 deletions agenta-web/src/components/NoResultsFound/NoResultsFound.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from "react"
import {Typography} from "antd"
import Image from "next/image"
import {createUseStyles} from "react-jss"
import {JSSTheme} from "@/lib/Types"

const useStyles = createUseStyles((theme: JSSTheme) => ({
notFound: {
width: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
padding: "80px 0px",
gap: 16,
"& > span": {
lineHeight: theme.lineHeightHeading4,
fontSize: theme.fontSizeHeading4,
fontWeight: theme.fontWeightMedium,
},
},
}))

const NoResultsFound = ({className}: {className?: string}) => {
const classes = useStyles()
return (
<div className={`${classes.notFound} ${className}`}>
<Image src="/assets/not-found.png" alt="not-found" width={240} height={210} />
<Typography.Text>No Results found</Typography.Text>
<Typography.Paragraph type="secondary">
No results match the search criteria.
</Typography.Paragraph>
</div>
)
}

export default NoResultsFound
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,14 @@ const TableHeaderComponent = ({
setInputValues(scopedInputValues)
updateTable(scopedInputValues)
setIsEditInputOpen(false)
setIsDataChanged(true)
}
}

const handleInputChange = (index: number, event: React.ChangeEvent<HTMLInputElement>) => {
const values = [...inputValues]
values[index] = event.target.value
setScopedInputValues(values)
setIsDataChanged(true)
}

const onAddColumn = () => {
Expand Down
46 changes: 4 additions & 42 deletions agenta-web/src/components/TestSetTable/TestsetTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,22 @@ import {IHeaderParams} from "ag-grid-community"
import {createUseStyles} from "react-jss"
import {Button, Input, Typography, message} from "antd"
import TestsetMusHaveNameModal from "./InsertTestsetNameModal"
import {fetchVariants} from "@/services/api"
import {createNewTestset, fetchTestset, updateTestset} from "@/services/testsets/api"
import {fetchTestset, updateTestset} from "@/services/testsets/api"
import {useRouter} from "next/router"
import {useAppTheme} from "../Layout/ThemeContextProvider"
import useBlockNavigation from "@/hooks/useBlockNavigation"
import {useUpdateEffect} from "usehooks-ts"
import useStateCallback from "@/hooks/useStateCallback"
import {AxiosResponse} from "axios"
import EditRowModal from "./EditRowModal"
import {getVariantInputParameters} from "@/lib/helpers/variantHelper"
import {convertToCsv, downloadCsv} from "@/lib/helpers/fileManipulations"
import {NoticeType} from "antd/es/message/interface"
import {GenericObject, KeyValuePair} from "@/lib/Types"
import TableCellsRenderer from "./TableCellsRenderer"
import TableHeaderComponent from "./TableHeaderComponent"

type TestsetTableProps = {
mode: "create" | "edit"
mode: "edit"
}
export type ColumnDefsType = {field: string; [key: string]: any}

Expand Down Expand Up @@ -85,7 +83,6 @@ const TestsetTable: React.FC<TestsetTableProps> = ({mode}) => {
const [inputValues, setInputValues] = useStateCallback(columnDefs.map((col) => col.field))
const [focusedRowData, setFocusedRowData] = useState<GenericObject>()
const [writeMode, setWriteMode] = useState(mode)
const [testsetId, setTestsetId] = useState(undefined)
const gridRef = useRef<any>(null)

const [selectedRow, setSelectedRow] = useState([])
Expand Down Expand Up @@ -119,19 +116,10 @@ const TestsetTable: React.FC<TestsetTableProps> = ({mode}) => {
async function applyColData(colData: {field: string}[] = []) {
const newColDefs = createNewColDefs(colData)
setColumnDefs(newColDefs)
if (writeMode === "create") {
const initialRowData = Array(3).fill({})
const separateRowData = initialRowData.map(() => {
return colData.reduce((acc, curr) => ({...acc, [curr.field]: ""}), {})
})

setRowData(separateRowData)
}
setInputValues(newColDefs.filter((col) => !!col.field).map((col) => col.field))
}

if (writeMode === "edit" && testset_id) {
setIsDataChanged(true)
fetchTestset(testset_id as string).then((data) => {
setTestsetName(data.name)
setRowData(data.csvdata)
Expand All @@ -141,19 +129,6 @@ const TestsetTable: React.FC<TestsetTableProps> = ({mode}) => {
})),
)
})
} else if (writeMode === "create" && appId) {
setIsDataChanged(true)
;(async () => {
const backendVariants = await fetchVariants(appId)
const variant = backendVariants[0]
const inputParams = await getVariantInputParameters(appId, variant)
const colData = inputParams.map((param) => ({field: param.name}))
colData.push({field: "correct_answer"})

applyColData(colData)
})().catch(() => {
applyColData([])
})
}
}, [writeMode, testset_id, appId])

Expand Down Expand Up @@ -233,24 +208,11 @@ const TestsetTable: React.FC<TestsetTableProps> = ({mode}) => {
}
}

if (writeMode === "create") {
if (!testsetName) {
setIsModalOpen(true)
setIsLoading(false)
} else {
const response = await createNewTestset(appId, testsetName, rowData)
afterSave(response)
setTestsetId(response.data.id)
}
} else if (writeMode === "edit") {
if (writeMode === "edit") {
if (!testsetName) {
setIsModalOpen(true)
} else {
const response = await updateTestset(
(testsetId || testset_id) as string,
testsetName,
rowData,
)
const response = await updateTestset(testset_id as string, testsetName, rowData)
afterSave(response)
}
}
Expand Down
76 changes: 76 additions & 0 deletions agenta-web/src/components/pages/testset/modals/CreateTestset.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import React from "react"
import {JSSTheme} from "@/lib/Types"
import {Typography} from "antd"
import {createUseStyles} from "react-jss"

const {Text, Paragraph} = Typography

const useStyles = createUseStyles((theme: JSSTheme) => ({
headerText: {
lineHeight: theme.lineHeightLG,
fontSize: theme.fontSizeHeading4,
fontWeight: theme.fontWeightStrong,
},
appTemplate: {
gap: 16,
display: "flex",
flexDirection: "column",
},
template: {
border: "1px solid",
borderColor: theme.colorBorderSecondary,
borderRadius: theme.borderRadiusLG,
paddingTop: theme.paddingSM,
paddingBottom: theme.paddingSM,
paddingInline: theme.padding,
boxShadow:
"0px 2px 4px 0px #00000005, 0px 1px 6px -1px #00000005, 0px 1px 2px 0px #00000008",
gap: 2,
cursor: "pointer",
"& > span": {
fontSize: theme.fontSizeLG,
lineHeight: theme.lineHeightLG,
fontWeight: theme.fontWeightMedium,
},
"& > div": {
marginBottom: 0,
},
},
}))

type Props = {setCurrent: React.Dispatch<React.SetStateAction<number>>}

const CreateTestset: React.FC<Props> = ({setCurrent}) => {
const classes = useStyles()
return (
<section className={classes.appTemplate}>
<Text className={classes.headerText}>Create new test set</Text>
<div className="flex flex-col gap-6">
<div
className={classes.template}
onClick={() => setCurrent(1)}
data-cy="create-testset-from-scratch"
>
<Text>Create from scratch</Text>
<Paragraph>Create a new test set directly from the webUI</Paragraph>
</div>
<div
className={classes.template}
onClick={() => setCurrent(2)}
data-cy="upload-testset"
>
<Text>Upload a test set</Text>
<Paragraph>Upload your test set as CSV or JSON</Paragraph>
</div>
<div className={classes.template} onClick={() => setCurrent(3)}>
<Text>Create with API</Text>
<Paragraph>
Create a test set programmatically using our API endpoints
</Paragraph>
</div>
</div>
</section>
)
}

export default CreateTestset
Loading
Loading