Skip to content

Commit ea3fe76

Browse files
JonasBapriscilawebdev
authored andcommitted
ui2: add enforce flag (#101988)
Add a flag to opt users into UI2 and the new experience
1 parent dda75a4 commit ea3fe76

File tree

5 files changed

+102
-11
lines changed

5 files changed

+102
-11
lines changed

static/app/utils/theme/useChonkPrompt.spec.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,25 @@ describe('useChonkPrompt', () => {
4242
expect(result.current.showDotIndicatorPrompt).toBe(false);
4343
});
4444

45+
it('org with chonk-ui-enforce does not show prompts', () => {
46+
MockApiClient.addMockResponse({
47+
url: '/organizations/org-slug/prompts-activity/',
48+
body: {data: {dismissed_ts: null}},
49+
});
50+
51+
MockApiClient.addMockResponse({
52+
url: '/organizations/org-slug/prompts-activity/',
53+
method: 'PUT',
54+
});
55+
56+
const {result} = renderHookWithProviders(() => useChonkPrompt(), {
57+
organization: OrganizationFixture({features: ['chonk-ui-enforce']}),
58+
});
59+
60+
expect(result.current.showBannerPrompt).toBe(false);
61+
expect(result.current.showDotIndicatorPrompt).toBe(false);
62+
});
63+
4564
it('dismissing tooltip prompt shows dot indicator prompt', async () => {
4665
MockApiClient.addMockResponse({
4766
url: '/organizations/org-slug/prompts-activity/',

static/app/utils/theme/useChonkPrompt.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,21 @@ function promptWasDismissedWithoutSnoozing(
3535
export function useChonkPrompt() {
3636
const user = useUser();
3737
const organization = useOrganization({allowNull: true});
38-
const hasChonkUI = organization?.features.includes('chonk-ui');
38+
const hasChonkUIAccess = organization?.features.includes('chonk-ui');
39+
const hasChonkUIEnforce = organization?.features.includes('chonk-ui-enforce');
3940

4041
const bannerPrompt = usePrompt({
4142
organization,
4243
feature: 'chonk_ui_banner',
4344
daysToSnooze: DAYS_SINCE_DISMISS,
44-
options: {enabled: hasChonkUI},
45+
options: {enabled: hasChonkUIAccess && !hasChonkUIEnforce},
4546
});
4647

4748
const dotIndicatorPrompt = usePrompt({
4849
organization,
4950
feature: 'chonk_ui_dot_indicator',
5051
daysToSnooze: DAYS_SINCE_DISMISS,
51-
options: {enabled: hasChonkUI},
52+
options: {enabled: hasChonkUIAccess && !hasChonkUIEnforce},
5253
});
5354

5455
const bannerData = bannerPrompt.data;
@@ -61,7 +62,7 @@ export function useChonkPrompt() {
6162
const showDotIndicatorPrompt = dotIndicatorPrompt.showPrompt;
6263

6364
useEffect(() => {
64-
if (!hasChonkUI) {
65+
if (!hasChonkUIAccess || hasChonkUIEnforce) {
6566
return;
6667
}
6768

@@ -91,7 +92,8 @@ export function useChonkPrompt() {
9192
dotIndicatorIsPromptDismissed,
9293
showBannerPrompt,
9394
showDotIndicatorPrompt,
94-
hasChonkUI,
95+
hasChonkUIAccess,
96+
hasChonkUIEnforce,
9597
user?.options?.prefersChonkUI,
9698
]);
9799

@@ -109,9 +111,10 @@ export function useChonkPrompt() {
109111

110112
// User is optional because we useUser hooks reads the value from ConfigStore,
111113
if (
114+
user?.options?.prefersChonkUI ||
112115
(bannerPrompt.isPromptDismissed && dotIndicatorPrompt.isPromptDismissed) ||
113-
!hasChonkUI ||
114-
user?.options?.prefersChonkUI
116+
!hasChonkUIAccess ||
117+
hasChonkUIEnforce
115118
) {
116119
return {
117120
showBannerPrompt: false,

static/app/utils/theme/useThemeSwitcher.spec.tsx

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,68 @@ describe('useChonkTheme', () => {
102102
expect(result.current).toBe(DO_NOT_USE_darkChonkTheme);
103103
});
104104
});
105+
106+
describe('enforce states', () => {
107+
it('returns light chonk theme if the organization has chonk-ui-enforce feature and user prefers chonk theme', () => {
108+
ConfigStore.loadInitialData(
109+
ConfigFixture({
110+
user: UserFixture({
111+
options: {...UserFixture().options, prefersChonkUI: true, theme: 'light'},
112+
}),
113+
})
114+
);
115+
OrganizationStore.onUpdate(OrganizationFixture({features: ['chonk-ui-enforce']}));
116+
const {result} = renderHookWithProviders(useThemeSwitcher);
117+
expect(result.current).toBe(DO_NOT_USE_lightChonkTheme);
118+
});
119+
120+
it('returns dark chonk theme if the organization has chonk-ui-enforce feature and user prefers chonk theme', () => {
121+
ConfigStore.loadInitialData(
122+
ConfigFixture({
123+
user: UserFixture({
124+
options: {...UserFixture().options, prefersChonkUI: true, theme: 'dark'},
125+
}),
126+
})
127+
);
128+
OrganizationStore.onUpdate(OrganizationFixture({features: ['chonk-ui-enforce']}));
129+
const {result} = renderHookWithProviders(useThemeSwitcher);
130+
expect(result.current).toBe(DO_NOT_USE_darkChonkTheme);
131+
});
132+
133+
it.each(['light', 'dark', 'system'] as const)(
134+
'opt-out is respected for opted out users',
135+
theme => {
136+
ConfigStore.loadInitialData(
137+
ConfigFixture({
138+
user: UserFixture({
139+
options: {...UserFixture().options, prefersChonkUI: false, theme},
140+
}),
141+
})
142+
);
143+
OrganizationStore.onUpdate(OrganizationFixture({features: ['chonk-ui-enforce']}));
144+
const {result} = renderHookWithProviders(useThemeSwitcher);
145+
expect(result.current).toBe(
146+
theme === 'light' || theme === 'system' ? lightTheme : darkTheme
147+
);
148+
}
149+
);
150+
151+
it.each(['light', 'dark', 'system'] as const)(
152+
'opt-out is respected for opted out users',
153+
theme => {
154+
ConfigStore.loadInitialData(
155+
ConfigFixture({
156+
user: UserFixture({
157+
options: {...UserFixture().options, prefersChonkUI: false, theme},
158+
}),
159+
})
160+
);
161+
OrganizationStore.onUpdate(OrganizationFixture({features: ['chonk-ui']}));
162+
const {result} = renderHookWithProviders(useThemeSwitcher);
163+
expect(result.current).toBe(
164+
theme === 'light' || theme === 'system' ? lightTheme : darkTheme
165+
);
166+
}
167+
);
168+
});
105169
});

static/app/utils/theme/useThemeSwitcher.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,12 @@ export function useThemeSwitcher(): DO_NOT_USE_ChonkTheme | Theme {
3131

3232
let theme: Theme | DO_NOT_USE_ChonkTheme =
3333
config.theme === 'dark' ? darkTheme : lightTheme;
34-
// Check feature access and if chonk theme is enabled
35-
if (organization?.features?.includes('chonk-ui') && user?.options?.prefersChonkUI) {
34+
35+
if (
36+
(organization?.features?.includes('chonk-ui') ||
37+
organization?.features?.includes('chonk-ui-enforce')) &&
38+
user?.options?.prefersChonkUI
39+
) {
3640
theme =
3741
config.theme === 'dark' ? DO_NOT_USE_darkChonkTheme : DO_NOT_USE_lightChonkTheme;
3842
}
@@ -70,7 +74,8 @@ export function useThemeSwitcher(): DO_NOT_USE_ChonkTheme | Theme {
7074
);
7175

7276
useHotkeys(
73-
organization?.features?.includes('chonk-ui')
77+
organization?.features?.includes('chonk-ui') ||
78+
organization?.features?.includes('chonk-ui-enforce')
7479
? [themeToggleHotkey, chonkThemeToggleHotkey]
7580
: [themeToggleHotkey]
7681
);

static/app/views/nav/primary/help.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ export function PrimaryNavigationHelp() {
147147
key: 'new-chonk-ui',
148148
label: (
149149
<Fragment>
150-
{t('Try our new look')} <FeatureBadge type="beta" />
150+
{t('Try our new look')} <FeatureBadge type="new" />
151151
</Fragment>
152152
),
153153
textValue: 'Try our new look',

0 commit comments

Comments
 (0)