Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit ce36da1

Browse files
committed
Merge pull request #119 from github/feature/pr/views
Pull Request list view and viewmodel
2 parents b028aa6 + 8b4c49e commit ce36da1

File tree

131 files changed

+5628
-1087
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

131 files changed

+5628
-1087
lines changed

GitHubVS.sln

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 14
4-
VisualStudioVersion = 14.0.24720.0
4+
VisualStudioVersion = 14.0.25029.0
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHub.VisualStudio", "src\GitHub.VisualStudio\GitHub.VisualStudio.csproj", "{11569514-5AE5-4B5B-92A2-F10B0967DE5F}"
77
EndProject
@@ -42,23 +42,22 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Script", "Script", "{7B6C5F
4242
ProjectSection(SolutionItems) = preProject
4343
.gitattributes = .gitattributes
4444
.gitignore = .gitignore
45+
script\Announce.ps1 = script\Announce.ps1
4546
script\Bootstrap.ps1 = script\Bootstrap.ps1
4647
build.cmd = build.cmd
4748
script\Bump-Version.ps1 = script\Bump-Version.ps1
4849
script\cibuild.ps1 = script\cibuild.ps1
4950
script\common.ps1 = script\common.ps1
5051
script\Deploy.ps1 = script\Deploy.ps1
5152
script\Get-CheckedOutBranch.ps1 = script\Get-CheckedOutBranch.ps1
53+
script\Get-HeadSha1.ps1 = script\Get-HeadSha1.ps1
5254
script\HubotTell-NativeRoom.ps1 = script\HubotTell-NativeRoom.ps1
5355
nuget.config = nuget.config
5456
script\Require-CleanWorkTree.ps1 = script\Require-CleanWorkTree.ps1
55-
script\SolutionInfo.cs = script\SolutionInfo.cs
56-
script\Upload-DirectoryToS3.ps1 = script\Upload-DirectoryToS3.ps1
57-
script\Announce.ps1 = script\Announce.ps1
58-
script\Get-HeadSha1.ps1 = script\Get-HeadSha1.ps1
5957
script\Run-NUnit.ps1 = script\Run-NUnit.ps1
6058
script\Run-XUnit.ps1 = script\Run-XUnit.ps1
61-
59+
script\SolutionInfo.cs = script\SolutionInfo.cs
60+
script\Upload-DirectoryToS3.ps1 = script\Upload-DirectoryToS3.ps1
6261
EndProjectSection
6362
EndProject
6463
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{8A7DA2E7-262B-4581-807A-1C45CE79CDFD}"
@@ -545,8 +544,8 @@ Global
545544
{161DBF01-1DBF-4B00-8551-C5C00F26720D}.Release|Any CPU.Build.0 = Release|Any CPU
546545
{161DBF01-1DBF-4B00-8551-C5C00F26720D}.Release|x86.ActiveCfg = Release|Any CPU
547546
{161DBF01-1DBF-4B00-8551-C5C00F26720D}.Release|x86.Build.0 = Release|Any CPU
548-
{161DBF01-1DBF-4B00-8551-C5C00F26720D}.XamlDesign|Any CPU.ActiveCfg = Release|Any CPU
549-
{161DBF01-1DBF-4B00-8551-C5C00F26720D}.XamlDesign|Any CPU.Build.0 = Release|Any CPU
547+
{161DBF01-1DBF-4B00-8551-C5C00F26720D}.XamlDesign|Any CPU.ActiveCfg = Debug|Any CPU
548+
{161DBF01-1DBF-4B00-8551-C5C00F26720D}.XamlDesign|Any CPU.Build.0 = Debug|Any CPU
550549
{161DBF01-1DBF-4B00-8551-C5C00F26720D}.XamlDesign|x86.ActiveCfg = Release|Any CPU
551550
{161DBF01-1DBF-4B00-8551-C5C00F26720D}.XamlDesign|x86.Build.0 = Release|Any CPU
552551
{161DBF01-1DBF-4B00-8551-C5C00F26720E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -561,8 +560,8 @@ Global
561560
{161DBF01-1DBF-4B00-8551-C5C00F26720E}.Release|Any CPU.Build.0 = Release|Any CPU
562561
{161DBF01-1DBF-4B00-8551-C5C00F26720E}.Release|x86.ActiveCfg = Release|Any CPU
563562
{161DBF01-1DBF-4B00-8551-C5C00F26720E}.Release|x86.Build.0 = Release|Any CPU
564-
{161DBF01-1DBF-4B00-8551-C5C00F26720E}.XamlDesign|Any CPU.ActiveCfg = Release|Any CPU
565-
{161DBF01-1DBF-4B00-8551-C5C00F26720E}.XamlDesign|Any CPU.Build.0 = Release|Any CPU
563+
{161DBF01-1DBF-4B00-8551-C5C00F26720E}.XamlDesign|Any CPU.ActiveCfg = Debug|Any CPU
564+
{161DBF01-1DBF-4B00-8551-C5C00F26720E}.XamlDesign|Any CPU.Build.0 = Debug|Any CPU
566565
{161DBF01-1DBF-4B00-8551-C5C00F26720E}.XamlDesign|x86.ActiveCfg = Release|Any CPU
567566
{161DBF01-1DBF-4B00-8551-C5C00F26720E}.XamlDesign|x86.Build.0 = Release|Any CPU
568567
{D1DFBB0C-B570-4302-8F1E-2E3A19C41961}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -577,8 +576,8 @@ Global
577576
{D1DFBB0C-B570-4302-8F1E-2E3A19C41961}.Release|Any CPU.Build.0 = Release|Any CPU
578577
{D1DFBB0C-B570-4302-8F1E-2E3A19C41961}.Release|x86.ActiveCfg = Release|Any CPU
579578
{D1DFBB0C-B570-4302-8F1E-2E3A19C41961}.Release|x86.Build.0 = Release|Any CPU
580-
{D1DFBB0C-B570-4302-8F1E-2E3A19C41961}.XamlDesign|Any CPU.ActiveCfg = Release|Any CPU
581-
{D1DFBB0C-B570-4302-8F1E-2E3A19C41961}.XamlDesign|Any CPU.Build.0 = Release|Any CPU
579+
{D1DFBB0C-B570-4302-8F1E-2E3A19C41961}.XamlDesign|Any CPU.ActiveCfg = Debug|Any CPU
580+
{D1DFBB0C-B570-4302-8F1E-2E3A19C41961}.XamlDesign|Any CPU.Build.0 = Debug|Any CPU
582581
{D1DFBB0C-B570-4302-8F1E-2E3A19C41961}.XamlDesign|x86.ActiveCfg = Release|Any CPU
583582
{D1DFBB0C-B570-4302-8F1E-2E3A19C41961}.XamlDesign|x86.Build.0 = Release|Any CPU
584583
EndGlobalSection

documentation/UIController.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
The `UIController` class creates views and associated viewmodels for each UI we have,
2+
and controls the UI logic graph. It uses various state machines to define
3+
the UI logic graph.
4+
5+
**State machines**
6+
7+
The UI logic graph is controlled by various state machines defined in
8+
`ConfigureLogicStates` and `ConfigureUIHandlingStates`
9+
10+
**ConfigureLogicStates**
11+
12+
`ConfigureLogicStates` defines the one state machine per UI group:
13+
- Authentication
14+
- Repository Clone
15+
- Repository Creation
16+
- Repository Publish,
17+
- Pull Requests (List, Detail, Creation)
18+
19+
All state machines have a common state of `None` (nothing happened yet),
20+
`End` (we're done, cleanup) and `Finish` (final state once cleanup is done), and
21+
UI-specific states that relate to what views the UI needs to show (Login, TwoFactor,
22+
PullRequestList, etc). States are defined in the enum `UIViewType`
23+
24+
All state machines support a variety of triggers for going from one state to another.
25+
These triggers are defined in the enum `Trigger`. `Cancel` and `Finish` are
26+
supported by all states (any state machine regardless of its current state supports
27+
exiting via `Cancel` (ends with success flag set to false) and `Finish` (ends with success flag set to true).
28+
Since most UI flows we support are linear (login followed by 2fa followed by clone
29+
followed by ending the flow), most states support the `Next` trigger to continue,
30+
and when at the end of a ui flow, `Next` ends it with success.
31+
32+
The Pull Requests UI flow is non-linear (there are more than one transition from the
33+
list view - it can go to the detail view, or the pr creation view, or other views),
34+
it does not support the `Next` trigger and instead has its own triggers.
35+
36+
**ConfigureUIHandlingStates**
37+
38+
`ConfigureUIHandlingStates` defines a state machine `uiStateMachine` connected
39+
to the `transition` observable, and executes whatever logic is needed to load the
40+
requested state, usually by creating the view and viewmodel that the UI state requires.
41+
Whenever a state transition happens in `uiStateMachine`, if the state requires
42+
loading a view, this view is sent back to the rendering code via the `transition`
43+
observable. When the state machine reaches the `End` state, the `completion` observable
44+
is completed with a flag indicating whether the ui flow ended successfully or was
45+
cancelled (via the `Next`/`Finish` triggers or the `Cancel` trigger) .
46+
47+
The transitions between states are dynamically evaluated at runtime based on the logic
48+
defined in `ConfigureLogicStates`. When `uiStateMachine` receives a trigger request,
49+
it passes that trigger to the state machine corresponding to the ui flow that's currently
50+
running (Authentication, Clone, etc), and that state machine determines which state
51+
to go to next.
52+
53+
In theory, `uiStateMachine` has no knowledge of the logic graph, and
54+
the only thing it's responsible for is loading UI whenever a state is entered, and cleaning
55+
up objects when things are done - making it essentially a big switch with nice entry and exit
56+
conditions. In practice, we need to configure the valid triggers from one state to the other
57+
just so we can call the corresponding state machine that handles the logic (defined in `ConfigureLogicStates`).
58+
There is a bit of code duplication because of this, and there's some room for improvement
59+
here, but because we have a small number of triggers, it's not a huge deal.

script

src/DesignTimeStyleHelper/WindowController.xaml.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System;
1+
using GitHub.UI;
2+
using System;
23
using System.Windows;
34
using System.Windows.Controls;
45

@@ -11,11 +12,11 @@ public partial class WindowController : Window
1112
{
1213
IDisposable disposable;
1314

14-
public WindowController(IObservable<UserControl> controls)
15+
public WindowController(IObservable<LoadData> controls)
1516
{
1617
InitializeComponent();
1718

18-
disposable = controls.Subscribe(c => Load(c),
19+
disposable = controls.Subscribe(c => Load(c.View),
1920
Close
2021
);
2122
}
@@ -26,8 +27,9 @@ protected override void OnClosed(EventArgs e)
2627
base.OnClosed(e);
2728
}
2829

29-
public void Load(UserControl control)
30+
public void Load(IView view)
3031
{
32+
var control = view as UserControl;
3133
Container.Children.Clear();
3234
Container.Children.Add(control);
3335
}

0 commit comments

Comments
 (0)