Merge branch 'main' into feature/multiple-text-string-property-editor
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
* @param {(mappable: T) => R} mappingFunction - Method to return the part for this Observable to return.
|
||||
* @param {(previousResult: R, currentResult: R) => boolean} [memoizationFunction] - Method to Compare if the data has changed. Should return true when data is different.
|
||||
* @description - Creates a RxJS Observable from RxJS Subject.
|
||||
* @example <caption>Example append new entry for a UniqueBehaviorSubject which is an array. Where the key is unique and the item will be updated if matched with existing.</caption>
|
||||
* @example <caption>Example append new entry for a ArrayState or a part of DeepState/ObjectState it which is an array. Where the key is unique and the item will be updated if matched with existing.</caption>
|
||||
* const entry = {key: 'myKey', value: 'myValue'};
|
||||
* const newDataSet = appendToFrozenArray(mySubject.getValue(), entry, x => x.key === key);
|
||||
* mySubject.next(newDataSet);
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { expect } from '@open-wc/testing';
|
||||
import { UniqueArrayBehaviorSubject } from './unique-array-behavior-subject';
|
||||
import { ArrayState } from './array-state';
|
||||
import { createObservablePart } from '@umbraco-cms/observable-api';
|
||||
|
||||
describe('UniqueArrayBehaviorSubject', () => {
|
||||
describe('ArrayState', () => {
|
||||
|
||||
type ObjectType = {key: string, another: string};
|
||||
type ArrayType = ObjectType[];
|
||||
|
||||
let subject: UniqueArrayBehaviorSubject<ObjectType>;
|
||||
let subject: ArrayState<ObjectType>;
|
||||
let initialData: ArrayType;
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -16,7 +16,7 @@ describe('UniqueArrayBehaviorSubject', () => {
|
||||
{key: '2', another: 'myValue2'},
|
||||
{key: '3', another: 'myValue3'}
|
||||
];
|
||||
subject = new UniqueArrayBehaviorSubject(initialData, x => x.key);
|
||||
subject = new ArrayState(initialData, x => x.key);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import { UniqueBehaviorSubject } from "./unique-behavior-subject";
|
||||
import { DeepState } from "./deep-state";
|
||||
import { appendToFrozenArray } from "./append-to-frozen-array.method";
|
||||
|
||||
/**
|
||||
* @export
|
||||
* @class UniqueObjectBehaviorSubject
|
||||
* @extends {UniqueBehaviorSubject<T>}
|
||||
* @description - A RxJS UniqueObjectBehaviorSubject which deepFreezes the object-data to ensure its not manipulated from any implementations.
|
||||
* @class ArrayState
|
||||
* @extends {DeepState<T>}
|
||||
* @description - A RxJS BehaviorSubject which deepFreezes the object-data to ensure its not manipulated from any implementations.
|
||||
* Additionally the Subject ensures the data is unique, not updating any Observes unless there is an actual change of the content.
|
||||
*
|
||||
* The UniqueObjectBehaviorSubject provides methods to append data when the data is an Object.
|
||||
* The ArrayState provides methods to append data when the data is an Object.
|
||||
*/
|
||||
|
||||
export class UniqueArrayBehaviorSubject<T> extends UniqueBehaviorSubject<T[]> {
|
||||
export class ArrayState<T> extends DeepState<T[]> {
|
||||
|
||||
|
||||
constructor(initialData: T[], private _getUnique?: (entry: T) => unknown) {
|
||||
@@ -27,7 +27,7 @@ export class UniqueArrayBehaviorSubject<T> extends UniqueBehaviorSubject<T[]> {
|
||||
* { key: 1, value: 'foo'},
|
||||
* { key: 2, value: 'bar'}
|
||||
* ];
|
||||
* const mySubject = new UniqueArrayBehaviorSubject(data, (x) => x.key);
|
||||
* const mySubject = new ArrayState(data, (x) => x.key);
|
||||
* mySubject.remove([1]);
|
||||
*/
|
||||
remove(uniques: unknown[]) {
|
||||
@@ -54,7 +54,7 @@ export class UniqueArrayBehaviorSubject<T> extends UniqueBehaviorSubject<T[]> {
|
||||
* { key: 1, value: 'foo'},
|
||||
* { key: 2, value: 'bar'}
|
||||
* ];
|
||||
* const mySubject = new UniqueArrayBehaviorSubject(data);
|
||||
* const mySubject = new ArrayState(data);
|
||||
* mySubject.append({ key: 1, value: 'replaced-foo'});
|
||||
*/
|
||||
appendOne(entry: T) {
|
||||
@@ -70,7 +70,7 @@ export class UniqueArrayBehaviorSubject<T> extends UniqueBehaviorSubject<T[]> {
|
||||
* { key: 1, value: 'foo'},
|
||||
* { key: 2, value: 'bar'}
|
||||
* ];
|
||||
* const mySubject = new UniqueArrayBehaviorSubject(data);
|
||||
* const mySubject = new ArrayState(data);
|
||||
* mySubject.append([
|
||||
* { key: 1, value: 'replaced-foo'},
|
||||
* { key: 3, value: 'another-bla'}
|
||||
19
src/Umbraco.Web.UI.Client/libs/observable-api/basic-state.ts
Normal file
19
src/Umbraco.Web.UI.Client/libs/observable-api/basic-state.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { BehaviorSubject } from "rxjs";
|
||||
|
||||
/**
|
||||
* @export
|
||||
* @class BasicState
|
||||
* @extends {BehaviorSubject<T>}
|
||||
* @description - A RxJS BehaviorSubject this Subject ensures the data is unique, not updating any Observes unless there is an actual change of the value.
|
||||
*/
|
||||
export class BasicState<T> extends BehaviorSubject<T> {
|
||||
constructor(initialData: T) {
|
||||
super(initialData);
|
||||
}
|
||||
|
||||
next(newData: T): void {
|
||||
if(newData !== this.getValue()) {
|
||||
super.next(newData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { distinctUntilChanged, map, Observable, shareReplay } from "rxjs";
|
||||
import { MappingFunction, MemoizationFunction, defaultMemoization } from "./unique-behavior-subject";
|
||||
import { MappingFunction, MemoizationFunction, defaultMemoization } from "./deep-state";
|
||||
|
||||
/**
|
||||
* @export
|
||||
@@ -12,7 +12,7 @@ import { MappingFunction, MemoizationFunction, defaultMemoization } from "./uniq
|
||||
* public readonly myPart = CreateObservablePart(this._data, (data) => data.myPart);
|
||||
*/
|
||||
|
||||
export function createObservablePart<T, R>(
|
||||
export function createObservablePart<R, T>(
|
||||
source$: Observable<T>,
|
||||
mappingFunction: MappingFunction<T, R>,
|
||||
memoizationFunction?: MemoizationFunction<R>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import { expect } from '@open-wc/testing';
|
||||
import { UniqueBehaviorSubject } from './unique-behavior-subject';
|
||||
import { DeepState } from './deep-state';
|
||||
import { createObservablePart } from '@umbraco-cms/observable-api';
|
||||
|
||||
describe('UniqueBehaviorSubject', () => {
|
||||
describe('DeepState', () => {
|
||||
|
||||
type ObjectType = {key: string, another: string};
|
||||
|
||||
let subject: UniqueBehaviorSubject<ObjectType>;
|
||||
let subject: DeepState<ObjectType>;
|
||||
let initialData: ObjectType;
|
||||
|
||||
beforeEach(() => {
|
||||
initialData = {key: 'some', another: 'myValue'};
|
||||
subject = new UniqueBehaviorSubject(initialData);
|
||||
subject = new DeepState(initialData);
|
||||
});
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { BehaviorSubject } from "rxjs";
|
||||
|
||||
// TODO: Should this handle array as well?
|
||||
function deepFreeze<T>(inObj: T): T {
|
||||
if(typeof inObj === 'object') {
|
||||
if(inObj != null && typeof inObj === 'object') {
|
||||
Object.freeze(inObj);
|
||||
|
||||
Object.getOwnPropertyNames(inObj)?.forEach(function (prop) {
|
||||
@@ -40,12 +40,12 @@ export function defaultMemoization(previousValue: any, currentValue: any): boole
|
||||
|
||||
/**
|
||||
* @export
|
||||
* @class UniqueBehaviorSubject
|
||||
* @class DeepState
|
||||
* @extends {BehaviorSubject<T>}
|
||||
* @description - A RxJS BehaviorSubject which deepFreezes the data to ensure its not manipulated from any implementations.
|
||||
* Additionally the Subject ensures the data is unique, not updating any Observes unless there is an actual change of the content.
|
||||
*/
|
||||
export class UniqueBehaviorSubject<T> extends BehaviorSubject<T> {
|
||||
export class DeepState<T> extends BehaviorSubject<T> {
|
||||
constructor(initialData: T) {
|
||||
super(deepFreeze(initialData));
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
export * from './observer.controller';
|
||||
export * from './observer';
|
||||
export * from './unique-behavior-subject';
|
||||
export * from './unique-array-behavior-subject';
|
||||
export * from './unique-object-behavior-subject';
|
||||
export * from './number-state';
|
||||
export * from './string-state';
|
||||
export * from './deep-state';
|
||||
export * from './array-state';
|
||||
export * from './object-state';
|
||||
export * from './create-observable-part.method'
|
||||
export * from './append-to-frozen-array.method'
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { BasicState } from "./basic-state";
|
||||
|
||||
/**
|
||||
* @export
|
||||
* @class NumberState
|
||||
* @extends {BehaviorSubject<T>}
|
||||
* @description - A RxJS BehaviorSubject this Subject ensures the data is unique, not updating any Observes unless there is an actual change of the value.
|
||||
*/
|
||||
export class NumberState<T> extends BasicState<T | number> {
|
||||
constructor(initialData: T | number) {
|
||||
super(initialData);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
import { expect } from '@open-wc/testing';
|
||||
import { UniqueObjectBehaviorSubject } from './unique-object-behavior-subject';
|
||||
import { ObjectState } from './object-state';
|
||||
import { createObservablePart } from '@umbraco-cms/observable-api';
|
||||
|
||||
describe('UniqueObjectBehaviorSubject', () => {
|
||||
describe('ObjectState', () => {
|
||||
|
||||
type ObjectType = {key: string, another: string};
|
||||
|
||||
let subject: UniqueObjectBehaviorSubject<ObjectType>;
|
||||
let subject: ObjectState<ObjectType>;
|
||||
let initialData: ObjectType;
|
||||
|
||||
beforeEach(() => {
|
||||
initialData = {key: 'some', another: 'myValue'};
|
||||
subject = new UniqueObjectBehaviorSubject(initialData);
|
||||
subject = new ObjectState(initialData);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { UniqueBehaviorSubject } from "./unique-behavior-subject";
|
||||
import { DeepState } from "./deep-state";
|
||||
|
||||
/**
|
||||
* @export
|
||||
* @class UniqueObjectBehaviorSubject
|
||||
* @extends {UniqueBehaviorSubject<T>}
|
||||
* @description - A RxJS UniqueObjectBehaviorSubject which deepFreezes the object-data to ensure its not manipulated from any implementations.
|
||||
* @class ObjectState
|
||||
* @extends {DeepState<T>}
|
||||
* @description - A RxJS BehaviorSubject which deepFreezes the object-data to ensure its not manipulated from any implementations.
|
||||
* Additionally the Subject ensures the data is unique, not updating any Observes unless there is an actual change of the content.
|
||||
*
|
||||
* The UniqueObjectBehaviorSubject provides methods to append data when the data is an Object.
|
||||
* The ObjectState provides methods to append data when the data is an Object.
|
||||
*/
|
||||
export class UniqueObjectBehaviorSubject<T> extends UniqueBehaviorSubject<T> {
|
||||
export class ObjectState<T> extends DeepState<T> {
|
||||
|
||||
/**
|
||||
* @method append
|
||||
@@ -17,7 +17,7 @@ export class UniqueObjectBehaviorSubject<T> extends UniqueBehaviorSubject<T> {
|
||||
* @description - Append some new data to this Object.
|
||||
* @example <caption>Example append some data.</caption>
|
||||
* const data = {key: 'myKey', value: 'myInitialValue'};
|
||||
* const mySubject = new UniqueObjectBehaviorSubject(data)
|
||||
* const mySubject = new ObjectState(data)
|
||||
* mySubject.append({value: 'myNewValue'})
|
||||
*/
|
||||
update(partialData: Partial<T>) {
|
||||
@@ -2,7 +2,7 @@ import { Observable } from 'rxjs';
|
||||
import { UmbObserver } from './observer';
|
||||
import { UmbControllerInterface, UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export class UmbObserverController<T> extends UmbObserver<T> implements UmbControllerInterface {
|
||||
export class UmbObserverController<T = unknown> extends UmbObserver<T> implements UmbControllerInterface {
|
||||
_alias?: string;
|
||||
public get unique() {
|
||||
return this._alias;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { BasicState } from "./basic-state";
|
||||
|
||||
/**
|
||||
* @export
|
||||
* @class StringState
|
||||
* @extends {BasicState<T>}
|
||||
* @description - A RxJS BehaviorSubject this Subject ensures the data is unique, not updating any Observes unless there is an actual change of the value.
|
||||
*/
|
||||
export class StringState<T> extends BasicState<T | string> {
|
||||
constructor(initialData: T | string) {
|
||||
super(initialData);
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,6 @@ import { defineElement } from '@umbraco-ui/uui-base/lib/registration';
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { css, html } from 'lit';
|
||||
|
||||
import { UmbNotificationService, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/notification';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
|
||||
import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '../core/modal';
|
||||
import { UmbUserStore } from './users/users/user.store';
|
||||
@@ -14,6 +12,7 @@ import {
|
||||
UMB_CURRENT_USER_HISTORY_STORE_CONTEXT_TOKEN,
|
||||
} from './users/current-user/current-user-history.store';
|
||||
|
||||
import { UmbBackofficeContext, UMB_BACKOFFICE_CONTEXT_TOKEN } from './shared/components/backoffice-frame/backoffice.context';
|
||||
import {UmbDocumentTypeDetailStore} from './documents/document-types/document-type.detail.store';
|
||||
import {UmbDocumentTypeTreeStore} from './documents/document-types/document-type.tree.store';
|
||||
import { UmbMediaTypeDetailStore } from './media/media-types/media-type.detail.store';
|
||||
@@ -30,9 +29,9 @@ import { UmbDictionaryTreeStore } from './translation/dictionary/dictionary.tree
|
||||
import { UmbDocumentBlueprintDetailStore } from './documents/document-blueprints/document-blueprint.detail.store';
|
||||
import { UmbDocumentBlueprintTreeStore } from './documents/document-blueprints/document-blueprint.tree.store';
|
||||
|
||||
import { UmbSectionStore, UMB_SECTION_STORE_CONTEXT_TOKEN } from './shared/components/section/section.store';
|
||||
import { UmbDataTypeDetailStore } from './settings/data-types/data-type.detail.store';
|
||||
import { UmbDataTypeTreeStore } from './settings/data-types/data-type.tree.store';
|
||||
import { UmbNotificationService, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/notification';
|
||||
|
||||
|
||||
// Domains
|
||||
@@ -45,6 +44,7 @@ import './users';
|
||||
import './packages';
|
||||
import './search';
|
||||
import './shared';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
|
||||
@defineElement('umb-backoffice')
|
||||
export class UmbBackofficeElement extends UmbLitElement {
|
||||
@@ -92,7 +92,7 @@ export class UmbBackofficeElement extends UmbLitElement {
|
||||
new UmbDocumentBlueprintDetailStore(this);
|
||||
new UmbDocumentBlueprintTreeStore(this);
|
||||
|
||||
this.provideContext(UMB_SECTION_STORE_CONTEXT_TOKEN, new UmbSectionStore());
|
||||
this.provideContext(UMB_BACKOFFICE_CONTEXT_TOKEN, new UmbBackofficeContext());
|
||||
this.provideContext(UMB_CURRENT_USER_HISTORY_STORE_CONTEXT_TOKEN, new UmbCurrentUserHistoryStore());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { DocumentBlueprintDetails } from '@umbraco-cms/models';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { createObservablePart, UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { createObservablePart, ArrayState } from '@umbraco-cms/observable-api';
|
||||
import { UmbStoreBase } from '@umbraco-cms/store';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
@@ -18,7 +18,7 @@ export class UmbDocumentBlueprintDetailStore extends UmbStoreBase {
|
||||
|
||||
|
||||
// TODO: use the right type:
|
||||
#data = new UniqueArrayBehaviorSubject<DocumentBlueprintDetails>([], (x) => x.key);
|
||||
#data = new ArrayState<DocumentBlueprintDetails>([], (x) => x.key);
|
||||
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
@@ -33,7 +33,7 @@ export class UmbDocumentBlueprintDetailStore extends UmbStoreBase {
|
||||
*/
|
||||
getByKey(key: string) {
|
||||
// TODO: use backend cli when available.
|
||||
fetch(`/umbraco/management/api/v1/document/document-blueprint/${key}`)
|
||||
fetch(`/umbraco/management/api/v1/document-blueprint/details/${key}`)
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
this.#data.append(data);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { DocumentBlueprintResource, DocumentTreeItem } from '@umbraco-cms/backend-api';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { createObservablePart, UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { createObservablePart, ArrayState } from '@umbraco-cms/observable-api';
|
||||
import { UmbStoreBase } from '@umbraco-cms/store';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
@@ -18,7 +18,7 @@ export const UMB_DocumentBlueprint_TREE_STORE_CONTEXT_TOKEN = new UmbContextToke
|
||||
export class UmbDocumentBlueprintTreeStore extends UmbStoreBase {
|
||||
|
||||
|
||||
#data = new UniqueArrayBehaviorSubject<DocumentTreeItem>([], (x) => x.key);
|
||||
#data = new ArrayState<DocumentTreeItem>([], (x) => x.key);
|
||||
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { DocumentTypeDetails } from '@umbraco-cms/models';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { createObservablePart, UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { createObservablePart, ArrayState } from '@umbraco-cms/observable-api';
|
||||
import { UmbStoreBase } from '@umbraco-cms/store';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
@@ -17,7 +17,7 @@ export const UMB_DOCUMENT_TYPE_DETAIL_STORE_CONTEXT_TOKEN = new UmbContextToken<
|
||||
export class UmbDocumentTypeDetailStore extends UmbStoreBase {
|
||||
|
||||
|
||||
#data = new UniqueArrayBehaviorSubject<DocumentTypeDetails>([], (x) => x.key);
|
||||
#data = new ArrayState<DocumentTypeDetails>([], (x) => x.key);
|
||||
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
@@ -32,7 +32,7 @@ export class UmbDocumentTypeDetailStore extends UmbStoreBase {
|
||||
*/
|
||||
getByKey(key: string) {
|
||||
// TODO: use backend cli when available.
|
||||
fetch(`/umbraco/management/api/v1/document/document-type/${key}`)
|
||||
fetch(`/umbraco/management/api/v1/document-type/details/${key}`)
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
this.#data.append(data);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { DocumentTypeResource, DocumentTreeItem } from '@umbraco-cms/backend-api';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { createObservablePart, UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { createObservablePart, ArrayState } from '@umbraco-cms/observable-api';
|
||||
import { UmbStoreBase } from '@umbraco-cms/store';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
@@ -18,7 +18,7 @@ export const UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken<Um
|
||||
export class UmbDocumentTypeTreeStore extends UmbStoreBase {
|
||||
|
||||
|
||||
#data = new UniqueArrayBehaviorSubject<DocumentTreeItem>([], (x) => x.key);
|
||||
#data = new ArrayState<DocumentTreeItem>([], (x) => x.key);
|
||||
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { DocumentDetails } from '@umbraco-cms/models';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { createObservablePart, UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { createObservablePart, ArrayState } from '@umbraco-cms/observable-api';
|
||||
import { UmbStoreBase, UmbContentStore } from '@umbraco-cms/store';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
@@ -17,7 +17,7 @@ export const UMB_DOCUMENT_DETAIL_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbDo
|
||||
export class UmbDocumentDetailStore extends UmbStoreBase implements UmbContentStore<DocumentDetails> {
|
||||
|
||||
|
||||
private _data = new UniqueArrayBehaviorSubject<DocumentDetails>([], (x) => x.key);
|
||||
private _data = new ArrayState<DocumentDetails>([], (x) => x.key);
|
||||
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
@@ -25,6 +25,7 @@ export class UmbDocumentDetailStore extends UmbStoreBase implements UmbContentSt
|
||||
}
|
||||
|
||||
getByKey(key: string) {
|
||||
console.log("document getByKey", key)
|
||||
// TODO: use backend cli when available.
|
||||
fetch(`/umbraco/management/api/v1/document/details/${key}`)
|
||||
.then((res) => res.json())
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { DocumentResource, DocumentTreeItem } from '@umbraco-cms/backend-api';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { createObservablePart, UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { createObservablePart, ArrayState } from '@umbraco-cms/observable-api';
|
||||
import { UmbStoreBase } from '@umbraco-cms/store';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
@@ -18,7 +18,7 @@ export const UMB_DOCUMENT_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbDocu
|
||||
export class UmbDocumentTreeStore extends UmbStoreBase {
|
||||
|
||||
|
||||
private _data = new UniqueArrayBehaviorSubject<DocumentTreeItem>([], (x) => x.key);
|
||||
private _data = new ArrayState<DocumentTreeItem>([], (x) => x.key);
|
||||
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { UMB_DOCUMENT_DETAIL_STORE_CONTEXT_TOKEN } from '../document.detail.store';
|
||||
import { UMB_DOCUMENT_TREE_STORE_CONTEXT_TOKEN } from '../document.tree.store';
|
||||
import type { ManifestTree, ManifestTreeItemAction } from '@umbraco-cms/models';
|
||||
|
||||
const treeAlias = 'Umb.Tree.Documents';
|
||||
@@ -8,7 +8,7 @@ const tree: ManifestTree = {
|
||||
alias: treeAlias,
|
||||
name: 'Documents Tree',
|
||||
meta: {
|
||||
storeAlias: UMB_DOCUMENT_DETAIL_STORE_CONTEXT_TOKEN.toString(),
|
||||
storeAlias: UMB_DOCUMENT_TREE_STORE_CONTEXT_TOKEN.toString(),
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ const DefaultDocumentData = {
|
||||
export class UmbWorkspaceDocumentContext extends UmbWorkspaceContentContext<DocumentDetails, UmbDocumentDetailStore> {
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
super(host, DefaultDocumentData, UMB_DOCUMENT_DETAIL_STORE_CONTEXT_TOKEN.toString(), 'document');
|
||||
|
||||
console.log("UMB_DOCUMENT_DETAIL_STORE_CONTEXT_TOKEN", UMB_DOCUMENT_DETAIL_STORE_CONTEXT_TOKEN.toString())
|
||||
}
|
||||
|
||||
public setPropertyValue(alias: string, value: unknown) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { DataTypeDetails } from '@umbraco-cms/models';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { ArrayState } from '@umbraco-cms/observable-api';
|
||||
import { UmbStoreBase } from '@umbraco-cms/store';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
@@ -17,7 +17,7 @@ export const UMB_MEDIA_TYPE_DETAIL_STORE_CONTEXT_TOKEN = new UmbContextToken<Umb
|
||||
export class UmbMediaTypeDetailStore extends UmbStoreBase {
|
||||
|
||||
|
||||
private _data = new UniqueArrayBehaviorSubject<DataTypeDetails>([], (x) => x.key);
|
||||
private _data = new ArrayState<DataTypeDetails>([], (x) => x.key);
|
||||
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { FolderTreeItem, MediaTypeResource } from '@umbraco-cms/backend-api';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { createObservablePart, UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { createObservablePart, ArrayState } from '@umbraco-cms/observable-api';
|
||||
import { UmbStoreBase } from '@umbraco-cms/store';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
@@ -17,7 +17,7 @@ export const UMB_DATA_TYPE_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbMed
|
||||
export class UmbMediaTypeTreeStore extends UmbStoreBase {
|
||||
|
||||
|
||||
#data = new UniqueArrayBehaviorSubject<FolderTreeItem>([], (x) => x.key);
|
||||
#data = new ArrayState<FolderTreeItem>([], (x) => x.key);
|
||||
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
import type { DocumentDetails, MediaDetails } from '@umbraco-cms/models';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { createObservablePart, UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { createObservablePart, ArrayState } from '@umbraco-cms/observable-api';
|
||||
import { UmbStoreBase, UmbContentStore } from '@umbraco-cms/store';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
|
||||
export const UMB_MEDIA_DETAIL_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbMediaDetailStore>('UmbDocumentDetailStore');
|
||||
export const UMB_MEDIA_DETAIL_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbMediaDetailStore>('UmbMediaDetailStore');
|
||||
|
||||
|
||||
/**
|
||||
* @export
|
||||
* @class UmbMediaStore
|
||||
* @class UmbMediaDetailStore
|
||||
* @extends {UmbStoreBase}
|
||||
* @description - Data Store for Media
|
||||
*/
|
||||
export class UmbMediaDetailStore extends UmbStoreBase implements UmbContentStore<MediaDetails> {
|
||||
|
||||
|
||||
#data = new UniqueArrayBehaviorSubject<DocumentDetails>([], (x) => x.key);
|
||||
#data = new ArrayState<DocumentDetails>([], (x) => x.key);
|
||||
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { Observable } from 'rxjs';
|
||||
import { MediaResource, ContentTreeItem } from '@umbraco-cms/backend-api';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { createObservablePart, UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { createObservablePart, ArrayState } from '@umbraco-cms/observable-api';
|
||||
import { UmbStoreBase } from '@umbraco-cms/store';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
@@ -10,7 +10,7 @@ import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
export const UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbMediaTreeStore>('UmbMediaTreeStore');
|
||||
|
||||
// TODO: Stop using ContentTreeItem
|
||||
type MediaTreeItem = ContentTreeItem;
|
||||
export type MediaTreeItem = ContentTreeItem;
|
||||
|
||||
/**
|
||||
* @export
|
||||
@@ -22,7 +22,7 @@ export class UmbMediaTreeStore extends UmbStoreBase {
|
||||
|
||||
|
||||
|
||||
#data = new UniqueArrayBehaviorSubject<MediaTreeItem>([], (x) => x.key);
|
||||
#data = new ArrayState<MediaTreeItem>([], (x) => x.key);
|
||||
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN } from '../media.tree.store';
|
||||
import type {
|
||||
ManifestWorkspace,
|
||||
ManifestWorkspaceAction,
|
||||
ManifestWorkspaceView,
|
||||
ManifestWorkspaceViewCollection,
|
||||
} from '@umbraco-cms/models';
|
||||
import { UMB_MEDIA_DETAIL_STORE_CONTEXT_TOKEN } from '../media.detail.store';
|
||||
|
||||
const workspace: ManifestWorkspace = {
|
||||
type: 'workspace',
|
||||
@@ -59,7 +59,7 @@ const workspaceViewCollections: Array<ManifestWorkspaceViewCollection> = [
|
||||
pathname: 'collection',
|
||||
icon: 'umb:grid',
|
||||
entityType: 'media',
|
||||
storeAlias: UMB_MEDIA_DETAIL_STORE_CONTEXT_TOKEN.toString(),
|
||||
storeAlias: UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN.toString(),
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { UMB_MEDIA_DETAIL_STORE_CONTEXT_TOKEN } from './media/media.detail.store';
|
||||
import { UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN } from './media/media.tree.store';
|
||||
import type { ManifestDashboardCollection, ManifestSection } from '@umbraco-cms/models';
|
||||
|
||||
const sectionAlias = 'Umb.Section.Media';
|
||||
@@ -25,7 +25,7 @@ const dashboards: Array<ManifestDashboardCollection> = [
|
||||
sections: [sectionAlias],
|
||||
pathname: 'media-management',
|
||||
entityType: 'media',
|
||||
storeAlias: UMB_MEDIA_DETAIL_STORE_CONTEXT_TOKEN.toString(),
|
||||
storeAlias: UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN.toString(),
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Observable } from 'rxjs';
|
||||
import type { MemberGroupDetails } from '@umbraco-cms/models';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { ArrayState } from '@umbraco-cms/observable-api';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
import { UmbStoreBase } from '@umbraco-cms/store';
|
||||
|
||||
@@ -16,7 +16,7 @@ export const UMB_MEMBER_GROUP_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbMembe
|
||||
export class UmbMemberGroupStore extends UmbStoreBase {
|
||||
|
||||
|
||||
#groups = new UniqueArrayBehaviorSubject<MemberGroupDetails>([], x => x.key);
|
||||
#groups = new ArrayState<MemberGroupDetails>([], x => x.key);
|
||||
public groups = this.#groups.asObservable();
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { MemberTypeDetails } from '@umbraco-cms/models';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { ArrayState } from '@umbraco-cms/observable-api';
|
||||
import { UmbStoreBase } from '@umbraco-cms/store';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
@@ -17,7 +17,7 @@ export const UMB_MEMBER_TYPE_DETAIL_STORE_CONTEXT_TOKEN = new UmbContextToken<Um
|
||||
export class UmbMemberTypeDetailStore extends UmbStoreBase {
|
||||
|
||||
|
||||
#data = new UniqueArrayBehaviorSubject<MemberTypeDetails>([], (x) => x.key);
|
||||
#data = new ArrayState<MemberTypeDetails>([], (x) => x.key);
|
||||
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { EntityTreeItem, MemberTypeResource, } from '@umbraco-cms/backend-api';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { createObservablePart, UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { createObservablePart, ArrayState } from '@umbraco-cms/observable-api';
|
||||
import { UmbStoreBase } from '@umbraco-cms/store';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
@@ -19,7 +19,7 @@ export class UmbMemberTypeTreeStore extends UmbStoreBase {
|
||||
|
||||
|
||||
// TODO: use the right type here:
|
||||
#data = new UniqueArrayBehaviorSubject<EntityTreeItem>([], (x) => x.key);
|
||||
#data = new ArrayState<EntityTreeItem>([], (x) => x.key);
|
||||
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import type { DataTypeDetails } from '@umbraco-cms/models';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { createObservablePart, UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { createObservablePart, ArrayState } from '@umbraco-cms/observable-api';
|
||||
import { UmbStoreBase } from '@umbraco-cms/store';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
import { DataTypeResource } from '@umbraco-cms/backend-api';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
|
||||
|
||||
|
||||
export const UMB_DATA_TYPE_DETAIL_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbDataTypeDetailStore>('UmbDataTypeDetailStore');
|
||||
@@ -17,7 +19,7 @@ export const UMB_DATA_TYPE_DETAIL_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbD
|
||||
export class UmbDataTypeDetailStore extends UmbStoreBase {
|
||||
|
||||
|
||||
#data = new UniqueArrayBehaviorSubject<DataTypeDetails>([], (x) => x.key);
|
||||
#data = new ArrayState<DataTypeDetails>([], (x) => x.key);
|
||||
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
@@ -32,12 +34,13 @@ export class UmbDataTypeDetailStore extends UmbStoreBase {
|
||||
*/
|
||||
getByKey(key: string) {
|
||||
// TODO: use backend cli when available.
|
||||
fetch(`/umbraco/management/api/v1/document/data-type/${key}`)
|
||||
fetch(`/umbraco/backoffice/data-type/details/${key}`)
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
this.#data.append(data);
|
||||
});
|
||||
|
||||
|
||||
return createObservablePart(this.#data, (documents) =>
|
||||
documents.find((document) => document.key === key)
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { DataTypeResource, DocumentTreeItem } from '@umbraco-cms/backend-api';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { createObservablePart, UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { createObservablePart, ArrayState } from '@umbraco-cms/observable-api';
|
||||
import { UmbStoreBase } from '@umbraco-cms/store';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
@@ -18,7 +18,7 @@ export const UMB_DATA_TYPE_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbDat
|
||||
export class UmbDataTypeTreeStore extends UmbStoreBase {
|
||||
|
||||
|
||||
#data = new UniqueArrayBehaviorSubject<DocumentTreeItem>([], (x) => x.key);
|
||||
#data = new ArrayState<DocumentTreeItem>([], (x) => x.key);
|
||||
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { ContentTreeItem } from '@umbraco-cms/backend-api';
|
||||
import { UmbTreeStore } from '@umbraco-cms/store';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
import { UmbContextToken, UmbContextConsumerController } from '@umbraco-cms/context-api';
|
||||
import { UniqueBehaviorSubject, UmbObserverController } from '@umbraco-cms/observable-api';
|
||||
import { DeepState, UmbObserverController } from '@umbraco-cms/observable-api';
|
||||
export class UmbCollectionContext<
|
||||
DataType extends ContentTreeItem,
|
||||
StoreType extends UmbTreeStore<DataType> = UmbTreeStore<DataType>
|
||||
@@ -13,15 +13,15 @@ export class UmbCollectionContext<
|
||||
private _store?: StoreType;
|
||||
protected _dataObserver?: UmbObserverController<DataType[]>;
|
||||
|
||||
#data = new UniqueBehaviorSubject(<Array<DataType>>[]);
|
||||
#data = new DeepState(<Array<DataType>>[]);
|
||||
public readonly data = this.#data.asObservable();
|
||||
|
||||
#selection = new UniqueBehaviorSubject(<Array<string>>[]);
|
||||
#selection = new DeepState(<Array<string>>[]);
|
||||
public readonly selection = this.#selection.asObservable();
|
||||
|
||||
/*
|
||||
TODO:
|
||||
private _search = new UniqueBehaviorSubject('');
|
||||
private _search = new StringState('');
|
||||
public readonly search = this._search.asObservable();
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { css, html } from 'lit';
|
||||
import { customElement, state } from 'lit/decorators.js';
|
||||
import { repeat } from 'lit/directives/repeat.js';
|
||||
import { UmbCollectionContext, UMB_COLLECTION_CONTEXT_TOKEN } from '../collection.context';
|
||||
import type { MediaDetails } from '@umbraco-cms/models';
|
||||
import type { MediaTreeItem } from '../../../media/media/media.tree.store';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
|
||||
@customElement('umb-collection-view-media-grid')
|
||||
@@ -65,12 +65,12 @@ export class UmbCollectionViewsMediaGridElement extends UmbLitElement {
|
||||
];
|
||||
|
||||
@state()
|
||||
private _mediaItems?: Array<MediaDetails>;
|
||||
private _mediaItems?: Array<MediaTreeItem>;
|
||||
|
||||
@state()
|
||||
private _selection?: Array<string>;
|
||||
private _selection: Array<string> = [];
|
||||
|
||||
private _collectionContext?: UmbCollectionContext<MediaDetails>;
|
||||
private _collectionContext?: UmbCollectionContext<MediaTreeItem>;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -115,24 +115,31 @@ export class UmbCollectionViewsMediaGridElement extends UmbLitElement {
|
||||
});
|
||||
}
|
||||
|
||||
private _handleOpenItem(mediaItem: MediaDetails) {
|
||||
private _handleOpenItem(mediaItem: MediaTreeItem) {
|
||||
//TODO: Fix when we have dynamic routing
|
||||
history.pushState(null, '', 'section/media/media/' + mediaItem.key);
|
||||
}
|
||||
|
||||
private _handleSelect(mediaItem: MediaDetails) {
|
||||
this._collectionContext?.select(mediaItem.key);
|
||||
private _handleSelect(mediaItem: MediaTreeItem) {
|
||||
if(mediaItem.key) {
|
||||
this._collectionContext?.select(mediaItem.key);
|
||||
}
|
||||
}
|
||||
|
||||
private _handleDeselect(mediaItem: MediaDetails) {
|
||||
this._collectionContext?.deselect(mediaItem.key);
|
||||
private _handleDeselect(mediaItem: MediaTreeItem) {
|
||||
if(mediaItem.key) {
|
||||
this._collectionContext?.deselect(mediaItem.key);
|
||||
}
|
||||
}
|
||||
|
||||
private _isSelected(mediaItem: MediaDetails) {
|
||||
return this._selection?.includes(mediaItem.key);
|
||||
private _isSelected(mediaItem: MediaTreeItem) {
|
||||
if(mediaItem.key) {
|
||||
return this._selection.includes(mediaItem.key);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private _renderMediaItem(item: MediaDetails) {
|
||||
private _renderMediaItem(item: MediaTreeItem) {
|
||||
const name = item.name || '';
|
||||
//TODO: fix the file extension when media items have a file extension.
|
||||
return html`<uui-card-media
|
||||
@@ -159,7 +166,7 @@ export class UmbCollectionViewsMediaGridElement extends UmbLitElement {
|
||||
${this._mediaItems
|
||||
? repeat(
|
||||
this._mediaItems,
|
||||
(file, index) => file.key + index,
|
||||
(file, index) => (file.key || '') + index,
|
||||
(file) => this._renderMediaItem(file)
|
||||
)
|
||||
: ''}
|
||||
|
||||
@@ -2,7 +2,8 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { css, CSSResultGroup, html } from 'lit';
|
||||
import { customElement, state } from 'lit/decorators.js';
|
||||
import { when } from 'lit/directives/when.js';
|
||||
import { UmbSectionStore, UMB_SECTION_STORE_CONTEXT_TOKEN } from '../section/section.store';
|
||||
import { UMB_BACKOFFICE_CONTEXT_TOKEN } from './backoffice.context';
|
||||
import type { UmbBackofficeContext } from './backoffice.context';
|
||||
import type { ManifestSection } from '@umbraco-cms/models';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
|
||||
@@ -49,13 +50,13 @@ export class UmbBackofficeHeaderSections extends UmbLitElement {
|
||||
@state()
|
||||
private _currentSectionAlias = '';
|
||||
|
||||
private _sectionStore?: UmbSectionStore;
|
||||
private _backofficeContext?: UmbBackofficeContext;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.consumeContext(UMB_SECTION_STORE_CONTEXT_TOKEN, (sectionStore) => {
|
||||
this._sectionStore = sectionStore;
|
||||
this.consumeContext(UMB_BACKOFFICE_CONTEXT_TOKEN, (backofficeContext) => {
|
||||
this._backofficeContext = backofficeContext;
|
||||
this._observeSections();
|
||||
this._observeCurrentSection();
|
||||
});
|
||||
@@ -66,15 +67,8 @@ export class UmbBackofficeHeaderSections extends UmbLitElement {
|
||||
this._open = !this._open;
|
||||
}
|
||||
|
||||
private _handleTabClick(e: PointerEvent) {
|
||||
const tab = e.currentTarget as HTMLElement;
|
||||
|
||||
// TODO: we need to be able to prevent the tab from setting the active state
|
||||
if (tab.id === 'moreTab') return;
|
||||
|
||||
if (!tab.dataset.alias) return;
|
||||
|
||||
this._sectionStore?.setCurrent(tab.dataset.alias);
|
||||
private _handleSectionTabClick(alias: string) {
|
||||
this._backofficeContext?.setActiveSectionAlias(alias);
|
||||
}
|
||||
|
||||
private _handleLabelClick() {
|
||||
@@ -85,19 +79,19 @@ export class UmbBackofficeHeaderSections extends UmbLitElement {
|
||||
}
|
||||
|
||||
private _observeSections() {
|
||||
if (!this._sectionStore) return;
|
||||
if (!this._backofficeContext) return;
|
||||
|
||||
this.observe(this._sectionStore.getAllowed(), (allowedSections) => {
|
||||
this.observe(this._backofficeContext.getAllowedSections(), (allowedSections) => {
|
||||
this._sections = allowedSections;
|
||||
this._visibleSections = this._sections;
|
||||
});
|
||||
}
|
||||
|
||||
private _observeCurrentSection() {
|
||||
if (!this._sectionStore) return;
|
||||
if (!this._backofficeContext) return;
|
||||
|
||||
this.observe(this._sectionStore.currentAlias, (currentSectionAlias) => {
|
||||
this._currentSectionAlias = currentSectionAlias;
|
||||
this.observe(this._backofficeContext.activeSectionAlias, (currentSectionAlias) => {
|
||||
this._currentSectionAlias = currentSectionAlias || '';
|
||||
});
|
||||
}
|
||||
|
||||
@@ -107,11 +101,11 @@ export class UmbBackofficeHeaderSections extends UmbLitElement {
|
||||
${this._visibleSections.map(
|
||||
(section: ManifestSection) => html`
|
||||
<uui-tab
|
||||
@click="${this._handleTabClick}"
|
||||
@click="${() => this._handleSectionTabClick(section.alias)}"
|
||||
?active="${this._currentSectionAlias === section.alias}"
|
||||
href="${`section/${section.meta.pathname}`}"
|
||||
label="${section.meta.label || section.name}"
|
||||
data-alias="${section.alias}"></uui-tab>
|
||||
></uui-tab>
|
||||
`
|
||||
)}
|
||||
${this._renderExtraSections()}
|
||||
@@ -123,7 +117,7 @@ export class UmbBackofficeHeaderSections extends UmbLitElement {
|
||||
return when(
|
||||
this._extraSections.length > 0,
|
||||
() => html`
|
||||
<uui-tab id="moreTab" @click="${this._handleTabClick}">
|
||||
<uui-tab id="moreTab">
|
||||
<uui-popover .open=${this._open} placement="bottom-start" @close="${() => (this._open = false)}">
|
||||
<uui-button slot="trigger" look="primary" label="More" @click="${this._handleMore}" compact>
|
||||
<uui-symbol-more></uui-symbol-more>
|
||||
|
||||
@@ -3,9 +3,9 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { css, html } from 'lit';
|
||||
import { state } from 'lit/decorators.js';
|
||||
import { IRoutingInfo } from 'router-slot';
|
||||
import { UmbSectionStore, UMB_SECTION_STORE_CONTEXT_TOKEN } from '../section/section.store';
|
||||
import { UmbSectionContext, UMB_SECTION_CONTEXT_TOKEN } from '../section/section.context';
|
||||
import { UmbSectionElement } from '../section/section.element';
|
||||
import { UmbBackofficeContext, UMB_BACKOFFICE_CONTEXT_TOKEN } from './backoffice.context';
|
||||
import { createExtensionElement } from '@umbraco-cms/extensions-api';
|
||||
import type { ManifestSection } from '@umbraco-cms/models';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
@@ -35,29 +35,31 @@ export class UmbBackofficeMain extends UmbLitElement {
|
||||
private _sections: Array<ManifestSection> = [];
|
||||
|
||||
private _routePrefix = 'section/';
|
||||
private _backofficeContext?: UmbBackofficeContext;
|
||||
private _sectionContext?: UmbSectionContext;
|
||||
private _sectionStore?: UmbSectionStore;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.consumeContext(UMB_SECTION_STORE_CONTEXT_TOKEN, (_instance) => {
|
||||
this._sectionStore = _instance;
|
||||
this._observeSections();
|
||||
this.consumeContext(UMB_BACKOFFICE_CONTEXT_TOKEN, (_instance) => {
|
||||
this._backofficeContext = _instance;
|
||||
this._observeBackoffice();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private async _observeSections() {
|
||||
if (!this._sectionStore) return;
|
||||
|
||||
this.observe(this._sectionStore.getAllowed(), (sections) => {
|
||||
this._sections = sections;
|
||||
if (!sections) return;
|
||||
this._createRoutes();
|
||||
});
|
||||
private async _observeBackoffice() {
|
||||
if(this._backofficeContext) {
|
||||
this.observe(this._backofficeContext.getAllowedSections(), (sections) => {
|
||||
this._sections = sections;
|
||||
this._createRoutes();
|
||||
}, 'observeAllowedSections');
|
||||
}
|
||||
}
|
||||
|
||||
private _createRoutes() {
|
||||
if (!this._sections) return;
|
||||
|
||||
this._routes = [];
|
||||
this._routes = this._sections.map((section) => {
|
||||
return {
|
||||
@@ -86,7 +88,7 @@ export class UmbBackofficeMain extends UmbLitElement {
|
||||
const currentPath = info.match.route.path;
|
||||
const section = this._sections.find((s) => this._routePrefix + s.meta.pathname === currentPath);
|
||||
if (!section) return;
|
||||
this._sectionStore?.setCurrent(section.alias);
|
||||
this._backofficeContext?.setActiveSectionAlias(section.alias);
|
||||
this._provideSectionContext(section);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { StringState } from '@umbraco-cms/observable-api';
|
||||
|
||||
export class UmbBackofficeContext {
|
||||
|
||||
|
||||
#activeSectionAlias = new StringState(undefined);
|
||||
public readonly activeSectionAlias = this.#activeSectionAlias.asObservable();
|
||||
|
||||
public getAllowedSections() {
|
||||
// TODO: implemented allowed filtering based on user, maybe this will be a general need and solved else where so this might not be needed in the end.
|
||||
/*
|
||||
const { data } = await getUserSections({});
|
||||
this._allowedSection = data.sections;
|
||||
*/
|
||||
return umbExtensionsRegistry.extensionsOfType('section');
|
||||
}
|
||||
|
||||
|
||||
public setActiveSectionAlias(alias: string) {
|
||||
this.#activeSectionAlias.next(alias);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export const UMB_BACKOFFICE_CONTEXT_TOKEN = new UmbContextToken<UmbBackofficeContext>('UmbBackofficeContext');
|
||||
@@ -8,7 +8,6 @@ import { createExtensionElement } from '@umbraco-cms/extensions-api';
|
||||
import type {
|
||||
ManifestDashboard,
|
||||
ManifestDashboardCollection,
|
||||
ManifestSection,
|
||||
ManifestWithMeta,
|
||||
} from '@umbraco-cms/models';
|
||||
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
|
||||
@@ -58,7 +57,7 @@ export class UmbSectionDashboardsElement extends UmbLitElement {
|
||||
@state()
|
||||
private _currentSectionPathname = '';
|
||||
|
||||
private _currentSectionAlias = '';
|
||||
private _currentSectionAlias?: string;
|
||||
private _sectionContext?: UmbSectionContext;
|
||||
|
||||
constructor() {
|
||||
@@ -73,12 +72,12 @@ export class UmbSectionDashboardsElement extends UmbLitElement {
|
||||
private _observeSectionContext() {
|
||||
if (!this._sectionContext) return;
|
||||
|
||||
this.observe(this._sectionContext.manifest.pipe(first()), (section) => {
|
||||
if (section) {
|
||||
this._currentSectionAlias = section.alias;
|
||||
this._currentSectionPathname = section.meta.pathname;
|
||||
this._observeDashboards();
|
||||
}
|
||||
this.observe(this._sectionContext.alias.pipe(first()), (alias) => {
|
||||
this._currentSectionAlias = alias;
|
||||
this._observeDashboards();
|
||||
});
|
||||
this.observe(this._sectionContext.pathname.pipe(first()), (pathname) => {
|
||||
this._currentSectionPathname = pathname || '';
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -28,8 +28,9 @@ export class UmbSectionSidebarMenuElement extends UmbLitElement {
|
||||
private _observeCurrentSection() {
|
||||
if (!this._sectionContext) return;
|
||||
|
||||
this.observe(this._sectionContext?.manifest, (section) => {
|
||||
this._currentSectionAlias = section.alias;
|
||||
this.observe(this._sectionContext.alias, (alias) => {
|
||||
console.log("this._sectionContext?.alias", alias)
|
||||
this._currentSectionAlias = alias;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { css, html } from 'lit';
|
||||
import { customElement, state } from 'lit/decorators.js';
|
||||
import { UmbSectionContext, UMB_SECTION_CONTEXT_TOKEN } from '../section.context';
|
||||
import type { ManifestSection } from '@umbraco-cms/models';
|
||||
|
||||
import '../../tree/context-menu/tree-context-menu.service';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
@@ -48,9 +47,11 @@ export class UmbSectionSidebarElement extends UmbLitElement {
|
||||
private _observeSectionContext() {
|
||||
if (!this._sectionContext) return;
|
||||
|
||||
this.observe(this._sectionContext.manifest, (section) => {
|
||||
this._sectionLabel = section.meta.label || section.name;
|
||||
this._sectionPathname = section.meta.pathname;
|
||||
this.observe(this._sectionContext.pathname, (pathname) => {
|
||||
this._sectionPathname = pathname || '';
|
||||
});
|
||||
this.observe(this._sectionContext.label, (label) => {
|
||||
this._sectionLabel = label || '';
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css';
|
||||
import { css, html, nothing } from 'lit';
|
||||
import { customElement, state } from 'lit/decorators.js';
|
||||
import { EMPTY, map, of, Subscription, switchMap } from 'rxjs';
|
||||
import { map, of } from 'rxjs';
|
||||
import { UmbSectionContext, UMB_SECTION_CONTEXT_TOKEN } from '../section.context';
|
||||
import type { ManifestSectionView } from '@umbraco-cms/models';
|
||||
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
import { UmbObserverController } from '@umbraco-cms/observable-api';
|
||||
|
||||
@customElement('umb-section-views')
|
||||
export class UmbSectionViewsElement extends UmbLitElement {
|
||||
@@ -35,11 +36,10 @@ export class UmbSectionViewsElement extends UmbLitElement {
|
||||
private _routerFolder = '';
|
||||
|
||||
@state()
|
||||
private _activeView?: ManifestSectionView;
|
||||
private _activeViewPathname?: string;
|
||||
|
||||
private _sectionContext?: UmbSectionContext;
|
||||
private _viewsSubscription?: Subscription;
|
||||
private _activeViewSubscription?: Subscription;
|
||||
private _extensionsObserver?: UmbObserverController;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -60,43 +60,35 @@ export class UmbSectionViewsElement extends UmbLitElement {
|
||||
private _observeViews() {
|
||||
if (!this._sectionContext) return;
|
||||
|
||||
this._viewsSubscription?.unsubscribe();
|
||||
|
||||
this._viewsSubscription = this._sectionContext?.manifest
|
||||
.pipe(
|
||||
switchMap((section) => {
|
||||
if (!section) return EMPTY;
|
||||
|
||||
return (
|
||||
umbExtensionsRegistry
|
||||
?.extensionsOfType('sectionView')
|
||||
.pipe(
|
||||
map((views) =>
|
||||
views
|
||||
.filter((view) => view.meta.sections.includes(section.alias))
|
||||
.sort((a, b) => b.meta.weight - a.meta.weight)
|
||||
)
|
||||
) ?? of([])
|
||||
);
|
||||
})
|
||||
)
|
||||
.subscribe((views) => {
|
||||
this._views = views;
|
||||
});
|
||||
this.observe(this._sectionContext.alias, (sectionAlias) => {
|
||||
this._observeExtensions(sectionAlias);
|
||||
}, 'viewsObserver')
|
||||
}
|
||||
private _observeExtensions(sectionAlias?: string) {
|
||||
this._extensionsObserver?.destroy();
|
||||
if(sectionAlias) {
|
||||
this._extensionsObserver = this.observe(
|
||||
umbExtensionsRegistry?.extensionsOfType('sectionView').pipe(
|
||||
map((views) =>
|
||||
views
|
||||
.filter((view) => view.meta.sections.includes(sectionAlias))
|
||||
.sort((a, b) => b.meta.weight - a.meta.weight)
|
||||
)
|
||||
) ?? of([])
|
||||
,
|
||||
(views) => {
|
||||
this._views = views;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private _observeActiveView() {
|
||||
this._activeViewSubscription?.unsubscribe();
|
||||
|
||||
this._activeViewSubscription = this._sectionContext?.activeView.subscribe((view) => {
|
||||
this._activeView = view;
|
||||
});
|
||||
}
|
||||
|
||||
disconnectedCallback(): void {
|
||||
super.disconnectedCallback();
|
||||
this._viewsSubscription?.unsubscribe();
|
||||
this._activeViewSubscription?.unsubscribe();
|
||||
if(this._sectionContext) {
|
||||
this.observe(this._sectionContext?.activeViewPathname, (pathname) => {
|
||||
this._activeViewPathname = pathname;
|
||||
}, 'activeViewPathnameObserver');
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -113,7 +105,7 @@ export class UmbSectionViewsElement extends UmbLitElement {
|
||||
<uui-tab
|
||||
.label="${view.meta.label || view.name}"
|
||||
href="${this._routerFolder}/view/${view.meta.pathname}"
|
||||
?active="${this._activeView?.meta?.pathname.includes(view.meta.pathname)}">
|
||||
?active="${this._activeViewPathname?.includes(view.meta.pathname)}">
|
||||
<uui-icon slot="icon" name=${view.meta.icon}></uui-icon>
|
||||
${view.meta.label || view.name}
|
||||
</uui-tab>
|
||||
|
||||
@@ -1,47 +1,55 @@
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import type { Entity, ManifestSection, ManifestSectionView, ManifestTree } from '@umbraco-cms/models';
|
||||
import { UniqueObjectBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import type { Entity, ManifestSection, ManifestSectionView } from '@umbraco-cms/models';
|
||||
import { ObjectState, StringState } from '@umbraco-cms/observable-api';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
|
||||
export class UmbSectionContext {
|
||||
#manifest;
|
||||
public readonly manifest;
|
||||
export type ActiveTreeItemType = Entity | undefined;
|
||||
|
||||
// TODO: what is the best context to put this in?
|
||||
export class UmbSectionContext {
|
||||
|
||||
#manifestAlias = new StringState<string | undefined>(undefined);
|
||||
#manifestPathname = new StringState<string | undefined>(undefined);
|
||||
#manifestLabel = new StringState<string | undefined>(undefined);
|
||||
public readonly alias = this.#manifestAlias.asObservable();
|
||||
public readonly pathname = this.#manifestPathname.asObservable();
|
||||
public readonly label = this.#manifestLabel.asObservable();
|
||||
|
||||
/*
|
||||
This was not used anywhere
|
||||
private _activeTree = new BehaviorSubject<ManifestTree | undefined>(undefined);
|
||||
public readonly activeTree = this._activeTree.asObservable();
|
||||
*/
|
||||
|
||||
// TODO: what is the best context to put this in?
|
||||
private _activeTreeItem = new UniqueObjectBehaviorSubject<Entity | undefined>(undefined);
|
||||
public readonly activeTreeItem = this._activeTreeItem.asObservable();
|
||||
#activeTreeItem = new ObjectState<ActiveTreeItemType | undefined>(undefined);
|
||||
public readonly activeTreeItem = this.#activeTreeItem.asObservable();
|
||||
|
||||
// TODO: what is the best context to put this in?
|
||||
private _activeView = new BehaviorSubject<ManifestSectionView | undefined>(undefined);
|
||||
public readonly activeView = this._activeView.asObservable();
|
||||
#activeViewPathname = new StringState(undefined);
|
||||
public readonly activeViewPathname = this.#activeViewPathname.asObservable();
|
||||
|
||||
constructor(sectionManifest: ManifestSection) {
|
||||
this.#manifest = new BehaviorSubject<ManifestSection>(sectionManifest);
|
||||
this.manifest = this.#manifest.asObservable();
|
||||
constructor(manifest: ManifestSection) {
|
||||
this.setManifest(manifest);
|
||||
}
|
||||
|
||||
public setManifest(data: ManifestSection) {
|
||||
this.#manifest.next({ ...data });
|
||||
}
|
||||
|
||||
public getData() {
|
||||
return this.#manifest.getValue();
|
||||
public setManifest(manifest?: ManifestSection) {
|
||||
this.#manifestAlias.next(manifest?.alias);
|
||||
this.#manifestPathname.next(manifest?.meta?.pathname);
|
||||
this.#manifestLabel.next(manifest ? (manifest.meta?.label || manifest.name) : undefined);
|
||||
}
|
||||
|
||||
/*
|
||||
This was not used anywhere
|
||||
public setActiveTree(tree: ManifestTree) {
|
||||
this._activeTree.next(tree);
|
||||
}
|
||||
*/
|
||||
|
||||
public setActiveTreeItem(item: Entity) {
|
||||
this._activeTreeItem.next(item);
|
||||
public setActiveTreeItem(item?: ActiveTreeItemType) {
|
||||
this.#activeTreeItem.next(item);
|
||||
}
|
||||
|
||||
public setActiveView(view: ManifestSectionView) {
|
||||
this._activeView.next(view);
|
||||
public setActiveView(view?: ManifestSectionView) {
|
||||
this.#activeViewPathname.next(view?.meta.pathname);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ export class UmbSectionElement extends UmbLitElement {
|
||||
private _views?: Array<ManifestSectionView>;
|
||||
|
||||
private _sectionContext?: UmbSectionContext;
|
||||
private _sectionAlias?: string;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -53,15 +54,15 @@ export class UmbSectionElement extends UmbLitElement {
|
||||
|
||||
// TODO: currently they don't corporate, as they overwrite each other...
|
||||
this._observeMenuItems();
|
||||
this._observeViews();
|
||||
this._observeSection();
|
||||
});
|
||||
}
|
||||
|
||||
private _observeMenuItems() {
|
||||
if (!this._sectionContext) return;
|
||||
|
||||
this.observe(this._sectionContext?.manifest, (section) => {
|
||||
this._observeSidebarMenuItem(section?.alias);
|
||||
this.observe(this._sectionContext?.alias, (alias) => {
|
||||
this._observeSidebarMenuItem(alias);
|
||||
});
|
||||
|
||||
this.observe(umbExtensionsRegistry.extensionsOfType('workspace'), (workspaceExtensions) => {
|
||||
@@ -88,6 +89,8 @@ export class UmbSectionElement extends UmbLitElement {
|
||||
}
|
||||
|
||||
private _createMenuRoutes() {
|
||||
|
||||
console.log("_createMenuRoutes")
|
||||
// TODO: find a way to make this reuseable across:
|
||||
const workspaceRoutes = this._workspaces?.map((workspace: ManifestWorkspace) => {
|
||||
return [
|
||||
@@ -138,30 +141,27 @@ export class UmbSectionElement extends UmbLitElement {
|
||||
];
|
||||
}
|
||||
|
||||
private _observeViews() {
|
||||
|
||||
|
||||
private _observeSection() {
|
||||
if (!this._sectionContext) return;
|
||||
|
||||
this.observe(
|
||||
this._sectionContext.manifest.pipe(
|
||||
switchMap((section) => {
|
||||
if (!section) return EMPTY;
|
||||
this._sectionContext.alias, (alias) => {
|
||||
this._sectionAlias = alias;
|
||||
this._observeViews();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
umbExtensionsRegistry
|
||||
?.extensionsOfType('sectionView')
|
||||
.pipe(
|
||||
map((views) =>
|
||||
views
|
||||
.filter((view) => view.meta.sections.includes(section.alias))
|
||||
.sort((a, b) => b.meta.weight - a.meta.weight)
|
||||
)
|
||||
) ?? of([])
|
||||
);
|
||||
})
|
||||
),
|
||||
(views) => {
|
||||
if (views.length > 0) {
|
||||
this._views = views;
|
||||
private _observeViews() {
|
||||
|
||||
this.observe(umbExtensionsRegistry?.extensionsOfType('sectionView'), (views) => {
|
||||
const sectionViews = views.filter((view) => {
|
||||
return this._sectionAlias ? view.meta.sections.includes(this._sectionAlias) : false
|
||||
}).sort((a, b) => b.meta.weight - a.meta.weight);
|
||||
if(sectionViews.length > 0) {
|
||||
this._views = sectionViews;
|
||||
this._createViewRoutes();
|
||||
}
|
||||
}
|
||||
@@ -169,6 +169,9 @@ export class UmbSectionElement extends UmbLitElement {
|
||||
}
|
||||
|
||||
private _createViewRoutes() {
|
||||
|
||||
console.log("_createViewRoutes")
|
||||
|
||||
this._routes =
|
||||
this._views?.map((view) => {
|
||||
return {
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
import { Observable, ReplaySubject } from 'rxjs';
|
||||
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
|
||||
// TODO: maybe this should be named something else than store?
|
||||
export class UmbSectionStore {
|
||||
private _currentAlias: ReplaySubject<string> = new ReplaySubject(1);
|
||||
public readonly currentAlias: Observable<string> = this._currentAlias.asObservable();
|
||||
|
||||
public getAllowed() {
|
||||
// TODO: implemented allowed filtering
|
||||
/*
|
||||
const { data } = await getUserSections({});
|
||||
this._allowedSection = data.sections;
|
||||
*/
|
||||
|
||||
return umbExtensionsRegistry.extensionsOfType('section');
|
||||
}
|
||||
|
||||
public setCurrent(alias: string) {
|
||||
this._currentAlias.next(alias);
|
||||
}
|
||||
}
|
||||
|
||||
export const UMB_SECTION_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbSectionStore>(UmbSectionStore.name);
|
||||
@@ -1,5 +1,5 @@
|
||||
import { customElement, property, state } from 'lit/decorators.js';
|
||||
import { UmbSectionContext, UMB_SECTION_CONTEXT_TOKEN } from '../../section/section.context';
|
||||
import { ActiveTreeItemType, UmbSectionContext, UMB_SECTION_CONTEXT_TOKEN } from '../../section/section.context';
|
||||
import {
|
||||
UmbTreeContextMenuPageService,
|
||||
UMB_TREE_CONTEXT_MENU_PAGE_SERVICE_CONTEXT_TOKEN,
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
UmbTreeContextMenuService,
|
||||
UMB_TREE_CONTEXT_MENU_SERVICE_CONTEXT_TOKEN,
|
||||
} from '../context-menu/tree-context-menu.service';
|
||||
import type { Entity, ManifestTreeItemAction, ManifestTree } from '@umbraco-cms/models';
|
||||
import type { ManifestTreeItemAction } from '@umbraco-cms/models';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
|
||||
export type ActionPageEntity = {
|
||||
@@ -24,8 +24,7 @@ export default class UmbTreeItemActionElement extends UmbLitElement {
|
||||
@state()
|
||||
protected _entity: ActionPageEntity = { name: '', key: '' };
|
||||
|
||||
protected _activeTree?: ManifestTree;
|
||||
protected _activeTreeItem?: Entity;
|
||||
protected _activeTreeItem?: ActiveTreeItemType;
|
||||
|
||||
protected _sectionContext?: UmbSectionContext;
|
||||
protected _treeContextMenuService?: UmbTreeContextMenuService;
|
||||
@@ -36,7 +35,6 @@ export default class UmbTreeItemActionElement extends UmbLitElement {
|
||||
|
||||
this.consumeContext(UMB_SECTION_CONTEXT_TOKEN, (sectionContext) => {
|
||||
this._sectionContext = sectionContext;
|
||||
this._observeActiveTree();
|
||||
this._observeActiveTreeItem();
|
||||
});
|
||||
|
||||
@@ -58,14 +56,6 @@ export default class UmbTreeItemActionElement extends UmbLitElement {
|
||||
});
|
||||
}
|
||||
|
||||
private _observeActiveTree() {
|
||||
if (!this._sectionContext) return;
|
||||
|
||||
this.observe(this._sectionContext.activeTree, (tree) => {
|
||||
this._activeTree = tree;
|
||||
});
|
||||
}
|
||||
|
||||
private _observeActiveTreeItem() {
|
||||
if (!this._sectionContext) return;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { customElement, state } from 'lit/decorators.js';
|
||||
import { map } from 'rxjs';
|
||||
import { UmbSectionContext, UMB_SECTION_CONTEXT_TOKEN } from '../../section/section.context';
|
||||
import type { Entity, ManifestTreeItemAction, ManifestTree } from '@umbraco-cms/models';
|
||||
import type { Entity, ManifestTreeItemAction } from '@umbraco-cms/models';
|
||||
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
|
||||
@@ -30,9 +30,6 @@ export class UmbTreeContextMenuPageActionListElement extends UmbLitElement {
|
||||
@state()
|
||||
private _actions?: Array<ManifestTreeItemAction>;
|
||||
|
||||
@state()
|
||||
private _activeTree?: ManifestTree;
|
||||
|
||||
@state()
|
||||
private _activeTreeItem?: Entity;
|
||||
|
||||
@@ -43,7 +40,6 @@ export class UmbTreeContextMenuPageActionListElement extends UmbLitElement {
|
||||
|
||||
this.consumeContext(UMB_SECTION_CONTEXT_TOKEN, (sectionContext) => {
|
||||
this._sectionContext = sectionContext;
|
||||
this._observeActiveTree();
|
||||
this._observeActiveTreeItem();
|
||||
this._observeTreeItemActions();
|
||||
});
|
||||
@@ -62,14 +58,6 @@ export class UmbTreeContextMenuPageActionListElement extends UmbLitElement {
|
||||
);
|
||||
}
|
||||
|
||||
private _observeActiveTree() {
|
||||
if (!this._sectionContext) return;
|
||||
|
||||
this.observe(this._sectionContext.activeTree, (tree) => {
|
||||
this._activeTree = tree || undefined;
|
||||
});
|
||||
}
|
||||
|
||||
private _observeActiveTreeItem() {
|
||||
if (!this._sectionContext) return;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { customElement, property, state } from 'lit/decorators.js';
|
||||
import UmbTreeItemActionElement, { ActionPageEntity } from '../action/tree-item-action.element';
|
||||
import { UmbTreeContextMenuService } from './tree-context-menu.service';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
import { UniqueBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { DeepState } from '@umbraco-cms/observable-api';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
|
||||
// TODO: Refactor this, its not a service and the data should be handled by a context api.
|
||||
@@ -15,7 +15,7 @@ export class UmbTreeContextMenuPageService extends UmbLitElement {
|
||||
@property({ type: Object })
|
||||
public actionEntity: ActionPageEntity = { key: '', name: '' };
|
||||
|
||||
#entity = new UniqueBehaviorSubject({ key: '', name: '' } as ActionPageEntity);
|
||||
#entity = new DeepState({ key: '', name: '' } as ActionPageEntity);
|
||||
public readonly entity = this.#entity.asObservable();
|
||||
|
||||
@state()
|
||||
|
||||
@@ -116,8 +116,8 @@ export class UmbTreeItem extends UmbLitElement {
|
||||
private _observeSection() {
|
||||
if (!this._sectionContext) return;
|
||||
|
||||
this.observe(this._sectionContext?.manifest, (section) => {
|
||||
this._href = this._constructPath(section?.meta.pathname || '', this.entityType, this.key);
|
||||
this.observe(this._sectionContext?.pathname, (pathname) => {
|
||||
this._href = this._constructPath(pathname || '', this.entityType, this.key);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -184,7 +184,8 @@ export class UmbTreeItem extends UmbLitElement {
|
||||
private _openActions() {
|
||||
if (!this._treeContext || !this._sectionContext) return;
|
||||
|
||||
this._sectionContext?.setActiveTree(this._treeContext?.tree);
|
||||
// This is out-commented as it was not used. only kept if someone need this later:
|
||||
//this._sectionContext?.setActiveTree(this._treeContext?.tree);
|
||||
|
||||
this._sectionContext?.setActiveTreeItem({
|
||||
key: this.key,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { Observable } from 'rxjs';
|
||||
import type { ManifestTree } from '@umbraco-cms/models';
|
||||
import { UniqueBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { DeepState } from '@umbraco-cms/observable-api';
|
||||
|
||||
export interface UmbTreeContext {
|
||||
tree: ManifestTree;
|
||||
@@ -14,10 +14,10 @@ export interface UmbTreeContext {
|
||||
export class UmbTreeContextBase implements UmbTreeContext {
|
||||
public tree: ManifestTree;
|
||||
|
||||
#selectable = new UniqueBehaviorSubject(false);
|
||||
#selectable = new DeepState(false);
|
||||
public readonly selectable = this.#selectable.asObservable();
|
||||
|
||||
#selection = new UniqueBehaviorSubject(<Array<string>>[]);
|
||||
#selection = new DeepState(<Array<string>>[]);
|
||||
public readonly selection = this.#selection.asObservable();
|
||||
|
||||
constructor(tree: ManifestTree) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { UmbWorkspaceContentContext } from '../workspace/workspace-content/workspace-content.context';
|
||||
import type { DataTypeDetails } from '@umbraco-cms/models';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
import { createObservablePart, UniqueObjectBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { createObservablePart, ObjectState } from '@umbraco-cms/observable-api';
|
||||
import { UmbContextConsumerController, UmbContextProviderController } from '@umbraco-cms/context-api';
|
||||
|
||||
// If we get this from the server then we can consider using TypeScripts Partial<> around the model from the Management-API.
|
||||
@@ -16,7 +16,7 @@ export type WorkspacePropertyData<ValueType> = {
|
||||
export class UmbWorkspacePropertyContext<ValueType = unknown> {
|
||||
private _providerController: UmbContextProviderController;
|
||||
|
||||
private _data = new UniqueObjectBehaviorSubject<WorkspacePropertyData<ValueType>>({});
|
||||
private _data = new ObjectState<WorkspacePropertyData<ValueType>>({});
|
||||
|
||||
public readonly alias = createObservablePart(this._data, (data) => data.alias);
|
||||
public readonly label = createObservablePart(this._data, (data) => data.label);
|
||||
@@ -45,7 +45,7 @@ export class UmbWorkspacePropertyContext<ValueType = unknown> {
|
||||
this._data.update({ description: description });
|
||||
}
|
||||
public setValue(value: WorkspacePropertyData<ValueType>['value']) {
|
||||
// Note: Do not try to compare new / old value, as it can of any type. We trust the UniqueBehaviorSubject in doing such.
|
||||
// Note: Do not try to compare new / old value, as it can of any type. We trust the ObjectState in doing such.
|
||||
|
||||
this._data.update({ value: value });
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { v4 as uuidv4 } from 'uuid';
|
||||
import { UmbNotificationService, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN, UmbNotificationDefaultData } from '@umbraco-cms/notification';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
import { UmbContextConsumerController, UmbContextProviderController } from '@umbraco-cms/context-api';
|
||||
import { UniqueBehaviorSubject, UmbObserverController, createObservablePart } from '@umbraco-cms/observable-api';
|
||||
import { DeepState, UmbObserverController, createObservablePart } from '@umbraco-cms/observable-api';
|
||||
import { UmbContentStore } from '@umbraco-cms/store';
|
||||
import type { ContentTreeItem } from '@umbraco-cms/backend-api';
|
||||
|
||||
@@ -33,7 +33,7 @@ export abstract class UmbWorkspaceContentContext<
|
||||
constructor(host: UmbControllerHostInterface, defaultData: ContentTypeType, storeAlias: string, entityType: string) {
|
||||
this._host = host;
|
||||
|
||||
this._data = new UniqueBehaviorSubject<ContentTypeType>(defaultData);
|
||||
this._data = new DeepState<ContentTypeType>(defaultData);
|
||||
this.data = this._data.asObservable();
|
||||
this.name = createObservablePart(this._data, (data) => data.name);
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { UmbContextProviderController } from '@umbraco-cms/context-api';
|
||||
import type { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
import { UniqueBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { DeepState } from '@umbraco-cms/observable-api';
|
||||
|
||||
export class UmbPropertyActionMenuContext {
|
||||
#isOpen = new UniqueBehaviorSubject(false);
|
||||
#isOpen = new DeepState(false);
|
||||
public readonly isOpen = this.#isOpen.asObservable();
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { DictionaryDetails } from '@umbraco-cms/models';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { createObservablePart, UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { createObservablePart, ArrayState } from '@umbraco-cms/observable-api';
|
||||
import { UmbStoreBase } from '@umbraco-cms/store';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
import { EntityTreeItem } from '@umbraco-cms/backend-api';
|
||||
@@ -19,7 +19,7 @@ export class UmbDictionaryDetailStore extends UmbStoreBase {
|
||||
|
||||
|
||||
// TODO: use the right type:
|
||||
#data = new UniqueArrayBehaviorSubject<EntityTreeItem>([], (x) => x.key);
|
||||
#data = new ArrayState<EntityTreeItem>([], (x) => x.key);
|
||||
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
@@ -34,7 +34,7 @@ export class UmbDictionaryDetailStore extends UmbStoreBase {
|
||||
*/
|
||||
getByKey(key: string) {
|
||||
// TODO: use backend cli when available.
|
||||
fetch(`/umbraco/management/api/v1/document/dictionary/${key}`)
|
||||
fetch(`/umbraco/management/api/v1/dictionary/details/${key}`)
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
this.#data.append(data);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { DictionaryResource, DocumentTreeItem } from '@umbraco-cms/backend-api';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { createObservablePart, UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { createObservablePart, ArrayState } from '@umbraco-cms/observable-api';
|
||||
import { UmbStoreBase } from '@umbraco-cms/store';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
@@ -18,7 +18,7 @@ export const UMB_DICTIONARY_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbDi
|
||||
export class UmbDictionaryTreeStore extends UmbStoreBase {
|
||||
|
||||
|
||||
#data = new UniqueArrayBehaviorSubject<DocumentTreeItem>([], (x) => x.key);
|
||||
#data = new ArrayState<DocumentTreeItem>([], (x) => x.key);
|
||||
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { createObservablePart, UniqueBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { createObservablePart, DeepState } from '@umbraco-cms/observable-api';
|
||||
|
||||
export type UmbModelType = 'dialog' | 'sidebar';
|
||||
|
||||
@@ -10,7 +10,7 @@ export type UmbCurrentUserHistoryItem = {
|
||||
};
|
||||
|
||||
export class UmbCurrentUserHistoryStore {
|
||||
#history = new UniqueBehaviorSubject(<Array<UmbCurrentUserHistoryItem>>[]);
|
||||
#history = new DeepState(<Array<UmbCurrentUserHistoryItem>>[]);
|
||||
|
||||
public readonly history = this.#history.asObservable();
|
||||
public readonly latestHistory = createObservablePart(this.#history, (historyItems) => historyItems.slice(-10));
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { umbUsersData } from '../../../core/mocks/data/users.data';
|
||||
import type { UserDetails } from '@umbraco-cms/models';
|
||||
import { umbracoPath } from '@umbraco-cms/utils';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { ObjectState } from '@umbraco-cms/observable-api';
|
||||
|
||||
export class UmbCurrentUserStore {
|
||||
private _currentUser = new BehaviorSubject<UserDetails>(umbUsersData.getAll()[0]); //TODO: Temp solution to set the first user as the current logged in user
|
||||
public readonly currentUser: Observable<UserDetails> = this._currentUser.asObservable();
|
||||
|
||||
private _currentUser = new ObjectState<UserDetails | undefined>(undefined);
|
||||
public readonly currentUser = this._currentUser.asObservable();
|
||||
|
||||
/**
|
||||
* logs out the user
|
||||
@@ -24,7 +24,8 @@ export class UmbCurrentUserStore {
|
||||
public get isAdmin(): boolean {
|
||||
//TODO: Find a way to figure out if current user is in the admin group
|
||||
const adminUserGroupKey = 'c630d49e-4e7b-42ea-b2bc-edc0edacb6b1';
|
||||
return this._currentUser.getValue()?.userGroups.includes(adminUserGroupKey);
|
||||
const currentUser = this._currentUser.getValue();
|
||||
return currentUser ? currentUser.userGroups.includes(adminUserGroupKey) : false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { UserGroupDetails } from '@umbraco-cms/models';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
import { createObservablePart, UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { createObservablePart, ArrayState } from '@umbraco-cms/observable-api';
|
||||
import { UmbStoreBase } from '@umbraco-cms/store';
|
||||
|
||||
// TODO: get rid of this type addition & { ... }:
|
||||
@@ -18,7 +18,7 @@ export const UMB_USER_GROUP_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbUserGro
|
||||
export class UmbUserGroupStore extends UmbStoreBase {
|
||||
|
||||
|
||||
#groups = new UniqueArrayBehaviorSubject<UmbUserGroupStoreItemType>([], x => x.key);
|
||||
#groups = new ArrayState<UmbUserGroupStoreItemType>([], x => x.key);
|
||||
public groups = this.#groups.asObservable();
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import type { ManifestWorkspace, UserDetails } from '@umbraco-cms/models';
|
||||
import { UmbUserStore, UMB_USER_STORE_CONTEXT_TOKEN } from 'src/backoffice/users/users/user.store';
|
||||
import { createExtensionElement } from '@umbraco-cms/extensions-api';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
import { UniqueBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { DeepState } from '@umbraco-cms/observable-api';
|
||||
|
||||
@customElement('umb-section-view-users')
|
||||
export class UmbSectionViewUsersElement extends UmbLitElement {
|
||||
@@ -33,13 +33,13 @@ export class UmbSectionViewUsersElement extends UmbLitElement {
|
||||
// TODO: This must be turned into context api: Maybe its a Collection View (SectionView Collection View)?
|
||||
private _userStore?: UmbUserStore;
|
||||
|
||||
#selection = new UniqueBehaviorSubject(<Array<string>>[]);
|
||||
#selection = new DeepState(<Array<string>>[]);
|
||||
public readonly selection = this.#selection.asObservable();
|
||||
|
||||
#users = new UniqueBehaviorSubject(<Array<UserDetails>>[]);
|
||||
#users = new DeepState(<Array<UserDetails>>[]);
|
||||
public readonly users = this.#users.asObservable();
|
||||
|
||||
#search = new UniqueBehaviorSubject('');
|
||||
#search = new DeepState('');
|
||||
public readonly search = this.#search.asObservable();
|
||||
|
||||
constructor() {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import type { UserDetails } from '@umbraco-cms/models';
|
||||
import { createObservablePart, UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
|
||||
import { createObservablePart, ArrayState, NumberState } from '@umbraco-cms/observable-api';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { UmbStoreBase } from '@umbraco-cms/store';
|
||||
import type { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
@@ -18,10 +17,10 @@ export const UMB_USER_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbUserStore>('U
|
||||
export class UmbUserStore extends UmbStoreBase {
|
||||
|
||||
|
||||
#users = new UniqueArrayBehaviorSubject<UserDetails>([], x => x.key);
|
||||
#users = new ArrayState<UserDetails>([], x => x.key);
|
||||
public users = this.#users.asObservable();
|
||||
|
||||
#totalUsers = new BehaviorSubject(0);
|
||||
#totalUsers = new NumberState(0);
|
||||
public readonly totalUsers = this.#totalUsers.asObservable();
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ import './layouts/property-editor-ui-picker/modal-layout-property-editor-ui-pick
|
||||
import './layouts/modal-layout-current-user.element';
|
||||
|
||||
import { UUIModalSidebarSize } from '@umbraco-ui/uui-modal-sidebar';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { UmbModalChangePasswordData } from './layouts/modal-layout-change-password.element';
|
||||
import type { UmbModalIconPickerData } from './layouts/icon-picker/modal-layout-icon-picker.element';
|
||||
|
||||
@@ -16,6 +15,7 @@ import type { UmbModalContentPickerData } from './layouts/content-picker/modal-l
|
||||
import type { UmbModalPropertyEditorUIPickerData } from './layouts/property-editor-ui-picker/modal-layout-property-editor-ui-picker.element';
|
||||
import { UmbModalHandler } from './modal-handler';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { ArrayState } from '@umbraco-cms/observable-api';
|
||||
|
||||
export type UmbModalType = 'dialog' | 'sidebar';
|
||||
|
||||
@@ -27,7 +27,8 @@ export interface UmbModalOptions<UmbModalData> {
|
||||
|
||||
// TODO: Should this be called UmbModalContext ? as we don't have 'services' as a term.
|
||||
export class UmbModalService {
|
||||
#modals = new BehaviorSubject(<Array<UmbModalHandler>>[]);
|
||||
|
||||
#modals = new ArrayState(<Array<UmbModalHandler>>[]);
|
||||
public readonly modals = this.#modals.asObservable();
|
||||
|
||||
/**
|
||||
|
||||
@@ -66,7 +66,7 @@ export class UmbInstallerConsentElement extends UmbLitElement {
|
||||
if (!this._installerContext) return;
|
||||
|
||||
this.observe(this._installerContext.settings, (settings) => {
|
||||
this._telemetryLevels = settings.user?.consentLevels ?? [];
|
||||
this._telemetryLevels = settings?.user?.consentLevels ?? [];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { BehaviorSubject, Observable, ReplaySubject } from 'rxjs';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Install, InstallResource, InstallSettings, ProblemDetails, TelemetryLevel } from '@umbraco-cms/backend-api';
|
||||
import { tryExecute } from '@umbraco-cms/resources';
|
||||
import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
import { ObjectState, NumberState } from '@umbraco-cms/observable-api';
|
||||
|
||||
/**
|
||||
* Context API for the installer
|
||||
@@ -9,20 +10,20 @@ import { UmbContextToken } from '@umbraco-cms/context-api';
|
||||
* @class UmbInstallerContext
|
||||
*/
|
||||
export class UmbInstallerContext {
|
||||
private _data = new BehaviorSubject<Install>({
|
||||
private _data = new ObjectState<Install>({
|
||||
user: { name: '', email: '', password: '', subscribeToNewsletter: false },
|
||||
database: { id: '', providerName: '' },
|
||||
telemetryLevel: TelemetryLevel.BASIC,
|
||||
});
|
||||
public readonly data = this._data.asObservable();
|
||||
|
||||
private _currentStep = new BehaviorSubject<number>(1);
|
||||
private _currentStep = new NumberState<number>(1);
|
||||
public readonly currentStep = this._currentStep.asObservable();
|
||||
|
||||
private _settings = new ReplaySubject<InstallSettings>();
|
||||
private _settings = new ObjectState<InstallSettings | undefined>(undefined);
|
||||
public readonly settings = this._settings.asObservable();
|
||||
|
||||
private _installStatus = new ReplaySubject<ProblemDetails | null>(1);
|
||||
private _installStatus = new ObjectState<ProblemDetails | null>(null);
|
||||
public readonly installStatus = this._installStatus.asObservable();
|
||||
|
||||
constructor() {
|
||||
|
||||
@@ -13,7 +13,7 @@ Generally a Store will be holding one or more RxJS Subjects, each Subject is mad
|
||||
````
|
||||
class MyProductStore {
|
||||
|
||||
protected _products = new UniqueBehaviorSubject(<Array<T>>[]);
|
||||
protected _products = new ArrayState(<Array<T>>[]);
|
||||
public readonly products = this._items.asObservable();
|
||||
|
||||
protected host: UmbControllerHostInterface;
|
||||
|
||||
Reference in New Issue
Block a user