diff --git a/package.json b/package.json index 92aff853..1f3d4de1 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "react-notification": "^6.8.5", "react-redux": "^7.2.6", "react-router-dom": "^5.3.0", + "react-select": "^5.8.0", "react-textarea-autosize": "^8.3.3", "redux": "^4.1.2", "redux-logger": "^3.0.6", diff --git a/src/components/all.scss b/src/components/all.scss index 493d1fbe..5e5bf9f9 100644 --- a/src/components/all.scss +++ b/src/components/all.scss @@ -8,6 +8,7 @@ @import "./elements/VerticalMenu"; @import "./elements/app/AppReminder"; @import "./elements/app/LoginAppReminder"; +@import "./elements/common/AccountName/index"; @import "./elements/common/DialogManager/index"; @import "./elements/common/Input/index"; @import './elements/donate/PresetSelector'; diff --git a/src/components/elements/common/AccountName/index.jsx b/src/components/elements/common/AccountName/index.jsx new file mode 100644 index 00000000..5d48afdf --- /dev/null +++ b/src/components/elements/common/AccountName/index.jsx @@ -0,0 +1,57 @@ +import React from 'react' +import tt from 'counterpart' +import AsyncSelect from 'react-select/async' +import { api } from 'golos-lib-js' + +import Userpic from 'app/components/elements/Userpic' + +class AccountName extends React.Component { + constructor(props) { + super(props) + } + + lookupAccounts = async (value) => { + try { + const accNames = await api.lookupAccountsAsync(value.toLowerCase(), 6, true) + const accs = await api.lookupAccountNamesAsync(accNames) + return accs + } catch (err) { + console.error(err) + return [] + } + } + + onChange = (acc) => { + const { onChange } = this.props + if (onChange) { + const e = { target: { value: acc.name, account: acc } } + onChange(e, acc) + } + } + + render() { + const { onChange, className, ...rest } = this.props + return { + return + + {`${option.name}`} + + }} + controlShouldRenderValue={false} + onChange={this.onChange} + {...rest} + /> + } +} + +export default AccountName diff --git a/src/components/elements/common/AccountName/index.scss b/src/components/elements/common/AccountName/index.scss new file mode 100644 index 00000000..bd494fc0 --- /dev/null +++ b/src/components/elements/common/AccountName/index.scss @@ -0,0 +1,14 @@ +.AccountName { + input { + box-shadow: none !important; + line-height: 1 !important; + height: 1.8rem !important; + } + .name-item { + margin-top: 0.45rem; + display: inline-block; + .title { + margin-left: 0.25rem; + } + } +} diff --git a/src/components/modules/CreateGroup.jsx b/src/components/modules/CreateGroup.jsx index 889e5047..c1825edb 100644 --- a/src/components/modules/CreateGroup.jsx +++ b/src/components/modules/CreateGroup.jsx @@ -16,7 +16,7 @@ import FormikAgent from 'app/components/elements/donate/FormikUtils' import Stepper from 'app/components/elements/messages/Stepper' import GroupName, { validateNameStep } from 'app/components/modules/groups/GroupName' import GroupLogo, { validateLogoStep } from 'app/components/modules/groups/GroupLogo' -import GroupAdmin, { validateAdminStep } from 'app/components/modules/groups/GroupAdmin' +import GroupMembers, { validateMembersStep } from 'app/components/modules/groups/GroupMembers' import GroupFinal from 'app/components/modules/groups/GroupFinal' import DialogManager from 'app/components/elements/common/DialogManager' import { showLoginDialog } from 'app/components/dialogs/LoginDialog' @@ -24,7 +24,7 @@ import { showLoginDialog } from 'app/components/dialogs/LoginDialog' const STEPS = () => { return { name: tt('create_group_jsx.step_name'), logo: tt('create_group_jsx.step_logo'), - admin: tt('create_group_jsx.step_admin'), + members: tt('create_group_jsx.step_members'), final: tt('create_group_jsx.step_create') } } @@ -35,14 +35,14 @@ class CreateGroup extends React.Component { step: 'name', validators: 0, initialValues: { + creatingNew: true, + title: '', name: '', is_encrypted: true, privacy: 'public_group', logo: '', - - admin: '', } } this.stepperRef = React.createRef() @@ -106,8 +106,8 @@ class CreateGroup extends React.Component { await validateNameStep(values, errors) } else if (step === 'logo') { await validateLogoStep(values, errors) - } else if (step === 'admin') { - await validateAdminStep(values, errors) + } else if (step === 'members') { + await validateMembersStep(values, errors) } await this.setValidating(false) return errors @@ -205,7 +205,7 @@ class CreateGroup extends React.Component { {!isSubmitting ? (step === 'name' ? : step === 'logo' ? : - step === 'admin' ? : + step === 'members' ? : step === 'final' ? : ) : null} @@ -215,7 +215,8 @@ class CreateGroup extends React.Component { {isSubmitting ?
: } @@ -223,10 +224,10 @@ class CreateGroup extends React.Component { )}}) return
-
-

{tt('msgs_start_panel.create_group')}

-
- {form} +
+

{tt('msgs_start_panel.create_group')}

+
+ {form}
} } @@ -243,7 +244,7 @@ export default connect( } }, dispatch => ({ - privateGroup: ({ password, creator, name, title, logo, admin, is_encrypted, privacy, + privateGroup: ({ password, creator, name, title, logo, moders, is_encrypted, privacy, onSuccess, onError }) => { let json_metadata = { app: 'golos-messenger', @@ -257,7 +258,6 @@ export default connect( creator, name, json_metadata, - admin: admin, is_encrypted, privacy, extensions: [], diff --git a/src/components/modules/Modals.jsx b/src/components/modules/Modals.jsx index 8ff3ffd2..b29bfd03 100644 --- a/src/components/modules/Modals.jsx +++ b/src/components/modules/Modals.jsx @@ -7,6 +7,7 @@ import Reveal from 'react-foundation-components/lib/global/reveal'; import CreateGroup from 'app/components/modules/CreateGroup' import GroupSettings from 'app/components/modules/groups/GroupSettings' +import GroupMembers from 'app/components/modules/groups/GroupMembers' import MyGroups from 'app/components/modules/groups/MyGroups' import Donate from 'app/components/modules/Donate' import LoginForm from 'app/components/modules/LoginForm'; @@ -23,6 +24,7 @@ class Modals extends React.Component { show_create_group_modal: PropTypes.bool, show_my_groups_modal: PropTypes.bool, show_group_settings_modal: PropTypes.bool, + show_group_members_modal: PropTypes.bool, show_app_download_modal: PropTypes.bool, hideDonate: PropTypes.func.isRequired, hideAppDownload: PropTypes.func.isRequired, @@ -47,12 +49,14 @@ class Modals extends React.Component { show_create_group_modal, show_my_groups_modal, show_group_settings_modal, + show_group_members_modal, show_app_download_modal, hideLogin, hideDonate, hideCreateGroup, hideMyGroups, hideGroupSettings, + hideGroupMembers, hideAppDownload, notifications, removeNotification, @@ -67,28 +71,45 @@ class Modals extends React.Component { return n; }) : []; + const modalStyle = { + borderRadius: '8px', + boxShadow: '0 0 19px 3px rgba(0,0,0, 0.2)', + overflow: 'hidden', + } + return (
- {show_login_modal && + {show_login_modal && } - {show_donate_modal && + {show_donate_modal && } - {show_create_group_modal && + {show_create_group_modal && } - {show_my_groups_modal && + {show_my_groups_modal && } - {show_group_settings_modal && + {show_group_settings_modal && } - {show_app_download_modal && + {show_group_members_modal && + + + } + {show_app_download_modal && } @@ -112,6 +133,7 @@ export default connect( show_create_group_modal: state.user.get('show_create_group_modal'), show_my_groups_modal: state.user.get('show_my_groups_modal'), show_group_settings_modal: state.user.get('show_group_settings_modal'), + show_group_members_modal: state.user.get('show_group_members_modal'), show_app_download_modal: state.user.get('show_app_download_modal'), loginUnclosable, notifications: state.app.get('notifications'), @@ -138,6 +160,10 @@ export default connect( if (e) e.preventDefault() dispatch(user.actions.hideGroupSettings()) }, + hideGroupMembers: e => { + if (e) e.preventDefault() + dispatch(user.actions.hideGroupMembers()) + }, hideAppDownload: e => { if (e) e.preventDefault() dispatch(user.actions.hideAppDownload()) diff --git a/src/components/modules/groups/GroupAdmin.jsx b/src/components/modules/groups/GroupAdmin.jsx deleted file mode 100644 index 56f8b3a6..00000000 --- a/src/components/modules/groups/GroupAdmin.jsx +++ /dev/null @@ -1,104 +0,0 @@ -import React from 'react' -import { connect } from 'react-redux' -import { Field, ErrorMessage, } from 'formik' -import tt from 'counterpart' -import { api } from 'golos-lib-js' -import { validateAccountName } from 'golos-lib-js/lib/utils' - -import Input from 'app/components/elements/common/Input'; - -export async function validateAdminStep(values, errors) { - if (!values.admin) { - errors.admin = tt('g.required') - } else { - const nameError = validateAccountName(values.admin) - if (nameError.error) { - errors.admin = tt('account_name.' + nameError.error) - } else { - try { - let accs = await api.getAccountsAsync([values.admin]) - accs = accs[0] - if (!accs) { - errors.admin = tt('g.username_does_not_exist') - } - } catch (err) { - console.error(err) - errors.admin = 'Blockchain unavailable :(' - } - } - } -} - -class GroupAdmin extends React.Component { - state = {} - - constructor(props) { - super(props) - } - - componentDidMount() { - this.load() - } - - componentDidUpdate() { - this.load() - } - - load = () => { - const { loaded } = this.state - if (!loaded) { - const { username, applyFieldValue } = this.props - if (username) { - applyFieldValue('admin', username) - this.setState({ - loaded: true - }) - } - } - } - - onChange = async (e) => { - e.preventDefault() - const { applyFieldValue } = this.props - applyFieldValue('admin', e.target.value) - } - - render() { - const { uploading } = this.state - - return -
-
- {tt('create_group_jsx.admin_desc')} -
-
-
-
- this.onChange(e)} - > - - -
-
-
- } -} - -export default connect( - // mapStateToProps - (state, ownProps) => { - const currentUser = state.user.get('current') - const username = currentUser && currentUser.get('username') - return { - ...ownProps, - username, - } - }, - dispatch => ({ - }) -)(GroupAdmin) diff --git a/src/components/modules/groups/GroupMembers.jsx b/src/components/modules/groups/GroupMembers.jsx new file mode 100644 index 00000000..f282b20a --- /dev/null +++ b/src/components/modules/groups/GroupMembers.jsx @@ -0,0 +1,144 @@ +import React from 'react' +import { connect } from 'react-redux' +import { Field, ErrorMessage, } from 'formik' +import tt from 'counterpart' +import { api } from 'golos-lib-js' +import { validateAccountName } from 'golos-lib-js/lib/utils' + +import g from 'app/redux/GlobalReducer' +import AccountName from 'app/components/elements/common/AccountName' +import Input from 'app/components/elements/common/Input'; +import LoadingIndicator from 'app/components/elements/LoadingIndicator' + +export async function validateMembersStep(values, errors) { + /*if (!values.admin) { + errors.admin = tt('g.required') + } else { + const nameError = validateAccountName(values.admin) + if (nameError.error) { + errors.admin = tt('account_name.' + nameError.error) + } else { + try { + let accs = await api.getAccountsAsync([values.admin]) + accs = accs[0] + if (!accs) { + errors.admin = tt('g.username_does_not_exist') + } + } catch (err) { + console.error(err) + errors.admin = 'Blockchain unavailable :(' + } + } + }*/ +} + +class GroupMembers extends React.Component { + state = {} + + constructor(props) { + super(props) + } + + componentDidMount() { + this.init() + } + + componentDidUpdate() { + this.init() + } + + isLoading = () => { + const { group } = this.props + if (!group) return true + const members = group.get('members') + if (!members) return true + return members.get('loading') + } + + init = () => { + const { initialized } = this.state + if (!initialized) { + const { currentGroup } = this.props + if (currentGroup) { + const group = currentGroup + this.props.fetchGroupMembers(group) + this.setState({ + initialized: true + }) + } + } + } + + render() { + const { currentGroup, group } = this.props + const loading = this.isLoading() + let members = group && group.get('members') + if (members) members = members.get('data') + if (members) members = members.toJS() + + if (loading) { + members =
+
+
+ +
+
+
+ } else { + members =
+
+
+ { alert(JSON.stringify(e))}} + /> +
+
+
+
+ {JSON.stringify(members)} +
+
+
+ } + + return
+
+
+ {tt('create_group_jsx.members_desc')} +
+
+ {members} +
+ } +} + +export default connect( + // mapStateToProps + (state, ownProps) => { + const currentUser = state.user.get('current') + const username = currentUser && currentUser.get('username') + + const { newGroup } = ownProps + let currentGroup + if (newGroup) { + currentGroup = newGroup + } else { + currentGroup = state.user.get('current_group') + if (currentGroup) currentGroup = currentGroup.toJS() + } + const group = currentGroup && state.global.getIn(['groups', currentGroup.name]) + return { + ...ownProps, + username, + currentGroup, + group, + } + }, + dispatch => ({ + fetchGroupMembers: (group) => { + dispatch(g.actions.fetchGroupMembers({ + group: group.name, creatingNew: !!group.creatingNew })) + }, + }) +)(GroupMembers) diff --git a/src/components/modules/groups/GroupSettings.jsx b/src/components/modules/groups/GroupSettings.jsx index 410b905c..27caa38e 100644 --- a/src/components/modules/groups/GroupSettings.jsx +++ b/src/components/modules/groups/GroupSettings.jsx @@ -17,7 +17,6 @@ import LoadingIndicator from 'app/components/elements/LoadingIndicator' import DialogManager from 'app/components/elements/common/DialogManager' import { showLoginDialog } from 'app/components/dialogs/LoginDialog' import { validateLogoStep } from 'app/components/modules/groups/GroupLogo' -import { validateAdminStep } from 'app/components/modules/groups/GroupAdmin' import { getGroupLogo, getGroupMeta, getGroupTitle } from 'app/utils/groups' import { proxifyImageUrlWithStrip } from 'app/utils/ProxifyUrl' @@ -32,20 +31,12 @@ class GroupSettings extends React.Component { componentDidMount() { const { currentGroup } = this.props const group = currentGroup.toJS() - const { name, member_list, privacy, json_metadata, is_encrypted } = group + const { name, privacy, json_metadata, is_encrypted } = group const meta = getGroupMeta(json_metadata) - let admin - for (const mem of member_list) { - if (mem.member_type === 'admin') { - admin = mem.account - } - break - } const initialValues = { name, title: meta.title, logo: meta.logo, - admin, privacy, is_encrypted, } @@ -67,11 +58,6 @@ class GroupSettings extends React.Component { applyFieldValue('logo', value) } - onAdminChange = (e, { applyFieldValue }) => { - const { value } = e.target - applyFieldValue('admin', value) - } - uploadLogo = (file, name, { applyFieldValue }) => { const { uploadImage } = this.props this.setState({ uploading: true }) @@ -114,7 +100,6 @@ class GroupSettings extends React.Component { errors.title = tt('create_group_jsx.group_min_length') } await validateLogoStep(values, errors) - await validateAdminStep(values, errors) return errors } @@ -241,19 +226,6 @@ class GroupSettings extends React.Component {
-
-
- {tt('create_group_jsx.admin')} - this.onAdminChange(e, { applyFieldValue })} - validateOnBlur={false} - /> - -
-
@@ -321,7 +293,7 @@ export default connect( payload: {file, progress}, }) }, - privateGroup: ({ password, creator, name, title, logo, admin, is_encrypted, privacy, + privateGroup: ({ password, creator, name, title, logo, is_encrypted, privacy, onSuccess, onError }) => { let json_metadata = { app: 'golos-messenger', @@ -335,7 +307,6 @@ export default connect( creator, name, json_metadata, - admin: admin, is_encrypted, privacy, extensions: [], diff --git a/src/components/modules/groups/MyGroups.jsx b/src/components/modules/groups/MyGroups.jsx index b43f78f0..80fceccf 100644 --- a/src/components/modules/groups/MyGroups.jsx +++ b/src/components/modules/groups/MyGroups.jsx @@ -75,6 +75,11 @@ class MyGroups extends React.Component { this.props.showGroupSettings({ group }) } + showGroupMembers = (e, group) => { + e.preventDefault() + this.props.showGroupMembers({ group }) + } + _renderGroup = (group) => { const { name, json_metadata } = group @@ -101,7 +106,9 @@ class MyGroups extends React.Component { { e.preventDefault() }}> - @@ -192,6 +199,9 @@ export default connect( showGroupSettings({ group }) { dispatch(user.actions.showGroupSettings({ group })) }, + showGroupMembers({ group }) { + dispatch(user.actions.showGroupMembers({ group })) + }, deleteGroup: ({ owner, name, password, onSuccess, onError }) => { const opData = { diff --git a/src/locales/en.json b/src/locales/en.json index c318f2e3..18cd2765 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -9,6 +9,10 @@ "each_account_segment_should_end_with_a_letter_or_digit": "Each account name segment should end with a letter or digit.", "each_account_segment_should_be_longer": "Each account name segment should be longer." }, + "account_name_jsx": { + "loading": "Loading...", + "no_options": "Cannot search..." + }, "chain_errors": { "exceeded_maximum_allowed_bandwidth": "Insufficient account bandwidth. Replenish the Golos Power or write to info@golos.id" }, @@ -118,7 +122,7 @@ "submit": "Create", "step_name": "Name", "step_logo": "Logo", - "step_admin": "Administrator", + "step_members": "Members", "step_create": "Create!", "group_already_exists": "Group already exists.", "group_min_length": "Min is 3 symbols.", @@ -129,7 +133,7 @@ "logo_desc": "The group logo is like a user’s avatar... Not required, but \"must have\"...", "logo_upload": "Upload logo", "logo_link": "Add logo from the URL", - "admin_desc": "Admin of group will be...", + "members_desc": "Add people, set moderators of the group...", "final_desc": "Now we are ready to create the group!", "image_wrong": "Cannot load this image.", "image_timeout": "Cannot load this image, it is loading too long..." @@ -260,6 +264,7 @@ "login": "Login", "logout": "Logout", "mentions": "Mentions", + "name": "Name", "night_mode": "Night Mode", "ok": "OK", "refresh": "Refresh", diff --git a/src/locales/ru-RU.json b/src/locales/ru-RU.json index c2db4afc..078f6f49 100644 --- a/src/locales/ru-RU.json +++ b/src/locales/ru-RU.json @@ -9,6 +9,10 @@ "each_account_segment_should_end_with_a_letter_or_digit": "Каждый сегмент имени аккаунта должен заканчиваться буквой или цифрой.", "each_account_segment_should_be_longer": "Сегмент имени аккаунта должен быть длиннее." }, + "account_name_jsx": { + "loading": "Загрузка...", + "no_options": "Не удается найти..." + }, "chain_errors": { "exceeded_maximum_allowed_bandwidth": "Недостаточно пропускной способности аккаунта. Пополните Силу Голоса или напишите на info@golos.id" }, @@ -121,7 +125,7 @@ "submit": "Создать", "step_name": "Имя", "step_logo": "Логотип", - "step_admin": "Администратор", + "step_members": "Участники", "step_create": "Создать!", "group_already_exists": "Такая группа уже существует.", "validating": "Проверка существования группы...", @@ -133,10 +137,11 @@ "logo_desc": "Логотип группы - это как аватарка у пользователя... Необязательно, но \"must have\"...", "logo_upload": "Загрузить логотип", "logo_link": "Добавить логотип ссылкой", - "admin_desc": "Администратором группы будeт...", + "members_desc": "Вы можете добавить в группу людей, назначить модераторов...", "final_desc": "Теперь все готово к созданию группы!", "image_wrong": "Не удается загрузить картинку.", - "image_timeout": "Не удается загрузить картинку, она загружается слишком долго..." + "image_timeout": "Не удается загрузить картинку, она загружается слишком долго...", + "add_member": "+ Добавить участника..." }, "my_groups_jsx": { "title": "Мои группы", @@ -271,6 +276,7 @@ "login": "Войти", "logout": "Выйти", "mentions": "Упоминания", + "name": "Имя", "night_mode": "Ночной режим", "ok": "OK", "refresh": "Обновить", diff --git a/src/redux/FetchDataSaga.js b/src/redux/FetchDataSaga.js index b1ebcbff..e5dbad58 100644 --- a/src/redux/FetchDataSaga.js +++ b/src/redux/FetchDataSaga.js @@ -9,6 +9,7 @@ export function* fetchDataWatches () { yield fork(watchFetchState) yield fork(watchFetchUiaBalances) yield fork(watchFetchMyGroups) + yield fork(watchFetchGroupMembers) } export function* watchLocationChange() { @@ -33,6 +34,7 @@ export function* fetchState(location_change_action) { state.messages_update = '0'; state.accounts = {} state.assets = {} + state.groups = {} let hasErr = false @@ -117,19 +119,54 @@ export function* watchFetchMyGroups() { export function* fetchMyGroups({ payload: { account } }) { try { - const groups = yield call([api, api.getGroupsAsync], { + const groupsOwn = yield call([api, api.getGroupsAsync], { member: account, - member_types: ['pending', 'member', 'moder', 'admin'], + member_types: [], start_group: '', limit: 100, with_members: { accounts: [account] } }) - console.log('LOO', groups) + let groups = yield call([api, api.getGroupsAsync], { + member: account, + member_types: ['pending', 'member', 'moder'], + start_group: '', + limit: 100, + with_members: { + accounts: [account] + } + }) + groups = [...groupsOwn, ...groups] yield put(g.actions.receiveMyGroups({ groups })) } catch (err) { console.error('fetchMyGroups', err) } } + +export function* watchFetchGroupMembers() { + yield takeLatest('global/FETCH_GROUP_MEMBERS', fetchGroupMembers) +} + +export function* fetchGroupMembers({ payload: { group, creatingNew } }) { + try { + if (creatingNew) { + yield put(g.actions.receiveGroupMembers({ group, members: [] })) + return + } + + yield put(g.actions.receiveGroupMembers({ group, loading: true })) + + const members = yield call([api, api.getGroupMembersAsync], { + group, + member_types: ['pending', 'member', 'moder'], + start_member: '', + limit: 100, + }) + + yield put(g.actions.receiveGroupMembers({ group, members })) + } catch (err) { + console.error('fetchGroupMembers', err) + } +} \ No newline at end of file diff --git a/src/redux/GlobalReducer.js b/src/redux/GlobalReducer.js index 9ab16b7d..0f9330bb 100644 --- a/src/redux/GlobalReducer.js +++ b/src/redux/GlobalReducer.js @@ -274,5 +274,26 @@ export default createModule({ return state.set('my_groups', fromJS(groups)) }, }, + { + action: 'FETCH_GROUP_MEMBERS', + reducer: state => state + }, + { + action: 'RECEIVE_GROUP_MEMBERS', + reducer: (state, { payload: { group, members, loading } }) => { + let new_state = state + new_state = state.updateIn(['groups', group], + Map(), + gro => { + gro = gro.updateIn(['members'], Map(), mems => { + mems = mems.set('loading', loading || false) + mems = mems.set('data', fromJS(members || [])) + return mems + }) + return gro + }) + return new_state + }, + }, ], }) diff --git a/src/redux/UserReducer.js b/src/redux/UserReducer.js index 50e75e0d..8f50ddf6 100644 --- a/src/redux/UserReducer.js +++ b/src/redux/UserReducer.js @@ -8,6 +8,7 @@ const defaultState = fromJS({ show_create_group_modal: false, show_my_groups_modal: false, show_group_settings_modal: false, + show_group_members_modal: false, show_app_download_modal: false, loginLoading: false, pub_keys_used: null, @@ -145,6 +146,12 @@ export default createModule({ return state }}, { action: 'HIDE_GROUP_SETTINGS', reducer: state => state.set('show_group_settings_modal', false) }, + { action: 'SHOW_GROUP_MEMBERS', reducer: (state, { payload: { group }}) => { + state = state.set('show_group_members_modal', true) + state = state.set('current_group', fromJS(group)) + return state + }}, + { action: 'HIDE_GROUP_MEMBERS', reducer: state => state.set('show_group_members_modal', false) }, { action: 'SHOW_APP_DOWNLOAD', reducer: state => state.set('show_app_download_modal', true) }, { action: 'HIDE_APP_DOWNLOAD', reducer: state => state.set('show_app_download_modal', false) }, { action: 'SET_DONATE_DEFAULTS', reducer: (state, {payload}) => state.set('donate_defaults', fromJS(payload)) }, diff --git a/yarn.lock b/yarn.lock index 840f5b11..f64113e3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1031,6 +1031,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.12.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.7.tgz#f4f0d5530e8dbdf59b3451b9b3e594b6ba082e12" + integrity sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.16.7", "@babel/template@^7.3.3": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" @@ -1109,6 +1116,94 @@ dependencies: postcss-value-parser "^4.2.0" +"@emotion/babel-plugin@^11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz#c2d872b6a7767a9d176d007f5b31f7d504bb5d6c" + integrity sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/runtime" "^7.18.3" + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/serialize" "^1.1.2" + babel-plugin-macros "^3.1.0" + convert-source-map "^1.5.0" + escape-string-regexp "^4.0.0" + find-root "^1.1.0" + source-map "^0.5.7" + stylis "4.2.0" + +"@emotion/cache@^11.11.0", "@emotion/cache@^11.4.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.11.0.tgz#809b33ee6b1cb1a625fef7a45bc568ccd9b8f3ff" + integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ== + dependencies: + "@emotion/memoize" "^0.8.1" + "@emotion/sheet" "^1.2.2" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + stylis "4.2.0" + +"@emotion/hash@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43" + integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ== + +"@emotion/memoize@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" + integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== + +"@emotion/react@^11.8.1": + version "11.11.4" + resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.4.tgz#3a829cac25c1f00e126408fab7f891f00ecc3c1d" + integrity sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw== + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/cache" "^11.11.0" + "@emotion/serialize" "^1.1.3" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + hoist-non-react-statics "^3.3.1" + +"@emotion/serialize@^1.1.2", "@emotion/serialize@^1.1.3": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.4.tgz#fc8f6d80c492cfa08801d544a05331d1cc7cd451" + integrity sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ== + dependencies: + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/unitless" "^0.8.1" + "@emotion/utils" "^1.2.1" + csstype "^3.0.2" + +"@emotion/sheet@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec" + integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== + +"@emotion/unitless@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3" + integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ== + +"@emotion/use-insertion-effect-with-fallbacks@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz#08de79f54eb3406f9daaf77c76e35313da963963" + integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw== + +"@emotion/utils@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.1.tgz#bbab58465738d31ae4cb3dbb6fc00a5991f755e4" + integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg== + +"@emotion/weak-memoize@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6" + integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww== + "@eslint/eslintrc@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.1.0.tgz#583d12dbec5d4f22f333f9669f7d0b7c7815b4d3" @@ -1124,6 +1219,26 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@floating-ui/core@^1.0.0": + version "1.6.3" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.3.tgz#5e7bb92843f47fd1d8dcb9b3cc3c243aaed54f95" + integrity sha512-1ZpCvYf788/ZXOhRQGFxnYQOVgeU+pi0i+d0Ow34La7qjIXETi6RNswGVKkA6KcDO8/+Ysu2E/CeUmmeEBDvTg== + dependencies: + "@floating-ui/utils" "^0.2.3" + +"@floating-ui/dom@^1.0.1": + version "1.6.6" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.6.tgz#be54c1ab2d19112ad323e63dbeb08185fed0ffd3" + integrity sha512-qiTYajAnh3P+38kECeffMSQgbvXty2VB6rS+42iWR4FPIlZjLK84E9qtLnMTLIpPz2znD/TaFqaiavMUrS+Hcw== + dependencies: + "@floating-ui/core" "^1.0.0" + "@floating-ui/utils" "^0.2.3" + +"@floating-ui/utils@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.3.tgz#506fcc73f730affd093044cb2956c31ba6431545" + integrity sha512-XGndio0l5/Gvd6CLIABvsav9HHezgDFFhDfHk1bvLfr9ni8dojqLSvBbotJEjmIwNHL7vK4QzBJTdBRoB+c1ww== + "@formatjs/ecma402-abstract@1.11.3": version "1.11.3" resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.3.tgz#f25276dfd4ef3dac90da667c3961d8aa9732e384" @@ -1925,6 +2040,13 @@ hoist-non-react-statics "^3.3.0" redux "^4.0.0" +"@types/react-transition-group@^4.4.0": + version "4.4.10" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.10.tgz#6ee71127bdab1f18f11ad8fb3322c6da27c327ac" + integrity sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q== + dependencies: + "@types/react" "*" + "@types/react@*", "@types/react@16 || 17": version "17.0.39" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.39.tgz#d0f4cde092502a6db00a1cded6e6bf2abb7633ce" @@ -3313,6 +3435,11 @@ convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: dependencies: safe-buffer "~5.1.1" +convert-source-map@^1.5.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -4038,6 +4165,14 @@ dom-helpers@^3.2.1: 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" + integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== + dependencies: + "@babel/runtime" "^7.8.7" + csstype "^3.0.2" + dom-serializer@0: version "0.2.2" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" @@ -4801,6 +4936,11 @@ find-cache-dir@^3.3.1: make-dir "^3.0.2" pkg-dir "^4.1.0" +find-root@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== + find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" @@ -5274,7 +5414,7 @@ history@4.10.1, history@^4.9.0: tiny-warning "^1.0.0" value-equal "^1.0.1" -hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: +hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -6809,6 +6949,11 @@ memfs@^3.1.2, memfs@^3.4.1: dependencies: fs-monkey "1.0.3" +memoize-one@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045" + integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw== + merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -8105,7 +8250,7 @@ prop-types-extra@^1.0.1, prop-types-extra@^1.1.1: react-is "^16.3.2" warning "^4.0.0" -prop-types@^15.5.10, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: +prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -8464,6 +8609,21 @@ react-scripts@^5.0.0: optionalDependencies: fsevents "^2.3.2" +react-select@^5.8.0: + version "5.8.0" + resolved "https://registry.yarnpkg.com/react-select/-/react-select-5.8.0.tgz#bd5c467a4df223f079dd720be9498076a3f085b5" + integrity sha512-TfjLDo58XrhP6VG5M/Mi56Us0Yt8X7xD6cDybC7yoRMUNm7BGO7qk8J0TLQOua/prb8vUOtsfnXZwfm30HGsAA== + dependencies: + "@babel/runtime" "^7.12.0" + "@emotion/cache" "^11.4.0" + "@emotion/react" "^11.8.1" + "@floating-ui/dom" "^1.0.1" + "@types/react-transition-group" "^4.4.0" + memoize-one "^6.0.0" + prop-types "^15.6.0" + react-transition-group "^4.3.0" + use-isomorphic-layout-effect "^1.1.2" + react-textarea-autosize@^8.3.3: version "8.3.3" resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.3.3.tgz#f70913945369da453fd554c168f6baacd1fa04d8" @@ -8473,6 +8633,16 @@ react-textarea-autosize@^8.3.3: use-composed-ref "^1.0.0" use-latest "^1.0.0" +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" + integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g== + dependencies: + "@babel/runtime" "^7.5.5" + dom-helpers "^5.0.1" + loose-envify "^1.4.0" + prop-types "^15.6.2" + react@^17.0.2: version "17.0.2" resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" @@ -8608,6 +8778,11 @@ regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.9: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + regenerator-transform@^0.14.2: version "0.14.5" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" @@ -9161,7 +9336,7 @@ source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, sourc resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@^0.5.0: +source-map@^0.5.0, source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= @@ -9396,6 +9571,11 @@ stylehacks@^5.0.3: browserslist "^4.16.6" postcss-selector-parser "^6.0.4" +stylis@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" + integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== + supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -9880,6 +10060,11 @@ use-isomorphic-layout-effect@^1.0.0: resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.1.tgz#7bb6589170cd2987a152042f9084f9effb75c225" integrity sha512-L7Evj8FGcwo/wpbv/qvSfrkHFtOpCzvM5yl2KVyDJoylVuSvzphiiasmjgQPttIGBAy2WKiBNR98q8w7PiNgKQ== +use-isomorphic-layout-effect@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb" + integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA== + use-latest@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/use-latest/-/use-latest-1.2.0.tgz#a44f6572b8288e0972ec411bdd0840ada366f232"