From 018d449130e3e3c2bb24f1854a08ee777f1ef304 Mon Sep 17 00:00:00 2001 From: dlcaldeira Date: Fri, 17 Nov 2023 10:37:18 +0000 Subject: [PATCH] Enumeration component: Add, edit, remove and import --- packages/design-system/package.json | 7 +- .../Enumeration/Enumeration.component.tsx | 203 ++++++++--------- .../Enumeration/Enumeration.module.scss | 38 +--- .../Enumeration/Enumeration.types.tsx | 12 +- .../EnumerationHeader.component.tsx | 204 ++++++++++++++++++ .../EnumerationHeader.module.scss | 28 +++ .../EnumerationIHeader.types.tsx | 17 ++ .../EnumerationItem.component.tsx | 100 +++++++++ .../EnumerationItem.module.scss | 27 +++ .../EnumerationItem/EnumerationItem.types.tsx | 10 + .../Primitives/InlineEditingPrimitive.tsx | 16 +- .../form/Enumeration/Enumeration.stories.tsx | 45 +++- .../stories/form/InlineEditing.stories.tsx | 12 ++ yarn.lock | 101 ++++++--- 14 files changed, 609 insertions(+), 211 deletions(-) create mode 100644 packages/design-system/src/components/Enumeration/EnumerationHeader/EnumerationHeader.component.tsx create mode 100644 packages/design-system/src/components/Enumeration/EnumerationHeader/EnumerationHeader.module.scss create mode 100644 packages/design-system/src/components/Enumeration/EnumerationHeader/EnumerationIHeader.types.tsx create mode 100644 packages/design-system/src/components/Enumeration/EnumerationItem/EnumerationItem.component.tsx create mode 100644 packages/design-system/src/components/Enumeration/EnumerationItem/EnumerationItem.module.scss create mode 100644 packages/design-system/src/components/Enumeration/EnumerationItem/EnumerationItem.types.tsx diff --git a/packages/design-system/package.json b/packages/design-system/package.json index c3768767442..7057be07771 100644 --- a/packages/design-system/package.json +++ b/packages/design-system/package.json @@ -40,8 +40,7 @@ "classnames": "^2.3.2", "keycode": "^2.2.1", "modern-css-reset": "^1.4.0", - "polished": "^4.2.2", - "react-transition-group": "^2.2.9", + "react-transition-group": "^2.9.0", "react-use": "^17.4.0", "react-virtualized": "^9.22.5", "typeface-inconsolata": "^1.1.13", @@ -76,12 +75,14 @@ "@talend/scripts-config-typescript": "^11.2.0", "@talend/storybook-docs": "^2.2.0", "@testing-library/cypress": "^9.0.0", + "@trivago/prettier-plugin-sort-imports": "^4.3.0", "@types/classnames": "^2.3.1", "@types/jest-axe": "^3.5.8", - "@types/react-is": "^18.2.4", "@types/react": "^18.2.37", "@types/react-dom": "^18.2.15", + "@types/react-is": "^18.2.4", "@types/react-transition-group": "^2.9.2", + "@types/react-virtualized": "^9.21.26", "browser-sync": "^2.29.3", "browser-sync-webpack-plugin": "^2.3.0", "concurrently": "^7.6.0", diff --git a/packages/design-system/src/components/Enumeration/Enumeration.component.tsx b/packages/design-system/src/components/Enumeration/Enumeration.component.tsx index 6103724be3d..bdf7835c531 100644 --- a/packages/design-system/src/components/Enumeration/Enumeration.component.tsx +++ b/packages/design-system/src/components/Enumeration/Enumeration.component.tsx @@ -1,136 +1,103 @@ -import { EnumerationItem, EnumerationProps, EnumerationMode } from './Enumeration.types'; - +import { useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { I18N_DOMAIN_DESIGN_SYSTEM } from '../constants'; -import { ChangeEvent, useState } from 'react'; -import { Form } from '../Form'; import { AutoSizer, InfiniteLoader, List } from 'react-virtualized'; -import { ButtonIcon, ButtonIconToggle } from '../ButtonIcon'; -import { Divider } from '../Divider'; -import { StackHorizontal } from '../Stack'; import { EmptyState } from '../EmptyState'; +import { StackHorizontal } from '../Stack'; +import { I18N_DOMAIN_DESIGN_SYSTEM } from '../constants'; +import { EnumerationMode, EnumerationProps } from './Enumeration.types'; +import { EnumerationHeader } from './EnumerationHeader/EnumerationHeader.component'; +import { EnumerationItem } from './EnumerationItem/EnumerationItem.component'; -import style from './Enumeration.module.scss'; +import styles from './Enumeration.module.scss'; -export const Enumeration = ({ items, loadMoreRows, onImport, title }: EnumerationProps) => { +export const Enumeration = ({ + id, + items, + loadMoreRows, + onCreate, + onChange, + onImport, + onRemove, + title, +}: EnumerationProps) => { const { t } = useTranslation(I18N_DOMAIN_DESIGN_SYSTEM); - const [mode, setMode] = useState(); - const [filteredItems, setFilteredItems] = useState(items); - const rowRenderer = ({ index }: { index: number }) => ( -
-

{filteredItems[index].label}

- {}} size="S"> - {t('ENUMERATION_IMPORT', 'Import items')} - -
- ); + const [mode, setMode] = useState(EnumerationMode.VIEW); + const [selectedItems, setSelectedItems] = useState([]); + const [filteredItems, setFilteredItems] = useState(items); - const ListEmptyState = () => ( - - + - - ); - const filterList = (event: ChangeEvent) => { - const value = event.target.value; - if (!value) { - setFilteredItems(items); - } else { - setFilteredItems(items.filter(item => item.id.includes(value))); - } - }; + {filteredItems.length ? ( +
+ + {({ width }) => { + const itemHeight = 38; - return ( -
-
-
-

{title}

+ return ( + !!items[index]} + loadMoreRows={loadMoreRows} + rowCount={filteredItems.length} + > + {({ onRowsRendered, registerChild }) => ( + ( + { + const indexToReplace = items.indexOf(filteredItems[index]); - - {onImport && ( -
  • - {}} size="S"> - {t('ENUMERATION_IMPORT', 'Import items')} - - -
  • - )} -
  • - { - setMode( - mode === EnumerationMode.CREATE ? EnumerationMode.VIEW : EnumerationMode.CREATE, - ); - }} - size="S" - > - {t('ENUMERATION_ADD', 'Add item')} - -
  • -
  • - { - setMode( - mode === EnumerationMode.EDIT ? EnumerationMode.VIEW : EnumerationMode.EDIT, - ); - }} - size="S" - > - {t('ENUMERATION_EDIT', 'Edit item')} - -
  • -
    + if (indexToReplace !== -1) { + const newItems = [...items]; + newItems[indexToReplace] = value; + onChange(newItems); + } + }} + onRemove={onRemove} + selectedItems={selectedItems} + setSelectedItems={setSelectedItems} + value={filteredItems[index]} + /> + )} + width={width} + /> + )} +
    + ); + }} +
    - - -
    - - {filteredItems.length ? ( - - {({ width }) => { - const itemHeight = 36; - - return ( - !!items[index]} - loadMoreRows={loadMoreRows} - rowCount={filteredItems.length} - > - {({ onRowsRendered, registerChild }) => ( - - )} - - ); - }} - ) : ( - + + + )}
    ); diff --git a/packages/design-system/src/components/Enumeration/Enumeration.module.scss b/packages/design-system/src/components/Enumeration/Enumeration.module.scss index e0e9aba462f..fb6240343ce 100644 --- a/packages/design-system/src/components/Enumeration/Enumeration.module.scss +++ b/packages/design-system/src/components/Enumeration/Enumeration.module.scss @@ -14,27 +14,9 @@ padding: 0; } - &__header { - border-bottom: tokens.$coral-border-s-solid tokens.$coral-color-neutral-border; - padding: tokens.$coral-spacing-s; - - h4 { - font: tokens.$coral-heading-m; - } - } - - &__title { - align-items: center; - display: flex; - margin-bottom: tokens.$coral-spacing-s; - - hr { - margin-left: tokens.$coral-spacing-xs; - } - } - - &__title h4, - p { + h4, + p, + label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -42,17 +24,7 @@ } &__body { - &--item { - align-items: center; - background-color: tokens.$coral-color-neutral-background; - display: flex; - justify-content: space-between; - padding: tokens.$coral-spacing-xxs tokens.$coral-spacing-s; - transition: background-color tokens.$coral-transition-fast; - - &:hover { - background-color: tokens.$coral-color-neutral-background-medium; - } - } + max-height: 400px; + overflow: hidden auto; } } diff --git a/packages/design-system/src/components/Enumeration/Enumeration.types.tsx b/packages/design-system/src/components/Enumeration/Enumeration.types.tsx index d822c95de98..e161b089497 100644 --- a/packages/design-system/src/components/Enumeration/Enumeration.types.tsx +++ b/packages/design-system/src/components/Enumeration/Enumeration.types.tsx @@ -1,12 +1,12 @@ -export interface EnumerationItem { - id: string; - label: string; -} - export interface EnumerationProps { - items: EnumerationItem[]; + error?: string; + id: string; + items: string[]; loadMoreRows: (params: { startIndex: number; stopIndex: number }) => Promise; + onChange: (items: string[]) => void; + onCreate?: (value: string) => Promise; onImport?: (...params: unknown[]) => void; + onRemove?: (entries: string[]) => Promise; title: string; } diff --git a/packages/design-system/src/components/Enumeration/EnumerationHeader/EnumerationHeader.component.tsx b/packages/design-system/src/components/Enumeration/EnumerationHeader/EnumerationHeader.component.tsx new file mode 100644 index 00000000000..82985744f32 --- /dev/null +++ b/packages/design-system/src/components/Enumeration/EnumerationHeader/EnumerationHeader.component.tsx @@ -0,0 +1,204 @@ +import { useEffect, useRef, useState } from 'react'; +import { useTranslation } from 'react-i18next'; + +import { ButtonDestructive } from '../../Button'; +import { ButtonIcon, ButtonIconToggle } from '../../ButtonIcon'; +import { Form } from '../../Form'; +import { InlineEditing } from '../../InlineEditing'; +import { InlineMessageDestructive } from '../../InlineMessage'; +import { StackHorizontal, StackVertical } from '../../Stack'; +import { I18N_DOMAIN_DESIGN_SYSTEM } from '../../constants'; +import { EnumerationMode } from '../Enumeration.types'; +import { EnumerationHeaderProps } from './EnumerationIHeader.types'; + +import styles from './EnumerationHeader.module.scss'; + +export const EnumerationHeader = ({ + filteredItems, + id, + items, + mode, + onCreate, + onChange, + onImport, + onRemove, + setFilteredItems, + setMode, + selectedItems, + setSelectedItems, + title, +}: EnumerationHeaderProps) => { + const { t } = useTranslation(I18N_DOMAIN_DESIGN_SYSTEM); + const importRef = useRef(null); + const [searchValue, setSearchValue] = useState(); + const [hasError, setHasError] = useState(false); + const enumerationItemsRef = useRef(null); + + const filterList = () => { + if (searchValue) { + setFilteredItems(items.filter(item => item.includes(searchValue))); + } else { + setFilteredItems(items); + } + }; + + const handleOnCreate = async (newValue?: string) => { + try { + if (newValue) { + await onCreate?.(newValue); + enumerationItemsRef.current?.scrollTo({ + top: 0, + behavior: 'smooth', + }); + onChange([newValue, ...items]); + } + } catch (e) { + //The parent component must do the error handling + } + }; + + const isAllChecked = () => selectedItems.length > 0 || selectedItems.length === items.length; + + const onToggleAll = (isChecked: boolean) => { + if (isChecked) { + setSelectedItems(items); + } else { + setSelectedItems([]); + } + }; + + useEffect(() => { + filterList(); + }, [searchValue, items]); + + return ( +
    +
    +

    {title}

    + + {selectedItems.length ? ( + { + await onRemove?.(selectedItems); + setSelectedItems([]); + }} + > + {t('ENUMERATION_REMOVE_BUTTON', { + count: selectedItems.length, + defaultValue: 'Remove ({{count}})', + })} + + ) : ( + +
  • + { + setSearchValue(undefined); + setFilteredItems(items); + setMode( + mode === EnumerationMode.CREATE ? EnumerationMode.VIEW : EnumerationMode.CREATE, + ); + }} + size="S" + > + {t('ENUMERATION_ADD_ACTION', 'Add item')} + +
  • +
  • + { + setMode( + mode === EnumerationMode.EDIT ? EnumerationMode.VIEW : EnumerationMode.EDIT, + ); + }} + size="S" + > + {t('ENUMERATION_EDIT_ACTION', 'Edit item')} + +
  • + {onImport && ( +
  • + { + const fr = new FileReader(); + const file = e.target.files?.[0]; + + if (file) { + fr.readAsText(file); + fr.onload = () => onImport(fr.result); + } + }} + /> + importRef.current?.click()} + size="S" + disabled={![EnumerationMode.VIEW].includes(mode)} + > + {t('ENUMERATION_IMPORT_ACTION', 'Import items')} + +
  • + )} +
    + )} +
    + + {mode === EnumerationMode.CREATE ? ( + + { + if (value) { + handleOnCreate(value); + setMode(EnumerationMode.VIEW); + } + + setHasError(!value); + }} + onCancel={() => { + setMode(EnumerationMode.VIEW); + }} + hasError={hasError} + /> + + {hasError && ( + + )} + + ) : ( + setSearchValue(e.target.value)} + placeholder="Search" + /> + )} + + {mode === EnumerationMode.EDIT && ( + onToggleAll(e.target.checked)} + checked={isAllChecked()} + indeterminate={selectedItems.length > 0} + /> + )} +
    + ); +}; diff --git a/packages/design-system/src/components/Enumeration/EnumerationHeader/EnumerationHeader.module.scss b/packages/design-system/src/components/Enumeration/EnumerationHeader/EnumerationHeader.module.scss new file mode 100644 index 00000000000..da02bad011e --- /dev/null +++ b/packages/design-system/src/components/Enumeration/EnumerationHeader/EnumerationHeader.module.scss @@ -0,0 +1,28 @@ +@use '~@talend/design-tokens/lib/tokens'; + +.enumeration { + &__header { + border-bottom: tokens.$coral-border-s-solid tokens.$coral-color-neutral-border; + display: flex; + flex-direction: column; + padding: tokens.$coral-spacing-s; + gap: tokens.$coral-spacing-s; + + h4 { + font: tokens.$coral-heading-m; + } + + [type='file'] { + display: none; + } + } + + &__title { + align-items: center; + display: flex; + + > button { + margin-left: auto; + } + } +} diff --git a/packages/design-system/src/components/Enumeration/EnumerationHeader/EnumerationIHeader.types.tsx b/packages/design-system/src/components/Enumeration/EnumerationHeader/EnumerationIHeader.types.tsx new file mode 100644 index 00000000000..0a9ece96fac --- /dev/null +++ b/packages/design-system/src/components/Enumeration/EnumerationHeader/EnumerationIHeader.types.tsx @@ -0,0 +1,17 @@ +import { EnumerationMode } from '../Enumeration.types'; + +export interface EnumerationHeaderProps { + filteredItems: string[]; + id: string; + items: string[]; + mode: EnumerationMode; + setFilteredItems: (filteredItems: string[]) => void; + setMode: (mode: EnumerationMode) => void; + onChange: any; + onCreate?: (value: string) => Promise; + onImport?: (...params: unknown[]) => void; + onRemove?: (entries: string[]) => Promise; + selectedItems: string[]; + setSelectedItems: (selectedItems: string[]) => void; + title: string; +} diff --git a/packages/design-system/src/components/Enumeration/EnumerationItem/EnumerationItem.component.tsx b/packages/design-system/src/components/Enumeration/EnumerationItem/EnumerationItem.component.tsx new file mode 100644 index 00000000000..8625598f26f --- /dev/null +++ b/packages/design-system/src/components/Enumeration/EnumerationItem/EnumerationItem.component.tsx @@ -0,0 +1,100 @@ +import { useState } from 'react'; +import { useTranslation } from 'react-i18next'; + +import classNames from 'classnames'; + +import { useId } from '../../../useId'; +import { ButtonIcon } from '../../ButtonIcon'; +import { Dropdown } from '../../Dropdown'; +import { Form } from '../../Form'; +import { InlineEditing } from '../../InlineEditing'; +import { I18N_DOMAIN_DESIGN_SYSTEM } from '../../constants'; +import { EnumerationMode } from '../Enumeration.types'; +import { EnumerationItemProps } from './EnumerationItem.types'; + +import styles from './EnumerationItem.module.scss'; + +export const EnumerationItem = ({ + mode, + onChange, + onRemove, + selectedItems, + setSelectedItems, + value, +}: EnumerationItemProps) => { + const { t } = useTranslation(I18N_DOMAIN_DESIGN_SYSTEM); + const id = useId(); + + const [isEdit, setIsEdit] = useState(false); + + const isChecked = (id: string) => selectedItems.includes(id); + + const onToggleItem = (value: string, isChecked: boolean) => { + if (isChecked) { + setSelectedItems([...selectedItems, value]); + } else { + setSelectedItems(selectedItems.filter(item => item !== value)); + } + }; + + return ( +
    + {isEdit ? ( + setIsEdit(false)} + onEdit={(_, value) => { + onChange(value); + setIsEdit(false); + }} + placeholder={value} + /> + ) : ( + <> + {mode === EnumerationMode.EDIT ? ( + onToggleItem(value, e.target.checked)} + /> + ) : ( +

    {value}

    + )} + setIsEdit(true), + type: 'button', + }, + { + label: t('ENUMERATION_DROPDOWN_REMOVE', 'Remove'), + icon: 'trash', + onClick: async () => await onRemove?.([value]), + type: 'button', + }, + ]} + > + {}} + size="S" + disabled={[EnumerationMode.CREATE, EnumerationMode.EDIT].includes(mode)} + > + {t('ENUMERATION_DROPDOWN_OPTIONS', 'Dropdown options')} + + + + )} +
    + ); +}; diff --git a/packages/design-system/src/components/Enumeration/EnumerationItem/EnumerationItem.module.scss b/packages/design-system/src/components/Enumeration/EnumerationItem/EnumerationItem.module.scss new file mode 100644 index 00000000000..431caa42449 --- /dev/null +++ b/packages/design-system/src/components/Enumeration/EnumerationItem/EnumerationItem.module.scss @@ -0,0 +1,27 @@ +@use '~@talend/design-tokens/lib/tokens'; + +.enumeration__item { + align-items: center; + background-color: tokens.$coral-color-neutral-background; + display: flex; + height: 38px; + justify-content: space-between; + padding: tokens.$coral-spacing-xxs tokens.$coral-spacing-m tokens.$coral-spacing-xxs tokens.$coral-spacing-s; + transition: background-color tokens.$coral-transition-fast; + + &:hover { + background-color: tokens.$coral-color-neutral-background-medium; + } + + > :first-child { + width: 100%; + + label { + flex: 1; + } + } + + &--edit { + padding: 0 tokens.$coral-spacing-m 0 tokens.$coral-spacing-xxs; + } +} diff --git a/packages/design-system/src/components/Enumeration/EnumerationItem/EnumerationItem.types.tsx b/packages/design-system/src/components/Enumeration/EnumerationItem/EnumerationItem.types.tsx new file mode 100644 index 00000000000..aa4a59e4108 --- /dev/null +++ b/packages/design-system/src/components/Enumeration/EnumerationItem/EnumerationItem.types.tsx @@ -0,0 +1,10 @@ +import { EnumerationMode } from '../Enumeration.types'; + +export interface EnumerationItemProps { + mode: EnumerationMode; + onChange: (items: string) => void; + onRemove?: (entries: string[]) => Promise; + selectedItems: string[]; + setSelectedItems: (selectedItems: string[]) => void; + value: string; +} diff --git a/packages/design-system/src/components/InlineEditing/Primitives/InlineEditingPrimitive.tsx b/packages/design-system/src/components/InlineEditing/Primitives/InlineEditingPrimitive.tsx index 20bbdd1e47f..a7606977436 100644 --- a/packages/design-system/src/components/InlineEditing/Primitives/InlineEditingPrimitive.tsx +++ b/packages/design-system/src/components/InlineEditing/Primitives/InlineEditingPrimitive.tsx @@ -14,11 +14,11 @@ import { useTranslation } from 'react-i18next'; import classnames from 'classnames'; import keycode from 'keycode'; +import { useId } from '../../../useId'; import { ButtonIcon } from '../../ButtonIcon'; import { Form } from '../../Form'; import { StackHorizontal } from '../../Stack'; import { I18N_DOMAIN_DESIGN_SYSTEM } from '../../constants'; -import { useId } from '../../../useId'; import styles from './InlineEditingPrimitive.module.scss'; @@ -39,6 +39,7 @@ export type OnEditEvent = | RKeyboardEvent; export type InlineEditingPrimitiveProps = { + isEditionMode?: boolean; loading?: boolean; onCancel?: () => void; onToggle?: (isEditionMode: boolean) => void; @@ -81,6 +82,7 @@ export type InlineEditingPrimitiveProps = { const InlineEditingPrimitive = forwardRef( (props: InlineEditingPrimitiveProps, ref: Ref) => { const { + isEditionMode = false, loading, ariaLabel, mode, @@ -102,7 +104,7 @@ const InlineEditingPrimitive = forwardRef( const { t } = useTranslation(I18N_DOMAIN_DESIGN_SYSTEM); - const [isEditing, setEditing] = useState(false); + const [isEditing, setEditing] = useState(isEditionMode); const [internalValue, setInternalValue] = useState(defaultValue); const inlineEditingId = useId(rest.id, 'inline-edit-'); @@ -129,11 +131,13 @@ const InlineEditingPrimitive = forwardRef( const handleSubmit = (event: OnEditEvent) => { event.stopPropagation(); - if (onEdit) { - onEdit(event, getValue() || ''); - } + if (!hasError) { + if (onEdit) { + onEdit(event, getValue() || ''); + } - toggleEditionMode(false); + toggleEditionMode(false); + } }; const handleCancel = () => { diff --git a/packages/design-system/src/stories/form/Enumeration/Enumeration.stories.tsx b/packages/design-system/src/stories/form/Enumeration/Enumeration.stories.tsx index ea5ebb43ea5..3152494ddc5 100644 --- a/packages/design-system/src/stories/form/Enumeration/Enumeration.stories.tsx +++ b/packages/design-system/src/stories/form/Enumeration/Enumeration.stories.tsx @@ -1,3 +1,5 @@ +import { useState } from 'react'; + import { Enumeration as EnumerationComponent } from '../../../components/Enumeration'; export default { @@ -11,15 +13,36 @@ const Enumeration = (args: any) => (
    ); -export const Default = () => ( - -); +export const Default = () => { + const [items, setItems] = useState([ + 'Item 1', + 'Item 2', + 'Item 3', + 'Item 4', + 'Item 5', + 'Item 6', + 'Item 7', + 'Item 8', + 'Item 9', + 'Item 10', + 'Item 11', + 'Item 12', + ]); + + return ( + new Promise(resolve => resolve([]))} + onChange={setItems} + onImport={(data: string) => { + console.log(data); + setItems([...data.split('\n').filter(Boolean), ...items]); + }} + onRemove={(ids: string[]) => setItems(items.filter(item => !ids.includes(item)))} + title="This is a title" + /> + ); +}; -export const Empty = () => ; +export const Empty = () => ; diff --git a/packages/design-system/src/stories/form/InlineEditing.stories.tsx b/packages/design-system/src/stories/form/InlineEditing.stories.tsx index a133e99b6be..ee093ceb113 100644 --- a/packages/design-system/src/stories/form/InlineEditing.stories.tsx +++ b/packages/design-system/src/stories/form/InlineEditing.stories.tsx @@ -142,6 +142,18 @@ export const LoadingMode = { ), }; +export const EditionMode = { + render: (props: Story) => ( + + ), +}; + export const InUse = (props: Story) => { const [data, setData] = useState('this is a default value'); const [error, setError] = useState(false); diff --git a/yarn.lock b/yarn.lock index 2dee7ec9e74..3912b62f030 100644 --- a/yarn.lock +++ b/yarn.lock @@ -258,7 +258,7 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/generator@^7.12.11", "@babel/generator@^7.17.3", "@babel/generator@^7.17.7", "@babel/generator@^7.22.9", "@babel/generator@^7.23.3", "@babel/generator@^7.7.2": +"@babel/generator@^7.12.11", "@babel/generator@^7.17.3", "@babel/generator@^7.17.7", "@babel/generator@^7.22.9", "@babel/generator@^7.23.0", "@babel/generator@^7.23.3", "@babel/generator@^7.7.2": version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.3.tgz#86e6e83d95903fbe7613f448613b8b319f330a8e" integrity sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg== @@ -471,7 +471,7 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.9.tgz#f2dde0c682ccc264a9a8595efd030a5cc8fd2539" integrity sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg== -"@babel/parser@^7.1.0", "@babel/parser@^7.13.16", "@babel/parser@^7.14.7", "@babel/parser@^7.17.3", "@babel/parser@^7.17.8", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.22.7", "@babel/parser@^7.23.0", "@babel/parser@^7.23.3", "@babel/parser@^7.9.4": +"@babel/parser@^7.1.0", "@babel/parser@^7.13.16", "@babel/parser@^7.14.7", "@babel/parser@^7.17.3", "@babel/parser@^7.17.8", "@babel/parser@^7.20.5", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.22.7", "@babel/parser@^7.23.0", "@babel/parser@^7.23.3", "@babel/parser@^7.9.4": version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.3.tgz#0ce0be31a4ca4f1884b5786057cadcb6c3be58f9" integrity sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw== @@ -1336,6 +1336,22 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@7.23.2": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8" + integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/generator" "^7.23.0" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.0" + "@babel/types" "^7.23.0" + debug "^4.1.0" + globals "^11.1.0" + "@babel/traverse@^7.1.6", "@babel/traverse@^7.17.3", "@babel/traverse@^7.22.8", "@babel/traverse@^7.23.2", "@babel/traverse@^7.23.3", "@babel/traverse@^7.4.5": version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.3.tgz#26ee5f252e725aa7aca3474aa5b324eaf7908b5b" @@ -2940,7 +2956,7 @@ resolved "https://registry.yarnpkg.com/@rooks/use-mutation-observer/-/use-mutation-observer-4.11.2.tgz#a0466c4338e0a4487ea19253c86bcd427c29f4af" integrity sha512-vpsdrZdr6TkB1zZJcHx+fR1YC/pHs2BaqcuYiEGjBVbwY5xcC49+h0hAUtQKHth3oJqXfIX/Ng8S7s5HFHdM/A== -"@sentry/cli@^1.75.1": +"@sentry/cli@^1.77.1": version "1.77.1" resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.77.1.tgz#ebcf884712ef6c3c75443f491ec16f6a22148aec" integrity sha512-OtJ7U9LeuPUAY/xow9wwcjM9w42IJIpDtClTKI/RliE685vd/OJUIpiAvebHNthDYpQynvwb/0iuF4fonh+CKw== @@ -2953,11 +2969,11 @@ which "^2.0.2" "@sentry/webpack-plugin@^1.20.1": - version "1.20.1" - resolved "https://registry.yarnpkg.com/@sentry/webpack-plugin/-/webpack-plugin-1.20.1.tgz#e70a2fe516f3a39a132acfa841e4f2ea2a1cecd2" - integrity sha512-klOLkfM/oSYzcR2M9oDmJA5/Mdaw0Mtck/h820Z+gqpd6WJepjhqVDel1z2VddaP/XMY0Dj6elCGp2/nDWNr0w== + version "1.21.0" + resolved "https://registry.yarnpkg.com/@sentry/webpack-plugin/-/webpack-plugin-1.21.0.tgz#bbe7cb293751f80246a4a56f9a7dd6de00f14b58" + integrity sha512-x0PYIMWcsTauqxgl7vWUY6sANl+XGKtx7DCVnnY7aOIIlIna0jChTAPANTfA2QrK+VK+4I/4JxatCEZBnXh3Og== dependencies: - "@sentry/cli" "^1.75.1" + "@sentry/cli" "^1.77.1" webpack-sources "^2.0.0 || ^3.0.0" "@sinclair/typebox@^0.24.1": @@ -4205,6 +4221,18 @@ javascript-natural-sort "0.7.1" lodash "4.17.21" +"@trivago/prettier-plugin-sort-imports@^4.3.0": + version "4.3.0" + resolved "https://registry.yarnpkg.com/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.3.0.tgz#725f411646b3942193a37041c84e0b2116339789" + integrity sha512-r3n0onD3BTOVUNPhR4lhVK4/pABGpbA7bW3eumZnYdKaHkf1qEC+Mag6DPbGNuuh0eG8AaYj+YqmVHSiGslaTQ== + dependencies: + "@babel/generator" "7.17.7" + "@babel/parser" "^7.20.5" + "@babel/traverse" "7.23.2" + "@babel/types" "7.17.0" + javascript-natural-sort "0.7.1" + lodash "^4.17.21" + "@trysound/sax@0.2.0": version "0.2.0" resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" @@ -4870,9 +4898,9 @@ "@types/node" "*" "@types/node@*", "@types/node@>=10.0.0": - version "20.9.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.9.0.tgz#bfcdc230583aeb891cf51e73cfdaacdd8deae298" - integrity sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw== + version "20.9.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.9.1.tgz#9d578c610ce1e984adda087f685ace940954fe19" + integrity sha512-HhmzZh5LSJNS5O8jQKpJ/3ZcrrlG6L70hpGqMIAoM9YVD0YBRNWYsfwcXq8VnSjlNpCpgLzMXdiPo+dxcvSmiA== dependencies: undici-types "~5.26.4" @@ -5699,7 +5727,7 @@ acorn@^7.4.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.0.0, acorn@^8.0.4, acorn@^8.1.0, acorn@^8.10.0, acorn@^8.7.1, acorn@^8.8.1, acorn@^8.8.2, acorn@^8.9.0: +acorn@^8.0.0, acorn@^8.0.4, acorn@^8.1.0, acorn@^8.10.0, acorn@^8.11.2, acorn@^8.7.1, acorn@^8.8.1, acorn@^8.8.2, acorn@^8.9.0: version "8.11.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== @@ -6862,9 +6890,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001538, caniuse-lite@^1.0.30001541: - version "1.0.30001562" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001562.tgz#9d16c5fd7e9c592c4cd5e304bc0f75b0008b2759" - integrity sha512-kfte3Hym//51EdX4239i+Rmp20EsLIYGdPkERegTgU19hQWCRhsRFGKHTliUlsry53tv17K7n077Kqa0WJU4ng== + version "1.0.30001563" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001563.tgz#aa68a64188903e98f36eb9c56e48fba0c1fe2a32" + integrity sha512-na2WUmOxnwIZtwnFI2CZ/3er0wdNzU7hN+cPYz/z2ajHThnkWjNBOpEPP4n+4r2WPM847JaMotaJE3bnfzjyKw== case-sensitive-paths-webpack-plugin@^2.4.0: version "2.4.0" @@ -7334,9 +7362,9 @@ commondir@^1.0.1: integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== component-emitter@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + version "1.3.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.1.tgz#ef1d5796f7d93f135ee6fb684340b26403c97d17" + integrity sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ== compressible@~2.0.16: version "2.0.18" @@ -8815,9 +8843,9 @@ ejs@^3.1.8: jake "^10.8.5" electron-to-chromium@^1.4.535: - version "1.4.585" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.585.tgz#7b3cb6846bb5cc10a8d5904c351a9b8aaa76ea90" - integrity sha512-B4yBlX0azdA3rVMxpYwLQfDpdwOgcnLCkpvSOd68iFmeedo+WYjaBJS3/W58LVD8CB2nf+o7C4K9xz1l09RkWg== + version "1.4.587" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.587.tgz#d8b864f21338b60798d447a3d83b90753f701d07" + integrity sha512-RyJX0q/zOkAoefZhB9XHghGeATVP0Q3mwA253XD/zj2OeXc+JZB9pCaEv6R578JUYaWM9PRhye0kXvd/V1cQ3Q== emittery@^0.13.1: version "0.13.1" @@ -9876,11 +9904,11 @@ file-entry-cache@^6.0.1: flat-cache "^3.0.4" file-entry-cache@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-7.0.1.tgz#c71b3509badb040f362255a53e21f15a4e74fc0f" - integrity sha512-uLfFktPmRetVCbHe5UPuekWrQ6hENufnA46qEGbfACkK5drjTTdQYUragRgMjHldcbYG+nslUerqMPjbBSHXjQ== + version "7.0.2" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-7.0.2.tgz#2d61bb70ba89b9548e3035b7c9173fe91deafff0" + integrity sha512-TfW7/1iI4Cy7Y8L6iqNdZQVvdXn0f8B4QcIXmkIbtTIe/Okm/nSlHb4IwGzRVOd3WfSieCgvf5cMzEfySAIl0g== dependencies: - flat-cache "^3.1.1" + flat-cache "^3.2.0" file-loader@^6.2.0: version "6.2.0" @@ -10013,7 +10041,7 @@ find-yarn-workspace-root2@1.2.16: micromatch "^4.0.2" pkg-dir "^4.2.0" -flat-cache@^3.0.4, flat-cache@^3.1.1: +flat-cache@^3.0.4, flat-cache@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== @@ -11092,9 +11120,9 @@ ignore-walk@3.0.4: minimatch "^3.0.4" ignore@^5.0.0, ignore@^5.1.9, ignore@^5.2.0, ignore@^5.2.4: - version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + version "5.3.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" + integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== immutable@^3, immutable@^3.7.6, immutable@^3.8.2: version "3.8.2" @@ -16157,7 +16185,7 @@ react-themeable@^1.1.0: dependencies: object-assign "^3.0.0" -react-transition-group@2.9.0, react-transition-group@^2.2.1, react-transition-group@^2.2.9, react-transition-group@^2.9.0: +react-transition-group@2.9.0, react-transition-group@^2.2.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== @@ -19046,14 +19074,14 @@ unpipe@1.0.0, unpipe@~1.0.0: integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== unplugin@^1.3.1: - version "1.5.0" - resolved "https://registry.yarnpkg.com/unplugin/-/unplugin-1.5.0.tgz#8938ae84defe62afc7757df9ca05d27160f6c20c" - integrity sha512-9ZdRwbh/4gcm1JTOkp9lAkIDrtOyOxgHmY7cjuwI8L/2RTikMcVG25GsZwNAgRuap3iDw2jeq7eoqtAsz5rW3A== + version "1.5.1" + resolved "https://registry.yarnpkg.com/unplugin/-/unplugin-1.5.1.tgz#806688376fa3dcca4d2fa2c5d27cf6cd0370fbef" + integrity sha512-0QkvG13z6RD+1L1FoibQqnvTwVBXvS4XSPwAyinVgoOCl2jAgwzdUKmEj05o4Lt8xwQI85Hb6mSyYkcAGwZPew== dependencies: - acorn "^8.10.0" + acorn "^8.11.2" chokidar "^3.5.3" webpack-sources "^3.2.3" - webpack-virtual-modules "^0.5.0" + webpack-virtual-modules "^0.6.0" unquote@~1.1.1: version "1.1.1" @@ -19609,6 +19637,11 @@ webpack-virtual-modules@^0.5.0: resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.5.0.tgz#362f14738a56dae107937ab98ea7062e8bdd3b6c" integrity sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw== +webpack-virtual-modules@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.0.tgz#95eb2cb160a8cb84a73bdc2b5c806693f690ad35" + integrity sha512-KnaMTE6EItz/f2q4Gwg5/rmeKVi79OR58NoYnwDJqCk9ywMtTGbBnBcfoBtN4QbYu0lWXvyMoH2Owxuhe4qI6Q== + webpack@5, webpack@^5.89.0: version "5.89.0" resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.89.0.tgz#56b8bf9a34356e93a6625770006490bf3a7f32dc"