From d6fd907a6ecd4b26a644a0920579ef04f376c726 Mon Sep 17 00:00:00 2001 From: Max Thonagel <12283268+thoniTUB@users.noreply.github.com> Date: Mon, 6 Feb 2023 11:36:19 +0100 Subject: [PATCH 001/111] fix early return condition --- .../main/java/com/bakdata/conquery/util/ConqueryEscape.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/com/bakdata/conquery/util/ConqueryEscape.java b/backend/src/main/java/com/bakdata/conquery/util/ConqueryEscape.java index 370fc8eed7..7a3f3f02ce 100644 --- a/backend/src/main/java/com/bakdata/conquery/util/ConqueryEscape.java +++ b/backend/src/main/java/com/bakdata/conquery/util/ConqueryEscape.java @@ -42,8 +42,8 @@ public class ConqueryEscape { public static String escape(@NonNull String word) { final int unescapedCharSequenceLength = (int) word.chars() - // Check if the character is larger than a byte - .takeWhile(c -> c >= 0x100 || c < 0) + // Check if the character is larger than a byte. Larger chars need to be escaped + .takeWhile(c -> c < 0x100 && c >= 0) //or if that byte needs encoding .takeWhile(c -> dontNeedEncoding((byte) (c & 0x00FF))) .count(); From 0d92548f16bd8cd6e2f6612ac18d89433dabfdbe Mon Sep 17 00:00:00 2001 From: Kai Rollmann Date: Mon, 6 Feb 2023 14:39:03 +0100 Subject: [PATCH 002/111] Support new textarea field for forms --- frontend/mock-api/forms/export-form.json | 38 ++++++++ frontend/src/js/GlobalStyles.tsx | 3 +- .../src/js/external-forms/config-types.ts | 14 +++ frontend/src/js/external-forms/form/Field.tsx | 27 ++++++ .../js/external-forms/transformQueryToApi.ts | 1 + frontend/src/js/external-forms/validators.ts | 1 + frontend/src/js/ui-components/BaseInput.tsx | 1 - frontend/src/js/ui-components/ImportModal.tsx | 1 + .../InputTextarea/InputTextarea.tsx | 97 +++++++++++++++++++ 9 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 frontend/src/js/ui-components/InputTextarea/InputTextarea.tsx diff --git a/frontend/mock-api/forms/export-form.json b/frontend/mock-api/forms/export-form.json index a47c1b8a47..789479e699 100644 --- a/frontend/mock-api/forms/export-form.json +++ b/frontend/mock-api/forms/export-form.json @@ -8,6 +8,44 @@ "de": "Dieses Formular erlaubt den Export von abhängigen Variablen zu einer bestimmten Ergebnisgruppe. Dabei wird eine CSV-Datei mit den Ergebnissen erzeugt, die dann heruntergeladen werden kann." }, "fields": [ + { + "name": "someString", + "type": "STRING", + "label": { + "de": "Ein STRING-Feld" + }, + "tooltip": { + "de": "Tippe einen Kurztext" + }, + "validations": ["NOT_EMPTY"] + }, + { + "name": "someString2", + "type": "STRING", + "label": { + "de": "Ein STRING-Feld in voller Breite" + }, + "tooltip": { + "de": "Tippe einen Kurztext" + }, + "style": { + "fullWidth": true + }, + "validations": ["NOT_EMPTY"] + }, + { + "name": "someTextarea", + "type": "TEXTAREA", + "label": { + "de": "Ein TEXTAREA-Feld" + }, + "tooltip": { + "de": "Tippe einen längeren Text" + }, + "style": { + "rows": 4 + } + }, { "name": "queryGroup", "type": "RESULT_GROUP", diff --git a/frontend/src/js/GlobalStyles.tsx b/frontend/src/js/GlobalStyles.tsx index 4f947a4412..1d566709a5 100644 --- a/frontend/src/js/GlobalStyles.tsx +++ b/frontend/src/js/GlobalStyles.tsx @@ -25,7 +25,8 @@ const globalStyles = (theme: Theme) => css` button, select, - input { + input, + textarea { font-family: "Roboto", "Arial", sans-serif; } diff --git a/frontend/src/js/external-forms/config-types.ts b/frontend/src/js/external-forms/config-types.ts index bff5f86e89..ce4d1f0e89 100644 --- a/frontend/src/js/external-forms/config-types.ts +++ b/frontend/src/js/external-forms/config-types.ts @@ -62,6 +62,7 @@ type GREATER_THAN_ZERO_VALIDATION = "GREATER_THAN_ZERO"; export type Field = | CheckboxField | StringField + | TextareaField | NumberField | SelectField | DatasetSelectField @@ -117,6 +118,19 @@ type StringField = CommonField & { /* ------------------------------ */ +type TextareaFieldValidation = NOT_EMPTY_VALIDATION; +type TextareaField = CommonField & { + type: "TEXTAREA"; + placeholder?: TranslatableString; + defaultValue?: string; // Default: "" + style?: { + rows?: number; // Default: 10 + }; + validations?: TextareaFieldValidation[]; +}; + +/* ------------------------------ */ + type NumberFieldValidation = | NOT_EMPTY_VALIDATION | GREATER_THAN_ZERO_VALIDATION; diff --git a/frontend/src/js/external-forms/form/Field.tsx b/frontend/src/js/external-forms/form/Field.tsx index 95cf52ebf8..93ee57403f 100644 --- a/frontend/src/js/external-forms/form/Field.tsx +++ b/frontend/src/js/external-forms/form/Field.tsx @@ -19,6 +19,7 @@ import InputCheckbox from "../../ui-components/InputCheckbox"; import InputDateRange from "../../ui-components/InputDateRange"; import InputPlain from "../../ui-components/InputPlain/InputPlain"; import InputSelect from "../../ui-components/InputSelect/InputSelect"; +import { InputTextarea } from "../../ui-components/InputTextarea/InputTextarea"; import ToggleButton from "../../ui-components/ToggleButton"; import type { Field as FieldT, GeneralField, Tabs } from "../config-types"; import { Description } from "../form-components/Description"; @@ -193,6 +194,32 @@ const Field = ({ field, ...commonProps }: PropsT) => { )} ); + case "TEXTAREA": + return ( + + {({ ref, ...fieldProps }) => ( + { + console.log(value); + setValue(field.name, value, setValueConfig); + }} + tooltip={field.tooltip ? field.tooltip[locale] : undefined} + optional={optional} + /> + )} + + ); case "NUMBER": return ( string | null) > = { STRING: null, + TEXTAREA: null, NUMBER: null, CHECKBOX: null, CONCEPT_LIST: null, diff --git a/frontend/src/js/ui-components/BaseInput.tsx b/frontend/src/js/ui-components/BaseInput.tsx index f7087cd835..d88d6afcff 100644 --- a/frontend/src/js/ui-components/BaseInput.tsx +++ b/frontend/src/js/ui-components/BaseInput.tsx @@ -20,7 +20,6 @@ const Input = styled("input")<{ large?: boolean }>` width: 100%; border: 1px solid ${({ theme }) => theme.col.grayMediumLight}; - font-size: ${({ theme }) => theme.font.md}; padding: ${({ large }) => large ? "10px 30px 10px 14px" : "6px 30px 6px 10px"}; font-size: ${({ theme, large }) => (large ? theme.font.lg : theme.font.sm)}; diff --git a/frontend/src/js/ui-components/ImportModal.tsx b/frontend/src/js/ui-components/ImportModal.tsx index 7b9810f4e2..4a9716c9fe 100644 --- a/frontend/src/js/ui-components/ImportModal.tsx +++ b/frontend/src/js/ui-components/ImportModal.tsx @@ -25,6 +25,7 @@ const Row = styled("div")` `; const Textarea = styled("textarea")` + font-family: monospace; width: 100%; `; diff --git a/frontend/src/js/ui-components/InputTextarea/InputTextarea.tsx b/frontend/src/js/ui-components/InputTextarea/InputTextarea.tsx new file mode 100644 index 0000000000..1a98823ad0 --- /dev/null +++ b/frontend/src/js/ui-components/InputTextarea/InputTextarea.tsx @@ -0,0 +1,97 @@ +import styled from "@emotion/styled"; +import { DetailedHTMLProps, forwardRef, TextareaHTMLAttributes } from "react"; +import { useTranslation } from "react-i18next"; + +import IconButton from "../../button/IconButton"; +import Labeled from "../Labeled"; + +const Root = styled("div")` + position: relative; +`; + +const Textarea = styled("textarea")` + outline: 0; + width: 100%; + border-radius: ${({ theme }) => theme.borderRadius}; + border: 1px solid ${({ theme }) => theme.col.grayMediumLight}; + padding: 6px 30px 6px 10px; + font-size: ${({ theme }) => theme.font.sm}; +`; + +const ClearZoneIconButton = styled(IconButton)` + position: absolute; + top: 0; + right: 10px; + height: 30px; + cursor: pointer; + display: flex; + align-items: center; +`; + +interface OtherProps { + label: string; + className?: string; + fullWidth?: boolean; + indexPrefix?: number; + tooltip?: string; + optional?: boolean; + onChange: (value: string | null) => void; +} + +type InputTextareaProps = DetailedHTMLProps< + TextareaHTMLAttributes, + HTMLTextAreaElement +>; + +export const InputTextarea = forwardRef< + HTMLTextAreaElement, + InputTextareaProps & OtherProps +>( + ( + { + label, + className, + fullWidth, + indexPrefix, + tooltip, + optional, + onChange, + ...props + }, + ref, + ) => { + const { t } = useTranslation(); + + return ( + + +