Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc6cf719

Browse files
authored
feat: show user limit on active users chart (#10101)
1 parent38bb854 commitc6cf719

File tree

9 files changed

+118
-7
lines changed

9 files changed

+118
-7
lines changed

‎site/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
"canvas":"2.11.0",
5555
"chart.js":"4.4.0",
5656
"chartjs-adapter-date-fns":"3.0.0",
57+
"chartjs-plugin-annotation":"3.0.1",
5758
"chroma-js":"2.4.2",
5859
"color-convert":"2.0.1",
5960
"cron-parser":"4.9.0",

‎site/pnpm-lock.yaml

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎site/src/components/ActiveUserChart/ActiveUserChart.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
importdayjsfrom"dayjs";
2525
import{FC}from"react";
2626
import{Line}from"react-chartjs-2";
27+
importannotationPluginfrom"chartjs-plugin-annotation";
2728

2829
ChartJS.register(
2930
CategoryScale,
@@ -35,16 +36,21 @@ ChartJS.register(
3536
Title,
3637
Tooltip,
3738
Legend,
39+
annotationPlugin,
3840
);
3941

42+
constUSER_LIMIT_DISPLAY_THRESHOLD=60;
43+
4044
exportinterfaceActiveUserChartProps{
4145
data:{date:string;amount:number}[];
4246
interval:"day"|"week";
47+
userLimit:number|undefined;
4348
}
4449

4550
exportconstActiveUserChart:FC<ActiveUserChartProps>=({
4651
data,
4752
interval,
53+
userLimit,
4854
})=>{
4955
consttheme:Theme=useTheme();
5056

@@ -57,6 +63,24 @@ export const ActiveUserChart: FC<ActiveUserChartProps> = ({
5763
constoptions:ChartOptions<"line">={
5864
responsive:true,
5965
plugins:{
66+
annotation:{
67+
annotations:[
68+
{
69+
type:"line",
70+
scaleID:"y",
71+
display:shouldDisplayUserLimit(userLimit,chartData),
72+
value:userLimit,
73+
borderColor:theme.palette.secondary.contrastText,
74+
borderWidth:5,
75+
label:{
76+
content:"User limit",
77+
color:theme.palette.primary.contrastText,
78+
display:true,
79+
font:{weight:"normal"},
80+
},
81+
},
82+
],
83+
},
6084
legend:{
6185
display:false,
6286
},
@@ -127,3 +151,15 @@ export const ActiveUsersTitle = () => {
127151
</Box>
128152
);
129153
};
154+
155+
functionshouldDisplayUserLimit(
156+
userLimit:number|undefined,
157+
activeUsers:number[],
158+
):boolean{
159+
if(!userLimit||activeUsers.length===0){
160+
returnfalse;
161+
}
162+
return(
163+
Math.max(...activeUsers)>=(userLimit*USER_LIMIT_DISPLAY_THRESHOLD)/100
164+
);
165+
}

‎site/src/pages/DeploySettingsPage/GeneralSettingsPage/GeneralSettingsPage.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ import { pageTitle } from "utils/page";
55
import{GeneralSettingsPageView}from"./GeneralSettingsPageView";
66
import{useQuery}from"react-query";
77
import{deploymentDAUs}from"api/queries/deployment";
8+
import{entitlements}from"api/queries/entitlements";
89

910
constGeneralSettingsPage:FC=()=>{
1011
const{ deploymentValues}=useDeploySettings();
1112
constdeploymentDAUsQuery=useQuery(deploymentDAUs());
13+
constentitlementsQuery=useQuery(entitlements());
1214

1315
return(
1416
<>
@@ -19,6 +21,7 @@ const GeneralSettingsPage: FC = () => {
1921
deploymentOptions={deploymentValues.options}
2022
deploymentDAUs={deploymentDAUsQuery.data}
2123
deploymentDAUsError={deploymentDAUsQuery.error}
24+
entitlements={entitlementsQuery.data}
2225
/>
2326
</>
2427
);

‎site/src/pages/DeploySettingsPage/GeneralSettingsPage/GeneralSettingsPageView.stories.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import{Meta,StoryObj}from"@storybook/react";
2-
import{mockApiError,MockDeploymentDAUResponse}from"testHelpers/entities";
2+
import{
3+
mockApiError,
4+
MockDeploymentDAUResponse,
5+
MockEntitlementsWithUserLimit,
6+
}from"testHelpers/entities";
37
import{GeneralSettingsPageView}from"./GeneralSettingsPageView";
48

59
constmeta:Meta<typeofGeneralSettingsPageView>={
@@ -44,6 +48,13 @@ type Story = StoryObj<typeof GeneralSettingsPageView>;
4448

4549
exportconstPage:Story={};
4650

51+
exportconstWithUserLimit:Story={
52+
args:{
53+
deploymentDAUs:MockDeploymentDAUResponse,
54+
entitlements:MockEntitlementsWithUserLimit,
55+
},
56+
};
57+
4758
exportconstNoDAUs:Story={
4859
args:{
4960
deploymentDAUs:undefined,

‎site/src/pages/DeploySettingsPage/GeneralSettingsPage/GeneralSettingsPageView.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
importBoxfrom"@mui/material/Box";
2-
import{ClibaseOption,DAUsResponse}from"api/typesGenerated";
2+
import{ClibaseOption,DAUsResponse,Entitlements}from"api/typesGenerated";
33
import{ErrorAlert}from"components/Alert/ErrorAlert";
44
import{
55
ActiveUserChart,
@@ -16,11 +16,13 @@ export type GeneralSettingsPageViewProps = {
1616
deploymentOptions:ClibaseOption[];
1717
deploymentDAUs?:DAUsResponse;
1818
deploymentDAUsError:unknown;
19+
entitlements:Entitlements|undefined;
1920
};
2021
exportconstGeneralSettingsPageView=({
2122
deploymentOptions,
2223
deploymentDAUs,
2324
deploymentDAUsError,
25+
entitlements,
2426
}:GeneralSettingsPageViewProps):JSX.Element=>{
2527
return(
2628
<>
@@ -36,7 +38,15 @@ export const GeneralSettingsPageView = ({
3638
{deploymentDAUs&&(
3739
<Boxheight={200}sx={{mb:3}}>
3840
<ChartSectiontitle={<ActiveUsersTitle/>}>
39-
<ActiveUserChartdata={deploymentDAUs.entries}interval="day"/>
41+
<ActiveUserChart
42+
data={deploymentDAUs.entries}
43+
interval="day"
44+
userLimit={
45+
entitlements?.features.user_limit.enabled
46+
?entitlements?.features.user_limit.limit
47+
:undefined
48+
}
49+
/>
4050
</ChartSection>
4151
</Box>
4252
)}

‎site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.stories.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
importtype{Meta,StoryObj}from"@storybook/react";
22
import{TemplateInsightsPageView}from"./TemplateInsightsPage";
3+
import{MockEntitlementsWithUserLimit}from"testHelpers/entities";
34

45
constmeta:Meta<typeofTemplateInsightsPageView>={
56
title:"pages/TemplateInsightsPageView",
@@ -515,7 +516,7 @@ export const Loaded: Story = {
515516
end_time:"2023-07-25T00:00:00Z",
516517
template_ids:["0d286645-29aa-4eaf-9b52-cc5d2740c90b"],
517518
interval:"day",
518-
active_users:11,
519+
active_users:16,
519520
},
520521
],
521522
},
@@ -861,3 +862,11 @@ export const Loaded: Story = {
861862
},
862863
},
863864
};
865+
866+
exportconstLoadedWithUserLimit:Story={
867+
...Loaded,
868+
args:{
869+
...Loaded.args,
870+
entitlements:MockEntitlementsWithUserLimit,
871+
},
872+
};

‎site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { Helmet } from "react-helmet-async";
2121
import{getTemplatePageTitle}from"../utils";
2222
import{Loader}from"components/Loader/Loader";
2323
import{
24+
Entitlements,
2425
Template,
2526
TemplateAppUsage,
2627
TemplateInsightsResponse,
@@ -48,6 +49,7 @@ import {
4849
insightsUserLatency,
4950
}from"api/queries/insights";
5051
import{useSearchParams}from"react-router-dom";
52+
import{entitlements}from"api/queries/entitlements";
5153

5254
constDEFAULT_NUMBER_OF_WEEKS=numberOfWeeksOptions[0];
5355

@@ -75,6 +77,7 @@ export default function TemplateInsightsPage() {
7577
const{data:templateInsights}=useQuery(insightsTemplate(insightsFilter));
7678
const{data:userLatency}=useQuery(insightsUserLatency(commonFilters));
7779
const{data:userActivity}=useQuery(insightsUserActivity(commonFilters));
80+
const{data:entitlementsQuery}=useQuery(entitlements());
7881

7982
return(
8083
<>
@@ -106,6 +109,7 @@ export default function TemplateInsightsPage() {
106109
userLatency={userLatency}
107110
userActivity={userActivity}
108111
interval={interval}
112+
entitlements={entitlementsQuery}
109113
/>
110114
</>
111115
);
@@ -146,12 +150,14 @@ export const TemplateInsightsPageView = ({
146150
templateInsights,
147151
userLatency,
148152
userActivity,
153+
entitlements,
149154
controls,
150155
interval,
151156
}:{
152157
templateInsights:TemplateInsightsResponse|undefined;
153158
userLatency:UserLatencyInsightsResponse|undefined;
154159
userActivity:UserActivityInsightsResponse|undefined;
160+
entitlements:Entitlements|undefined;
155161
controls:ReactNode;
156162
interval:InsightsInterval;
157163
})=>{
@@ -178,6 +184,11 @@ export const TemplateInsightsPageView = ({
178184
<ActiveUsersPanel
179185
sx={{gridColumn:"span 2"}}
180186
interval={interval}
187+
userLimit={
188+
entitlements?.features.user_limit.enabled
189+
?entitlements?.features.user_limit.limit
190+
:undefined
191+
}
181192
data={templateInsights?.interval_reports}
182193
/>
183194
<UsersLatencyPaneldata={userLatency}/>
@@ -198,10 +209,12 @@ export const TemplateInsightsPageView = ({
198209
constActiveUsersPanel=({
199210
data,
200211
interval,
212+
userLimit,
201213
...panelProps
202214
}:PanelProps&{
203215
data:TemplateInsightsResponse["interval_reports"]|undefined;
204216
interval:InsightsInterval;
217+
userLimit:number|undefined;
205218
})=>{
206219
return(
207220
<Panel{...panelProps}>
@@ -216,6 +229,7 @@ const ActiveUsersPanel = ({
216229
{data&&data.length>0&&(
217230
<ActiveUserChart
218231
interval={interval}
232+
userLimit={userLimit}
219233
data={data.map((d)=>({
220234
amount:d.active_users,
221235
date:d.start_time,

‎site/src/testHelpers/entities.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ export const MockTemplateDAUResponse: TypesGen.DAUsResponse = {
3030
exportconstMockDeploymentDAUResponse:TypesGen.DAUsResponse={
3131
tz_hour_offset:0,
3232
entries:[
33-
{date:"2022-08-27T00:00:00Z",amount:1},
34-
{date:"2022-08-29T00:00:00Z",amount:2},
35-
{date:"2022-08-30T00:00:00Z",amount:1},
33+
{date:"2022-08-27T00:00:00Z",amount:10},
34+
{date:"2022-08-29T00:00:00Z",amount:22},
35+
{date:"2022-08-30T00:00:00Z",amount:14},
3636
],
3737
};
3838
exportconstMockSessionToken:TypesGen.LoginWithPasswordResponse={
@@ -1925,6 +1925,22 @@ export const MockEntitlementsWithScheduling: TypesGen.Entitlements = {
19251925
}),
19261926
};
19271927

1928+
exportconstMockEntitlementsWithUserLimit:TypesGen.Entitlements={
1929+
errors:[],
1930+
warnings:[],
1931+
has_license:true,
1932+
require_telemetry:false,
1933+
trial:false,
1934+
refreshed_at:"2022-05-20T16:45:57.122Z",
1935+
features:withDefaultFeatures({
1936+
user_limit:{
1937+
enabled:true,
1938+
entitlement:"entitled",
1939+
limit:25,
1940+
},
1941+
}),
1942+
};
1943+
19281944
exportconstMockExperiments:TypesGen.Experiment[]=["moons"];
19291945

19301946
exportconstMockAuditLog:TypesGen.AuditLog={

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp