From 87501f5273aaaef843e97bf26ad063b2e07cfcbb Mon Sep 17 00:00:00 2001 From: Matheus Lasserre Date: Thu, 15 Feb 2024 06:33:00 -0300 Subject: [PATCH] feat: project usage limits (#3313) --- frontend/common/services/useProject.ts | 17 ++++ frontend/common/types/requests.ts | 1 + frontend/common/types/responses.ts | 1 + frontend/web/components/ProjectUsage.tsx | 82 +++++++++++++++++++ .../components/pages/ProjectSettingsPage.js | 6 ++ 5 files changed, 107 insertions(+) create mode 100644 frontend/web/components/ProjectUsage.tsx diff --git a/frontend/common/services/useProject.ts b/frontend/common/services/useProject.ts index ce8f1de93940..b929c6c47eec 100644 --- a/frontend/common/services/useProject.ts +++ b/frontend/common/services/useProject.ts @@ -7,6 +7,12 @@ export const projectService = service .enhanceEndpoints({ addTagTypes: ['Project'] }) .injectEndpoints({ endpoints: (builder) => ({ + getProject: builder.query({ + providesTags: (res) => [{ id: res?.id, type: 'Project' }], + query: (query: Req['getProject']) => ({ + url: `projects/${query.id}`, + }), + }), getProjects: builder.query({ providesTags: [{ id: 'LIST', type: 'Project' }], query: (data) => ({ @@ -28,9 +34,20 @@ export async function getProjects( store.dispatch(projectService.util.getRunningQueriesThunk()), ) } +export async function getProject( + store: any, + data: Req['getProject'], + options?: Parameters[1], +) { + store.dispatch(projectService.endpoints.getProject.initiate(data, options)) + return Promise.all( + store.dispatch(projectService.util.getRunningQueriesThunk()), + ) +} // END OF FUNCTION_EXPORTS export const { + useGetProjectQuery, useGetProjectsQuery, // END OF EXPORTS } = projectService diff --git a/frontend/common/types/requests.ts b/frontend/common/types/requests.ts index 40989a6601c0..2c664f232427 100644 --- a/frontend/common/types/requests.ts +++ b/frontend/common/types/requests.ts @@ -235,5 +235,6 @@ export type Req = { data: { name: string } } getAuditLogItem: { id: string } + getProject: { id: string } // END OF TYPES } diff --git a/frontend/common/types/responses.ts b/frontend/common/types/responses.ts index 946e340936d8..c73fb4a979d1 100644 --- a/frontend/common/types/responses.ts +++ b/frontend/common/types/responses.ts @@ -397,6 +397,7 @@ export type Res = { auditLogs: PagedResponse organisations: PagedResponse projects: ProjectSummary[] + project: Project environments: PagedResponse organisationUsage: { totals: { diff --git a/frontend/web/components/ProjectUsage.tsx b/frontend/web/components/ProjectUsage.tsx new file mode 100644 index 000000000000..2f399405f7bf --- /dev/null +++ b/frontend/web/components/ProjectUsage.tsx @@ -0,0 +1,82 @@ +import { FC, useEffect, useState } from 'react' +import Project from 'common/project' +import InfoMessage from './InfoMessage' +import { useGetProjectQuery } from 'common/services/useProject' +import { useGetEnvironmentsQuery } from 'common/services/useEnvironment' +import { Environment } from 'common/types/responses' +const _data = require('common/data/base/_data') + +type ProjectUsageType = { + projectId: string +} + +const ProjectUsage: FC = ({ projectId }) => { + const { data: project } = useGetProjectQuery({ id: projectId }) + const { data: environments } = useGetEnvironmentsQuery({ projectId }) + + const [segmentOverridesUsage, setSegmentOverridesUsage] = useState(0) + + const getSegmentOverridesUsage = (apiKeys: string[]) => { + apiKeys.forEach((apiKey) => { + _data + .get(`${Project.api}environments/${apiKey}`) + .then((res: Environment) => { + setSegmentOverridesUsage( + (prev) => prev + (res.total_segment_overrides || 0), + ) + }) + }) + } + + useEffect(() => { + if (environments) { + const apiKeys = environments.results.map((env) => env.api_key) + getSegmentOverridesUsage(apiKeys) + } + }, [environments]) + + return ( +
+ + + + In order to ensure consistent performance, Flagsmith has the + following usage limits.{' '} + + Check the Docs for more details. + + + + +
Project Usage
+
+ +

+ Features:{' '} + + {project?.total_features}/{project?.max_features_allowed} + +

+

+ Segments:{' '} + + {project?.total_segments}/{project?.max_segments_allowed} + +

+

+ Segment Overrides:{' '} + + {segmentOverridesUsage}/{project?.max_segment_overrides_allowed} + +

+
+
+
+ ) +} + +export default ProjectUsage diff --git a/frontend/web/components/pages/ProjectSettingsPage.js b/frontend/web/components/pages/ProjectSettingsPage.js index 9b3d803a6771..802e0e01930f 100644 --- a/frontend/web/components/pages/ProjectSettingsPage.js +++ b/frontend/web/components/pages/ProjectSettingsPage.js @@ -18,6 +18,7 @@ import { getRolesProjectPermissions } from 'common/services/useRolePermission' import AccountStore from 'common/stores/account-store' import ImportPage from 'components/import-export/ImportPage' import FeatureExport from 'components/import-export/FeatureExport' +import ProjectUsage from 'components/ProjectUsage' const ProjectSettingsPage = class extends Component { static displayName = 'ProjectSettingsPage' @@ -473,6 +474,11 @@ const ProjectSettingsPage = class extends Component { + + + {