feat(app): show workspace identity badges (#3445)
Let users opt into branch and project context on workspace rows while keeping the default sidebar quiet. Project names follow the existing project-icon visibility rule so grouped rows do not repeat their parent.
This commit is contained in:
@@ -66,6 +66,8 @@ const TITLE_SOURCE_ICONS: Record<WorkspaceTitleSource, OptionIcon> = {
|
|||||||
// The same marks these things carry on the workspace row itself, so the menu and the row it
|
// The same marks these things carry on the workspace row itself, so the menu and the row it
|
||||||
// configures name each item the same way twice.
|
// configures name each item the same way twice.
|
||||||
const ROW_ITEM_ICONS: Record<SidebarRowItem, OptionIcon> = {
|
const ROW_ITEM_ICONS: Record<SidebarRowItem, OptionIcon> = {
|
||||||
|
branch: withUnistyles(GitBranch),
|
||||||
|
project: withUnistyles(Folder),
|
||||||
host: withUnistyles(Server),
|
host: withUnistyles(Server),
|
||||||
changeRequest: withUnistyles(GitPullRequest),
|
changeRequest: withUnistyles(GitPullRequest),
|
||||||
services: withUnistyles(Globe),
|
services: withUnistyles(Globe),
|
||||||
@@ -99,6 +101,8 @@ const TITLE_SOURCE_LABEL_KEYS: Record<WorkspaceTitleSource, string> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const ROW_ITEM_LABEL_KEYS: Record<SidebarRowItem, string> = {
|
const ROW_ITEM_LABEL_KEYS: Record<SidebarRowItem, string> = {
|
||||||
|
branch: "sidebar.display.show.branch",
|
||||||
|
project: "sidebar.display.show.project",
|
||||||
host: "sidebar.display.show.host",
|
host: "sidebar.display.show.host",
|
||||||
changeRequest: "sidebar.display.show.changeRequest",
|
changeRequest: "sidebar.display.show.changeRequest",
|
||||||
services: "sidebar.display.show.services",
|
services: "sidebar.display.show.services",
|
||||||
|
|||||||
@@ -3,14 +3,17 @@ import {
|
|||||||
DEFAULT_SIDEBAR_ROW_ITEMS,
|
DEFAULT_SIDEBAR_ROW_ITEMS,
|
||||||
isChecksHiddenByLegacyRowItem,
|
isChecksHiddenByLegacyRowItem,
|
||||||
parseSidebarRowItems,
|
parseSidebarRowItems,
|
||||||
SIDEBAR_ROW_ITEMS,
|
|
||||||
} from "./row-items";
|
} from "./row-items";
|
||||||
|
|
||||||
describe("parseSidebarRowItems", () => {
|
describe("parseSidebarRowItems", () => {
|
||||||
it("shows everything by default", () => {
|
it("shows operational metadata but hides identity badges by default", () => {
|
||||||
for (const item of SIDEBAR_ROW_ITEMS) {
|
expect(DEFAULT_SIDEBAR_ROW_ITEMS).toEqual({
|
||||||
expect(DEFAULT_SIDEBAR_ROW_ITEMS[item]).toBe(true);
|
branch: false,
|
||||||
}
|
project: false,
|
||||||
|
host: true,
|
||||||
|
changeRequest: true,
|
||||||
|
services: true,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("applies stored overrides", () => {
|
it("applies stored overrides", () => {
|
||||||
@@ -21,7 +24,7 @@ describe("parseSidebarRowItems", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("leaves items absent from storage at their default", () => {
|
it("leaves items absent from storage at their default", () => {
|
||||||
// A newly added item must ship visible rather than inheriting "missing means off".
|
// An absent key takes the item's explicit product default.
|
||||||
expect(parseSidebarRowItems({ host: false })).toEqual({
|
expect(parseSidebarRowItems({ host: false })).toEqual({
|
||||||
...DEFAULT_SIDEBAR_ROW_ITEMS,
|
...DEFAULT_SIDEBAR_ROW_ITEMS,
|
||||||
host: false,
|
host: false,
|
||||||
|
|||||||
@@ -12,18 +12,22 @@
|
|||||||
* that knows what an item is.
|
* that knows what an item is.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const SIDEBAR_ROW_ITEMS = ["host", "changeRequest", "services"] as const;
|
export const SIDEBAR_ROW_ITEMS = [
|
||||||
|
"branch",
|
||||||
|
"project",
|
||||||
|
"host",
|
||||||
|
"changeRequest",
|
||||||
|
"services",
|
||||||
|
] as const;
|
||||||
|
|
||||||
export type SidebarRowItem = (typeof SIDEBAR_ROW_ITEMS)[number];
|
export type SidebarRowItem = (typeof SIDEBAR_ROW_ITEMS)[number];
|
||||||
|
|
||||||
export type SidebarRowItems = Record<SidebarRowItem, boolean>;
|
export type SidebarRowItems = Record<SidebarRowItem, boolean>;
|
||||||
|
|
||||||
/**
|
/** The persisted record is merged over these explicit product defaults. */
|
||||||
* Everything on by default. A new item ships visible and users turn it off, which is also why
|
|
||||||
* the persisted shape is a record of overrides rather than a list of enabled items: an absent
|
|
||||||
* key has to mean "default", not "off".
|
|
||||||
*/
|
|
||||||
export const DEFAULT_SIDEBAR_ROW_ITEMS: SidebarRowItems = {
|
export const DEFAULT_SIDEBAR_ROW_ITEMS: SidebarRowItems = {
|
||||||
|
branch: false,
|
||||||
|
project: false,
|
||||||
host: true,
|
host: true,
|
||||||
changeRequest: true,
|
changeRequest: true,
|
||||||
services: true,
|
services: true,
|
||||||
|
|||||||
@@ -196,6 +196,8 @@ export const SidebarWorkspaceRowContent = memo(function SidebarWorkspaceRowConte
|
|||||||
<View style={sidebarWorkspaceRowStyles.rowRight}>{children}</View>
|
<View style={sidebarWorkspaceRowStyles.rowRight}>{children}</View>
|
||||||
</View>
|
</View>
|
||||||
<WorkspaceMetaRow
|
<WorkspaceMetaRow
|
||||||
|
currentBranch={workspace.currentBranch}
|
||||||
|
projectName={leadingProjectName}
|
||||||
hostBadge={hostBadge ?? null}
|
hostBadge={hostBadge ?? null}
|
||||||
prHint={workspace.prHint}
|
prHint={workspace.prHint}
|
||||||
serviceSummary={serviceSummary}
|
serviceSummary={serviceSummary}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import { Pressable, Text, View, type GestureResponderEvent } from "react-native"
|
|||||||
import { StyleSheet, withUnistyles } from "react-native-unistyles";
|
import { StyleSheet, withUnistyles } from "react-native-unistyles";
|
||||||
import {
|
import {
|
||||||
ExternalLink,
|
ExternalLink,
|
||||||
|
Folder,
|
||||||
|
GitBranch,
|
||||||
GitMerge,
|
GitMerge,
|
||||||
GitPullRequest,
|
GitPullRequest,
|
||||||
GitPullRequestClosed,
|
GitPullRequestClosed,
|
||||||
@@ -35,12 +37,15 @@ export {
|
|||||||
const META_ICON_SIZE = HOST_BADGE_ICON_SIZE;
|
const META_ICON_SIZE = HOST_BADGE_ICON_SIZE;
|
||||||
|
|
||||||
const ThemedExternalLink = withUnistyles(ExternalLink);
|
const ThemedExternalLink = withUnistyles(ExternalLink);
|
||||||
|
const ThemedFolder = withUnistyles(Folder);
|
||||||
|
const ThemedGitBranch = withUnistyles(GitBranch);
|
||||||
const ThemedGitPullRequest = withUnistyles(GitPullRequest);
|
const ThemedGitPullRequest = withUnistyles(GitPullRequest);
|
||||||
const ThemedGitMerge = withUnistyles(GitMerge);
|
const ThemedGitMerge = withUnistyles(GitMerge);
|
||||||
const ThemedGitPullRequestClosed = withUnistyles(GitPullRequestClosed);
|
const ThemedGitPullRequestClosed = withUnistyles(GitPullRequestClosed);
|
||||||
const ThemedGlobe = withUnistyles(Globe);
|
const ThemedGlobe = withUnistyles(Globe);
|
||||||
|
|
||||||
const foregroundMapping = (theme: Theme) => ({ color: theme.colors.foreground });
|
const foregroundMapping = (theme: Theme) => ({ color: theme.colors.foreground });
|
||||||
|
const mutedMapping = (theme: Theme) => ({ color: theme.colors.foregroundMuted });
|
||||||
const mergedMapping = (theme: Theme) => ({ color: theme.colors.statusMerged });
|
const mergedMapping = (theme: Theme) => ({ color: theme.colors.statusMerged });
|
||||||
const dangerMapping = (theme: Theme) => ({ color: theme.colors.statusDanger });
|
const dangerMapping = (theme: Theme) => ({ color: theme.colors.statusDanger });
|
||||||
|
|
||||||
@@ -55,16 +60,22 @@ const dangerMapping = (theme: Theme) => ({ color: theme.colors.statusDanger });
|
|||||||
* leaves color to mean status.
|
* leaves color to mean status.
|
||||||
*/
|
*/
|
||||||
export function WorkspaceMetaRow({
|
export function WorkspaceMetaRow({
|
||||||
|
currentBranch,
|
||||||
|
projectName,
|
||||||
hostBadge,
|
hostBadge,
|
||||||
prHint,
|
prHint,
|
||||||
serviceSummary,
|
serviceSummary,
|
||||||
}: {
|
}: {
|
||||||
|
currentBranch: string | null;
|
||||||
|
projectName: string | null;
|
||||||
hostBadge: HostBadgeModel | null;
|
hostBadge: HostBadgeModel | null;
|
||||||
prHint: PrHint | null;
|
prHint: PrHint | null;
|
||||||
serviceSummary: WorkspaceServiceSummary | null;
|
serviceSummary: WorkspaceServiceSummary | null;
|
||||||
}) {
|
}) {
|
||||||
const { rowItems, checksDisplay } = useSidebarMetaPreferences();
|
const { rowItems, checksDisplay } = useSidebarMetaPreferences();
|
||||||
const items = selectMetaRowItems({
|
const items = selectMetaRowItems({
|
||||||
|
currentBranch,
|
||||||
|
projectName,
|
||||||
hasHostBadge: hostBadge !== null,
|
hasHostBadge: hostBadge !== null,
|
||||||
prHint,
|
prHint,
|
||||||
serviceSummary,
|
serviceSummary,
|
||||||
@@ -93,6 +104,12 @@ function MetaItemNode({
|
|||||||
item: MetaRowItem;
|
item: MetaRowItem;
|
||||||
hostBadge: HostBadgeModel | null;
|
hostBadge: HostBadgeModel | null;
|
||||||
}): ReactNode {
|
}): ReactNode {
|
||||||
|
if (item.kind === "branch") {
|
||||||
|
return <IdentityItem kind="branch" name={item.name} />;
|
||||||
|
}
|
||||||
|
if (item.kind === "project") {
|
||||||
|
return <IdentityItem kind="project" name={item.name} />;
|
||||||
|
}
|
||||||
if (item.kind === "host") {
|
if (item.kind === "host") {
|
||||||
return hostBadge ? <HostBadge badge={hostBadge} /> : null;
|
return hostBadge ? <HostBadge badge={hostBadge} /> : null;
|
||||||
}
|
}
|
||||||
@@ -105,6 +122,20 @@ function MetaItemNode({
|
|||||||
return <ServiceItem summary={item.summary} />;
|
return <ServiceItem summary={item.summary} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function IdentityItem({ kind, name }: { kind: "branch" | "project"; name: string }) {
|
||||||
|
const Icon = kind === "branch" ? ThemedGitBranch : ThemedFolder;
|
||||||
|
return (
|
||||||
|
<View style={styles.identityItem} testID={`sidebar-workspace-${kind}`}>
|
||||||
|
<View style={styles.identityIcon}>
|
||||||
|
<Icon size={META_ICON_SIZE} uniProps={mutedMapping} />
|
||||||
|
</View>
|
||||||
|
<Text style={styles.identityText} numberOfLines={1}>
|
||||||
|
{name}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The only thing on the line that navigates, so it is the only thing that answers the
|
* The only thing on the line that navigates, so it is the only thing that answers the
|
||||||
* pointer: it brightens to full foreground and its icon becomes an external-link arrow,
|
* pointer: it brightens to full foreground and its icon becomes an external-link arrow,
|
||||||
@@ -267,6 +298,22 @@ const styles = StyleSheet.create((theme) => ({
|
|||||||
minWidth: 0,
|
minWidth: 0,
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
},
|
},
|
||||||
|
identityItem: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: 3,
|
||||||
|
minWidth: 0,
|
||||||
|
flexShrink: 1,
|
||||||
|
},
|
||||||
|
identityIcon: {
|
||||||
|
flexShrink: 0,
|
||||||
|
},
|
||||||
|
identityText: {
|
||||||
|
color: theme.colors.foregroundMuted,
|
||||||
|
fontSize: theme.fontSize.xs,
|
||||||
|
lineHeight: 16,
|
||||||
|
flexShrink: 1,
|
||||||
|
},
|
||||||
itemPressed: {
|
itemPressed: {
|
||||||
opacity: 0.82,
|
opacity: 0.82,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ const SERVICE: WorkspaceServiceSummary = { name: "web", health: null };
|
|||||||
|
|
||||||
function select(overrides: Partial<Parameters<typeof selectMetaRowItems>[0]> = {}) {
|
function select(overrides: Partial<Parameters<typeof selectMetaRowItems>[0]> = {}) {
|
||||||
return selectMetaRowItems({
|
return selectMetaRowItems({
|
||||||
|
currentBranch: "feature/sidebar-badges",
|
||||||
|
projectName: "Paseo",
|
||||||
hasHostBadge: true,
|
hasHostBadge: true,
|
||||||
prHint: PR_HINT,
|
prHint: PR_HINT,
|
||||||
serviceSummary: SERVICE,
|
serviceSummary: SERVICE,
|
||||||
@@ -29,12 +31,40 @@ function select(overrides: Partial<Parameters<typeof selectMetaRowItems>[0]> = {
|
|||||||
const kinds = (items: ReturnType<typeof selectMetaRowItems>) => items.map((item) => item.kind);
|
const kinds = (items: ReturnType<typeof selectMetaRowItems>) => items.map((item) => item.kind);
|
||||||
|
|
||||||
describe("selectMetaRowItems", () => {
|
describe("selectMetaRowItems", () => {
|
||||||
it("reads identity, then the change, then its state, then what is running", () => {
|
it("puts the enabled branch and project badges first", () => {
|
||||||
expect(kinds(select())).toEqual(["host", "changeRequest", "checks", "services"]);
|
const visible = { ...DEFAULT_SIDEBAR_ROW_ITEMS, branch: true, project: true };
|
||||||
|
expect(kinds(select({ visible }))).toEqual([
|
||||||
|
"branch",
|
||||||
|
"project",
|
||||||
|
"host",
|
||||||
|
"changeRequest",
|
||||||
|
"checks",
|
||||||
|
"services",
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("omits what the workspace does not have", () => {
|
it("omits what the workspace does not have", () => {
|
||||||
expect(kinds(select({ hasHostBadge: false, prHint: null, serviceSummary: null }))).toEqual([]);
|
expect(
|
||||||
|
kinds(
|
||||||
|
select({
|
||||||
|
currentBranch: null,
|
||||||
|
projectName: null,
|
||||||
|
hasHostBadge: false,
|
||||||
|
prHint: null,
|
||||||
|
serviceSummary: null,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("only draws identity badges when enabled and available", () => {
|
||||||
|
const visible = { ...DEFAULT_SIDEBAR_ROW_ITEMS, branch: true, project: true };
|
||||||
|
expect(kinds(select({ currentBranch: null, projectName: null, visible }))).toEqual([
|
||||||
|
"host",
|
||||||
|
"changeRequest",
|
||||||
|
"checks",
|
||||||
|
"services",
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it.each([
|
it.each([
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import type { WorkspaceServiceSummary } from "./service-summary";
|
|||||||
* running. Identity first, then the work, then the work's state.
|
* running. Identity first, then the work, then the work's state.
|
||||||
*/
|
*/
|
||||||
export type MetaRowItem =
|
export type MetaRowItem =
|
||||||
|
| { kind: "branch"; name: string }
|
||||||
|
| { kind: "project"; name: string }
|
||||||
| { kind: "host" }
|
| { kind: "host" }
|
||||||
| { kind: "changeRequest"; hint: PrHint }
|
| { kind: "changeRequest"; hint: PrHint }
|
||||||
| { kind: "checks"; summary: CheckSummary; label: boolean }
|
| { kind: "checks"; summary: CheckSummary; label: boolean }
|
||||||
@@ -26,15 +28,31 @@ export type MetaRowItem =
|
|||||||
* has no badge to hand down, so by the time a row sees one it is meant to be drawn.
|
* has no badge to hand down, so by the time a row sees one it is meant to be drawn.
|
||||||
*/
|
*/
|
||||||
export function selectMetaRowItems(input: {
|
export function selectMetaRowItems(input: {
|
||||||
|
currentBranch: string | null;
|
||||||
|
projectName: string | null;
|
||||||
hasHostBadge: boolean;
|
hasHostBadge: boolean;
|
||||||
prHint: PrHint | null;
|
prHint: PrHint | null;
|
||||||
serviceSummary: WorkspaceServiceSummary | null;
|
serviceSummary: WorkspaceServiceSummary | null;
|
||||||
visible: SidebarRowItems;
|
visible: SidebarRowItems;
|
||||||
checksDisplay: SidebarChecksDisplay;
|
checksDisplay: SidebarChecksDisplay;
|
||||||
}): MetaRowItem[] {
|
}): MetaRowItem[] {
|
||||||
const { hasHostBadge, prHint, serviceSummary, visible, checksDisplay } = input;
|
const {
|
||||||
|
currentBranch,
|
||||||
|
projectName,
|
||||||
|
hasHostBadge,
|
||||||
|
prHint,
|
||||||
|
serviceSummary,
|
||||||
|
visible,
|
||||||
|
checksDisplay,
|
||||||
|
} = input;
|
||||||
const items: MetaRowItem[] = [];
|
const items: MetaRowItem[] = [];
|
||||||
|
|
||||||
|
if (currentBranch && visible.branch) {
|
||||||
|
items.push({ kind: "branch", name: currentBranch });
|
||||||
|
}
|
||||||
|
if (projectName && visible.project) {
|
||||||
|
items.push({ kind: "project", name: projectName });
|
||||||
|
}
|
||||||
if (hasHostBadge) {
|
if (hasHostBadge) {
|
||||||
items.push({ kind: "host" });
|
items.push({ kind: "host" });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,8 @@ export interface Settings extends AppSettings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const SidebarRowItemsSchema = z.strictObject({
|
const SidebarRowItemsSchema = z.strictObject({
|
||||||
|
branch: z.boolean().optional(),
|
||||||
|
project: z.boolean().optional(),
|
||||||
host: z.boolean().optional(),
|
host: z.boolean().optional(),
|
||||||
changeRequest: z.boolean().optional(),
|
changeRequest: z.boolean().optional(),
|
||||||
services: z.boolean().optional(),
|
services: z.boolean().optional(),
|
||||||
|
|||||||
@@ -970,6 +970,8 @@ export const ar: TranslationResources = {
|
|||||||
},
|
},
|
||||||
show: {
|
show: {
|
||||||
label: "إظهار",
|
label: "إظهار",
|
||||||
|
branch: "الفرع",
|
||||||
|
project: "المشروع",
|
||||||
host: "المضيف",
|
host: "المضيف",
|
||||||
changeRequest: "طلب السحب",
|
changeRequest: "طلب السحب",
|
||||||
checks: "الفحوصات",
|
checks: "الفحوصات",
|
||||||
|
|||||||
@@ -979,6 +979,8 @@ export const en = {
|
|||||||
},
|
},
|
||||||
show: {
|
show: {
|
||||||
label: "Show",
|
label: "Show",
|
||||||
|
branch: "Branch",
|
||||||
|
project: "Project",
|
||||||
host: "Host",
|
host: "Host",
|
||||||
changeRequest: "Pull request",
|
changeRequest: "Pull request",
|
||||||
checks: "Checks",
|
checks: "Checks",
|
||||||
|
|||||||
@@ -1001,6 +1001,8 @@ export const es: TranslationResources = {
|
|||||||
},
|
},
|
||||||
show: {
|
show: {
|
||||||
label: "Mostrar",
|
label: "Mostrar",
|
||||||
|
branch: "Rama",
|
||||||
|
project: "Proyecto",
|
||||||
host: "Host",
|
host: "Host",
|
||||||
changeRequest: "Pull request",
|
changeRequest: "Pull request",
|
||||||
checks: "Comprobaciones",
|
checks: "Comprobaciones",
|
||||||
|
|||||||
@@ -1000,6 +1000,8 @@ export const fr: TranslationResources = {
|
|||||||
},
|
},
|
||||||
show: {
|
show: {
|
||||||
label: "Afficher",
|
label: "Afficher",
|
||||||
|
branch: "Branche",
|
||||||
|
project: "Projet",
|
||||||
host: "Hôte",
|
host: "Hôte",
|
||||||
changeRequest: "Pull request",
|
changeRequest: "Pull request",
|
||||||
checks: "Vérifications",
|
checks: "Vérifications",
|
||||||
|
|||||||
@@ -981,6 +981,8 @@ export const ja: TranslationResources = {
|
|||||||
},
|
},
|
||||||
show: {
|
show: {
|
||||||
label: "表示項目",
|
label: "表示項目",
|
||||||
|
branch: "ブランチ",
|
||||||
|
project: "プロジェクト",
|
||||||
host: "ホスト",
|
host: "ホスト",
|
||||||
changeRequest: "プルリクエスト",
|
changeRequest: "プルリクエスト",
|
||||||
checks: "チェック",
|
checks: "チェック",
|
||||||
|
|||||||
@@ -977,6 +977,8 @@ export const ko: TranslationResources = {
|
|||||||
},
|
},
|
||||||
show: {
|
show: {
|
||||||
label: "표시 항목",
|
label: "표시 항목",
|
||||||
|
branch: "브랜치",
|
||||||
|
project: "프로젝트",
|
||||||
host: "호스트",
|
host: "호스트",
|
||||||
changeRequest: "풀 리퀘스트",
|
changeRequest: "풀 리퀘스트",
|
||||||
checks: "검사",
|
checks: "검사",
|
||||||
|
|||||||
@@ -992,6 +992,8 @@ export const ptBR: TranslationResources = {
|
|||||||
},
|
},
|
||||||
show: {
|
show: {
|
||||||
label: "Mostrar",
|
label: "Mostrar",
|
||||||
|
branch: "Branch",
|
||||||
|
project: "Projeto",
|
||||||
host: "Host",
|
host: "Host",
|
||||||
changeRequest: "Pull request",
|
changeRequest: "Pull request",
|
||||||
checks: "Verificações",
|
checks: "Verificações",
|
||||||
|
|||||||
@@ -992,6 +992,8 @@ export const ru: TranslationResources = {
|
|||||||
},
|
},
|
||||||
show: {
|
show: {
|
||||||
label: "Показывать",
|
label: "Показывать",
|
||||||
|
branch: "Ветка",
|
||||||
|
project: "Проект",
|
||||||
host: "Хост",
|
host: "Хост",
|
||||||
changeRequest: "Pull request",
|
changeRequest: "Pull request",
|
||||||
checks: "Проверки",
|
checks: "Проверки",
|
||||||
|
|||||||
@@ -962,6 +962,8 @@ export const zhCN: TranslationResources = {
|
|||||||
},
|
},
|
||||||
show: {
|
show: {
|
||||||
label: "显示",
|
label: "显示",
|
||||||
|
branch: "分支",
|
||||||
|
project: "项目",
|
||||||
host: "主机",
|
host: "主机",
|
||||||
changeRequest: "拉取请求",
|
changeRequest: "拉取请求",
|
||||||
checks: "检查",
|
checks: "检查",
|
||||||
|
|||||||
@@ -241,7 +241,13 @@ function BadgePreview({
|
|||||||
<Text style={styles.previewTitle} numberOfLines={1}>
|
<Text style={styles.previewTitle} numberOfLines={1}>
|
||||||
{t("settings.host.appearance.preview.workspaceName")}
|
{t("settings.host.appearance.preview.workspaceName")}
|
||||||
</Text>
|
</Text>
|
||||||
<WorkspaceMetaRow hostBadge={hostBadge} prHint={null} serviceSummary={null} />
|
<WorkspaceMetaRow
|
||||||
|
currentBranch={null}
|
||||||
|
projectName={null}
|
||||||
|
hostBadge={hostBadge}
|
||||||
|
prHint={null}
|
||||||
|
serviceSummary={null}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user