diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql index 06fd2e50aa..4dd0b9a1a7 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql +++ b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql @@ -1781,6 +1781,12 @@ type ClientConfig { isClickHouseConfigured: Boolean! } +type UsageBreakdownItem { + key: String! + label: String + creditsUsed: Float! +} + type ConfigVariable { name: String! description: String! @@ -2380,6 +2386,26 @@ type Impersonate { workspace: WorkspaceUrlsAndId! } +type UsageTimeSeries { + date: String! + creditsUsed: Float! +} + +type UsageUserDaily { + userWorkspaceId: String! + dailyUsage: [UsageTimeSeries!]! +} + +type UsageAnalytics { + usageByUser: [UsageBreakdownItem!]! + usageByOperationType: [UsageBreakdownItem!]! + usageByModel: [UsageBreakdownItem!]! + timeSeries: [UsageTimeSeries!]! + periodStart: DateTime! + periodEnd: DateTime! + userDailyUsage: UsageUserDaily +} + type DevelopmentApplication { id: String! universalIdentifier: String! @@ -2575,31 +2601,6 @@ type PostgresCredentials { workspaceId: UUID! } -type UsageBreakdownItem { - key: String! - label: String - creditsUsed: Float! -} - -type UsageTimeSeries { - date: String! - creditsUsed: Float! -} - -type UsageUserDaily { - userWorkspaceId: String! - dailyUsage: [UsageTimeSeries!]! -} - -type UsageAnalytics { - usageByUser: [UsageBreakdownItem!]! - usageByOperationType: [UsageBreakdownItem!]! - timeSeries: [UsageTimeSeries!]! - periodStart: DateTime! - periodEnd: DateTime! - userDailyUsage: UsageUserDaily -} - type FrontComponent { id: UUID! name: String! @@ -3274,6 +3275,8 @@ type Query { getAiProviders: JSON! getModelsDevProviders: [ModelsDevProviderSuggestion!]! getModelsDevSuggestions(providerType: String!): [ModelsDevModelSuggestion!]! + getAdminAiUsageByWorkspace(periodStart: DateTime, periodEnd: DateTime): [UsageBreakdownItem!]! + getUsageAnalytics(input: UsageAnalyticsInput): UsageAnalytics! getPostgresCredentials: PostgresCredentials findManyPublicDomains: [PublicDomain!]! getEmailingDomains: [EmailingDomain!]! @@ -3281,7 +3284,6 @@ type Query { findOneMarketplaceApp(universalIdentifier: String!): MarketplaceApp! findManyApplications: [Application!]! findOneApplication(id: UUID, universalIdentifier: UUID): Application! - getUsageAnalytics(input: UsageAnalyticsInput): UsageAnalytics! } input GetApiKeyInput { @@ -3394,6 +3396,14 @@ input UsageAnalyticsInput { periodStart: DateTime periodEnd: DateTime userWorkspaceId: String + operationTypes: [UsageOperationType!] +} + +enum UsageOperationType { + AI_CHAT_TOKEN + AI_WORKFLOW_TOKEN + WORKFLOW_EXECUTION + CODE_EXECUTION } type Mutation { diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.ts b/packages/twenty-client-sdk/src/metadata/generated/schema.ts index 4ccb220e3d..57b0e4f1a5 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/schema.ts +++ b/packages/twenty-client-sdk/src/metadata/generated/schema.ts @@ -1460,6 +1460,13 @@ export interface ClientConfig { __typename: 'ClientConfig' } +export interface UsageBreakdownItem { + key: Scalars['String'] + label?: Scalars['String'] + creditsUsed: Scalars['Float'] + __typename: 'UsageBreakdownItem' +} + export interface ConfigVariable { name: Scalars['String'] description: Scalars['String'] @@ -2064,6 +2071,29 @@ export interface Impersonate { __typename: 'Impersonate' } +export interface UsageTimeSeries { + date: Scalars['String'] + creditsUsed: Scalars['Float'] + __typename: 'UsageTimeSeries' +} + +export interface UsageUserDaily { + userWorkspaceId: Scalars['String'] + dailyUsage: UsageTimeSeries[] + __typename: 'UsageUserDaily' +} + +export interface UsageAnalytics { + usageByUser: UsageBreakdownItem[] + usageByOperationType: UsageBreakdownItem[] + usageByModel: UsageBreakdownItem[] + timeSeries: UsageTimeSeries[] + periodStart: Scalars['DateTime'] + periodEnd: Scalars['DateTime'] + userDailyUsage?: UsageUserDaily + __typename: 'UsageAnalytics' +} + export interface DevelopmentApplication { id: Scalars['String'] universalIdentifier: Scalars['String'] @@ -2275,35 +2305,6 @@ export interface PostgresCredentials { __typename: 'PostgresCredentials' } -export interface UsageBreakdownItem { - key: Scalars['String'] - label?: Scalars['String'] - creditsUsed: Scalars['Float'] - __typename: 'UsageBreakdownItem' -} - -export interface UsageTimeSeries { - date: Scalars['String'] - creditsUsed: Scalars['Float'] - __typename: 'UsageTimeSeries' -} - -export interface UsageUserDaily { - userWorkspaceId: Scalars['String'] - dailyUsage: UsageTimeSeries[] - __typename: 'UsageUserDaily' -} - -export interface UsageAnalytics { - usageByUser: UsageBreakdownItem[] - usageByOperationType: UsageBreakdownItem[] - timeSeries: UsageTimeSeries[] - periodStart: Scalars['DateTime'] - periodEnd: Scalars['DateTime'] - userDailyUsage?: UsageUserDaily - __typename: 'UsageAnalytics' -} - export interface FrontComponent { id: Scalars['UUID'] name: Scalars['String'] @@ -2823,6 +2824,8 @@ export interface Query { getAiProviders: Scalars['JSON'] getModelsDevProviders: ModelsDevProviderSuggestion[] getModelsDevSuggestions: ModelsDevModelSuggestion[] + getAdminAiUsageByWorkspace: UsageBreakdownItem[] + getUsageAnalytics: UsageAnalytics getPostgresCredentials?: PostgresCredentials findManyPublicDomains: PublicDomain[] getEmailingDomains: EmailingDomain[] @@ -2830,7 +2833,6 @@ export interface Query { findOneMarketplaceApp: MarketplaceApp findManyApplications: Application[] findOneApplication: Application - getUsageAnalytics: UsageAnalytics __typename: 'Query' } @@ -2846,6 +2848,8 @@ export type SortNulls = 'NULLS_FIRST' | 'NULLS_LAST' export type EventLogTable = 'WORKSPACE_EVENT' | 'PAGEVIEW' | 'OBJECT_EVENT' | 'USAGE_EVENT' +export type UsageOperationType = 'AI_CHAT_TOKEN' | 'AI_WORKFLOW_TOKEN' | 'WORKFLOW_EXECUTION' | 'CODE_EXECUTION' + export interface Mutation { addQueryToEventStream: Scalars['Boolean'] removeQueryFromEventStream: Scalars['Boolean'] @@ -4585,6 +4589,14 @@ export interface ClientConfigGenqlSelection{ __scalar?: boolean | number } +export interface UsageBreakdownItemGenqlSelection{ + key?: boolean | number + label?: boolean | number + creditsUsed?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + export interface ConfigVariableGenqlSelection{ name?: boolean | number description?: boolean | number @@ -5246,6 +5258,32 @@ export interface ImpersonateGenqlSelection{ __scalar?: boolean | number } +export interface UsageTimeSeriesGenqlSelection{ + date?: boolean | number + creditsUsed?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface UsageUserDailyGenqlSelection{ + userWorkspaceId?: boolean | number + dailyUsage?: UsageTimeSeriesGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface UsageAnalyticsGenqlSelection{ + usageByUser?: UsageBreakdownItemGenqlSelection + usageByOperationType?: UsageBreakdownItemGenqlSelection + usageByModel?: UsageBreakdownItemGenqlSelection + timeSeries?: UsageTimeSeriesGenqlSelection + periodStart?: boolean | number + periodEnd?: boolean | number + userDailyUsage?: UsageUserDailyGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + export interface DevelopmentApplicationGenqlSelection{ id?: boolean | number universalIdentifier?: boolean | number @@ -5476,39 +5514,6 @@ export interface PostgresCredentialsGenqlSelection{ __scalar?: boolean | number } -export interface UsageBreakdownItemGenqlSelection{ - key?: boolean | number - label?: boolean | number - creditsUsed?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface UsageTimeSeriesGenqlSelection{ - date?: boolean | number - creditsUsed?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface UsageUserDailyGenqlSelection{ - userWorkspaceId?: boolean | number - dailyUsage?: UsageTimeSeriesGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface UsageAnalyticsGenqlSelection{ - usageByUser?: UsageBreakdownItemGenqlSelection - usageByOperationType?: UsageBreakdownItemGenqlSelection - timeSeries?: UsageTimeSeriesGenqlSelection - periodStart?: boolean | number - periodEnd?: boolean | number - userDailyUsage?: UsageUserDailyGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - export interface FrontComponentGenqlSelection{ id?: boolean | number name?: boolean | number @@ -6056,6 +6061,8 @@ export interface QueryGenqlSelection{ getAiProviders?: boolean | number getModelsDevProviders?: ModelsDevProviderSuggestionGenqlSelection getModelsDevSuggestions?: (ModelsDevModelSuggestionGenqlSelection & { __args: {providerType: Scalars['String']} }) + getAdminAiUsageByWorkspace?: (UsageBreakdownItemGenqlSelection & { __args?: {periodStart?: (Scalars['DateTime'] | null), periodEnd?: (Scalars['DateTime'] | null)} }) + getUsageAnalytics?: (UsageAnalyticsGenqlSelection & { __args?: {input?: (UsageAnalyticsInput | null)} }) getPostgresCredentials?: PostgresCredentialsGenqlSelection findManyPublicDomains?: PublicDomainGenqlSelection getEmailingDomains?: EmailingDomainGenqlSelection @@ -6063,7 +6070,6 @@ export interface QueryGenqlSelection{ findOneMarketplaceApp?: (MarketplaceAppGenqlSelection & { __args: {universalIdentifier: Scalars['String']} }) findManyApplications?: ApplicationGenqlSelection findOneApplication?: (ApplicationGenqlSelection & { __args?: {id?: (Scalars['UUID'] | null), universalIdentifier?: (Scalars['UUID'] | null)} }) - getUsageAnalytics?: (UsageAnalyticsGenqlSelection & { __args?: {input?: (UsageAnalyticsInput | null)} }) __typename?: boolean | number __scalar?: boolean | number } @@ -6098,7 +6104,7 @@ export interface LineChartDataInput {objectMetadataId: Scalars['UUID'],configura export interface BarChartDataInput {objectMetadataId: Scalars['UUID'],configuration: Scalars['JSON']} -export interface UsageAnalyticsInput {periodStart?: (Scalars['DateTime'] | null),periodEnd?: (Scalars['DateTime'] | null),userWorkspaceId?: (Scalars['String'] | null)} +export interface UsageAnalyticsInput {periodStart?: (Scalars['DateTime'] | null),periodEnd?: (Scalars['DateTime'] | null),userWorkspaceId?: (Scalars['String'] | null),operationTypes?: (UsageOperationType[] | null)} export interface MutationGenqlSelection{ addQueryToEventStream?: { __args: {input: AddQuerySubscriptionInput} } @@ -7593,6 +7599,14 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null + const UsageBreakdownItem_possibleTypes: string[] = ['UsageBreakdownItem'] + export const isUsageBreakdownItem = (obj?: { __typename?: any } | null): obj is UsageBreakdownItem => { + if (!obj?.__typename) throw new Error('__typename is missing in "isUsageBreakdownItem"') + return UsageBreakdownItem_possibleTypes.includes(obj.__typename) + } + + + const ConfigVariable_possibleTypes: string[] = ['ConfigVariable'] export const isConfigVariable = (obj?: { __typename?: any } | null): obj is ConfigVariable => { if (!obj?.__typename) throw new Error('__typename is missing in "isConfigVariable"') @@ -8225,6 +8239,30 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null + const UsageTimeSeries_possibleTypes: string[] = ['UsageTimeSeries'] + export const isUsageTimeSeries = (obj?: { __typename?: any } | null): obj is UsageTimeSeries => { + if (!obj?.__typename) throw new Error('__typename is missing in "isUsageTimeSeries"') + return UsageTimeSeries_possibleTypes.includes(obj.__typename) + } + + + + const UsageUserDaily_possibleTypes: string[] = ['UsageUserDaily'] + export const isUsageUserDaily = (obj?: { __typename?: any } | null): obj is UsageUserDaily => { + if (!obj?.__typename) throw new Error('__typename is missing in "isUsageUserDaily"') + return UsageUserDaily_possibleTypes.includes(obj.__typename) + } + + + + const UsageAnalytics_possibleTypes: string[] = ['UsageAnalytics'] + export const isUsageAnalytics = (obj?: { __typename?: any } | null): obj is UsageAnalytics => { + if (!obj?.__typename) throw new Error('__typename is missing in "isUsageAnalytics"') + return UsageAnalytics_possibleTypes.includes(obj.__typename) + } + + + const DevelopmentApplication_possibleTypes: string[] = ['DevelopmentApplication'] export const isDevelopmentApplication = (obj?: { __typename?: any } | null): obj is DevelopmentApplication => { if (!obj?.__typename) throw new Error('__typename is missing in "isDevelopmentApplication"') @@ -8409,38 +8447,6 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null - const UsageBreakdownItem_possibleTypes: string[] = ['UsageBreakdownItem'] - export const isUsageBreakdownItem = (obj?: { __typename?: any } | null): obj is UsageBreakdownItem => { - if (!obj?.__typename) throw new Error('__typename is missing in "isUsageBreakdownItem"') - return UsageBreakdownItem_possibleTypes.includes(obj.__typename) - } - - - - const UsageTimeSeries_possibleTypes: string[] = ['UsageTimeSeries'] - export const isUsageTimeSeries = (obj?: { __typename?: any } | null): obj is UsageTimeSeries => { - if (!obj?.__typename) throw new Error('__typename is missing in "isUsageTimeSeries"') - return UsageTimeSeries_possibleTypes.includes(obj.__typename) - } - - - - const UsageUserDaily_possibleTypes: string[] = ['UsageUserDaily'] - export const isUsageUserDaily = (obj?: { __typename?: any } | null): obj is UsageUserDaily => { - if (!obj?.__typename) throw new Error('__typename is missing in "isUsageUserDaily"') - return UsageUserDaily_possibleTypes.includes(obj.__typename) - } - - - - const UsageAnalytics_possibleTypes: string[] = ['UsageAnalytics'] - export const isUsageAnalytics = (obj?: { __typename?: any } | null): obj is UsageAnalytics => { - if (!obj?.__typename) throw new Error('__typename is missing in "isUsageAnalytics"') - return UsageAnalytics_possibleTypes.includes(obj.__typename) - } - - - const FrontComponent_possibleTypes: string[] = ['FrontComponent'] export const isFrontComponent = (obj?: { __typename?: any } | null): obj is FrontComponent => { if (!obj?.__typename) throw new Error('__typename is missing in "isFrontComponent"') @@ -9455,6 +9461,13 @@ export const enumEventLogTable = { USAGE_EVENT: 'USAGE_EVENT' as const } +export const enumUsageOperationType = { + AI_CHAT_TOKEN: 'AI_CHAT_TOKEN' as const, + AI_WORKFLOW_TOKEN: 'AI_WORKFLOW_TOKEN' as const, + WORKFLOW_EXECUTION: 'WORKFLOW_EXECUTION' as const, + CODE_EXECUTION: 'CODE_EXECUTION' as const +} + export const enumAnalyticsType = { PAGEVIEW: 'PAGEVIEW' as const, TRACK: 'TRACK' as const diff --git a/packages/twenty-client-sdk/src/metadata/generated/types.ts b/packages/twenty-client-sdk/src/metadata/generated/types.ts index 9547787a6b..577440f629 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/types.ts +++ b/packages/twenty-client-sdk/src/metadata/generated/types.ts @@ -54,17 +54,17 @@ export default { 171, 174, 178, - 181, 182, - 184, - 189, - 194, + 183, + 185, + 190, 195, - 210, - 227, - 244, - 283, - 284, + 196, + 211, + 228, + 245, + 287, + 288, 299, 300, 325, @@ -85,11 +85,12 @@ export default { 356, 357, 359, - 372, - 398, - 482, - 487, - 488 + 366, + 373, + 399, + 483, + 488, + 489 ], "types": { "BillingProductDTO": { @@ -796,10 +797,10 @@ export default { 3 ], "relation": [ - 243 + 244 ], "morphRelations": [ - 243 + 244 ], "object": [ 46 @@ -858,7 +859,7 @@ export default { 36 ], "objectMetadata": [ - 236, + 237, { "paging": [ 39, @@ -871,7 +872,7 @@ export default { } ], "indexFieldMetadatas": [ - 234, + 235, { "paging": [ 39, @@ -1116,7 +1117,7 @@ export default { 37 ], "fields": [ - 241, + 242, { "paging": [ 39, @@ -1129,7 +1130,7 @@ export default { } ], "indexMetadatas": [ - 239, + 240, { "paging": [ 39, @@ -1701,7 +1702,7 @@ export default { 49 ], "featureFlags": [ - 197 + 198 ], "billingSubscriptions": [ 130 @@ -1710,7 +1711,7 @@ export default { 130 ], "billingEntitlements": [ - 226 + 227 ], "hasValidEnterpriseKey": [ 6 @@ -1814,7 +1815,7 @@ export default { 20 ], "deletedWorkspaceMembers": [ - 225 + 226 ], "hasPassword": [ 6 @@ -1826,7 +1827,7 @@ export default { 17 ], "availableWorkspaces": [ - 224 + 225 ], "__typename": [ 1 @@ -3564,6 +3565,20 @@ export default { 1 ] }, + "UsageBreakdownItem": { + "key": [ + 1 + ], + "label": [ + 1 + ], + "creditsUsed": [ + 11 + ], + "__typename": [ + 1 + ] + }, "ConfigVariable": { "name": [ 1 @@ -3578,13 +3593,13 @@ export default { 6 ], "source": [ - 181 + 182 ], "isEnvOnly": [ 6 ], "type": [ - 182 + 183 ], "options": [ 15 @@ -3597,10 +3612,10 @@ export default { "ConfigVariableType": {}, "ConfigVariablesGroupData": { "variables": [ - 180 + 181 ], "name": [ - 184 + 185 ], "description": [ 1 @@ -3615,7 +3630,7 @@ export default { "ConfigVariablesGroup": {}, "ConfigVariables": { "groups": [ - 183 + 184 ], "__typename": [ 1 @@ -3640,7 +3655,7 @@ export default { 21 ], "results": [ - 186 + 187 ], "__typename": [ 1 @@ -3657,7 +3672,7 @@ export default { 15 ], "state": [ - 189 + 190 ], "timestamp": [ 11 @@ -3707,7 +3722,7 @@ export default { }, "QueueJobsResponse": { "jobs": [ - 188 + 189 ], "count": [ 11 @@ -3719,7 +3734,7 @@ export default { 6 ], "retentionConfig": [ - 190 + 191 ], "__typename": [ 1 @@ -3730,7 +3745,7 @@ export default { 21 ], "results": [ - 186 + 187 ], "__typename": [ 1 @@ -3738,13 +3753,13 @@ export default { }, "SystemHealthService": { "id": [ - 194 + 195 ], "label": [ 1 ], "status": [ - 195 + 196 ], "__typename": [ 1 @@ -3754,7 +3769,7 @@ export default { "AdminPanelHealthServiceStatus": {}, "SystemHealth": { "services": [ - 193 + 194 ], "__typename": [ 1 @@ -3808,10 +3823,10 @@ export default { 157 ], "users": [ - 198 + 199 ], "featureFlags": [ - 197 + 198 ], "__typename": [ 1 @@ -3819,10 +3834,10 @@ export default { }, "UserLookup": { "user": [ - 198 + 199 ], "workspaces": [ - 199 + 200 ], "__typename": [ 1 @@ -3847,7 +3862,7 @@ export default { 1 ], "status": [ - 195 + 196 ], "__typename": [ 1 @@ -3855,7 +3870,7 @@ export default { }, "AdminPanelHealthServiceData": { "id": [ - 194 + 195 ], "label": [ 1 @@ -3864,7 +3879,7 @@ export default { 1 ], "status": [ - 195 + 196 ], "errorMessage": [ 1 @@ -3873,7 +3888,7 @@ export default { 1 ], "queues": [ - 202 + 203 ], "__typename": [ 1 @@ -3944,7 +3959,7 @@ export default { 1 ], "data": [ - 206 + 207 ], "__typename": [ 1 @@ -3987,13 +4002,13 @@ export default { 11 ], "timeRange": [ - 210 + 211 ], "details": [ - 208 + 209 ], "data": [ - 207 + 208 ], "__typename": [ 1 @@ -4019,7 +4034,7 @@ export default { 1 ], "versionDistribution": [ - 211 + 212 ], "__typename": [ 1 @@ -4128,7 +4143,7 @@ export default { 160 ], "workspace": [ - 219 + 220 ], "__typename": [ 1 @@ -4197,7 +4212,7 @@ export default { 1 ], "sso": [ - 222 + 223 ], "__typename": [ 1 @@ -4205,10 +4220,10 @@ export default { }, "AvailableWorkspaces": { "availableWorkspacesForSignIn": [ - 223 + 224 ], "availableWorkspacesForSignUp": [ - 223 + 224 ], "__typename": [ 1 @@ -4236,7 +4251,7 @@ export default { }, "BillingEntitlement": { "key": [ - 227 + 228 ], "value": [ 6 @@ -4274,7 +4289,7 @@ export default { 1 ], "records": [ - 228 + 229 ], "__typename": [ 1 @@ -4310,10 +4325,10 @@ export default { }, "IndexConnection": { "pageInfo": [ - 231 + 232 ], "edges": [ - 230 + 231 ], "__typename": [ 1 @@ -4332,10 +4347,10 @@ export default { }, "IndexIndexFieldMetadatasConnection": { "pageInfo": [ - 231 + 232 ], "edges": [ - 233 + 234 ], "__typename": [ 1 @@ -4354,10 +4369,10 @@ export default { }, "IndexObjectMetadataConnection": { "pageInfo": [ - 231 + 232 ], "edges": [ - 235 + 236 ], "__typename": [ 1 @@ -4376,10 +4391,10 @@ export default { }, "ObjectConnection": { "pageInfo": [ - 231 + 232 ], "edges": [ - 235 + 236 ], "__typename": [ 1 @@ -4387,10 +4402,10 @@ export default { }, "ObjectIndexMetadatasConnection": { "pageInfo": [ - 231 + 232 ], "edges": [ - 230 + 231 ], "__typename": [ 1 @@ -4409,10 +4424,10 @@ export default { }, "ObjectFieldsConnection": { "pageInfo": [ - 231 + 232 ], "edges": [ - 240 + 241 ], "__typename": [ 1 @@ -4431,7 +4446,7 @@ export default { }, "Relation": { "type": [ - 244 + 245 ], "sourceObjectMetadata": [ 46 @@ -4452,10 +4467,10 @@ export default { "RelationType": {}, "FieldConnection": { "pageInfo": [ - 231 + 232 ], "edges": [ - 240 + 241 ], "__typename": [ 1 @@ -4514,10 +4529,10 @@ export default { }, "AuthTokenPair": { "accessOrWorkspaceAgnosticToken": [ - 251 + 252 ], "refreshToken": [ - 251 + 252 ], "__typename": [ 1 @@ -4525,10 +4540,10 @@ export default { }, "AvailableWorkspacesAndAccessTokens": { "tokens": [ - 252 + 253 ], "availableWorkspaces": [ - 224 + 225 ], "__typename": [ 1 @@ -4577,10 +4592,10 @@ export default { }, "SignUp": { "loginToken": [ - 251 + 252 ], "workspace": [ - 257 + 258 ], "__typename": [ 1 @@ -4588,7 +4603,7 @@ export default { }, "TransientToken": { "transientToken": [ - 251 + 252 ], "__typename": [ 1 @@ -4610,7 +4625,7 @@ export default { }, "VerifyEmailAndGetLoginToken": { "loginToken": [ - 251 + 252 ], "workspaceUrls": [ 157 @@ -4629,7 +4644,7 @@ export default { }, "AuthTokens": { "tokens": [ - 252 + 253 ], "__typename": [ 1 @@ -4637,7 +4652,7 @@ export default { }, "LoginToken": { "loginToken": [ - 251 + 252 ], "__typename": [ 1 @@ -4667,10 +4682,58 @@ export default { }, "Impersonate": { "loginToken": [ - 251 + 252 ], "workspace": [ - 257 + 258 + ], + "__typename": [ + 1 + ] + }, + "UsageTimeSeries": { + "date": [ + 1 + ], + "creditsUsed": [ + 11 + ], + "__typename": [ + 1 + ] + }, + "UsageUserDaily": { + "userWorkspaceId": [ + 1 + ], + "dailyUsage": [ + 269 + ], + "__typename": [ + 1 + ] + }, + "UsageAnalytics": { + "usageByUser": [ + 180 + ], + "usageByOperationType": [ + 180 + ], + "usageByModel": [ + 180 + ], + "timeSeries": [ + 269 + ], + "periodStart": [ + 4 + ], + "periodEnd": [ + 4 + ], + "userDailyUsage": [ + 270 ], "__typename": [ 1 @@ -4700,10 +4763,10 @@ export default { }, "ApplicationTokenPair": { "applicationAccessToken": [ - 251 + 252 ], "applicationRefreshToken": [ - 251 + 252 ], "__typename": [ 1 @@ -4775,7 +4838,7 @@ export default { 1 ], "fields": [ - 272 + 276 ], "__typename": [ 1 @@ -4872,10 +4935,10 @@ export default { 6 ], "objectPermissions": [ - 276 + 280 ], "fieldPermissions": [ - 277 + 281 ], "permissionFlags": [ 1 @@ -4925,19 +4988,19 @@ export default { 1 ], "objects": [ - 273 + 277 ], "fields": [ - 272 + 276 ], "logicFunctions": [ - 274 + 278 ], "frontComponents": [ - 275 + 279 ], "defaultRole": [ - 278 + 282 ], "sourcePackage": [ 1 @@ -4997,13 +5060,13 @@ export default { 1 ], "driver": [ - 283 + 287 ], "status": [ - 284 + 288 ], "verificationRecords": [ - 281 + 285 ], "verifiedAt": [ 4 @@ -5050,7 +5113,7 @@ export default { 1 ], "location": [ - 286 + 290 ], "__typename": [ 1 @@ -5078,13 +5141,13 @@ export default { }, "ImapSmtpCaldavConnectionParameters": { "IMAP": [ - 288 + 292 ], "SMTP": [ - 288 + 292 ], "CALDAV": [ - 288 + 292 ], "__typename": [ 1 @@ -5104,7 +5167,7 @@ export default { 3 ], "connectionParameters": [ - 289 + 293 ], "__typename": [ 1 @@ -5138,65 +5201,6 @@ export default { 1 ] }, - "UsageBreakdownItem": { - "key": [ - 1 - ], - "label": [ - 1 - ], - "creditsUsed": [ - 11 - ], - "__typename": [ - 1 - ] - }, - "UsageTimeSeries": { - "date": [ - 1 - ], - "creditsUsed": [ - 11 - ], - "__typename": [ - 1 - ] - }, - "UsageUserDaily": { - "userWorkspaceId": [ - 1 - ], - "dailyUsage": [ - 294 - ], - "__typename": [ - 1 - ] - }, - "UsageAnalytics": { - "usageByUser": [ - 293 - ], - "usageByOperationType": [ - 293 - ], - "timeSeries": [ - 294 - ], - "periodStart": [ - 4 - ], - "periodEnd": [ - 4 - ], - "userDailyUsage": [ - 295 - ], - "__typename": [ - 1 - ] - }, "FrontComponent": { "id": [ 3 @@ -5238,7 +5242,7 @@ export default { 6 ], "applicationTokenPair": [ - 270 + 274 ], "__typename": [ 1 @@ -5761,7 +5765,7 @@ export default { }, "AgentChatThreadConnection": { "pageInfo": [ - 231 + 232 ], "edges": [ 320 @@ -6388,7 +6392,7 @@ export default { } ], "objectRecordCounts": [ - 237 + 238 ], "object": [ 46, @@ -6400,7 +6404,7 @@ export default { } ], "objects": [ - 238, + 239, { "paging": [ 39, @@ -6440,7 +6444,7 @@ export default { } ], "indexMetadatas": [ - 232, + 233, { "paging": [ 39, @@ -6489,7 +6493,7 @@ export default { } ], "fields": [ - 245, + 246, { "paging": [ 39, @@ -6659,7 +6663,7 @@ export default { } ], "checkUserExists": [ - 265, + 266, { "email": [ 1, @@ -6671,7 +6675,7 @@ export default { } ], "checkWorkspaceInviteHashIsValid": [ - 266, + 267, { "inviteHash": [ 1, @@ -6689,7 +6693,7 @@ export default { } ], "validatePasswordResetToken": [ - 260, + 261, { "passwordResetToken": [ 1, @@ -6698,7 +6702,7 @@ export default { } ], "findApplicationRegistrationByClientId": [ - 214, + 215, { "clientId": [ 1, @@ -6728,7 +6732,7 @@ export default { } ], "findApplicationRegistrationStats": [ - 212, + 213, { "id": [ 1, @@ -6769,10 +6773,10 @@ export default { } ], "getSSOIdentityProviders": [ - 220 + 221 ], "getConnectedImapSmtpCaldavAccount": [ - 290, + 294, { "id": [ 3, @@ -6781,7 +6785,7 @@ export default { } ], "getAutoCompleteAddress": [ - 285, + 289, { "address": [ 1, @@ -6800,7 +6804,7 @@ export default { } ], "getAddressDetails": [ - 287, + 291, { "placeId": [ 1, @@ -6813,40 +6817,40 @@ export default { } ], "getConfigVariablesGrouped": [ - 185 + 186 ], "getSystemHealthStatus": [ - 196 + 197 ], "getIndicatorHealthStatus": [ - 203, + 204, { "indicatorId": [ - 194, + 195, "HealthIndicatorId!" ] } ], "getQueueMetrics": [ - 209, + 210, { "queueName": [ 1, "String!" ], "timeRange": [ - 210 + 211 ] } ], "versionInfo": [ - 201 + 202 ], "getAdminAiModels": [ 168 ], "getDatabaseConfigVariable": [ - 180, + 181, { "key": [ 1, @@ -6855,14 +6859,14 @@ export default { } ], "getQueueJobs": [ - 191, + 192, { "queueName": [ 1, "String!" ], "state": [ - 189, + 190, "JobState!" ], "limit": [ @@ -6880,10 +6884,10 @@ export default { 15 ], "getModelsDevProviders": [ - 205 + 206 ], "getModelsDevSuggestions": [ - 204, + 205, { "providerType": [ 1, @@ -6891,20 +6895,39 @@ export default { ] } ], + "getAdminAiUsageByWorkspace": [ + 180, + { + "periodStart": [ + 4 + ], + "periodEnd": [ + 4 + ] + } + ], + "getUsageAnalytics": [ + 271, + { + "input": [ + 365 + ] + } + ], "getPostgresCredentials": [ - 292 + 296 ], "findManyPublicDomains": [ - 280 + 284 ], "getEmailingDomains": [ - 282 + 286 ], "findManyMarketplaceApps": [ - 279 + 283 ], "findOneMarketplaceApp": [ - 279, + 283, { "universalIdentifier": [ 1, @@ -6926,14 +6949,6 @@ export default { ] } ], - "getUsageAnalytics": [ - 296, - { - "input": [ - 365 - ] - } - ], "__typename": [ 1 ] @@ -7141,16 +7156,20 @@ export default { "userWorkspaceId": [ 1 ], + "operationTypes": [ + 366 + ], "__typename": [ 1 ] }, + "UsageOperationType": {}, "Mutation": { "addQueryToEventStream": [ 6, { "input": [ - 367, + 368, "AddQuerySubscriptionInput!" ] } @@ -7159,7 +7178,7 @@ export default { 6, { "input": [ - 368, + 369, "RemoveQueryFromEventStreamInput!" ] } @@ -7168,7 +7187,7 @@ export default { 145, { "inputs": [ - 369, + 370, "[CreateNavigationMenuItemInput!]!" ] } @@ -7177,7 +7196,7 @@ export default { 145, { "input": [ - 369, + 370, "CreateNavigationMenuItemInput!" ] } @@ -7186,7 +7205,7 @@ export default { 145, { "inputs": [ - 370, + 371, "[UpdateOneNavigationMenuItemInput!]!" ] } @@ -7195,7 +7214,7 @@ export default { 145, { "input": [ - 370, + 371, "UpdateOneNavigationMenuItemInput!" ] } @@ -7222,7 +7241,7 @@ export default { 141, { "file": [ - 372, + 373, "Upload!" ] } @@ -7231,7 +7250,7 @@ export default { 141, { "file": [ - 372, + 373, "Upload!" ] } @@ -7240,7 +7259,7 @@ export default { 141, { "file": [ - 372, + 373, "Upload!" ] } @@ -7249,7 +7268,7 @@ export default { 141, { "file": [ - 372, + 373, "Upload!" ] } @@ -7258,7 +7277,7 @@ export default { 141, { "file": [ - 372, + 373, "Upload!" ], "fieldMetadataId": [ @@ -7271,7 +7290,7 @@ export default { 141, { "file": [ - 372, + 373, "Upload!" ], "fieldMetadataUniversalIdentifier": [ @@ -7284,7 +7303,7 @@ export default { 52, { "input": [ - 373, + 374, "CreateViewFilterGroupInput!" ] } @@ -7297,7 +7316,7 @@ export default { "String!" ], "input": [ - 374, + 375, "UpdateViewFilterGroupInput!" ] } @@ -7324,7 +7343,7 @@ export default { 54, { "input": [ - 375, + 376, "CreateViewFilterInput!" ] } @@ -7333,7 +7352,7 @@ export default { 54, { "input": [ - 376, + 377, "UpdateViewFilterInput!" ] } @@ -7342,7 +7361,7 @@ export default { 54, { "input": [ - 378, + 379, "DeleteViewFilterInput!" ] } @@ -7351,7 +7370,7 @@ export default { 54, { "input": [ - 379, + 380, "DestroyViewFilterInput!" ] } @@ -7360,7 +7379,7 @@ export default { 60, { "input": [ - 380, + 381, "CreateViewInput!" ] } @@ -7373,7 +7392,7 @@ export default { "String!" ], "input": [ - 381, + 382, "UpdateViewInput!" ] } @@ -7400,7 +7419,7 @@ export default { 57, { "input": [ - 382, + 383, "CreateViewSortInput!" ] } @@ -7409,7 +7428,7 @@ export default { 57, { "input": [ - 383, + 384, "UpdateViewSortInput!" ] } @@ -7418,7 +7437,7 @@ export default { 6, { "input": [ - 385, + 386, "DeleteViewSortInput!" ] } @@ -7427,7 +7446,7 @@ export default { 6, { "input": [ - 386, + 387, "DestroyViewSortInput!" ] } @@ -7436,7 +7455,7 @@ export default { 59, { "input": [ - 387, + 388, "UpdateViewFieldGroupInput!" ] } @@ -7445,7 +7464,7 @@ export default { 59, { "input": [ - 389, + 390, "CreateViewFieldGroupInput!" ] } @@ -7454,7 +7473,7 @@ export default { 59, { "inputs": [ - 389, + 390, "[CreateViewFieldGroupInput!]!" ] } @@ -7463,7 +7482,7 @@ export default { 59, { "input": [ - 390, + 391, "DeleteViewFieldGroupInput!" ] } @@ -7472,7 +7491,7 @@ export default { 59, { "input": [ - 391, + 392, "DestroyViewFieldGroupInput!" ] } @@ -7481,7 +7500,7 @@ export default { 60, { "input": [ - 392, + 393, "UpsertFieldsWidgetInput!" ] } @@ -7490,7 +7509,7 @@ export default { 2, { "input": [ - 395, + 396, "CreateApiKeyInput!" ] } @@ -7499,7 +7518,7 @@ export default { 2, { "input": [ - 396, + 397, "UpdateApiKeyInput!" ] } @@ -7508,7 +7527,7 @@ export default { 2, { "input": [ - 397, + 398, "RevokeApiKeyInput!" ] } @@ -7550,7 +7569,7 @@ export default { 115, { "type": [ - 398, + 399, "AnalyticsType!" ], "name": [ @@ -7663,7 +7682,7 @@ export default { 140, { "input": [ - 399, + 400, "CreateApprovedAccessDomainInput!" ] } @@ -7672,7 +7691,7 @@ export default { 6, { "input": [ - 400, + 401, "DeleteApprovedAccessDomainInput!" ] } @@ -7681,7 +7700,7 @@ export default { 140, { "input": [ - 401, + 402, "ValidateApprovedAccessDomainInput!" ] } @@ -7690,7 +7709,7 @@ export default { 112, { "input": [ - 402, + 403, "CreatePageLayoutTabInput!" ] } @@ -7703,7 +7722,7 @@ export default { "String!" ], "input": [ - 403, + 404, "UpdatePageLayoutTabInput!" ] } @@ -7721,7 +7740,7 @@ export default { 113, { "input": [ - 404, + 405, "CreatePageLayoutInput!" ] } @@ -7734,7 +7753,7 @@ export default { "String!" ], "input": [ - 405, + 406, "UpdatePageLayoutInput!" ] } @@ -7756,7 +7775,7 @@ export default { "String!" ], "input": [ - 406, + 407, "UpdatePageLayoutWithTabsInput!" ] } @@ -7765,7 +7784,7 @@ export default { 75, { "input": [ - 410, + 411, "CreatePageLayoutWidgetInput!" ] } @@ -7778,7 +7797,7 @@ export default { "String!" ], "input": [ - 411, + 412, "UpdatePageLayoutWidgetInput!" ] } @@ -7805,7 +7824,7 @@ export default { 32, { "input": [ - 412, + 413, "CreateLogicFunctionFromSourceInput!" ] } @@ -7814,7 +7833,7 @@ export default { 154, { "input": [ - 413, + 414, "ExecuteOneLogicFunctionInput!" ] } @@ -7823,7 +7842,7 @@ export default { 6, { "input": [ - 414, + 415, "UpdateLogicFunctionFromSourceInput!" ] } @@ -7832,7 +7851,7 @@ export default { 298, { "input": [ - 416, + 417, "CreateCommandMenuItemInput!" ] } @@ -7841,7 +7860,7 @@ export default { 298, { "input": [ - 417, + 418, "UpdateCommandMenuItemInput!" ] } @@ -7859,7 +7878,7 @@ export default { 297, { "input": [ - 418, + 419, "CreateFrontComponentInput!" ] } @@ -7868,7 +7887,7 @@ export default { 297, { "input": [ - 419, + 420, "UpdateFrontComponentInput!" ] } @@ -7886,7 +7905,7 @@ export default { 46, { "input": [ - 421, + 422, "CreateOneObjectInput!" ] } @@ -7895,7 +7914,7 @@ export default { 46, { "input": [ - 423, + 424, "DeleteOneObjectInput!" ] } @@ -7904,7 +7923,7 @@ export default { 46, { "input": [ - 424, + 425, "UpdateOneObjectInput!" ] } @@ -7913,7 +7932,7 @@ export default { 50, { "input": [ - 426, + 427, "UpdateViewFieldInput!" ] } @@ -7922,7 +7941,7 @@ export default { 50, { "input": [ - 428, + 429, "CreateViewFieldInput!" ] } @@ -7931,7 +7950,7 @@ export default { 50, { "inputs": [ - 428, + 429, "[CreateViewFieldInput!]!" ] } @@ -7940,7 +7959,7 @@ export default { 50, { "input": [ - 429, + 430, "DeleteViewFieldInput!" ] } @@ -7949,7 +7968,7 @@ export default { 50, { "input": [ - 430, + 431, "DestroyViewFieldInput!" ] } @@ -7958,7 +7977,7 @@ export default { 25, { "input": [ - 431, + 432, "CreateAgentInput!" ] } @@ -7967,7 +7986,7 @@ export default { 25, { "input": [ - 432, + 433, "UpdateAgentInput!" ] } @@ -7998,7 +8017,7 @@ export default { 29, { "createRoleInput": [ - 433, + 434, "CreateRoleInput!" ] } @@ -8007,7 +8026,7 @@ export default { 29, { "updateRoleInput": [ - 434, + 435, "UpdateRoleInput!" ] } @@ -8025,7 +8044,7 @@ export default { 16, { "upsertObjectPermissionsInput": [ - 436, + 437, "UpsertObjectPermissionsInput!" ] } @@ -8034,7 +8053,7 @@ export default { 27, { "upsertPermissionFlagsInput": [ - 438, + 439, "UpsertPermissionFlagsInput!" ] } @@ -8043,16 +8062,16 @@ export default { 26, { "upsertFieldPermissionsInput": [ - 439, + 440, "UpsertFieldPermissionsInput!" ] } ], "upsertRowLevelPermissionPredicates": [ - 242, + 243, { "input": [ - 441, + 442, "UpsertRowLevelPermissionPredicatesInput!" ] } @@ -8083,7 +8102,7 @@ export default { 34, { "input": [ - 444, + 445, "CreateOneFieldMetadataInput!" ] } @@ -8092,7 +8111,7 @@ export default { 34, { "input": [ - 446, + 447, "UpdateOneFieldMetadataInput!" ] } @@ -8101,7 +8120,7 @@ export default { 34, { "input": [ - 448, + 449, "DeleteOneFieldInput!" ] } @@ -8110,7 +8129,7 @@ export default { 56, { "input": [ - 449, + 450, "CreateViewGroupInput!" ] } @@ -8119,7 +8138,7 @@ export default { 56, { "inputs": [ - 449, + 450, "[CreateViewGroupInput!]!" ] } @@ -8128,7 +8147,7 @@ export default { 56, { "input": [ - 450, + 451, "UpdateViewGroupInput!" ] } @@ -8137,7 +8156,7 @@ export default { 56, { "inputs": [ - 450, + 451, "[UpdateViewGroupInput!]!" ] } @@ -8146,7 +8165,7 @@ export default { 56, { "input": [ - 452, + 453, "DeleteViewGroupInput!" ] } @@ -8155,7 +8174,7 @@ export default { 56, { "input": [ - 453, + 454, "DestroyViewGroupInput!" ] } @@ -8164,7 +8183,7 @@ export default { 338, { "input": [ - 454, + 455, "UpdateMessageFolderInput!" ] } @@ -8173,7 +8192,7 @@ export default { 338, { "input": [ - 456, + 457, "UpdateMessageFoldersInput!" ] } @@ -8182,7 +8201,7 @@ export default { 330, { "input": [ - 457, + 458, "UpdateMessageChannelInput!" ] } @@ -8200,7 +8219,7 @@ export default { 324, { "input": [ - 459, + 460, "UpdateCalendarChannelInput!" ] } @@ -8209,7 +8228,7 @@ export default { 345, { "input": [ - 461, + 462, "CreateWebhookInput!" ] } @@ -8218,7 +8237,7 @@ export default { 345, { "input": [ - 462, + 463, "UpdateWebhookInput!" ] } @@ -8239,7 +8258,7 @@ export default { 315, { "input": [ - 464, + 465, "CreateSkillInput!" ] } @@ -8248,7 +8267,7 @@ export default { 315, { "input": [ - 465, + 466, "UpdateSkillInput!" ] } @@ -8312,16 +8331,16 @@ export default { } ], "getAuthorizationUrlForSSO": [ - 255, + 256, { "input": [ - 466, + 467, "GetAuthorizationUrlForSSOInput!" ] } ], "getLoginTokenFromCredentials": [ - 264, + 265, { "email": [ 1, @@ -8347,7 +8366,7 @@ export default { } ], "signIn": [ - 253, + 254, { "email": [ 1, @@ -8369,7 +8388,7 @@ export default { } ], "verifyEmailAndGetLoginToken": [ - 261, + 262, { "emailVerificationToken": [ 1, @@ -8389,7 +8408,7 @@ export default { } ], "verifyEmailAndGetWorkspaceAgnosticToken": [ - 253, + 254, { "emailVerificationToken": [ 1, @@ -8405,7 +8424,7 @@ export default { } ], "getAuthTokensFromOTP": [ - 263, + 264, { "otp": [ 1, @@ -8425,7 +8444,7 @@ export default { } ], "signUp": [ - 253, + 254, { "email": [ 1, @@ -8447,7 +8466,7 @@ export default { } ], "signUpInWorkspace": [ - 258, + 259, { "email": [ 1, @@ -8478,13 +8497,13 @@ export default { } ], "signUpInNewWorkspace": [ - 258 - ], - "generateTransientToken": [ 259 ], + "generateTransientToken": [ + 260 + ], "getAuthTokensFromLoginToken": [ - 263, + 264, { "loginToken": [ 1, @@ -8497,7 +8516,7 @@ export default { } ], "authorizeApp": [ - 250, + 251, { "clientId": [ 1, @@ -8519,7 +8538,7 @@ export default { } ], "renewToken": [ - 263, + 264, { "appToken": [ 1, @@ -8528,7 +8547,7 @@ export default { } ], "generateApiKeyToken": [ - 262, + 263, { "apiKeyId": [ 3, @@ -8541,7 +8560,7 @@ export default { } ], "emailPasswordResetLink": [ - 254, + 255, { "email": [ 1, @@ -8553,7 +8572,7 @@ export default { } ], "updatePasswordViaResetToken": [ - 256, + 257, { "passwordResetToken": [ 1, @@ -8566,10 +8585,10 @@ export default { } ], "createApplicationRegistration": [ - 213, + 214, { "input": [ - 467, + 468, "CreateApplicationRegistrationInput!" ] } @@ -8578,7 +8597,7 @@ export default { 7, { "input": [ - 468, + 469, "UpdateApplicationRegistrationInput!" ] } @@ -8593,7 +8612,7 @@ export default { } ], "rotateApplicationRegistrationClientSecret": [ - 215, + 216, { "id": [ 1, @@ -8605,7 +8624,7 @@ export default { 5, { "input": [ - 470, + 471, "CreateApplicationRegistrationVariableInput!" ] } @@ -8614,7 +8633,7 @@ export default { 5, { "input": [ - 471, + 472, "UpdateApplicationRegistrationVariableInput!" ] } @@ -8632,7 +8651,7 @@ export default { 7, { "file": [ - 372, + 373, "Upload!" ], "universalIdentifier": [ @@ -8654,7 +8673,7 @@ export default { } ], "initiateOTPProvisioning": [ - 248, + 249, { "loginToken": [ 1, @@ -8667,10 +8686,10 @@ export default { } ], "initiateOTPProvisioningForAuthenticatedUser": [ - 248 + 249 ], "deleteTwoFactorAuthenticationMethod": [ - 247, + 248, { "twoFactorAuthenticationMethodId": [ 3, @@ -8679,7 +8698,7 @@ export default { } ], "verifyTwoFactorAuthenticationMethodForAuthenticatedUser": [ - 249, + 250, { "otp": [ 1, @@ -8712,7 +8731,7 @@ export default { } ], "resendEmailVerificationToken": [ - 216, + 217, { "email": [ 1, @@ -8728,7 +8747,7 @@ export default { 66, { "data": [ - 473, + 474, "ActivateWorkspaceInput!" ] } @@ -8737,7 +8756,7 @@ export default { 66, { "data": [ - 474, + 475, "UpdateWorkspaceInput!" ] } @@ -8746,46 +8765,46 @@ export default { 66 ], "checkCustomDomainValidRecords": [ - 229 + 230 ], "createOIDCIdentityProvider": [ - 221, + 222, { "input": [ - 475, + 476, "SetupOIDCSsoInput!" ] } ], "createSAMLIdentityProvider": [ - 221, + 222, { "input": [ - 476, + 477, "SetupSAMLSsoInput!" ] } ], "deleteSSOIdentityProvider": [ - 217, + 218, { "input": [ - 477, + 478, "DeleteSsoInput!" ] } ], "editSSOIdentityProvider": [ - 218, + 219, { "input": [ - 478, + 479, "EditSsoInput!" ] } ], "impersonate": [ - 267, + 268, { "userId": [ 3, @@ -8807,7 +8826,7 @@ export default { } ], "saveImapSmtpCaldavAccount": [ - 291, + 295, { "accountOwnerId": [ 3, @@ -8818,7 +8837,7 @@ export default { "String!" ], "connectionParameters": [ - 479, + 480, "EmailAccountConnectionParameters!" ], "id": [ @@ -8827,16 +8846,16 @@ export default { } ], "updateLabPublicFeatureFlag": [ - 197, + 198, { "input": [ - 481, + 482, "UpdateLabPublicFeatureFlagInput!" ] } ], "userLookupAdminPanel": [ - 200, + 201, { "userIdentifier": [ 1, @@ -8891,7 +8910,7 @@ export default { 6, { "role": [ - 482, + 483, "AiModelRole!" ], "modelId": [ @@ -8936,7 +8955,7 @@ export default { } ], "retryJobs": [ - 192, + 193, { "queueName": [ 1, @@ -8949,7 +8968,7 @@ export default { } ], "deleteJobs": [ - 187, + 188, { "queueName": [ 1, @@ -9010,13 +9029,13 @@ export default { } ], "enablePostgresProxy": [ - 292 + 296 ], "disablePostgresProxy": [ - 292 + 296 ], "createPublicDomain": [ - 280, + 284, { "domain": [ 1, @@ -9034,7 +9053,7 @@ export default { } ], "checkPublicDomainValidRecords": [ - 229, + 230, { "domain": [ 1, @@ -9043,14 +9062,14 @@ export default { } ], "createEmailingDomain": [ - 282, + 286, { "domain": [ 1, "String!" ], "driver": [ - 283, + 287, "EmailingDomainDriver!" ] } @@ -9065,7 +9084,7 @@ export default { } ], "verifyEmailingDomain": [ - 282, + 286, { "id": [ 1, @@ -9077,7 +9096,7 @@ export default { 68, { "input": [ - 483, + 484, "CreateOneAppTokenInput!" ] } @@ -9110,7 +9129,7 @@ export default { 6, { "workspaceMigration": [ - 485, + 486, "WorkspaceMigrationInput!" ] } @@ -9142,7 +9161,7 @@ export default { } ], "createDevelopmentApplication": [ - 268, + 272, { "universalIdentifier": [ 1, @@ -9155,7 +9174,7 @@ export default { } ], "generateApplicationToken": [ - 270, + 274, { "applicationId": [ 3, @@ -9164,7 +9183,7 @@ export default { } ], "syncApplication": [ - 269, + 273, { "manifest": [ 15, @@ -9173,10 +9192,10 @@ export default { } ], "uploadApplicationFile": [ - 271, + 275, { "file": [ - 372, + 373, "Upload!" ], "applicationUniversalIdentifier": [ @@ -9184,7 +9203,7 @@ export default { "String!" ], "fileFolder": [ - 488, + 489, "FileFolder!" ], "filePath": [ @@ -9207,7 +9226,7 @@ export default { } ], "renewApplicationToken": [ - 270, + 274, { "applicationRefreshToken": [ 1, @@ -9290,7 +9309,7 @@ export default { 3 ], "update": [ - 371 + 372 ], "__typename": [ 1 @@ -9394,7 +9413,7 @@ export default { 3 ], "update": [ - 377 + 378 ], "__typename": [ 1 @@ -9567,7 +9586,7 @@ export default { 3 ], "update": [ - 384 + 385 ], "__typename": [ 1 @@ -9602,7 +9621,7 @@ export default { 3 ], "update": [ - 388 + 389 ], "__typename": [ 1 @@ -9666,10 +9685,10 @@ export default { 3 ], "groups": [ - 393 + 394 ], "fields": [ - 394 + 395 ], "__typename": [ 1 @@ -9689,7 +9708,7 @@ export default { 6 ], "fields": [ - 394 + 395 ], "__typename": [ 1 @@ -9855,7 +9874,7 @@ export default { 3 ], "tabs": [ - 407 + 408 ], "__typename": [ 1 @@ -9878,7 +9897,7 @@ export default { 79 ], "widgets": [ - 408 + 409 ], "__typename": [ 1 @@ -9901,7 +9920,7 @@ export default { 3 ], "gridPosition": [ - 409 + 410 ], "position": [ 15 @@ -9947,7 +9966,7 @@ export default { 3 ], "gridPosition": [ - 409 + 410 ], "position": [ 15 @@ -9970,7 +9989,7 @@ export default { 3 ], "gridPosition": [ - 409 + 410 ], "position": [ 15 @@ -10039,7 +10058,7 @@ export default { 3 ], "update": [ - 415 + 416 ], "__typename": [ 1 @@ -10190,7 +10209,7 @@ export default { 3 ], "update": [ - 420 + 421 ], "__typename": [ 1 @@ -10209,7 +10228,7 @@ export default { }, "CreateOneObjectInput": { "object": [ - 422 + 423 ], "__typename": [ 1 @@ -10269,7 +10288,7 @@ export default { }, "UpdateOneObjectInput": { "update": [ - 425 + 426 ], "id": [ 3 @@ -10327,7 +10346,7 @@ export default { 3 ], "update": [ - 427 + 428 ], "__typename": [ 1 @@ -10517,7 +10536,7 @@ export default { }, "UpdateRoleInput": { "update": [ - 435 + 436 ], "id": [ 3 @@ -10572,7 +10591,7 @@ export default { 3 ], "objectPermissions": [ - 437 + 438 ], "__typename": [ 1 @@ -10614,7 +10633,7 @@ export default { 3 ], "fieldPermissions": [ - 440 + 441 ], "__typename": [ 1 @@ -10645,10 +10664,10 @@ export default { 3 ], "predicates": [ - 442 + 443 ], "predicateGroups": [ - 443 + 444 ], "__typename": [ 1 @@ -10708,7 +10727,7 @@ export default { }, "CreateOneFieldMetadataInput": { "field": [ - 445 + 446 ], "__typename": [ 1 @@ -10781,7 +10800,7 @@ export default { 3 ], "update": [ - 447 + 448 ], "__typename": [ 1 @@ -10873,7 +10892,7 @@ export default { 3 ], "update": [ - 451 + 452 ], "__typename": [ 1 @@ -10917,7 +10936,7 @@ export default { 3 ], "update": [ - 455 + 456 ], "__typename": [ 1 @@ -10936,7 +10955,7 @@ export default { 3 ], "update": [ - 455 + 456 ], "__typename": [ 1 @@ -10947,7 +10966,7 @@ export default { 3 ], "update": [ - 458 + 459 ], "__typename": [ 1 @@ -10984,7 +11003,7 @@ export default { 3 ], "update": [ - 460 + 461 ], "__typename": [ 1 @@ -11032,7 +11051,7 @@ export default { 3 ], "update": [ - 463 + 464 ], "__typename": [ 1 @@ -11152,7 +11171,7 @@ export default { 1 ], "update": [ - 469 + 470 ], "__typename": [ 1 @@ -11215,7 +11234,7 @@ export default { 1 ], "update": [ - 472 + 473 ], "__typename": [ 1 @@ -11375,13 +11394,13 @@ export default { }, "EmailAccountConnectionParameters": { "IMAP": [ - 480 + 481 ], "SMTP": [ - 480 + 481 ], "CALDAV": [ - 480 + 481 ], "__typename": [ 1 @@ -11421,7 +11440,7 @@ export default { "AiModelRole": {}, "CreateOneAppTokenInput": { "appToken": [ - 484 + 485 ], "__typename": [ 1 @@ -11437,7 +11456,7 @@ export default { }, "WorkspaceMigrationInput": { "actions": [ - 486 + 487 ], "__typename": [ 1 @@ -11445,7 +11464,7 @@ export default { }, "WorkspaceMigrationDeleteActionInput": { "type": [ - 487 + 488 ], "metadataName": [ 341 @@ -11470,10 +11489,10 @@ export default { } ], "logicFunctionLogs": [ - 246, + 247, { "input": [ - 490, + 491, "LogicFunctionLogsInput!" ] } diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index f802e41ec1..280545c26e 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -4278,6 +4278,7 @@ export type Query = { getAISystemPromptPreview: AiSystemPromptPreview; getAddressDetails: PlaceDetailsResult; getAdminAiModels: AdminAiModels; + getAdminAiUsageByWorkspace: Array; getAiProviders: Scalars['JSON']; getApprovedAccessDomains: Array; getAutoCompleteAddress: Array; @@ -4491,6 +4492,12 @@ export type QueryGetAddressDetailsArgs = { }; +export type QueryGetAdminAiUsageByWorkspaceArgs = { + periodEnd?: InputMaybe; + periodStart?: InputMaybe; +}; + + export type QueryGetAutoCompleteAddressArgs = { address: Scalars['String']; country?: InputMaybe; @@ -5642,12 +5649,14 @@ export type UsageAnalytics = { periodEnd: Scalars['DateTime']; periodStart: Scalars['DateTime']; timeSeries: Array; + usageByModel: Array; usageByOperationType: Array; usageByUser: Array; userDailyUsage?: Maybe; }; export type UsageAnalyticsInput = { + operationTypes?: InputMaybe>; periodEnd?: InputMaybe; periodStart?: InputMaybe; userWorkspaceId?: InputMaybe; @@ -5660,6 +5669,13 @@ export type UsageBreakdownItem = { label?: Maybe; }; +export enum UsageOperationType { + AI_CHAT_TOKEN = 'AI_CHAT_TOKEN', + AI_WORKFLOW_TOKEN = 'AI_WORKFLOW_TOKEN', + CODE_EXECUTION = 'CODE_EXECUTION', + WORKFLOW_EXECUTION = 'WORKFLOW_EXECUTION' +} + export type UsageTimeSeries = { __typename?: 'UsageTimeSeries'; creditsUsed: Scalars['Float']; @@ -7056,6 +7072,14 @@ export type GetAdminAiModelsQueryVariables = Exact<{ [key: string]: never; }>; export type GetAdminAiModelsQuery = { __typename?: 'Query', getAdminAiModels: { __typename?: 'AdminAIModels', defaultSmartModelId?: string | null, defaultFastModelId?: string | null, models: Array<{ __typename?: 'AdminAIModelConfig', modelId: string, label: string, modelFamily?: ModelFamily | null, sdkPackage?: string | null, isAvailable: boolean, isAdminEnabled: boolean, isDeprecated?: boolean | null, isRecommended?: boolean | null, contextWindowTokens?: number | null, maxOutputTokens?: number | null, inputCostPerMillionTokens?: number | null, outputCostPerMillionTokens?: number | null, providerName?: string | null, providerLabel?: string | null, name?: string | null, dataResidency?: string | null }> } }; +export type GetAdminAiUsageByWorkspaceQueryVariables = Exact<{ + periodStart?: InputMaybe; + periodEnd?: InputMaybe; +}>; + + +export type GetAdminAiUsageByWorkspaceQuery = { __typename?: 'Query', getAdminAiUsageByWorkspace: Array<{ __typename?: 'UsageBreakdownItem', key: string, label?: string | null, creditsUsed: number }> }; + export type GetAiProvidersQueryVariables = Exact<{ [key: string]: never; }>; @@ -7670,7 +7694,7 @@ export type GetUsageAnalyticsQueryVariables = Exact<{ }>; -export type GetUsageAnalyticsQuery = { __typename?: 'Query', getUsageAnalytics: { __typename?: 'UsageAnalytics', periodStart: string, periodEnd: string, usageByUser: Array<{ __typename?: 'UsageBreakdownItem', key: string, label?: string | null, creditsUsed: number }>, usageByOperationType: Array<{ __typename?: 'UsageBreakdownItem', key: string, creditsUsed: number }>, timeSeries: Array<{ __typename?: 'UsageTimeSeries', date: string, creditsUsed: number }>, userDailyUsage?: { __typename?: 'UsageUserDaily', userWorkspaceId: string, dailyUsage: Array<{ __typename?: 'UsageTimeSeries', date: string, creditsUsed: number }> } | null } }; +export type GetUsageAnalyticsQuery = { __typename?: 'Query', getUsageAnalytics: { __typename?: 'UsageAnalytics', periodStart: string, periodEnd: string, usageByUser: Array<{ __typename?: 'UsageBreakdownItem', key: string, label?: string | null, creditsUsed: number }>, usageByOperationType: Array<{ __typename?: 'UsageBreakdownItem', key: string, creditsUsed: number }>, usageByModel: Array<{ __typename?: 'UsageBreakdownItem', key: string, creditsUsed: number }>, timeSeries: Array<{ __typename?: 'UsageTimeSeries', date: string, creditsUsed: number }>, userDailyUsage?: { __typename?: 'UsageUserDaily', userWorkspaceId: string, dailyUsage: Array<{ __typename?: 'UsageTimeSeries', date: string, creditsUsed: number }> } | null } }; export type BillingSubscriptionFragmentFragment = { __typename?: 'BillingSubscription', id: string, status: SubscriptionStatus, metadata: any, phases: Array<{ __typename?: 'BillingSubscriptionSchedulePhase', start_date: number, end_date: number, items: Array<{ __typename?: 'BillingSubscriptionSchedulePhaseItem', price: string, quantity?: number | null }> }> }; @@ -8264,6 +8288,7 @@ export const SetAdminAiModelEnabledDocument = {"kind":"Document","definitions":[ export const SetAdminAiModelRecommendedDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SetAdminAiModelRecommended"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"modelId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"recommended"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"setAdminAiModelRecommended"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"modelId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modelId"}}},{"kind":"Argument","name":{"kind":"Name","value":"recommended"},"value":{"kind":"Variable","name":{"kind":"Name","value":"recommended"}}}]}]}}]} as unknown as DocumentNode; export const SetAdminDefaultAiModelDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SetAdminDefaultAiModel"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"role"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AiModelRole"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"modelId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"setAdminDefaultAiModel"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"role"},"value":{"kind":"Variable","name":{"kind":"Name","value":"role"}}},{"kind":"Argument","name":{"kind":"Name","value":"modelId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modelId"}}}]}]}}]} as unknown as DocumentNode; export const GetAdminAiModelsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetAdminAiModels"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getAdminAiModels"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"defaultSmartModelId"}},{"kind":"Field","name":{"kind":"Name","value":"defaultFastModelId"}},{"kind":"Field","name":{"kind":"Name","value":"models"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"modelId"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"modelFamily"}},{"kind":"Field","name":{"kind":"Name","value":"sdkPackage"}},{"kind":"Field","name":{"kind":"Name","value":"isAvailable"}},{"kind":"Field","name":{"kind":"Name","value":"isAdminEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"isDeprecated"}},{"kind":"Field","name":{"kind":"Name","value":"isRecommended"}},{"kind":"Field","name":{"kind":"Name","value":"contextWindowTokens"}},{"kind":"Field","name":{"kind":"Name","value":"maxOutputTokens"}},{"kind":"Field","name":{"kind":"Name","value":"inputCostPerMillionTokens"}},{"kind":"Field","name":{"kind":"Name","value":"outputCostPerMillionTokens"}},{"kind":"Field","name":{"kind":"Name","value":"providerName"}},{"kind":"Field","name":{"kind":"Name","value":"providerLabel"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"dataResidency"}}]}}]}}]}}]} as unknown as DocumentNode; +export const GetAdminAiUsageByWorkspaceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetAdminAiUsageByWorkspace"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"periodStart"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"DateTime"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"periodEnd"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"DateTime"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getAdminAiUsageByWorkspace"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"periodStart"},"value":{"kind":"Variable","name":{"kind":"Name","value":"periodStart"}}},{"kind":"Argument","name":{"kind":"Name","value":"periodEnd"},"value":{"kind":"Variable","name":{"kind":"Name","value":"periodEnd"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"creditsUsed"}}]}}]}}]} as unknown as DocumentNode; export const GetAiProvidersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetAiProviders"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getAiProviders"}}]}}]} as unknown as DocumentNode; export const GetModelsDevProvidersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetModelsDevProviders"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getModelsDevProviders"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"modelCount"}},{"kind":"Field","name":{"kind":"Name","value":"npm"}}]}}]}}]} as unknown as DocumentNode; export const GetModelsDevSuggestionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetModelsDevSuggestions"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"providerType"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getModelsDevSuggestions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"providerType"},"value":{"kind":"Variable","name":{"kind":"Name","value":"providerType"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"modelId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"inputCostPerMillionTokens"}},{"kind":"Field","name":{"kind":"Name","value":"outputCostPerMillionTokens"}},{"kind":"Field","name":{"kind":"Name","value":"cachedInputCostPerMillionTokens"}},{"kind":"Field","name":{"kind":"Name","value":"cacheCreationCostPerMillionTokens"}},{"kind":"Field","name":{"kind":"Name","value":"contextWindowTokens"}},{"kind":"Field","name":{"kind":"Name","value":"maxOutputTokens"}},{"kind":"Field","name":{"kind":"Name","value":"modalities"}},{"kind":"Field","name":{"kind":"Name","value":"supportsReasoning"}}]}}]}}]} as unknown as DocumentNode; @@ -8351,7 +8376,7 @@ export const ValidateApprovedAccessDomainDocument = {"kind":"Document","definiti export const GetApprovedAccessDomainsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetApprovedAccessDomains"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getApprovedAccessDomains"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"isValidated"}}]}}]}}]} as unknown as DocumentNode; export const GetSsoIdentityProvidersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSSOIdentityProviders"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getSSOIdentityProviders"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"issuer"}},{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]} as unknown as DocumentNode; export const VerifyTwoFactorAuthenticationMethodForAuthenticatedUserDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"verifyTwoFactorAuthenticationMethodForAuthenticatedUser"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"otp"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"verifyTwoFactorAuthenticationMethodForAuthenticatedUser"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"otp"},"value":{"kind":"Variable","name":{"kind":"Name","value":"otp"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"success"}}]}}]}}]} as unknown as DocumentNode; -export const GetUsageAnalyticsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetUsageAnalytics"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UsageAnalyticsInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getUsageAnalytics"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"usageByUser"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"creditsUsed"}}]}},{"kind":"Field","name":{"kind":"Name","value":"usageByOperationType"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"creditsUsed"}}]}},{"kind":"Field","name":{"kind":"Name","value":"timeSeries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"creditsUsed"}}]}},{"kind":"Field","name":{"kind":"Name","value":"periodStart"}},{"kind":"Field","name":{"kind":"Name","value":"periodEnd"}},{"kind":"Field","name":{"kind":"Name","value":"userDailyUsage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userWorkspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"dailyUsage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"creditsUsed"}}]}}]}}]}}]}}]} as unknown as DocumentNode; +export const GetUsageAnalyticsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetUsageAnalytics"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UsageAnalyticsInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getUsageAnalytics"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"usageByUser"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"creditsUsed"}}]}},{"kind":"Field","name":{"kind":"Name","value":"usageByOperationType"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"creditsUsed"}}]}},{"kind":"Field","name":{"kind":"Name","value":"usageByModel"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"creditsUsed"}}]}},{"kind":"Field","name":{"kind":"Name","value":"timeSeries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"creditsUsed"}}]}},{"kind":"Field","name":{"kind":"Name","value":"periodStart"}},{"kind":"Field","name":{"kind":"Name","value":"periodEnd"}},{"kind":"Field","name":{"kind":"Name","value":"userDailyUsage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userWorkspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"dailyUsage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"creditsUsed"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const DeleteUserAccountDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteUserAccount"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteUser"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]} as unknown as DocumentNode; export const DeleteUserWorkspaceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteUserWorkspace"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"workspaceMemberIdToDelete"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteUserFromWorkspace"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"workspaceMemberIdToDelete"},"value":{"kind":"Variable","name":{"kind":"Name","value":"workspaceMemberIdToDelete"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]} as unknown as DocumentNode; export const GetCurrentUserDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetCurrentUser"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"currentUser"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"UserQueryFragment"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkspaceMemberQueryFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceMember"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}}]}},{"kind":"Field","name":{"kind":"Name","value":"colorScheme"}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}},{"kind":"Field","name":{"kind":"Name","value":"locale"}},{"kind":"Field","name":{"kind":"Name","value":"userEmail"}},{"kind":"Field","name":{"kind":"Name","value":"userWorkspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"timeZone"}},{"kind":"Field","name":{"kind":"Name","value":"dateFormat"}},{"kind":"Field","name":{"kind":"Name","value":"timeFormat"}},{"kind":"Field","name":{"kind":"Name","value":"calendarStartDay"}},{"kind":"Field","name":{"kind":"Name","value":"numberFormat"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"PartialWorkspaceMemberQueryFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceMember"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}}]}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}},{"kind":"Field","name":{"kind":"Name","value":"userEmail"}},{"kind":"Field","name":{"kind":"Name","value":"userWorkspaceId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"DeletedWorkspaceMemberQueryFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"DeletedWorkspaceMember"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}}]}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}},{"kind":"Field","name":{"kind":"Name","value":"userEmail"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"RowLevelPermissionPredicateFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"RowLevelPermissionPredicate"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"fieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"objectMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"operand"}},{"kind":"Field","name":{"kind":"Name","value":"subFieldName"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceMemberFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceMemberSubFieldName"}},{"kind":"Field","name":{"kind":"Name","value":"rowLevelPermissionPredicateGroupId"}},{"kind":"Field","name":{"kind":"Name","value":"positionInRowLevelPermissionPredicateGroup"}},{"kind":"Field","name":{"kind":"Name","value":"roleId"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"RowLevelPermissionPredicateGroupFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"RowLevelPermissionPredicateGroup"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"parentRowLevelPermissionPredicateGroupId"}},{"kind":"Field","name":{"kind":"Name","value":"logicalOperator"}},{"kind":"Field","name":{"kind":"Name","value":"positionInRowLevelPermissionPredicateGroup"}},{"kind":"Field","name":{"kind":"Name","value":"roleId"}},{"kind":"Field","name":{"kind":"Name","value":"objectMetadataId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ObjectPermissionFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ObjectPermission"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"objectMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"canReadObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canSoftDeleteObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canDestroyObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"restrictedFields"}},{"kind":"Field","name":{"kind":"Name","value":"rowLevelPermissionPredicates"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"RowLevelPermissionPredicateFragment"}}]}},{"kind":"Field","name":{"kind":"Name","value":"rowLevelPermissionPredicateGroups"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"RowLevelPermissionPredicateGroupFragment"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkspaceUrlsFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceUrls"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"subdomainUrl"}},{"kind":"Field","name":{"kind":"Name","value":"customUrl"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BillingSubscriptionSchedulePhaseItemFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"BillingSubscriptionSchedulePhaseItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"price"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BillingSubscriptionSchedulePhaseFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"BillingSubscriptionSchedulePhase"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start_date"}},{"kind":"Field","name":{"kind":"Name","value":"end_date"}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"BillingSubscriptionSchedulePhaseItemFragment"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CurrentBillingSubscriptionFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"BillingSubscription"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"interval"}},{"kind":"Field","name":{"kind":"Name","value":"metadata"}},{"kind":"Field","name":{"kind":"Name","value":"currentPeriodEnd"}},{"kind":"Field","name":{"kind":"Name","value":"phases"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"BillingSubscriptionSchedulePhaseFragment"}}]}},{"kind":"Field","name":{"kind":"Name","value":"billingSubscriptionItems"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"hasReachedCurrentPeriodCap"}},{"kind":"Field","name":{"kind":"Name","value":"quantity"}},{"kind":"Field","name":{"kind":"Name","value":"stripePriceId"}},{"kind":"Field","name":{"kind":"Name","value":"billingProduct"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"images"}},{"kind":"Field","name":{"kind":"Name","value":"metadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"productKey"}},{"kind":"Field","name":{"kind":"Name","value":"planKey"}},{"kind":"Field","name":{"kind":"Name","value":"priceUsageBased"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BillingSubscriptionFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"BillingSubscription"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"metadata"}},{"kind":"Field","name":{"kind":"Name","value":"phases"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"BillingSubscriptionSchedulePhaseFragment"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"RoleFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Role"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateAllSettings"}},{"kind":"Field","name":{"kind":"Name","value":"canAccessAllTools"}},{"kind":"Field","name":{"kind":"Name","value":"isEditable"}},{"kind":"Field","name":{"kind":"Name","value":"canReadAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canSoftDeleteAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canDestroyAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canBeAssignedToUsers"}},{"kind":"Field","name":{"kind":"Name","value":"canBeAssignedToAgents"}},{"kind":"Field","name":{"kind":"Name","value":"canBeAssignedToApiKeys"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AvailableWorkspaceFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AvailableWorkspace"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"displayName"}},{"kind":"Field","name":{"kind":"Name","value":"loginToken"}},{"kind":"Field","name":{"kind":"Name","value":"inviteHash"}},{"kind":"Field","name":{"kind":"Name","value":"personalInviteToken"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceUrls"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"subdomainUrl"}},{"kind":"Field","name":{"kind":"Name","value":"customUrl"}}]}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"sso"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"issuer"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AvailableWorkspacesFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AvailableWorkspaces"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"availableWorkspacesForSignIn"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AvailableWorkspaceFragment"}}]}},{"kind":"Field","name":{"kind":"Name","value":"availableWorkspacesForSignUp"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AvailableWorkspaceFragment"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"UserQueryFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"hasPassword"}},{"kind":"Field","name":{"kind":"Name","value":"canAccessFullAdminPanel"}},{"kind":"Field","name":{"kind":"Name","value":"canImpersonate"}},{"kind":"Field","name":{"kind":"Name","value":"supportUserHash"}},{"kind":"Field","name":{"kind":"Name","value":"onboardingStatus"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceMember"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkspaceMemberQueryFragment"}}]}},{"kind":"Field","name":{"kind":"Name","value":"workspaceMembers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"PartialWorkspaceMemberQueryFragment"}}]}},{"kind":"Field","name":{"kind":"Name","value":"deletedWorkspaceMembers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"DeletedWorkspaceMemberQueryFragment"}}]}},{"kind":"Field","name":{"kind":"Name","value":"currentUserWorkspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"permissionFlags"}},{"kind":"Field","name":{"kind":"Name","value":"objectsPermissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ObjectPermissionFragment"}}]}},{"kind":"Field","name":{"kind":"Name","value":"twoFactorAuthenticationMethodSummary"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"twoFactorAuthenticationMethodId"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"strategy"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"currentWorkspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"displayName"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"inviteHash"}},{"kind":"Field","name":{"kind":"Name","value":"allowImpersonation"}},{"kind":"Field","name":{"kind":"Name","value":"activationStatus"}},{"kind":"Field","name":{"kind":"Name","value":"isPublicInviteLinkEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"isGoogleAuthEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"isMicrosoftAuthEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"isPasswordAuthEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"isGoogleAuthBypassEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"isMicrosoftAuthBypassEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"isPasswordAuthBypassEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"subdomain"}},{"kind":"Field","name":{"kind":"Name","value":"customDomain"}},{"kind":"Field","name":{"kind":"Name","value":"hasValidEnterpriseKey"}},{"kind":"Field","name":{"kind":"Name","value":"hasValidSignedEnterpriseKey"}},{"kind":"Field","name":{"kind":"Name","value":"hasValidEnterpriseValidityToken"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceCustomApplication"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"isCustomDomainEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceUrls"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkspaceUrlsFragment"}}]}},{"kind":"Field","name":{"kind":"Name","value":"featureFlags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}},{"kind":"Field","name":{"kind":"Name","value":"metadataVersion"}},{"kind":"Field","name":{"kind":"Name","value":"currentBillingSubscription"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CurrentBillingSubscriptionFragment"}}]}},{"kind":"Field","name":{"kind":"Name","value":"billingSubscriptions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"BillingSubscriptionFragment"}}]}},{"kind":"Field","name":{"kind":"Name","value":"billingEntitlements"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}},{"kind":"Field","name":{"kind":"Name","value":"workspaceMembersCount"}},{"kind":"Field","name":{"kind":"Name","value":"defaultRole"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"RoleFragment"}}]}},{"kind":"Field","name":{"kind":"Name","value":"fastModel"}},{"kind":"Field","name":{"kind":"Name","value":"smartModel"}},{"kind":"Field","name":{"kind":"Name","value":"aiAdditionalInstructions"}},{"kind":"Field","name":{"kind":"Name","value":"enabledAiModelIds"}},{"kind":"Field","name":{"kind":"Name","value":"useRecommendedModels"}},{"kind":"Field","name":{"kind":"Name","value":"isTwoFactorAuthenticationEnforced"}},{"kind":"Field","name":{"kind":"Name","value":"trashRetentionDays"}},{"kind":"Field","name":{"kind":"Name","value":"eventLogRetentionDays"}},{"kind":"Field","name":{"kind":"Name","value":"editableProfileFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"availableWorkspaces"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AvailableWorkspacesFragment"}}]}},{"kind":"Field","name":{"kind":"Name","value":"userVars"}}]}}]} as unknown as DocumentNode; diff --git a/packages/twenty-front/src/modules/ai/components/internal/AIChatContextUsageButton.tsx b/packages/twenty-front/src/modules/ai/components/internal/AIChatContextUsageButton.tsx index 334d1c361d..7edb4d55b6 100644 --- a/packages/twenty-front/src/modules/ai/components/internal/AIChatContextUsageButton.tsx +++ b/packages/twenty-front/src/modules/ai/components/internal/AIChatContextUsageButton.tsx @@ -14,6 +14,7 @@ import { type AgentChatLastMessageUsage, } from '@/ai/states/agentChatUsageState'; import { SettingsBillingLabelValueItem } from '@/settings/billing/components/internal/SettingsBillingLabelValueItem'; +import { billingState } from '@/client-config/states/billingState'; import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { formatNumber } from '~/utils/format/formatNumber'; @@ -78,17 +79,6 @@ const StyledSectionTitle = styled.span` padding-bottom: ${themeCssVariables.spacing[2]}; `; -const formatCredits = (credits: number): string => { - if (Number.isInteger(credits)) { - return credits.toLocaleString(); - } - - return credits.toLocaleString(undefined, { - minimumFractionDigits: 0, - maximumFractionDigits: 1, - }); -}; - const getCachedLabel = (lastMessage: AgentChatLastMessageUsage): string => { if (lastMessage.cachedInputTokens <= 0 || lastMessage.inputTokens <= 0) { return ''; @@ -105,6 +95,19 @@ export const AIChatContextUsageButton = () => { const { t } = useLingui(); const [isHovered, setIsHovered] = useState(false); const agentChatUsage = useAtomStateValue(agentChatUsageState); + const billing = useAtomStateValue(billingState); + const isBillingEnabled = billing?.isBillingEnabled ?? false; + + // Values from the streaming API arrive as display credits (micro-credits / 1000). + // 1000 display credits = $1. Convert accordingly. + const formatChatCost = (displayCredits: number): string => { + if (isBillingEnabled) { + return `${formatNumber(displayCredits, { decimals: 1 })} credits`; + } + const dollars = displayCredits / 1000; + + return `$${formatNumber(dollars, { decimals: 2 })}`; + }; const hasMessages = useAtomComponentSelectorValue( agentChatHasMessageComponentSelector, @@ -202,7 +205,9 @@ export const AIChatContextUsageButton = () => { /> @@ -230,7 +235,7 @@ export const AIChatContextUsageButton = () => { /> diff --git a/packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx b/packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx index 936bd5731c..a7f840fa0a 100644 --- a/packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx +++ b/packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx @@ -155,6 +155,12 @@ const SettingsAI = lazy(() => })), ); +const SettingsAIUsageUserDetail = lazy(() => + import('~/pages/settings/ai/SettingsAIUsageUserDetail').then((module) => ({ + default: module.SettingsAIUsageUserDetail, + })), +); + const SettingsApplications = lazy(() => import('~/pages/settings/applications/SettingsApplications').then( (module) => ({ @@ -536,6 +542,10 @@ export const SettingsRoutes = ({ isAdminPageEnabled }: SettingsRoutesProps) => ( path={SettingsPath.AISkillDetail} element={} /> + } + /> } diff --git a/packages/twenty-front/src/modules/command-menu-item/server-items/display/components/CommandMenuItemMoreActionsButton.tsx b/packages/twenty-front/src/modules/command-menu-item/server-items/display/components/CommandMenuItemMoreActionsButton.tsx index 602812372c..7c7dc4409b 100644 --- a/packages/twenty-front/src/modules/command-menu-item/server-items/display/components/CommandMenuItemMoreActionsButton.tsx +++ b/packages/twenty-front/src/modules/command-menu-item/server-items/display/components/CommandMenuItemMoreActionsButton.tsx @@ -3,7 +3,6 @@ import { isSidePanelOpenedState } from '@/side-panel/states/isSidePanelOpenedSta import { PAGE_HEADER_SIDE_PANEL_BUTTON_CLICK_OUTSIDE_ID } from '@/ui/layout/page-header/constants/PageHeaderSidePanelButtonClickOutsideId'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { styled } from '@linaria/react'; -import { i18n } from '@lingui/core'; import { t } from '@lingui/core/macro'; import { AppTooltip, @@ -52,7 +51,7 @@ export const CommandMenuItemMoreActionsButton = () => { - 0 && keys.length > 0} - /> + {showLegend && data.length > 0 && keys.length > 0 && ( + + )} ); }; diff --git a/packages/twenty-front/src/modules/page-layout/widgets/graph/graph-widget-gauge-chart/components/GraphWidgetGaugeChart.tsx b/packages/twenty-front/src/modules/page-layout/widgets/graph/graph-widget-gauge-chart/components/GraphWidgetGaugeChart.tsx index d9a6808ed8..8ab8fe3599 100644 --- a/packages/twenty-front/src/modules/page-layout/widgets/graph/graph-widget-gauge-chart/components/GraphWidgetGaugeChart.tsx +++ b/packages/twenty-front/src/modules/page-layout/widgets/graph/graph-widget-gauge-chart/components/GraphWidgetGaugeChart.tsx @@ -146,16 +146,18 @@ export const GraphWidgetGaugeChart = ({ )} - + {showLegend && ( + + )} ); }; diff --git a/packages/twenty-front/src/modules/page-layout/widgets/graph/graph-widget-line-chart/components/GraphWidgetLineChart.tsx b/packages/twenty-front/src/modules/page-layout/widgets/graph/graph-widget-line-chart/components/GraphWidgetLineChart.tsx index 2c363ec336..8fbbe40517 100644 --- a/packages/twenty-front/src/modules/page-layout/widgets/graph/graph-widget-line-chart/components/GraphWidgetLineChart.tsx +++ b/packages/twenty-front/src/modules/page-layout/widgets/graph/graph-widget-line-chart/components/GraphWidgetLineChart.tsx @@ -348,10 +348,9 @@ export const GraphWidgetLineChart = ({ onMouseEnter={handleTooltipMouseEnter} onMouseLeave={handleTooltipMouseLeave} /> - 0} - items={legendItems} - /> + {showLegend && data.length > 0 && ( + + )} ); }; diff --git a/packages/twenty-front/src/modules/page-layout/widgets/graph/graph-widget-pie-chart/components/GraphWidgetPieChart.tsx b/packages/twenty-front/src/modules/page-layout/widgets/graph/graph-widget-pie-chart/components/GraphWidgetPieChart.tsx index b5570bfeaf..05b4f393e9 100644 --- a/packages/twenty-front/src/modules/page-layout/widgets/graph/graph-widget-pie-chart/components/GraphWidgetPieChart.tsx +++ b/packages/twenty-front/src/modules/page-layout/widgets/graph/graph-widget-pie-chart/components/GraphWidgetPieChart.tsx @@ -231,10 +231,9 @@ export const GraphWidgetPieChart = ({ displayType={displayType} onSliceClick={onSliceClick} /> - 0} - items={legendItems} - /> + {showLegend && data.length > 0 && ( + + )} ); }; diff --git a/packages/twenty-front/src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx b/packages/twenty-front/src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx index f87ada1f77..1ff84371d8 100644 --- a/packages/twenty-front/src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx +++ b/packages/twenty-front/src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx @@ -1,11 +1,14 @@ -import { useMemo } from 'react'; +import { useMemo, useState } from 'react'; import { useMutation, useQuery } from '@apollo/client/react'; import { t } from '@lingui/core/macro'; import { Tag } from 'twenty-ui/components'; import { H2Title, IconBolt, IconLock, IconRobot } from 'twenty-ui/display'; import { Card, Section } from 'twenty-ui/layout'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; +import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; +import { billingState } from '@/client-config/states/billingState'; import { useClientConfig } from '@/client-config/hooks/useClientConfig'; import { SettingsAdminAiModelsTable } from '@/settings/admin-panel/ai/components/SettingsAdminAiModelsTable'; import { SettingsAdminAiProviderListCard } from '@/settings/admin-panel/ai/components/SettingsAdminAiProviderListCard'; @@ -13,23 +16,51 @@ import { AI_PROVIDER_SOURCE } from '@/settings/admin-panel/ai/constants/AiProvid import { SET_ADMIN_AI_MODEL_RECOMMENDED } from '@/settings/admin-panel/ai/graphql/mutations/setAdminAiModelRecommended'; import { SET_ADMIN_DEFAULT_AI_MODEL } from '@/settings/admin-panel/ai/graphql/mutations/setAdminDefaultAiModel'; import { GET_ADMIN_AI_MODELS } from '@/settings/admin-panel/ai/graphql/queries/getAdminAiModels'; +import { GET_ADMIN_AI_USAGE_BY_WORKSPACE } from '@/settings/admin-panel/ai/graphql/queries/getAdminAiUsageByWorkspace'; import { GET_AI_PROVIDERS } from '@/settings/admin-panel/ai/graphql/queries/getAiProviders'; import { type GetAiProvidersResult } from '@/settings/admin-panel/ai/types/GetAiProvidersResult'; import { getModelIcon } from '@/settings/admin-panel/ai/utils/getModelIcon'; import { parseProviderItems } from '@/settings/admin-panel/ai/utils/parseProviderItems'; import { SettingsAdminTabSkeletonLoader } from '@/settings/admin-panel/components/SettingsAdminTabSkeletonLoader'; +import { SettingsEnterpriseFeatureGateCard } from '@/settings/components/SettingsEnterpriseFeatureGateCard'; import { SettingsOptionCardContentSelect } from '@/settings/components/SettingsOptions/SettingsOptionCardContentSelect'; +import { useUsageValueFormatter } from '@/settings/usage/hooks/useUsageValueFormatter'; +import { getPeriodDates } from '@/settings/usage/utils/getPeriodDates'; +import { getPeriodOptions } from '@/settings/usage/utils/getPeriodOptions'; +import { type PeriodPreset } from '@/settings/usage/utils/periodPreset'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; +import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { Select } from '@/ui/input/components/Select'; +import { Table } from '@/ui/layout/table/components/Table'; +import { TableCell } from '@/ui/layout/table/components/TableCell'; +import { TableHeader } from '@/ui/layout/table/components/TableHeader'; +import { TableRow } from '@/ui/layout/table/components/TableRow'; import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth'; import { AiModelRole, type AdminAiModelConfig, } from '~/generated-metadata/graphql'; +const USAGE_TABLE_GRID_TEMPLATE_COLUMNS = '1fr 120px'; + +type UsageBreakdownItem = { + key: string; + label?: string | null; + creditsUsed: number; +}; + export const SettingsAdminAI = () => { const { enqueueErrorSnackBar } = useSnackBar(); const { refetch: refetchClientConfig } = useClientConfig(); + const { formatUsageValue } = useUsageValueFormatter(); + const currentWorkspace = useAtomStateValue(currentWorkspaceState); + const billing = useAtomStateValue(billingState); + const isBillingEnabled = billing?.isBillingEnabled ?? false; + const hasEnterpriseAccess = + isBillingEnabled || currentWorkspace?.hasValidEnterpriseKey === true; + const [usagePeriod, setUsagePeriod] = useState('30d'); + const periodOptions = getPeriodOptions(); + const usageDates = getPeriodDates(usagePeriod); const { data, loading: isLoadingModels } = useQuery<{ getAdminAiModels: { @@ -45,6 +76,19 @@ export const SettingsAdminAI = () => { const { data: providersData, loading: isLoadingProviders } = useQuery(GET_AI_PROVIDERS); + const { data: usageData, previousData: previousUsageData } = useQuery<{ + getAdminAiUsageByWorkspace: UsageBreakdownItem[]; + }>(GET_ADMIN_AI_USAGE_BY_WORKSPACE, { + variables: { + periodStart: usageDates.periodStart, + periodEnd: usageDates.periodEnd, + }, + skip: !hasEnterpriseAccess, + }); + + const effectiveUsageData = usageData ?? previousUsageData; + const usageByWorkspace = effectiveUsageData?.getAdminAiUsageByWorkspace ?? []; + const models = data?.getAdminAiModels?.models ?? []; const providerItems = useMemo( @@ -208,6 +252,70 @@ export const SettingsAdminAI = () => { /> )} + +
+ + ) : ( + + ) + } + /> + {hasEnterpriseAccess ? ( + usageByWorkspace.length > 0 ? ( + + + {t`Workspace`} + {t`Usage`} + + {usageByWorkspace.map((item) => ( + + + {item.label ?? item.key} + + + {formatUsageValue(item.creditsUsed)} + + + ))} +
+ ) : ( + + + + {t`No AI usage data recorded yet.`} + + + + ) + ) : ( + + )} +
); }; diff --git a/packages/twenty-front/src/modules/settings/admin-panel/ai/graphql/queries/getAdminAiUsageByWorkspace.ts b/packages/twenty-front/src/modules/settings/admin-panel/ai/graphql/queries/getAdminAiUsageByWorkspace.ts new file mode 100644 index 0000000000..98fddec246 --- /dev/null +++ b/packages/twenty-front/src/modules/settings/admin-panel/ai/graphql/queries/getAdminAiUsageByWorkspace.ts @@ -0,0 +1,17 @@ +import { gql } from '@apollo/client'; + +export const GET_ADMIN_AI_USAGE_BY_WORKSPACE = gql` + query GetAdminAiUsageByWorkspace( + $periodStart: DateTime + $periodEnd: DateTime + ) { + getAdminAiUsageByWorkspace( + periodStart: $periodStart + periodEnd: $periodEnd + ) { + key + label + creditsUsed + } + } +`; diff --git a/packages/twenty-front/src/modules/settings/billing/components/SettingsBillingCreditsSection.tsx b/packages/twenty-front/src/modules/settings/billing/components/SettingsBillingCreditsSection.tsx index 5a98dbc3c8..bd34339ff5 100644 --- a/packages/twenty-front/src/modules/settings/billing/components/SettingsBillingCreditsSection.tsx +++ b/packages/twenty-front/src/modules/settings/billing/components/SettingsBillingCreditsSection.tsx @@ -63,7 +63,6 @@ export const SettingsBillingCreditsSection = ({ } = getWorkflowNodeExecutionUsage(); const progressBarValue = (usedCredits / totalGrantedCredits) * 100; - const displayedProgressBarValue = progressBarValue < 3 ? 3 : progressBarValue; const intervalLabel = getIntervalLabel(isMonthlyPlan); @@ -90,7 +89,7 @@ export const SettingsBillingCreditsSection = ({ value={`${formatNumber(usedCredits)}/${formatNumber(totalGrantedCredits, { abbreviate: true, decimals: 2 })}`} /> 100 ? theme.color.red8 : theme.color.blue } diff --git a/packages/twenty-front/src/modules/settings/components/SettingsEnterpriseFeatureGateCard.tsx b/packages/twenty-front/src/modules/settings/components/SettingsEnterpriseFeatureGateCard.tsx new file mode 100644 index 0000000000..8f6655308a --- /dev/null +++ b/packages/twenty-front/src/modules/settings/components/SettingsEnterpriseFeatureGateCard.tsx @@ -0,0 +1,44 @@ +import { currentUserState } from '@/auth/states/currentUserState'; +import { SettingsOptionCardContentButton } from '@/settings/components/SettingsOptions/SettingsOptionCardContentButton'; +import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; +import { t } from '@lingui/core/macro'; +import { SettingsPath } from 'twenty-shared/types'; +import { IconArrowUp, IconLock } from 'twenty-ui/display'; +import { Button } from 'twenty-ui/input'; +import { Card } from 'twenty-ui/layout'; +import { useNavigateSettings } from '~/hooks/useNavigateSettings'; + +export const SettingsEnterpriseFeatureGateCard = ({ + description, +}: { + description: string; +}) => { + const currentUser = useAtomStateValue(currentUserState); + const navigateSettings = useNavigateSettings(); + + const canAccessAdminPanel = currentUser?.canAccessFullAdminPanel === true; + + return ( + + + navigateSettings(SettingsPath.AdminPanelEnterprise) + } + /> + ) : undefined + } + /> + + ); +}; diff --git a/packages/twenty-front/src/modules/settings/enterprise/components/EnterprisePlanModal.tsx b/packages/twenty-front/src/modules/settings/enterprise/components/EnterprisePlanModal.tsx index 35a74bc240..4f3fc72cd9 100644 --- a/packages/twenty-front/src/modules/settings/enterprise/components/EnterprisePlanModal.tsx +++ b/packages/twenty-front/src/modules/settings/enterprise/components/EnterprisePlanModal.tsx @@ -71,9 +71,20 @@ const StyledIntervalContainer = styled.div` width: 100%; `; +const StyledIntervalCardContent = styled.div` + display: flex; + flex-direction: column; +`; + const StyledIntervalTitle = styled.div` color: ${themeCssVariables.font.color.secondary}; font-size: ${themeCssVariables.font.size.md}; + margin-bottom: ${themeCssVariables.spacing[2]}; +`; + +const StyledIntervalSubtitle = styled.div` + color: ${themeCssVariables.font.color.tertiary}; + font-size: ${themeCssVariables.font.size.md}; `; export const EnterprisePlanModal = () => { @@ -132,7 +143,7 @@ export const EnterprisePlanModal = () => { return ( @@ -157,13 +168,19 @@ export const EnterprisePlanModal = () => { checked={selectedInterval === 'monthly'} handleChange={() => setSelectedInterval('monthly')} > - {t`Monthly subscription`} + + {t`Monthly`} + {`$${MONTHLY_PRICE} / ${t`seat / month`}`} + setSelectedInterval('yearly')} > - {t`Yearly subscription`} + + {t`Yearly`} + {`$${YEARLY_PRICE} / ${t`seat / month`}`} + diff --git a/packages/twenty-front/src/modules/settings/hooks/useSettingsNavigationItems.tsx b/packages/twenty-front/src/modules/settings/hooks/useSettingsNavigationItems.tsx index 3fdecf9e5e..37305db70e 100644 --- a/packages/twenty-front/src/modules/settings/hooks/useSettingsNavigationItems.tsx +++ b/packages/twenty-front/src/modules/settings/hooks/useSettingsNavigationItems.tsx @@ -22,7 +22,6 @@ import { IconCalendarEvent, IconColorSwatch, type IconComponent, - IconChartBar, IconCurrencyDollar, IconDoorEnter, IconHelpCircle, @@ -79,9 +78,6 @@ const useSettingsNavigationItems = (): SettingsNavigationSection[] => { const isApplicationEnabled = useIsFeatureEnabled( FeatureFlagKey.IS_APPLICATION_ENABLED, ); - const isUsageAnalyticsEnabled = useIsFeatureEnabled( - FeatureFlagKey.IS_USAGE_ANALYTICS_ENABLED, - ); const isSupportChatConfigured = supportChat?.supportDriver === 'FRONT' && isNonEmptyString(supportChat.supportFrontChatId); @@ -165,15 +161,6 @@ const useSettingsNavigationItems = (): SettingsNavigationSection[] => { isHidden: !isBillingEnabled || !permissionMap[PermissionFlagType.WORKSPACE], }, - { - label: t`Usage`, - path: SettingsPath.Usage, - Icon: IconChartBar, - isHidden: - !isUsageAnalyticsEnabled || - isBillingEnabled || - !permissionMap[PermissionFlagType.WORKSPACE], - }, { label: t`APIs & Webhooks`, path: SettingsPath.ApiWebhooks, diff --git a/packages/twenty-front/src/modules/settings/usage/components/SettingsUsageAnalyticsSection.tsx b/packages/twenty-front/src/modules/settings/usage/components/SettingsUsageAnalyticsSection.tsx index 23cd806f3c..3056e9be15 100644 --- a/packages/twenty-front/src/modules/settings/usage/components/SettingsUsageAnalyticsSection.tsx +++ b/packages/twenty-front/src/modules/settings/usage/components/SettingsUsageAnalyticsSection.tsx @@ -1,129 +1,23 @@ +import { isClickHouseConfiguredState } from '@/client-config/states/isClickHouseConfiguredState'; import { SettingsBillingLabelValueItem } from '@/settings/billing/components/internal/SettingsBillingLabelValueItem'; import { SubscriptionInfoContainer } from '@/settings/billing/components/SubscriptionInfoContainer'; -import { useNumberFormat } from '@/localization/hooks/useNumberFormat'; -import { GraphWidgetLineChart } from '@/page-layout/widgets/graph/graph-widget-line-chart/components/GraphWidgetLineChart'; -import { type LineChartSeriesWithColor } from '@/page-layout/widgets/graph/graph-widget-line-chart/types/LineChartSeriesWithColor'; -import { createGraphColorRegistry } from '@/page-layout/widgets/graph/utils/createGraphColorRegistry'; -import { getColorSchemeByIndex } from '@/page-layout/widgets/graph/utils/getColorSchemeByIndex'; -import { Select } from '@/ui/input/components/Select'; -import { Table } from '@/ui/layout/table/components/Table'; -import { TableCell } from '@/ui/layout/table/components/TableCell'; -import { TableHeader } from '@/ui/layout/table/components/TableHeader'; -import { TableRow } from '@/ui/layout/table/components/TableRow'; -import { getOperationTypeLabel } from '@/settings/usage/utils/getOperationTypeLabel'; -import { getPeriodDates } from '@/settings/usage/utils/getPeriodDates'; -import { getPeriodOptions } from '@/settings/usage/utils/getPeriodOptions'; -import { type PeriodPreset } from '@/settings/usage/utils/periodPreset'; -import { UsagePieChart } from '@/settings/usage/components/UsagePieChart'; +import { UsageBreakdownPieSection } from '@/settings/usage/components/UsageBreakdownPieSection'; +import { UsageByUserTableSection } from '@/settings/usage/components/UsageByUserTableSection'; +import { UsageDailyChartSection } from '@/settings/usage/components/UsageDailyChartSection'; +import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { t } from '@lingui/core/macro'; -import { styled } from '@linaria/react'; -import { useContext, useState } from 'react'; +import { Link } from 'react-router-dom'; import { SettingsPath } from 'twenty-shared/types'; import { getSettingsPath } from 'twenty-shared/utils'; -import { Avatar, H2Title, IconChevronRight } from 'twenty-ui/display'; -import { SearchInput } from 'twenty-ui/input'; +import { H2Title, IconSparkles } from 'twenty-ui/display'; +import { Button } from 'twenty-ui/input'; import { Section } from 'twenty-ui/layout'; -import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants'; -import { useQuery } from '@apollo/client/react'; -import { GetUsageAnalyticsDocument } from '~/generated-metadata/graphql'; -import { formatDate } from '~/utils/date-utils'; -import { normalizeSearchText } from '~/utils/normalizeSearchText'; - -const StyledSearchInputContainer = styled.div` - padding-bottom: ${themeCssVariables.spacing[2]}; -`; - -const StyledIconChevronRightContainer = styled.div` - color: ${themeCssVariables.font.color.tertiary}; -`; - -const StyledLineChartContainer = styled.div` - height: 200px; - width: 100%; -`; - -const USAGE_USER_TABLE_GRID_TEMPLATE_COLUMNS = '1fr 120px 36px'; +import { SETTINGS_AI_TABS } from '~/pages/settings/ai/constants/SettingsAiTabs'; export const SettingsUsageAnalyticsSection = () => { - const { theme } = useContext(ThemeContext); - const { formatNumber } = useNumberFormat(); + const isClickHouseConfigured = useAtomStateValue(isClickHouseConfiguredState); - const [typePeriod, setTypePeriod] = useState('30d'); - const [dailyPeriod, setDailyPeriod] = useState('30d'); - const [userPeriod, setUserPeriod] = useState('30d'); - const [userSearchTerm, setUserSearchTerm] = useState(''); - - const colorRegistry = createGraphColorRegistry(theme.color); - const periodOptions = getPeriodOptions(); - - const typeDates = getPeriodDates(typePeriod); - const dailyDates = getPeriodDates(dailyPeriod); - const userDates = getPeriodDates(userPeriod); - - const { data: typeData, loading: typeLoading } = useQuery( - GetUsageAnalyticsDocument, - { variables: { input: typeDates } }, - ); - - const { data: dailyData, loading: dailyLoading } = useQuery( - GetUsageAnalyticsDocument, - { variables: { input: dailyDates } }, - ); - - const { data: userData, loading: userLoading } = useQuery( - GetUsageAnalyticsDocument, - { variables: { input: userDates } }, - ); - - const typeAnalytics = typeData?.getUsageAnalytics; - const dailyAnalytics = dailyData?.getUsageAnalytics; - const userAnalytics = userData?.getUsageAnalytics; - - const usageByOperationType = typeAnalytics?.usageByOperationType ?? []; - const timeSeries = dailyAnalytics?.timeSeries ?? []; - const usageByUser = userAnalytics?.usageByUser ?? []; - - const anyLoading = typeLoading || dailyLoading || userLoading; - - if (anyLoading) { - return null; - } - - const hasAnyData = - usageByOperationType.length > 0 || - timeSeries.length > 0 || - usageByUser.length > 0; - - const totalCredits = usageByOperationType.reduce( - (sum, item) => sum + item.creditsUsed, - 0, - ); - - const filteredUsageByUser = usageByUser.filter((item) => { - const search = normalizeSearchText(userSearchTerm); - const name = normalizeSearchText(item.label ?? item.key); - - return name.includes(search); - }); - - const pieData = usageByOperationType.map((item, index) => ({ - id: getOperationTypeLabel(item.key), - value: item.creditsUsed, - color: getColorSchemeByIndex(colorRegistry, index).solid, - })); - - const lineData: LineChartSeriesWithColor[] = [ - { - id: 'credits', - label: t`Credits`, - data: timeSeries.map((point) => ({ - x: formatDate(point.date, 'MMM d'), - y: point.creditsUsed, - })), - }, - ]; - - if (!hasAnyData) { + if (!isClickHouseConfigured) { return (
{ />
@@ -142,125 +36,39 @@ export const SettingsUsageAnalyticsSection = () => { return ( <> - {usageByOperationType.length > 0 && ( -
- - } + + + + getSettingsPath(SettingsPath.UsageUserDetail, { + userWorkspaceId, + }) + } + showAvatar + /> +
+ +
- )} - - {timeSeries.length > 0 && ( -
- - } - /> - - - - - -
- )} - - {usageByUser.length > 0 && ( -
- - } - /> - - - - - - {t`Name`} - {t`Credits`} - - - {filteredUsageByUser.map((item) => ( - - - - {item.label ?? item.key} - - - {formatNumber(item.creditsUsed)} - - - - - - - - ))} -
-
- )} + +
); }; diff --git a/packages/twenty-front/src/modules/settings/usage/components/UsageBreakdownPieSection.tsx b/packages/twenty-front/src/modules/settings/usage/components/UsageBreakdownPieSection.tsx new file mode 100644 index 0000000000..49ceab712a --- /dev/null +++ b/packages/twenty-front/src/modules/settings/usage/components/UsageBreakdownPieSection.tsx @@ -0,0 +1,101 @@ +import { createGraphColorRegistry } from '@/page-layout/widgets/graph/utils/createGraphColorRegistry'; +import { getColorSchemeByIndex } from '@/page-layout/widgets/graph/utils/getColorSchemeByIndex'; +import { SubscriptionInfoContainer } from '@/settings/billing/components/SubscriptionInfoContainer'; +import { UsagePieChart } from '@/settings/usage/components/UsagePieChart'; +import { UsageSectionSkeleton } from '@/settings/usage/components/UsageSectionSkeleton'; +import { useUsageAnalyticsData } from '@/settings/usage/hooks/useUsageAnalyticsData'; +import { useUsageValueFormatter } from '@/settings/usage/hooks/useUsageValueFormatter'; +import { getOperationTypeLabel } from '@/settings/usage/utils/getOperationTypeLabel'; +import { Select } from '@/ui/input/components/Select'; +import { useContext } from 'react'; +import { H2Title } from 'twenty-ui/display'; +import { Section } from 'twenty-ui/layout'; +import { ThemeContext } from 'twenty-ui/theme-constants'; +import { type UsageOperationType } from '~/generated-metadata/graphql'; + +type UsageBreakdownField = 'operationType' | 'model'; + +type UsageBreakdownPieSectionProps = { + title: string; + description?: string; + operationTypes?: UsageOperationType[]; + userWorkspaceId?: string; + skip?: boolean; + breakdownField: UsageBreakdownField; + sectionId: string; +}; + +export const UsageBreakdownPieSection = ({ + title, + description, + operationTypes, + userWorkspaceId, + skip, + breakdownField, + sectionId, +}: UsageBreakdownPieSectionProps) => { + const { theme } = useContext(ThemeContext); + const { formatUsageValue } = useUsageValueFormatter(); + const colorRegistry = createGraphColorRegistry(theme.color); + + const { analytics, isInitialLoading, period, setPeriod, periodOptions } = + useUsageAnalyticsData({ + operationTypes, + userWorkspaceId, + skip, + }); + + if (isInitialLoading) { + return ; + } + + if (!analytics) { + return null; + } + + const breakdownData = + breakdownField === 'operationType' + ? analytics.usageByOperationType + : analytics.usageByModel; + + if (breakdownData.length === 0) { + return null; + } + + const total = breakdownData.reduce((sum, item) => sum + item.creditsUsed, 0); + + const formatLabel = + breakdownField === 'operationType' + ? getOperationTypeLabel + : (key: string) => key; + + const pieData = breakdownData.map((item, index) => ({ + id: formatLabel(item.key), + value: item.creditsUsed, + color: getColorSchemeByIndex(colorRegistry, index).solid, + })); + + const resolvedDescription = description ?? formatUsageValue(total); + + return ( +
+ + } + /> + + + +
+ ); +}; diff --git a/packages/twenty-front/src/modules/settings/usage/components/UsageByUserTableSection.tsx b/packages/twenty-front/src/modules/settings/usage/components/UsageByUserTableSection.tsx new file mode 100644 index 0000000000..5a57edf350 --- /dev/null +++ b/packages/twenty-front/src/modules/settings/usage/components/UsageByUserTableSection.tsx @@ -0,0 +1,142 @@ +import { UsageSectionSkeleton } from '@/settings/usage/components/UsageSectionSkeleton'; +import { useUsageAnalyticsData } from '@/settings/usage/hooks/useUsageAnalyticsData'; +import { useUsageValueFormatter } from '@/settings/usage/hooks/useUsageValueFormatter'; +import { Select } from '@/ui/input/components/Select'; +import { Table } from '@/ui/layout/table/components/Table'; +import { TableCell } from '@/ui/layout/table/components/TableCell'; +import { TableHeader } from '@/ui/layout/table/components/TableHeader'; +import { TableRow } from '@/ui/layout/table/components/TableRow'; +import { styled } from '@linaria/react'; +import { t } from '@lingui/core/macro'; +import { useContext, useState } from 'react'; +import { Avatar, H2Title, IconChevronRight } from 'twenty-ui/display'; +import { SearchInput } from 'twenty-ui/input'; +import { Section } from 'twenty-ui/layout'; +import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants'; +import { type UsageOperationType } from '~/generated-metadata/graphql'; +import { normalizeSearchText } from '~/utils/normalizeSearchText'; + +const StyledSearchInputContainer = styled.div` + padding-bottom: ${themeCssVariables.spacing[2]}; +`; + +const StyledIconChevronRightContainer = styled.div` + color: ${themeCssVariables.font.color.tertiary}; +`; + +const GRID_TEMPLATE_COLUMNS = '1fr 120px 36px'; + +type UsageByUserTableSectionProps = { + title: string; + description: string; + operationTypes?: UsageOperationType[]; + skip?: boolean; + getDetailPath: (userWorkspaceId: string) => string; + showAvatar?: boolean; +}; + +export const UsageByUserTableSection = ({ + title, + description, + operationTypes, + skip, + getDetailPath, + showAvatar = false, +}: UsageByUserTableSectionProps) => { + const { theme } = useContext(ThemeContext); + const { formatUsageValue } = useUsageValueFormatter(); + const [searchTerm, setSearchTerm] = useState(''); + + const { analytics, isInitialLoading, period, setPeriod, periodOptions } = + useUsageAnalyticsData({ + operationTypes, + skip, + }); + + if (isInitialLoading) { + return ; + } + + if (!analytics) { + return null; + } + + const usageByUser = analytics.usageByUser; + + if (usageByUser.length === 0) { + return null; + } + + const filteredUsers = usageByUser.filter((item) => { + const search = normalizeSearchText(searchTerm); + const name = normalizeSearchText(item.label ?? item.key); + + return name.includes(search); + }); + + return ( +
+ + } + /> + + + + + + {t`Name`} + {t`Usage`} + + + {filteredUsers.map((item) => ( + + + {showAvatar && ( + + )} + {item.label ?? item.key} + + + {formatUsageValue(item.creditsUsed)} + + + + + + + + ))} +
+
+ ); +}; diff --git a/packages/twenty-front/src/modules/settings/usage/components/UsageDailyChartSection.tsx b/packages/twenty-front/src/modules/settings/usage/components/UsageDailyChartSection.tsx new file mode 100644 index 0000000000..c2bee73c61 --- /dev/null +++ b/packages/twenty-front/src/modules/settings/usage/components/UsageDailyChartSection.tsx @@ -0,0 +1,105 @@ +import { GraphWidgetLineChart } from '@/page-layout/widgets/graph/graph-widget-line-chart/components/GraphWidgetLineChart'; +import { type LineChartSeriesWithColor } from '@/page-layout/widgets/graph/graph-widget-line-chart/types/LineChartSeriesWithColor'; +import { WidgetComponentInstanceContext } from '@/page-layout/widgets/states/contexts/WidgetComponentInstanceContext'; +import { SubscriptionInfoContainer } from '@/settings/billing/components/SubscriptionInfoContainer'; +import { UsageSectionSkeleton } from '@/settings/usage/components/UsageSectionSkeleton'; +import { useUsageAnalyticsData } from '@/settings/usage/hooks/useUsageAnalyticsData'; +import { Select } from '@/ui/input/components/Select'; +import { styled } from '@linaria/react'; +import { H2Title } from 'twenty-ui/display'; +import { Section } from 'twenty-ui/layout'; +import { type UsageOperationType } from '~/generated-metadata/graphql'; +import { formatDate } from '~/utils/date-utils'; + +const StyledLineChartContainer = styled.div` + height: 200px; + width: 100%; +`; + +type UsageDailyChartSectionProps = { + title: string; + description: string; + chartId: string; + chartLabel: string; + operationTypes?: UsageOperationType[]; + userWorkspaceId?: string; + skip?: boolean; +}; + +export const UsageDailyChartSection = ({ + title, + description, + chartId, + chartLabel, + operationTypes, + userWorkspaceId, + skip, +}: UsageDailyChartSectionProps) => { + const { analytics, isInitialLoading, period, setPeriod, periodOptions } = + useUsageAnalyticsData({ + operationTypes, + userWorkspaceId, + skip, + }); + + if (isInitialLoading) { + return ; + } + + if (!analytics) { + return null; + } + + const timeSeries = userWorkspaceId + ? (analytics.userDailyUsage?.dailyUsage ?? []) + : analytics.timeSeries; + + if (timeSeries.length === 0) { + return null; + } + + const lineData: LineChartSeriesWithColor[] = [ + { + id: chartId, + label: chartLabel, + data: timeSeries.map((point) => ({ + x: formatDate(point.date, 'MMM d'), + y: point.creditsUsed, + })), + }, + ]; + + return ( +
+ + } + /> + + + + + + + +
+ ); +}; diff --git a/packages/twenty-front/src/modules/settings/usage/components/UsagePieChart.tsx b/packages/twenty-front/src/modules/settings/usage/components/UsagePieChart.tsx index 3854c2927d..10be83a390 100644 --- a/packages/twenty-front/src/modules/settings/usage/components/UsagePieChart.tsx +++ b/packages/twenty-front/src/modules/settings/usage/components/UsagePieChart.tsx @@ -1,10 +1,11 @@ import { CHART_MOTION_CONFIG } from '@/page-layout/widgets/graph/constants/ChartMotionConfig'; +import { GraphWidgetLegendDot } from '@/page-layout/widgets/graph/components/GraphWidgetLegendDot'; import { useNumberFormat } from '@/localization/hooks/useNumberFormat'; import { t } from '@lingui/core/macro'; import { styled } from '@linaria/react'; import { ResponsivePie } from '@nivo/pie'; import { useContext } from 'react'; -import { ThemeContext } from 'twenty-ui/theme-constants'; +import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants'; type UsagePieChartDatum = { id: string; @@ -21,6 +22,35 @@ const StyledContainer = styled.div` width: 100%; `; +const StyledTooltip = styled.div` + background: ${themeCssVariables.background.primary}; + border: 1px solid ${themeCssVariables.border.color.light}; + border-radius: ${themeCssVariables.border.radius.md}; + box-shadow: ${themeCssVariables.boxShadow.strong}; + display: flex; + flex-direction: column; + gap: ${themeCssVariables.spacing[2]}; + padding: ${themeCssVariables.spacing[2]}; +`; + +const StyledTooltipRow = styled.div` + align-items: center; + display: flex; + font-size: ${themeCssVariables.font.size.xs}; + gap: ${themeCssVariables.spacing[2]}; +`; + +const StyledTooltipLabel = styled.span` + color: ${themeCssVariables.font.color.secondary}; + font-weight: ${themeCssVariables.font.weight.medium}; +`; + +const StyledTooltipValue = styled.span` + color: ${themeCssVariables.font.color.tertiary}; + font-weight: ${themeCssVariables.font.weight.semiBold}; + white-space: nowrap; +`; + export const UsagePieChart = ({ data }: UsagePieChartProps) => { const { theme } = useContext(ThemeContext); const { formatNumber } = useNumberFormat(); @@ -44,7 +74,15 @@ export const UsagePieChart = ({ data }: UsagePieChartProps) => { animate motionConfig={CHART_MOTION_CONFIG} tooltip={({ datum }) => ( -
{`${String(datum.id)}: ${t`${formatNumber(datum.value)} credits`}`}
+ + + + {String(datum.id)} + + {t`${formatNumber(datum.value)} credits`} + + + )} /> diff --git a/packages/twenty-front/src/modules/settings/usage/components/UsageSectionSkeleton.tsx b/packages/twenty-front/src/modules/settings/usage/components/UsageSectionSkeleton.tsx new file mode 100644 index 0000000000..81caf1ad3e --- /dev/null +++ b/packages/twenty-front/src/modules/settings/usage/components/UsageSectionSkeleton.tsx @@ -0,0 +1,27 @@ +import { useContext } from 'react'; + +import Skeleton, { SkeletonTheme } from 'react-loading-skeleton'; +import { Section } from 'twenty-ui/layout'; +import { ThemeContext } from 'twenty-ui/theme-constants'; + +export const UsageSectionSkeleton = () => { + const { theme } = useContext(ThemeContext); + + return ( + +
+ + +
+
+ ); +}; diff --git a/packages/twenty-front/src/modules/settings/usage/constants/AiOperationTypes.ts b/packages/twenty-front/src/modules/settings/usage/constants/AiOperationTypes.ts new file mode 100644 index 0000000000..7a1a342c9d --- /dev/null +++ b/packages/twenty-front/src/modules/settings/usage/constants/AiOperationTypes.ts @@ -0,0 +1,6 @@ +import { UsageOperationType } from '~/generated-metadata/graphql'; + +export const AI_OPERATION_TYPES: UsageOperationType[] = [ + UsageOperationType.AI_CHAT_TOKEN, + UsageOperationType.AI_WORKFLOW_TOKEN, +]; diff --git a/packages/twenty-front/src/modules/settings/usage/graphql/queries/getUsageAnalytics.ts b/packages/twenty-front/src/modules/settings/usage/graphql/queries/getUsageAnalytics.ts index b956c9cc11..c53f64ccc6 100644 --- a/packages/twenty-front/src/modules/settings/usage/graphql/queries/getUsageAnalytics.ts +++ b/packages/twenty-front/src/modules/settings/usage/graphql/queries/getUsageAnalytics.ts @@ -12,6 +12,10 @@ export const GET_USAGE_ANALYTICS = gql` key creditsUsed } + usageByModel { + key + creditsUsed + } timeSeries { date creditsUsed diff --git a/packages/twenty-front/src/modules/settings/usage/hooks/useUsageAnalyticsData.ts b/packages/twenty-front/src/modules/settings/usage/hooks/useUsageAnalyticsData.ts new file mode 100644 index 0000000000..e5f9675fba --- /dev/null +++ b/packages/twenty-front/src/modules/settings/usage/hooks/useUsageAnalyticsData.ts @@ -0,0 +1,51 @@ +import { useQuery } from '@apollo/client/react'; +import { useState } from 'react'; + +import { getPeriodDates } from '@/settings/usage/utils/getPeriodDates'; +import { getPeriodOptions } from '@/settings/usage/utils/getPeriodOptions'; +import { type PeriodPreset } from '@/settings/usage/utils/periodPreset'; +import { + GetUsageAnalyticsDocument, + type UsageOperationType, +} from '~/generated-metadata/graphql'; + +type UseUsageAnalyticsDataParams = { + operationTypes?: UsageOperationType[]; + userWorkspaceId?: string; + skip?: boolean; +}; + +export const useUsageAnalyticsData = ({ + operationTypes, + userWorkspaceId, + skip, +}: UseUsageAnalyticsDataParams) => { + const [period, setPeriod] = useState('30d'); + + const periodDates = getPeriodDates(period); + const periodOptions = getPeriodOptions(); + + const { data, loading, previousData } = useQuery(GetUsageAnalyticsDocument, { + variables: { + input: { + ...periodDates, + ...(operationTypes ? { operationTypes } : {}), + ...(userWorkspaceId ? { userWorkspaceId } : {}), + }, + }, + skip, + }); + + const effectiveData = data ?? previousData; + const analytics = effectiveData?.getUsageAnalytics; + const isInitialLoading = loading && !effectiveData; + + return { + analytics, + loading, + isInitialLoading, + period, + setPeriod, + periodOptions, + }; +}; diff --git a/packages/twenty-front/src/modules/settings/usage/hooks/useUsageValueFormatter.ts b/packages/twenty-front/src/modules/settings/usage/hooks/useUsageValueFormatter.ts new file mode 100644 index 0000000000..2b752b501a --- /dev/null +++ b/packages/twenty-front/src/modules/settings/usage/hooks/useUsageValueFormatter.ts @@ -0,0 +1,21 @@ +import { billingState } from '@/client-config/states/billingState'; +import { useNumberFormat } from '@/localization/hooks/useNumberFormat'; +import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; + +export const useUsageValueFormatter = () => { + const billing = useAtomStateValue(billingState); + const isBillingEnabled = billing?.isBillingEnabled ?? false; + const { formatNumber } = useNumberFormat(); + + const formatUsageValue = (value: number): string => { + if (isBillingEnabled) { + return `${formatNumber(value)} credits`; + } + + return `$${formatNumber(value, { decimals: 2 })}`; + }; + + const unitLabel = isBillingEnabled ? 'credits' : '$'; + + return { formatUsageValue, isBillingEnabled, unitLabel }; +}; diff --git a/packages/twenty-front/src/modules/settings/usage/utils/getOperationTypeLabel.ts b/packages/twenty-front/src/modules/settings/usage/utils/getOperationTypeLabel.ts index aca29c9481..46c27adde5 100644 --- a/packages/twenty-front/src/modules/settings/usage/utils/getOperationTypeLabel.ts +++ b/packages/twenty-front/src/modules/settings/usage/utils/getOperationTypeLabel.ts @@ -2,8 +2,10 @@ import { t } from '@lingui/core/macro'; export const getOperationTypeLabel = (key: string): string => { switch (key) { - case 'AI_TOKEN': + case 'AI_CHAT_TOKEN': return t`AI Chat`; + case 'AI_WORKFLOW_TOKEN': + return t`AI Workflow`; case 'WORKFLOW_EXECUTION': return t`Workflow Execution`; case 'CODE_EXECUTION': diff --git a/packages/twenty-front/src/modules/ui/layout/page-header/components/PageHeaderToggleSidePanelButton.tsx b/packages/twenty-front/src/modules/ui/layout/page-header/components/PageHeaderToggleSidePanelButton.tsx index e03906067d..dc6da71d91 100644 --- a/packages/twenty-front/src/modules/ui/layout/page-header/components/PageHeaderToggleSidePanelButton.tsx +++ b/packages/twenty-front/src/modules/ui/layout/page-header/components/PageHeaderToggleSidePanelButton.tsx @@ -6,7 +6,6 @@ import { RootStackingContextZIndices } from '@/ui/layout/constants/RootStackingC import { PAGE_HEADER_SIDE_PANEL_BUTTON_CLICK_OUTSIDE_ID } from '@/ui/layout/page-header/constants/PageHeaderSidePanelButtonClickOutsideId'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { styled } from '@linaria/react'; -import { i18n } from '@lingui/core'; import { t } from '@lingui/core/macro'; import { motion } from 'framer-motion'; import { useContext } from 'react'; @@ -167,7 +166,7 @@ export const PageHeaderToggleSidePanelButton = () => { { children: Workspace, href: getSettingsPath(SettingsPath.Workspace), }, + { + children: Billing, + href: getSettingsPath(SettingsPath.Billing), + }, { children: Usage }, ]} > diff --git a/packages/twenty-front/src/pages/settings/SettingsUsageUserDetail.tsx b/packages/twenty-front/src/pages/settings/SettingsUsageUserDetail.tsx index 2eb3b46e44..e8f984b6b9 100644 --- a/packages/twenty-front/src/pages/settings/SettingsUsageUserDetail.tsx +++ b/packages/twenty-front/src/pages/settings/SettingsUsageUserDetail.tsx @@ -1,32 +1,23 @@ import { SettingsBillingLabelValueItem } from '@/settings/billing/components/internal/SettingsBillingLabelValueItem'; import { SubscriptionInfoContainer } from '@/settings/billing/components/SubscriptionInfoContainer'; -import { useNumberFormat } from '@/localization/hooks/useNumberFormat'; -import { GraphWidgetLineChart } from '@/page-layout/widgets/graph/graph-widget-line-chart/components/GraphWidgetLineChart'; -import { type LineChartSeriesWithColor } from '@/page-layout/widgets/graph/graph-widget-line-chart/types/LineChartSeriesWithColor'; -import { createGraphColorRegistry } from '@/page-layout/widgets/graph/utils/createGraphColorRegistry'; -import { getColorSchemeByIndex } from '@/page-layout/widgets/graph/utils/getColorSchemeByIndex'; -import { Select } from '@/ui/input/components/Select'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; +import { UsageBreakdownPieSection } from '@/settings/usage/components/UsageBreakdownPieSection'; +import { UsageDailyChartSection } from '@/settings/usage/components/UsageDailyChartSection'; +import { UsageSectionSkeleton } from '@/settings/usage/components/UsageSectionSkeleton'; +import { useUsageAnalyticsData } from '@/settings/usage/hooks/useUsageAnalyticsData'; +import { useUsageValueFormatter } from '@/settings/usage/hooks/useUsageValueFormatter'; import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; -import { getOperationTypeLabel } from '@/settings/usage/utils/getOperationTypeLabel'; -import { getPeriodDates } from '@/settings/usage/utils/getPeriodDates'; -import { getPeriodOptions } from '@/settings/usage/utils/getPeriodOptions'; -import { type PeriodPreset } from '@/settings/usage/utils/periodPreset'; -import { UsagePieChart } from '@/settings/usage/components/UsagePieChart'; -import { Trans, useLingui } from '@lingui/react/macro'; -import { t } from '@lingui/core/macro'; import { styled } from '@linaria/react'; -import { useContext, useState } from 'react'; +import { t } from '@lingui/core/macro'; +import { Trans, useLingui } from '@lingui/react/macro'; +import { useContext } from 'react'; import Skeleton, { SkeletonTheme } from 'react-loading-skeleton'; import { useParams } from 'react-router-dom'; import { SettingsPath } from 'twenty-shared/types'; import { getSettingsPath } from 'twenty-shared/utils'; -import { Avatar, H2Title } from 'twenty-ui/display'; +import { Avatar } from 'twenty-ui/display'; import { Section } from 'twenty-ui/layout'; import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants'; -import { useQuery } from '@apollo/client/react'; -import { GetUsageAnalyticsDocument } from '~/generated-metadata/graphql'; -import { formatDate } from '~/utils/date-utils'; const StyledUserHeader = styled.div` align-items: center; @@ -51,96 +42,44 @@ const StyledUserCredits = styled.span` font-size: ${themeCssVariables.font.size.sm}; `; -const StyledLineChartContainer = styled.div` - height: 200px; - width: 100%; -`; - export const SettingsUsageUserDetail = () => { const { t: tLingui } = useLingui(); const { userWorkspaceId } = useParams<{ userWorkspaceId: string }>(); const { theme } = useContext(ThemeContext); - const { formatNumber } = useNumberFormat(); - const colorRegistry = createGraphColorRegistry(theme.color); + const { formatUsageValue } = useUsageValueFormatter(); - const [dailyPeriod, setDailyPeriod] = useState('30d'); - const [typePeriod, setTypePeriod] = useState('30d'); + const { analytics, isInitialLoading } = useUsageAnalyticsData({ + userWorkspaceId, + skip: !userWorkspaceId, + }); - const periodOptions = getPeriodOptions(); + const userName = analytics?.usageByUser?.find( + (item) => item.key === userWorkspaceId, + )?.label; - const dailyDates = getPeriodDates(dailyPeriod); - const typeDates = getPeriodDates(typePeriod); - - const { data: dailyData, loading: dailyLoading } = useQuery( - GetUsageAnalyticsDocument, - { - variables: { - input: { - ...dailyDates, - userWorkspaceId, - }, - }, - skip: !userWorkspaceId, - }, - ); - - const { data: typeData, loading: typeLoading } = useQuery( - GetUsageAnalyticsDocument, - { - variables: { - input: { - ...typeDates, - userWorkspaceId, - }, - }, - skip: !userWorkspaceId, - }, - ); - - const dailyAnalytics = dailyData?.getUsageAnalytics; - const typeAnalytics = typeData?.getUsageAnalytics; - - const userDailyUsage = dailyAnalytics?.userDailyUsage?.dailyUsage ?? []; - const usageByOperationType = typeAnalytics?.usageByOperationType ?? []; - - const userName = - dailyAnalytics?.usageByUser?.find((item) => item.key === userWorkspaceId) - ?.label ?? - typeAnalytics?.usageByUser?.find((item) => item.key === userWorkspaceId) - ?.label; - - const totalCredits = usageByOperationType.reduce( - (sum, item) => sum + item.creditsUsed, - 0, - ); + const totalCredits = analytics + ? analytics.usageByOperationType.reduce( + (sum, item) => sum + item.creditsUsed, + 0, + ) + : 0; const displayName = userName ?? userWorkspaceId ?? ''; - const pieData = usageByOperationType.map((item, index) => ({ - id: getOperationTypeLabel(item.key), - value: item.creditsUsed, - color: getColorSchemeByIndex(colorRegistry, index).solid, - })); - - const lineData: LineChartSeriesWithColor[] = [ - { - id: 'credits', - label: t`Credits`, - data: userDailyUsage.map((point) => ({ - x: formatDate(point.date, 'MMM d'), - y: point.creditsUsed, - })), - }, - ]; - - const isInitialLoading = - (dailyLoading || typeLoading) && !dailyData && !typeData; + const hasAnyData = analytics + ? (analytics.userDailyUsage?.dailyUsage?.length ?? 0) > 0 || + analytics.usageByOperationType.length > 0 + : false; const breadcrumbLinks = [ { children: Workspace, href: getSettingsPath(SettingsPath.Workspace), }, + { + children: Billing, + href: getSettingsPath(SettingsPath.Billing), + }, { children: Usage, href: getSettingsPath(SettingsPath.Usage), @@ -167,24 +106,8 @@ export const SettingsUsageUserDetail = () => { -
- - -
-
- - -
+ + @@ -204,12 +127,12 @@ export const SettingsUsageUserDetail = () => { {displayName} - {t`${formatNumber(totalCredits)} credits used`} + {t`${formatUsageValue(totalCredits)} used`} - {userDailyUsage.length === 0 && pieData.length === 0 && ( + {!hasAnyData && (
{
)} - {userDailyUsage.length > 0 && ( -
- - } - /> - - - - - -
- )} - - {usageByOperationType.length > 0 && ( -
- - } - /> - - - -
- )} + + ); diff --git a/packages/twenty-front/src/pages/settings/ai/SettingsAI.tsx b/packages/twenty-front/src/pages/settings/ai/SettingsAI.tsx index ee7cfece90..cf23c2aa49 100644 --- a/packages/twenty-front/src/pages/settings/ai/SettingsAI.tsx +++ b/packages/twenty-front/src/pages/settings/ai/SettingsAI.tsx @@ -7,12 +7,14 @@ import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBa import { TabList } from '@/ui/layout/tab-list/components/TabList'; import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; -import { SettingsPath } from 'twenty-shared/types'; +import { FeatureFlagKey, SettingsPath } from 'twenty-shared/types'; import { getSettingsPath } from 'twenty-shared/utils'; +import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { t } from '@lingui/core/macro'; import { H2Title, + IconChartBar, IconCpu, IconFileText, IconSettingsBolt, @@ -23,6 +25,7 @@ import { Button } from 'twenty-ui/input'; import { Card, Section } from 'twenty-ui/layout'; import { SettingsAIMCP } from './components/SettingsAIMCP'; import { SettingsAIModelsTab } from './components/SettingsAIModelsTab'; +import { SettingsAIUsageTab } from './components/SettingsAIUsageTab'; import { SettingsAgentSkills } from './components/SettingsAgentSkills'; import { SettingsToolsTable } from './components/SettingsToolsTable'; import { SETTINGS_AI_TABS } from './constants/SettingsAiTabs'; @@ -39,6 +42,10 @@ export const SettingsAI = () => { SETTINGS_AI_TABS.COMPONENT_INSTANCE_ID, ); + const isUsageAnalyticsEnabled = useIsFeatureEnabled( + FeatureFlagKey.IS_USAGE_ANALYTICS_ENABLED, + ); + const tabs = [ { id: SETTINGS_AI_TABS.TABS_IDS.MODELS, @@ -55,6 +62,15 @@ export const SettingsAI = () => { title: t`Tools`, Icon: IconTool, }, + ...(isUsageAnalyticsEnabled + ? [ + { + id: SETTINGS_AI_TABS.TABS_IDS.USAGE, + title: t`Usage`, + Icon: IconChartBar, + }, + ] + : []), { id: SETTINGS_AI_TABS.TABS_IDS.MORE, title: t`More`, @@ -65,6 +81,7 @@ export const SettingsAI = () => { const isModelsTab = activeTabId === SETTINGS_AI_TABS.TABS_IDS.MODELS; const isSkillsTab = activeTabId === SETTINGS_AI_TABS.TABS_IDS.SKILLS; const isToolsTab = activeTabId === SETTINGS_AI_TABS.TABS_IDS.TOOLS; + const isUsageTab = activeTabId === SETTINGS_AI_TABS.TABS_IDS.USAGE; const isMoreTab = activeTabId === SETTINGS_AI_TABS.TABS_IDS.MORE; return ( @@ -86,6 +103,7 @@ export const SettingsAI = () => { {isModelsTab && } {isSkillsTab && } {isToolsTab && } + {isUsageTab && } {isMoreTab && ( <>
diff --git a/packages/twenty-front/src/pages/settings/ai/SettingsAIUsageUserDetail.tsx b/packages/twenty-front/src/pages/settings/ai/SettingsAIUsageUserDetail.tsx new file mode 100644 index 0000000000..2e1134a08c --- /dev/null +++ b/packages/twenty-front/src/pages/settings/ai/SettingsAIUsageUserDetail.tsx @@ -0,0 +1,107 @@ +import { SettingsBillingLabelValueItem } from '@/settings/billing/components/internal/SettingsBillingLabelValueItem'; +import { SubscriptionInfoContainer } from '@/settings/billing/components/SubscriptionInfoContainer'; +import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; +import { UsageBreakdownPieSection } from '@/settings/usage/components/UsageBreakdownPieSection'; +import { UsageDailyChartSection } from '@/settings/usage/components/UsageDailyChartSection'; +import { UsageSectionSkeleton } from '@/settings/usage/components/UsageSectionSkeleton'; +import { AI_OPERATION_TYPES } from '@/settings/usage/constants/AiOperationTypes'; +import { useUsageAnalyticsData } from '@/settings/usage/hooks/useUsageAnalyticsData'; +import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { t } from '@lingui/core/macro'; +import { Trans, useLingui } from '@lingui/react/macro'; +import { useParams } from 'react-router-dom'; +import { SettingsPath } from 'twenty-shared/types'; +import { getSettingsPath } from 'twenty-shared/utils'; +import { Section } from 'twenty-ui/layout'; + +export const SettingsAIUsageUserDetail = () => { + const { t: tLingui } = useLingui(); + const { userWorkspaceId } = useParams<{ userWorkspaceId: string }>(); + + const { analytics, isInitialLoading } = useUsageAnalyticsData({ + operationTypes: AI_OPERATION_TYPES, + userWorkspaceId, + skip: !userWorkspaceId, + }); + + const userName = analytics?.usageByUser?.find( + (item) => item.key === userWorkspaceId, + )?.label; + + const displayName = userName ?? userWorkspaceId ?? ''; + + const hasAnyData = analytics + ? (analytics.userDailyUsage?.dailyUsage?.length ?? 0) > 0 || + analytics.usageByOperationType.length > 0 + : false; + + const breadcrumbLinks = [ + { + children: Workspace, + href: getSettingsPath(SettingsPath.Workspace), + }, + { + children: AI, + href: getSettingsPath(SettingsPath.AI), + }, + { children: isInitialLoading ? '' : displayName }, + ]; + + if (isInitialLoading) { + return ( + + + + + + + ); + } + + return ( + + + {!hasAnyData && ( +
+ + + +
+ )} + + + + +
+
+ ); +}; diff --git a/packages/twenty-front/src/pages/settings/ai/components/SettingsAIUsageTab.tsx b/packages/twenty-front/src/pages/settings/ai/components/SettingsAIUsageTab.tsx new file mode 100644 index 0000000000..49256edb8c --- /dev/null +++ b/packages/twenty-front/src/pages/settings/ai/components/SettingsAIUsageTab.tsx @@ -0,0 +1,101 @@ +import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; +import { billingState } from '@/client-config/states/billingState'; +import { isClickHouseConfiguredState } from '@/client-config/states/isClickHouseConfiguredState'; +import { SettingsBillingLabelValueItem } from '@/settings/billing/components/internal/SettingsBillingLabelValueItem'; +import { SubscriptionInfoContainer } from '@/settings/billing/components/SubscriptionInfoContainer'; +import { SettingsEnterpriseFeatureGateCard } from '@/settings/components/SettingsEnterpriseFeatureGateCard'; +import { UsageBreakdownPieSection } from '@/settings/usage/components/UsageBreakdownPieSection'; +import { UsageByUserTableSection } from '@/settings/usage/components/UsageByUserTableSection'; +import { UsageDailyChartSection } from '@/settings/usage/components/UsageDailyChartSection'; +import { AI_OPERATION_TYPES } from '@/settings/usage/constants/AiOperationTypes'; +import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; +import { t } from '@lingui/core/macro'; +import { SettingsPath } from 'twenty-shared/types'; +import { getSettingsPath } from 'twenty-shared/utils'; +import { Tag } from 'twenty-ui/components'; +import { H2Title, IconLock } from 'twenty-ui/display'; +import { Section } from 'twenty-ui/layout'; + +export const SettingsAIUsageTab = () => { + const currentWorkspace = useAtomStateValue(currentWorkspaceState); + const billing = useAtomStateValue(billingState); + const isBillingEnabled = billing?.isBillingEnabled ?? false; + const isClickHouseConfigured = useAtomStateValue(isClickHouseConfiguredState); + + const hasEnterpriseAccess = + isBillingEnabled || currentWorkspace?.hasValidEnterpriseKey === true; + + if (!hasEnterpriseAccess) { + return ( +
+ + } + /> + +
+ ); + } + + if (!isClickHouseConfigured) { + return ( +
+ + + + +
+ ); + } + + return ( + <> + + + + + getSettingsPath(SettingsPath.AIUsageUserDetail, { + userWorkspaceId, + }) + } + /> + + ); +}; diff --git a/packages/twenty-front/src/pages/settings/ai/constants/SettingsAiTabs.ts b/packages/twenty-front/src/pages/settings/ai/constants/SettingsAiTabs.ts index 37adb796cf..285b7a1ff2 100644 --- a/packages/twenty-front/src/pages/settings/ai/constants/SettingsAiTabs.ts +++ b/packages/twenty-front/src/pages/settings/ai/constants/SettingsAiTabs.ts @@ -4,6 +4,7 @@ export const SETTINGS_AI_TABS = { MODELS: 'models', SKILLS: 'skills', TOOLS: 'tools', + USAGE: 'usage', MORE: 'more', }, } as const; diff --git a/packages/twenty-front/src/pages/settings/enterprise/SettingsEnterprise.tsx b/packages/twenty-front/src/pages/settings/enterprise/SettingsEnterprise.tsx index 5381be3e41..7a2b047171 100644 --- a/packages/twenty-front/src/pages/settings/enterprise/SettingsEnterprise.tsx +++ b/packages/twenty-front/src/pages/settings/enterprise/SettingsEnterprise.tsx @@ -311,7 +311,6 @@ export const SettingsEnterprise = ({
diff --git a/packages/twenty-front/src/pages/settings/security/SettingsSecurity.tsx b/packages/twenty-front/src/pages/settings/security/SettingsSecurity.tsx index 8f8965424a..d01568be36 100644 --- a/packages/twenty-front/src/pages/settings/security/SettingsSecurity.tsx +++ b/packages/twenty-front/src/pages/settings/security/SettingsSecurity.tsx @@ -8,6 +8,7 @@ import { authProvidersState } from '@/client-config/states/authProvidersState'; import { isClickHouseConfiguredState } from '@/client-config/states/isClickHouseConfiguredState'; import { isMultiWorkspaceEnabledState } from '@/client-config/states/isMultiWorkspaceEnabledState'; import { Separator } from '@/settings/components/Separator'; +import { SettingsEnterpriseFeatureGateCard } from '@/settings/components/SettingsEnterpriseFeatureGateCard'; import { SettingsOptionCardContentButton } from '@/settings/components/SettingsOptions/SettingsOptionCardContentButton'; import { SettingsOptionCardContentCounter } from '@/settings/components/SettingsOptions/SettingsOptionCardContentCounter'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; @@ -25,6 +26,7 @@ import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBa import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { CombinedGraphQLErrors } from '@apollo/client/errors'; +import { useMutation } from '@apollo/client/react'; import { SettingsPath } from 'twenty-shared/types'; import { getSettingsPath } from 'twenty-shared/utils'; import { Tag } from 'twenty-ui/components'; @@ -38,7 +40,6 @@ import { import { Button } from 'twenty-ui/input'; import { Card, Section } from 'twenty-ui/layout'; import { themeCssVariables } from 'twenty-ui/theme-constants'; -import { useMutation } from '@apollo/client/react'; import { UpdateWorkspaceDocument } from '~/generated-metadata/graphql'; const StyledContainer = styled.div` @@ -250,49 +251,53 @@ export const SettingsSecurity = () => { /> } /> - - + - -