desktop: Releases > Send for review (App Store submission state, builds by number, Submit / Resubmit / in-app purchases; Play versionCodes by number, Send to production, managed publishing, console plans for countries and Send changes for review), plan panel before every owner dialog with streamed progress; App info console steps for every console plan form with verify; Catalog price-change owner actions and the declined state; Data safety deletion answer; TestFlight create missing groups; Android SDK in Dependencies; upload progress in job toasts; boot check send-for-review cases on D1 and D3 state
This commit is contained in:
parent
33eb24a3dc
commit
2b101f0fd8
22 changed files with 1527 additions and 57 deletions
|
|
@ -1,7 +1,9 @@
|
|||
// Releases: the release timeline (one version on both stores on one track: build -> testing -> review -> live ->
|
||||
// rollout %), then every version read from the stores. Submit and release stay in the consoles.
|
||||
// rollout %), then every version read from the stores, then sending for review (Submit.tsx): App Store submit /
|
||||
// resubmit / in-app purchases and the Google Play production release as owner actions, the Play steps without an API
|
||||
// as console plans. Releasing an approved version (manual release) stays in App Store Connect.
|
||||
import { useState } from 'react';
|
||||
import { api, type ReleaseTrain, type StoreRelease } from '../../api';
|
||||
import type { ReleaseTrain, StoreRelease } from '../../api';
|
||||
import type { UnifiedApp } from '../../lib/identity';
|
||||
import { WriteButton } from '../../ui/WriteButton';
|
||||
import { type Key, t } from '../../i18n';
|
||||
|
|
@ -11,7 +13,7 @@ import { useData, useRead, useWrite } from '../../store';
|
|||
import { Icon, StoreGlyph } from '../../ui/icons';
|
||||
import { RolloutBar } from '../../ui/charts';
|
||||
import { Card, Chip, Empty, Notice, PhaseChip, storeName } from '../../ui/kit';
|
||||
import { ascUrl, PLAY_CONSOLE } from '../AppView';
|
||||
import { AppleSubmitCard, PlayProductionCard } from './Submit';
|
||||
|
||||
const STAGE_KEY: Record<(typeof STAGES)[number], Key> = { build: 'stage.build', testing: 'stage.testing', review: 'stage.review', live: 'stage.live', rollout: 'stage.rollout' };
|
||||
|
||||
|
|
@ -121,16 +123,29 @@ export function ReleasesTab({ app }: { app: UnifiedApp }) {
|
|||
const l = d.liveFor(app);
|
||||
const project = app.project;
|
||||
const tf = useRead<TestFlightStatus>(app.target, 'apple.testflight_status', { network: true, title: 'TestFlight', skip: !app.ios && !d.statusFor(app)?.app?.platforms.ios });
|
||||
const open = (url: string) => { api.openExternal(url).catch(() => {}); };
|
||||
const sum = project ? d.statusOf(project)?.summary : null;
|
||||
const submit = project && (sum?.apple || sum?.play) ? (
|
||||
<section className="stack" aria-labelledby="sub-section" data-section="submit">
|
||||
<h2 id="sub-section" className="section-h row" style={{ gap: 8 }}><Icon name="send" />{t('sub.section')}</h2>
|
||||
<div className="grid g2" style={{ alignItems: 'start' }}>
|
||||
{sum?.apple && <AppleSubmitCard app={app} project={project} />}
|
||||
{sum?.play && <PlayProductionCard app={app} project={project} />}
|
||||
</div>
|
||||
<p className="small muted">{t('releases.ownerNote')}</p>
|
||||
</section>
|
||||
) : null;
|
||||
|
||||
if (!l) {
|
||||
return (
|
||||
<>
|
||||
<Card pad={false}>
|
||||
<Empty illo="cloud" title={t('releases.notReadTitle')} actions={<>
|
||||
<button className="btn btn-primary" onClick={() => d.refreshPortfolio(true)} disabled={!!d.portfolioBusy}><Icon name="refresh" />{t('action.readStores')}</button>
|
||||
{project && !project.playAccount && !project.appleAccount && <span className="small muted">{t('releases.noAccounts')}</span>}
|
||||
</>}>{t('releases.notReadText')}</Empty>
|
||||
</Card>
|
||||
{submit}
|
||||
</>
|
||||
);
|
||||
}
|
||||
const history = versionHistory(l.release.all ?? []);
|
||||
|
|
@ -164,10 +179,7 @@ export function ReleasesTab({ app }: { app: UnifiedApp }) {
|
|||
) : <Empty compact illo="unknown" title={t('releases.noVersions')} />}
|
||||
</Card>
|
||||
|
||||
<Notice tone="info" icon="shield" action={<div className="actions">
|
||||
{l.app?.platforms.ios && <button className="btn btn-sm" onClick={() => open(ascUrl(l.app?.platforms.ios?.ascAppId))}><Icon name="external" />App Store Connect</button>}
|
||||
{l.app?.platforms.android && <button className="btn btn-sm" onClick={() => open(PLAY_CONSOLE)}><Icon name="external" />Play Console</button>}
|
||||
</div>}>{t('releases.consoleNote')}</Notice>
|
||||
{submit}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue