Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

[Enhancement] Decouple Shell Flyout and Navigation. #12800

Open
glatzert opened this issue Nov 11, 2020 · 4 comments
Open

[Enhancement] Decouple Shell Flyout and Navigation. #12800

glatzert opened this issue Nov 11, 2020 · 4 comments

Comments

@glatzert
Copy link

Summary

We use AppShell in a not very complex application with ~10 top-level routes and some second level navigations, which do not fit into tabbed navigation. AppShell has been brought into the app especially for the flyout and for the navigation capabilities.
Unfortunately Flyout and Routing seem to be tighlty coupled, which has some drawbacks:

  • Routing gets complicated, if it's between Shell-Routes and Custom-Routes (ex. RegisterRoute()), since it does not really play well together - especially if one view should be used with different routes.
  • The Flyout-Body is restricted to MenuItems and FlyoutItems.

API Changes

  • Allow Flyout to be a container for my custom content.
  • Introduce Routing-awareness e.g. via Behaviors, in such a way I can annotate an item, so it get's an "active"-view-state, if it's the active route (allow for fullmatch or prefix).
  • Make routing consistent, so it's always /monkey/details and not //monkey/details or ///monkey/details depending on where I call GoToAsync();
  • Introduce a Navigation-Command, which automatically wires up navigation to a given route.

Intended Use Case

This can be used to have a simple and robust navigation to anything and allow us developers to modify the contents of the flyout as we see fit. By decoupling navigation and Flyout, it might also be possible to use all sorts of pages in combination with shell.

@PureWeen
Copy link
Contributor

PureWeen commented Jan 7, 2021

@glatzert can you elaborate on this point? Give me an example where you're having to change it up based on where you are?

  • Make routing consistent, so it's always /monkey/details and not //monkey/details or ///monkey/details depending on where I call GoToAsync();

@PureWeen PureWeen self-assigned this Jan 7, 2021
@glatzert
Copy link
Author

glatzert commented Jan 11, 2021

Consider having /animals/monkey/details in Shell.
Also globally Register /animals/care-takers/details during App-Startup.

Now assume being on /animals/care-takers/details?name=Frank and try to link /animals/monkey/details?name=Baboon.
The expected route (if we talk about quasi-URLs here) would be ../../monkey/details?name=Baboon.

But the docs state

  • '..' is a back navigation (which might then go back to another detail page before?)
  • 'route' or '/route' are invalid, since it cannot be pushed on the navigation stack (why not?)
    So we need ///../../monkey/details?name=Baboon

If we link the other way:

  • '//page' or '///page' are invalid, since they cant be the only page on the navigation stack (why not?)

So now its /../../care-takers/details?name=Baboon

So the "same" navigation steps require two different scenarios (if not more, due to .. being back).
I think there'll be more havoc, since the routes do intertwine, but I hope the gist is clear.

It seem to get especially harsh, if you want to place routes into the shell-routing-hierarchy ^^.

I think the basic problem here stems from the fact, shell is trying to have this "shell-content" thing, which (I'd say) is not the main selling point for shell. The top feature of shell is a presumely unified navigation and the flyout itself. The latter one giving everything a frame to be "an application".
Coming from WPF, I did expect flyout to behave more or less like PrismLibraries Regions, but somehow it intertwines routes and the routes content via the flyout and that seems to overcoplicate things.

If you like, I can show or send our source code - since we are working for a university, there's (nearly) nothing secret in the code.

@PureWeen
Copy link
Contributor

@glatzert If you could send me code that'd be helpful
shneuvil at microsoft.com
Or just post here

The main limitation with pushing is that global routes can't be the first page and you can't push shell content (unfortunate limitations but just setting a starting point)

I'm not the biggest fan of calling shell "URI navigation". In hindsight we would have just removed all references to URI and called it "path" navigation. If we stuck with URI's then we should make it so each URI was unique and you'd just have stacks of URI's (it sounds like this is how you're thinking it works which is understandable)

But how it works is fundamentally like PRISM. You could give everything a unique string name and just concatenate paths

<ShellContent Route="shellroute"
RegisterRoute("globalroute")

//shellroute/globalroute/globalroute/globalroute

This indicates a shell content that's active and then 3 pages that are pushed to the stack

The only reason in global routes to register a full uri is that you are specifying where you need to be for a route to be valid

so if your shell file looks like this

<Tab route="animals">
     <ShellContent Route="monkeys" />
     <ShellContent Route="bears" />
     <ShellContent Route="cats" />
</Tab>

Then you can register a global route like

"animals/bears/details"
"animals/cats/details"
"animals/monkeys/details"

So now if the user is at

//animals/monkeys then you can call
GotoAsync("Details") and it will push the page you registered at animals/bears/details

Think of it like you've specified your shell routes like this (which is how I hope to one day make it)

<Tab route="animals">
     <ShellContent Route="monkeys">
             <ShellContent Route="details">
             </ShellContent>
     </ShellContent>
     <ShellContent Route="bears" />
     <ShellContent Route="cats" />
</Tab>

There are some issues that I'm fixing in 5.0 #13330
That might have made this a bit more confusing because certain scenarios aren't working like promised :-/

@glatzert
Copy link
Author

glatzert commented Feb 9, 2021

Thanks for your write up. I think this makes some things clearer for me - and unfortunately it seems, Shell is no solution to our problems - which means we'll probably take the render-parts of shell and see where to get a stack-based uri-navigation (as in a browser).

We misuse Flyout as container for different things (using MenuItem to get around), so we also need to swap that component into something which is flexible. My impression here is, that you have a very specific use case in mind, which does not align with our use case of having a container which allows us to put whatever we like into it.

@PureWeen PureWeen removed their assignment Aug 3, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants