Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Dynamic Facet Explorer</title> | |
| <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet"> | |
| <style> | |
| .sticky-query { | |
| position: sticky; | |
| top: 0; | |
| z-index: 1; | |
| background-color: white; | |
| padding: 1rem; | |
| box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | |
| animation: zoomIn 0.5s ease-out; | |
| } | |
| .box-format { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 25%; /* Adjust the width as needed */ | |
| height: 100vh; | |
| z-index: 1; | |
| background-color: white; | |
| padding: 1rem; | |
| box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | |
| overflow-y: auto; | |
| } | |
| .fade-in { | |
| animation: fadeIn 0.5s ease-out; | |
| } | |
| @keyframes fadeIn { | |
| 0% { opacity: 0; } | |
| 100% { opacity: 1; } | |
| } | |
| .sticky-sidebar { | |
| position: sticky; | |
| top: 0; | |
| height: 100vh; | |
| overflow-y: auto; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50 min-h-screen font-sans text-gray-800"> | |
| <div class="container mx-auto px-4 py-12 flex"> | |
| <!-- Sidebar Content --> | |
| <div class="box-format w-1/4 sticky-sidebar bg-white rounded-lg shadow-md p-6 min-h-screen"> | |
| <h1 class="text-2xl font-bold mb-6 text-center">Output Generator 2</h1> | |
| <!-- Input for API key --> | |
| <div class="mb-4"> | |
| <input type="password" id="apiKeyInput" class="form-control border border-gray-300 p-2 rounded-md w-full" placeholder="Enter your API key" /> | |
| </div> | |
| <!-- Suggestions --> | |
| <div class="mb-4"> | |
| <button type="button" class="btn btn-info mt-2 w-full flex items-center justify-center" onclick="fetchSuggestion()"> | |
| <svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 21a2 2 0 01-2-2V5a2 2 0 012-2h6a2 2 0 012 2v14a2 2 0 01-2 2h-6z"></path> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 14a2 2 0 100-4 2 2 0 000 4z"></path> | |
| </svg> | |
| Find Facets | |
| </button> | |
| </div> | |
| <!-- Loading Indicator --> | |
| <div id="loadingIndicator" class="mb-4 hidden"> | |
| <div class="spinner-border animate-spin inline-block w-8 h-8 border-4 rounded-full" role="status"></div> | |
| </div> | |
| <form id="dynamicForm" class="space-y-4"> | |
| <div id="inputContainer" class="space-y-4"> | |
| <!-- Initial Input Box --> | |
| <div class="flex items-center space-x-2"> | |
| <input type="text" class="form-control border border-gray-300 p-2 rounded-md flex-grow" placeholder="Enter value"> | |
| <button type="button" class="btn btn-danger delete-btn" onclick="deleteInput(this)" disabled> | |
| <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path> | |
| </svg> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="flex justify-between space-x-4"> | |
| <button type="button" class="btn btn-primary" onclick="addInput()">Add Facets</button> | |
| <button type="submit" class="btn btn-success">Facet List</button> | |
| <button type="button" class="btn btn-secondary" onclick="resetForm()">Reset</button> | |
| </div> | |
| </form> | |
| <!-- Output container --> | |
| <div id="output" class="mt-6 p-4 bg-gray-200 rounded-md hidden"> | |
| <h2 class="text-lg font-semibold mb-2">Output:</h2> | |
| <pre id="formattedOutput" class="text-gray-800 font-mono whitespace-pre-wrap"></pre> | |
| </div> | |
| </div> | |
| <!-- Main Content --> | |
| <div class="w-3/4 pl-4"> | |
| <!-- Query Input --> | |
| <div class="sticky-query bg-white rounded-lg shadow-lg p-8 mb-12"> | |
| <div class="mb-6"> | |
| <label for="query" class="block text-lg font-medium text-gray-700 mb-2">Query</label> | |
| <input type="text" id="query" placeholder="Enter your query" class="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
| </div> | |
| </div> | |
| <!-- Section 1: Input --> | |
| <div class="bg-white rounded-lg shadow-lg p-8 mb-12"> | |
| <div class="mb-6"> | |
| <label for="given_facet" class="block text-lg font-medium text-gray-700 mb-2">Given Facet</label> | |
| <input type="text" id="given_facet" placeholder="Enter your facet in Python dictionary format" class="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
| </div> | |
| <div class="mb-6"> | |
| <label class="block text-lg font-medium text-gray-700 mb-2">Processing Method</label> | |
| <div class="flex items-center space-x-4"> | |
| <label class="inline-flex items-center"> | |
| <input type="radio" name="processingMethod" value="v1" checked class="form-radio h-5 w-5 text-blue-600"> | |
| <span class="ml-2">V1 (Original)</span> | |
| </label> | |
| <label class="inline-flex items-center"> | |
| <input type="radio" name="processingMethod" value="v2" class="form-radio h-5 w-5 text-blue-600"> | |
| <span class="ml-2">V2 (New)</span> | |
| </label> | |
| </div> | |
| </div> | |
| <button id="submit" class="w-full bg-blue-600 text-white py-3 px-6 rounded-md hover:bg-blue-700 transition duration-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">Submit</button> | |
| </div> | |
| <!-- Section 2: Dynamic Boxes --> | |
| <div id="dynamicBoxes" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"></div> | |
| <!-- Get List Button --> | |
| <div class="mt-12 text-center"> | |
| <button id="getList" class="bg-green-600 text-white py-3 px-8 rounded-md hover:bg-green-700 transition duration-300 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2">Get List</button> | |
| <button id="reset" class="bg-red-600 text-white py-3 px-8 ml-4 rounded-md hover:bg-red-700 transition duration-300 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2">Reset</button> | |
| </div> | |
| <!-- Result Display --> | |
| <div id="result" class="mt-12 text-center text-2xl font-semibold"></div> | |
| </div> | |
| </div> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> | |
| <script> | |
| $(document).ready(function() { | |
| let isResultShown = false; | |
| let facetData = []; | |
| $('#submit').click(function() { | |
| const query = $('#query').val(); | |
| const givenFacet = $('#given_facet').val(); | |
| const processingMethod = $('input[name="processingMethod"]:checked').val(); | |
| try { | |
| if (processingMethod === 'v1') { | |
| facetData = eval('(' + givenFacet + ')'); | |
| } else { | |
| facetData = JSON.parse(givenFacet.replace(/'/g, '"')); | |
| } | |
| generateBoxes(facetData, processingMethod); | |
| resetResult(); | |
| } catch (error) { | |
| alert('Invalid facet format. Please check your input and try again.'); | |
| } | |
| }); | |
| function generateBoxes(facetObj, method) { | |
| const $dynamicBoxes = $('#dynamicBoxes').empty(); | |
| if (method === 'v1') { | |
| Object.entries(facetObj).forEach(([key, values]) => { | |
| createBox(key, values); | |
| }); | |
| } else { | |
| facetObj.forEach((item, index) => { | |
| const [key, values] = Object.entries(item)[0]; | |
| createBox(key, values, index); | |
| }); | |
| } | |
| function createBox(key, values, index = null) { | |
| const $box = $('<div>').addClass('bg-white rounded-lg shadow-md p-6 fade-in'); | |
| const $title = $('<div>').addClass('flex items-center justify-between mb-4') | |
| .append($('<h2>').addClass('text-xl font-semibold').text(`'${key}'`)) | |
| .append($('<input>').attr({ | |
| type: 'checkbox', | |
| name: key, | |
| 'data-index': index, | |
| class: 'form-checkbox h-5 w-5 text-blue-600' | |
| })); | |
| const $content = $('<div>').addClass('space-y-2'); | |
| values.forEach(value => { | |
| $content.append($('<p>').addClass('text-gray-600').text(value)); | |
| }); | |
| $box.append($title).append($content); | |
| $dynamicBoxes.append($box); | |
| } | |
| } | |
| $('#getList').click(function() { | |
| const processingMethod = $('input[name="processingMethod"]:checked').val(); | |
| let result; | |
| if (processingMethod === 'v1') { | |
| result = $('input[type="checkbox"]:checked').map(function() { | |
| return `'${this.name}'`; | |
| }).get(); | |
| } else { | |
| result = facetData.reduce((acc, facetObj, index) => { | |
| const [key] = Object.keys(facetObj); | |
| const $categoryCheckbox = $(`input[type="checkbox"][data-index="${index}"]`); | |
| if ($categoryCheckbox.is(':checked')) { | |
| acc.push(`'${key}'`); | |
| } | |
| return acc; | |
| }, []); | |
| } | |
| const formattedResult = `[${result.join(', ')}]`; | |
| $('#result').text(formattedResult).addClass('fade-in'); | |
| isResultShown = true; | |
| }); | |
| $('#reset').click(function() { | |
| $('input[type="checkbox"]').prop('checked', false); | |
| if (isResultShown) { | |
| $('#result').text('').removeClass('fade-in'); | |
| isResultShown = false; | |
| } | |
| }); | |
| function resetResult() { | |
| $('#result').text('').removeClass('fade-in'); | |
| isResultShown = false; | |
| } | |
| }); | |
| // Add input field | |
| function addInput() { | |
| const container = document.getElementById('inputContainer'); | |
| const newInput = document.createElement('div'); | |
| newInput.className = 'flex items-center space-x-2'; | |
| newInput.innerHTML = ` | |
| <input type="text" class="form-control border border-gray-300 p-2 rounded-md flex-grow" placeholder="Enter value"> | |
| <button type="button" class="btn btn-danger delete-btn" onclick="deleteInput(this)"> | |
| <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path> | |
| </svg> | |
| </button> | |
| `; | |
| container.appendChild(newInput); | |
| updateDeleteButtons(); | |
| } | |
| // Delete input field | |
| function deleteInput(button) { | |
| button.parentElement.remove(); | |
| updateDeleteButtons(); | |
| } | |
| // Update delete button states | |
| function updateDeleteButtons() { | |
| const deleteButtons = document.querySelectorAll('.delete-btn'); | |
| deleteButtons.forEach(btn => { | |
| btn.disabled = deleteButtons.length === 1; | |
| }); | |
| } | |
| // Reset form | |
| function resetForm() { | |
| const container = document.getElementById('inputContainer'); | |
| container.innerHTML = ` | |
| <div class="flex items-center space-x-2"> | |
| <input type="text" class="form-control border border-gray-300 p-2 rounded-md flex-grow" placeholder="Enter value"> | |
| <button type="button" class="btn btn-danger delete-btn" onclick="deleteInput(this)" disabled> | |
| <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path> | |
| </svg> | |
| </button> | |
| </div> | |
| `; | |
| document.getElementById('output').classList.add('hidden'); | |
| document.getElementById('formattedOutput').textContent = ''; | |
| } | |
| // Process input value (trim, lowercase, replace spaces with underscores) | |
| function processInputValue(value) { | |
| return value.trim().toLowerCase().replace(/\s+/g, '_'); | |
| } | |
| // Submit form event | |
| document.getElementById('dynamicForm').addEventListener('submit', function(e) { | |
| e.preventDefault(); | |
| const inputs = document.querySelectorAll('#inputContainer input'); | |
| const values = Array.from(inputs).map(input => processInputValue(input.value)); | |
| const formattedOutput = '[' + values.map(v => `'${v}'`).join(', ') + ']'; | |
| document.getElementById('formattedOutput').textContent = formattedOutput; | |
| document.getElementById('output').classList.remove('hidden'); | |
| }); | |
| // Fetch suggestion from the API and dynamically adjust the input boxes | |
| async function fetchSuggestion() { | |
| const queryValue = document.getElementById('query').value; | |
| const apiKey = document.getElementById('apiKeyInput').value; | |
| if (!queryValue) { | |
| alert("Please enter a query!"); | |
| return; | |
| } | |
| if (!apiKey) { | |
| alert("Please enter your API key!"); | |
| return; | |
| } | |
| // Show loading indicator | |
| document.getElementById('loadingIndicator').classList.remove('hidden'); | |
| // Clear previous inputs | |
| resetForm(); | |
| const data = { | |
| question: queryValue | |
| }; | |
| try { | |
| const response = await fetch('https://subham9126-hfflow.hf.space/api/v1/prediction/447aeeb8-3505-47ac-84c5-6a1e72454f80', { | |
| method: "POST", | |
| headers: { | |
| "Authorization": `Bearer ${apiKey}`, | |
| "Content-Type": "application/json" | |
| }, | |
| body: JSON.stringify(data) | |
| }); | |
| if (!response.ok) { | |
| throw new Error("Error fetching suggestion"); | |
| } | |
| const result = await response.json(); | |
| const attributes = result.json.attributes; // Get attributes from response | |
| const inputContainer = document.getElementById('inputContainer'); | |
| const currentInputCount = document.querySelectorAll('#inputContainer input').length; | |
| // If the number of attributes is greater than current input boxes, add more boxes | |
| if (attributes.length > currentInputCount) { | |
| for (let i = currentInputCount; i < attributes.length; i++) { | |
| addInput(); | |
| } | |
| } | |
| // Update the values of the input boxes to match the attributes | |
| const inputs = document.querySelectorAll('#inputContainer input'); | |
| inputs.forEach((input, index) => { | |
| if (attributes[index]) { | |
| input.value = attributes[index]; // Align attribute with input box | |
| } | |
| }); | |
| } catch (error) { | |
| console.error("Error fetching suggestion:", error); | |
| alert("Failed to fetch suggestions. Please check your API key or network."); | |
| } finally { | |
| // Hide loading indicator | |
| document.getElementById('loadingIndicator').classList.add('hidden'); | |
| } | |
| } | |
| </script> | |
| </body> | |
| </html> | |