Closed spencern closed 4 years ago
Links for designs below
Design annotations in Zeplin :)
Reaction core team link: Web: https://zpl.io/1YphHq Zeplin App: zpl://project?pid=59487558eca97e6140dd4b5b
Public link: https://scene.zeplin.io/project/59487558eca97e6140dd4b5b
this seems completed already by @spencern 's reactioncommerce/reaction#2429?
Yeah, this is done-ish. I need to add a way to switch back to the main shop with "shopper" permissions if you're only an admin for a merchant shop
Leaving this open because we lost this selector when moving to new Catalyst UI, and we need to add it back. @rymorgan
@aldeed We have a plan for shop switcher in the catalyst UI but I didn't think we had official support for this yet?
@rymorgan I think whoever adds the shop switcher would at the same time need to add some "current shop" state tracking and make sure that the UI updates and re-queries when this changes. There shouldn't be a ton of work beyond that because the API already fully supports multi-shop. Possibly we'll need to clean/move/fix some of the shop creation code/UI, too.
I suppose the shop switcher could be some sort of drop down in the shop settings for now but our long term vision is to is the logo area for the shop switcher.
Continuing conversation from https://github.com/reactioncommerce/reaction-admin/pull/235 here.
@loan-laux is interested in working on this as part of his work to develop a community solution to marketplace.
Despite what the earlier conversations and designs in this issue state, I believe where we landed is that we do NOT want a site-wide shop selector or site-wide "current shop" state. We want to take steps to remove all such existing code and instead be smarter about how we determine shop or shops for each individual admin page.
Furthermore, we want the concept of "shop admin UI access" (and really any type of UI "permissions") to be completely separate from API authorization permissions. Hiding or showing parts of the UI is NOT a security measure and shouldn't be thought of as one, and shouldn't be tied to account security, even if there is sometimes overlap.
What this means in terms of an accounts manager's workflow is that when there's a new shop manager user, they would needs to both grant API permissions so that they can read and/or write certain data in the database, AND also add the account to a list of accounts that can select each shop in the UI.
There is no technical design for this as far as I know, but I'd go with something like this:
adminUIShopIds
array field on Account
in mongoadminUIShops
array, so that you could request the _id
and the name
for each shop as part of the viewer
query, and then build the select with that data. grantAdminUIAccess(accountId, shopId)
and revokeAdminUIAccess(accountId, shopId)
And all of the above would be just to get to the point of having the necessary shop data for building selectors.
After this we'd need a single-select and a multi-select shop component.
Then we'd need to go page by page and decide how shop selection makes sense for that page.
shopId
param.)shopIds
array param.)Other UI elements such as the logo in the corner will need to be rethought to be unrelated to any particular shop.
Accounts are not shop specific and would not need shop selectors. But Account Groups can be either global or shop specific, so they'd need a single-select shop selector that is optional.
@mikemurray @willopez @rymorgan Do you have anything to add or any alternative points of view here.
@aldeed Thanks a lot for the guidelines. I'll work on implementing that. Expect a first PR soon!
Hi, I'm implementing a solution for this too. I'm trying to add multi-client support to create a Saas solution.
Then we'd need to go page by page and decide how shop selection makes sense for that page. For most forms, we'd likely add a single-select shop field to the form and use that rather than the "current" or "primary" shop from state For some data tables, we'd add a single-select shop filter that works in tandem with any existing filter options. (If GQL query allows only a single shopId param.) For other data tables, we'd add a multi-select shop filter that works in tandem with any existing filter options. (If GQL query allows a shopIds array param.)
@aldeed I don't understand why you should implement a store selector on each form as you said above. It would be enough to have a store selector in the top right corner, and that selector would set the context of the app and update the data for each store selected.
I also think it would be confusing for users and not very usable. I mean, the user might forget which store they are in and mistakenly do something they shouldn't in that store.
I think it would be much simpler and would meet the objective for an account with multiple stores.
Finally I would like to know how I can help you guys? @aldeed @loan-laux
I agree with @jhonsfran1165 on the fact that having shop selectors on each form would be confusing.
@jhonsfran1165 @loan-laux The reason is because when we did some preliminary discussions on the use cases, there were many workflows that involved multiple stores at once. For example, most, if not all, of the tables should support multiple selection of shop IDs so that I can see and work orders across shops. Some entities might also be applicable to multiple shops in the future (for example, defining only one set of tax rules that you then apply to one or more shops).
So in that sense, when you say "the user might forget which store they are in", that isn't an issue because they're never "in" any particular shop.
Another reason is because some things like accounts are not shop specific, and having a visible shop selector while editing accounts would lead to confusion.
Another reason is because we might move toward UI microsites, where "Orders Admin UI" is different from "Products Admin UI". And though they could still be combined into one UI using iframes, the more they each own their own state, the easier it is.
I'll also clarify, for anyone following this, the difference between "multi-shop" and "marketplace":
shopId
associated with it, and therefore you can manage multiple shops in a single database. Multi-shop is supported in the open source API plugins and will continue to be improved.So this discussion is solely about changes to the admin UI to make multi-shop easier to administer.
@aldeed I also expect a global shop select, sitting on the header bar to be the most reasonable solution. Pages could have control over it, so It could be greyed out in the Accounts page for example. If certain actions will only work for single shops, we could quickly add a warning to them, or to make things look nice add a warning icon to that shop selector when on these pages.
Are you firmly convinced such a selector wouldn’t fit the workflow for some? After all, hiding it and sticking to the primary with an optional env should be easy.
Regarding the actual table filters, I’d like them to be more flexible, so they could also contain shopId as manually selected filter, thereby overriding global shop selection, but you would need to proactively select that. This way it could be one filter out of many, but not as visually striking as a separate shop select dropdown per table, where we use the global one instead. I would expect this to be a very clean solution with a resonable low risk of confusion.
@janus-reith If there is a good reason for a global selector, it could be included, but my gut says that almost every page would want to implement its own types of shop selectors instead, which means that the presence of a global, often-disabled selector might just cause confusion. The exception would be "settings" pages, which could benefit from a specific settings-specific shop selector. But orders, carts, payments, shipping methods, payment methods, restrictions, products, catalogs, tags, categories are all going to end up wanting their own filters that allow for selection of multiple shops or "all", and a "shop" or "shops" field on their edit forms.
What is needed are at least some rough wireframe designs for all the pages, so that everyone can visualize what each alternative would look like before building it.
@aldeed Maybe we have totally different usecases in mind - Usually, I'd expect an admin to maybe perform multiple task for one or many shops, staying in the same context of that one or many shops that would have been selected globally. Like, you select the shop(s), and then do something with carts for that shop, orders, products, and so on. I actually wouldn't see that global selection become invalidated in many typical usecases I could imagine. Could you give an example usecase, were you would want to perform an action and this gets in the way?
Having an "All shops" selection could be a great, but as I currently got it, all the API calls would still require you to explicitly list all the shops you want to query? I agree that some mockup would be helpful, also I wonder if there is any other existing example of a multi-tenant dashboard we could use for comparison.
@janus-reith It's true that some GraphQL queries would need to support additional filter arguments, e.g., shopIds rather than shopId. This does complicate permission checks as well.
But as far as the use case, I originally thought as you did, but when we investigated multi-shop needs a year or two ago, we found that many companies have a need to manage multiple brands though single flows. For example, Gap and Old Navy might be managed as two separate shops/catalogs, but might have the same order fulfillment team. Therefore those people need to see a multi-shop list of orders in their worklists.
It's true that there is also the use case you're referring to, which would also encompass a marketplace scenario, but since page-specific (entity-specific) shop selection works for every use case, it seemed like the best solution.
I'm sort of mixing two different questions: (1) should shop selection allow multiple and (2) should shop selector be global or on each page? But my feeling is that a global multi-shop selector would cause confusion on pages that would be naturally single-shop. This is why I personally prefer that each page decides what is best, which can match whatever that GQL query supports.
At the end of the day there is probably no one best answer, and the best solution would be the community coming up with multiple different frontends and the GQL being generic enough to support them all. I'm just trying to make sure everyone understands the various concerns.
@aldeed Agreed on the order fulfillment example. I guess we'd need @rymorgan to chime in here and give us his thoughts on what the UX should be like, bearing this requirement in mind. I still like the idea of a global shop selector, but if it complicates things too much, I think having a designer's point of view would be best.
@aldeed Thanks for the details. So regarding your example, what would stop the order fulfilment team from selecting those two shops in a global multi select? Allowing an arry of shopIds on every query/mutation in the api might be some way to go still, but that would certainly also apply if we do it the other way around, and in the meantime, I'd maybe just put a note on those views which don't support it if multiple shops were selected. Either with some toggle + warning that would display inside that page with one preselected, or (my preference) make the global shop selector switch to some alerting state, indicating that only one selection is active, also with the option to change it directly inside that. I'd like to keep the flexibility of allowing shop(s) as optional filter per table aswell, but make the Shop selector aware of that, so it would switch to a similar greyed out/warning state maybe like it would when the current page only allows single-tenant. Being a bit more verbose here and just telling the user what is happening wouldn't hurt here and avoid confusion I think. (Like, Alert Icon appears on the Shop select in these cases, hover or click reveals an explanation text ).
Preferrably, directly define on the highest level which pages are restricted and not multi-tenant, to avoid much additional work per page/plugin, e.g. in the operatorRoutes
array, so in the registerOperatorRoute
calls and pass that info to the useShops
hook.
But I agree with @loan-laux that the opinion of a dedicated UX designer would help here.
A global dropdown with support for multi-select, that's interesting @janus-reith. Would still require modals (or any other way to prompt users) for the creation of items (tags, products etc), but that's probably the best compromise we can have. Again, I'm no UX expert so I think we should ask one. :)
Yes I agree that global multi select could work. It is a question of how confusing it might be, which I don't really know without seeing mockups.
@rymorgan I imagine you're busy and this is low priority, but is there any chance you could weigh in on this topic?
Hi Team,looks like this feature is not prioritized yet. I am actually looking for Hyperlocal Marketplace feature exposed via REST APIs to be consumed by custom native mobie Apps (Android, iOS) allowing:
Sellers to register through App and post product(s) by providing details like Product category, name, quantity, service location radius (Lat/long, distance e.g. 10 KM/Miles area).
Buyer to get a list of products available in nearby area (customizable via Lat/Long/radius). Receive notifications about new/updated products. These features mean that the APIs and associated services (PUSH notifications/webhooks/events...) are supported by the backend. As per Admin UI access control change, looks like Reaction platform now supports adding and managing Shops via REST APIs (UI might not be ready though). I need your confirmation and advise on achieving above mentined Hyperlocal Marketplace capability. UI development is not critical for me since custom mobile App UI should cover that but I need APIs and other backend capabilities e.g. webhooks/events... Please note that I came across Reaction platform recently and yet to deep dive doc/technical specs. Thanks in advance !
Users with owner/admin permissions for multiple shops should be able to switch the shop context in which they are viewing the dashboard, catalog and products.
Could be a dropdown to just switch contexts, maybe next to the username dropdown. Could also be done with expanding and collapsing panels, though that wouldn't transfer to the pdp/grid view as well.