move routing logic into the view manager
This commit is contained in:
@@ -1,8 +1,13 @@
|
||||
import { UmbBaseController } from '@umbraco-cms/backoffice/class-api';
|
||||
import { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbExtensionsManifestInitializer } from '@umbraco-cms/backoffice/extension-api';
|
||||
import { UmbExtensionsManifestInitializer, createExtensionElement } from '@umbraco-cms/backoffice/extension-api';
|
||||
import { ManifestCollectionView, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { UmbArrayState, UmbObjectState, UmbStringState } from '@umbraco-cms/backoffice/observable-api';
|
||||
import { UmbRoute } from '@umbraco-cms/backoffice/router';
|
||||
|
||||
export interface UmbCollectionViewManagerConfig {
|
||||
defaultViewAlias: string;
|
||||
}
|
||||
|
||||
export class UmbCollectionViewManager extends UmbBaseController {
|
||||
#views = new UmbArrayState<ManifestCollectionView>([], (x) => x.alias);
|
||||
@@ -11,12 +16,18 @@ export class UmbCollectionViewManager extends UmbBaseController {
|
||||
#currentView = new UmbObjectState<ManifestCollectionView | undefined>(undefined);
|
||||
public readonly currentView = this.#currentView.asObservable();
|
||||
|
||||
#routes = new UmbArrayState<UmbRoute>([], (x) => x.path);
|
||||
public readonly routes = this.#routes.asObservable();
|
||||
|
||||
#rootPathname = new UmbStringState('');
|
||||
public readonly rootPathname = this.#rootPathname.asObservable();
|
||||
|
||||
constructor(host: UmbControllerHost) {
|
||||
#defaultViewAlias?: string;
|
||||
|
||||
constructor(host: UmbControllerHost, config: UmbCollectionViewManagerConfig) {
|
||||
super(host);
|
||||
|
||||
this.#defaultViewAlias = config.defaultViewAlias;
|
||||
this.#observeViews();
|
||||
|
||||
// TODO: hack - we need to figure out how to get the "parent path" from the router
|
||||
@@ -47,25 +58,36 @@ export class UmbCollectionViewManager extends UmbBaseController {
|
||||
|
||||
#observeViews() {
|
||||
return new UmbExtensionsManifestInitializer(this, umbExtensionsRegistry, 'collectionView', null, (views) => {
|
||||
this.#views.next(views.map((view) => view.manifest));
|
||||
this.#initCurrentView();
|
||||
const manifests = views.map((view) => view.manifest);
|
||||
this.#views.next(manifests);
|
||||
this.#createRoutes(manifests);
|
||||
});
|
||||
}
|
||||
|
||||
#initCurrentView() {
|
||||
// if we already have a current view, don't set it again
|
||||
if (this.#currentView.getValue()) return;
|
||||
#createRoutes(views: ManifestCollectionView[] | null) {
|
||||
let routes: Array<UmbRoute> = [];
|
||||
|
||||
const currentUrl = new URL(window.location.href);
|
||||
const lastPathSegment = currentUrl.pathname.split('/').pop();
|
||||
const views = this.#views.getValue();
|
||||
const viewMatch = views.find((view) => view.meta.pathName === lastPathSegment);
|
||||
if (views) {
|
||||
// find the default view from the config. If it doesn't exist, use the first view
|
||||
const defaultView = views.find((view) => view.alias === this.#defaultViewAlias);
|
||||
const fallbackView = defaultView?.meta.pathName || views[0].meta.pathName;
|
||||
|
||||
/* TODO: Find a way to figure out which layout it starts with and set _currentLayout to that instead of [0]. eg. '/table'
|
||||
For document, media and members this will come as part of a data type configuration, but in other cases "users" we should find another way.
|
||||
This should only happen if the current layout is not set in the URL.
|
||||
*/
|
||||
const currentView = viewMatch || views[0];
|
||||
this.setCurrentView(currentView);
|
||||
routes = views.map((view) => {
|
||||
return {
|
||||
path: `${view.meta.pathName}`,
|
||||
component: () => createExtensionElement(view),
|
||||
setup: () => {
|
||||
this.setCurrentView(view);
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
routes.push({
|
||||
path: '',
|
||||
redirectTo: fallbackView,
|
||||
});
|
||||
}
|
||||
|
||||
this.#routes.next(routes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,16 +41,17 @@ export class UmbDefaultCollectionContext<ItemType = any, FilterModelType extends
|
||||
|
||||
public readonly pagination = new UmbPaginationManager();
|
||||
public readonly selection = new UmbSelectionManager();
|
||||
public readonly view = new UmbCollectionViewManager(this);
|
||||
public readonly view;
|
||||
|
||||
constructor(host: UmbControllerHostElement, config: UmbCollectionConfiguration = { pageSize: 50 }) {
|
||||
super(host);
|
||||
|
||||
this.view = new UmbCollectionViewManager(this, { defaultViewAlias: config.defaultViewAlias });
|
||||
this.#configure(config);
|
||||
|
||||
// listen for page changes on the pagination manager
|
||||
this.pagination.addEventListener(UmbChangeEvent.TYPE, this.#onPageChange);
|
||||
|
||||
this.#configure(config);
|
||||
|
||||
this.provideContext(UMB_COLLECTION_CONTEXT, this);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
import { UMB_COLLECTION_CONTEXT, UmbDefaultCollectionContext } from './collection-default.context.js';
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { createExtensionElement } from '@umbraco-cms/backoffice/extension-api';
|
||||
import {
|
||||
umbExtensionsRegistry,
|
||||
type ManifestCollectionView,
|
||||
UmbBackofficeManifestKind,
|
||||
} from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { umbExtensionsRegistry, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||
import type { UmbRoute } from '@umbraco-cms/backoffice/router';
|
||||
|
||||
@@ -33,41 +28,19 @@ export class UmbCollectionDefaultElement extends UmbLitElement {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.#observeCollectionViews();
|
||||
this.consumeContext(UMB_COLLECTION_CONTEXT, (instance) => {
|
||||
this.#collectionContext = instance;
|
||||
|
||||
this.#observeCollectionViews();
|
||||
this.#observeCollectionRoutes();
|
||||
});
|
||||
}
|
||||
|
||||
#observeCollectionViews() {
|
||||
#observeCollectionRoutes() {
|
||||
if (!this.#collectionContext) return;
|
||||
|
||||
this.observe(this.#collectionContext.view.views, (views) => {
|
||||
this.#createRoutes(views);
|
||||
this.observe(this.#collectionContext.view.routes, (routes) => {
|
||||
this._routes = routes;
|
||||
}),
|
||||
'umbCollectionViewsObserver';
|
||||
}
|
||||
|
||||
#createRoutes(views: ManifestCollectionView[] | null) {
|
||||
this._routes = [];
|
||||
|
||||
if (views) {
|
||||
this._routes = views.map((view) => {
|
||||
return {
|
||||
path: `${view.meta.pathName}`,
|
||||
component: () => createExtensionElement(view),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
this._routes.push({
|
||||
path: '',
|
||||
redirectTo: views?.[0]?.meta.pathName ?? '/',
|
||||
});
|
||||
|
||||
this.requestUpdate();
|
||||
'umbCollectionRoutesObserver';
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { UmbUserCollectionFilterModel, UmbUserDetailModel } from '../types.js';
|
||||
import { UMB_COLLECTION_VIEW_USER_GRID } from './views/index.js';
|
||||
import { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection';
|
||||
import { UserOrderModel, UserStateModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
@@ -8,7 +9,7 @@ export class UmbUserCollectionContext extends UmbDefaultCollectionContext<
|
||||
UmbUserCollectionFilterModel
|
||||
> {
|
||||
constructor(host: UmbControllerHostElement) {
|
||||
super(host, { pageSize: 50 });
|
||||
super(host, { pageSize: 50, defaultViewAlias: UMB_COLLECTION_VIEW_USER_GRID });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user