Skip to content

Commit 27bd4fa

Browse files
committed
more refinement
1 parent 11c7306 commit 27bd4fa

File tree

6 files changed

+82
-31
lines changed

6 files changed

+82
-31
lines changed

app/models/job/JobService.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ class JobService @Inject()(wkConf: WkConf,
262262
private def getJobCostPerGVx(jobCommand: JobCommand): Fox[BigDecimal] =
263263
jobCommand match {
264264
case JobCommand.infer_neurons => Fox.successful(wkConf.Features.neuronInferralCostPerGVx)
265+
case JobCommand.infer_nuclei => Fox.successful(wkConf.Features.neuronInferralCostPerGVx)
265266
case JobCommand.infer_mitochondria => Fox.successful(wkConf.Features.mitochondriaInferralCostPerGVx)
266267
case JobCommand.align_sections => Fox.successful(wkConf.Features.alignmentCostPerGVx)
267268
case _ => Fox.failure(s"Unsupported job command $jobCommand")

frontend/javascripts/viewer/view/action_bar_view.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ import {
4444
import type { StartAIJobModalState } from "./action-bar/ai_job_modals/constants";
4545
// import { StartAIJobModal } from "./action-bar/ai_job_modals/start_ai_job_modal";
4646
import ToolkitView from "./action-bar/tools/toolkit_switcher_view";
47+
import { AiJobsDrawer } from "./ai_jobs/ai_jobs_drawer";
4748
import ButtonComponent from "./components/button_component";
4849
import { NumberSliderSetting } from "./components/setting_input_views";
49-
import { AiJobsDrawer } from "./ai_jobs/ai_jobs_drawer";
5050

5151
const VersionRestoreWarning = (
5252
<Alert

frontend/javascripts/viewer/view/ai_jobs/ai_jobs_drawer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Drawer, Tabs } from "antd";
2+
import { AiImageAlignment } from "./alignment/ai_image_alignment_job";
23
import { AiImageSegmentation } from "./run_ai_model/ai_image_segmentation_job";
34
import { AiModelTraining } from "./train_ai_model/ai_model_training_job";
4-
import { AiImageAlignment } from "./alignment/ai_image_alignment_job";
55

66
const { TabPane } = Tabs;
77

frontend/javascripts/viewer/view/ai_jobs/credit_information.tsx

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1+
import { CreditCardOutlined } from "@ant-design/icons";
2+
import { useQuery } from "@tanstack/react-query";
13
import { type JobCreditCostInfo, getJobCreditCost } from "admin/rest_api";
2-
import { Button, Card, Col, Row, Spin, Typography } from "antd";
4+
import { Button, Card, Col, Row, Space, Spin, Typography } from "antd";
5+
import features from "features";
36
import { formatCreditsString, formatVoxels } from "libs/format_utils";
4-
import { useFetch } from "libs/react_helpers";
57
import { useWkSelector } from "libs/react_hooks";
68
import { computeArrayFromBoundingBox } from "libs/utils";
79
import type React from "react";
8-
import { useRunAiModelJobContext } from "./run_ai_model/ai_image_segmentation_job_context";
9-
import BoundingBox from "viewer/model/bucket_data_handling/bounding_box";
1010
import { useCallback, useMemo } from "react";
1111
import { APIJobType } from "types/api_types";
12-
import features from "features";
12+
import BoundingBox from "viewer/model/bucket_data_handling/bounding_box";
13+
import { useRunAiModelJobContext } from "./run_ai_model/ai_image_segmentation_job_context";
1314

1415
const { Title, Text } = Typography;
1516

1617
export const CreditInformation: React.FC = () => {
17-
const jobTypeToCreditCostPerGVx: Record<APIJobType, number> = useMemo(
18+
const jobTypeToCreditCostPerGVx: Partial<Record<APIJobType, number>> = useMemo(
1819
() => ({
1920
[APIJobType.INFER_NUCLEI]: features().neuronInferralCostPerGVx,
2021
[APIJobType.INFER_NEURONS]: features().neuronInferralCostPerGVx,
@@ -30,17 +31,19 @@ export const CreditInformation: React.FC = () => {
3031
(state) => state.activeOrganization?.creditBalance || "0",
3132
);
3233

33-
const jobCreditCostInfo = useFetch<JobCreditCostInfo | undefined>(
34-
async () =>
35-
selectedBoundingBox && selectedJobType
36-
? await getJobCreditCost(
37-
selectedJobType,
38-
computeArrayFromBoundingBox(selectedBoundingBox.boundingBox),
39-
)
40-
: undefined,
41-
undefined,
42-
[selectedBoundingBox, selectedJobType],
43-
);
34+
const { data: jobCreditCostInfo, isFetching } = useQuery<JobCreditCostInfo>({
35+
queryKey: [
36+
"jobCreditCost",
37+
selectedJobType ?? "no-type",
38+
selectedBoundingBox?.boundingBox ?? "no-bb",
39+
],
40+
queryFn: async () =>
41+
await getJobCreditCost(
42+
selectedJobType!,
43+
computeArrayFromBoundingBox(selectedBoundingBox!.boundingBox),
44+
),
45+
enabled: Boolean(selectedBoundingBox && selectedJobType),
46+
});
4447

4548
const getBoundingBoxinVoxels = useCallback((): string => {
4649
if (selectedBoundingBox) {
@@ -53,7 +56,14 @@ export const CreditInformation: React.FC = () => {
5356
const costInCredits = jobCreditCostInfo?.costInCredits;
5457

5558
return (
56-
<Card title="Credit Information">
59+
<Card
60+
title={
61+
<Space align="center">
62+
<CreditCardOutlined style={{ color: "#ddbc00" }} />
63+
Credit Information
64+
</Space>
65+
}
66+
>
5767
<Row justify="space-between" align="middle">
5868
<Col>
5969
<Text>Available Credits</Text>
@@ -96,7 +106,7 @@ export const CreditInformation: React.FC = () => {
96106
<Text>Total Cost:</Text>
97107
</Col>
98108
<Col>
99-
{jobCreditCostInfo === undefined && selectedBoundingBox && selectedModel ? (
109+
{isFetching && selectedBoundingBox && selectedModel ? (
100110
<Spin size="small" />
101111
) : (
102112
<Text strong>{costInCredits ? formatCreditsString(costInCredits) : "-"}</Text>

frontend/javascripts/viewer/view/ai_jobs/run_ai_model/ai_analysis_parameters.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import { Card, Col, Input, Row, Select, Typography } from "antd";
1+
import { SettingOutlined } from "@ant-design/icons";
2+
import { Card, Col, Input, Row, Select, Space, Typography } from "antd";
23
import { useWkSelector } from "libs/react_hooks";
34
import type React from "react";
45
import { getColorLayers } from "viewer/model/accessors/dataset_accessor";
56
import { BoundingBoxSelector } from "../bounding_box_selector";
67
import { useRunAiModelJobContext } from "./ai_image_segmentation_job_context";
78

8-
const { Text } = Typography;
9+
const { Text, Title } = Typography;
910

1011
export const AiAnalysisParameters: React.FC = () => {
1112
const {
@@ -20,7 +21,14 @@ export const AiAnalysisParameters: React.FC = () => {
2021
const colorLayers = getColorLayers(dataset);
2122

2223
return (
23-
<Card title="Analysis Parameters">
24+
<Card
25+
title={
26+
<Space align="center">
27+
<SettingOutlined style={{ color: "#1890ff" }} />
28+
Analysis Parameters
29+
</Space>
30+
}
31+
>
2432
<Row gutter={24}>
2533
<Col span={12}>
2634
<div style={{ marginBottom: "16px" }}>

frontend/javascripts/viewer/view/ai_jobs/run_ai_model/ai_model_selector.tsx

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import { ExperimentOutlined } from "@ant-design/icons";
12
import { APIAiModelCategory, getAiModels } from "admin/rest_api";
23
import { Avatar, Card, Input, List, Space, Spin, Tag, Typography } from "antd";
34
import { useGuardedFetch } from "libs/react_helpers";
45
import type React from "react";
6+
import { useMemo, useState } from "react";
57
import { APIJobType, type AiModel } from "types/api_types";
68
import { useRunAiModelJobContext } from "./ai_image_segmentation_job_context";
79

@@ -46,6 +48,7 @@ const mapCategoryToJobType = (category: APIAiModelCategory): APIJobType => {
4648

4749
export const AiModelSelector: React.FC = () => {
4850
const { selectedModel, setSelectedModel, setSelectedJobType } = useRunAiModelJobContext();
51+
const [searchTerm, setSearchTerm] = useState("");
4952

5053
const [customModels, isLoading] = useGuardedFetch(
5154
async function () {
@@ -72,16 +75,45 @@ export const AiModelSelector: React.FC = () => {
7275
setSelectedJobType(jobType as APIJobType);
7376
};
7477

75-
return (
76-
<Card title="Select AI Model">
77-
<div style={{ marginBottom: "24px" }}>
78-
<Input.Search placeholder="Search models..." style={{ width: 300 }} />
79-
</div>
78+
const filterModels = (models: (AiModel | (Partial<AiModel> & { jobType?: APIJobType }))[]) => {
79+
if (!searchTerm) {
80+
return models;
81+
}
82+
const lowerCaseSearchTerm = searchTerm.toLowerCase();
83+
return models.filter(
84+
(model) =>
85+
model.name.toLowerCase().includes(lowerCaseSearchTerm) ||
86+
(model.comment && model.comment.toLowerCase().includes(lowerCaseSearchTerm)),
87+
);
88+
};
8089

90+
const filteredPreTrainedModels = useMemo(() => filterModels(preTrainedModels), [searchTerm]);
91+
const filteredCustomModels = useMemo(
92+
() => filterModels(customModels),
93+
[searchTerm, customModels],
94+
);
95+
96+
return (
97+
<Card
98+
title={
99+
<Space align="center">
100+
<ExperimentOutlined style={{ color: "#1890ff" }} />
101+
Select AI Model
102+
</Space>
103+
}
104+
extra={
105+
<Input.Search
106+
placeholder="Search models..."
107+
style={{ width: 300 }}
108+
onChange={(e) => setSearchTerm(e.target.value)}
109+
value={searchTerm}
110+
/>
111+
}
112+
>
81113
<Title level={5}>Pre-trained Models</Title>
82114
<List
83115
itemLayout="horizontal"
84-
dataSource={preTrainedModels}
116+
dataSource={filteredPreTrainedModels}
85117
renderItem={(item) => (
86118
<List.Item
87119
style={{
@@ -118,7 +150,7 @@ export const AiModelSelector: React.FC = () => {
118150
) : (
119151
<List
120152
itemLayout="horizontal"
121-
dataSource={customModels}
153+
dataSource={filteredCustomModels}
122154
renderItem={(item) => (
123155
<List.Item
124156
style={{

0 commit comments

Comments
 (0)