Skip to content

Commit

Permalink
chore: rtk identity traits (#5125)
Browse files Browse the repository at this point in the history
  • Loading branch information
kyle-ssg authored Feb 25, 2025
1 parent 9a58249 commit 0592f83
Show file tree
Hide file tree
Showing 14 changed files with 1,437 additions and 1,274 deletions.
2 changes: 0 additions & 2 deletions frontend/common/dispatcher/action-constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ const Actions = Object.assign({}, require('./base/_action-constants'), {
'CREATE_PROJECT': 'CREATE_PROJECT',
'DELETE_CHANGE_REQUEST': 'DELETE_CHANGE_REQUEST',
'DELETE_ENVIRONMENT': 'DELETE_ENVIRONMENT',
'DELETE_IDENTITY_TRAIT': 'DELETE_IDENTITY_TRAIT',
'DELETE_INVITE': 'DELETE_INVITE',
'DELETE_ORGANISATION': 'DELETE_ORGANISATION',
'DELETE_PROJECT': 'DELETE_PROJECT',
Expand All @@ -23,7 +22,6 @@ const Actions = Object.assign({}, require('./base/_action-constants'), {
'EDIT_FEATURE_MV': 'EDIT_FEATURE_MV',
'EDIT_ORGANISATION': 'EDIT_ORGANISATION',
'EDIT_PROJECT': 'EDIT_PROJECT',
'EDIT_TRAIT': 'EDIT_TRAIT',
'EDIT_USER_FLAG': 'EDIT_USER_FLAG',
'ENABLE_TWO_FACTOR': 'ENABLE_TWO_FACTOR',
'GET_CHANGE_REQUEST': 'GET_CHANGE_REQUEST',
Expand Down
14 changes: 0 additions & 14 deletions frontend/common/dispatcher/app-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,6 @@ const AppActions = Object.assign({}, require('./base/_app-actions'), {
env,
})
},
deleteIdentityTrait(envId, identity, id) {
Dispatcher.handleViewAction({
actionType: Actions.DELETE_IDENTITY_TRAIT,
envId,
id,
identity,
})
},
deleteInvite(id) {
Dispatcher.handleViewAction({
actionType: Actions.DELETE_INVITE,
Expand Down Expand Up @@ -188,12 +180,6 @@ const AppActions = Object.assign({}, require('./base/_app-actions'), {
project,
})
},
editTrait(params) {
Dispatcher.handleViewAction({
actionType: Actions.EDIT_TRAIT,
...params,
})
},
editUserFlag(params) {
Dispatcher.handleViewAction({
actionType: Actions.EDIT_USER_FLAG,
Expand Down
20 changes: 1 addition & 19 deletions frontend/common/providers/IdentityProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ const IdentityProvider = class extends React.Component {
identityFlags: IdentityStore.getIdentityFlags(),
isLoading: IdentityStore.isLoading || FeatureListStore.isLoading,
isSaving: IdentityStore.isSaving,
traits: IdentityStore.getTraits(),
})
})
this.listenTo(FeatureListStore, 'change', () => {
Expand Down Expand Up @@ -72,14 +71,6 @@ const IdentityProvider = class extends React.Component {
})
}

editTrait = ({ environmentId, identity, trait }) => {
AppActions.editTrait({ environmentId, identity, trait })
}

createTrait = ({ environmentId, identity, isCreate, trait }) => {
AppActions.editTrait({ environmentId, identity, isCreate, trait })
}

removeFlag = ({ environmentId, identity, identityFlag }) => {
AppActions.removeUserFlag({ environmentId, identity, identityFlag })
}
Expand All @@ -94,21 +85,12 @@ const IdentityProvider = class extends React.Component {
}

render() {
const {
changeUserFlag,
createTrait,
editFeatureValue,
editTrait,
removeFlag,
toggleFlag,
} = this
const { changeUserFlag, editFeatureValue, removeFlag, toggleFlag } = this
return this.props.children(
{ ...this.state },
{
changeUserFlag,
createTrait,
editFeatureValue,
editTrait,
removeFlag,
toggleFlag,
},
Expand Down
3 changes: 1 addition & 2 deletions frontend/common/services/useIdentity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,11 @@ export const identityService = service
pageType,
pages,
q,
search,
} = baseQuery
let url = `${getIdentityEndpoint(environmentId, isEdge)}/?q=${
dashboard_alias ? 'dashboard_alias:' : ''
}${encodeURIComponent(
dashboard_alias || search || q || '',
dashboard_alias || q || '',
)}&page_size=${page_size}`
let last_evaluated_key = null
if (!isEdge) {
Expand Down
233 changes: 233 additions & 0 deletions frontend/common/services/useIdentityTrait.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
import { IdentityTrait, Res } from 'common/types/responses'
import { Req } from 'common/types/requests'
import { service } from 'common/service'
import Utils from 'common/utils/utils'
import { getStore } from 'common/store'
import { identitySegmentService } from './useIdentitySegment'
import q from 'refractor/lang/q'

function getTraitEndpoint(
use_edge_identities: boolean,
environmentId: string,
userId: string,
) {
if (use_edge_identities) {
return `/environments/${environmentId}/edge-identities/${userId}/list-traits/`
}
return `/environments/${environmentId}/identities/${userId}/traits/`
}

function getUpdateTraitEndpoint(
use_edge_identities: boolean,
environmentId: string,
userId: string,
id?: number | string,
) {
if (use_edge_identities) {
return `/environments/${environmentId}/edge-identities/${userId}/update-traits/`
}
return `/environments/${environmentId}/identities/${userId}/traits/${
id ? `${id}/` : ''
}`
}

function getTraitBody(
use_edge_identities: boolean,
identity: string,
trait: IdentityTrait,
) {
const { trait_key, trait_value } = trait
return {
identity: !use_edge_identities ? { identifier: identity } : undefined,
trait_key,
...(use_edge_identities
? { trait_value }
: Utils.valueToTrait(trait_value)),
}
}
export const identityTraitService = service
.enhanceEndpoints({ addTagTypes: ['IdentityTrait'] })
.injectEndpoints({
endpoints: (builder) => ({
createIdentityTrait: builder.mutation<
Res['identityTrait'],
Req['createIdentityTrait']
>({
invalidatesTags: [{ id: 'LIST', type: 'IdentityTrait' }],
query: (query: Req['createIdentityTrait']) => {
return {
body: getTraitBody(
query.use_edge_identities,
query.identity,
query.data,
),
method: query.use_edge_identities ? 'PUT' : 'POST',
url: getUpdateTraitEndpoint(
query.use_edge_identities,
query.environmentId,
query.identity,
),
}
},
transformResponse: (res) => {
getStore().dispatch(
identitySegmentService.util.invalidateTags(['IdentitySegment']),
)
return res
},
}),
deleteIdentityTrait: builder.mutation<
Res['identityTrait'],
Req['deleteIdentityTrait']
>({
invalidatesTags: [{ id: 'LIST', type: 'IdentityTrait' }],
query: (query: Req['deleteIdentityTrait']) => {
if (query.use_edge_identities) {
return {
body: getTraitBody(query.use_edge_identities, query.identity, {
...query.data,
trait_value: null,
}),
method: 'PUT',
url: getUpdateTraitEndpoint(
query.use_edge_identities,
query.environmentId,
query.identity,
),
}
}
return {
body: {},
method: 'DELETE',
url: getUpdateTraitEndpoint(
query.use_edge_identities,
query.environmentId,
query.identity,
query.data.id,
),
}
},
transformResponse: (res) => {
getStore().dispatch(
identitySegmentService.util.invalidateTags(['IdentitySegment']),
)
return res
},
}),
getIdentityTraits: builder.query<
Res['identityTraits'],
Req['getIdentityTraits']
>({
providesTags: [{ id: 'LIST', type: 'IdentityTrait' }],
query: (query) => ({
url: getTraitEndpoint(
query.use_edge_identities,
query.environmentId,
query.identity,
),
}),
transformResponse: (res) => {
// Core API returns paginated were as edge doesn't
if (res?.results) {
return res?.results.map((v) => ({
...v,
trait_value: Utils.featureStateToValue(v),
}))
}
return res
},
}),
updateIdentityTrait: builder.mutation<
Res['identityTrait'],
Req['updateIdentityTrait']
>({
invalidatesTags: (res) => [
{ id: 'LIST', type: 'IdentityTrait' },
{ id: res?.id, type: 'IdentityTrait' },
],
query: (query: Req['createIdentityTrait']) => {
return {
body: getTraitBody(
query.use_edge_identities,
query.identity,
query.data,
),
method: 'PUT',
url: getUpdateTraitEndpoint(
query.use_edge_identities,
query.environmentId,
query.identity,
query.data.id,
),
}
},
transformResponse: (res) => {
getStore().dispatch(
identitySegmentService.util.invalidateTags(['IdentitySegment']),
)
return res
},
}),
// END OF ENDPOINTS
}),
})

export async function createIdentityTrait(
store: any,
data: Req['createIdentityTrait'],
options?: Parameters<
typeof identityTraitService.endpoints.createIdentityTrait.initiate
>[1],
) {
return store.dispatch(
identityTraitService.endpoints.createIdentityTrait.initiate(data, options),
)
}
export async function getIdentityTraits(
store: any,
data: Req['getIdentityTraits'],
options?: Parameters<
typeof identityTraitService.endpoints.getIdentityTraits.initiate
>[1],
) {
return store.dispatch(
identityTraitService.endpoints.getIdentityTraits.initiate(data, options),
)
}
export async function updateIdentityTrait(
store: any,
data: Req['updateIdentityTrait'],
options?: Parameters<
typeof identityTraitService.endpoints.updateIdentityTrait.initiate
>[1],
) {
return store.dispatch(
identityTraitService.endpoints.updateIdentityTrait.initiate(data, options),
)
}
export async function deleteIdentityTrait(
store: any,
data: Req['deleteIdentityTrait'],
options?: Parameters<
typeof identityTraitService.endpoints.deleteIdentityTrait.initiate
>[1],
) {
return store.dispatch(
identityTraitService.endpoints.deleteIdentityTrait.initiate(data, options),
)
}
// END OF FUNCTION_EXPORTS

export const {
useCreateIdentityTraitMutation,
useDeleteIdentityTraitMutation,
useGetIdentityTraitsQuery,
useUpdateIdentityTraitMutation,
// END OF EXPORTS
} = identityTraitService

/* Usage examples:
const { data, isLoading } = useGetIdentityTraitQuery({ id: 2 }, {}) //get hook
const [createIdentityTrait, { isLoading, data, isSuccess }] = useCreateIdentityTraitMutation() //create hook
identityTraitService.endpoints.getIdentityTrait.select({id: 2})(store.getState()) //access data from any function
*/
Loading

0 comments on commit 0592f83

Please sign in to comment.