Skip to content
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
16 changes: 0 additions & 16 deletions src/components/JSONViewer/style.css
Original file line number Diff line number Diff line change
@@ -1,25 +1,9 @@
.recipe-box {
width: 45%;
float: left;
}

.config-box {
width: 45%;
float: right;
}

.recipe-json {
max-height: 300px;
width: 450px;
overflow-y: auto;
}

.config-json {
max-height: 300px;
width: 450px;
overflow-y: auto;
}

.collapsible {
width: 450px;
margin-top: 5%;
Expand Down
61 changes: 20 additions & 41 deletions src/components/PackingInput/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useEffect, useState } from "react";
import { FirebaseDict } from "../../types";
import { FIRESTORE_COLLECTIONS } from "../../constants/firebase";
import { getDocById, getLocationDict } from "../../utils/firebase";
import { Dictionary, PackingInputs } from "../../types";
import { getPackingInputsDict } from "../../utils/firebase";
import { getFirebaseRecipe } from "../../utils/recipeLoader";
import Dropdown from "../Dropdown";
import JSONViewer from "../JSONViewer";
Expand All @@ -15,37 +14,34 @@ const PackingInput = (props: PackingInputProps): JSX.Element => {
const { startPacking } = props;
const [selectedRecipeId, setSelectedRecipeId] = useState("");
const [selectedConfigId, setSelectedConfigId] = useState("");
const [recipes, setRecipes] = useState<FirebaseDict>({});
const [configs, setConfigs] = useState<FirebaseDict>({});
const [selectedInputId, setSelectedInputId] = useState("");
const [inputOptions, setInputOptions] = useState<Dictionary<PackingInputs>>({});
const [recipeStr, setRecipeStr] = useState<string>("");
const [configStr, setConfigStr] = useState<string>("");
const [viewRecipe, setViewRecipe] = useState<boolean>(true);
const [viewConfig, setViewConfig] = useState<boolean>(true);

useEffect(() => {
const fetchData = async () => {
const recipeDict = await getLocationDict(FIRESTORE_COLLECTIONS.RECIPES);
const configDict = await getLocationDict(FIRESTORE_COLLECTIONS.CONFIGS);
setRecipes(recipeDict);
setConfigs(configDict);
const inputDict = await getPackingInputsDict();
setInputOptions(inputDict);
};
fetchData();
}, []);

const selectRecipe = async (recipe: string) => {
setSelectedRecipeId(recipe);
const recStr = await getFirebaseRecipe(recipe);
setRecipeStr(recStr);
const selectInput = async (inputName: string) => {
setSelectedInputId(inputName);
const recipeId: string = inputOptions[inputName]?.recipe || "";
const configId: string = inputOptions[inputName]?.config || "";
await selectRecipe(recipeId);
setSelectedConfigId(configId);
}

const selectConfig = async (config: string) => {
setSelectedConfigId(config);
const confStr = await getDocById(FIRESTORE_COLLECTIONS.CONFIGS, config);
setConfigStr(confStr);
const selectRecipe = async (recipeId: string) => {
setSelectedRecipeId(recipeId);
const recStr = await getFirebaseRecipe(recipeId);
setRecipeStr(recStr);
}

const runPacking = async () => {
setViewConfig(false);
setViewRecipe(false);
startPacking(selectedRecipeId, selectedConfigId, recipeStr);
};
Expand All @@ -54,26 +50,16 @@ const PackingInput = (props: PackingInputProps): JSX.Element => {
setViewRecipe(!viewRecipe);
}

const toggleConfig = () => {
setViewConfig(!viewConfig);
}

return (
<div>
<div className="input-container">
<Dropdown
value={selectedRecipeId}
value={selectedInputId}
placeholder="Select a recipe"
options={recipes}
onChange={selectRecipe}
options={inputOptions}
onChange={selectInput}
/>
<Dropdown
value={selectedConfigId}
placeholder="Select a config"
options={configs}
onChange={selectConfig}
/>
<button onClick={runPacking} disabled={!selectedRecipeId}>
<button onClick={runPacking} disabled={!selectedInputId}>
Pack
</button>
</div>
Expand All @@ -86,13 +72,6 @@ const PackingInput = (props: PackingInputProps): JSX.Element => {
onToggle={toggleRecipe}
onChange={setRecipeStr}
/>
<JSONViewer
title="Config"
content={configStr}
isVisible={viewConfig}
isEditable={false}
onToggle={toggleConfig}
/>
</div>
</div>
);
Expand Down
5 changes: 2 additions & 3 deletions src/components/PackingInput/style.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
.box {
display: flex;
justify-content: space-between;
flex-direction: row;
text-align: start;
justify-content: center;
align-items: center;
}
3 changes: 3 additions & 0 deletions src/constants/firebase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const FIRESTORE_COLLECTIONS = {
EXAMPLE_RECIPES: "example_recipes",
EDITED_RECIPES: "recipes_edited",
JOB_STATUS: "job_status",
PACKING_INPUTS: "example_packings",
};

//firestore field names
Expand All @@ -34,6 +35,8 @@ export const FIRESTORE_FIELDS = {
URL: "url",
STATUS: "status",
TIMESTAMP: "timestamp",
RECIPE: "recipe",
CONFIG: "config",
} as const;

export const RETENTION_POLICY = {
Expand Down
7 changes: 7 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ export interface Document {
name?: string;
original_location?: string;
recipe_path?: string;
recipe?: string;
config?: string;
}

export type FirestoreDoc = Document & {
Expand Down Expand Up @@ -31,6 +33,11 @@ export interface Dictionary<T> {
[Key: string]: T;
}

export type PackingInputs = {
config: string;
recipe: string;
}

export interface RefsByCollection {
recipes: Dictionary<FirebaseRecipe>;
composition: Dictionary<FirebaseComposition>;
Expand Down
32 changes: 16 additions & 16 deletions src/utils/firebase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ import {
RETENTION_POLICY,
} from "../constants/firebase";
import {
FirebaseDict,
FirestoreDoc,
PackingInputs,
Dictionary,
} from "../types";

const getEnvVar = (key: string): string => {
Expand Down Expand Up @@ -119,22 +120,21 @@ const getAllDocsFromCollection = async (collectionName: string) => {
return mapQuerySnapshotToDocs(querySnapshot);
};

const getLocationDict = async (collectionName: string) => {
const docs = await getAllDocsFromCollection(collectionName);
// docs is an array of objects, each with an id, a name, and other fields
// we want to create a dictionary with the name as the key and the original_location as the value
// `reduce` is a method that takes an array and reduces it to a single value
const locationDict = docs.reduce((locationDict: FirebaseDict, doc: FirestoreDoc) => {
const getPackingInputsDict = async () => {
const docs = await getAllDocsFromCollection(FIRESTORE_COLLECTIONS.PACKING_INPUTS);
const inputsDict: Dictionary<PackingInputs> = docs.reduce((inputsDict: Dictionary<PackingInputs>, doc: FirestoreDoc) => {
const name = doc[FIRESTORE_FIELDS.NAME];
const id = doc.id;
if (name) {
locationDict[name] = {
[FIRESTORE_FIELDS.FIREBASE_ID]: id,
const config = doc[FIRESTORE_FIELDS.CONFIG];
const recipe = doc[FIRESTORE_FIELDS.RECIPE];
if (name && config && recipe) {
inputsDict[name] = {
[FIRESTORE_FIELDS.CONFIG]: config,
[FIRESTORE_FIELDS.RECIPE]: recipe,
};
}
return locationDict;
}, {} as FirebaseDict);
return locationDict;
}
return inputsDict;
}, {});
return inputsDict;
}

const getDocById = async (coll: string, id: string) => {
Expand Down Expand Up @@ -184,4 +184,4 @@ const docCleanup = async () => {
console.log(`Cleaned up ${deletePromises.length} documents from ${collectionConfig.name}`);
}
}
export { db, queryDocumentById, getLocationDict, getDocById, getDocsByIds, getJobStatus, getResultPath, addRecipe, docCleanup };
export { db, queryDocumentById, getDocById, getDocsByIds, getJobStatus, getResultPath, addRecipe, docCleanup, getPackingInputsDict };