diff --git a/frontend/common/ES6Component.js b/frontend/common/ES6Component.js index 08c09392f739..172fdc938ed2 100644 --- a/frontend/common/ES6Component.js +++ b/frontend/common/ES6Component.js @@ -1,3 +1,6 @@ +import each from 'lodash/each' +import partial from 'lodash/partial' + function es6Component(context, onUnmount) { context._listeners = [] @@ -31,7 +34,7 @@ function es6Component(context, onUnmount) { } context.setPathState = function setPathState(path, e) { - return _.partial(() => { + return partial(() => { const newState = {} newState[path] = Utils.safeParseEventValue(e) this.setState(newState) @@ -39,7 +42,7 @@ function es6Component(context, onUnmount) { } context.toggleState = function toggleState(path) { - return _.partial(() => { + return partial(() => { const newState = {} newState[path] = !this.state[path] this.setState(newState) @@ -47,7 +50,7 @@ function es6Component(context, onUnmount) { } context.componentWillUnmount = function componentWillUnmount() { - _.each(this._listeners, (listener, index) => { + each(this._listeners, (listener, index) => { if (listener) this.stopListening(index) }) if (onUnmount) { diff --git a/frontend/common/providers/withSegmentOverrides.js b/frontend/common/providers/withSegmentOverrides.js index 964c0bd361ac..3f74ef50ac00 100644 --- a/frontend/common/providers/withSegmentOverrides.js +++ b/frontend/common/providers/withSegmentOverrides.js @@ -1,3 +1,6 @@ +import cloneDeep from 'lodash/cloneDeep' +import each from 'lodash/each' +import findIndex from 'lodash/findIndex' import data from 'common/data/base/_data' import ProjectStore from 'common/stores/project-store' import FeatureListStore from 'common/stores/feature-list-store' @@ -56,9 +59,9 @@ export default (WrappedComponent) => { const environmentOverride = res2.results.find( (v) => !v.feature_segment && !v.identity, ) - _.each(featureStates, (f) => { + each(featureStates, (f) => { if (f.feature_segment) { - const index = _.findIndex(results, { id: f.feature_segment }) + const index = findIndex(results, { id: f.feature_segment }) if (index !== -1) { results[index].value = Utils.featureStateToValue( f.feature_state_value, @@ -188,7 +191,7 @@ export default (WrappedComponent) => { priority: i, })) - const originalSegmentOverrides = _.cloneDeep(segmentOverrides) + const originalSegmentOverrides = cloneDeep(segmentOverrides) this.setState({ environmentVariations: environmentOverride && diff --git a/frontend/common/stores/account-store.js b/frontend/common/stores/account-store.js index 06fa52d7680b..ef32cf654d50 100644 --- a/frontend/common/stores/account-store.js +++ b/frontend/common/stores/account-store.js @@ -1,4 +1,8 @@ import { matchPath } from 'react-router-dom' +import filter from 'lodash/filter' +import find from 'lodash/find' +import findIndex from 'lodash/findIndex' +import get from 'lodash/get' import { storageGet, storageSet } from 'common/safeLocalStorage' import Dispatcher from 'common/dispatcher/dispatcher' import BaseStore from './base/_store' @@ -125,7 +129,7 @@ const controller = { data .delete(`${Project.api}organisations/${store.organisation.id}/`) .then(() => { - store.model.organisations = _.filter( + store.model.organisations = filter( store.model.organisations, (org) => org.id !== store.organisation.id, ) @@ -149,7 +153,7 @@ const controller = { data .put(`${Project.api}organisations/${store.organisation.id}/`, org) .then((res) => { - const idx = _.findIndex(store.model.organisations, { + const idx = findIndex(store.model.organisations, { id: store.organisation.id, }) if (idx !== -1) { @@ -304,7 +308,7 @@ const controller = { selectOrganisation: (id) => { API.setCookie('organisation', `${id}`) - store.organisation = _.find(store.model.organisations, { id }) + store.organisation = find(store.model.organisations, { id }) store.changed() }, @@ -459,8 +463,8 @@ const store = Object.assign({}, BaseStore, { return ( store.model && store.model.organisations && - _.get( - _.find(store.model.organisations, (org) => + get( + find(store.model.organisations, (org) => id ? org.id === id : org.id === (store.organisation && store.organisation.id), @@ -477,7 +481,7 @@ const store = Object.assign({}, BaseStore, { }, getPlans() { if (!store.model) return [] - return _.filter( + return filter( store.model.organisations.map( (org) => org.subscription && org.subscription.plan, ), diff --git a/frontend/common/stores/feature-list-store.ts b/frontend/common/stores/feature-list-store.ts index f5c1a37e5d78..0adea7137d97 100644 --- a/frontend/common/stores/feature-list-store.ts +++ b/frontend/common/stores/feature-list-store.ts @@ -1,3 +1,8 @@ +import find from 'lodash/find' +import findIndex from 'lodash/findIndex' +import keyBy from 'lodash/keyBy' +import map from 'lodash/map' +import throttle from 'lodash/throttle' import Constants from 'common/constants' import ProjectStore from './project-store' import { @@ -149,7 +154,7 @@ const controller = { store.model = { features: features.results, keyedEnvironmentFeatures: - environmentFeatures && _.keyBy(environmentFeatures, 'feature'), + environmentFeatures && keyBy(environmentFeatures, 'feature'), } store.model.lastSaved = new Date().valueOf() getStore().dispatch( @@ -185,7 +190,7 @@ const controller = { onComplete(res) } if (store.model?.features) { - const index = _.findIndex(store.model.features, { id: flag.id }) + const index = findIndex(store.model.features, { id: flag.id }) store.model.features[index] = controller.parseFlag(flag) store.model.lastSaved = new Date().valueOf() getStore().dispatch( @@ -457,12 +462,12 @@ const controller = { if (store.model?.keyedEnvironmentFeatures) { store.model.keyedEnvironmentFeatures[projectFlag.id] = res if (segmentRes) { - const feature = _.find( + const feature = find( store.model.features, (f) => f.id === projectFlag.id, ) if (feature) { - feature.feature_segments = _.map( + feature.feature_segments = map( segmentRes.feature_segments, (segment) => ({ ...segment, @@ -929,7 +934,7 @@ const controller = { store.model = { features: features.results.map(controller.parseFlag), - keyedEnvironmentFeatures: _.keyBy( + keyedEnvironmentFeatures: keyBy( environmentFeatures, 'feature', ), @@ -955,7 +960,7 @@ const controller = { })), } }, - searchFeatures: _.throttle( + searchFeatures: throttle( (search, environmentId, projectId, filter, pageSize) => { store.search = encodeURIComponent(search || '') controller.getFeatures( diff --git a/frontend/common/stores/identity-store.js b/frontend/common/stores/identity-store.js index 7d421cccda93..9b3880858c92 100644 --- a/frontend/common/stores/identity-store.js +++ b/frontend/common/stores/identity-store.js @@ -1,3 +1,5 @@ +import cloneDeep from 'lodash/cloneDeep' +import keyBy from 'lodash/keyBy' import Constants from 'common/constants' import Utils from 'common/utils/utils' @@ -98,7 +100,7 @@ const controller = { const features = (flags && flags.results) || flags store.model = store.model || {} - store.model.features = features && _.keyBy(features, (f) => f.feature) + store.model.features = features && keyBy(features, (f) => f.feature) store.model.identity = identity store.loaded() }) @@ -178,7 +180,7 @@ const store = Object.assign({}, BaseStore, { return store.model && store.model.features }, getIdentityForEditing() { - return store.model && _.cloneDeep(store.model) // immutable + return store.model && cloneDeep(store.model) // immutable }, id: 'identity', }) diff --git a/frontend/common/stores/organisation-store.js b/frontend/common/stores/organisation-store.js index bce7a0eff124..53ccd705248d 100644 --- a/frontend/common/stores/organisation-store.js +++ b/frontend/common/stores/organisation-store.js @@ -7,7 +7,10 @@ import { getSubscriptionMetadata } from 'common/services/useSubscriptionMetadata import Dispatcher from 'common/dispatcher/dispatcher' import BaseStore from './base/_store' import data from 'common/data/base/_data' -import _ from 'lodash' +import filter from 'lodash/filter' +import find from 'lodash/find' +import findIndex from 'lodash/findIndex' +import keyBy from 'lodash/keyBy' const controller = { createProject: (name) => { @@ -75,7 +78,7 @@ const controller = { .then(() => { API.trackEvent(Constants.events.DELETE_INVITE) if (store.model) { - store.model.invites = _.filter( + store.model.invites = filter( store.model.invites, (i) => i.id !== id, ) @@ -89,11 +92,11 @@ const controller = { const idInt = parseInt(id) store.saving() if (store.model) { - store.model.projects = _.filter( + store.model.projects = filter( store.model.projects, (p) => p.id !== idInt, ) - store.model.keyedProjects = _.keyBy(store.model.projects, 'id') + store.model.keyedProjects = keyBy(store.model.projects, 'id') } API.trackEvent(Constants.events.REMOVE_PROJECT) data.delete(`${Project.api}projects/${id}/`).then(() => { @@ -110,7 +113,7 @@ const controller = { .then(() => { API.trackEvent(Constants.events.DELETE_USER) if (store.model) { - store.model.users = _.filter(store.model.users, (u) => u.id !== id) + store.model.users = filter(store.model.users, (u) => u.id !== id) } store.saved() }) @@ -121,7 +124,7 @@ const controller = { data .put(`${Project.api}organisations/${store.id}/`, { name }) .then((res) => { - const idx = _.findIndex(store.model.organisations, { + const idx = findIndex(store.model.organisations, { id: store.organisation.id, }) if (idx !== -1) { @@ -154,7 +157,7 @@ const controller = { if (`${id}` === `${store.id}`) { // eslint-disable-next-line prefer-const let [_projects, users, invites, subscriptionMeta] = res - let projects = _.sortBy(_projects, 'name') + let projects = sortBy(_projects, 'name') store.model = { ...store.model, @@ -215,7 +218,7 @@ const controller = { data .get(`${Project.api}environments/?project=${project.id}`) .then((res) => { - projects[i].environments = _.sortBy(res.results, 'name') + projects[i].environments = sortBy(res.results, 'name') }) .catch(() => { projects[i].environments = [] @@ -228,7 +231,7 @@ const controller = { return textA < textB ? -1 : textA > textB ? 1 : 0 }) store.model.projects = projects - store.model.keyedProjects = _.keyBy(store.model.projects, 'id') + store.model.keyedProjects = keyBy(store.model.projects, 'id') store.loaded() }) } @@ -278,7 +281,7 @@ const controller = { ) .then(() => { API.trackEvent(Constants.events.UPDATE_USER_ROLE) - const index = _.findIndex(store.model.users, (user) => user.id === id) + const index = findIndex(store.model.users, (user) => user.id === id) if (index !== -1) { store.model.users[index].role = role store.saved() diff --git a/frontend/common/stores/project-store.js b/frontend/common/stores/project-store.js index 48bb7ae6d8f3..eed66684ed1b 100644 --- a/frontend/common/stores/project-store.js +++ b/frontend/common/stores/project-store.js @@ -1,4 +1,8 @@ import OrganisationStore from './organisation-store' +import filter from 'lodash/filter' +import find from 'lodash/find' +import findIndex from 'lodash/findIndex' +import sortBy from 'lodash/sortBy' import Constants from 'common/constants' import Utils from 'common/utils/utils' @@ -77,7 +81,7 @@ const controller = { deleteEnv: (env) => { API.trackEvent(Constants.events.REMOVE_ENVIRONMENT) data.delete(`${Project.api}environments/${env.api_key}/`).then(() => { - store.model.environments = _.filter( + store.model.environments = filter( store.model.environments, (e) => e.id !== env.id, ) @@ -95,7 +99,7 @@ const controller = { data .put(`${Project.api}environments/${env.api_key}/`, env) .then((res) => { - const index = _.findIndex(store.model.environments, { id: env.id }) + const index = findIndex(store.model.environments, { id: env.id }) store.model.environments[index] = res store.saved() getStore().dispatch( @@ -147,7 +151,7 @@ const controller = { project.total_features = project.total_features || 0 project.total_segments = project.total_segments || 0 store.model = Object.assign(project, { - environments: _.sortBy(environments.results, 'name'), + environments: sortBy(environments.results, 'name'), }) if (project.organisation !== OrganisationStore.id) { AppActions.selectOrganisation(project.organisation) @@ -174,11 +178,11 @@ const controller = { const store = Object.assign({}, BaseStore, { getEnvironment: (api_key) => - store.model && _.find(store.model.environments, { api_key }), + store.model && find(store.model.environments, { api_key }), getEnvironmentById: (id) => - store.model && _.find(store.model.environments, { id }), + store.model && find(store.model.environments, { id }), getEnvironmentIdFromKey: (api_key) => { - const env = _.find(store.model.environments, { api_key }) + const env = find(store.model.environments, { api_key }) return env && env.id }, getEnvironmentIdFromKeyAsync: async (projectId, apiKey) => { @@ -191,7 +195,7 @@ const store = Object.assign({}, BaseStore, { }, getEnvs: () => store.model && store.model.environments, getIsVersioned: (api_key) => { - const env = _.find(store.model.environments, { api_key }) + const env = find(store.model.environments, { api_key }) return env && env.use_v2_feature_versioning }, getMaxFeaturesAllowed: () => { diff --git a/frontend/common/utils/base/_utils.js b/frontend/common/utils/base/_utils.js index c6b6dbee044d..64edec49841f 100644 --- a/frontend/common/utils/base/_utils.js +++ b/frontend/common/utils/base/_utils.js @@ -1,3 +1,5 @@ +import range from 'lodash/range' + const Utils = { GUID(append) { let d = new Date().getTime() @@ -439,7 +441,7 @@ emailRegex: /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*| prevTruncated: startPage > 2, // can go forward a page - range: _.range(startPage, endPage), + range: range(startPage, endPage), showFirstPage: startPage > 1, diff --git a/frontend/common/utils/utils.tsx b/frontend/common/utils/utils.tsx index 476e439fd1d2..61d66b67c00f 100644 --- a/frontend/common/utils/utils.tsx +++ b/frontend/common/utils/utils.tsx @@ -17,7 +17,7 @@ import { } from 'common/types/responses' import flagsmith from '@flagsmith/flagsmith' import { ReactNode } from 'react' -import _ from 'lodash' +import find from 'lodash/find' import ErrorMessage from 'components/ErrorMessage' import WarningMessage from 'components/WarningMessage' import Constants from 'common/constants' @@ -500,7 +500,7 @@ const Utils = Object.assign({}, BaseUtils, { if (!plans || !plans.length) { return false } - const found = _.find( + const found = find( plans.map((plan: string) => Utils.getPlanPermission(plan, feature)), (perm) => !!perm, ) diff --git a/frontend/web/components/App.js b/frontend/web/components/App.js index 3f6670b3c0b6..30b8734a2c00 100644 --- a/frontend/web/components/App.js +++ b/frontend/web/components/App.js @@ -1,4 +1,6 @@ import React, { Component } from 'react' +import get from 'lodash/get' +import find from 'lodash/find' import { matchPath, withRouter } from 'react-router-dom' import * as amplitude from '@amplitude/analytics-browser' import { plugin as engagementPlugin } from '@amplitude/engagement-browser' @@ -55,7 +57,7 @@ const App = class extends Component { strict: false, }) const projectId = - _.get(match, 'params.projectId') || _.get(match2, 'params.projectId') + get(match, 'params.projectId') || get(match2, 'params.projectId') return !!projectId && parseInt(projectId) } getEnvironmentId = (props) => { @@ -68,7 +70,7 @@ const App = class extends Component { strict: false, }) - const environmentId = _.get(match, 'params.environmentId') + const environmentId = get(match, 'params.environmentId') return environmentId } @@ -163,7 +165,7 @@ const App = class extends Component { } if (res) { const lastEnv = JSON.parse(res) - const lastOrg = _.find(AccountStore.getUser().organisations, { + const lastOrg = find(AccountStore.getUser().organisations, { id: lastEnv.orgId, }) if (!lastOrg) { diff --git a/frontend/web/components/CompareEnvironments.js b/frontend/web/components/CompareEnvironments.js index 214a4fc048a2..4532d2ae411c 100644 --- a/frontend/web/components/CompareEnvironments.js +++ b/frontend/web/components/CompareEnvironments.js @@ -1,5 +1,8 @@ // import propTypes from 'prop-types'; import React, { Component } from 'react' +import each from 'lodash/each' +import sortBy from 'lodash/sortBy' +import keyBy from 'lodash/keyBy' import EnvironmentSelect from './EnvironmentSelect' import data from 'common/data/base/_data' import ProjectStore from 'common/stores/project-store' @@ -81,8 +84,8 @@ class CompareEnvironments extends Component { ]) => { const changes = [] const same = [] - _.each( - _.sortBy(environmentLeftProjectFlags.results, (p) => p.name), + each( + sortBy(environmentLeftProjectFlags.results, (p) => p.name), (projectFlagLeft) => { const projectFlagRight = environmentRightProjectFlags.results?.find( @@ -123,11 +126,11 @@ class CompareEnvironments extends Component { ) this.setState({ changes, - environmentLeftFlags: _.keyBy( + environmentLeftFlags: keyBy( environmentLeftFlags.results, 'feature', ), - environmentRightFlags: _.keyBy( + environmentRightFlags: keyBy( environmentRightFlags.results, 'feature', ), diff --git a/frontend/web/components/DateList.tsx b/frontend/web/components/DateList.tsx index cf54d7cadc99..a61e309cad39 100644 --- a/frontend/web/components/DateList.tsx +++ b/frontend/web/components/DateList.tsx @@ -1,7 +1,7 @@ import React, { FC, useMemo } from 'react' import moment from 'moment' import { PagedResponse } from 'common/types/responses' -import _ from 'lodash' +import groupBy from 'lodash/groupBy' import Icon from './icons/Icon' import Paging from './Paging' import classNames from 'classnames' @@ -41,7 +41,7 @@ const DateList = ({ renderRow, }: DateListType) => { const groupedData = useMemo(() => { - return _.groupBy(items?.results || [], (item) => + return groupBy(items?.results || [], (item) => moment(item[dateProperty] as unknown as string).format(dateFormat), ) }, [items, dateFormat, dateProperty]) diff --git a/frontend/web/components/FlagSelect.js b/frontend/web/components/FlagSelect.js index fd3e449b57ac..ed9029e80875 100644 --- a/frontend/web/components/FlagSelect.js +++ b/frontend/web/components/FlagSelect.js @@ -1,4 +1,5 @@ import React, { Component } from 'react' +import sortBy from 'lodash/sortBy' import _data from 'common/data/base/_data' class FlagSelect extends Component { @@ -27,14 +28,6 @@ class FlagSelect extends Component { .then((res) => this.setState({ data: res.results, isLoading: false })) } - // searchFeatures = _.throttle((search) => { - // this.fetch() - // }, 1000) - // - // search = (e)=>{ - // this.setState({search:Utils.safeParseEventValue(e)}, this.searchFeatures) - // } - render() { if (!this.state.data || this.state.isLoading) { return ( @@ -43,7 +36,7 @@ class FlagSelect extends Component { ) } - const options = _.sortBy( + const options = sortBy( this.state.data .map((v) => ({ flag: v, label: v.name, value: v.id })) .filter((v) => !(this.props.ignore || []).includes(v.value)) diff --git a/frontend/web/components/Paging.js b/frontend/web/components/Paging.js index 89e6927ba072..134e0e14019b 100644 --- a/frontend/web/components/Paging.js +++ b/frontend/web/components/Paging.js @@ -1,5 +1,7 @@ // import propTypes from 'prop-types'; import React, { PureComponent } from 'react' +import map from 'lodash/map' +import range from 'lodash/range' import propTypes from 'prop-types' import cn from 'classnames' import { chevronBackOutline, chevronForwardOutline } from 'ionicons/icons' @@ -29,8 +31,8 @@ export default class Paging extends PureComponent { lastPage, (currentIndex || currentIndex + 1) + spaceBetween, ) - const range = _.range(from, to) - const noPages = range.length < 1 + const pageRange = range(from, to) + const noPages = pageRange.length < 1 if (noPages && !(paging.next || paging.previous)) { return null } @@ -57,7 +59,7 @@ export default class Paging extends PureComponent { {paging.currentPage ? ( - {!range.includes(0) && !noPages && ( + {!pageRange.includes(0) && !noPages && ( <>
{1}
- {!range.includes(1) && !noPages && ( + {!pageRange.includes(1) && !noPages && (
)} {!noPages && - _.map(range, (index) => ( + map(pageRange, (index) => (
))} {!noPages && - !range.includes(lastPage - 1) && - !range.includes(lastPage - 2) && ( + !pageRange.includes(lastPage - 1) && + !pageRange.includes(lastPage - 2) && ( <>
)} - {!noPages && !range.includes(lastPage - 1) && ( + {!noPages && !pageRange.includes(lastPage - 1) && ( <>
(props: PanelSearchProps): ReactElement => { const defaultSortingOption = useMemo(() => { return sorting - ? (_.find(sorting, { default: true }) as SortOption | undefined) + ? (find(sorting, { default: true }) as SortOption | undefined) : undefined }, [sorting]) @@ -102,7 +104,7 @@ const PanelSearch = (props: PanelSearchProps): ReactElement => { const sortItems = useCallback( (itemsToSort: T[]): T[] => { if (!sortBy) return itemsToSort - return _.orderBy( + return orderBy( itemsToSort, [sortBy], [(sortOrder?.toLowerCase() || 'asc') as 'asc' | 'desc'], @@ -117,7 +119,7 @@ const PanelSearch = (props: PanelSearchProps): ReactElement => { search = search.replace(/^"+|"+$/g, '') } if (filterRow && (search || filter)) { - const filtered = _.filter(items, (item, index) => + const filtered = lodashFilter(items, (item, index) => filterRow(item, search.toLowerCase(), index), ) return sortItems(filtered) @@ -188,7 +190,7 @@ const PanelSearch = (props: PanelSearchProps): ReactElement => { const filteredItems = filterItems() const currentSort: SortOption | undefined = useMemo(() => { - return sorting ? _.find(sorting, (v) => v.value === sortBy) : undefined + return sorting ? find(sorting, (v) => v.value === sortBy) : undefined }, [sorting, sortBy]) let search = propSearch || internalSearch || '' diff --git a/frontend/web/components/SegmentOverrides.js b/frontend/web/components/SegmentOverrides.js index ef3811de23b7..db5f16d34d7e 100644 --- a/frontend/web/components/SegmentOverrides.js +++ b/frontend/web/components/SegmentOverrides.js @@ -1,4 +1,7 @@ import React, { Component, Fragment } from 'react' +import cloneDeep from 'lodash/cloneDeep' +import filter from 'lodash/filter' +import find from 'lodash/find' import classNames from 'classnames' import { DragDropProvider } from '@dnd-kit/react' import { useSortable, isSortable } from '@dnd-kit/react/sortable' @@ -420,7 +423,7 @@ const SegmentOverrideListInner = ({ setValue(index, value) }} setVariations={(i, override, mvOptions) => { - const newValue = _.cloneDeep(mvOptions) + const newValue = cloneDeep(mvOptions) newValue[i] = { ...newValue[i], percentage_allocation: @@ -467,7 +470,7 @@ const SegmentOverrideListInner = ({ setValue(index, value) }} setVariations={(i, override, mvOptions) => { - const newValue = _.cloneDeep(mvOptions) + const newValue = cloneDeep(mvOptions) newValue[i] = { ...newValue[i], percentage_allocation: override.default_percentage_allocation, @@ -617,7 +620,7 @@ class TheComponent extends Component { confirmRemove = (i) => { if (!this.props.value[i].id) { this.props.onChange( - _.filter(this.props.value, (v, index) => index !== i).map((v, i) => ({ + filter(this.props.value, (v, index) => index !== i).map((v, i) => ({ ...v, priority: i, })), @@ -683,7 +686,7 @@ class TheComponent extends Component { if (segment.feature && segment.feature !== this.props.feature) return false if (this.props.id && this.props.id !== segment.id) return null - const foundSegment = _.find(value, (v) => v.segment === segment.id) + const foundSegment = find(value, (v) => v.segment === segment.id) return !value || !foundSegment || (foundSegment && foundSegment.toRemove) } const InnerComponent = diff --git a/frontend/web/components/modals/CreateTrait.tsx b/frontend/web/components/modals/CreateTrait.tsx index d17216024cd1..b4de0abe17fd 100644 --- a/frontend/web/components/modals/CreateTrait.tsx +++ b/frontend/web/components/modals/CreateTrait.tsx @@ -12,7 +12,7 @@ import Format from 'common/utils/format' import ErrorMessage from 'components/ErrorMessage' import ModalHR from './ModalHR' import IdentityProvider from 'common/providers/IdentityProvider' -import _ from 'lodash' +import find from 'lodash/find' import ProjectProvider from 'common/providers/ProjectProvider' import Button from 'components/base/forms/Button' import InputGroup from 'components/base/forms/InputGroup' @@ -164,7 +164,7 @@ const CreateTrait: FC = ({ {' '} { - _.find(project.environments, { + find(project.environments, { api_key: environmentId, })?.name } diff --git a/frontend/web/components/modals/InviteUsers.tsx b/frontend/web/components/modals/InviteUsers.tsx index 9d6d43d52450..50206a96da0f 100644 --- a/frontend/web/components/modals/InviteUsers.tsx +++ b/frontend/web/components/modals/InviteUsers.tsx @@ -9,7 +9,8 @@ import { getPlanBasedOption } from 'components/PlanBasedAccess' import InputGroup from 'components/base/forms/InputGroup' import OrganisationProvider from 'common/providers/OrganisationProvider' import Utils from 'common/utils/utils' -import _ from 'lodash' +import every from 'lodash/every' +import map from 'lodash/map' import ErrorMessage from 'components/ErrorMessage' import AccountStore from 'common/stores/account-store' import { close as closeIcon } from 'ionicons/icons' @@ -81,7 +82,7 @@ const InviteUsers: FC = () => { }, []) const isValid = (): boolean => { - return _.every( + return every( invites, (invite) => Utils.isValidEmail(invite.emailAddress) && invite.role, ) @@ -190,7 +191,7 @@ const InviteUsers: FC = () => { onChange(invite.temporaryId, 'role', role) } className='pl-2 react-select' - options={_.map(Constants.roles, (label, value) => + options={map(Constants.roles, (label, value) => value === 'ADMIN' ? { label, diff --git a/frontend/web/components/modals/create-experiment/index.js b/frontend/web/components/modals/create-experiment/index.js index 808c3f545a2a..85e2464f97d4 100644 --- a/frontend/web/components/modals/create-experiment/index.js +++ b/frontend/web/components/modals/create-experiment/index.js @@ -1,4 +1,6 @@ import React, { Component } from 'react' +import cloneDeep from 'lodash/cloneDeep' +import find from 'lodash/find' import ProjectStore from 'common/stores/project-store' import ConfigProvider from 'common/providers/ConfigProvider' import FeatureListStore from 'common/stores/feature-list-store' @@ -34,7 +36,7 @@ const Index = class extends Component { super(props, context) const projectFlagData = this.props.projectFlag - ? _.cloneDeep(this.props.projectFlag) + ? cloneDeep(this.props.projectFlag) : { description: undefined, is_archived: undefined, @@ -46,7 +48,7 @@ const Index = class extends Component { } const sourceFlag = this.props.identityFlag || this.props.environmentFlag - const environmentFlagData = sourceFlag ? _.cloneDeep(sourceFlag) : {} + const environmentFlagData = sourceFlag ? cloneDeep(sourceFlag) : {} this.state = { changeRequests: [], @@ -79,7 +81,7 @@ const Index = class extends Component { environmentFlagSource.updated_at !== prevEnvironmentFlagSource.updated_at ) { this.setState({ - environmentFlag: _.cloneDeep(environmentFlagSource), + environmentFlag: cloneDeep(environmentFlagSource), }) } @@ -91,7 +93,7 @@ const Index = class extends Component { this.props.projectFlag.updated_at !== prevProps.projectFlag.updated_at ) { this.setState({ - projectFlag: _.cloneDeep(this.props.projectFlag), + projectFlag: cloneDeep(this.props.projectFlag), }) } @@ -525,7 +527,7 @@ const Index = class extends Component { projectFlag={projectFlag} environmentId={this.props.environmentId} environmentName={ - _.find(project.environments, { + find(project.environments, { api_key: this.props.environmentId, })?.name || '' } @@ -650,7 +652,7 @@ const Index = class extends Component { {' '} { - _.find(project.environments, { + find(project.environments, { api_key: this.props.environmentId, }).name } diff --git a/frontend/web/components/modals/create-feature/index.tsx b/frontend/web/components/modals/create-feature/index.tsx index 18b583fd38b5..bd414bc77755 100644 --- a/frontend/web/components/modals/create-feature/index.tsx +++ b/frontend/web/components/modals/create-feature/index.tsx @@ -1,6 +1,5 @@ import React, { FC, useCallback, useEffect, useRef, useState } from 'react' -// @ts-ignore untyped module -import _ from 'lodash' +import cloneDeep from 'lodash/cloneDeep' import moment from 'moment' import { useProjectEnvironments } from 'common/hooks/useProjectEnvironments' import { useHasGithubIntegration } from 'common/hooks/useHasGithubIntegration' @@ -86,7 +85,7 @@ const CreateFeatureModal: FC = (props) => { const [projectFlag, setProjectFlag] = useState(() => props.projectFlag - ? _.cloneDeep(props.projectFlag) + ? cloneDeep(props.projectFlag) : { description: undefined, is_archived: undefined, @@ -100,7 +99,7 @@ const CreateFeatureModal: FC = (props) => { const [environmentFlag, setEnvironmentFlag] = useState(() => { const sourceFlag = props.identityFlag || props.environmentFlag - return sourceFlag ? _.cloneDeep(sourceFlag) : {} + return sourceFlag ? cloneDeep(sourceFlag) : {} }) const [_changeRequests, setChangeRequests] = useState([]) @@ -208,7 +207,7 @@ const CreateFeatureModal: FC = (props) => { useEffect(() => { const source = props.identityFlag || props.environmentFlag if (source?.updated_at) { - setEnvironmentFlag(_.cloneDeep(source)) + setEnvironmentFlag(cloneDeep(source)) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [(props.identityFlag || props.environmentFlag)?.updated_at]) @@ -219,7 +218,7 @@ const CreateFeatureModal: FC = (props) => { // overwrite the user's unsaved edits to settings/tags/description. useEffect(() => { if (props.projectFlag) { - setProjectFlag(_.cloneDeep(props.projectFlag)) + setProjectFlag(cloneDeep(props.projectFlag)) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [props.projectFlag?.id]) diff --git a/frontend/web/components/pages/EnvironmentSettingsPage.tsx b/frontend/web/components/pages/EnvironmentSettingsPage.tsx index 7447a977b95a..7e48a66ebafc 100644 --- a/frontend/web/components/pages/EnvironmentSettingsPage.tsx +++ b/frontend/web/components/pages/EnvironmentSettingsPage.tsx @@ -13,7 +13,7 @@ import ColourSelect from 'components/tags/ColourSelect' import Constants from 'common/constants' import Switch from 'components/Switch' import Icon from 'components/icons/Icon' -import _ from 'lodash' +import find from 'lodash/find' import PageTitle from 'components/PageTitle' import { getStore } from 'common/store' import { getRoles } from 'common/services/useRole' @@ -376,7 +376,7 @@ const EnvironmentSettingsPage: React.FC = () => { onSave={onSave} > {({ deleteEnv, isLoading, isSaving, project }) => { - const env = _.find(project?.environments, { + const env = find(project?.environments, { api_key: match.params.environmentId, }) if ( @@ -602,7 +602,7 @@ const EnvironmentSettingsPage: React.FC = () => {