From 67f2bdf2a84859e5140c7e70536c38d9d6b52c1a Mon Sep 17 00:00:00 2001 From: Lia Date: Sat, 9 Dec 2023 19:34:39 +0300 Subject: [PATCH] fix some comments --- web-app/client/.gitignore | 2 +- web-app/client/package.json | 1 - web-app/client/src/atoms/ACTaskAtom.ts | 5 +- .../ACInstance/ACInstance.module.scss | 40 +-- .../src/components/ACInstance/ACInstance.tsx | 86 +++++ .../client/src/components/ACInstance/index.ts | 1 + .../AlgorithmFormConfigurator.tsx | 33 +- .../ConfigureAlgorithm.module.scss | 18 +- .../useFormFactory.tsx | 37 +- .../CollapsableView.module.scss | 14 +- .../CollapsableView/CollapsableView.tsx | 47 +-- .../src/components/CollapsableView/index.ts | 1 + .../Inputs/NumberInput/NumberInput.tsx | 9 +- .../Inputs/NumberSlider/NumberSlider.tsx | 14 +- .../NumberInputWithButton.module.scss | 8 + .../NumberInputWithButton.tsx | 31 ++ .../components/NumberInputWithButton/index.ts | 1 + .../ReportsLayout/ReportsLayout.tsx | 14 +- .../\320\220\320\241/Intervals/Intervals.tsx" | 119 ------- .../SeedCustomInput.module.scss | 2 +- .../SeedCustomInput.tsx | 19 +- .../ACForm/SeedCustomInput/index.ts | 1 + .../ACForm/SeedCustomInputs/index.ts | 0 .../configuratorForm/ACForm/index.ts | 50 +-- .../client/src/constants/formPrimitives.ts | 2 +- .../src/constants/primitiveReportPathnames.ts | 2 +- web-app/client/src/graphql/client.ts | 1 - web-app/client/src/graphql/context.ts | 1 - .../pages/create-task/configure-algorithm.tsx | 2 +- .../reports/ACFakeData/data4Histogram.ts | 86 +++++ .../reports/ACFakeData/data4InstanceList.ts | 167 +++++++++ .../src/pages/reports/ac-instance-list.tsx | 251 ++------------ .../client/src/pages/reports/histogram.tsx | 321 +++++++----------- web-app/client/src/styles/common/_mixins.scss | 2 +- web-app/client/src/styles/common/index.scss | 2 +- ...{_variables.scss => variables.module.scss} | 11 + web-app/client/src/styles/common/variables.ts | 13 + ...e.scss => configure-algorithm.module.scss} | 10 +- .../client/src/styles/histogram.module.scss | 18 +- web-app/client/yarn.lock | 259 +++++++++++++- 40 files changed, 975 insertions(+), 726 deletions(-) rename "web-app/client/src/components/\320\220\320\241/Intervals/Intervals.module.scss" => web-app/client/src/components/ACInstance/ACInstance.module.scss (79%) create mode 100644 web-app/client/src/components/ACInstance/ACInstance.tsx create mode 100644 web-app/client/src/components/ACInstance/index.ts rename "web-app/client/src/components/\320\220\320\241/CollapsableView/CollapsableView.module.scss" => web-app/client/src/components/CollapsableView/CollapsableView.module.scss (85%) rename "web-app/client/src/components/\320\220\320\241/CollapsableView/CollapsableView.tsx" => web-app/client/src/components/CollapsableView/CollapsableView.tsx (58%) create mode 100644 web-app/client/src/components/CollapsableView/index.ts create mode 100644 web-app/client/src/components/NumberInputWithButton/NumberInputWithButton.module.scss create mode 100644 web-app/client/src/components/NumberInputWithButton/NumberInputWithButton.tsx create mode 100644 web-app/client/src/components/NumberInputWithButton/index.ts delete mode 100644 "web-app/client/src/components/\320\220\320\241/Intervals/Intervals.tsx" rename web-app/client/src/constants/configuratorForm/ACForm/{SeedCustomInputs => SeedCustomInput}/SeedCustomInput.module.scss (100%) rename web-app/client/src/constants/configuratorForm/ACForm/{SeedCustomInputs => SeedCustomInput}/SeedCustomInput.tsx (70%) create mode 100644 web-app/client/src/constants/configuratorForm/ACForm/SeedCustomInput/index.ts delete mode 100644 web-app/client/src/constants/configuratorForm/ACForm/SeedCustomInputs/index.ts create mode 100644 web-app/client/src/pages/reports/ACFakeData/data4Histogram.ts create mode 100644 web-app/client/src/pages/reports/ACFakeData/data4InstanceList.ts rename web-app/client/src/styles/common/{_variables.scss => variables.module.scss} (91%) create mode 100644 web-app/client/src/styles/common/variables.ts rename web-app/client/src/styles/{configure-algoritm.module.scss => configure-algorithm.module.scss} (97%) diff --git a/web-app/client/.gitignore b/web-app/client/.gitignore index b119deafc..79e364afa 100644 --- a/web-app/client/.gitignore +++ b/web-app/client/.gitignore @@ -43,4 +43,4 @@ cmsTypes.ts .graphqlconfig schema.graphql -web-app\client\proxy.config.js +proxy.config.js diff --git a/web-app/client/package.json b/web-app/client/package.json index a10ca686d..24ad642c0 100755 --- a/web-app/client/package.json +++ b/web-app/client/package.json @@ -62,7 +62,6 @@ "@testing-library/react": "^13.4.0", "@testing-library/react-hooks": "^8.0.1", "@testing-library/user-event": "^14.4.3", - "@trivago/prettier-plugin-sort-imports": "^4.3.0", "@types/apollo-upload-client": "^17.0.1", "@types/classnames": "^2.3.1", "@types/clientjs": "^0.2.0", diff --git a/web-app/client/src/atoms/ACTaskAtom.ts b/web-app/client/src/atoms/ACTaskAtom.ts index 14f844bea..311041618 100644 --- a/web-app/client/src/atoms/ACTaskAtom.ts +++ b/web-app/client/src/atoms/ACTaskAtom.ts @@ -1,11 +1,12 @@ -import { Intervals } from '@graphql/operations/queries/__generated__/GetMainTaskDeps'; +import { Interval } from '@graphql/operations/queries/__generated__/GetMainTaskDeps'; import { atom } from 'jotai'; import { ACSortBy, OrderBy, Pagination } from 'types/globalTypes'; export type ACInstance = { + id: string; attribute1: string; attribute2: string; - intervals: Intervals[]; + intervals: Interval[]; outliers: number[]; }; diff --git "a/web-app/client/src/components/\320\220\320\241/Intervals/Intervals.module.scss" b/web-app/client/src/components/ACInstance/ACInstance.module.scss similarity index 79% rename from "web-app/client/src/components/\320\220\320\241/Intervals/Intervals.module.scss" rename to web-app/client/src/components/ACInstance/ACInstance.module.scss index bccf208fd..0899c1e0a 100644 --- "a/web-app/client/src/components/\320\220\320\241/Intervals/Intervals.module.scss" +++ b/web-app/client/src/components/ACInstance/ACInstance.module.scss @@ -2,61 +2,51 @@ .containerOuter { @include paragraph-small; + display: flex; + justify-content: space-between; + gap: 16px; margin-bottom: 16px; + border: solid 2px $black-50; + border-radius: 8px; box-sizing: border-box; padding: 16px; max-width: 836px; + background-color: $white-25; cursor: pointer; - background-color: $white; - border: solid 2px $black; - border-radius: 8px; - display: flex; - justify-content: space-between; - gap: 16px; } .icons { - color: $black-75; width: 16px; height: 16px; + color: $black-75; } .containerInner { - min-width: 0; - width: 100%; display: flex; flex-direction: column; gap: 8px; -} - -.default { - background-color: $white-25; - border-color: $black-50; -} - -.error { - background-color: $error-10; - border-color: $error; + width: 100%; + min-width: 0; } .selected { - background-color: $secondary-1; border-color: $primary-0; + background-color: $secondary-1; } .attributes { display: flex; - gap: 8px; align-items: center; + gap: 8px; } .attr { @include paragraph-small; - border-radius: 8px; - text-align: center; - background: $black-10; border: 2px solid transparent; - color: $black-75; + border-radius: 8px; padding-left: 8px; padding-right: 8px; + background: $black-10; + text-align: center; + color: $black-75; } diff --git a/web-app/client/src/components/ACInstance/ACInstance.tsx b/web-app/client/src/components/ACInstance/ACInstance.tsx new file mode 100644 index 000000000..fab4b3ca9 --- /dev/null +++ b/web-app/client/src/components/ACInstance/ACInstance.tsx @@ -0,0 +1,86 @@ +import DivisionIcon from '@assets/icons/division.svg?component'; +import MinusIcon from '@assets/icons/minus.svg?component'; +import MultiplicationIcon from '@assets/icons/multiplication.svg?component'; +import PlusIcon from '@assets/icons/plus.svg?component'; +import ACAtom, { + ACAtomDefaultValuesWithParams, + ACInstance, +} from '@atoms/ACTaskAtom'; +import { + GetMainTaskDeps_taskInfo_TaskInfo_data_result_ACTaskResult_ACs_attributes, + GetMainTaskDeps_taskInfo_TaskInfo_data_result_ACTaskResult_ACs_intervals, + GetMainTaskDeps_taskInfo_TaskInfo_data_result_ACTaskResult_ACs_outliers, + Operation, +} from '@graphql/operations/queries/__generated__/GetMainTaskDeps'; +import cn from 'classnames'; +import { useAtom } from 'jotai'; +import { FC } from 'react'; +import CollapsableView from '../CollapsableView'; +import styles from './ACInstance.module.scss'; + +type Props = { + id: string; + attributes: GetMainTaskDeps_taskInfo_TaskInfo_data_result_ACTaskResult_ACs_attributes; + operation: Operation; + outliers: GetMainTaskDeps_taskInfo_TaskInfo_data_result_ACTaskResult_ACs_outliers; + intervals: GetMainTaskDeps_taskInfo_TaskInfo_data_result_ACTaskResult_ACs_intervals; +}; + +export const operationIcons = { + [Operation.ADDITION]: PlusIcon, + [Operation.MULTIPLICATION]: MultiplicationIcon, + [Operation.DIVISION]: DivisionIcon, + [Operation.SUBTRACTION]: MinusIcon, +}; + +const ACInstance: FC = ({ + id, + attributes, + operation, + outliers, + intervals, +}) => { + const [atom, setAtom] = useAtom(ACAtom); + const handleSelect = () => { + const instance: ACInstance = { + id: id, + attribute1: attributes.attr1, + attribute2: attributes.attr2, + intervals: intervals.intervals, + outliers: outliers.outliers, + }; + setAtom({ ...ACAtomDefaultValuesWithParams(atom.taskID, instance) }); + }; + + const OperationIcon = operationIcons[operation as Operation]; + + const isSelected = atom.instanceSelected?.id === id; + + return ( +
+
+ Operation +
+
{attributes.attr1}
+ + +
{attributes.attr2}
+
+
+ `[${elem[0]}, ${elem[1]}]`)} + amount={intervals.amount} + /> + elem.toString())} + /> +
+ ); +}; + +export default ACInstance; diff --git a/web-app/client/src/components/ACInstance/index.ts b/web-app/client/src/components/ACInstance/index.ts new file mode 100644 index 000000000..87add6eff --- /dev/null +++ b/web-app/client/src/components/ACInstance/index.ts @@ -0,0 +1 @@ +export { default } from './ACInstance'; diff --git a/web-app/client/src/components/AlgorithmFormConfigurator/AlgorithmFormConfigurator.tsx b/web-app/client/src/components/AlgorithmFormConfigurator/AlgorithmFormConfigurator.tsx index d263fddfe..b237b3fce 100644 --- a/web-app/client/src/components/AlgorithmFormConfigurator/AlgorithmFormConfigurator.tsx +++ b/web-app/client/src/components/AlgorithmFormConfigurator/AlgorithmFormConfigurator.tsx @@ -1,12 +1,11 @@ +import cn from 'classnames'; +import { useRouter } from 'next/router'; import FormFooter from '@components/AlgorithmFormConfigurator/FormFooter'; import FormHeader from '@components/AlgorithmFormConfigurator/FormHeader'; import useFormFactory from '@components/AlgorithmFormConfigurator/useFormFactory'; import PresetSelector from '@components/PresetSelector'; import WizardLayout from '@components/WizardLayout'; import { UsedPrimitivesType } from '@constants/formPrimitives'; -import cn from 'classnames'; -import { useRouter } from 'next/router'; -import React from 'react'; import styles from './ConfigureAlgorithm.module.scss'; type QueryProps = { @@ -34,11 +33,7 @@ const AlgorithmFormConfigurator = ({ primitive, formParams, }); - - const numColumnContainer = `container${ - entries.length > 4 ? 'Over4' : 'Less4' - }Inputs`; - + return (
({ entries.length > 4 && styles.bigFormContainer, )} > -
+
4 + ? 'containerOver4Inputs' + : 'baseFormContainer' + ] + } + > ({
-
{entries}
+
4 + ? 'containerOver4Inputs' + : 'containerLess4Inputs' + ] + } + > + {entries} +
); diff --git a/web-app/client/src/components/AlgorithmFormConfigurator/ConfigureAlgorithm.module.scss b/web-app/client/src/components/AlgorithmFormConfigurator/ConfigureAlgorithm.module.scss index 0d377c872..b23e51ccf 100644 --- a/web-app/client/src/components/AlgorithmFormConfigurator/ConfigureAlgorithm.module.scss +++ b/web-app/client/src/components/AlgorithmFormConfigurator/ConfigureAlgorithm.module.scss @@ -4,12 +4,11 @@ margin-top: 16px; } - -.baseFormContainer { - margin: auto; +.baseFormContainer, .containerLess4Inputs { + display: flex; flex-direction: column; gap: 24px; - display: flex; + margin: auto; width: 100%; max-width: 466px; } @@ -18,15 +17,6 @@ max-width: 1100px; } -.containerLess4Inputs { - margin: auto; - flex-direction: column; - gap: 24px; - display: flex; - width: 100%; - max-width: 466px; -} - .containerOver4Inputs { display: grid; grid-template-columns: 1fr 1fr; @@ -42,9 +32,9 @@ } .line { - width: 100%; grid-column: span 2; border: 0; border-top: 1px solid $black-25; + width: 100%; padding: 0; } diff --git a/web-app/client/src/components/AlgorithmFormConfigurator/useFormFactory.tsx b/web-app/client/src/components/AlgorithmFormConfigurator/useFormFactory.tsx index d06b1d4a8..6b94167f4 100644 --- a/web-app/client/src/components/AlgorithmFormConfigurator/useFormFactory.tsx +++ b/web-app/client/src/components/AlgorithmFormConfigurator/useFormFactory.tsx @@ -76,8 +76,8 @@ const useFormFactory = ({ ({ ...formObject.formDefaults, ...formParams, - } as typeof formObject.formDefaults), - [formObject, formParams] + }) as typeof formObject.formDefaults, + [formObject, formParams], ); const formFields = formObject.formFields as FormFieldsProps< typeof formDefaultValues @@ -102,7 +102,7 @@ const useFormFactory = ({ onError: (error) => { showError( error.message, - "Can't fetch file information. Please try later." + "Can't fetch file information. Please try later.", ); }, }); @@ -116,9 +116,9 @@ const useFormFactory = ({ (value) => value.filenames === 'EveryFile' || (fileNameData?.datasetInfo?.fileName && - value.filenames.includes(fileNameData?.datasetInfo?.fileName)) + value.filenames.includes(fileNameData?.datasetInfo?.fileName)), )) as Presets, - [fileNameData?.datasetInfo?.fileName, fileNameLoading, formObject] + [fileNameData?.datasetInfo?.fileName, fileNameLoading, formObject], ); const methods = useForm({ @@ -156,11 +156,11 @@ const useFormFactory = ({ checkbox: FormCheckbox, // not working, don't use radio: FormRadio, // not working, don't use text: FormText, // not working, don't use - } as unknown as Record< + }) as unknown as Record< string, FormInputElement - >), - [] + >, + [], ); type FormInput = { @@ -177,7 +177,7 @@ const useFormFactory = ({ () => ( Object.entries(formState).sort( - (A, B) => A[1].order - B[1].order + (A, B) => A[1].order - B[1].order, ) as Entries ).map(([name, fieldProps]) => { return { @@ -203,9 +203,12 @@ const useFormFactory = ({ if (fieldProps.type === 'custom') { const Component = fieldProps.component; return ( -
- + {/*TODO: fix any*/} +
); } @@ -220,7 +223,7 @@ const useFormFactory = ({ }, } as FormInput; }), - [formState, inputs] + [formState, inputs], ); const [createTask] = useMutation< @@ -239,7 +242,7 @@ const useFormFactory = ({ .map(([name]) => name); const cleanedData = _.omit( data, - clientOnlyFields + clientOnlyFields, ) as IntersectionMainTaskProps; createTask({ variables: { @@ -257,20 +260,20 @@ const useFormFactory = ({ query: { taskID: resp.data?.createMainTaskWithDatasetChoosing.taskID, }, - }) + }), ) .catch((error) => { if (error instanceof Error) { showError( error.message, - 'Internal error occurred. Please try later.' + 'Internal error occurred. Please try later.', ); } }); }, () => { showError('Input error', 'You need to correct the errors in the form.'); - } + }, ); const entries = formInputs.map(({ name, rules, render }) => ( @@ -297,7 +300,7 @@ const useFormFactory = ({ formLogic(formState, setFormState, methods, depsIndex); }, // eslint-disable-next-line react-hooks/exhaustive-deps - [formDefaultValues, formLogic, formPresets, methods] + [formDefaultValues, formLogic, formPresets, methods], ); return { diff --git "a/web-app/client/src/components/\320\220\320\241/CollapsableView/CollapsableView.module.scss" b/web-app/client/src/components/CollapsableView/CollapsableView.module.scss similarity index 85% rename from "web-app/client/src/components/\320\220\320\241/CollapsableView/CollapsableView.module.scss" rename to web-app/client/src/components/CollapsableView/CollapsableView.module.scss index 709b15fc6..b0d31cbc1 100644 --- "a/web-app/client/src/components/\320\220\320\241/CollapsableView/CollapsableView.module.scss" +++ b/web-app/client/src/components/CollapsableView/CollapsableView.module.scss @@ -1,11 +1,11 @@ @import "styles/common"; .container { - min-width: 0; - width: 100%; display: flex; flex-direction: column; gap: 8px; + width: 100%; + min-width: 0; } .collabsableOutput { @@ -14,16 +14,19 @@ text-overflow: ellipsis; span { - white-space: nowrap; margin-right: 4px; + white-space: nowrap; } } .buttonShow { @include paragraph-small; - color: $primary-0; - text-decoration: underline; margin-left: 4px; + border: none; + background-color: transparent; + cursor: pointer; + text-decoration: underline; + color: $primary-0; } .withShowAll { @@ -31,7 +34,6 @@ } .whenShowAll { - overflow: visible; white-space: normal; } diff --git "a/web-app/client/src/components/\320\220\320\241/CollapsableView/CollapsableView.tsx" b/web-app/client/src/components/CollapsableView/CollapsableView.tsx similarity index 58% rename from "web-app/client/src/components/\320\220\320\241/CollapsableView/CollapsableView.tsx" rename to web-app/client/src/components/CollapsableView/CollapsableView.tsx index bbef8065d..92aa20473 100644 --- "a/web-app/client/src/components/\320\220\320\241/CollapsableView/CollapsableView.tsx" +++ b/web-app/client/src/components/CollapsableView/CollapsableView.tsx @@ -1,50 +1,38 @@ -import { - GetMainTaskDeps_taskInfo_TaskInfo_data_result_ACTaskResult_ACs_intervals, - GetMainTaskDeps_taskInfo_TaskInfo_data_result_ACTaskResult_ACs_outliers, -} from '@graphql/operations/queries/__generated__/GetMainTaskDeps'; import cn from 'classnames'; import { FC, useLayoutEffect, useRef, useState } from 'react'; import styles from './CollapsableView.module.scss'; -const titles = ['Intervals', 'Outliers'] as const; -type Title = (typeof titles)[number]; - type Props = { - output: - | GetMainTaskDeps_taskInfo_TaskInfo_data_result_ACTaskResult_ACs_outliers - | GetMainTaskDeps_taskInfo_TaskInfo_data_result_ACTaskResult_ACs_intervals; - title: Title; + output: string[]; + title: string; + amount?: number; }; const states = ['not required', 'hidden', 'view'] as const; type CollapseState = (typeof states)[number]; -const CollapsableView: FC = ({ output, title }) => { +const CollapsableView: FC = ({ output, title, amount }) => { const parentRef = useRef(null); const childRef = useRef(null); const [collapseState, setCollapseState] = useState('not required'); + useLayoutEffect(() => { const parentOffset = parentRef.current?.offsetWidth; const childScroll = childRef.current?.scrollWidth; if (parentOffset && childScroll) { - if (parentOffset < childScroll && collapseState == 'not required') { + if (parentOffset < childScroll) { setCollapseState('hidden'); } else { setCollapseState('not required'); } } }, []); - const shownData = - output && - ('outliers' in output - ? output.outliers - : output.intervals.map((intr) => `[${intr[0]}, ${intr[1]}]`)); - return (
- {`${title} (${output.amount})`} + {title} + {amount && ` (${amount})`}
= ({ output, title }) => { )} ref={childRef} > - {shownData && - shownData.map((elem, index) => ( - <> - {elem}{' '} - - ))} + {output.map((elem) => ( + <> + {elem}{' '} + + ))} {collapseState === 'view' && ( - setCollapseState('hidden')} > Show less - + )}
{collapseState === 'hidden' && ( -
setCollapseState('view')} > Show all -
+ )}
diff --git a/web-app/client/src/components/CollapsableView/index.ts b/web-app/client/src/components/CollapsableView/index.ts new file mode 100644 index 000000000..eb1cfbfdb --- /dev/null +++ b/web-app/client/src/components/CollapsableView/index.ts @@ -0,0 +1 @@ +export { default } from './CollapsableView'; diff --git a/web-app/client/src/components/Inputs/NumberInput/NumberInput.tsx b/web-app/client/src/components/Inputs/NumberInput/NumberInput.tsx index 20d5b7059..034cc80c7 100644 --- a/web-app/client/src/components/Inputs/NumberInput/NumberInput.tsx +++ b/web-app/client/src/components/Inputs/NumberInput/NumberInput.tsx @@ -1,14 +1,16 @@ import classNames from 'classnames'; import { - forwardRef, ForwardRefRenderFunction, HTMLProps, ReactNode, + forwardRef, useEffect, useState, } from 'react'; + import { InputPropsBase, Text } from '@components/Inputs'; import Tooltip from '@components/Tooltip'; + import styles from './NumberInput.module.scss'; export interface NumberInputProps { @@ -90,8 +92,9 @@ const NumberInput: ForwardRefRenderFunction = ( {...props} value={displayValue} onBlur={(e) => { - onChange(prepareValue(e.target.value)); - setDisplayValue(prepareValue(e.target.value).toString()); + const preparedValue = prepareValue(e.target.value); + onChange(preparedValue); + setDisplayValue(preparedValue.toString()); }} onChange={(e) => setDisplayValue(e.currentTarget.value)} className={styles.text} diff --git a/web-app/client/src/components/Inputs/NumberSlider/NumberSlider.tsx b/web-app/client/src/components/Inputs/NumberSlider/NumberSlider.tsx index 09372e061..f8fe18cc1 100644 --- a/web-app/client/src/components/Inputs/NumberSlider/NumberSlider.tsx +++ b/web-app/client/src/components/Inputs/NumberSlider/NumberSlider.tsx @@ -1,5 +1,3 @@ -import classNames from 'classnames'; -import Slider, { SliderProps } from 'rc-slider'; import { BaseHTMLAttributes, forwardRef, @@ -9,8 +7,10 @@ import { useEffect, useState, } from 'react'; -import { InputPropsBase, Text } from '@components/Inputs'; +import classNames from 'classnames'; +import Slider, { SliderProps } from 'rc-slider'; import 'rc-slider/assets/index.css'; +import { InputPropsBase, Text } from '@components/Inputs'; import Tooltip from '@components/Tooltip'; import styles from './NumberSlider.module.scss'; @@ -76,9 +76,6 @@ const NumberSlider: ForwardRefRenderFunction = ( if (parsed >= max) return max; return parsed; }; - const prepareValue = (s: string): number => { - return placeInsideBorders(s); - }; return (
= ( {...props} value={tempValue} onBlur={(e) => { - onChange(prepareValue(e.target.value)); - setTempValue(prepareValue(e.target.value).toString()); + const preparedValue = placeInsideBorders(e.target.value); + onChange(preparedValue); + setTempValue(preparedValue.toString()); }} onChange={(e) => setTempValue(e.currentTarget.value)} className={styles.text} diff --git a/web-app/client/src/components/NumberInputWithButton/NumberInputWithButton.module.scss b/web-app/client/src/components/NumberInputWithButton/NumberInputWithButton.module.scss new file mode 100644 index 000000000..f18c09a84 --- /dev/null +++ b/web-app/client/src/components/NumberInputWithButton/NumberInputWithButton.module.scss @@ -0,0 +1,8 @@ +@import "styles/common"; + +.inputContainer { + display: flex; + align-items: last baseline; + gap: 8px; + color: $primary-0; +} \ No newline at end of file diff --git a/web-app/client/src/components/NumberInputWithButton/NumberInputWithButton.tsx b/web-app/client/src/components/NumberInputWithButton/NumberInputWithButton.tsx new file mode 100644 index 000000000..1f33a8cbc --- /dev/null +++ b/web-app/client/src/components/NumberInputWithButton/NumberInputWithButton.tsx @@ -0,0 +1,31 @@ +import Button from '@components/Button' +import styles from './NumberInputWithButton.module.scss' +import { FC, useState } from 'react'; +import NumberInput, { NumberInputProps } from '@components/Inputs/NumberInput/NumberInput'; + +type Props = { + numberProps: NumberInputProps; + buttonText: string; + label: string +} + +const NumberInputWithButton: FC = ({numberProps, buttonText, label}) => { + const [displayValue, setDisplayValue] = useState(numberProps.defaultNum) + const handleButtonClick = () => { + console.log(displayValue) + } + return ( +
+ setDisplayValue(e)} + /> + +
+ + ) +} + +export default NumberInputWithButton \ No newline at end of file diff --git a/web-app/client/src/components/NumberInputWithButton/index.ts b/web-app/client/src/components/NumberInputWithButton/index.ts new file mode 100644 index 000000000..a92270dac --- /dev/null +++ b/web-app/client/src/components/NumberInputWithButton/index.ts @@ -0,0 +1 @@ +export { default } from './NumberInputWithButton'; \ No newline at end of file diff --git a/web-app/client/src/components/ReportsLayout/ReportsLayout.tsx b/web-app/client/src/components/ReportsLayout/ReportsLayout.tsx index e57104cef..dc990d9ef 100644 --- a/web-app/client/src/components/ReportsLayout/ReportsLayout.tsx +++ b/web-app/client/src/components/ReportsLayout/ReportsLayout.tsx @@ -3,6 +3,7 @@ import { useRouter } from 'next/router'; import React, { FC, PropsWithChildren } from 'react'; import Background from '@assets/backgrounds/reports.svg?component'; import ChartIcon from '@assets/icons/chart.svg?component'; +import HistogramIcon from '@assets/icons/bar-chart.svg?component'; import ClusterIcon from '@assets/icons/cluster.svg?component'; import DatatableIcon from '@assets/icons/datatable.svg?component'; import DropDownIcon from '@assets/icons/list-dropdown.svg?component'; @@ -41,6 +42,16 @@ const menuMFDClusters = { pathname: '/reports/metric-dependencies', icon: , }; +const menuACHistogram = { + label: 'Histogram', + pathname: '/reports/histogram', + icon: , +}; +const menuACInstanceList = { + label: 'Instance List', + pathname: '/reports/ac-instance-list', + icon: , +}; export const reportsTabs: Record< PrimitiveType, @@ -53,6 +64,7 @@ export const reportsTabs: Record< [PrimitiveType.TypoFD]: [menuPrimitiveList, menuClusters, menuDatasetSnippet], [PrimitiveType.MFD]: [menuMFDClusters], [PrimitiveType.Stats]: [], + [PrimitiveType.AC]: [menuACInstanceList, menuACHistogram, menuDatasetSnippet], }; export const ReportsLayout: FC = ({ @@ -62,7 +74,7 @@ export const ReportsLayout: FC = ({ }) => { const router = useRouter(); const { data } = useTaskState(); - const type = data.type as PrimitiveType; + const type = data.taskID === '22fcfc02-de6e-4e4b-b75d-16e3881f68ad' ? PrimitiveType.AC : data.type as PrimitiveType; return (
diff --git "a/web-app/client/src/components/\320\220\320\241/Intervals/Intervals.tsx" "b/web-app/client/src/components/\320\220\320\241/Intervals/Intervals.tsx" deleted file mode 100644 index 4ba6df8d5..000000000 --- "a/web-app/client/src/components/\320\220\320\241/Intervals/Intervals.tsx" +++ /dev/null @@ -1,119 +0,0 @@ -import DivisionIcon from '@assets/icons/division.svg?component'; -import MinusIcon from '@assets/icons/minus.svg?component'; -import MultiplicationIcon from '@assets/icons/multiplication.svg?component'; -import PlusIcon from '@assets/icons/plus.svg?component'; -import ACAtom, { - ACAtomDefaultValuesWithParams, - ACInstance, -} from '@atoms/ACTaskAtom'; -import { - GetMainTaskDeps_taskInfo_TaskInfo_data_result_ACTaskResult_ACs_attributes, - GetMainTaskDeps_taskInfo_TaskInfo_data_result_ACTaskResult_ACs_intervals, - GetMainTaskDeps_taskInfo_TaskInfo_data_result_ACTaskResult_ACs_outliers, - Operation, -} from '@graphql/operations/queries/__generated__/GetMainTaskDeps'; -import cn from 'classnames'; -import { useAtom } from 'jotai'; -import { FC, useLayoutEffect, useRef, useState } from 'react'; -import CollapsableView from '../CollapsableView/CollapsableView'; -import styles from './Intervals.module.scss'; - -type Props = { - attributes: GetMainTaskDeps_taskInfo_TaskInfo_data_result_ACTaskResult_ACs_attributes; - operation: Operation; - outliers: GetMainTaskDeps_taskInfo_TaskInfo_data_result_ACTaskResult_ACs_outliers; - intervals: GetMainTaskDeps_taskInfo_TaskInfo_data_result_ACTaskResult_ACs_intervals; -}; - -const states = ['not required', 'hidden', 'view'] as const; -type OutputState = (typeof states)[number]; - -const Intervals: FC = ({ - attributes, - operation, - outliers, - intervals, -}) => { - const intervalsRef = useRef(null); - const intervalsOutputRef = useRef(null); - const oultiersRef = useRef(null); - const outliersOutputRef = useRef(null); - - const [intervalsState, setIntervalsState] = - useState('not required'); - const [outliersState, setOutliersState] = - useState('not required'); - - useLayoutEffect(() => { - const parentIntervalsOffset = intervalsRef.current?.offsetWidth; - const childIntervalsScroll = intervalsOutputRef.current?.scrollWidth; - - const parentOutliersOffset = oultiersRef.current?.offsetWidth; - const childOutliersScroll = outliersOutputRef.current?.scrollWidth; - - if (parentIntervalsOffset && childIntervalsScroll) { - if ( - parentIntervalsOffset < childIntervalsScroll && - intervalsState == 'not required' - ) { - setIntervalsState('hidden'); - } else { - setIntervalsState('not required'); - } - } - - if (parentOutliersOffset && childOutliersScroll) { - if ( - parentOutliersOffset < childOutliersScroll && - outliersState == 'not required' - ) { - setOutliersState('hidden'); - } else { - setOutliersState('not required'); - } - } - }, [intervalsState, outliersState]); - const operationIcon = - (operation === 'ADDITION' && ) || - (operation === 'MULTIPLICATION' && ( - - )) || - (operation === 'DIVISION' && ) || - (operation === 'SUBTRACTION' && ); - - const [atom, setAtom] = useAtom(ACAtom); - const handleSelect = () => { - const instance: ACInstance = { - attribute1: attributes.attr1, - attribute2: attributes.attr2, - intervals: intervals.intervals, - outliers: outliers.outliers, - }; - setAtom({ ...ACAtomDefaultValuesWithParams(atom.taskID, instance) }); - }; - - const variant = - atom.instanceSelected?.attribute1 === attributes.attr1 && - atom.instanceSelected?.attribute2 === attributes.attr2 - ? 'selected' - : 'default'; - return ( -
-
- Operation -
-
{attributes.attr1}
- {operationIcon} -
{attributes.attr2}
-
-
- - -
- ); -}; - -export default Intervals; diff --git a/web-app/client/src/constants/configuratorForm/ACForm/SeedCustomInputs/SeedCustomInput.module.scss b/web-app/client/src/constants/configuratorForm/ACForm/SeedCustomInput/SeedCustomInput.module.scss similarity index 100% rename from web-app/client/src/constants/configuratorForm/ACForm/SeedCustomInputs/SeedCustomInput.module.scss rename to web-app/client/src/constants/configuratorForm/ACForm/SeedCustomInput/SeedCustomInput.module.scss index bb0c488aa..adad5a874 100644 --- a/web-app/client/src/constants/configuratorForm/ACForm/SeedCustomInputs/SeedCustomInput.module.scss +++ b/web-app/client/src/constants/configuratorForm/ACForm/SeedCustomInput/SeedCustomInput.module.scss @@ -1,7 +1,7 @@ .seedCustomInput { display: flex; - gap: 16px; align-items: flex-end; + gap: 16px; } .input { diff --git a/web-app/client/src/constants/configuratorForm/ACForm/SeedCustomInputs/SeedCustomInput.tsx b/web-app/client/src/constants/configuratorForm/ACForm/SeedCustomInput/SeedCustomInput.tsx similarity index 70% rename from web-app/client/src/constants/configuratorForm/ACForm/SeedCustomInputs/SeedCustomInput.tsx rename to web-app/client/src/constants/configuratorForm/ACForm/SeedCustomInput/SeedCustomInput.tsx index 73fc5eb9c..4df3cb457 100644 --- a/web-app/client/src/constants/configuratorForm/ACForm/SeedCustomInputs/SeedCustomInput.tsx +++ b/web-app/client/src/constants/configuratorForm/ACForm/SeedCustomInput/SeedCustomInput.tsx @@ -1,21 +1,10 @@ import Button from '@components/Button'; -import styles from './SeedCustomInput.module.scss'; import { NumberInput } from '@components/Inputs'; -import { - FormCustomProps, - FormFieldProps, - FormNumberInputProps, -} from 'types/form'; -import { - BaseSyntheticEvent, - FC, - ForwardRefRenderFunction, - forwardRef, -} from 'react'; +import { ForwardRefRenderFunction, forwardRef } from 'react'; import { ControllerRenderProps } from 'react-hook-form'; +import { FormCustomProps } from 'types/form'; import { ACDefaults } from '../index'; - -//Omit, "rules"> & Record & ControllerRenderProps +import styles from './SeedCustomInput.module.scss'; type Props = Omit, 'rules'> & ControllerRenderProps; @@ -25,7 +14,7 @@ const SeedCustomInput: ForwardRefRenderFunction = ( ref, ) => { const handlerRandomSeed = () => { - const newSeed = Math.round(Math.random() * 999_999); + const newSeed = Math.floor(Math.random() * 900000) + 100000; props.onChange(newSeed); }; return ( diff --git a/web-app/client/src/constants/configuratorForm/ACForm/SeedCustomInput/index.ts b/web-app/client/src/constants/configuratorForm/ACForm/SeedCustomInput/index.ts new file mode 100644 index 000000000..31b0450f9 --- /dev/null +++ b/web-app/client/src/constants/configuratorForm/ACForm/SeedCustomInput/index.ts @@ -0,0 +1 @@ +export { default } from './SeedCustomInput'; diff --git a/web-app/client/src/constants/configuratorForm/ACForm/SeedCustomInputs/index.ts b/web-app/client/src/constants/configuratorForm/ACForm/SeedCustomInputs/index.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/web-app/client/src/constants/configuratorForm/ACForm/index.ts b/web-app/client/src/constants/configuratorForm/ACForm/index.ts index 7c7c01ee8..aed6ba1a1 100644 --- a/web-app/client/src/constants/configuratorForm/ACForm/index.ts +++ b/web-app/client/src/constants/configuratorForm/ACForm/index.ts @@ -2,7 +2,7 @@ import { ACoptions } from '@constants/options'; import { UpperCaseOption } from '@utils/uppercaseOptions'; import { toScreamingSnakeOption } from '@constants/options'; import { Defaults, FormFieldsProps, CreateForm, Presets } from 'types/form'; -import SeedCustomInput from './SeedCustomInputs/SeedCustomInput'; +import SeedCustomInput from './SeedCustomInput'; const ACoperations = [ 'Addition', @@ -30,7 +30,7 @@ export const ACDefaults = { operation: 'MULTIPLICATION', } satisfies Defaults; -const FDPresets: Presets = [ +const ACPresets: Presets = [ { filenames: 'EveryFile', presetName: 'Some preset', @@ -49,6 +49,13 @@ const ACFields = { isLoading: false, options: ACoptions, }, + operation: { + order: 1, + type: 'select', + label: 'Operation', + isLoading: false, + options: ACoperationOptions, + }, bumpsLimit: { order: 2, type: 'number_input', @@ -62,6 +69,14 @@ const ACFields = { numbersAfterDot: 0, }, }, + weight: { + order: 3, + type: 'number_slider', + label: 'Weight', + tooltip: + 'Weight defines the size of discovered intervals, 0 — lots of small intervals, 1 — a single large one. This parameter is called w in the paper.', + numberSliderProps: { min: 0, max: 1, step: 1e-4, size: 4 }, + }, iterationsLimit: { order: 4, type: 'number_input', @@ -75,12 +90,13 @@ const ACFields = { numbersAfterDot: 0, }, }, - operation: { - order: 1, - type: 'select', - label: 'Operation', - isLoading: false, - options: ACoperationOptions, + fuzziness: { + order: 5, + type: 'number_slider', + label: 'Fuzziness', + tooltip: + 'Fuzziness is the fraction of rows not included in the sample: the closer to 0, the more rows will be selected and the closer to 1, the fewer rows will be selected. This parameter is called f in the paper.', + numberSliderProps: { min: 0, max: 1, step: 1e-4, size: 4 }, }, seed: { order: 6, @@ -92,22 +108,6 @@ const ACFields = { }, component: SeedCustomInput as any, //TODO: investigate later }, - weight: { - order: 3, - type: 'number_slider', - label: 'Weight', - tooltip: - 'Weight defines the size of discovered intervals, 0 — lots of small intervals, 1 — a single large one. This parameter is called w in the paper.', - numberSliderProps: { min: 0, max: 1, step: 1e-4, size: 4 }, - }, - fuzziness: { - order: 5, - type: 'number_slider', - label: 'Fuzziness', - tooltip: - 'Fuzziness is the fraction of rows not included in the sample: the closer to 0, the more rows will be selected and the closer to 1, the fewer rows will be selected. This parameter is called f in the paper.', - numberSliderProps: { min: 0, max: 1, step: 1e-4, size: 4 }, - }, pFuzz: { order: 7, type: 'number_slider', @@ -121,5 +121,5 @@ const ACFields = { export const ACForm = CreateForm({ formDefaults: ACDefaults, formFields: ACFields, - formPresets: FDPresets, + formPresets: ACPresets, }); diff --git a/web-app/client/src/constants/formPrimitives.ts b/web-app/client/src/constants/formPrimitives.ts index 69d9b83a7..1e9fcd837 100644 --- a/web-app/client/src/constants/formPrimitives.ts +++ b/web-app/client/src/constants/formPrimitives.ts @@ -2,7 +2,7 @@ import { ARForm } from '@constants/configuratorForm/ARForm'; import { CFDForm } from '@constants/configuratorForm/CFDForm'; import { FDForm } from '@constants/configuratorForm/FDForm'; import { MFDForm } from '@constants/configuratorForm/MFDForm'; -import { ACForm } from '@constants/configuratorForm/ACForm/index'; +import { ACForm } from '@constants/configuratorForm/ACForm'; import { TypoFDForm } from '@constants/configuratorForm/TypoFDForm'; import { MainPrimitiveType } from 'types/globalTypes'; diff --git a/web-app/client/src/constants/primitiveReportPathnames.ts b/web-app/client/src/constants/primitiveReportPathnames.ts index 4762bdd42..b70d737b6 100644 --- a/web-app/client/src/constants/primitiveReportPathnames.ts +++ b/web-app/client/src/constants/primitiveReportPathnames.ts @@ -8,5 +8,5 @@ export const primitivePathnames: Record = { Stats: 'reports/dependencies', TypoCluster: 'reports/dependencies', TypoFD: 'reports/dependencies', - AC: 'reports/dependencies', + AC: 'reports/ac-instance-list', }; diff --git a/web-app/client/src/graphql/client.ts b/web-app/client/src/graphql/client.ts index 9befae98c..59533f2f4 100644 --- a/web-app/client/src/graphql/client.ts +++ b/web-app/client/src/graphql/client.ts @@ -7,7 +7,6 @@ import { customFetch } from '@graphql/customFetch'; import { pathnameToLocalURL } from '@utils/pathnameToValidURL'; const isServer = typeof window === 'undefined'; -console.log(serverProxyURL) const client = new ApolloClient({ ssrMode: isServer, uri: isServer ? pathnameToLocalURL(serverProxyURL) : serverProxyURL, diff --git a/web-app/client/src/graphql/context.ts b/web-app/client/src/graphql/context.ts index e740a940f..e7bd92352 100644 --- a/web-app/client/src/graphql/context.ts +++ b/web-app/client/src/graphql/context.ts @@ -131,7 +131,6 @@ export const errorLink = onError( return forward$.flatMap(() => forward(operation)); default: - console.log(err) showError(err.extensions.code, `Error: ${err.message}`); } } diff --git a/web-app/client/src/pages/create-task/configure-algorithm.tsx b/web-app/client/src/pages/create-task/configure-algorithm.tsx index 8bf8b8686..0f84f1032 100644 --- a/web-app/client/src/pages/create-task/configure-algorithm.tsx +++ b/web-app/client/src/pages/create-task/configure-algorithm.tsx @@ -7,7 +7,7 @@ import { UsedPrimitivesType, } from '@constants/formPrimitives'; import { useTaskUrlParams } from '@hooks/useTaskUrlParams'; -import styles from '@components/AlgorithmFormConfigurator/ConfigureAlgorithm.module.scss'; +import styles from '@styles/configure-algorithm.module.scss'; const ConfigureAlgorithm: NextPage = () => { const router = useRouter(); diff --git a/web-app/client/src/pages/reports/ACFakeData/data4Histogram.ts b/web-app/client/src/pages/reports/ACFakeData/data4Histogram.ts new file mode 100644 index 000000000..4241081bb --- /dev/null +++ b/web-app/client/src/pages/reports/ACFakeData/data4Histogram.ts @@ -0,0 +1,86 @@ +export const myData = { + taskInfo: { + __typename: 'TaskInfo', + taskID: '22fcfc02-de6e-4e4b-b75d-16e3881f68ad', + data: { + __typename: 'ACTaskData', + operation: 'ADDITION', + histogramData: { + __typename: 'ACHistogramData', + taskID: '22fcfc02-de6e-4e4b-b75d-16e3881f68ad', + barsAmount: 6, + granularity: 10, + attributes: { + __typename: 'Attributes', + attribute1: 'Coffee', + attribute2: 'Milk', + }, + data: [ + { + __typename: 'ACHistogramBar', + range: [0, 1], + valuesInRange: 3, + option: 'outlier', + associatedInterval: null, + }, + { + __typename: 'ACHistogramBar', + range: [1, 2], + valuesInRange: 8, + option: 'default', + associatedInterval: [1, 4], + }, + { + __typename: 'ACHistogramBar', + range: [2, 3], + valuesInRange: 10, + option: 'default', + associatedInterval: [1, 4], + }, + { + __typename: 'ACHistogramBar', + range: [3, 4], + valuesInRange: 9, + option: 'default', + associatedInterval: [1, 4], + }, + { + __typename: 'ACHistogramBar', + range: [4, 5], + valuesInRange: 11, + option: 'outlier', + associatedInterval: null, + }, + { + __typename: 'ACHistogramBar', + range: [5, 6], + valuesInRange: null, + option: 'outlier', + associatedInterval: null, + }, + { + __typename: 'ACHistogramBar', + range: [6, 7], + valuesInRange: 1, + option: 'outlier', + associatedInterval: null, + }, + { + __typename: 'ACHistogramBar', + range: [7, 8], + valuesInRange: 4, + option: 'default', + associatedInterval: [7, 8], + }, + { + __typename: 'ACHistogramBar', + range: [8, 9], + valuesInRange: 2, + option: 'outlier', + associatedInterval: null, + }, + ], + }, + }, + }, +}; \ No newline at end of file diff --git a/web-app/client/src/pages/reports/ACFakeData/data4InstanceList.ts b/web-app/client/src/pages/reports/ACFakeData/data4InstanceList.ts new file mode 100644 index 000000000..c03892274 --- /dev/null +++ b/web-app/client/src/pages/reports/ACFakeData/data4InstanceList.ts @@ -0,0 +1,167 @@ +import { GetMainTaskDeps } from "@graphql/operations/queries/__generated__/GetMainTaskDeps"; + +export const myData: GetMainTaskDeps = { + taskInfo: { + __typename: 'TaskInfo', + taskID: '22fcfc02-de6e-4e4b-b75d-16e3881f68ad', + data: { + __typename: 'ACTaskData', + operation: 'ADDITION', + result: { + __typename: 'ACTaskResult', + taskID: '22fcfc02-de6e-4e4b-b75d-16e3881f68ad', + pairsAttributesAmount: 6, + ACs: [ + { + __typename: 'AC', + attributes: { + __typename: 'Attributes', + attr1: 'Coffee', + attr2: 'Milk', + }, + intervals: { + __typename: 'Intervals', + amount: 5, + intervals: [ + [0, 1], + [2, 3], + [4, 5], + [6, 7], + [8, 9], + ], + }, + outliers: { + __typename: 'Outliers', + amount: 17, + outliers: [ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + ], + }, + }, + { + __typename: 'AC', + attributes: { + __typename: 'Attributes', + attr1: 'Milk', + attr2: 'Chocolate', + }, + intervals: { + __typename: 'Intervals', + amount: 2, + intervals: [ + [0, 1], + [4, 5], + ], + }, + outliers: { + __typename: 'Outliers', + amount: 3, + outliers: [3, 4, 5], + }, + }, + { + __typename: 'AC', + attributes: { + __typename: 'Attributes', + attr1: 'Coffee', + attr2: 'Chocolate', + }, + intervals: { + __typename: 'Intervals', + amount: 6, + intervals: [ + [980, 1010], + [1012, 1019], + [1110, 1140], + [1200, 1228], + [1245, 1260], + [1280, 1320], + ], + }, + outliers: { + __typename: 'Outliers', + amount: 12, + outliers: [ + 100, 104, 108, 112, 113, 114, 115, 116, 117, 118, 119, 120, + ], + }, + }, + { + __typename: 'AC', + attributes: { + __typename: 'Attributes', + attr1: 'Tea', + attr2: 'Milk', + }, + intervals: { + __typename: 'Intervals', + amount: 5, + intervals: [ + [0, 1], + [2, 3], + [4, 5], + [6, 7], + [8, 9], + ], + }, + outliers: { + __typename: 'Outliers', + amount: 17, + outliers: [ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + ], + }, + }, + { + __typename: 'AC', + attributes: { + __typename: 'Attributes', + attr1: 'Tea', + attr2: 'Chocolate', + }, + intervals: { + __typename: 'Intervals', + amount: 6, + intervals: [ + [980, 1010], + [1012, 1019], + [1110, 1140], + [1200, 1228], + [1245, 1260], + [1280, 1320], + ], + }, + outliers: { + __typename: 'Outliers', + amount: 12, + outliers: [ + 100, 104, 108, 112, 113, 114, 115, 116, 117, 118, 119, 120, + ], + }, + }, + { + __typename: 'AC', + attributes: { + __typename: 'Attributes', + attr1: 'Tea', + attr2: 'Coffee', + }, + intervals: { + __typename: 'Intervals', + amount: 2, + intervals: [ + [0, 1], + [4, 5], + ], + }, + outliers: { + __typename: 'Outliers', + amount: 3, + outliers: [3, 4, 5], + }, + }, + ], + }, + }, + }, +}; diff --git a/web-app/client/src/pages/reports/ac-instance-list.tsx b/web-app/client/src/pages/reports/ac-instance-list.tsx index 944f4832e..4dbcea3b3 100644 --- a/web-app/client/src/pages/reports/ac-instance-list.tsx +++ b/web-app/client/src/pages/reports/ac-instance-list.tsx @@ -1,241 +1,31 @@ -import OrderingIcon from '@assets/icons/ordering.svg?component'; import ACAtom, { ACAtomDefaultValuesWithParams } from '@atoms/ACTaskAtom'; +import { Operation } from '@graphql/operations/queries/__generated__/GetMainTaskDeps'; +import { useAtom } from 'jotai'; +import { ReactElement, useEffect, useState } from 'react'; +import { FormProvider } from 'react-hook-form'; +import { ACSortBy, OrderBy, PrimitiveType } from 'types/globalTypes'; +import { NextPageWithLayout } from 'types/pageWithLayout'; + +import ACInstance from '@components/ACInstance'; import Button from '@components/Button'; import { OrderingWindow, useFilters } from '@components/Filters'; import { Text } from '@components/Inputs'; import Pagination from '@components/Pagination/Pagination'; import ReportsLayout from '@components/ReportsLayout'; import { TaskContextProvider } from '@components/TaskContext'; -import Intervals from '@components/АС/Intervals/Intervals'; -import { GetMainTaskDeps } from '@graphql/operations/queries/__generated__/GetMainTaskDeps'; + import styles from '@styles/Dependencies.module.scss'; -import { useAtom } from 'jotai'; -import { ReactElement, useEffect, useState } from 'react'; -import { FormProvider } from 'react-hook-form'; -import { - ACSortBy, - OrderBy, - PrimitiveType, -} from 'types/globalTypes'; -import { NextPageWithLayout } from 'types/pageWithLayout'; -type Props = { - defaultData?: GetMainTaskDeps; -}; +import OrderingIcon from '@assets/icons/ordering.svg?component'; + +import { myData } from './ACFakeData/data4InstanceList'; const ReportsAlgebraicConstraints: NextPageWithLayout = () => { - const myData: GetMainTaskDeps = { - taskInfo: { - __typename: 'TaskInfo', - taskID: '22fcfc02-de6e-4e4b-b75d-16e3881f68ad', - data: { - __typename: 'ACTaskData', - operation: 'ADDITION', - result: { - __typename: 'ACTaskResult', - taskID: '22fcfc02-de6e-4e4b-b75d-16e3881f68ad', - pairsAttributesAmount: 6, - ACs: [ - { - __typename: 'AC', - attributes: { - __typename: 'Attributes', - attr1: 'Coffee', - attr2: 'Milk', - }, - intervals: { - __typename: 'Intervals', - amount: 5, - intervals: [ - [0, 1], - [2, 3], - [4, 5], - [6, 7], - [8, 9], - ], - }, - outliers: { - __typename: 'Outliers', - amount: 17, - outliers: [ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - ], - }, - }, - { - __typename: 'AC', - attributes: { - __typename: 'Attributes', - attr1: 'Milk', - attr2: 'Chocolate', - }, - intervals: { - __typename: 'Intervals', - amount: 2, - intervals: [ - [0, 1], - [4, 5], - ], - }, - outliers: { - __typename: 'Outliers', - amount: 3, - outliers: [3, 4, 5], - }, - }, - { - __typename: 'AC', - attributes: { - __typename: 'Attributes', - attr1: 'Coffee', - attr2: 'Chocolate', - }, - intervals: { - __typename: 'Intervals', - amount: 6, - intervals: [ - [980, 1010], - [1012, 1019], - [1110, 1140], - [1200, 1228], - [1245, 1260], - [1280, 1320], - ], - }, - outliers: { - __typename: 'Outliers', - amount: 12, - outliers: [ - 100, 104, 108, 112, 113, 114, 115, 116, 117, 118, 119, 120, - ], - }, - }, - { - __typename: 'AC', - attributes: { - __typename: 'Attributes', - attr1: 'Tea', - attr2: 'Milk', - }, - intervals: { - __typename: 'Intervals', - amount: 5, - intervals: [ - [0, 1], - [2, 3], - [4, 5], - [6, 7], - [8, 9], - ], - }, - outliers: { - __typename: 'Outliers', - amount: 17, - outliers: [ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - ], - }, - }, - { - __typename: 'AC', - attributes: { - __typename: 'Attributes', - attr1: 'Tea', - attr2: 'Chocolate', - }, - intervals: { - __typename: 'Intervals', - amount: 6, - intervals: [ - [980, 1010], - [1012, 1019], - [1110, 1140], - [1200, 1228], - [1245, 1260], - [1280, 1320], - ], - }, - outliers: { - __typename: 'Outliers', - amount: 12, - outliers: [ - 100, 104, 108, 112, 113, 114, 115, 116, 117, 118, 119, 120, - ], - }, - }, - { - __typename: 'AC', - attributes: { - __typename: 'Attributes', - attr1: 'Tea', - attr2: 'Coffee', - }, - intervals: { - __typename: 'Intervals', - amount: 2, - intervals: [ - [0, 1], - [4, 5], - ], - }, - outliers: { - __typename: 'Outliers', - amount: 3, - outliers: [3, 4, 5], - }, - }, - ], - }, - }, - }, - }; const [isOrderingShown, setIsOrderingShown] = useState(false); - - const primitive = PrimitiveType.AC; - const methods = useFilters(primitive || PrimitiveType.FD); + const methods = useFilters(PrimitiveType.AC); const { register, setValue: setFilterParam } = methods; - /*const { search, page, ordering, direction } = watch(); - - const [getDeps, { loading, data, previousData }] = useLazyQuery< - GetMainTaskDeps, - GetMainTaskDepsVariables - >(GET_MAIN_TASK_DEPS); - - const [sortBy, setSortBy] = useState(ACSortBy.NUMBER_OF_INTERVALS); - const [orderBy, setOrderBy] = useState(OrderBy.ASC); - - const filter = useMemo(() => { - const sortingParams = { - [PrimitiveType.AC + 'SortBy']: ordering, - }; - - return { - filterString: search, - pagination: { limit: 6, offset: (page - 1) * 6 }, - ...sortingParams, - orderBy: direction, - }; - }, [ - primitive, - search, - page, - ordering, - direction, - ]); - - useEffect(() => { - if (!primitive) return; - - getDeps({ - variables: { - taskID, - filter, - }, - }); - }, [taskID, primitive, getDeps, filter]);*/ + const [atom, setAtom] = useAtom(ACAtom); - // todo add loading text/animation, maybe in Pagination component too - //const shownData = (loading ? previousData : data) || myData; const shownData = myData; const ACs = (shownData.taskInfo.data.result && @@ -245,14 +35,12 @@ const ReportsAlgebraicConstraints: NextPageWithLayout = () => { const operation = ('operation' in shownData.taskInfo.data && shownData.taskInfo.data.operation) || - 'ADDITION'; + Operation.ADDITION; const recordsCount = shownData?.taskInfo.data.result && 'pairsAttributesAmount' in shownData?.taskInfo.data.result && shownData?.taskInfo.data.result.pairsAttributesAmount; - const [atom, setAtom] = useAtom(ACAtom); - useEffect(() => { setAtom({ ...ACAtomDefaultValuesWithParams( @@ -261,6 +49,7 @@ const ReportsAlgebraicConstraints: NextPageWithLayout = () => { ), }); }, [shownData.taskInfo.taskID]); + return ( <> @@ -292,14 +81,14 @@ const ReportsAlgebraicConstraints: NextPageWithLayout = () => { > Ordering - {/*primitive && */}
- {ACs.map((value, index) => ( - ( + { + const { payload } = props; + if (payload && payload.length) { + const { associatedInterval, range, option, valuesInRange } = + payload[0].payload; + return ( +
+

{`Range: [${range[0]}, ${range[1]}]`}

+

{'Values in range: ' + valuesInRange}

+ {option === 'default' && ( +

{`Associated interval: [${associatedInterval[0]}, ${associatedInterval[1]}]`}

+ )} +
+ ); + } +}; + +const renderActiveBar = (props: any) => { + const { x, y, width, height, payload } = props; + const color = + payload.option === 'default' ? colors.primary[100] : colors.black[50]; + + return ( + + ); }; +interface shownDataType { + range: number[]; + mediana: number; + valuesInRange: number; + option: 'default' | 'outlier'; + associatedInterval: number[]; +} + const ReportsHistogram: NextPageWithLayout = () => { const [activeInterval, setActiveInterval] = useState(null); + const { operation, histogramData } = myData.taskInfo.data; + const { attributes, granularity } = histogramData; - const renderActiveBar = (props: any) => { - const { x, y, width, height } = props; - const color = props.payload.option === 'default' ? '#7600D1' : '#808080'; + const OperationIcon = operationIcons[operation as Operation]; - return ; - }; - - const CustomTooltip = (props: any) => { - if (props.payload && props.payload.length) { - const associated = props.payload[0].payload.associated; - const interval = props.payload[0].payload.interval; - return ( -
-

{`Range: [${interval[0]}, ${interval[1]}]`}

-

{'Values in range: ' + props.payload[0].payload.value}

- {props.payload[0].payload.option === 'default' && ( -

{`Associated interval: [${associated[0]}, ${associated[1]}]`}

- )} -
- ); - } - return null; + const numberProps: NumberInputProps = { + defaultNum: granularity, + min: 1, + includingMin: true, + numbersAfterDot: 0, }; - const data = myData.taskInfo.data.histogramData.data; - const operation = myData.taskInfo.data.operation; - const attributes = myData.taskInfo.data.histogramData.attributes; - - const operationIcon = - (operation === 'ADDITION' && ) || - (operation === 'MULTIPLICATION' && ( - - )) || - (operation === 'DIVISION' && ) || - (operation === 'SUBTRACTION' && ); + const data = myData.taskInfo.data.histogramData.data.map( + (elem) => + ({ + range: elem.range, + mediana: (elem.range[0] + elem.range[1]) / 2, + valuesInRange: elem.valuesInRange, + option: elem.option, + associatedInterval: elem.associatedInterval, + }) as shownDataType, + ); - const numberProps: NumberInputProps = { - defaultNum: myData.taskInfo.data.histogramData.granularity, + const fillActiveBar = (entry: shownDataType) => { + if ( + activeInterval && + entry.associatedInterval && + entry.associatedInterval[0] === activeInterval[0] && + entry.associatedInterval[1] === activeInterval[1] + ) { + return colors.primary[75]; + } + if (entry.option === 'default') { + return colors.black[75]; + } + return colors.black[25]; }; return ( <>
-
- Granularity -
- {}} - /> - -
-
+
-
{attributes.attr1}
- {operationIcon} -
{attributes.attr2}
+
{attributes.attribute1}
+ +
{attributes.attribute2}
- - - - [ - Math.floor(dataMin), - Math.ceil(dataMax), - ]} - /> - - } /> - setActiveInterval(props.associated)} - onMouseLeave={() => setActiveInterval(null)} - dataKey="value" - activeBar={renderActiveBar} - > - {data.map((entry, index) => ( - - ))} - - - +
+ + + + [ + Math.floor(dataMin), + Math.ceil(dataMax), + ]} + /> + + } /> + + setActiveInterval(props.associatedInterval) + } + onMouseLeave={() => setActiveInterval(null)} + dataKey="valuesInRange" + activeBar={renderActiveBar} + > + {data.map((entry) => ( + + ))} + + + +
); }; diff --git a/web-app/client/src/styles/common/_mixins.scss b/web-app/client/src/styles/common/_mixins.scss index 814ab9cbc..f245310f1 100644 --- a/web-app/client/src/styles/common/_mixins.scss +++ b/web-app/client/src/styles/common/_mixins.scss @@ -1,4 +1,4 @@ -@import "variables"; +@import "variables.module"; @mixin heading-1 { font-family: $font-display; diff --git a/web-app/client/src/styles/common/index.scss b/web-app/client/src/styles/common/index.scss index e9336edb8..cb13c5377 100644 --- a/web-app/client/src/styles/common/index.scss +++ b/web-app/client/src/styles/common/index.scss @@ -1,2 +1,2 @@ -@import "variables"; +@import "variables.module"; @import "mixins"; \ No newline at end of file diff --git a/web-app/client/src/styles/common/_variables.scss b/web-app/client/src/styles/common/variables.module.scss similarity index 91% rename from web-app/client/src/styles/common/_variables.scss rename to web-app/client/src/styles/common/variables.module.scss index 15c2c2fec..7b8265ab8 100644 --- a/web-app/client/src/styles/common/_variables.scss +++ b/web-app/client/src/styles/common/variables.module.scss @@ -45,6 +45,7 @@ $white-25: rgba($white, 0.25); $white-10: rgba($white, 0.10); $white-05: rgba($white, 0.05); +$primary-75: rgba($primary-0, 0.75); $primary-50: rgba($primary-0, 0.50); $primary-25: rgba($primary-0, 0.25); $primary-10: rgba($primary-0, 0.10); @@ -67,3 +68,13 @@ $background: rgb(242, 245, 251); /* Breakpoints */ $screen-sm-max: 768px; $screen-md-min: $screen-sm-max + 1px; + +/* stylelint-disable */ +:export { + primary100: $primary-0; + primary75: $primary-75; + black50: $black-50; + black25: $black-25; + black75: $black-75; +} +/* stylelint-enable */ diff --git a/web-app/client/src/styles/common/variables.ts b/web-app/client/src/styles/common/variables.ts new file mode 100644 index 000000000..955f3f3a3 --- /dev/null +++ b/web-app/client/src/styles/common/variables.ts @@ -0,0 +1,13 @@ +import variables from './variables.module.scss' + +export const colors = { + primary: { + 75: variables.primary75, + 100: variables.primary100, + }, + black: { + 25: variables.black25, + 50: variables.black50, + 75: variables.black75, + }, +}; \ No newline at end of file diff --git a/web-app/client/src/styles/configure-algoritm.module.scss b/web-app/client/src/styles/configure-algorithm.module.scss similarity index 97% rename from web-app/client/src/styles/configure-algoritm.module.scss rename to web-app/client/src/styles/configure-algorithm.module.scss index 2e835b7de..b2cff05bd 100644 --- a/web-app/client/src/styles/configure-algoritm.module.scss +++ b/web-app/client/src/styles/configure-algorithm.module.scss @@ -1,16 +1,16 @@ @import "styles/common"; .filler { - height: 80px; - width: fit-content; - margin: auto; display: flex; align-items: center; - + margin: auto; + height: 80px; + width: fit-content; + .text { h6 { @include heading-6; margin-bottom: 8px; } } -} \ No newline at end of file +} diff --git a/web-app/client/src/styles/histogram.module.scss b/web-app/client/src/styles/histogram.module.scss index 7c6b60826..a01314c90 100644 --- a/web-app/client/src/styles/histogram.module.scss +++ b/web-app/client/src/styles/histogram.module.scss @@ -2,8 +2,8 @@ .attributes { display: flex; + align-items: center; gap: 8px; - align-items: baseline; color: $primary-0; } @@ -12,12 +12,12 @@ height: 24px; } -.attr { +.attribute { @include paragraph; border-radius: 8px; - text-align: center; - background: $secondary-2; padding: 16px 32px; + background: $secondary-2; + text-align: center; } .header { @@ -32,11 +32,15 @@ .customTooltip { @include paragraph-small; - color: $black-75; - background-color: $white; border: 2px solid $black-50; border-radius: 4px; padding: 16px; max-width: 400px; + background-color: $white; + color: $black-75; +} -} \ No newline at end of file +.histogramContainer { + width: 80%; + height: 80%; +} diff --git a/web-app/client/yarn.lock b/web-app/client/yarn.lock index f7ed183ca..65733a08e 100644 --- a/web-app/client/yarn.lock +++ b/web-app/client/yarn.lock @@ -1088,6 +1088,13 @@ resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== +"@babel/runtime@^7.1.2": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.5.tgz#11edb98f8aeec529b82b211028177679144242db" + integrity sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/runtime@^7.10.1", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.22.6" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.6.tgz#57d64b9ae3cff1d67eb067ae117dac087f5bd438" @@ -2305,6 +2312,69 @@ resolved "https://registry.yarnpkg.com/@types/crypto-js/-/crypto-js-4.1.1.tgz#602859584cecc91894eb23a4892f38cfa927890d" integrity sha512-BG7fQKZ689HIoc5h+6D2Dgq1fABRa0RbBWKBd9SP/MVRVXROflpm5fhwyATX5duFmbStzyzyycPB8qUYKDH3NA== +"@types/d3-array@^3.0.3": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.2.1.tgz#1f6658e3d2006c4fceac53fde464166859f8b8c5" + integrity sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg== + +"@types/d3-color@*": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.3.tgz#368c961a18de721da8200e80bf3943fb53136af2" + integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A== + +"@types/d3-ease@^3.0.0": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-3.0.2.tgz#e28db1bfbfa617076f7770dd1d9a48eaa3b6c51b" + integrity sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA== + +"@types/d3-interpolate@^3.0.1": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz#412b90e84870285f2ff8a846c6eb60344f12a41c" + integrity sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA== + dependencies: + "@types/d3-color" "*" + +"@types/d3-path@*": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-3.0.2.tgz#4327f4a05d475cf9be46a93fc2e0f8d23380805a" + integrity sha512-WAIEVlOCdd/NKRYTsqCpOMHQHemKBEINf8YXMYOtXH0GA7SY0dqMB78P3Uhgfy+4X+/Mlw2wDtlETkN6kQUCMA== + +"@types/d3-path@^1": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-1.0.11.tgz#45420fee2d93387083b34eae4fe6d996edf482bc" + integrity sha512-4pQMp8ldf7UaB/gR8Fvvy69psNHkTpD/pVw3vmEi8iZAB9EPMBruB1JvHO4BIq9QkUUd2lV1F5YXpMNj7JPBpw== + +"@types/d3-scale@^4.0.2": + version "4.0.8" + resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.8.tgz#d409b5f9dcf63074464bf8ddfb8ee5a1f95945bb" + integrity sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ== + dependencies: + "@types/d3-time" "*" + +"@types/d3-shape@^1": + version "1.3.12" + resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-1.3.12.tgz#8f2f9f7a12e631ce6700d6d55b84795ce2c8b259" + integrity sha512-8oMzcd4+poSLGgV0R1Q1rOlx/xdmozS4Xab7np0eamFFUYq71AU9pOCJEFnkXW2aI/oXdVYJzw6pssbSut7Z9Q== + dependencies: + "@types/d3-path" "^1" + +"@types/d3-shape@^3.1.0": + version "3.1.6" + resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.6.tgz#65d40d5a548f0a023821773e39012805e6e31a72" + integrity sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA== + dependencies: + "@types/d3-path" "*" + +"@types/d3-time@*", "@types/d3-time@^3.0.0": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.3.tgz#3c186bbd9d12b9d84253b6be6487ca56b54f88be" + integrity sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw== + +"@types/d3-timer@^3.0.0": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-3.0.2.tgz#70bbda77dc23aa727413e22e214afa3f0e852f70" + integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw== + "@types/extract-files@*": version "8.1.1" resolved "https://registry.yarnpkg.com/@types/extract-files/-/extract-files-8.1.1.tgz#11b67e795ad2c8b483431e8d4f190db2fd22944b" @@ -2460,6 +2530,14 @@ "@types/scheduler" "*" csstype "^3.0.2" +"@types/recharts@^1.8.28": + version "1.8.28" + resolved "https://registry.yarnpkg.com/@types/recharts/-/recharts-1.8.28.tgz#2e4a4468e4390c5db8d822783f925d6e80ae8297" + integrity sha512-31D+dVBdVMtBnRMOjfM9210oRsclujQetwDNnCfapy/gF1BruvQkiK9WZ2ZMqDZY2xnDpIV8sWjISBcY+wgkLw== + dependencies: + "@types/d3-shape" "^1" + "@types/react" "*" + "@types/scheduler@*": version "0.16.3" resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5" @@ -3937,6 +4015,11 @@ clsx@^1.1.1: resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== +clsx@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.0.0.tgz#12658f3fd98fafe62075595a5c30e43d18f3d00b" + integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q== + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -4162,6 +4245,77 @@ csstype@^3.0.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== +"d3-array@2 - 3", "d3-array@2.10.0 - 3", d3-array@^3.1.6: + version "3.2.4" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.4.tgz#15fec33b237f97ac5d7c986dc77da273a8ed0bb5" + integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== + dependencies: + internmap "1 - 2" + +"d3-color@1 - 3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2" + integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== + +d3-ease@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-3.0.1.tgz#9658ac38a2140d59d346160f1f6c30fda0bd12f4" + integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== + +"d3-format@1 - 3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641" + integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA== + +"d3-interpolate@1.2.0 - 3", d3-interpolate@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d" + integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== + dependencies: + d3-color "1 - 3" + +d3-path@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-3.1.0.tgz#22df939032fb5a71ae8b1800d61ddb7851c42526" + integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== + +d3-scale@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396" + integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ== + dependencies: + d3-array "2.10.0 - 3" + d3-format "1 - 3" + d3-interpolate "1.2.0 - 3" + d3-time "2.1.1 - 3" + d3-time-format "2 - 4" + +d3-shape@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-3.2.0.tgz#a1a839cbd9ba45f28674c69d7f855bcf91dfc6a5" + integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA== + dependencies: + d3-path "^3.1.0" + +"d3-time-format@2 - 4": + version "4.1.0" + resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a" + integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg== + dependencies: + d3-time "1 - 3" + +"d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.1.0.tgz#9310db56e992e3c0175e1ef385e545e48a9bb5c7" + integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q== + dependencies: + d3-array "2 - 3" + +d3-timer@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0" + integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== + damerau-levenshtein@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" @@ -4222,6 +4376,11 @@ decamelize@^1.1.0, decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== +decimal.js-light@^2.4.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" + integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== + decimal.js@^10.4.2: version "10.4.3" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" @@ -4390,6 +4549,13 @@ dom-accessibility-api@^0.5.6, dom-accessibility-api@^0.5.9: resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453" integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== +dom-helpers@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8" + integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA== + dependencies: + "@babel/runtime" "^7.1.2" + dom-helpers@^5.0.1: version "5.2.1" resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" @@ -4950,6 +5116,11 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +eventemitter3@^4.0.1: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -5043,6 +5214,11 @@ fast-diff@^1.1.2: resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== +fast-equals@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-5.0.1.tgz#a4eefe3c5d1c0d021aeed0bc10ba5e0c12ee405d" + integrity sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ== + fast-glob@^3.2.12, fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" @@ -5851,6 +6027,11 @@ internal-slot@^1.0.3, internal-slot@^1.0.4, internal-slot@^1.0.5: has "^1.0.3" side-channel "^1.0.4" +"internmap@1 - 2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009" + integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== + interpret@^1.0.0: version "1.4.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" @@ -7064,7 +7245,7 @@ lodash.xorby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.xorby/-/lodash.xorby-4.7.0.tgz#9c19a6f9f063a6eb53dd03c1b6871799801463d7" integrity sha512-gYiD6nvuQy0AEkMoUju+t4f4Rn18fjsLB/7x7YZFqtFT9kmegRLrj/uGEQVyVDy7otTmSrIMXNOk2wwuLcfHCQ== -lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.15, lodash@^4.17.21, lodash@^4.17.4: +lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.4: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -8144,7 +8325,7 @@ react-hook-form@^7.43.1: resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.45.2.tgz#c757f3d5e633ccb186443d57c10fc511df35721a" integrity sha512-9s45OdTaKN+4NSTbXVqeDITd/nwIg++nxJGL8+OD5uf1DxvhsXQ641kaYHk5K28cpIOTYm71O/fYk7rFaygb3A== -react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0: +react-is@^16.10.2, react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -8159,6 +8340,11 @@ react-is@^17.0.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +react-lifecycles-compat@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + react-outside-click-handler@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/react-outside-click-handler/-/react-outside-click-handler-1.3.0.tgz#3831d541ac059deecd38ec5423f81e80ad60e115" @@ -8200,6 +8386,14 @@ react-shallow-renderer@^16.15.0: object-assign "^4.1.1" react-is "^16.12.0 || ^17.0.0 || ^18.0.0" +react-smooth@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-2.0.5.tgz#d153b7dffc7143d0c99e82db1532f8cf93f20ecd" + integrity sha512-BMP2Ad42tD60h0JW6BFaib+RJuV5dsXJK9Baxiv/HlNFjvRLqA9xrNKxVWnUIZPQfzUwGXIlU/dSYLU+54YGQA== + dependencies: + fast-equals "^5.0.0" + react-transition-group "2.9.0" + react-spring@^9.5.2: version "9.7.2" resolved "https://registry.yarnpkg.com/react-spring/-/react-spring-9.7.2.tgz#218360d0ca53d04d8faac984f0d8683819b967b4" @@ -8228,6 +8422,16 @@ react-toastify@^9.1.1: dependencies: clsx "^1.1.1" +react-transition-group@2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" + integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== + dependencies: + dom-helpers "^3.4.0" + loose-envify "^1.4.0" + prop-types "^15.6.2" + react-lifecycles-compat "^3.0.4" + react-transition-group@^4.3.0: version "4.4.5" resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1" @@ -8298,6 +8502,27 @@ recast@^0.21.0: source-map "~0.6.1" tslib "^2.0.1" +recharts-scale@^0.4.4: + version "0.4.5" + resolved "https://registry.yarnpkg.com/recharts-scale/-/recharts-scale-0.4.5.tgz#0969271f14e732e642fcc5bd4ab270d6e87dd1d9" + integrity sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w== + dependencies: + decimal.js-light "^2.4.1" + +recharts@^2.10.3: + version "2.10.3" + resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.10.3.tgz#a5dbe219354d744701e8bbd116fe42393af92f6b" + integrity sha512-G4J96fKTZdfFQd6aQnZjo2nVNdXhp+uuLb00+cBTGLo85pChvm1+E67K3wBOHDE/77spcYb2Cy9gYWVqiZvQCg== + dependencies: + clsx "^2.0.0" + eventemitter3 "^4.0.1" + lodash "^4.17.19" + react-is "^16.10.2" + react-smooth "^2.0.5" + recharts-scale "^0.4.4" + tiny-invariant "^1.3.1" + victory-vendor "^36.6.8" + rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" @@ -8359,6 +8584,11 @@ regenerator-runtime@^0.13.11: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== +regenerator-runtime@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" + integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== + regenerator-transform@^0.15.1: version "0.15.1" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.1.tgz#f6c4e99fc1b4591f780db2586328e4d9a9d8dc56" @@ -9284,6 +9514,11 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== +tiny-invariant@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642" + integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw== + titleize@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53" @@ -9674,6 +9909,26 @@ validator@^13.7.0: resolved "https://registry.yarnpkg.com/validator/-/validator-13.9.0.tgz#33e7b85b604f3bbce9bb1a05d5c3e22e1c2ff855" integrity sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA== +victory-vendor@^36.6.8: + version "36.7.0" + resolved "https://registry.yarnpkg.com/victory-vendor/-/victory-vendor-36.7.0.tgz#e02af33e249e74e659fa65c6d5936042c42e7aa8" + integrity sha512-nqYuTkLSdTTeACyXcCLbL7rl0y6jpzLPtTNGOtSnajdR+xxMxBdjMxDjfNJNlhR+ZU8vbXz+QejntcbY7h9/ZA== + dependencies: + "@types/d3-array" "^3.0.3" + "@types/d3-ease" "^3.0.0" + "@types/d3-interpolate" "^3.0.1" + "@types/d3-scale" "^4.0.2" + "@types/d3-shape" "^3.1.0" + "@types/d3-time" "^3.0.0" + "@types/d3-timer" "^3.0.0" + d3-array "^3.1.6" + d3-ease "^3.0.1" + d3-interpolate "^3.0.1" + d3-scale "^4.0.2" + d3-shape "^3.1.0" + d3-time "^3.0.0" + d3-timer "^3.0.1" + vscode-jsonrpc@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz#108bdb09b4400705176b957ceca9e0880e9b6d4e"