summaryrefslogtreecommitdiffstats
path: root/client/js
diff options
context:
space:
mode:
authorValerij Fredriksen <valerijf@yahooinc.com>2022-08-13 12:12:42 +0200
committerValerij Fredriksen <valerijf@yahooinc.com>2022-08-14 12:01:13 +0200
commit2a578dc668c93e3949884e694b142383aac74c41 (patch)
treef26e89a65b8f6c23fd4606abc503d2ff8f203ea1 /client/js
parentc87c2f75145b5c447b6b17118d560c2662150185 (diff)
Implement GET query
Diffstat (limited to 'client/js')
-rw-r--r--client/js/app/src/app/pages/querybuilder/context/query-builder-provider.jsx68
-rw-r--r--client/js/app/src/app/pages/querybuilder/query-derived/query-derived.jsx2
-rw-r--r--client/js/app/src/app/pages/querybuilder/query-endpoint/query-endpoint.jsx50
-rw-r--r--client/js/app/src/app/pages/querybuilder/query-filters/query-filters.jsx4
-rw-r--r--client/js/app/src/app/pages/querybuilder/query-response/query-response.jsx2
5 files changed, 79 insertions, 47 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 622641e8cb6..98a040159da 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
@@ -10,12 +10,24 @@ const context = createContext(null);
export const ACTION = Object.freeze({
SET_QUERY: 0,
SET_HTTP: 1,
+ SET_METHOD: 2,
+ SET_URL: 3,
INPUT_ADD: 10,
INPUT_UPDATE: 11,
INPUT_REMOVE: 12,
});
+function inputsToSearchParams(inputs, parent) {
+ return inputs.reduce((acc, { input, type: { name }, children }) => {
+ const key = parent ? `${parent}.${name}` : name;
+ return Object.assign(
+ acc,
+ children ? inputsToSearchParams(children, key) : { [key]: input }
+ );
+ }, {});
+}
+
function inputsToJson(inputs) {
return Object.fromEntries(
inputs.map(({ children, input, type: { name, type } }) => [
@@ -53,9 +65,9 @@ function parseInput(input, type) {
return input;
}
-function inputAdd(query, { id: parentId, type: typeName }) {
- const inputs = cloneDeep(query.children);
- const parent = parentId ? findInput(inputs, parentId) : query;
+function inputAdd(params, { id: parentId, type: typeName }) {
+ const inputs = cloneDeep(params.children);
+ const parent = parentId ? findInput(inputs, parentId) : params;
const nextId =
parseInt(last(last(parent.children)?.id?.split('.')) ?? -1) + 1;
@@ -68,21 +80,21 @@ function inputAdd(query, { id: parentId, type: typeName }) {
type.children && { children: [] }
)
);
- return { ...query, children: inputs };
+ return { ...params, children: inputs };
}
-function inputUpdate(query, { id, ...props }) {
+function inputUpdate(params, { id, ...props }) {
const keys = Object.keys(props);
if (keys.length !== 1)
throw new Error(`Expected to update exactly 1 input prop, got: ${keys}`);
if (!['input', 'type'].includes(keys[0]))
throw new Error(`Cannot update key ${keys[0]}`);
- const inputs = cloneDeep(query.children);
+ const inputs = cloneDeep(params.children);
const node = Object.assign(findInput(inputs, id), props);
if (node.type.children) node.children = [];
else delete node.children;
- return { ...query, children: inputs };
+ return { ...params, children: inputs };
}
function findInput(inputs, id, Delete = false) {
@@ -95,9 +107,25 @@ function findInput(inputs, id, Delete = false) {
function reducer(state, action) {
const result = preReducer(state, action);
- if (state.query.children !== result.query.children) {
- const json = inputsToJson(result.query.children);
- result.query.input = JSON.stringify(json, null, 4);
+ const { request: sr, params: sp } = state;
+ const { request: rr, params: rp } = result;
+ if (sp.children !== rp.children || sr.method !== rr.method) {
+ result.query =
+ rr.method === 'POST'
+ ? JSON.stringify(inputsToJson(rp.children), null, 4)
+ : new URLSearchParams(inputsToSearchParams(rp.children)).toString();
+ }
+
+ if (sr.url !== rr.url || state.query !== result.query) {
+ if (rr.method === 'POST') {
+ rr.fullUrl = rr.url;
+ rr.body = result.query;
+ } else {
+ const url = new URL(rr.url);
+ url.search = result.query;
+ rr.fullUrl = url.toString();
+ rr.body = null;
+ }
}
return result;
}
@@ -107,22 +135,26 @@ function preReducer(state, { action, data }) {
case ACTION.SET_QUERY: {
try {
const children = jsonToInputs(JSON.parse(data));
- return { ...state, query: { ...root, children } };
+ return { ...state, params: { ...root, children } };
} catch (error) {
return state;
}
}
case ACTION.SET_HTTP:
return { ...state, http: data };
+ case ACTION.SET_METHOD:
+ return { ...state, request: { ...state.request, method: data } };
+ case ACTION.SET_URL:
+ return { ...state, request: { ...state.request, url: data } };
case ACTION.INPUT_ADD:
- return { ...state, query: inputAdd(state.query, data) };
+ return { ...state, params: inputAdd(state.params, data) };
case ACTION.INPUT_UPDATE:
- return { ...state, query: inputUpdate(state.query, data) };
+ return { ...state, params: inputUpdate(state.params, data) };
case ACTION.INPUT_REMOVE: {
- const inputs = cloneDeep(state.query.children);
+ const inputs = cloneDeep(state.params.children);
findInput(inputs, data, true);
- return { ...state, query: { ...state.query, children: inputs } };
+ return { ...state, params: { ...state.params, children: inputs } };
}
default:
@@ -133,7 +165,11 @@ function preReducer(state, { action, data }) {
export function QueryBuilderProvider({ children }) {
const [value, dispatch] = useReducer(
reducer,
- { http: {}, query: { ...root, input: '', children: [] } },
+ {
+ request: { url: 'http://localhost:8080/search/', method: 'POST' },
+ http: {},
+ params: { ...root, children: [] },
+ },
(s) => reducer(s, { action: ACTION.SET_QUERY, data: '{"yql":""}' })
);
_dispatch = dispatch;
diff --git a/client/js/app/src/app/pages/querybuilder/query-derived/query-derived.jsx b/client/js/app/src/app/pages/querybuilder/query-derived/query-derived.jsx
index c369083a6a0..e4626d194c5 100644
--- a/client/js/app/src/app/pages/querybuilder/query-derived/query-derived.jsx
+++ b/client/js/app/src/app/pages/querybuilder/query-derived/query-derived.jsx
@@ -12,7 +12,7 @@ import { Icon } from 'app/components';
import { PasteModal } from 'app/pages/querybuilder/query-derived/paste-modal';
export function QueryDerived() {
- const query = useQueryBuilderContext((ctx) => ctx.query.input);
+ const query = useQueryBuilderContext('query');
return (
<Stack>
diff --git a/client/js/app/src/app/pages/querybuilder/query-endpoint/query-endpoint.jsx b/client/js/app/src/app/pages/querybuilder/query-endpoint/query-endpoint.jsx
index 36545316255..8e8b64bb0d1 100644
--- a/client/js/app/src/app/pages/querybuilder/query-endpoint/query-endpoint.jsx
+++ b/client/js/app/src/app/pages/querybuilder/query-endpoint/query-endpoint.jsx
@@ -1,4 +1,4 @@
-import React, { useState } from 'react';
+import React from 'react';
import { Select, TextInput, Button } from '@mantine/core';
import { errorMessage } from 'app/libs/notification';
import {
@@ -8,12 +8,13 @@ import {
} from 'app/pages/querybuilder/context/query-builder-provider';
import { Container, Content } from 'app/components';
-function send(method, url, query) {
+function send(event, method, url, body) {
+ event.preventDefault();
dispatch(ACTION.SET_HTTP, { loading: true });
fetch(url, {
method,
headers: { 'Content-Type': 'application/json;charset=utf-8' },
- body: method === 'POST' ? query : null,
+ body,
})
.then((response) => response.json())
.then((result) =>
@@ -28,34 +29,29 @@ function send(method, url, query) {
}
export default function QueryEndpoint() {
- const httpMethods = ['POST', 'GET'];
- const [method, setMethod] = useState('POST');
- const [url, setUrl] = useState('http://localhost:8080/search/');
- const query = useQueryBuilderContext((ctx) => ctx.query.input);
+ const { method, url, fullUrl, body } = useQueryBuilderContext('request');
const loading = useQueryBuilderContext((ctx) => ctx.http.loading);
return (
<Content>
- <Container sx={{ gridTemplateColumns: 'max-content auto max-content' }}>
- <Select
- data={httpMethods}
- onChange={setMethod}
- value={method}
- radius={0}
- />
- <TextInput
- onChange={(event) => setUrl(event.currentTarget.value)}
- value={url}
- radius={0}
- />
- <Button
- radius={0}
- onClick={() => send(method, url, query)}
- loading={loading}
- >
- Send
- </Button>
- </Container>
+ <form onSubmit={(event) => send(event, method, fullUrl, body)}>
+ <Container sx={{ gridTemplateColumns: 'max-content auto max-content' }}>
+ <Select
+ data={['POST', 'GET']}
+ onChange={(value) => dispatch(ACTION.SET_METHOD, value)}
+ value={method}
+ radius={0}
+ />
+ <TextInput
+ onChange={(e) => dispatch(ACTION.SET_URL, e.currentTarget.value)}
+ value={url}
+ radius={0}
+ />
+ <Button radius={0} type="submit" loading={loading}>
+ Send
+ </Button>
+ </Container>
+ </form>
</Content>
);
}
diff --git a/client/js/app/src/app/pages/querybuilder/query-filters/query-filters.jsx b/client/js/app/src/app/pages/querybuilder/query-filters/query-filters.jsx
index 628f52908a1..2f59b0af86e 100644
--- a/client/js/app/src/app/pages/querybuilder/query-filters/query-filters.jsx
+++ b/client/js/app/src/app/pages/querybuilder/query-filters/query-filters.jsx
@@ -121,11 +121,11 @@ function Inputs({ id, type, inputs }) {
}
export function QueryFilters() {
- const { children, type } = useQueryBuilderContext('query');
+ const { children, type } = useQueryBuilderContext('params');
return (
<Stack>
<Group>
- <Badge variant="filled">Query filters</Badge>
+ <Badge variant="filled">Parameters</Badge>
</Group>
<Container sx={{ alignContent: 'start' }}>
<Content padding={0}>
diff --git a/client/js/app/src/app/pages/querybuilder/query-response/query-response.jsx b/client/js/app/src/app/pages/querybuilder/query-response/query-response.jsx
index 055618ac636..56562ae1717 100644
--- a/client/js/app/src/app/pages/querybuilder/query-response/query-response.jsx
+++ b/client/js/app/src/app/pages/querybuilder/query-response/query-response.jsx
@@ -17,7 +17,7 @@ export function QueryResponse() {
return (
<Stack>
<Group position="apart">
- <Badge variant="filled">Query response</Badge>
+ <Badge variant="filled">Response</Badge>
<Group spacing="xs">
<CopyButton value={response}>
{({ copied, copy }) => (