# Retool Setup with Database Query ## Database Structure Your table has: - **id** (problem name, e.g., "0a1d4ef5") - **json** (ARC puzzle JSON stored as text) ## Setup Instructions ### Step 1: Create Database Query 1. In Retool, add a **SQL Query** (or REST API query, depending on your database) 2. Name it something like `arcPuzzleQuery` 3. Write your query: ```sql SELECT id, json FROM arc_problems WHERE id = {{ selectProblem.value }} -- Or to get all: -- SELECT id, json FROM arc_problems ``` ### Step 2: Add JavaScript Code 1. Create a new **JavaScript Query** named `arcRenderCode` 2. Copy and paste the **entire contents** of `arcRender_retool.js` 3. Set it to run **On page load** (optional, just loads the functions) ### Step 3: Create HTML Component for Main Display 1. Add an **HTML** component 2. In the HTML content field, use: #### Option A: If json column is already parsed as object ```javascript {{ renderArcPuzzle(arcPuzzleQuery.data[0].json) }} ``` #### Option B: If json column is stored as text string ```javascript {{ renderArcPuzzle(JSON.parse(arcPuzzleQuery.data[0].json)) }} ``` #### Option C: With error handling ```javascript {{ (() => { try { const puzzleData = arcPuzzleQuery.data && arcPuzzleQuery.data[0] ? arcPuzzleQuery.data[0].json : null; if (!puzzleData) { return '
No puzzle selected
'; } // Parse if it's a string, otherwise use as-is const data = typeof puzzleData === 'string' ? JSON.parse(puzzleData) : puzzleData; return renderArcPuzzle(data); } catch (error) { return '
Error loading puzzle: ' + error.message + '
'; } })() }} ``` ### Step 4: Add Problem Selector (Optional) 1. Add a **Select** component named `selectProblem` 2. Set **Data source** to query all problem IDs: ```sql SELECT id, id as label FROM arc_problems ORDER BY id ``` 3. Set the select to trigger `arcPuzzleQuery` on change ### Step 5: Add Test Output Component (Separate) 1. Add another **HTML** component for the test output answer 2. Add a **Toggle** or **Button** component to control visibility 3. In the HTML component: ```javascript {{ (() => { if (!toggleShowAnswer.value) { return ''; // Hidden } try { const puzzleData = arcPuzzleQuery.data && arcPuzzleQuery.data[0] ? arcPuzzleQuery.data[0].json : null; if (!puzzleData) { return '
No puzzle data
'; } const data = typeof puzzleData === 'string' ? JSON.parse(puzzleData) : puzzleData; // Check if test output exists if (!data.test || !data.test[0] || !data.test[0].output) { return '
No test output available
'; } return renderTestOutput(data.test[0].output); } catch (error) { return '
Error: ' + error.message + '
'; } })() }} ``` ## Complete Retool Layout Example ``` ┌─────────────────────────────────────┐ │ Select Problem: [Dropdown ▼] │ └─────────────────────────────────────┘ ┌─────────────────────────────────────┐ │ HTML Component (Main Puzzle) │ │ {{ renderArcPuzzle(...) }} │ │ │ │ [Training Examples Display] │ │ [Test Input Display] │ └─────────────────────────────────────┘ ┌─────────────────────────────────────┐ │ [Toggle] Show Test Answer │ └─────────────────────────────────────┘ ┌─────────────────────────────────────┐ │ HTML Component (Test Output) │ │ {{ renderTestOutput(...) }} │ │ (Visible only if toggle is on) │ └─────────────────────────────────────┘ ``` ## Troubleshooting ### "renderArcPuzzle is not defined" - Make sure the JavaScript query with the render functions is set to run on page load - Or copy the functions directly into the HTML component's JS section ### "Unexpected token" or JSON parsing errors - Check if your json column returns a string or object - Use `console.log(typeof arcPuzzleQuery.data[0].json)` to check - Adjust parsing accordingly (use JSON.parse only if it's a string) ### Puzzle not displaying - Check the browser console (F12) for errors - Verify query returned data: `{{ arcPuzzleQuery.data }}` - Test with a simple value first: `{{ JSON.stringify(arcPuzzleQuery.data[0]) }}` ### Grid borders not showing correctly - Make sure the HTML component has enough width/height - Try setting min-height on the HTML component (e.g., 800px) ## Alternative: Inline Function Approach If you have issues with the separate JavaScript query, you can inline everything: ```javascript {{ // Color mapping for ARC puzzles (0-9) const ARC_COLORS = { 0: '#000000', 1: '#0074D9', 2: '#FF4136', 3: '#2ECC40', 4: '#FFDC00', 5: '#AAAAAA', 6: '#F012BE', 7: '#FF851B', 8: '#7FDBFF', 9: '#85144b' }; function renderGrid(grid, label) { // ... paste full function here } function renderPair(inputGrid, outputGrid, exampleIndex) { // ... paste full function here } function renderArcPuzzle(jsonData) { // ... paste full function here } // Then call it const data = typeof arcPuzzleQuery.data[0].json === 'string' ? JSON.parse(arcPuzzleQuery.data[0].json) : arcPuzzleQuery.data[0].json; return renderArcPuzzle(data); }} ``` ## Database Query Examples ### PostgreSQL ```sql SELECT id, json::text as json FROM arc_problems WHERE id = {{ selectProblem.value }} ``` ### MySQL ```sql SELECT id, json FROM arc_problems WHERE id = {{ selectProblem.value }} ``` ### SQLite ```sql SELECT id, json FROM arc_problems WHERE id = ? -- Use {{ selectProblem.value }} as parameter ```