Skip to content

Commit

Permalink
chore: rtk segment identities (#5121)
Browse files Browse the repository at this point in the history
  • Loading branch information
kyle-ssg authored Feb 19, 2025
1 parent a1dcdb8 commit 951b216
Show file tree
Hide file tree
Showing 12 changed files with 261 additions and 251 deletions.
1 change: 0 additions & 1 deletion frontend/common/dispatcher/action-constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ const Actions = Object.assign({}, require('./base/_action-constants'), {
'GET_FEATURE_USAGE': 'GET_FEATURE_USAGE',
'GET_FLAGS': 'GET_FLAGS',
'GET_IDENTITY': 'GET_IDENTITY',
'GET_IDENTITY_SEGMENTS': 'GET_IDENTITY_SEGMENTS',
'GET_ORGANISATION': 'GET_ORGANISATION',
'GET_PROJECT': 'GET_PROJECT',
'INVALIDATE_INVITE_LINK': 'INVALIDATE_INVITE_LINK',
Expand Down
7 changes: 0 additions & 7 deletions frontend/common/dispatcher/app-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,13 +260,6 @@ const AppActions = Object.assign({}, require('./base/_app-actions'), {
id,
})
},
getIdentitySegments(projectId, id) {
Dispatcher.handleViewAction({
actionType: Actions.GET_IDENTITY_SEGMENTS,
id,
projectId,
})
},
getOrganisation(organisationId) {
Dispatcher.handleViewAction({
actionType: Actions.GET_ORGANISATION,
Expand Down
42 changes: 0 additions & 42 deletions frontend/common/providers/IdentitySegmentsProvider.js

This file was deleted.

59 changes: 59 additions & 0 deletions frontend/common/services/useIdentitySegment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Res } from 'common/types/responses'
import { Req } from 'common/types/requests'
import { service } from 'common/service'
import Utils from 'common/utils/utils'
import transformCorePaging from 'common/transformCorePaging'
import { sortBy } from 'lodash'

export const identitySegmentService = service
.enhanceEndpoints({ addTagTypes: ['IdentitySegment'] })
.injectEndpoints({
endpoints: (builder) => ({
getIdentitySegments: builder.query<
Res['identitySegments'],
Req['getIdentitySegments']
>({
providesTags: (res) => [{ id: res?.id, type: 'IdentitySegment' }],
query: ({ projectId, ...query }: Req['getIdentitySegments']) => ({
url: `/projects/${projectId}/segments/?${Utils.toParam(query)}`,
}),
transformResponse: (
res: Res['identitySegments'],
_,
req: Req['getIdentitySegments'],
) =>
transformCorePaging(req, {
...res,
results: sortBy(res.results, 'name'),
}),
}),
// END OF ENDPOINTS
}),
})

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

export const {
useGetIdentitySegmentsQuery,
// END OF EXPORTS
} = identitySegmentService

/* Usage examples:
const { data, isLoading } = useGetIdentitySegmentsQuery({ id: 2 }, {}) //get hook
const [createIdentitySegments, { isLoading, data, isSuccess }] = useCreateIdentitySegmentsMutation() //create hook
identitySegmentService.endpoints.getIdentitySegments.select({id: 2})(store.getState()) //access data from any function
*/
46 changes: 0 additions & 46 deletions frontend/common/stores/identity-segments-store.js

This file was deleted.

5 changes: 5 additions & 0 deletions frontend/common/types/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -568,5 +568,10 @@ export type Req = {
getAuditLogWebhooks: { organisationId: string }
updateAuditLogWebhooks: { organisationId: string; data: Webhook }
deleteAuditLogWebhook: { organisationId: string; id: number }
getIdentitySegments: PagedRequest<{
q?: string
identity: string
projectId: string
}>
// END OF TYPES
}
1 change: 1 addition & 0 deletions frontend/common/types/responses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,7 @@ export type Res = {
metadata_xml: string
}
samlAttributeMapping: PagedResponse<SAMLAttributeMapping>
identitySegments: PagedResponse<Segment>
organisationWebhooks: PagedResponse<Webhook>
// END OF TYPES
}
7 changes: 6 additions & 1 deletion frontend/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ declare global {
) => void
const openConfirm: (data: OpenConfirm) => void
const Row: typeof Component
const toast: (value: ReactNode, theme?: string, expiry?: number, action?: { buttonText: string; onClick: () => void }) => void
const toast: (
value: ReactNode,
theme?: string,
expiry?: number,
action?: { buttonText: string; onClick: () => void },
) => void
const Flex: typeof Component
const isMobile: boolean
const FormGroup: typeof Component
Expand Down
2 changes: 1 addition & 1 deletion frontend/web/components/EnvironmentSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { FC, useMemo } from 'react'
import { useGetEnvironmentsQuery } from 'common/services/useEnvironment'
import { Props } from 'react-select/lib/Select'

export type EnvironmentSelectType = Partial<Props> & {
export type EnvironmentSelectType = Partial<Omit<Props, 'value'>> & {
projectId: string
value?: string
label?: string
Expand Down
5 changes: 3 additions & 2 deletions frontend/web/components/modals/AuditLogWebhooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ const AuditLogWebhooks: FC<AuditLogWebhooksType> = ({ organisationId }) => {
<h5 className='mb-2'>Audit Webhooks</h5>
<p className='fs-small lh-sm mb-4'>
Audit webhooks let you know when audit logs occur. You can configure
1 or more audit webhooks per organisation.<br/>
1 or more audit webhooks per organisation.
<br />
<Button
theme='text'
href='https://docs.flagsmith.com/system-administration/webhooks'
Expand All @@ -87,7 +88,7 @@ const AuditLogWebhooks: FC<AuditLogWebhooksType> = ({ organisationId }) => {
) : (
<PanelSearch
id='webhook-list'
className="no-pad"
className='no-pad'
items={webhooks?.results}
renderRow={(webhook: Webhook) => (
<Row
Expand Down
118 changes: 67 additions & 51 deletions frontend/web/components/modals/CreateSegmentUsersTabContent.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import React from 'react'
import React, { FC } from 'react'
import EnvironmentSelect from 'components/EnvironmentSelect'
import IdentitySegmentsProvider from 'common/providers/IdentitySegmentsProvider'
import PanelSearch from 'components/PanelSearch'
import InfoMessage from 'components/InfoMessage'
import InputGroup from 'components/base/forms/InputGroup'
import Utils from 'common/utils/utils'
import { Res, Segment } from 'common/types/responses'
import { Res } from 'common/types/responses'
import Icon from 'components/Icon'
import AppActions from 'common/dispatcher/app-actions'
import {
identitySegmentService,
useGetIdentitySegmentsQuery,
} from 'common/services/useIdentitySegment'
import { getStore } from 'common/store'

interface CreateSegmentUsersTabContentProps {
projectId: string | number
Expand All @@ -22,6 +25,55 @@ interface CreateSegmentUsersTabContentProps {
setSearchInput: (input: string) => void
}

type UserRowType = {
id: string
identifier: string
segmentName: string
projectId: string
index: number
}

const UserRow: FC<UserRowType> = ({
id,
identifier,
index,
projectId,
segmentName,
}) => {
const { data: segments } = useGetIdentitySegmentsQuery({
identity: id,
projectId,
})
let inSegment = false
if (segments?.results.find((v) => v.name === segmentName)) {
inSegment = true
}
return (
<Row key={id} className='list-item list-item-sm clickable'>
<Row space className='px-3' key={id} data-test={`user-item-${index}`}>
<div className='font-weight-medium'>{identifier}</div>
<Row
className={`font-weight-medium fs-small lh-sm ${
inSegment ? 'text-primary' : 'faint'
}`}
>
{inSegment ? (
<>
<Icon name='checkmark-circle' width={20} fill='#6837FC' />
<span className='ml-1'>User in segment</span>
</>
) : (
<>
<Icon name='minus-circle' width={20} fill='#9DA4AE' />
<span className='ml-1'>Not in segment</span>
</>
)}
</Row>
</Row>
</Row>
)
}

const CreateSegmentUsersTabContent: React.FC<
CreateSegmentUsersTabContentProps
> = ({
Expand Down Expand Up @@ -96,60 +148,24 @@ const CreateSegmentUsersTabContent: React.FC<
onRefresh={
environmentId
? () =>
identities?.results.forEach((identity) =>
AppActions.getIdentitySegments(projectId, identity.id),
getStore().dispatch(
identitySegmentService.util.invalidateTags([
'IdentitySegment',
]),
)
: undefined
}
renderRow={(
{ id, identifier }: { id: string; identifier: string },
index: number,
) => (
<Row key={id} className='list-item list-item-sm clickable'>
<IdentitySegmentsProvider fetch id={id} projectId={projectId}>
{({ segments }: { segments?: Segment[] }) => {
let inSegment = false
if (segments?.find((v) => v.name === name)) {
inSegment = true
}
return (
<Row
space
className='px-3'
key={id}
data-test={`user-item-${index}`}
>
<div className='font-weight-medium'>{identifier}</div>
<Row
className={`font-weight-medium fs-small lh-sm ${
inSegment ? 'text-primary' : 'faint'
}`}
>
{inSegment ? (
<>
<Icon
name='checkmark-circle'
width={20}
fill='#6837FC'
/>
<span className='ml-1'>User in segment</span>
</>
) : (
<>
<Icon
name='minus-circle'
width={20}
fill='#9DA4AE'
/>
<span className='ml-1'>Not in segment</span>
</>
)}
</Row>
</Row>
)
}}
</IdentitySegmentsProvider>
</Row>
<UserRow
segmentName={name}
projectId={`${projectId}`}
index={index}
id={id}
identifier={identifier}
/>
)}
filterRow={() => true}
search={searchInput}
Expand Down
Loading

0 comments on commit 951b216

Please sign in to comment.