From aae71e2f121fe53399adbf03d9cc7cb5d987ad14 Mon Sep 17 00:00:00 2001 From: wahyuwidharto Date: Mon, 13 Jul 2026 21:37:20 +0700 Subject: [PATCH 1/3] feat(admin): single-file build guidance in ADT build picker Add a non-blocking info banner at the top of the shared ADTBuildPickerModal so it surfaces in both the create-playtest form and the distribution tab's Change Build flow (both open the same picker). Collapsed it reads "Before uploading to ADT, package your build into a single file." with a Learn more toggle; expanded it explains that a single-file build yields one clean download link per invite while multi-file builds produce a link per file. Progressive disclosure keeps it out of the way. Info icon nudged to align with the title's first line. Adds a test covering the notice + Learn more / Show less toggle. --- admin/src/federated-element.test.tsx | 28 ++++++++++++++++++++++ admin/src/shared/adt-build-picker.tsx | 34 ++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/admin/src/federated-element.test.tsx b/admin/src/federated-element.test.tsx index a18976c..91607b4 100644 --- a/admin/src/federated-element.test.tsx +++ b/admin/src/federated-element.test.tsx @@ -472,6 +472,34 @@ describe('PlaytestCreatePage', () => { expect(within(dialog).getByText(/starfield dev/i)).toBeInTheDocument() }) + it('shows the single-file packaging notice with a Learn more / Show less toggle', async () => { + setLinkages() + mockGetAdtGames.mockReturnValue({ + data: { games: [{ id: 'game-1', name: 'Starfield Dev' }] }, + isLoading: false, + error: null + }) + renderAt('/new') + const user = userEvent.setup() + await gotoDistributionStep(user) + await user.click(screen.getByRole('radio', { name: /^ADT$/i })) + await user.click(screen.getByLabelText(/adt linkage/i)) + await user.click(await screen.findByText(/adt-ns-1/i)) + await user.click(await screen.findByRole('button', { name: /select game build/i })) + + const dialog = await screen.findByRole('dialog', { name: /select game build/i }) + const notice = within(dialog).getByTestId('adt-single-file-notice') + // Compact line is always present; the detail is hidden until "Learn more". + expect(within(notice).getByText(/package your build into a single file/i)).toBeInTheDocument() + expect(within(notice).queryByText(/harder to follow/i)).not.toBeInTheDocument() + + await user.click(within(notice).getByText(/learn more/i)) + expect(within(notice).getByText(/harder to follow/i)).toBeInTheDocument() + + await user.click(within(notice).getByText(/show less/i)) + expect(within(notice).queryByText(/harder to follow/i)).not.toBeInTheDocument() + }) + it('groups builds by game_version_name in the left rail with per-version build counts', async () => { setLinkages() mockGetAdtGames.mockReturnValue({ diff --git a/admin/src/shared/adt-build-picker.tsx b/admin/src/shared/adt-build-picker.tsx index 0bbdb4a..734c4b2 100644 --- a/admin/src/shared/adt-build-picker.tsx +++ b/admin/src/shared/adt-build-picker.tsx @@ -1,5 +1,6 @@ import { useAppUIContext } from '@accelbyte/sdk-extend-app-ui' -import { Card, Modal, Select, Space, Tag, Typography } from 'antd' +import { InfoCircleFilled } from '@ant-design/icons' +import { Alert, Card, Modal, Select, Space, Tag, Typography } from 'antd' import { useMemo, useState } from 'react' import type { V1AdtBuild } from '../playtesthubapi/generated-definitions/V1AdtBuild' import type { V1AdtGame } from '../playtesthubapi/generated-definitions/V1AdtGame' @@ -30,6 +31,7 @@ export function ADTBuildPickerModal({ const [gameId, setGameId] = useState(initialGameId) const [versionName, setVersionName] = useState(null) const [pickedBuildId, setPickedBuildId] = useState(null) + const [showSingleFileDetail, setShowSingleFileDetail] = useState(false) const buildsQuery = usePlaytesthubServiceAdminApi_GetBuildsAdt_ByAdtLinkageId( sdk, @@ -68,6 +70,36 @@ export function ADTBuildPickerModal({ Choose a game, select a version, then pick a specific build to use for this playtest. + } + style={{ marginBottom: 16, alignItems: 'flex-start' }} + data-testid="adt-single-file-notice" + message={ +
+ Before uploading to ADT, package your build into a single file. + {!showSingleFileDetail && ( + <> + {' '} + setShowSingleFileDetail(true)}>Learn more + + )} + {showSingleFileDetail && ( + <> + + A single-file build gives every approved playtester one clean download link in their invite, simple to + share and reliable to deliver. Builds split across multiple files produce a separate link for each + file, which makes invites longer and harder to follow. + + setShowSingleFileDetail(false)} style={{ display: 'inline-block', marginTop: 8 }}> + Show less + + + )} +
+ } + />