feat(ui): external services tab with Azure DevOps PAT, draft PR button and link in company repos

This commit is contained in:
mika kuns
2026-10-01 12:13:57 +02:00
parent fed0b6ac51
commit 4976ded7ae
9 changed files with 247 additions and 15 deletions
@@ -321,8 +321,18 @@
<TextBlock Classes="diff-del" Text="{Binding DiffDelText}" />
</StackPanel>
<!-- Company repo: no local target — approve pushes and opens a draft PR. -->
<StackPanel Spacing="6" IsVisible="{Binding Merge.IsCompanyRepo}">
<TextBlock Classes="meta" Text="{loc:Tr details.workConsole.companyTargetHint}" TextWrapping="Wrap" />
<Button Classes="btn" HorizontalAlignment="Left"
Content="{loc:Tr details.workConsole.openPr}"
ToolTip.Tip="{Binding Merge.PullRequestUrl}"
Command="{Binding Merge.OpenPullRequestCommand}"
IsVisible="{Binding Merge.HasPullRequest}" />
</StackPanel>
<!-- Target branch + pre-flight mergeability -->
<StackPanel Spacing="4">
<StackPanel Spacing="4" IsVisible="{Binding Merge.ShowApproveMerge}">
<TextBlock Classes="field-label" Text="{loc:Tr details.workConsole.targetBranch}" />
<ComboBox ItemsSource="{Binding Merge.MergeTargetBranches}"
SelectedItem="{Binding Merge.SelectedMergeTarget, Mode=TwoWay}"
@@ -333,7 +343,8 @@
IsVisible="{Binding Merge.TargetDirty}" />
</StackPanel>
<StackPanel Spacing="0">
<!-- The preview is against the local target, meaningless when the PR targets origin. -->
<StackPanel Spacing="0" IsVisible="{Binding Merge.ShowApproveMerge}">
<TextBlock Classes="meta" Text="{Binding Merge.MergePreviewText}" TextWrapping="Wrap"
Foreground="{DynamicResource MossBrush}"
IsVisible="{Binding Merge.MergeIsClean}" />
@@ -400,8 +411,13 @@
<WrapPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal" Spacing="{StaticResource SpaceSm}" Margin="0,0,8,8">
<Button Classes="btn accent" Content="{loc:Tr details.workConsole.approveMerge}"
Command="{Binding ApproveReviewCommand}" />
<Button Classes="btn accent" Command="{Binding ApproveReviewCommand}">
<Panel>
<TextBlock Text="{loc:Tr details.workConsole.approveMerge}" IsVisible="{Binding Merge.ShowApproveMerge}" />
<TextBlock Text="{loc:Tr details.workConsole.createDraftPr}" IsVisible="{Binding Merge.ShowCreatePr}" />
<TextBlock Text="{loc:Tr details.workConsole.updatePr}" IsVisible="{Binding Merge.ShowUpdatePr}" />
</Panel>
</Button>
<controls:OperationIndicator Status="{Binding ApproveOp}" />
</StackPanel>
<StackPanel Orientation="Horizontal" Spacing="{StaticResource SpaceSm}" Margin="0,0,8,8">
@@ -738,12 +738,14 @@
</ScrollViewer>
</TabItem>
<!-- Ticketsystem: Base-URL + PAT for the Bandel ticket integration. Empty base URL
disables the feature entirely, so this tab intentionally never forces a value. -->
<!-- External services: Bandel ticket system (base URL + PAT; empty base URL disables it, so
this tab never forces a value) and the Azure DevOps PAT for company-repo push + draft PR. -->
<TabItem Header="{loc:Tr settings.sidebar.categoryTickets}">
<ScrollViewer>
<StackPanel Spacing="14" Margin="0,8,0,0">
<TextBlock Classes="section-label" Text="{loc:Tr settings.tickets.ticketSection}"/>
<StackPanel Spacing="4">
<TextBlock Classes="field-label" Text="{loc:Tr settings.tickets.baseUrl}"/>
<TextBox Text="{Binding Tickets.ApiBaseUrl, Mode=TwoWay}"/>
@@ -785,6 +787,33 @@
<TextBlock Classes="meta" Text="{loc:Tr settings.tickets.fallbackListHint}"
TextWrapping="Wrap" Opacity="0.6"/>
</StackPanel>
<Border BorderBrush="{DynamicResource LineBrush}" BorderThickness="0,1,0,0" Margin="0,8,0,0"/>
<TextBlock Classes="section-label" Text="{loc:Tr settings.tickets.azdoSection}"/>
<StackPanel Spacing="4">
<TextBlock Classes="field-label" Text="{loc:Tr settings.tickets.azdoToken}"/>
<TextBox Text="{Binding Tickets.AzdoToken, Mode=TwoWay}"
PasswordChar="•"
PlaceholderText="{Binding Tickets.AzdoTokenPlaceholder}"/>
<TextBlock Classes="meta" Text="{loc:Tr settings.tickets.azdoHint}"
TextWrapping="Wrap" Opacity="0.6"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Spacing="8">
<Button Classes="btn"
Content="{loc:Tr settings.tickets.testConnection}"
Command="{Binding Tickets.TestAzdoConnectionCommand}"
IsEnabled="{Binding !Tickets.IsBusy}"/>
<Button Classes="btn danger"
Content="{loc:Tr settings.tickets.clearToken}"
Command="{Binding Tickets.ClearAzdoTokenCommand}"
IsEnabled="{Binding !Tickets.IsBusy}"/>
</StackPanel>
<TextBlock Classes="meta" Text="{Binding Tickets.AzdoStatusMessage}" TextWrapping="Wrap"
IsVisible="{Binding Tickets.AzdoStatusMessage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
</StackPanel>
</ScrollViewer>
</TabItem>