-
Notifications
You must be signed in to change notification settings - Fork 0
Feature/show precomputed results tweaks #146
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
Changes from 12 commits
bd571c5
fdba1c7
c05b6f9
efa879f
cd11abb
a9b3864
3aa354c
dae5a6a
2353947
1a595f1
774e287
dd22a51
9517f3f
893bb5a
3e50510
a157b63
369421c
72092e3
29f22d1
dc5b4b2
0b84b49
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,16 +1,17 @@ | ||
| import { SIMULARIUM_EMBED_URL } from "../../constants/urls"; | ||
| import { useResultUrl } from "../../state/store"; | ||
| import "./style.css"; | ||
|
|
||
| interface ViewerProps { | ||
| resultUrl: string; | ||
| } | ||
|
|
||
| const Viewer = (props: ViewerProps): JSX.Element => { | ||
| const { resultUrl } = props; | ||
| const Viewer = (): JSX.Element => { | ||
| const resultUrl = useResultUrl(); | ||
| return ( | ||
| <div className="viewer-container"> | ||
| <iframe className="simularium-embed" src={resultUrl} /> | ||
| <iframe | ||
| className="simularium-embed" | ||
| src={`${SIMULARIUM_EMBED_URL}${resultUrl}`} | ||
| /> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default Viewer; | ||
| export default Viewer; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| import { EditableField, PackingResults } from "../types"; | ||
|
|
||
| // stable/frozen empty array to prevent re-renders | ||
| export const EMPTY_FIELDS: readonly EditableField[] = Object.freeze([]); | ||
| export const EMPTY_PACKING_RESULTS: PackingResults = Object.freeze({ | ||
| jobId: "", | ||
| jobStatus: "", | ||
meganrm marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| jobLogs: "", | ||
| resultUrl: "", | ||
| runTime: -1, | ||
meganrm marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| outputDir: "", | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,10 @@ | ||
| import { create } from "zustand"; | ||
| import { subscribeWithSelector } from "zustand/middleware"; | ||
| import { get as lodashGet, set as lodashSet } from "lodash-es"; | ||
| import { PackingInputs } from "../types"; | ||
| import { PackingResults, RecipeManifest } from "../types"; | ||
| import { getFirebaseRecipe, jsonToString } from "../utils/recipeLoader"; | ||
| import { getPackingInputsDict } from "../utils/firebase"; | ||
| import { EMPTY_PACKING_RESULTS } from "./constants"; | ||
|
|
||
| export interface RecipeData { | ||
| id: string; | ||
|
|
@@ -14,8 +15,9 @@ export interface RecipeData { | |
|
|
||
| export interface RecipeState { | ||
| selectedRecipeId: string; | ||
| inputOptions: Record<string, PackingInputs>; | ||
| inputOptions: Record<string, RecipeManifest>; | ||
| recipes: Record<string, RecipeData>; | ||
| packingResults: PackingResults; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think ideally we want packingResults to be a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah I was thinking about that, maybe good to have in a separate PR
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
|
|
||
| export interface UIState { | ||
|
|
@@ -43,6 +45,9 @@ type Actions = { | |
| recipeString: string | ||
| ) => Promise<void> | ||
| ) => Promise<void>; | ||
| setPackingResults: (results: PackingResults) => void; | ||
| setJobLogs: (logs: string) => void; | ||
| setJobId: (jobId: string) => void; | ||
| }; | ||
|
|
||
| export type RecipeStore = RecipeState & UIState & Actions; | ||
|
|
@@ -55,6 +60,7 @@ const initialState: RecipeState & UIState = { | |
| recipes: {}, | ||
| isLoading: false, | ||
| isPacking: false, | ||
| packingResults: { ...EMPTY_PACKING_RESULTS }, | ||
| }; | ||
|
|
||
| export const useRecipeStore = create<RecipeStore>()( | ||
|
|
@@ -114,6 +120,9 @@ export const useRecipeStore = create<RecipeStore>()( | |
| }, | ||
|
|
||
| selectRecipe: async (recipeId) => { | ||
| set({ | ||
| packingResults: { ...EMPTY_PACKING_RESULTS }, | ||
| }); | ||
| const sel = get().inputOptions[recipeId]; | ||
| if (!sel) return; | ||
|
|
||
|
|
@@ -126,6 +135,27 @@ export const useRecipeStore = create<RecipeStore>()( | |
| } | ||
| }, | ||
|
|
||
| setPackingResults: (results: PackingResults) => { | ||
| set({ packingResults: results }); | ||
| }, | ||
|
|
||
| setJobLogs: (logs: string) => { | ||
| set({ | ||
| packingResults: { | ||
| ...(get().packingResults as PackingResults), | ||
| jobLogs: logs, | ||
| }, | ||
| }); | ||
meganrm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }, | ||
| setJobId: (jobId: string) => { | ||
| set({ | ||
| packingResults: { | ||
| ...(get().packingResults as PackingResults), | ||
| jobId: jobId, | ||
| }, | ||
| }); | ||
meganrm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }, | ||
|
|
||
| updateRecipeString: (recipeId, newString) => { | ||
| set((s) => { | ||
| const rec = s.recipes[recipeId]; | ||
|
|
@@ -216,12 +246,13 @@ export const useRecipeStore = create<RecipeStore>()( | |
| })) | ||
| ); | ||
|
|
||
| // tiny helpers/selectors (all derived — not stored) | ||
| // simple selectors | ||
| export const useSelectedRecipeId = () => | ||
| useRecipeStore((s) => s.selectedRecipeId); | ||
| export const useCurrentRecipeString = () => | ||
| useRecipeStore((s) => s.recipes[s.selectedRecipeId]?.currentString ?? ""); | ||
| export const useInputOptions = () => useRecipeStore((s) => s.inputOptions); | ||
|
|
||
| export const useIsLoading = () => useRecipeStore((s) => s.isLoading); | ||
| export const useIsPacking = () => useRecipeStore((s) => s.isPacking); | ||
| export const useFieldsToDisplay = () => | ||
|
|
@@ -230,6 +261,53 @@ export const useIsCurrentRecipeModified = () => | |
| useRecipeStore((s) => s.recipes[s.selectedRecipeId]?.isModified ?? false); | ||
| export const useGetOriginalValue = () => | ||
| useRecipeStore((s) => s.getOriginalValue); | ||
| const usePackingResults = () => useRecipeStore((s) => s.packingResults); | ||
|
|
||
| // compound selectors | ||
|
|
||
| const useCurrentRecipeManifest = () => { | ||
| const selectedRecipeId = useSelectedRecipeId(); | ||
| const inputOptions = useInputOptions(); | ||
| if (!selectedRecipeId) return undefined; | ||
| return inputOptions[selectedRecipeId]; | ||
| }; | ||
| const useDefaultResultPath = () => { | ||
| const manifest = useCurrentRecipeManifest(); | ||
| return manifest?.defaultResultPath || ""; | ||
| }; | ||
|
|
||
| export const useRunTime = () => { | ||
| const results = usePackingResults(); | ||
| return results ? results.runTime : 0; | ||
| }; | ||
|
|
||
| export const useJobLogs = () => { | ||
| const results = usePackingResults(); | ||
| return results ? results.jobLogs : ""; | ||
| }; | ||
|
|
||
| export const useJobId = () => { | ||
| const results = usePackingResults(); | ||
| return results ? results.jobId : ""; | ||
| }; | ||
|
|
||
| export const useOutputsDirectory = () => { | ||
| const results = usePackingResults(); | ||
| return results ? results.outputDir : ""; | ||
meganrm marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| }; | ||
|
|
||
| export const useResultUrl = () => { | ||
| let path = ""; | ||
| const results = usePackingResults(); | ||
| const currentRecipeId = useSelectedRecipeId(); | ||
| const defaultResultPath = useDefaultResultPath(); | ||
| if (results.resultUrl) { | ||
| path = results.resultUrl; | ||
| } else if (currentRecipeId) { | ||
| path = defaultResultPath; | ||
| } | ||
| return path; | ||
| }; | ||
meganrm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // action selectors (stable identities) | ||
| export const useLoadInputOptions = () => | ||
|
|
@@ -245,3 +323,7 @@ export const useRestoreRecipeDefault = () => | |
| export const useStartPacking = () => useRecipeStore((s) => s.startPacking); | ||
| export const useGetCurrentValue = () => | ||
| useRecipeStore((s) => s.getCurrentValue); | ||
| export const useSetPackingResults = () => | ||
| useRecipeStore((s) => s.setPackingResults); | ||
| export const useSetJobLogs = () => useRecipeStore((s) => s.setJobLogs); | ||
| export const useSetJobId = () => useRecipeStore((s) => s.setJobId); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ export interface Document { | |
| recipe?: string; | ||
| config?: string; | ||
| editable_fields?: string[]; | ||
| result_path?: string; | ||
| } | ||
|
|
||
| export type FirestoreDoc = Document & { | ||
|
|
@@ -15,10 +16,11 @@ export interface Dictionary<T> { | |
| [Key: string]: T; | ||
| } | ||
|
|
||
| export type PackingInputs = { | ||
| export type RecipeManifest = { | ||
| name?: string; | ||
| config: string; | ||
| recipe: string; | ||
| defaultResultPath?: string; | ||
| editable_fields?: EditableField[]; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should use camel case here? |
||
| }; | ||
|
|
||
|
|
@@ -29,6 +31,14 @@ export type JobStatusObject = { | |
| result_path: string; | ||
| }; | ||
|
|
||
| export type PackingResults = { | ||
| jobId: string; | ||
| jobLogs: string; | ||
| resultUrl: string; | ||
| runTime: number; | ||
| outputDir: string; | ||
| }; | ||
|
|
||
| export type EditableField = { | ||
| id: string; | ||
| name: string; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.