From b066fbf5640c0485ff774577ef69ee6718033734 Mon Sep 17 00:00:00 2001 From: Alex Lin Date: Wed, 28 Aug 2024 07:53:43 +0900 Subject: [PATCH] Chore: Improved CSV Preview truncation, bugfixes (#42) * Improved how truncation is handled in CsvPreview * Updated various broken text sample inputs --- README.md | 2 + .../QuickInput/QuickInput.stories.js | 28 +++---- .../QuickInput/Tabs/CsvInput/CsvPreview.js | 79 ++++++++++++------- .../QuickInput/Tabs/CsvInput/CsvPreview.scss | 51 +++++++++++- .../Tabs/SampleInput/SampleInputsTab.js | 2 +- .../Outputs/AudioToText/AudioToTextOutput.js | 2 - .../testDocumentQuestionAnsweringOuput.js | 2 +- .../Outputs/Text/testData/testTextOutput.js | 2 +- .../testData/testTextClassification.js | 2 +- .../testTextGuidedImageToImageOutput.js | 2 +- .../testData/testTextToAudioOutput.js | 2 +- .../testData/testTextToCodeOutput.js | 2 +- .../testData/testTextToImageOutput.js | 2 +- .../testData/testTextToVideoOutput.js | 2 +- .../testVisualQuestionAnsweringOutput.js | 2 +- src/helpers/Task.js | 3 +- src/helpers/sampleImages.js | 59 +++++++------- src/resources/icons/icon-tableEditing.svg | 5 +- 18 files changed, 154 insertions(+), 95 deletions(-) diff --git a/README.md b/README.md index 3d7ae706..07fd4580 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,7 @@ The project is structured as follows: - `TaskName.scss` - Create a new story for the task in `QuickInput.stories.js` + - For the sample inputs, you'll create them below. Come back and import them here once you have. - If the task requires new input type(s), you will need to add those: - Add the new input type to `TaskInputTypes` and `QuickInputType` @@ -113,6 +114,7 @@ The project is structured as follows: - You can temporarily switch the default state for `selectedTab` to the index of your new tab, so that you don't need to repeatedly switch tabs through page refreshes - Update `SampleInputsTab`: - Open `sampleImages.js` and add `Sample[TaskName]Inputs`. If your task is using `useMultiInput` then you will need to make a parent array, and then for each input type another array of sample input objects. + - Go back to `QuickInput.stories.js` and update the sample inputs - Add the new input type to `makeSampleInput` - Create a `makeSample[input type]Input` function - Add the new input type with appropriate text to `makeTaskTitle` diff --git a/src/components/Experiment/QuickInput/QuickInput.stories.js b/src/components/Experiment/QuickInput/QuickInput.stories.js index 60dbc7a2..cbc55702 100644 --- a/src/components/Experiment/QuickInput/QuickInput.stories.js +++ b/src/components/Experiment/QuickInput/QuickInput.stories.js @@ -45,7 +45,11 @@ import { SampleAudioClassificationInputs, SampleVideoClassificationInputs, SampleMaskGenerationInputs, - SampleTableEditingInputs + SampleTableEditingInputs, + SampleTextToAudio, + SampleTextConversationInputs, + SampleTextToCodeInputs, + SampleTextInputs } from "../../../helpers/sampleImages"; import { TaskInputTypes } from "../../../helpers/TaskInputTypes"; @@ -132,11 +136,7 @@ MaskGeneration.args = { export const Text = Template.bind({}); Text.args = { - sampleInputs: [ - "The quick brown fox jumps over the lazy dog", - "The five boxing wizards jump quickly", - "look at the dog", - ], + sampleInputs: SampleTextInputs, model: { output: { type: textToText, @@ -146,11 +146,7 @@ Text.args = { export const TextToCode = Template.bind({}); TextToCode.args = { - sampleInputs: [ - "The quick brown fox jumps over the lazy dog", - "The five boxing wizards jump quickly", - "look at the dog", - ], + sampleInputs: SampleTextToCodeInputs, model: { output: { type: textToCode, @@ -186,9 +182,7 @@ AudioToText.args = { export const TextToAudio = Template.bind({}); TextToAudio.args = { - sampleInputs: [ - "a chill song with influences from lofi, chillstep and downtempo", - ], + sampleInputs: SampleTextToAudio, model: { output: { type: textToAudio, @@ -198,11 +192,7 @@ TextToAudio.args = { export const TextConversation = Template.bind({}); TextConversation.args = { - sampleInputs: [ - "Show me a recipe for pizza", - "What is the weather tomorrow?", - "What is the meaning of life?", - ], + sampleInputs: SampleTextConversationInputs, model: { output: { type: textConversation, diff --git a/src/components/Experiment/QuickInput/Tabs/CsvInput/CsvPreview.js b/src/components/Experiment/QuickInput/Tabs/CsvInput/CsvPreview.js index 61237274..1b339ce0 100644 --- a/src/components/Experiment/QuickInput/Tabs/CsvInput/CsvPreview.js +++ b/src/components/Experiment/QuickInput/Tabs/CsvInput/CsvPreview.js @@ -6,6 +6,7 @@ import useBEMNaming from "../../../../../common/useBEMNaming"; import "./CsvPreview.scss"; const columnLimit = 10; +const rowLimit = 10; export default function CsvPreview(props) { const csvUrl = props.url; @@ -14,20 +15,22 @@ export default function CsvPreview(props) { const [csvHeaders, setCsvHeaders] = useState([]); const [csvData, setCsvData] = useState([]); - const [isTruncated, setIsTruncated] = useState(false); + const [rowsTruncated, setRowsTruncated] = useState(false); + const [colsTruncated, setColsTruncated] = useState(false); const config = { header: true, download: true, dynamicTyping: true, - preview: 10, // Only parse (and display) the first 10 rows of the csv file - complete: function(results) { + preview: rowLimit, // Only parse the first X rows of the csv file + complete: (results) => { const { errors, meta, data } = results; const fields = meta.fields; setCsvHeaders(fields) - setCsvData(data); - setIsTruncated(meta.truncated || (fields.length > columnLimit)); + setCsvData(data); + setRowsTruncated(meta.truncated); // T/F depending on if config.preview was less than # of rows in the csv + setColsTruncated(fields.length > columnLimit) if (errors.length > 0) { // Per PapaParse documentation, errors don't necessarily mean that parsing failed @@ -42,19 +45,27 @@ export default function CsvPreview(props) { return (
-
+ { (rowsTruncated || colsTruncated) && ( +
+ Note: This table has been truncated. + You can download the full file below. +
+ )} +
{ csvData.length > 0 ? (
-
- { csvHeaders.map((header, index) => { - if (index < columnLimit) { - return ( -
- {header} -
- ) - } - })} +
+
+ { csvHeaders.map((header, index) => { + if (index < columnLimit) { + return ( +
+ {header} +
+ ) + } + })} +
{ csvData.map((item, rowIndex) => { return ( @@ -63,28 +74,30 @@ export default function CsvPreview(props) { if (colIndex < columnLimit) { const cellText = !(val instanceof Date) ? val : val.toDateString(); return ( -
-
+
+
+ {cellText} +
+
+ {cellText} -
-
- - {cellText} - -
+
+
) }}) }
) })} - { isTruncated && ( + { rowsTruncated && (
-
- Note: This table has been truncated. - You can download the full file below. +
+ ...
+ {[...Array(columnLimit - 1)].map((x, i) => +
+ )}
)}
@@ -93,6 +106,16 @@ export default function CsvPreview(props) { Loading csv data...
)} + { colsTruncated && ( +
+
+ ... +
+ {[...Array(rowLimit)].map((x, i) => +
+ )} +
+ )}
) diff --git a/src/components/Experiment/QuickInput/Tabs/CsvInput/CsvPreview.scss b/src/components/Experiment/QuickInput/Tabs/CsvInput/CsvPreview.scss index 8d126815..4b6b4680 100644 --- a/src/components/Experiment/QuickInput/Tabs/CsvInput/CsvPreview.scss +++ b/src/components/Experiment/QuickInput/Tabs/CsvInput/CsvPreview.scss @@ -3,12 +3,20 @@ .csv-preview { width: 902px; // 90px per cell * 10 cells per row + 2px border + &__table-container { + display: flex; + flex-direction: row; + } &__table { display: flex; flex-direction: column; border: 1px solid $charcoalLightest; font-size: 13px; } + &__max-header { + display: flex; + flex-direction: row; + } &__header { display: flex; flex-direction: row; @@ -27,7 +35,10 @@ &__cell { border-right: 1px solid $charcoalLightest; padding: 5px; + display: flex; + align-items: center; width: 90px; + height: 42px; } &__cell:last-of-type { border-right: none; @@ -56,8 +67,44 @@ &__cell:hover .tooltip-text { visibility: visible; } - &__truncated { - padding: 10px 5px; + &__warning { color: $darkRed; + padding-bottom: 20px; + } + &__truncated-table { + color: $darkRed; + border-top: 1px solid $charcoalLightest; + border-right: 1px solid $charcoalLightest; + border-bottom: 1px solid $charcoalLightest; + } + &__truncated-header { + color: $darkRed; + background-color: $smokeDarkest; + border-bottom: 1px solid $charcoalLightest; + display: flex; + align-items: center; + height: 43px; + padding: 5px; + } + &__truncated-header, &__truncated-row-cell { + font-size: 20px; + letter-spacing: 2px; + } + &__truncated-col-cell, &__truncated-row-cell { + padding: 5px; + display: flex; + align-items: center; + } + &__truncated-row-cell { + width: 90px; + border-right: 1px solid $charcoalLightest; + color: $darkRed; + } + &__truncated-row-cell:last-of-type { + border-right: none; + } + &__truncated-col-cell { + height: 43px; + border-bottom: 1px solid $charcoalLightest; } } \ No newline at end of file diff --git a/src/components/Experiment/QuickInput/Tabs/SampleInput/SampleInputsTab.js b/src/components/Experiment/QuickInput/Tabs/SampleInput/SampleInputsTab.js index 2de65398..8641ac09 100644 --- a/src/components/Experiment/QuickInput/Tabs/SampleInput/SampleInputsTab.js +++ b/src/components/Experiment/QuickInput/Tabs/SampleInput/SampleInputsTab.js @@ -74,7 +74,7 @@ export default function SampleInputsTab(props) { function makeSampleTextInput(text, index) { return ( ); } diff --git a/src/components/Experiment/QuickOutput/Outputs/AudioToText/AudioToTextOutput.js b/src/components/Experiment/QuickOutput/Outputs/AudioToText/AudioToTextOutput.js index 15892fc2..a2a57c6c 100644 --- a/src/components/Experiment/QuickOutput/Outputs/AudioToText/AudioToTextOutput.js +++ b/src/components/Experiment/QuickOutput/Outputs/AudioToText/AudioToTextOutput.js @@ -9,8 +9,6 @@ import { TextOutputBox } from "../Text/TextOutputBox"; import { audioToText } from "../../../../../helpers/TaskIDs"; export default function AudioToTextOutput(props) { - console.log("AudioToTextOutput", props) - const { getBlock } = useBEMNaming("audio-to-text-output"); const { output, inferenceDuration, input, setInput } = useTextOutput( props.trial diff --git a/src/components/Experiment/QuickOutput/Outputs/DocumentQuestionAnswering/testData/testDocumentQuestionAnsweringOuput.js b/src/components/Experiment/QuickOutput/Outputs/DocumentQuestionAnswering/testData/testDocumentQuestionAnsweringOuput.js index c428fe5b..1b693e2b 100644 --- a/src/components/Experiment/QuickOutput/Outputs/DocumentQuestionAnswering/testData/testDocumentQuestionAnsweringOuput.js +++ b/src/components/Experiment/QuickOutput/Outputs/DocumentQuestionAnswering/testData/testDocumentQuestionAnsweringOuput.js @@ -11,7 +11,7 @@ export const TestDocumentQuestionAnswering = { inputType:"document" }, { - description: "Hello World", + src: "Hello World", inputType:"text" } ], diff --git a/src/components/Experiment/QuickOutput/Outputs/Text/testData/testTextOutput.js b/src/components/Experiment/QuickOutput/Outputs/Text/testData/testTextOutput.js index 9f7df8db..d980d1f1 100644 --- a/src/components/Experiment/QuickOutput/Outputs/Text/testData/testTextOutput.js +++ b/src/components/Experiment/QuickOutput/Outputs/Text/testData/testTextOutput.js @@ -106,7 +106,7 @@ export const TestTextOutputGeneratedToken = { export const TestTextOutput = { id: "9d52d414-cc78-4cd5-a292-afdc0b9332ec", inputs: [ - 'translate English to German: "Luigi often said to me that he never wanted the brothers to end up in court," she wrote.', + { src: 'translate English to German: "Luigi often said to me that he never wanted the brothers to end up in court," she wrote.' }, ], completed_at: "2022-06-03T18:17:14.513854Z", results: { diff --git a/src/components/Experiment/QuickOutput/Outputs/TextClassification/testData/testTextClassification.js b/src/components/Experiment/QuickOutput/Outputs/TextClassification/testData/testTextClassification.js index 41a679e9..c4cbedde 100644 --- a/src/components/Experiment/QuickOutput/Outputs/TextClassification/testData/testTextClassification.js +++ b/src/components/Experiment/QuickOutput/Outputs/TextClassification/testData/testTextClassification.js @@ -4,7 +4,7 @@ export const TestTextClassificationOutputGeneratedToken = { export const TestTextClassificationOutput = { id: "sampletesttextclassificationoutputidhere", - inputs: ["The weather is very pleasant today."], + inputs: [{ src: "The weather is very pleasant today." }], completed_at: "2023-06-03T18:17:14.513854Z", results: { 'duration': "9.216154124s", diff --git a/src/components/Experiment/QuickOutput/Outputs/TextGuidedImageToImage/testData/testTextGuidedImageToImageOutput.js b/src/components/Experiment/QuickOutput/Outputs/TextGuidedImageToImage/testData/testTextGuidedImageToImageOutput.js index b55386c7..b489306a 100644 --- a/src/components/Experiment/QuickOutput/Outputs/TextGuidedImageToImage/testData/testTextGuidedImageToImageOutput.js +++ b/src/components/Experiment/QuickOutput/Outputs/TextGuidedImageToImage/testData/testTextGuidedImageToImageOutput.js @@ -13,7 +13,7 @@ export const TestTextGuidedImageToImage = { inputType: "image" }, { - description: "Hello World", + src: "Hello World", inputType: "text" } ], diff --git a/src/components/Experiment/QuickOutput/Outputs/TextToAudio/testData/testTextToAudioOutput.js b/src/components/Experiment/QuickOutput/Outputs/TextToAudio/testData/testTextToAudioOutput.js index 51e927cf..5f8c2126 100644 --- a/src/components/Experiment/QuickOutput/Outputs/TextToAudio/testData/testTextToAudioOutput.js +++ b/src/components/Experiment/QuickOutput/Outputs/TextToAudio/testData/testTextToAudioOutput.js @@ -5,7 +5,7 @@ export const TestTextToAudioOutputGeneratedToken = { export const TestTextToAudioOutput = { id: "sampletesttexttoaudiooutputidhere", inputs: [ - 'a chill song with influences from lofi, chillstep and downtempo', + { src: 'a chill song with influences from lofi, chillstep and downtempo' }, ], completed_at: "2023-06-03T18:17:14.513854Z", results: { diff --git a/src/components/Experiment/QuickOutput/Outputs/TextToCode/testData/testTextToCodeOutput.js b/src/components/Experiment/QuickOutput/Outputs/TextToCode/testData/testTextToCodeOutput.js index 861a9673..8ed78048 100644 --- a/src/components/Experiment/QuickOutput/Outputs/TextToCode/testData/testTextToCodeOutput.js +++ b/src/components/Experiment/QuickOutput/Outputs/TextToCode/testData/testTextToCodeOutput.js @@ -3,7 +3,7 @@ import { textToCode } from "../../../../../../helpers/TaskIDs"; export const TestTextToCodeOutput = { id: "9d52d414-cc78-4cd5-a292-afdc0b9332ec", inputs: [ - "write an iterator that squares each element of a list of numbers and returns an iterator of the squares.", + { src: "write an iterator that squares each element of a list of numbers and returns an iterator of the squares." }, ], completed_at: "2022-06-03T18:17:14.513854Z", results: { diff --git a/src/components/Experiment/QuickOutput/Outputs/TextToImage/testData/testTextToImageOutput.js b/src/components/Experiment/QuickOutput/Outputs/TextToImage/testData/testTextToImageOutput.js index 2310b9cb..05c49e8b 100644 --- a/src/components/Experiment/QuickOutput/Outputs/TextToImage/testData/testTextToImageOutput.js +++ b/src/components/Experiment/QuickOutput/Outputs/TextToImage/testData/testTextToImageOutput.js @@ -8,7 +8,7 @@ export const TestTextToImageGeneratedToken = { export const TestTextToImageOutput = { id: "sampletesttexttovideooutputidhere", inputs: [ - 'a chill song with influences from lofi, chillstep and downtempo', + { src: 'a chill song with influences from lofi, chillstep and downtempo' }, ], completed_at: "2023-06-03T18:17:14.513854Z", results: { diff --git a/src/components/Experiment/QuickOutput/Outputs/TextToVideo/testData/testTextToVideoOutput.js b/src/components/Experiment/QuickOutput/Outputs/TextToVideo/testData/testTextToVideoOutput.js index b3e54ca9..64073922 100644 --- a/src/components/Experiment/QuickOutput/Outputs/TextToVideo/testData/testTextToVideoOutput.js +++ b/src/components/Experiment/QuickOutput/Outputs/TextToVideo/testData/testTextToVideoOutput.js @@ -8,7 +8,7 @@ export const TestTextToVideoGeneratedToken = { export const TestTextToVideoOutput = { id: "sampletesttexttovideooutputidhere", inputs: [ - 'a chill song with influences from lofi, chillstep and downtempo', + { src: 'a chill song with influences from lofi, chillstep and downtempo' }, ], completed_at: "2023-06-03T18:17:14.513854Z", results: { diff --git a/src/components/Experiment/QuickOutput/Outputs/VisualQuestionAnswering/testData/testVisualQuestionAnsweringOutput.js b/src/components/Experiment/QuickOutput/Outputs/VisualQuestionAnswering/testData/testVisualQuestionAnsweringOutput.js index 37e954a5..ffac21bd 100644 --- a/src/components/Experiment/QuickOutput/Outputs/VisualQuestionAnswering/testData/testVisualQuestionAnsweringOutput.js +++ b/src/components/Experiment/QuickOutput/Outputs/VisualQuestionAnswering/testData/testVisualQuestionAnsweringOutput.js @@ -13,7 +13,7 @@ export const TestVisualQuestionAnswering = { inputType: "image" }, { - description: "Hello World", + src: "Hello World", inputType: "text" } ], diff --git a/src/helpers/Task.js b/src/helpers/Task.js index 505eda07..b8f72a37 100644 --- a/src/helpers/Task.js +++ b/src/helpers/Task.js @@ -97,6 +97,7 @@ import { SampleAudioClassificationInputs, SampleVideoClassificationInputs, SampleTableEditingInputs, + SampleTextToAudio, } from "./sampleImages"; import { TestImageClassificationResult } from "../components/Experiment/QuickOutput/Outputs/Classification/Features"; import { TestImageEnhancementData } from "../components/Experiment/QuickOutput/Outputs/ImageEnhancement/testData/TestFeatures"; @@ -304,7 +305,7 @@ export default class Task { inputText: "See how well this model can generate audio from inputted text.", outputText: "Play the file below to listen to the generated audio file.", icon: (props) => , - sampleInputs: [], + sampleInputs: SampleTextToAudio, tutorialDescription: "Text to audio models bring your written words to life.", inputType: TaskInputTypes.Text, diff --git a/src/helpers/sampleImages.js b/src/helpers/sampleImages.js index 224c431d..595aa299 100644 --- a/src/helpers/sampleImages.js +++ b/src/helpers/sampleImages.js @@ -118,15 +118,15 @@ export const SampleMaskGenerationInputs = [ ] export const SampleTextInputs = [ - "Lorem ipsum dolor sit amet", - "Consectetur adipiscing elit", - "Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua", + { src: "Lorem ipsum dolor sit amet" }, + { src: "Consectetur adipiscing elit" }, + { src: "Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua" }, ]; export const SampleTextToCodeInputs = [ - "Lorem ipsum dolor sit amet", - "Consectetur adipiscing elit", - "Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua", + { src: "Lorem ipsum dolor sit amet" }, + { src: "Consectetur adipiscing elit" }, + { src: "Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua" }, ]; export const SampleAudioToTextInputs = [ @@ -137,9 +137,9 @@ export const SampleAudioToTextInputs = [ ]; export const SampleTextConversationInputs = [ - "Show me a recipe for pizza", - "What is the weather tomorrow?", - "What is the meaning of life?", + { src: "Show me a recipe for pizza" }, + { src: "What is the weather tomorrow?" }, + { src: "What is the meaning of life?", } ]; export const SampleVisualQuestionAnsweringInputs = [ [{ @@ -156,9 +156,9 @@ export const SampleVisualQuestionAnsweringInputs = [ } ], [ - "What is the color of the bird?", - "What is the animal in the image?", - "Where is the crab?" + { src: "What is the color of the bird?" }, + { src: "What is the animal in the image?" }, + { src: "Where is the crab?" } ] ]; export const SampleTextGuidedImageToImageInputs = [ @@ -176,9 +176,9 @@ export const SampleTextGuidedImageToImageInputs = [ } ], [ - "Replace the background with a beach.", - "Make the animal look like a cartoon.", - "Make the image look like a painting." + { src: "Replace the background with a beach." }, + { src: "Make the animal look like a cartoon." }, + { src: "Make the image look like a painting." } ] ]; export const SampleDocumentQuestionAnsweringInputs = [ @@ -196,21 +196,21 @@ export const SampleDocumentQuestionAnsweringInputs = [ } ], [ - "What is the color of the bird?", - "What is the animal in the image?", - "What is the total amount in the invoice?" + { src: "What is the color of the bird?" }, + { src: "What is the animal in the image?" }, + { src: "What is the total amount in the invoice?" } ] ]; export const SampleTextToImageInputs = [ - "Cat and dog playing", - "Flower in a garden", - "Sunset on a beach" + { src: "Cat and dog playing" }, + { src: "Flower in a garden" }, + { src: "Sunset on a beach" } ]; export const SampleTextToVideoInputs = [ - "Cat and dog playing", - "Flower in a garden", - "Sunset on a beach" + { src: "Cat and dog playing" }, + { src: "Flower in a garden" }, + { src: "Sunset on a beach" } ]; export const SampleImageToTextInputs = [ @@ -233,9 +233,9 @@ export const SampleTextTo3DInputs = [ ]; export const SampleTextClassificationInputs = [ - "The weather is very pleasant today.", - "The ending of the movie was sad.", - "There is a car parked there." + { src: "The weather is very pleasant today." }, + { src: "The ending of the movie was sad." }, + { src: "There is a car parked there." }, ]; export const SampleAudioToAudioInputs = [ @@ -263,9 +263,7 @@ export const SampleAudioClassificationInputs = [ }, ]; export const SampleTextToAudio = [ - "Waves at a beach", - "Traffic noise", - "Roar of a tiger" + { src: "a chill song with influences from lofi, chillstep and downtempo" }, ]; export const SampleVideoClassificationInputs = [ @@ -282,7 +280,6 @@ export const SampleVideoClassificationInputs = [ { description: "Video of a flower", src: "https://xlab1.netlify.app/samples/video/flower.mp4" - }, ]; diff --git a/src/resources/icons/icon-tableEditing.svg b/src/resources/icons/icon-tableEditing.svg index 88f83c78..659777b1 100644 --- a/src/resources/icons/icon-tableEditing.svg +++ b/src/resources/icons/icon-tableEditing.svg @@ -1,5 +1,6 @@ - - + + +