Desktop D3 UI: studios and store accounts (health checks with fixes, import apps), one card per app across studios (automatic iOS / Android pairing, manual pair / unpair, links, studio moves), store-only apps read-only, ignore list, portfolio search / studio filter / sort / grouping, collapsible studio sidebar, complete Settings, notifications, fixtures with 3 studios and 5 accounts
This commit is contained in:
parent
e058d09683
commit
7b2cc8da0a
24 changed files with 2225 additions and 312 deletions
|
|
@ -8,7 +8,7 @@ export const en = {
|
|||
'nav.appsLabel': 'Apps',
|
||||
'nav.workspace': 'Workspace',
|
||||
'nav.apps': 'App folders',
|
||||
'nav.accounts': 'Accounts',
|
||||
'nav.accounts': 'Studios & accounts',
|
||||
'nav.dependencies': 'Dependencies',
|
||||
'nav.settings': 'Settings',
|
||||
'nav.noApps': 'No apps yet',
|
||||
|
|
@ -557,4 +557,221 @@ export const en = {
|
|||
'wz.back': 'Back',
|
||||
'wz.next': 'Next',
|
||||
'wz.finish': 'Finish',
|
||||
|
||||
'nav.ignored': 'Ignored',
|
||||
'nav.studios': 'Studios',
|
||||
'nav.studiosLabel': 'Studios',
|
||||
'palette.studio': 'Studio',
|
||||
'action.importApps': 'Import apps',
|
||||
'action.importAppsHint': 'Read-only: every app each store account can see, from App Store Connect and Google Play',
|
||||
'apps.storeOnly': 'Store only',
|
||||
'apps.storeOnlyHint': 'On a store account, no app folder yet: store data only (read-only)',
|
||||
'common.save': 'Save',
|
||||
'studio.studio': 'Studio',
|
||||
'studio.none': 'No studio',
|
||||
'studio.noneSub': 'Accounts not in a studio yet',
|
||||
'studio.new': 'New studio',
|
||||
'studio.newSub': 'A studio groups store accounts, and with them their apps',
|
||||
'studio.name': 'Name',
|
||||
'studio.namePlaceholder': 'Example Games',
|
||||
'studio.color': 'Colour',
|
||||
'studio.add': 'Add a studio',
|
||||
'studio.added': 'Studio {name} added',
|
||||
'studio.edit': 'Edit',
|
||||
'studio.logo': 'Logo',
|
||||
'studio.logoClear': 'Remove logo',
|
||||
'studio.remove': 'Remove',
|
||||
'studio.removeHint': 'Removes the studio only: its accounts and apps stay, without a studio',
|
||||
'studio.counts': '{count} accounts · {apps} apps · {store} store only',
|
||||
'studio.noAccounts': 'No store account in this studio yet: add one below and pick this studio.',
|
||||
'studio.allAssigned': 'Every account is in a studio.',
|
||||
'color.indigo': 'Indigo',
|
||||
'color.violet': 'Violet',
|
||||
'color.rose': 'Rose',
|
||||
'color.amber': 'Amber',
|
||||
'color.emerald': 'Emerald',
|
||||
'color.teal': 'Teal',
|
||||
'color.sky': 'Sky',
|
||||
'color.slate': 'Slate',
|
||||
'accounts.leadStudios': 'Studios group your store accounts: Google Play service accounts and App Store Connect team keys. Keys stay in the system keychain; apps come in with Import apps.',
|
||||
'accounts.emptyTextStudios': 'Add a studio, then its Google Play service account and App Store Connect keys. Import apps then lists every app those keys can see.',
|
||||
'accounts.playSubMany': 'Service account JSON key. One service account can be invited to several Play developer accounts: it sees all their apps.',
|
||||
'accounts.appleSubMany': 'One API key per team (company or individual): key id, issuer id and the .p8 file.',
|
||||
'accounts.safetyStudios': 'Keys are read once from the file you pick, stored in the system keychain and never shown again. storebound gets one account\'s key in memory for one call. Studio names, labels and app lists stay on this computer.',
|
||||
'acct.ok': 'Works',
|
||||
'acct.noApps': 'No apps',
|
||||
'acct.permission': 'Permission missing',
|
||||
'acct.revoked': 'Key revoked',
|
||||
'acct.apiDisabled': 'API off',
|
||||
'acct.error': 'Not reachable',
|
||||
'acct.notTested': 'Not tested',
|
||||
'acct.kindPlay': 'Google Play service account',
|
||||
'acct.kindApple': 'App Store Connect team key',
|
||||
'acct.appsRead': '{count} apps, read {when}',
|
||||
'acct.appsRead_one': '1 app, read {when}',
|
||||
'acct.notImported': 'apps not imported yet',
|
||||
'acct.folders': 'used by {count} folders',
|
||||
'acct.folders_one': 'used by 1 folder',
|
||||
'acct.test': 'Test',
|
||||
'acct.testAll': 'Test all accounts',
|
||||
'acct.import': 'Import apps',
|
||||
'acct.edit': 'Rename or move to a studio',
|
||||
'acct.editAria': 'Edit {label}',
|
||||
'acct.ignore': 'Ignore this account',
|
||||
'acct.ignoreHint': 'Ignore: leave this account\'s apps out of the portfolio and store reads',
|
||||
'acct.unignore': 'Show this account again',
|
||||
'acct.ignored': 'Ignored',
|
||||
'acct.openFix': 'Open',
|
||||
'ignored.lead': 'Apps and accounts left out of the portfolio, the sidebar and store reads. Nothing on the stores changes.',
|
||||
'ignored.restoreAll': 'Restore all',
|
||||
'ignored.restore': 'Restore',
|
||||
'ignored.emptyTitle': 'Nothing is ignored',
|
||||
'ignored.emptyText': 'Ignore an app from its page (or a whole account in Studios & accounts) to keep test apps and old titles out of the way.',
|
||||
'ignored.apps': 'Apps',
|
||||
'ignored.appsSub': '{count} ignored',
|
||||
'ignored.accounts': 'Accounts',
|
||||
'ignored.accountsSub': 'Every app of these accounts is left out',
|
||||
'ignored.accountApps': '{count} apps',
|
||||
'ignored.accountApps_one': '1 app',
|
||||
'ignored.noApps': 'No ignored app.',
|
||||
'ignored.noAccounts': 'No ignored account.',
|
||||
'ignored.howTo': 'Pairing and single-store apps:',
|
||||
'ignored.toPairing': 'Settings > App pairing',
|
||||
'pair.folder': 'From its app folder',
|
||||
'pair.manual': 'Paired by hand',
|
||||
'pair.id': 'Paired: same bundle id and package name',
|
||||
'pair.close': 'Paired: close ids',
|
||||
'pair.name': 'Paired: same name',
|
||||
'pair.single': 'One store only',
|
||||
'app.moveStudio': 'Move to a studio',
|
||||
'app.pairWith': 'Pair with',
|
||||
'app.pairWithName': 'Pair {name} with',
|
||||
'app.pick': 'Pick an app',
|
||||
'app.unpair': 'Unpair',
|
||||
'app.ignore': 'Ignore',
|
||||
'app.ignoreHint': 'Leave this app out of the portfolio and store reads (Ignored lists it to restore)',
|
||||
'app.studioHint': 'Open the studio',
|
||||
'app.storeOnlyTitle': 'Store only.',
|
||||
'app.storeOnlyText': 'This app is on your store accounts but has no app folder: releases, reviews, health and TestFlight are shown read-only. Link its folder, or start one, to manage listings, products and checks.',
|
||||
'app.linkFolder': 'Link a folder',
|
||||
'app.initHere': 'Start an app folder here',
|
||||
'app.linked': '{name} is linked',
|
||||
'app.linkFailed': 'Could not link the folder',
|
||||
'portfolio.subStudios': '{count} apps · {stores} store listings · {studios} studios',
|
||||
'portfolio.emptyAccounts': 'Add a studio and its accounts',
|
||||
'portfolio.notImported': 'Apps of {count} accounts are not imported yet: Import apps lists everything those keys can see.',
|
||||
'portfolio.notImported_one': 'Apps of 1 account are not imported yet: Import apps lists everything its key can see.',
|
||||
'portfolio.toolbar': 'Filter and sort the apps',
|
||||
'portfolio.search': 'Search apps, bundle ids, packages',
|
||||
'portfolio.studioFilter': 'Studio',
|
||||
'portfolio.allStudios': 'All studios',
|
||||
'portfolio.sort': 'Sort',
|
||||
'portfolio.sortAttention': 'Needs attention',
|
||||
'portfolio.sortRecent': 'Recently updated',
|
||||
'portfolio.sortName': 'Name',
|
||||
'portfolio.group': 'Group by studio',
|
||||
'portfolio.groupCount': '{count} apps',
|
||||
'portfolio.noConfig': 'No config',
|
||||
'portfolio.storeOnlyCheck': 'Store only',
|
||||
'portfolio.noMatch': 'No app matches',
|
||||
'portfolio.noMatchText': 'Clear the search or pick another studio.',
|
||||
'portfolio.studiosN': '{count} studios',
|
||||
'portfolio.studiosN_one': '1 studio',
|
||||
'portfolio.folders': 'App folders',
|
||||
'portfolio.foldersN': '{count} folders · {store} store only',
|
||||
'portfolio.ignoredN': '{count} apps',
|
||||
'portfolio.ignoredN_one': '1 app',
|
||||
'kpi.appsSubStore': 'iOS {ios} · Android {android} · {store} store only',
|
||||
'toast.importing': 'Importing apps',
|
||||
'toast.importingDetail': 'Every app each account can see (read-only)',
|
||||
'toast.importDone': '{count} apps on your accounts',
|
||||
'toast.importDone_one': '1 app on your accounts',
|
||||
'toast.importDoneDetail': 'from {count} accounts',
|
||||
'toast.importDoneDetail_one': 'from 1 account',
|
||||
'toast.importPartial': '{count} accounts could not be read',
|
||||
'toast.importPartial_one': '1 account could not be read',
|
||||
'toast.saveFailed': 'Not saved',
|
||||
'notify.releaseTitle': '{name}: store state changed',
|
||||
'notify.releaseBody': '{store} {version}: {phase}',
|
||||
'notify.lowTitle': '{name}: {count} new low ratings',
|
||||
'notify.lowTitle_one': '{name}: a new low rating',
|
||||
'notify.crashTitle': '{name}: over the Play threshold',
|
||||
'set.lead': 'Studios, accounts, store reads, the offline cache, language, theme, notifications and more. Everything stays on this computer.',
|
||||
'set.sections': 'Settings sections',
|
||||
'set.studios': 'Studios & accounts',
|
||||
'set.studiosSub': 'Which accounts belong to which studio',
|
||||
'set.studioLine': 'Play {play} · App Store {apple} · {apps} apps',
|
||||
'set.noStudios': 'No studio yet. Studios group accounts and their apps in the portfolio and the sidebar.',
|
||||
'set.manage': 'Manage',
|
||||
'set.pairing': 'App pairing & ignore list',
|
||||
'set.pairingSub': 'An iOS and an Android app become one card when their ids or names match; pair or split them by hand here',
|
||||
'set.pairedHow': 'Pairing',
|
||||
'set.noCandidates': 'Nothing to pair with',
|
||||
'set.noStoreOnly': 'Every app has its folder: pairing comes from the configs.',
|
||||
'set.ignoredLine': 'Ignored: {count} apps, {accounts} accounts.',
|
||||
'set.openIgnored': 'Open the list',
|
||||
'set.refresh': 'Store reads',
|
||||
'set.refreshSub': 'Reads use each account\'s API quota: they run when you ask, or on the schedule here',
|
||||
'set.autoRefresh': 'Read the stores automatically',
|
||||
'set.autoHint': 'While the app is open. Off by default.',
|
||||
'set.off': 'Off',
|
||||
'set.min': '{n} min',
|
||||
'set.hour': '{n} h',
|
||||
'set.onLaunch': 'Read when the app starts',
|
||||
'set.onLaunchHint': 'Imports the apps of every account, then reads every app\'s store status',
|
||||
'set.icons': 'Store icons on import',
|
||||
'set.iconsHint': 'One extra request per app; folders use their own icon',
|
||||
'set.parallel': 'Apps read at the same time',
|
||||
'set.parallelHint': 'Fewer is gentler on rate limits',
|
||||
'set.cache': 'Offline cache',
|
||||
'set.cacheSub': 'The last store reads, shown with their time when you are offline',
|
||||
'set.cacheSize': 'On disk',
|
||||
'set.cacheRows': '{count} saved reads',
|
||||
'set.cacheRows_one': '1 saved read',
|
||||
'set.cacheOldest': 'Oldest',
|
||||
'set.keep': 'Keep saved reads',
|
||||
'set.days': '{n} days',
|
||||
'set.year': '1 year',
|
||||
'set.always': 'Always',
|
||||
'set.notifications': 'Notifications',
|
||||
'set.notificationsSub': 'After a read, when something changed since the previous one',
|
||||
'set.nReview': 'Review and release state changes',
|
||||
'set.nReviewHint': 'In review, approved, rejected, live, halted',
|
||||
'set.nLow': 'New 1 or 2 star reviews',
|
||||
'set.nLowHint': 'When the Reviews tab reads new ones',
|
||||
'set.nCrash': 'Crash or ANR rate over the threshold',
|
||||
'set.nCrashHint': 'Google Play bad behavior thresholds',
|
||||
'set.testNotify': 'Send a test notification',
|
||||
'set.testTitle': 'storebound',
|
||||
'set.testBody': 'Notifications work.',
|
||||
'set.appCopy': 'app copy',
|
||||
'set.depsText': 'Store work needs no local tool. Screenshots, previews and icons use ffmpeg and Chrome: one click on the Dependencies screen.',
|
||||
'set.cli': 'CLI sidecar',
|
||||
'set.protocol': 'Protocol',
|
||||
'set.state': 'State',
|
||||
'set.running': 'Running',
|
||||
'set.writes': 'Writes',
|
||||
'set.writesText': 'Dry run first, then your Apply in a system dialog. Submit, release and publish stay in the consoles.',
|
||||
'set.privacy': 'Privacy',
|
||||
'set.p1': 'No telemetry, no analytics, no crash reports: the app talks only to the stores, with your keys, when you ask.',
|
||||
'set.p2': 'Store keys live in the system keychain; the app data folder holds names, settings and saved reads, never keys.',
|
||||
'set.p3': 'Nothing is written into your app folders unless you confirm it in a system dialog.',
|
||||
'set.p4': 'Tester emails stay masked; review drafts stay in each app folder\'s .storebound/ (gitignored).',
|
||||
'set.reveal': 'Show the data folder',
|
||||
'set.scQuit': 'Quit',
|
||||
'set.updates': 'Updates',
|
||||
'set.channel': 'Channel',
|
||||
'set.stable': 'Stable',
|
||||
'set.beta': 'Beta',
|
||||
'set.updatesText': 'Signed updates from storebound.dev arrive with the first public desktop release; the channel is kept for then.',
|
||||
'set.reset': 'Reset',
|
||||
'set.resetText': 'Forgets {accounts} accounts (their keys are removed from the keychain), {studios} studios, {folders} app folders (the folders stay on disk), pairing, the ignore list, settings and saved reads. A system dialog asks first.',
|
||||
'set.resetButton': 'Reset the app',
|
||||
'set.resetDone': 'storebound desktop was reset',
|
||||
'set.footer': '{n} apps known to this computer',
|
||||
|
||||
'studio.counts_one': '1 account · {apps} apps · {store} store only',
|
||||
'portfolio.groupCount_one': '1 app',
|
||||
'portfolio.groupAccounts': '{count} accounts',
|
||||
'portfolio.groupAccounts_one': '1 account',
|
||||
} as const;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue