Reordering in InputAddressMulti (#2337)
* Reorderable InputAddressMulti * Styling Co-authored-by: Jaco Greeff <jacogr@gmail.com>
This commit is contained in:
parent
2c070bad4d
commit
b43c7dc593
@ -43,6 +43,7 @@
|
||||
"@types/chart.js": "^2.9.15",
|
||||
"@types/file-saver": "^2.0.1",
|
||||
"@types/i18next": "^13.0.0",
|
||||
"@types/react-beautiful-dnd": "^12.1.1",
|
||||
"@types/react-copy-to-clipboard": "^4.3.0",
|
||||
"@types/react-dom": "^16.9.5",
|
||||
"@types/react-router-dom": "^5.1.3",
|
||||
|
||||
@ -25,6 +25,8 @@ interface SidebarState {
|
||||
transition: SideBarTransition;
|
||||
}
|
||||
|
||||
export const PORTAL_ID = 'portals';
|
||||
|
||||
function sanitize (value?: string): string {
|
||||
return value?.toLowerCase().replace('-', ' ') || '';
|
||||
}
|
||||
@ -98,6 +100,7 @@ function Apps ({ className }: Props): React.ReactElement<Props> {
|
||||
</Signer>
|
||||
<ConnectingOverlay />
|
||||
<AccountsOverlay />
|
||||
<div id={PORTAL_ID} />
|
||||
</div>
|
||||
<WarmUp />
|
||||
</>
|
||||
|
||||
@ -51,11 +51,12 @@ export default function RecoverSetup ({ address, className, onClose }: Props): R
|
||||
/>
|
||||
<InputAddressMulti
|
||||
available={availableHelpers}
|
||||
availableLabel={t('available social recovery helpers')}
|
||||
help={t('The addresses that are able to help in recovery. You can select up to {{maxHelpers}} trusted helpers.', { replace: { maxHelpers: MAX_HELPERS } })}
|
||||
label={t('trusted social recovery helpers')}
|
||||
onChange={setHelpers}
|
||||
maxCount={MAX_HELPERS}
|
||||
value={helpers}
|
||||
valueLabel={t('trusted social recovery helpers')}
|
||||
/>
|
||||
<InputNumber
|
||||
help={t('The threshold of vouches that is to be reached for the account to be recovered.')}
|
||||
|
||||
@ -58,9 +58,9 @@ class Vote extends TxModal<Props, State> {
|
||||
}
|
||||
|
||||
protected isDisabled = (): boolean => {
|
||||
const { accountId, votes } = this.state;
|
||||
const { accountId, votes, voteValue } = this.state;
|
||||
|
||||
return !accountId || votes.length === 0;
|
||||
return !accountId || votes.length === 0 || voteValue.lten(0);
|
||||
}
|
||||
|
||||
protected renderTrigger = (): React.ReactNode => {
|
||||
@ -97,11 +97,12 @@ class Vote extends TxModal<Props, State> {
|
||||
/>
|
||||
<InputAddressMulti
|
||||
available={available}
|
||||
help={t('Filter available candidates based on name, address or short account index.')}
|
||||
label={t('filter candidates')}
|
||||
availableLabel={t('council candidates')}
|
||||
help={t('Select and order council candidates you wish to vote for.')}
|
||||
maxCount={MAX_VOTES}
|
||||
onChange={this.onChangeVotes}
|
||||
value={votes}
|
||||
valueLabel={t('my ordered votes')}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@ -39,8 +39,6 @@ function Parachain ({ className, basePath, isMine, paraInfoRef, sudoKey }: Props
|
||||
);
|
||||
}
|
||||
|
||||
console.log(parachain);
|
||||
|
||||
if (!id || isNull(parachain)) {
|
||||
return (
|
||||
<>
|
||||
|
||||
@ -78,12 +78,13 @@ function Nominate ({ className, controllerId, nominees, onClose, next, stakingOv
|
||||
/>
|
||||
<InputAddressMulti
|
||||
available={available}
|
||||
availableLabel={t('candidate accounts')}
|
||||
className='medium'
|
||||
help={t('Filter available candidates based on name, address or short account index.')}
|
||||
label={t('filter candidates')}
|
||||
maxCount={MAX_NOMINEES}
|
||||
onChange={setSelection}
|
||||
value={selection || []}
|
||||
valueLabel={t('nominated accounts')}
|
||||
/>
|
||||
</Modal.Content>
|
||||
<Modal.Actions onCancel={onClose}>
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
"i18next-browser-languagedetector": "^4.0.2",
|
||||
"i18next-xhr-backend": "^3.2.2",
|
||||
"react": "^16.13.0",
|
||||
"react-beautiful-dnd": "^13.0.0",
|
||||
"react-chartjs-2": "^2.9.0",
|
||||
"react-copy-to-clipboard": "^5.0.2",
|
||||
"react-dom": "^16.13.0",
|
||||
|
||||
@ -15,61 +15,64 @@ import Toggle from './Toggle';
|
||||
interface Props {
|
||||
address: string;
|
||||
className?: string;
|
||||
isHidden?: boolean;
|
||||
filter?: string;
|
||||
noToggle?: boolean;
|
||||
onChange?: (isChecked: boolean) => void;
|
||||
value: boolean;
|
||||
value?: boolean;
|
||||
}
|
||||
|
||||
function AddressToggle ({ address, className, filter, onChange, value }: Props): React.ReactElement<Props> | null {
|
||||
function getIsFiltered (address: string, filter?: string, info?: DeriveAccountInfo): boolean {
|
||||
if (!filter || address.includes(filter)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const [,, extracted] = getAddressName(address);
|
||||
const filterLower = filter.toLowerCase();
|
||||
|
||||
if (extracted.toLowerCase().includes(filterLower)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (info) {
|
||||
const { accountId, accountIndex, identity, nickname } = info;
|
||||
|
||||
if (identity.display?.toLowerCase().includes(filterLower) || accountId?.toString().includes(filter) || accountIndex?.toString().includes(filter) || nickname?.toLowerCase().includes(filterLower)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function AddressToggle ({ address, className, filter, isHidden, noToggle, onChange, value }: Props): React.ReactElement<Props> | null {
|
||||
const { api } = useApi();
|
||||
const info = useCall<DeriveAccountInfo>(api.derive.accounts.info as any, [address]);
|
||||
const [isFiltered, setIsFiltered] = useState(false);
|
||||
|
||||
useEffect((): void => {
|
||||
let isFiltered = true;
|
||||
|
||||
if (!filter || address.includes(filter)) {
|
||||
isFiltered = false;
|
||||
} else if (info) {
|
||||
const [,, extracted] = getAddressName(address);
|
||||
const filterLower = filter.toLowerCase();
|
||||
|
||||
if (extracted.toLowerCase().includes(filterLower)) {
|
||||
isFiltered = false;
|
||||
} else if (info) {
|
||||
const { accountId, accountIndex, identity, nickname } = info;
|
||||
|
||||
if (identity.display?.toLowerCase().includes(filterLower) || accountId?.toString().includes(filter) || accountIndex?.toString().includes(filter) || nickname?.toLowerCase().includes(filterLower)) {
|
||||
isFiltered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setIsFiltered(isFiltered);
|
||||
}, [filter, info, value]);
|
||||
|
||||
if (isFiltered) {
|
||||
return null;
|
||||
}
|
||||
setIsFiltered(getIsFiltered(address, filter, info));
|
||||
}, [address, filter, info]);
|
||||
|
||||
const _onClick = (): void => onChange && onChange(!value);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`ui--AddressToggle ${className} ${value ? 'isAye' : 'isNay'}`}
|
||||
className={`ui--AddressToggle ${className} ${(value || noToggle) ? 'isAye' : 'isNay'} ${isHidden || isFiltered ? 'isHidden' : ''}`}
|
||||
onClick={_onClick}
|
||||
>
|
||||
<AddressMini
|
||||
className='ui--AddressToggle-address'
|
||||
value={address}
|
||||
/>
|
||||
<div className='ui--AddressToggle-toggle'>
|
||||
<Toggle
|
||||
label=''
|
||||
onChange={onChange}
|
||||
value={value}
|
||||
/>
|
||||
</div>
|
||||
{!noToggle && (
|
||||
<div className='ui--AddressToggle-toggle'>
|
||||
<Toggle
|
||||
label=''
|
||||
value={value}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -96,7 +99,17 @@ export default styled(AddressToggle)`
|
||||
border-color: #ccc;
|
||||
}
|
||||
|
||||
&.isHidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.isDragging {
|
||||
background: white;
|
||||
box-shadow: 0px 3px 5px 0px rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
&.isAye {
|
||||
cursor: move;
|
||||
.ui--AddressToggle-address {
|
||||
filter: none;
|
||||
opacity: 1;
|
||||
|
||||
@ -18,6 +18,7 @@ interface Props extends BareProps {
|
||||
defaultValue?: any;
|
||||
help?: React.ReactNode;
|
||||
icon?: React.ReactNode;
|
||||
inputClassName?: string;
|
||||
isAction?: boolean;
|
||||
isDisabled?: boolean;
|
||||
isDisabledError?: boolean;
|
||||
@ -89,7 +90,7 @@ const isSelectAll = (key: string, isPreKeyDown: boolean): boolean =>
|
||||
|
||||
let counter = 0;
|
||||
|
||||
export default function Input ({ autoFocus = false, children, className, defaultValue, help, icon, isEditable = false, isAction = false, isDisabled = false, isDisabledError = false, isError = false, isFull = false, isHidden = false, isReadOnly = false, label, labelExtra, max, maxLength, min, name, onBlur, onChange, onEnter, onEscape, onKeyDown, onKeyUp, onPaste, placeholder, style, tabIndex, type = 'text', value, withEllipsis, withLabel }: Props): React.ReactElement<Props> {
|
||||
export default function Input ({ autoFocus = false, children, className, defaultValue, help, icon, inputClassName, isEditable = false, isAction = false, isDisabled = false, isDisabledError = false, isError = false, isFull = false, isHidden = false, isReadOnly = false, label, labelExtra, max, maxLength, min, name, onBlur, onChange, onEnter, onEscape, onKeyDown, onKeyUp, onPaste, placeholder, style, tabIndex, type = 'text', value, withEllipsis, withLabel }: Props): React.ReactElement<Props> {
|
||||
const [stateName] = useState(`in_${counter++}_at_${Date.now()}`);
|
||||
|
||||
const _onBlur = (): void => {
|
||||
@ -133,9 +134,12 @@ export default function Input ({ autoFocus = false, children, className, default
|
||||
action={isAction}
|
||||
autoFocus={autoFocus}
|
||||
className={
|
||||
isEditable
|
||||
? 'ui--Input edit icon'
|
||||
: 'ui--Input'
|
||||
[
|
||||
isEditable
|
||||
? 'ui--Input edit icon'
|
||||
: 'ui--Input',
|
||||
inputClassName || ''
|
||||
].join(' ')
|
||||
}
|
||||
defaultValue={
|
||||
isUndefined(value)
|
||||
|
||||
@ -2,70 +2,194 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
|
||||
import styled from 'styled-components';
|
||||
import { useDebounce } from '@polkadot/react-hooks';
|
||||
|
||||
// FIXME :()
|
||||
import { PORTAL_ID } from '../../apps/src/Apps';
|
||||
import { useTranslation } from './translate';
|
||||
import AddressToggle from './AddressToggle';
|
||||
import Input from './Input';
|
||||
|
||||
interface Props {
|
||||
available: string[];
|
||||
availableLabel: React.ReactNode;
|
||||
className?: string;
|
||||
help: React.ReactNode;
|
||||
label: React.ReactNode;
|
||||
maxCount: number;
|
||||
onChange: (values: string[]) => void;
|
||||
valueLabel: React.ReactNode;
|
||||
value: string[];
|
||||
}
|
||||
|
||||
function InputAddressMulti ({ available, className, help, label, maxCount, onChange, value }: Props): React.ReactElement<Props> {
|
||||
function uniquesOf (list: string[]): string[] {
|
||||
return [...new Set(list)];
|
||||
}
|
||||
|
||||
function InputAddressMulti ({ available: propsAvailable = [], className, help, maxCount, onChange, availableLabel, valueLabel, value }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const [_filter, setFilter] = useState<string>('');
|
||||
const filter = useDebounce(_filter);
|
||||
|
||||
const _onClick = (key: string): (isChecked: boolean) => void =>
|
||||
(isChecked: boolean): void => {
|
||||
let newValues = value.filter((address): boolean => address !== key);
|
||||
const available = useMemo(
|
||||
(): string[] => uniquesOf(propsAvailable),
|
||||
[propsAvailable]
|
||||
);
|
||||
|
||||
if (isChecked) {
|
||||
newValues = [key].concat(newValues).slice(0, maxCount);
|
||||
const isSelected = useMemo(
|
||||
(): Record<string, boolean> => {
|
||||
return available.reduce(
|
||||
(result: Record<string, boolean>, address) => {
|
||||
return {
|
||||
...result,
|
||||
[address]: value.includes(address)
|
||||
};
|
||||
},
|
||||
{}
|
||||
);
|
||||
},
|
||||
[value, available]
|
||||
);
|
||||
|
||||
const onReorder = (source: any, destination: any): void => {
|
||||
const result = Array.from(value);
|
||||
const [removed] = result.splice(source.index, 1);
|
||||
result.splice(destination.index, 0, removed);
|
||||
|
||||
onChange(uniquesOf(result));
|
||||
};
|
||||
|
||||
const onSelect = (address: string): () => void => {
|
||||
return (): void => {
|
||||
if (isSelected[address] || (maxCount && value.length >= maxCount)) {
|
||||
return;
|
||||
}
|
||||
|
||||
onChange(newValues);
|
||||
onChange(
|
||||
uniquesOf(
|
||||
[
|
||||
...value,
|
||||
address
|
||||
]
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
const onDeselect = (index: number): () => void => {
|
||||
return (): void => {
|
||||
onChange(
|
||||
uniquesOf([
|
||||
...value.slice(0, index),
|
||||
...value.slice(index + 1)
|
||||
])
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
const onDragEnd = (result: any): void => {
|
||||
const { source, destination } = result;
|
||||
|
||||
onReorder(source, destination);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`ui--InputAddressMulti ${className}`}>
|
||||
<Input
|
||||
autoFocus
|
||||
className='ui--InputAddressMulti-Input'
|
||||
help={help}
|
||||
label={label}
|
||||
onChange={setFilter}
|
||||
placeholder={t('partial name, address or account index')}
|
||||
value={_filter}
|
||||
/>
|
||||
<div className='ui--InputAddressMulti-container'>
|
||||
{available.map((key): React.ReactNode => (
|
||||
<AddressToggle
|
||||
address={key}
|
||||
filter={filter}
|
||||
key={key}
|
||||
onChange={_onClick(key)}
|
||||
value={value.includes(key)}
|
||||
/>
|
||||
))}
|
||||
<div className='ui--InputAddressMulti-column'>
|
||||
<Input
|
||||
autoFocus
|
||||
className='ui--InputAddressMulti-Input label-small'
|
||||
label={availableLabel}
|
||||
onChange={setFilter}
|
||||
placeholder={t('filter by name, address, or account index')}
|
||||
value={_filter}
|
||||
/>
|
||||
<div className='ui--InputAddressMulti-items'>
|
||||
{available.map((address): React.ReactNode => (
|
||||
<AddressToggle
|
||||
address={address}
|
||||
filter={filter}
|
||||
isHidden={isSelected[address]}
|
||||
key={address}
|
||||
noToggle
|
||||
onChange={onSelect(address)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className='ui--InputAddressMulti-column'>
|
||||
<Input
|
||||
autoFocus
|
||||
className='ui--InputAddressMulti-Input label-small'
|
||||
help={help}
|
||||
inputClassName='retain-appearance'
|
||||
isDisabled
|
||||
label={valueLabel}
|
||||
onChange={setFilter}
|
||||
placeholder={t('drag and drop to reorder')}
|
||||
value={''}
|
||||
/>
|
||||
<DragDropContext onDragEnd={onDragEnd}>
|
||||
<Droppable droppableId='available'>
|
||||
{(provided: any): React.ReactNode => (
|
||||
<div
|
||||
className='ui--InputAddressMulti-items'
|
||||
ref={provided.innerRef}
|
||||
>
|
||||
{value.map((address, index): React.ReactNode => (
|
||||
<Draggable
|
||||
key={address}
|
||||
draggableId={address}
|
||||
index={index}
|
||||
>
|
||||
{(provided: any, snapshot: any): React.ReactNode => {
|
||||
const element = (
|
||||
<div
|
||||
ref={provided.innerRef}
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
>
|
||||
<AddressToggle
|
||||
address={address}
|
||||
className={snapshot.isDragging ? 'isDragging' : ''}
|
||||
noToggle
|
||||
onChange={onDeselect(index)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
if (snapshot.isDragging) {
|
||||
return ReactDOM.createPortal(element, document.getElementById(PORTAL_ID) as Element);
|
||||
}
|
||||
|
||||
return element;
|
||||
}}
|
||||
</Draggable>
|
||||
))}
|
||||
{provided.placeholder}
|
||||
</div>
|
||||
)}
|
||||
</Droppable>
|
||||
</DragDropContext>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default styled(InputAddressMulti)`
|
||||
border-top-width: 0px;
|
||||
margin-left: 2rem;
|
||||
width: calc(100% - 2rem);
|
||||
display: inline-flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.ui--InputAddressMulti-Input {
|
||||
.ui.input {
|
||||
margin-bottom: 0rem;
|
||||
opacity: 1 !important;
|
||||
|
||||
input {
|
||||
border-bottom-width: 0px;
|
||||
@ -75,19 +199,21 @@ export default styled(InputAddressMulti)`
|
||||
}
|
||||
}
|
||||
|
||||
.ui--InputAddressMulti-container {
|
||||
background: white;
|
||||
border: 1px solid rgba(34,36,38,.15);
|
||||
border-top-width: 0px;
|
||||
border-radius: 0 0 0.25rem 0.25rem;
|
||||
margin-left: 2rem;
|
||||
max-height: 15rem;
|
||||
overflow-y: scroll;
|
||||
padding: 0.25rem 0.5rem;
|
||||
.ui--InputAddressMulti-column {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
min-height: 15rem;
|
||||
max-height: 15rem;
|
||||
width: 50%;
|
||||
padding: 0.25rem 0.5rem;
|
||||
|
||||
.ui--AddressToggle {}
|
||||
.ui--InputAddressMulti-items {
|
||||
background: white;
|
||||
border: 1px solid rgba(34,36,38,0.15);
|
||||
border-top-width: 0;
|
||||
border-radius: 0 0 0.286rem 0.286rem;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
5
packages/react-components/src/react-beautiful-dnd.d.ts
vendored
Normal file
5
packages/react-components/src/react-beautiful-dnd.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
// Copyright 2017-2020 @polkadot/react-components authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
declare module 'react-beautiful-dnd';
|
||||
@ -55,7 +55,7 @@ export default css`
|
||||
.ui.input {
|
||||
width: 100%;
|
||||
|
||||
&.disabled {
|
||||
&.disabled:not(.retain-appearance) {
|
||||
opacity: 1;
|
||||
|
||||
input {
|
||||
|
||||
111
yarn.lock
111
yarn.lock
@ -3239,6 +3239,7 @@ __metadata:
|
||||
i18next-browser-languagedetector: ^4.0.2
|
||||
i18next-xhr-backend: ^3.2.2
|
||||
react: ^16.13.0
|
||||
react-beautiful-dnd: ^13.0.0
|
||||
react-chartjs-2: ^2.9.0
|
||||
react-copy-to-clipboard: ^5.0.2
|
||||
react-dom: ^16.13.0
|
||||
@ -3788,6 +3789,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/react-beautiful-dnd@npm:^12.1.1":
|
||||
version: 12.1.1
|
||||
resolution: "@types/react-beautiful-dnd@npm:12.1.1"
|
||||
dependencies:
|
||||
"@types/react": "*"
|
||||
checksum: 2/976a6b6642f5ff19a9f427b014974be36f4c2a4d67d8e92d17b803245401e08c603180a91f17f736f8019a3560139029290f5757cbae9ff1509767e5cb9ce11b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/react-copy-to-clipboard@npm:^4.3.0":
|
||||
version: 4.3.0
|
||||
resolution: "@types/react-copy-to-clipboard@npm:4.3.0"
|
||||
@ -7246,6 +7256,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"css-box-model@npm:^1.2.0":
|
||||
version: 1.2.0
|
||||
resolution: "css-box-model@npm:1.2.0"
|
||||
dependencies:
|
||||
tiny-invariant: ^1.0.6
|
||||
checksum: 2/5ad584c36128969604a150e5447de64979d48f7dd1c8e113c069895c859f20746103786509d282ca74126252e7ba54baa04f1b2484c8d8641591c13bf3f977e9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"css-color-keywords@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "css-color-keywords@npm:1.0.0"
|
||||
@ -14075,6 +14094,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"memoize-one@npm:^5.1.1":
|
||||
version: 5.1.1
|
||||
resolution: "memoize-one@npm:5.1.1"
|
||||
checksum: 2/e7c4a9cceca71334bf09c38818c375a280dc6e8ec03a92701c16199763269ce756b7b0b370f4b464c071045349fb7b3e4a3cc7460a3f46a277f394d8634a6eb5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"memoizee@npm:^0.4.14":
|
||||
version: 0.4.14
|
||||
resolution: "memoizee@npm:0.4.14"
|
||||
@ -17099,6 +17125,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"raf-schd@npm:^4.0.2":
|
||||
version: 4.0.2
|
||||
resolution: "raf-schd@npm:4.0.2"
|
||||
checksum: 2/28ad12b28814dc1b145a518e5ec6011e12aaf4b490cc7548ee0f8f2e26a7ac2168b62281588320a61743f7c4f70966c2db947aae60021f17546cb721a8d45821
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ramda@npm:^0.26":
|
||||
version: 0.26.1
|
||||
resolution: "ramda@npm:0.26.1"
|
||||
@ -17169,6 +17202,24 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-beautiful-dnd@npm:^13.0.0":
|
||||
version: 13.0.0
|
||||
resolution: "react-beautiful-dnd@npm:13.0.0"
|
||||
dependencies:
|
||||
"@babel/runtime": ^7.8.4
|
||||
css-box-model: ^1.2.0
|
||||
memoize-one: ^5.1.1
|
||||
raf-schd: ^4.0.2
|
||||
react-redux: ^7.1.1
|
||||
redux: ^4.0.4
|
||||
use-memo-one: ^1.1.1
|
||||
peerDependencies:
|
||||
react: ^16.8.5
|
||||
react-dom: ^16.8.5
|
||||
checksum: 2/0ce5027375308139c04f6fd1c429591fdd17b175903a63bf238d2e0b2c3db1260272870b24ee50262fc7718db914416274740e50f19eaf0e8bbd03a9cf0cd556
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-chartjs-2@npm:^2.9.0":
|
||||
version: 2.9.0
|
||||
resolution: "react-chartjs-2@npm:2.9.0"
|
||||
@ -17235,7 +17286,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-is@npm:^16.12.0, react-is@npm:^16.13.0, react-is@npm:^16.6.0, react-is@npm:^16.6.3, react-is@npm:^16.7.0, react-is@npm:^16.8.1, react-is@npm:^16.8.6":
|
||||
"react-is@npm:^16.12.0, react-is@npm:^16.13.0, react-is@npm:^16.6.0, react-is@npm:^16.6.3, react-is@npm:^16.7.0, react-is@npm:^16.8.1, react-is@npm:^16.8.6, react-is@npm:^16.9.0":
|
||||
version: 16.13.0
|
||||
resolution: "react-is@npm:16.13.0"
|
||||
checksum: 2/122f38efe00aca3f8c391a90513cb5e2ef2710db164730c9c6125f2f089b5cd413f22669e06606c5d84df08086c9a6b50fae90efa532baa82bc3a7c5c3b8b5da
|
||||
@ -17291,6 +17342,29 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-redux@npm:^7.1.1":
|
||||
version: 7.2.0
|
||||
resolution: "react-redux@npm:7.2.0"
|
||||
dependencies:
|
||||
"@babel/runtime": ^7.5.5
|
||||
hoist-non-react-statics: ^3.3.0
|
||||
loose-envify: ^1.4.0
|
||||
prop-types: ^15.7.2
|
||||
react-is: ^16.9.0
|
||||
peerDependencies:
|
||||
react: ^16.8.3
|
||||
react-dom: "*"
|
||||
react-native: "*"
|
||||
redux: ^2.0.0 || ^3.0.0 || ^4.0.0-0
|
||||
peerDependenciesMeta:
|
||||
react-dom:
|
||||
optional: true
|
||||
react-native:
|
||||
optional: true
|
||||
checksum: 2/e4beaa6064a5354f65bdeaf22c90fb8bf3df1ec0bcecf7c568321c6eba0cdf4b432236a828cb53801c5815a83d5090f38738f67ed14fb8cfddd21abe5fba317c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-router-dom@npm:^5.1.2":
|
||||
version: 5.1.2
|
||||
resolution: "react-router-dom@npm:5.1.2"
|
||||
@ -17591,6 +17665,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"redux@npm:^4.0.4":
|
||||
version: 4.0.5
|
||||
resolution: "redux@npm:4.0.5"
|
||||
dependencies:
|
||||
loose-envify: ^1.4.0
|
||||
symbol-observable: ^1.2.0
|
||||
checksum: 2/112739c2fb83ae2e18335d942a883b3ee14ebada31ff3a7924511a1f38a4278a762f5823491f3eb5083492de601ed76cb2687295c7d5db9a6e098c2542cdc05b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"regenerate-unicode-properties@npm:^8.1.0":
|
||||
version: 8.1.0
|
||||
resolution: "regenerate-unicode-properties@npm:8.1.0"
|
||||
@ -18165,6 +18249,7 @@ __metadata:
|
||||
"@types/chart.js": ^2.9.15
|
||||
"@types/file-saver": ^2.0.1
|
||||
"@types/i18next": ^13.0.0
|
||||
"@types/react-beautiful-dnd": ^12.1.1
|
||||
"@types/react-copy-to-clipboard": ^4.3.0
|
||||
"@types/react-dom": ^16.9.5
|
||||
"@types/react-router-dom": ^5.1.3
|
||||
@ -19672,6 +19757,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"symbol-observable@npm:^1.2.0":
|
||||
version: 1.2.0
|
||||
resolution: "symbol-observable@npm:1.2.0"
|
||||
checksum: 2/268834a1d4cba19d40f367e5c2755f612969c8418e43a3be17408e392802a667f8bb542893440d58a080a8ea8da05ea98e27e472b9f4ff6fbda78a21a1a41c53
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"symbol-tree@npm:^3.2.2":
|
||||
version: 3.2.4
|
||||
resolution: "symbol-tree@npm:3.2.4"
|
||||
@ -19963,7 +20055,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tiny-invariant@npm:^1.0.2":
|
||||
"tiny-invariant@npm:^1.0.2, tiny-invariant@npm:^1.0.6":
|
||||
version: 1.1.0
|
||||
resolution: "tiny-invariant@npm:1.1.0"
|
||||
checksum: 2/64318fbd77c451cfff23b57b9f3aef56594d9cea051a87dc538c9b371f97e8d474eaa2a7cbd60b8aa23f852393152495e8651b197607465fdf9c8ff134043b1b
|
||||
@ -20815,6 +20907,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"use-memo-one@npm:^1.1.1":
|
||||
version: 1.1.1
|
||||
resolution: "use-memo-one@npm:1.1.1"
|
||||
peerDependencies:
|
||||
react: ^16.8.0
|
||||
checksum: 2/691a41156a966ec83246b0c684f9ce84dcf9fe1d6441d136d3a2cf681d84f5be510265e1e3a5951b1f2f45a760a3492e3c389392c1e66240d5430150148383df
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"use@npm:^3.1.0":
|
||||
version: 3.1.1
|
||||
resolution: "use@npm:3.1.1"
|
||||
@ -21811,8 +21912,8 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"ws@npm:^7.0.0, ws@npm:^7.1.0":
|
||||
version: 7.2.1
|
||||
resolution: "ws@npm:7.2.1"
|
||||
version: 7.2.2
|
||||
resolution: "ws@npm:7.2.2"
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: ^5.0.2
|
||||
@ -21821,7 +21922,7 @@ __metadata:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
checksum: 2/097beba4b2722f097b8bcf92b1da6e81838c389b5e7f0246eb622a1949083fc6868aed0f51bc4c520d2d37f983e45134f903ee98b0881b0d7d51e25a1446753d
|
||||
checksum: 2/fe66f98e07cdb832d6161edd147e6bdec13cf7e811cd34b11d85fdc7b7c17eaf9498c1656dc4786c9d2207dc1cd86aef0060706af8c756ef86e9b5e9421ef566
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user