aboutsummaryrefslogtreecommitdiffstats
path: root/client/js
diff options
context:
space:
mode:
authorValerij Fredriksen <valerijf@yahooinc.com>2022-08-12 14:47:58 +0200
committerValerij Fredriksen <valerijf@yahooinc.com>2022-08-12 15:02:05 +0200
commit9aa5e8e284080168ba168f8196f203425fb7c6a6 (patch)
tree633b56ce4cabae472119d170a94c59f10e23b986 /client/js
parent07a74e30b98ae8ae7790e4fc5762cc32a8ae77d3 (diff)
Implement paste JSON
Diffstat (limited to 'client/js')
-rw-r--r--client/js/app/src/app/pages/querybuilder/context/query-builder-provider.jsx12
-rw-r--r--client/js/app/src/app/pages/querybuilder/query-derived/paste-modal.jsx65
2 files changed, 55 insertions, 22 deletions
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 (
+ <Stack>
+ <Textarea
+ placeholder="Your Vespa query JSON"
+ error={error}
+ minRows={34}
+ value={query}
+ onChange={({ target }) => setQuery(target.value)}
+ autosize
+ />
+ <Button leftIcon={<Icon name="paste" />} onClick={onSubmit}>
+ Save
+ </Button>
+ </Stack>
+ );
+}
export function PasteModal() {
const [opened, setOpened] = useState(false);
+ const close = () => setOpened(false);
+
return (
<>
<Modal
opened={opened}
- onClose={() => setOpened(false)}
+ onClose={close}
title="Vespa Query"
overlayColor="white"
shadow="1px 3px 10px 2px rgb(0 0 0 / 20%)"
@@ -16,23 +59,7 @@ export function PasteModal() {
size="xl"
centered
>
- <Stack>
- <JsonInput
- placeholder="Your Vespa query JSON"
- validationError="Invalid JSON or Vespa invalid query"
- minRows={34}
- formatOnBlur
- autosize
- />
- <Button
- leftIcon={<Icon name="paste" />}
- onClick={() => {
- console.log('paste and close');
- }}
- >
- Paste
- </Button>
- </Stack>
+ <PasteForm close={close} />
</Modal>
<Button
onClick={() => setOpened(true)}