From 9aa5e8e284080168ba168f8196f203425fb7c6a6 Mon Sep 17 00:00:00 2001 From: Valerij Fredriksen Date: Fri, 12 Aug 2022 14:47:58 +0200 Subject: Implement paste JSON --- .../context/query-builder-provider.jsx | 12 +++- .../querybuilder/query-derived/paste-modal.jsx | 65 +++++++++++++++------- 2 files changed, 55 insertions(+), 22 deletions(-) (limited to 'client/js') diff --git a/client/js/app/src/app/pages/querybuilder/context/query-builder-provider.jsx b/client/js/app/src/app/pages/querybuilder/context/query-builder-provider.jsx index 31cafeb860f..cfe39aaf5ee 100644 --- a/client/js/app/src/app/pages/querybuilder/context/query-builder-provider.jsx +++ b/client/js/app/src/app/pages/querybuilder/context/query-builder-provider.jsx @@ -1,6 +1,6 @@ +import { cloneDeep, last } from 'lodash'; import React, { useReducer } from 'react'; import { createContext, useContextSelector } from 'use-context-selector'; -import { cloneDeep, last } from 'lodash'; import parameters from 'app/pages/querybuilder/context/parameters'; let _dispatch; @@ -25,13 +25,19 @@ function inputsToJson(inputs) { ); } -function jsonToInputs(json, parent) { +export function jsonToInputs(json, parent = root) { return Object.entries(json).map(([key, value], i) => { const node = { id: parent.id ? `${parent.id}.${i}` : i.toString(), type: parent.type.children[key], parent, }; + if (!node.type) { + const location = parent.type.name + ? `under ${parent.type.name}` + : 'on root level'; + throw new Error(`Unknown property '${key}' ${location}`); + } if (typeof value === 'object') { node.input = ''; node.children = jsonToInputs(value, node); @@ -100,7 +106,7 @@ function preReducer(state, { action, data }) { switch (action) { case ACTION.SET_QUERY: { try { - const children = jsonToInputs(JSON.parse(data), root); + const children = jsonToInputs(JSON.parse(data)); return { ...state, query: { ...root, children } }; } catch (error) { alert(`Failed to parse query: ${error}`); // TODO: Change to toast diff --git a/client/js/app/src/app/pages/querybuilder/query-derived/paste-modal.jsx b/client/js/app/src/app/pages/querybuilder/query-derived/paste-modal.jsx index 9b68bd23e1c..04827427133 100644 --- a/client/js/app/src/app/pages/querybuilder/query-derived/paste-modal.jsx +++ b/client/js/app/src/app/pages/querybuilder/query-derived/paste-modal.jsx @@ -1,14 +1,57 @@ +import { Button, Modal, Stack, Textarea } from '@mantine/core'; import React, { useState } from 'react'; -import { Modal, Button, JsonInput, Stack } from '@mantine/core'; import { Icon } from 'app/components'; +import { + ACTION, + dispatch, + jsonToInputs, +} from 'app/pages/querybuilder/context/query-builder-provider'; + +function PasteForm({ close }) { + const [query, setQuery] = useState(''); + const [error, setError] = useState(''); + + function onSubmit() { + try { + const json = JSON.parse(query); + try { + jsonToInputs(json); + dispatch(ACTION.SET_QUERY, query); + close(); + } catch (error) { + setError(`Invalid Vespa query: ${error.message}`); + } + } catch (error) { + setError(`Invalid JSON: ${error.message}`); + } + } + + return ( + +