Merge branch 'main' into manual-json-schema
This commit is contained in:
@@ -44,6 +44,7 @@
|
|||||||
"local-rules/enforce-element-suffix-on-element-class-name": "error",
|
"local-rules/enforce-element-suffix-on-element-class-name": "error",
|
||||||
"local-rules/prefer-umbraco-cms-imports": "error",
|
"local-rules/prefer-umbraco-cms-imports": "error",
|
||||||
"local-rules/no-external-imports": "error",
|
"local-rules/no-external-imports": "error",
|
||||||
|
"local-rules/umb-class-prefix": "error",
|
||||||
"@typescript-eslint/no-non-null-assertion": "off"
|
"@typescript-eslint/no-non-null-assertion": "off"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
|
|||||||
@@ -205,4 +205,31 @@ module.exports = {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** @type {import('eslint').Rule.RuleModule} */
|
||||||
|
'umb-class-prefix': {
|
||||||
|
meta: {
|
||||||
|
type: 'problem',
|
||||||
|
docs: {
|
||||||
|
description: 'Ensure that all class declarations are prefixed with "Umb"',
|
||||||
|
category: 'Best Practices',
|
||||||
|
recommended: true,
|
||||||
|
},
|
||||||
|
schema: [],
|
||||||
|
},
|
||||||
|
create: function (context) {
|
||||||
|
function checkClassName(node) {
|
||||||
|
if (node.id && node.id.name && !node.id.name.startsWith('Umb')) {
|
||||||
|
context.report({
|
||||||
|
node: node.id,
|
||||||
|
message: 'Class declaration should be prefixed with "Umb"',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
ClassDeclaration: checkClassName,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { UmbContextRequestEventImplementation, umbContextRequestEventType } from
|
|||||||
|
|
||||||
const testContextAlias = 'my-test-context';
|
const testContextAlias = 'my-test-context';
|
||||||
|
|
||||||
class MyClass {
|
class UmbTestContextConsumerClass {
|
||||||
prop = 'value from provider';
|
prop = 'value from provider';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,16 +39,20 @@ describe('UmbContextConsumer', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('works with UmbContextProvider', (done) => {
|
it('works with UmbContextProvider', (done) => {
|
||||||
const provider = new UmbContextProvider(document.body, testContextAlias, new MyClass());
|
const provider = new UmbContextProvider(document.body, testContextAlias, new UmbTestContextConsumerClass());
|
||||||
provider.hostConnected();
|
provider.hostConnected();
|
||||||
|
|
||||||
const element = document.createElement('div');
|
const element = document.createElement('div');
|
||||||
document.body.appendChild(element);
|
document.body.appendChild(element);
|
||||||
|
|
||||||
const localConsumer = new UmbContextConsumer(element, testContextAlias, (_instance: MyClass) => {
|
const localConsumer = new UmbContextConsumer(
|
||||||
expect(_instance.prop).to.eq('value from provider');
|
element,
|
||||||
done();
|
testContextAlias,
|
||||||
});
|
(_instance: UmbTestContextConsumerClass) => {
|
||||||
|
expect(_instance.prop).to.eq('value from provider');
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
);
|
||||||
localConsumer.hostConnected();
|
localConsumer.hostConnected();
|
||||||
|
|
||||||
provider.hostDisconnected();
|
provider.hostDisconnected();
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable no-case-declarations */
|
||||||
/**
|
/**
|
||||||
* Change the collection of Contexts into a simplified array of data
|
* Change the collection of Contexts into a simplified array of data
|
||||||
*
|
*
|
||||||
@@ -39,10 +40,36 @@ function contextItemData(contextInstance:any):DebugContextItemData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const value = contextInstance[key];
|
const value = contextInstance[key];
|
||||||
if (typeof value === 'string' || typeof value === 'boolean') {
|
const valueType = typeof value;
|
||||||
props.push({ key: key, value: value, type: typeof value });
|
|
||||||
} else {
|
switch (valueType) {
|
||||||
props.push({ key: key, type: typeof value });
|
case 'string':
|
||||||
|
case 'boolean':
|
||||||
|
case 'number':
|
||||||
|
props.push({ key: key, value: value, type: typeof value });
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'object':
|
||||||
|
|
||||||
|
// Check if the object is an observable (by checking if it has a subscribe method/function)
|
||||||
|
const isSubscribeLike = 'subscribe' in value && typeof value['subscribe'] === 'function';
|
||||||
|
const isWebComponent = value instanceof HTMLElement;
|
||||||
|
|
||||||
|
let valueToDisplay = "Complex Object";
|
||||||
|
if(isWebComponent){
|
||||||
|
const tagName = value.tagName.toLowerCase();
|
||||||
|
|
||||||
|
valueToDisplay = `Web Component <${tagName}>`;
|
||||||
|
} else if(isSubscribeLike){
|
||||||
|
valueToDisplay = "Subscribable";
|
||||||
|
}
|
||||||
|
|
||||||
|
props.push({ key: key, type: typeof value, value: valueToDisplay });
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
props.push({ key: key, type: typeof value });
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,21 +3,21 @@ import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
|||||||
import { UmbContextConsumer } from '../consume/context-consumer';
|
import { UmbContextConsumer } from '../consume/context-consumer';
|
||||||
import { UmbContextProviderController } from './context-provider.controller';
|
import { UmbContextProviderController } from './context-provider.controller';
|
||||||
|
|
||||||
class MyClass {
|
class UmbTestContextProviderControllerClass {
|
||||||
prop = 'value from provider';
|
prop = 'value from provider';
|
||||||
}
|
}
|
||||||
|
|
||||||
class ControllerHostElement extends UmbLitElement {}
|
class UmbTestControllerHostElement extends UmbLitElement {}
|
||||||
const controllerHostElement = defineCE(ControllerHostElement);
|
const controllerHostElement = defineCE(UmbTestControllerHostElement);
|
||||||
|
|
||||||
describe('UmbContextProviderController', () => {
|
describe('UmbContextProviderController', () => {
|
||||||
let instance: MyClass;
|
let instance: UmbTestContextProviderControllerClass;
|
||||||
let provider: UmbContextProviderController;
|
let provider: UmbContextProviderController;
|
||||||
let element: UmbLitElement;
|
let element: UmbLitElement;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
element = await fixture(`<${controllerHostElement}></${controllerHostElement}>`);
|
element = await fixture(`<${controllerHostElement}></${controllerHostElement}>`);
|
||||||
instance = new MyClass();
|
instance = new UmbTestContextProviderControllerClass();
|
||||||
provider = new UmbContextProviderController(element, 'my-test-context', instance);
|
provider = new UmbContextProviderController(element, 'my-test-context', instance);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -39,11 +39,15 @@ describe('UmbContextProviderController', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('works with UmbContextConsumer', (done) => {
|
it('works with UmbContextConsumer', (done) => {
|
||||||
const localConsumer = new UmbContextConsumer(element, 'my-test-context', (_instance: MyClass) => {
|
const localConsumer = new UmbContextConsumer(
|
||||||
expect(_instance.prop).to.eq('value from provider');
|
element,
|
||||||
done();
|
'my-test-context',
|
||||||
localConsumer.hostDisconnected();
|
(_instance: UmbTestContextProviderControllerClass) => {
|
||||||
});
|
expect(_instance.prop).to.eq('value from provider');
|
||||||
|
done();
|
||||||
|
localConsumer.hostDisconnected();
|
||||||
|
}
|
||||||
|
);
|
||||||
localConsumer.hostConnected();
|
localConsumer.hostConnected();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,16 +3,16 @@ import { UmbContextConsumer } from '../consume/context-consumer';
|
|||||||
import { UmbContextRequestEventImplementation } from '../consume/context-request.event';
|
import { UmbContextRequestEventImplementation } from '../consume/context-request.event';
|
||||||
import { UmbContextProvider } from './context-provider';
|
import { UmbContextProvider } from './context-provider';
|
||||||
|
|
||||||
class MyClass {
|
class UmbTestContextProviderClass {
|
||||||
prop = 'value from provider';
|
prop = 'value from provider';
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('UmbContextProvider', () => {
|
describe('UmbContextProvider', () => {
|
||||||
let instance: MyClass;
|
let instance: UmbTestContextProviderClass;
|
||||||
let provider: UmbContextProvider;
|
let provider: UmbContextProvider;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
instance = new MyClass();
|
instance = new UmbTestContextProviderClass();
|
||||||
provider = new UmbContextProvider(document.body, 'my-test-context', instance);
|
provider = new UmbContextProvider(document.body, 'my-test-context', instance);
|
||||||
provider.hostConnected();
|
provider.hostConnected();
|
||||||
});
|
});
|
||||||
@@ -40,10 +40,13 @@ describe('UmbContextProvider', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('handles context request events', (done) => {
|
it('handles context request events', (done) => {
|
||||||
const event = new UmbContextRequestEventImplementation('my-test-context', (_instance: MyClass) => {
|
const event = new UmbContextRequestEventImplementation(
|
||||||
expect(_instance.prop).to.eq('value from provider');
|
'my-test-context',
|
||||||
done();
|
(_instance: UmbTestContextProviderClass) => {
|
||||||
});
|
expect(_instance.prop).to.eq('value from provider');
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
document.body.dispatchEvent(event);
|
document.body.dispatchEvent(event);
|
||||||
});
|
});
|
||||||
@@ -52,11 +55,15 @@ describe('UmbContextProvider', () => {
|
|||||||
const element = document.createElement('div');
|
const element = document.createElement('div');
|
||||||
document.body.appendChild(element);
|
document.body.appendChild(element);
|
||||||
|
|
||||||
const localConsumer = new UmbContextConsumer(element, 'my-test-context', (_instance: MyClass) => {
|
const localConsumer = new UmbContextConsumer(
|
||||||
expect(_instance.prop).to.eq('value from provider');
|
element,
|
||||||
done();
|
'my-test-context',
|
||||||
localConsumer.hostDisconnected();
|
(_instance: UmbTestContextProviderClass) => {
|
||||||
});
|
expect(_instance.prop).to.eq('value from provider');
|
||||||
|
done();
|
||||||
|
localConsumer.hostDisconnected();
|
||||||
|
}
|
||||||
|
);
|
||||||
localConsumer.hostConnected();
|
localConsumer.hostConnected();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ import { UmbContextToken } from './context-token';
|
|||||||
|
|
||||||
const testContextAlias = 'my-test-context';
|
const testContextAlias = 'my-test-context';
|
||||||
|
|
||||||
class MyClass {
|
class UmbTestContextTokenClass {
|
||||||
prop = 'value from provider';
|
prop = 'value from provider';
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('ContextAlias', () => {
|
describe('ContextAlias', () => {
|
||||||
const contextAlias = new UmbContextToken<MyClass>(testContextAlias);
|
const contextAlias = new UmbContextToken<UmbTestContextTokenClass>(testContextAlias);
|
||||||
const typedProvider = new UmbContextProvider(document.body, contextAlias, new MyClass());
|
const typedProvider = new UmbContextProvider(document.body, contextAlias, new UmbTestContextTokenClass());
|
||||||
typedProvider.hostConnected();
|
typedProvider.hostConnected();
|
||||||
|
|
||||||
after(() => {
|
after(() => {
|
||||||
@@ -27,7 +27,7 @@ describe('ContextAlias', () => {
|
|||||||
document.body.appendChild(element);
|
document.body.appendChild(element);
|
||||||
|
|
||||||
const localConsumer = new UmbContextConsumer(element, contextAlias, (_instance) => {
|
const localConsumer = new UmbContextConsumer(element, contextAlias, (_instance) => {
|
||||||
expect(_instance).to.be.instanceOf(MyClass);
|
expect(_instance).to.be.instanceOf(UmbTestContextTokenClass);
|
||||||
expect(_instance.prop).to.eq('value from provider');
|
expect(_instance.prop).to.eq('value from provider');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -39,8 +39,8 @@ describe('ContextAlias', () => {
|
|||||||
const element = document.createElement('div');
|
const element = document.createElement('div');
|
||||||
document.body.appendChild(element);
|
document.body.appendChild(element);
|
||||||
|
|
||||||
const localConsumer = new UmbContextConsumer(element, testContextAlias, (_instance: MyClass) => {
|
const localConsumer = new UmbContextConsumer(element, testContextAlias, (_instance: UmbTestContextTokenClass) => {
|
||||||
expect(_instance).to.be.instanceOf(MyClass);
|
expect(_instance).to.be.instanceOf(UmbTestContextTokenClass);
|
||||||
expect(_instance.prop).to.eq('value from provider');
|
expect(_instance.prop).to.eq('value from provider');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,18 +3,18 @@ import { customElement } from 'lit/decorators.js';
|
|||||||
import { UmbControllerHostElement, UmbControllerHostMixin } from './controller-host.mixin';
|
import { UmbControllerHostElement, UmbControllerHostMixin } from './controller-host.mixin';
|
||||||
import { UmbContextProviderController } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextProviderController } from '@umbraco-cms/backoffice/context-api';
|
||||||
|
|
||||||
class MyClass {
|
class UmbTestContext {
|
||||||
prop = 'value from provider';
|
prop = 'value from provider';
|
||||||
}
|
}
|
||||||
|
|
||||||
@customElement('test-my-controller-host')
|
@customElement('test-my-controller-host')
|
||||||
export class MyHostElement extends UmbControllerHostMixin(HTMLElement) {}
|
export class UmbTestControllerHostElement extends UmbControllerHostMixin(HTMLElement) {}
|
||||||
|
|
||||||
describe('UmbContextProvider', () => {
|
describe('UmbContextProvider', () => {
|
||||||
type NewType = UmbControllerHostElement;
|
type NewType = UmbControllerHostElement;
|
||||||
|
|
||||||
let hostElement: NewType;
|
let hostElement: NewType;
|
||||||
const contextInstance = new MyClass();
|
const contextInstance = new UmbTestContext();
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
hostElement = document.createElement('test-my-controller-host') as UmbControllerHostElement;
|
hostElement = document.createElement('test-my-controller-host') as UmbControllerHostElement;
|
||||||
@@ -35,7 +35,7 @@ describe('UmbContextProvider', () => {
|
|||||||
describe('Unique controllers replace each other', () => {
|
describe('Unique controllers replace each other', () => {
|
||||||
it('has a host property', () => {
|
it('has a host property', () => {
|
||||||
const firstCtrl = new UmbContextProviderController(hostElement, 'my-test-context', contextInstance);
|
const firstCtrl = new UmbContextProviderController(hostElement, 'my-test-context', contextInstance);
|
||||||
const secondCtrl = new UmbContextProviderController(hostElement, 'my-test-context', new MyClass());
|
const secondCtrl = new UmbContextProviderController(hostElement, 'my-test-context', new UmbTestContext());
|
||||||
|
|
||||||
expect(hostElement.hasController(firstCtrl)).to.be.false;
|
expect(hostElement.hasController(firstCtrl)).to.be.false;
|
||||||
expect(hostElement.hasController(secondCtrl)).to.be.true;
|
expect(hostElement.hasController(secondCtrl)).to.be.true;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* @param {(mappable: T) => R} mappingFunction - Method to return the part for this Observable to return.
|
* @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.
|
* @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.
|
* @description - Creates a RxJS Observable from RxJS Subject.
|
||||||
* @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>
|
* @example <caption>Example append new entry for a ArrayState or a part of UmbDeepState/UmbObjectState it which is an array. Where the key is unique and the item will be updated if matched with existing.</caption>
|
||||||
* const entry = {id: 'myKey', value: 'myValue'};
|
* const entry = {id: 'myKey', value: 'myValue'};
|
||||||
* const newDataSet = appendToFrozenArray(mySubject.getValue(), entry, x => x.id === id);
|
* const newDataSet = appendToFrozenArray(mySubject.getValue(), entry, x => x.id === id);
|
||||||
* mySubject.next(newDataSet);
|
* mySubject.next(newDataSet);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { expect } from '@open-wc/testing';
|
import { expect } from '@open-wc/testing';
|
||||||
import { ArrayState } from './array-state';
|
import { UmbArrayState } from './array-state';
|
||||||
|
|
||||||
describe('ArrayState', () => {
|
describe('ArrayState', () => {
|
||||||
type ObjectType = { key: string; another: string };
|
type ObjectType = { key: string; another: string };
|
||||||
type ArrayType = ObjectType[];
|
type ArrayType = ObjectType[];
|
||||||
|
|
||||||
let subject: ArrayState<ObjectType>;
|
let subject: UmbArrayState<ObjectType>;
|
||||||
let initialData: ArrayType;
|
let initialData: ArrayType;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -14,7 +14,7 @@ describe('ArrayState', () => {
|
|||||||
{ key: '2', another: 'myValue2' },
|
{ key: '2', another: 'myValue2' },
|
||||||
{ key: '3', another: 'myValue3' },
|
{ key: '3', another: 'myValue3' },
|
||||||
];
|
];
|
||||||
subject = new ArrayState(initialData, (x) => x.key);
|
subject = new UmbArrayState(initialData, (x) => x.key);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('replays latests, no matter the amount of subscriptions.', (done) => {
|
it('replays latests, no matter the amount of subscriptions.', (done) => {
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
import { DeepState } from './deep-state';
|
import { UmbDeepState } from './deep-state';
|
||||||
import { partialUpdateFrozenArray } from './partial-update-frozen-array.function';
|
import { partialUpdateFrozenArray } from './partial-update-frozen-array.function';
|
||||||
import { pushToUniqueArray } from './push-to-unique-array.function';
|
import { pushToUniqueArray } from './push-to-unique-array.function';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @export
|
* @export
|
||||||
* @class ArrayState
|
* @class UmbArrayState
|
||||||
* @extends {DeepState<T>}
|
* @extends {UmbDeepState<T>}
|
||||||
* @description - A RxJS BehaviorSubject which deepFreezes the object-data to ensure its not manipulated from any implementations.
|
* @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.
|
* Additionally the Subject ensures the data is unique, not updating any Observes unless there is an actual change of the content.
|
||||||
*
|
*
|
||||||
* The ArrayState 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 ArrayState<T> extends DeepState<T[]> {
|
export class UmbArrayState<T> extends UmbDeepState<T[]> {
|
||||||
#getUnique?: (entry: T) => unknown;
|
#getUnique?: (entry: T) => unknown;
|
||||||
#sortMethod?: (a: T, b: T) => number;
|
#sortMethod?: (a: T, b: T) => number;
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ export class ArrayState<T> extends DeepState<T[]> {
|
|||||||
* { key: 1, value: 'foo'},
|
* { key: 1, value: 'foo'},
|
||||||
* { key: 2, value: 'bar'}
|
* { key: 2, value: 'bar'}
|
||||||
* ];
|
* ];
|
||||||
* const myState = new ArrayState(data, (x) => x.key);
|
* const myState = new UmbArrayState(data, (x) => x.key);
|
||||||
* myState.sortBy((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0));
|
* myState.sortBy((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0));
|
||||||
*/
|
*/
|
||||||
sortBy(sortMethod?: (a: T, b: T) => number) {
|
sortBy(sortMethod?: (a: T, b: T) => number) {
|
||||||
@@ -48,14 +48,14 @@ export class ArrayState<T> extends DeepState<T[]> {
|
|||||||
/**
|
/**
|
||||||
* @method remove
|
* @method remove
|
||||||
* @param {unknown[]} uniques - The unique values to remove.
|
* @param {unknown[]} uniques - The unique values to remove.
|
||||||
* @return {ArrayState<T>} Reference to it self.
|
* @return {UmbArrayState<T>} Reference to it self.
|
||||||
* @description - Remove some new data of this Subject.
|
* @description - Remove some new data of this Subject.
|
||||||
* @example <caption>Example remove entry with id '1' and '2'</caption>
|
* @example <caption>Example remove entry with id '1' and '2'</caption>
|
||||||
* const data = [
|
* const data = [
|
||||||
* { id: 1, value: 'foo'},
|
* { id: 1, value: 'foo'},
|
||||||
* { id: 2, value: 'bar'}
|
* { id: 2, value: 'bar'}
|
||||||
* ];
|
* ];
|
||||||
* const myState = new ArrayState(data, (x) => x.id);
|
* const myState = new UmbArrayState(data, (x) => x.id);
|
||||||
* myState.remove([1, 2]);
|
* myState.remove([1, 2]);
|
||||||
*/
|
*/
|
||||||
remove(uniques: unknown[]) {
|
remove(uniques: unknown[]) {
|
||||||
@@ -77,14 +77,14 @@ export class ArrayState<T> extends DeepState<T[]> {
|
|||||||
/**
|
/**
|
||||||
* @method removeOne
|
* @method removeOne
|
||||||
* @param {unknown} unique - The unique value to remove.
|
* @param {unknown} unique - The unique value to remove.
|
||||||
* @return {ArrayState<T>} Reference to it self.
|
* @return {UmbArrayState<T>} Reference to it self.
|
||||||
* @description - Remove some new data of this Subject.
|
* @description - Remove some new data of this Subject.
|
||||||
* @example <caption>Example remove entry with id '1'</caption>
|
* @example <caption>Example remove entry with id '1'</caption>
|
||||||
* const data = [
|
* const data = [
|
||||||
* { id: 1, value: 'foo'},
|
* { id: 1, value: 'foo'},
|
||||||
* { id: 2, value: 'bar'}
|
* { id: 2, value: 'bar'}
|
||||||
* ];
|
* ];
|
||||||
* const myState = new ArrayState(data, (x) => x.id);
|
* const myState = new UmbArrayState(data, (x) => x.id);
|
||||||
* myState.removeOne(1);
|
* myState.removeOne(1);
|
||||||
*/
|
*/
|
||||||
removeOne(unique: unknown) {
|
removeOne(unique: unknown) {
|
||||||
@@ -104,7 +104,7 @@ export class ArrayState<T> extends DeepState<T[]> {
|
|||||||
/**
|
/**
|
||||||
* @method filter
|
* @method filter
|
||||||
* @param {unknown} filterMethod - The unique value to remove.
|
* @param {unknown} filterMethod - The unique value to remove.
|
||||||
* @return {ArrayState<T>} Reference to it self.
|
* @return {UmbArrayState<T>} Reference to it self.
|
||||||
* @description - Remove some new data of this Subject.
|
* @description - Remove some new data of this Subject.
|
||||||
* @example <caption>Example remove entry with key '1'</caption>
|
* @example <caption>Example remove entry with key '1'</caption>
|
||||||
* const data = [
|
* const data = [
|
||||||
@@ -112,7 +112,7 @@ export class ArrayState<T> extends DeepState<T[]> {
|
|||||||
* { key: 2, value: 'bar'},
|
* { key: 2, value: 'bar'},
|
||||||
* { key: 3, value: 'poo'}
|
* { key: 3, value: 'poo'}
|
||||||
* ];
|
* ];
|
||||||
* const myState = new ArrayState(data, (x) => x.key);
|
* const myState = new UmbArrayState(data, (x) => x.key);
|
||||||
* myState.filter((entry) => entry.key !== 1);
|
* myState.filter((entry) => entry.key !== 1);
|
||||||
*
|
*
|
||||||
* Result:
|
* Result:
|
||||||
@@ -130,14 +130,14 @@ export class ArrayState<T> extends DeepState<T[]> {
|
|||||||
/**
|
/**
|
||||||
* @method appendOne
|
* @method appendOne
|
||||||
* @param {T} entry - new data to be added in this Subject.
|
* @param {T} entry - new data to be added in this Subject.
|
||||||
* @return {ArrayState<T>} Reference to it self.
|
* @return {UmbArrayState<T>} Reference to it self.
|
||||||
* @description - Append some new data to this Subject.
|
* @description - Append some new data to this Subject.
|
||||||
* @example <caption>Example append some data.</caption>
|
* @example <caption>Example append some data.</caption>
|
||||||
* const data = [
|
* const data = [
|
||||||
* { key: 1, value: 'foo'},
|
* { key: 1, value: 'foo'},
|
||||||
* { key: 2, value: 'bar'}
|
* { key: 2, value: 'bar'}
|
||||||
* ];
|
* ];
|
||||||
* const myState = new ArrayState(data);
|
* const myState = new UmbArrayState(data);
|
||||||
* myState.append({ key: 1, value: 'replaced-foo'});
|
* myState.append({ key: 1, value: 'replaced-foo'});
|
||||||
*/
|
*/
|
||||||
appendOne(entry: T) {
|
appendOne(entry: T) {
|
||||||
@@ -154,14 +154,14 @@ export class ArrayState<T> extends DeepState<T[]> {
|
|||||||
/**
|
/**
|
||||||
* @method append
|
* @method append
|
||||||
* @param {T[]} entries - A array of new data to be added in this Subject.
|
* @param {T[]} entries - A array of new data to be added in this Subject.
|
||||||
* @return {ArrayState<T>} Reference to it self.
|
* @return {UmbArrayState<T>} Reference to it self.
|
||||||
* @description - Append some new data to this Subject, if it compares to existing data it will replace it.
|
* @description - Append some new data to this Subject, if it compares to existing data it will replace it.
|
||||||
* @example <caption>Example append some data.</caption>
|
* @example <caption>Example append some data.</caption>
|
||||||
* const data = [
|
* const data = [
|
||||||
* { key: 1, value: 'foo'},
|
* { key: 1, value: 'foo'},
|
||||||
* { key: 2, value: 'bar'}
|
* { key: 2, value: 'bar'}
|
||||||
* ];
|
* ];
|
||||||
* const myState = new ArrayState(data);
|
* const myState = new UmbArrayState(data);
|
||||||
* myState.append([
|
* myState.append([
|
||||||
* { key: 1, value: 'replaced-foo'},
|
* { key: 1, value: 'replaced-foo'},
|
||||||
* { key: 3, value: 'another-bla'}
|
* { key: 3, value: 'another-bla'}
|
||||||
@@ -184,14 +184,14 @@ export class ArrayState<T> extends DeepState<T[]> {
|
|||||||
* @method updateOne
|
* @method updateOne
|
||||||
* @param {unknown} unique - Unique value to find entry to update.
|
* @param {unknown} unique - Unique value to find entry to update.
|
||||||
* @param {Partial<T>} entry - new data to be added in this Subject.
|
* @param {Partial<T>} entry - new data to be added in this Subject.
|
||||||
* @return {ArrayState<T>} Reference to it self.
|
* @return {UmbArrayState<T>} Reference to it self.
|
||||||
* @description - Update a item with some new data, requires the ArrayState to be constructed with a getUnique method.
|
* @description - Update a item with some new data, requires the ArrayState to be constructed with a getUnique method.
|
||||||
* @example <caption>Example append some data.</caption>
|
* @example <caption>Example append some data.</caption>
|
||||||
* const data = [
|
* const data = [
|
||||||
* { key: 1, value: 'foo'},
|
* { key: 1, value: 'foo'},
|
||||||
* { key: 2, value: 'bar'}
|
* { key: 2, value: 'bar'}
|
||||||
* ];
|
* ];
|
||||||
* const myState = new ArrayState(data, (x) => x.key);
|
* const myState = new UmbArrayState(data, (x) => x.key);
|
||||||
* myState.updateOne(2, {value: 'updated-bar'});
|
* myState.updateOne(2, {value: 'updated-bar'});
|
||||||
*/
|
*/
|
||||||
updateOne(unique: unknown, entry: Partial<T>) {
|
updateOne(unique: unknown, entry: Partial<T>) {
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ import { BehaviorSubject } from 'rxjs';
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @export
|
* @export
|
||||||
* @class BasicState
|
* @class UmbBasicState
|
||||||
* @extends {BehaviorSubject<T>}
|
* @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.
|
* @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> {
|
export class UmbBasicState<T> extends BehaviorSubject<T> {
|
||||||
constructor(initialData: T) {
|
constructor(initialData: T) {
|
||||||
super(initialData);
|
super(initialData);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { BasicState } from './basic-state';
|
import { UmbBasicState } from './basic-state';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @export
|
* @export
|
||||||
* @class BooleanState
|
* @class UmbBooleanState
|
||||||
* @extends {BehaviorSubject<T>}
|
* @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.
|
* @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 BooleanState<T> extends BasicState<T | boolean> {
|
export class UmbBooleanState<T> extends UmbBasicState<T | boolean> {
|
||||||
constructor(initialData: T | boolean) {
|
constructor(initialData: T | boolean) {
|
||||||
super(initialData);
|
super(initialData);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import { BehaviorSubject } from 'rxjs';
|
import { BehaviorSubject } from 'rxjs';
|
||||||
|
|
||||||
interface ClassStateData {
|
interface UmbClassStateData {
|
||||||
equal(otherClass: ClassStateData): boolean;
|
equal(otherClass: UmbClassStateData): boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @export
|
* @export
|
||||||
* @class ClassState
|
* @class UmbClassState
|
||||||
* @extends {BehaviorSubject<T>}
|
* @extends {BehaviorSubject<T>}
|
||||||
* @description - A RxJS BehaviorSubject which can hold class instance which has a equal method to compare in coming instances for changes.
|
* @description - A RxJS BehaviorSubject which can hold class instance which has a equal method to compare in coming instances for changes.
|
||||||
*/
|
*/
|
||||||
export class ClassState<T extends ClassStateData | undefined | null> extends BehaviorSubject<T> {
|
export class UmbClassState<T extends UmbClassStateData | undefined | null> extends BehaviorSubject<T> {
|
||||||
constructor(initialData: T) {
|
constructor(initialData: T) {
|
||||||
super(initialData);
|
super(initialData);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,27 @@
|
|||||||
import { expect } from '@open-wc/testing';
|
import { expect } from '@open-wc/testing';
|
||||||
import { DeepState } from './deep-state';
|
import { UmbDeepState } from './deep-state';
|
||||||
|
|
||||||
describe('DeepState', () => {
|
describe('UmbDeepState', () => {
|
||||||
|
type ObjectType = { key: string; another: string };
|
||||||
|
|
||||||
type ObjectType = {key: string, another: string};
|
let subject: UmbDeepState<ObjectType>;
|
||||||
|
|
||||||
let subject: DeepState<ObjectType>;
|
|
||||||
let initialData: ObjectType;
|
let initialData: ObjectType;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
initialData = {key: 'some', another: 'myValue'};
|
initialData = { key: 'some', another: 'myValue' };
|
||||||
subject = new DeepState(initialData);
|
subject = new UmbDeepState(initialData);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('getValue gives the initial data', () => {
|
it('getValue gives the initial data', () => {
|
||||||
expect(subject.value.another).to.be.equal(initialData.another);
|
expect(subject.value.another).to.be.equal(initialData.another);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('update via next', () => {
|
it('update via next', () => {
|
||||||
subject.next({key: 'some', another: 'myNewValue'});
|
subject.next({ key: 'some', another: 'myNewValue' });
|
||||||
expect(subject.value.another).to.be.equal('myNewValue');
|
expect(subject.value.another).to.be.equal('myNewValue');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('replays latests, no matter the amount of subscriptions.', (done) => {
|
it('replays latests, no matter the amount of subscriptions.', (done) => {
|
||||||
|
|
||||||
const observer = subject.asObservable();
|
const observer = subject.asObservable();
|
||||||
observer.subscribe((value) => {
|
observer.subscribe((value) => {
|
||||||
expect(value).to.be.equal(initialData);
|
expect(value).to.be.equal(initialData);
|
||||||
@@ -33,28 +30,24 @@ describe('DeepState', () => {
|
|||||||
expect(value).to.be.equal(initialData);
|
expect(value).to.be.equal(initialData);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('use gObservablePart, updates on its specific change.', (done) => {
|
it('use gObservablePart, updates on its specific change.', (done) => {
|
||||||
|
|
||||||
let amountOfCallbacks = 0;
|
let amountOfCallbacks = 0;
|
||||||
|
|
||||||
const subObserver = subject.getObservablePart(data => data.another);
|
const subObserver = subject.getObservablePart((data) => data.another);
|
||||||
subObserver.subscribe((value) => {
|
subObserver.subscribe((value) => {
|
||||||
amountOfCallbacks++;
|
amountOfCallbacks++;
|
||||||
if(amountOfCallbacks === 1) {
|
if (amountOfCallbacks === 1) {
|
||||||
expect(value).to.be.equal('myValue');
|
expect(value).to.be.equal('myValue');
|
||||||
}
|
}
|
||||||
if(amountOfCallbacks === 2) {
|
if (amountOfCallbacks === 2) {
|
||||||
expect(value).to.be.equal('myNewValue');
|
expect(value).to.be.equal('myNewValue');
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
subject.next({key: 'change_this_first_should_not_trigger_update', another: 'myValue'});
|
subject.next({ key: 'change_this_first_should_not_trigger_update', another: 'myValue' });
|
||||||
subject.next({key: 'some', another: 'myNewValue'});
|
subject.next({ key: 'some', another: 'myNewValue' });
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ import { naiveObjectComparison } from './naive-object-comparison';
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @export
|
* @export
|
||||||
* @class DeepState
|
* @class UmbDeepState
|
||||||
* @extends {BehaviorSubject<T>}
|
* @extends {BehaviorSubject<T>}
|
||||||
* @description - A RxJS BehaviorSubject which deepFreezes the data to ensure its not manipulated from any implementations.
|
* @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.
|
* Additionally the Subject ensures the data is unique, not updating any Observes unless there is an actual change of the content.
|
||||||
*/
|
*/
|
||||||
export class DeepState<T> extends BehaviorSubject<T> {
|
export class UmbDeepState<T> extends BehaviorSubject<T> {
|
||||||
constructor(initialData: T) {
|
constructor(initialData: T) {
|
||||||
super(deepFreeze(initialData));
|
super(deepFreeze(initialData));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { BasicState } from './basic-state';
|
import { UmbBasicState } from './basic-state';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @export
|
* @export
|
||||||
* @class NumberState
|
* @class UmbNumberState
|
||||||
* @extends {BehaviorSubject<T>}
|
* @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.
|
* @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> {
|
export class UmbNumberState<T> extends UmbBasicState<T | number> {
|
||||||
constructor(initialData: T | number) {
|
constructor(initialData: T | number) {
|
||||||
super(initialData);
|
super(initialData);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,18 @@
|
|||||||
import { expect } from '@open-wc/testing';
|
import { expect } from '@open-wc/testing';
|
||||||
import { ObjectState } from './object-state';
|
import { UmbObjectState } from './object-state';
|
||||||
|
|
||||||
describe('ObjectState', () => {
|
describe('UmbObjectState', () => {
|
||||||
|
type ObjectType = { key: string; another: string };
|
||||||
|
|
||||||
type ObjectType = {key: string, another: string};
|
let subject: UmbObjectState<ObjectType>;
|
||||||
|
|
||||||
let subject: ObjectState<ObjectType>;
|
|
||||||
let initialData: ObjectType;
|
let initialData: ObjectType;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
initialData = {key: 'some', another: 'myValue'};
|
initialData = { key: 'some', another: 'myValue' };
|
||||||
subject = new ObjectState(initialData);
|
subject = new UmbObjectState(initialData);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('replays latests, no matter the amount of subscriptions.', (done) => {
|
it('replays latests, no matter the amount of subscriptions.', (done) => {
|
||||||
|
|
||||||
const observer = subject.asObservable();
|
const observer = subject.asObservable();
|
||||||
observer.subscribe((value) => {
|
observer.subscribe((value) => {
|
||||||
expect(value).to.be.equal(initialData);
|
expect(value).to.be.equal(initialData);
|
||||||
@@ -24,28 +21,24 @@ describe('ObjectState', () => {
|
|||||||
expect(value).to.be.equal(initialData);
|
expect(value).to.be.equal(initialData);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('use getObservablePart, updates on its specific change.', (done) => {
|
it('use getObservablePart, updates on its specific change.', (done) => {
|
||||||
|
|
||||||
let amountOfCallbacks = 0;
|
let amountOfCallbacks = 0;
|
||||||
|
|
||||||
const subObserver = subject.getObservablePart(data => data.another);
|
const subObserver = subject.getObservablePart((data) => data.another);
|
||||||
subObserver.subscribe((value) => {
|
subObserver.subscribe((value) => {
|
||||||
amountOfCallbacks++;
|
amountOfCallbacks++;
|
||||||
if(amountOfCallbacks === 1) {
|
if (amountOfCallbacks === 1) {
|
||||||
expect(value).to.be.equal('myValue');
|
expect(value).to.be.equal('myValue');
|
||||||
}
|
}
|
||||||
if(amountOfCallbacks === 2) {
|
if (amountOfCallbacks === 2) {
|
||||||
expect(value).to.be.equal('myNewValue');
|
expect(value).to.be.equal('myNewValue');
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
subject.update({key: 'change_this_first_should_not_trigger_update'});
|
subject.update({ key: 'change_this_first_should_not_trigger_update' });
|
||||||
subject.update({another: 'myNewValue'});
|
subject.update({ another: 'myNewValue' });
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
import { DeepState } from './deep-state';
|
import { UmbDeepState } from './deep-state';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @export
|
* @export
|
||||||
* @class ObjectState
|
* @class UmbObjectState
|
||||||
* @extends {DeepState<T>}
|
* @extends {UmbDeepState<T>}
|
||||||
* @description - A RxJS BehaviorSubject which deepFreezes the object-data to ensure its not manipulated from any implementations.
|
* @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.
|
* Additionally the Subject ensures the data is unique, not updating any Observes unless there is an actual change of the content.
|
||||||
*
|
*
|
||||||
* The ObjectState provides methods to append data when the data is an Object.
|
* The UmbObjectState provides methods to append data when the data is an Object.
|
||||||
*/
|
*/
|
||||||
export class ObjectState<T> extends DeepState<T> {
|
export class UmbObjectState<T> extends UmbDeepState<T> {
|
||||||
/**
|
/**
|
||||||
* @method update
|
* @method update
|
||||||
* @param {Partial<T>} partialData - A object containing some of the data to update in this Subject.
|
* @param {Partial<T>} partialData - A object containing some of the data to update in this Subject.
|
||||||
* @description - Append some new data to this Object.
|
* @description - Append some new data to this Object.
|
||||||
* @return {ObjectState<T>} Reference to it self.
|
* @return {UmbObjectState<T>} Reference to it self.
|
||||||
* @example <caption>Example append some data.</caption>
|
* @example <caption>Example append some data.</caption>
|
||||||
* const data = {key: 'myKey', value: 'myInitialValue'};
|
* const data = {key: 'myKey', value: 'myInitialValue'};
|
||||||
* const myState = new ObjectState(data);
|
* const myState = new UmbObjectState(data);
|
||||||
* myState.update({value: 'myNewValue'});
|
* myState.update({value: 'myNewValue'});
|
||||||
*/
|
*/
|
||||||
update(partialData: Partial<T>) {
|
update(partialData: Partial<T>) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* @param {(mappable: T) => R} mappingFunction - Method to return the part for this Observable to return.
|
* @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.
|
* @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.
|
* @description - Creates a RxJS Observable from RxJS Subject.
|
||||||
* @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>
|
* @example <caption>Example append new entry for a ArrayState or a part of UmbDeepState/UmbObjectState it which is an array. Where the key is unique and the item will be updated if matched with existing.</caption>
|
||||||
* const partialEntry = {value: 'myValue'};
|
* const partialEntry = {value: 'myValue'};
|
||||||
* const newDataSet = partialUpdateFrozenArray(mySubject.getValue(), partialEntry, x => x.key === 'myKey');
|
* const newDataSet = partialUpdateFrozenArray(mySubject.getValue(), partialEntry, x => x.key === 'myKey');
|
||||||
* mySubject.next(newDataSet);
|
* mySubject.next(newDataSet);
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { BasicState } from './basic-state';
|
import { UmbBasicState } from './basic-state';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @export
|
* @export
|
||||||
* @class StringState
|
* @class UmbStringState
|
||||||
* @extends {BasicState<T>}
|
* @extends {UmbBasicState<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.
|
* @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> {
|
export class UmbStringState<T> extends UmbBasicState<T | string> {
|
||||||
constructor(initialData: T | string) {
|
constructor(initialData: T | string) {
|
||||||
super(initialData);
|
super(initialData);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
import { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
import { ArrayState, partialUpdateFrozenArray } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbArrayState, partialUpdateFrozenArray } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbStoreBase, UmbTreeStore } from '@umbraco-cms/backoffice/store';
|
import { UmbStoreBase, UmbTreeStore } from '@umbraco-cms/backoffice/store';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -9,7 +9,7 @@ import { UmbStoreBase, UmbTreeStore } from '@umbraco-cms/backoffice/store';
|
|||||||
* @description - General Tree Data Store
|
* @description - General Tree Data Store
|
||||||
*/
|
*/
|
||||||
export class UmbEntityTreeStore extends UmbStoreBase implements UmbTreeStore<EntityTreeItemResponseModel> {
|
export class UmbEntityTreeStore extends UmbStoreBase implements UmbTreeStore<EntityTreeItemResponseModel> {
|
||||||
#data = new ArrayState<EntityTreeItemResponseModel>([], (x) => x.id);
|
#data = new UmbArrayState<EntityTreeItemResponseModel>([], (x) => x.id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends items to the store
|
* Appends items to the store
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { FileSystemTreeItemPresentationModel } from '@umbraco-cms/backoffice/backend-api';
|
import { FileSystemTreeItemPresentationModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
import { ArrayState, partialUpdateFrozenArray } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbArrayState, partialUpdateFrozenArray } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbStoreBase, UmbTreeStore } from '@umbraco-cms/backoffice/store';
|
import { UmbStoreBase, UmbTreeStore } from '@umbraco-cms/backoffice/store';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -9,7 +9,7 @@ import { UmbStoreBase, UmbTreeStore } from '@umbraco-cms/backoffice/store';
|
|||||||
* @description - General Tree Data Store
|
* @description - General Tree Data Store
|
||||||
*/
|
*/
|
||||||
export class UmbFileSystemTreeStore extends UmbStoreBase implements UmbTreeStore<FileSystemTreeItemPresentationModel> {
|
export class UmbFileSystemTreeStore extends UmbStoreBase implements UmbTreeStore<FileSystemTreeItemPresentationModel> {
|
||||||
#data = new ArrayState<FileSystemTreeItemPresentationModel>([], (x) => x.path);
|
#data = new UmbArrayState<FileSystemTreeItemPresentationModel>([], (x) => x.path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends items to the store
|
* Appends items to the store
|
||||||
|
|||||||
1812
src/Umbraco.Web.UI.Client/package-lock.json
generated
1812
src/Umbraco.Web.UI.Client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -61,8 +61,8 @@
|
|||||||
"npm": ">=9.5 < 10"
|
"npm": ">=9.5 < 10"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@umbraco-ui/uui": "^1.2.0-rc.2",
|
"@umbraco-ui/uui": "^1.2.0-rc.3",
|
||||||
"@umbraco-ui/uui-css": "^1.2.0-rc.2",
|
"@umbraco-ui/uui-css": "^1.2.0-rc.3",
|
||||||
"element-internals-polyfill": "^1.1.19",
|
"element-internals-polyfill": "^1.1.19",
|
||||||
"lit": "^2.7.0",
|
"lit": "^2.7.0",
|
||||||
"lodash-es": "4.17.21",
|
"lodash-es": "4.17.21",
|
||||||
|
|||||||
@@ -46,26 +46,23 @@ export class UmbAppElement extends UmbLitElement {
|
|||||||
{
|
{
|
||||||
path: 'upgrade',
|
path: 'upgrade',
|
||||||
component: () => import('./upgrader/upgrader.element'),
|
component: () => import('./upgrader/upgrader.element'),
|
||||||
guards: [this._isAuthorizedGuard('/upgrade')],
|
guards: [this.#isAuthorizedGuard('/upgrade')],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '**',
|
path: '**',
|
||||||
component: () => import('./backoffice/backoffice.element'),
|
component: () => import('./backoffice/backoffice.element'),
|
||||||
guards: [this._isAuthorizedGuard()],
|
guards: [this.#isAuthorizedGuard()],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
private _umbIconRegistry = new UmbIconStore();
|
#umbIconRegistry = new UmbIconStore();
|
||||||
|
#uuiIconRegistry = new UUIIconRegistryEssential();
|
||||||
private _iconRegistry = new UUIIconRegistryEssential();
|
#runtimeLevel = RuntimeLevelModel.UNKNOWN;
|
||||||
private _runtimeLevel = RuntimeLevelModel.UNKNOWN;
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
this.#umbIconRegistry.attach(this);
|
||||||
this._umbIconRegistry.attach(this);
|
this.#uuiIconRegistry.attach(this);
|
||||||
|
|
||||||
this._setup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
@@ -78,8 +75,7 @@ export class UmbAppElement extends UmbLitElement {
|
|||||||
OpenAPI.WITH_CREDENTIALS = true;
|
OpenAPI.WITH_CREDENTIALS = true;
|
||||||
|
|
||||||
this.provideContext('UMBRACOBASE', OpenAPI.BASE);
|
this.provideContext('UMBRACOBASE', OpenAPI.BASE);
|
||||||
|
this.#setInitStatus();
|
||||||
this._setInitStatus();
|
|
||||||
|
|
||||||
// Listen for the debug event from the <umb-debug> component
|
// Listen for the debug event from the <umb-debug> component
|
||||||
this.addEventListener(umbDebugContextEventType, (event: any) => {
|
this.addEventListener(umbDebugContextEventType, (event: any) => {
|
||||||
@@ -104,19 +100,14 @@ export class UmbAppElement extends UmbLitElement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _setup() {
|
async #setInitStatus() {
|
||||||
await this._setInitStatus();
|
|
||||||
this._iconRegistry.attach(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _setInitStatus() {
|
|
||||||
const { data } = await tryExecuteAndNotify(this, ServerResource.getServerStatus());
|
const { data } = await tryExecuteAndNotify(this, ServerResource.getServerStatus());
|
||||||
this._runtimeLevel = data?.serverStatus ?? RuntimeLevelModel.UNKNOWN;
|
this.#runtimeLevel = data?.serverStatus ?? RuntimeLevelModel.UNKNOWN;
|
||||||
this._redirect();
|
this.#redirect();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _redirect() {
|
#redirect() {
|
||||||
switch (this._runtimeLevel) {
|
switch (this.#runtimeLevel) {
|
||||||
case RuntimeLevelModel.INSTALL:
|
case RuntimeLevelModel.INSTALL:
|
||||||
history.replaceState(null, '', 'install');
|
history.replaceState(null, '', 'install');
|
||||||
break;
|
break;
|
||||||
@@ -137,18 +128,18 @@ export class UmbAppElement extends UmbLitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unsupported runtime level: ${this._runtimeLevel}`);
|
throw new Error(`Unsupported runtime level: ${this.#runtimeLevel}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _isAuthorized(): boolean {
|
#isAuthorized(): boolean {
|
||||||
return true; // TODO: Return true for now, until new login page is up and running
|
return true; // TODO: Return true for now, until new login page is up and running
|
||||||
//return sessionStorage.getItem('is-authenticated') === 'true';
|
//return sessionStorage.getItem('is-authenticated') === 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
private _isAuthorizedGuard(redirectTo?: string): Guard {
|
#isAuthorizedGuard(redirectTo?: string): Guard {
|
||||||
return () => {
|
return () => {
|
||||||
if (this._isAuthorized()) {
|
if (this.#isAuthorized()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { DocumentBlueprintDetails } from '@umbraco-cms/backoffice/models';
|
import type { DocumentBlueprintDetails } from '@umbraco-cms/backoffice/models';
|
||||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||||
import { ArrayState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
|||||||
*/
|
*/
|
||||||
export class UmbDocumentBlueprintStore extends UmbStoreBase {
|
export class UmbDocumentBlueprintStore extends UmbStoreBase {
|
||||||
// TODO: use the right type:
|
// TODO: use the right type:
|
||||||
#data = new ArrayState<DocumentBlueprintDetails>([], (x) => x.id);
|
#data = new UmbArrayState<DocumentBlueprintDetails>([], (x) => x.id);
|
||||||
|
|
||||||
constructor(host: UmbControllerHostElement) {
|
constructor(host: UmbControllerHostElement) {
|
||||||
super(host, UMB_DOCUMENT_BLUEPRINT_STORE_CONTEXT_TOKEN.toString());
|
super(host, UMB_DOCUMENT_BLUEPRINT_STORE_CONTEXT_TOKEN.toString());
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { DocumentTypeTreeServerDataSource } from './sources/document-type.tree.server.data';
|
import { UmbDocumentTypeTreeServerDataSource } from './sources/document-type.tree.server.data';
|
||||||
import { UmbDocumentTypeServerDataSource } from './sources/document-type.server.data';
|
import { UmbDocumentTypeServerDataSource } from './sources/document-type.server.data';
|
||||||
import { UmbDocumentTypeTreeStore, UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT_TOKEN } from './document-type.tree.store';
|
import { UmbDocumentTypeTreeStore, UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT_TOKEN } from './document-type.tree.store';
|
||||||
import { UmbDocumentTypeStore, UMB_DOCUMENT_TYPE_STORE_CONTEXT_TOKEN } from './document-type.store';
|
import { UmbDocumentTypeStore, UMB_DOCUMENT_TYPE_STORE_CONTEXT_TOKEN } from './document-type.store';
|
||||||
@@ -27,7 +27,7 @@ export class UmbDocumentTypeRepository implements UmbTreeRepository<ItemType>, U
|
|||||||
this.#host = host;
|
this.#host = host;
|
||||||
|
|
||||||
// TODO: figure out how spin up get the correct data source
|
// TODO: figure out how spin up get the correct data source
|
||||||
this.#treeSource = new DocumentTypeTreeServerDataSource(this.#host);
|
this.#treeSource = new UmbDocumentTypeTreeServerDataSource(this.#host);
|
||||||
this.#detailDataSource = new UmbDocumentTypeServerDataSource(this.#host);
|
this.#detailDataSource = new UmbDocumentTypeServerDataSource(this.#host);
|
||||||
|
|
||||||
this.#init = Promise.all([
|
this.#init = Promise.all([
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { DocumentTypeResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
import { DocumentTypeResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||||
import { ArrayState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
|||||||
* @description - Data Store for Document Types
|
* @description - Data Store for Document Types
|
||||||
*/
|
*/
|
||||||
export class UmbDocumentTypeStore extends UmbStoreBase {
|
export class UmbDocumentTypeStore extends UmbStoreBase {
|
||||||
#data = new ArrayState<DocumentTypeResponseModel>([], (x) => x.id);
|
#data = new UmbArrayState<DocumentTypeResponseModel>([], (x) => x.id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance of UmbDocumentTypeStore.
|
* Creates an instance of UmbDocumentTypeStore.
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
|
|||||||
/**
|
/**
|
||||||
* A data source for the Document tree that fetches data from the server
|
* A data source for the Document tree that fetches data from the server
|
||||||
* @export
|
* @export
|
||||||
* @class DocumentTreeServerDataSource
|
* @class UmbDocumentTypeTreeServerDataSource
|
||||||
* @implements {DocumentTreeDataSource}
|
* @implements {UmbTreeDataSource}
|
||||||
*/
|
*/
|
||||||
export class DocumentTypeTreeServerDataSource implements UmbTreeDataSource {
|
export class UmbDocumentTypeTreeServerDataSource implements UmbTreeDataSource {
|
||||||
#host: UmbControllerHostElement;
|
#host: UmbControllerHostElement;
|
||||||
|
|
||||||
// TODO: how do we handle trashed items?
|
// TODO: how do we handle trashed items?
|
||||||
@@ -42,9 +42,9 @@ export class DocumentTypeTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance of DocumentTreeServerDataSource.
|
* Creates an instance of UmbDocumentTypeTreeServerDataSource.
|
||||||
* @param {UmbControllerHostElement} host
|
* @param {UmbControllerHostElement} host
|
||||||
* @memberof DocumentTreeServerDataSource
|
* @memberof UmbDocumentTypeTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
constructor(host: UmbControllerHostElement) {
|
constructor(host: UmbControllerHostElement) {
|
||||||
this.#host = host;
|
this.#host = host;
|
||||||
@@ -53,7 +53,7 @@ export class DocumentTypeTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
/**
|
/**
|
||||||
* Fetches the root items for the tree from the server
|
* Fetches the root items for the tree from the server
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof DocumentTreeServerDataSource
|
* @memberof UmbDocumentTypeTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getRootItems() {
|
async getRootItems() {
|
||||||
return tryExecuteAndNotify(this.#host, DocumentTypeResource.getTreeDocumentTypeRoot({}));
|
return tryExecuteAndNotify(this.#host, DocumentTypeResource.getTreeDocumentTypeRoot({}));
|
||||||
@@ -63,7 +63,7 @@ export class DocumentTypeTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
* Fetches the children of a given parent id from the server
|
* Fetches the children of a given parent id from the server
|
||||||
* @param {(string | null)} parentId
|
* @param {(string | null)} parentId
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof DocumentTreeServerDataSource
|
* @memberof UmbDocumentTypeTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getChildrenOf(parentId: string | null) {
|
async getChildrenOf(parentId: string | null) {
|
||||||
if (!parentId) {
|
if (!parentId) {
|
||||||
@@ -83,7 +83,7 @@ export class DocumentTypeTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
* Fetches the items for the given ids from the server
|
* Fetches the items for the given ids from the server
|
||||||
* @param {Array<string>} ids
|
* @param {Array<string>} ids
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof DocumentTreeServerDataSource
|
* @memberof UmbDocumentTypeTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getItems(ids: Array<string>) {
|
async getItems(ids: Array<string>) {
|
||||||
if (ids) {
|
if (ids) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { UmbDocumentServerDataSource } from './sources/document.server.data';
|
import { UmbDocumentServerDataSource } from './sources/document.server.data';
|
||||||
import { UmbDocumentStore, UMB_DOCUMENT_STORE_CONTEXT_TOKEN } from './document.store';
|
import { UmbDocumentStore, UMB_DOCUMENT_STORE_CONTEXT_TOKEN } from './document.store';
|
||||||
import { UmbDocumentTreeStore, UMB_DOCUMENT_TREE_STORE_CONTEXT_TOKEN } from './document.tree.store';
|
import { UmbDocumentTreeStore, UMB_DOCUMENT_TREE_STORE_CONTEXT_TOKEN } from './document.tree.store';
|
||||||
import { DocumentTreeServerDataSource } from './sources/document.tree.server.data';
|
import { UmbDocumentTreeServerDataSource } from './sources/document.tree.server.data';
|
||||||
import type { UmbTreeDataSource, UmbTreeRepository, UmbDetailRepository } from '@umbraco-cms/backoffice/repository';
|
import type { UmbTreeDataSource, UmbTreeRepository, UmbDetailRepository } from '@umbraco-cms/backoffice/repository';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
|
||||||
@@ -32,7 +32,7 @@ export class UmbDocumentRepository implements UmbTreeRepository<ItemType>, UmbDe
|
|||||||
this.#host = host;
|
this.#host = host;
|
||||||
|
|
||||||
// TODO: figure out how spin up get the correct data source
|
// TODO: figure out how spin up get the correct data source
|
||||||
this.#treeSource = new DocumentTreeServerDataSource(this.#host);
|
this.#treeSource = new UmbDocumentTreeServerDataSource(this.#host);
|
||||||
this.#detailDataSource = new UmbDocumentServerDataSource(this.#host);
|
this.#detailDataSource = new UmbDocumentServerDataSource(this.#host);
|
||||||
|
|
||||||
this.#init = Promise.all([
|
this.#init = Promise.all([
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { DocumentResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
import { DocumentResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||||
import { ArrayState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
|||||||
* @description - Data Store for Template Details
|
* @description - Data Store for Template Details
|
||||||
*/
|
*/
|
||||||
export class UmbDocumentStore extends UmbStoreBase {
|
export class UmbDocumentStore extends UmbStoreBase {
|
||||||
#data = new ArrayState<DocumentResponseModel>([], (x) => x.id);
|
#data = new UmbArrayState<DocumentResponseModel>([], (x) => x.id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance of UmbDocumentDetailStore.
|
* Creates an instance of UmbDocumentDetailStore.
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
|
|||||||
/**
|
/**
|
||||||
* A data source for the Document tree that fetches data from the server
|
* A data source for the Document tree that fetches data from the server
|
||||||
* @export
|
* @export
|
||||||
* @class DocumentTreeServerDataSource
|
* @class UmbDocumentTreeServerDataSource
|
||||||
* @implements {DocumentTreeDataSource}
|
* @implements {UmbTreeDataSource}
|
||||||
*/
|
*/
|
||||||
export class DocumentTreeServerDataSource implements UmbTreeDataSource {
|
export class UmbDocumentTreeServerDataSource implements UmbTreeDataSource {
|
||||||
#host: UmbControllerHostElement;
|
#host: UmbControllerHostElement;
|
||||||
|
|
||||||
// TODO: how do we handle trashed items?
|
// TODO: how do we handle trashed items?
|
||||||
@@ -42,9 +42,9 @@ export class DocumentTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance of DocumentTreeServerDataSource.
|
* Creates an instance of UmbDocumentTreeServerDataSource.
|
||||||
* @param {UmbControllerHostElement} host
|
* @param {UmbControllerHostElement} host
|
||||||
* @memberof DocumentTreeServerDataSource
|
* @memberof UmbDocumentTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
constructor(host: UmbControllerHostElement) {
|
constructor(host: UmbControllerHostElement) {
|
||||||
this.#host = host;
|
this.#host = host;
|
||||||
@@ -53,7 +53,7 @@ export class DocumentTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
/**
|
/**
|
||||||
* Fetches the root items for the tree from the server
|
* Fetches the root items for the tree from the server
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof DocumentTreeServerDataSource
|
* @memberof UmbDocumentTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getRootItems() {
|
async getRootItems() {
|
||||||
return tryExecuteAndNotify(this.#host, DocumentResource.getTreeDocumentRoot({}));
|
return tryExecuteAndNotify(this.#host, DocumentResource.getTreeDocumentRoot({}));
|
||||||
@@ -63,7 +63,7 @@ export class DocumentTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
* Fetches the children of a given parent id from the server
|
* Fetches the children of a given parent id from the server
|
||||||
* @param {(string | null)} parentId
|
* @param {(string | null)} parentId
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof DocumentTreeServerDataSource
|
* @memberof UmbDocumentTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getChildrenOf(parentId: string | null) {
|
async getChildrenOf(parentId: string | null) {
|
||||||
if (!parentId) {
|
if (!parentId) {
|
||||||
@@ -83,7 +83,7 @@ export class DocumentTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
* Fetches the items for the given ids from the server
|
* Fetches the items for the given ids from the server
|
||||||
* @param {Array<string>} ids
|
* @param {Array<string>} ids
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof DocumentTreeServerDataSource
|
* @memberof UmbDocumentTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getItems(ids: Array<string>) {
|
async getItems(ids: Array<string>) {
|
||||||
if (!ids) {
|
if (!ids) {
|
||||||
|
|||||||
@@ -6,7 +6,11 @@ import { UmbVariantId } from '../../../shared/variants/variant-id.class';
|
|||||||
import { UmbWorkspacePropertyStructureManager } from '../../../shared/components/workspace/workspace-context/workspace-structure-manager.class';
|
import { UmbWorkspacePropertyStructureManager } from '../../../shared/components/workspace/workspace-context/workspace-structure-manager.class';
|
||||||
import { UmbWorkspaceSplitViewManager } from '../../../shared/components/workspace/workspace-context/workspace-split-view-manager.class';
|
import { UmbWorkspaceSplitViewManager } from '../../../shared/components/workspace/workspace-context/workspace-split-view-manager.class';
|
||||||
import type { CreateDocumentRequestModel, DocumentResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
import type { CreateDocumentRequestModel, DocumentResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
import { partialUpdateFrozenArray, ObjectState, UmbObserverController } from '@umbraco-cms/backoffice/observable-api';
|
import {
|
||||||
|
partialUpdateFrozenArray,
|
||||||
|
UmbObjectState,
|
||||||
|
UmbObserverController,
|
||||||
|
} from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
|
|
||||||
// TODO: should this context be called DocumentDraft instead of workspace? or should the draft be part of this?
|
// TODO: should this context be called DocumentDraft instead of workspace? or should the draft be part of this?
|
||||||
@@ -22,12 +26,12 @@ export class UmbDocumentWorkspaceContext
|
|||||||
* For now lets not share this publicly as it can become confusing.
|
* For now lets not share this publicly as it can become confusing.
|
||||||
* TODO: Use this to compare, for variants with changes.
|
* TODO: Use this to compare, for variants with changes.
|
||||||
*/
|
*/
|
||||||
#document = new ObjectState<EntityType | undefined>(undefined);
|
#document = new UmbObjectState<EntityType | undefined>(undefined);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The document is the current state/draft version of the document.
|
* The document is the current state/draft version of the document.
|
||||||
*/
|
*/
|
||||||
#draft = new ObjectState<EntityType | undefined>(undefined);
|
#draft = new UmbObjectState<EntityType | undefined>(undefined);
|
||||||
readonly unique = this.#draft.getObservablePart((data) => data?.id);
|
readonly unique = this.#draft.getObservablePart((data) => data?.id);
|
||||||
readonly documentTypeKey = this.#draft.getObservablePart((data) => data?.contentTypeId);
|
readonly documentTypeKey = this.#draft.getObservablePart((data) => data?.contentTypeId);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||||
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
import { ArrayState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import type { MediaTypeDetails } from '@umbraco-cms/backoffice/models';
|
import type { MediaTypeDetails } from '@umbraco-cms/backoffice/models';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -11,7 +11,7 @@ import type { MediaTypeDetails } from '@umbraco-cms/backoffice/models';
|
|||||||
* @description - Details Data Store for Media Types
|
* @description - Details Data Store for Media Types
|
||||||
*/
|
*/
|
||||||
export class UmbMediaTypeStore extends UmbStoreBase {
|
export class UmbMediaTypeStore extends UmbStoreBase {
|
||||||
#data = new ArrayState<MediaTypeDetails>([], (x) => x.id);
|
#data = new UmbArrayState<MediaTypeDetails>([], (x) => x.id);
|
||||||
|
|
||||||
constructor(host: UmbControllerHostElement) {
|
constructor(host: UmbControllerHostElement) {
|
||||||
super(host, UMB_MEDIA_TYPE_STORE_CONTEXT_TOKEN.toString());
|
super(host, UMB_MEDIA_TYPE_STORE_CONTEXT_TOKEN.toString());
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { UmbMediaTypeTreeStore, UMB_MEDIA_TYPE_TREE_STORE_CONTEXT_TOKEN } from './media-type.tree.store';
|
import { UmbMediaTypeTreeStore, UMB_MEDIA_TYPE_TREE_STORE_CONTEXT_TOKEN } from './media-type.tree.store';
|
||||||
import { UmbMediaTypeDetailServerDataSource } from './sources/media-type.detail.server.data';
|
import { UmbMediaTypeDetailServerDataSource } from './sources/media-type.detail.server.data';
|
||||||
import { UmbMediaTypeStore, UMB_MEDIA_TYPE_STORE_CONTEXT_TOKEN } from './media-type.detail.store';
|
import { UmbMediaTypeStore, UMB_MEDIA_TYPE_STORE_CONTEXT_TOKEN } from './media-type.detail.store';
|
||||||
import { MediaTypeTreeServerDataSource } from './sources/media-type.tree.server.data';
|
import { UmbMediaTypeTreeServerDataSource } from './sources/media-type.tree.server.data';
|
||||||
import { ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api';
|
import { ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
@@ -26,7 +26,7 @@ export class UmbMediaTypeRepository implements UmbTreeRepository {
|
|||||||
this.#host = host;
|
this.#host = host;
|
||||||
|
|
||||||
// TODO: figure out how spin up get the correct data source
|
// TODO: figure out how spin up get the correct data source
|
||||||
this.#treeSource = new MediaTypeTreeServerDataSource(this.#host);
|
this.#treeSource = new UmbMediaTypeTreeServerDataSource(this.#host);
|
||||||
this.#detailSource = new UmbMediaTypeDetailServerDataSource(this.#host);
|
this.#detailSource = new UmbMediaTypeDetailServerDataSource(this.#host);
|
||||||
|
|
||||||
this.#init = Promise.all([
|
this.#init = Promise.all([
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
|
|||||||
/**
|
/**
|
||||||
* A data source for the MediaType tree that fetches data from the server
|
* A data source for the MediaType tree that fetches data from the server
|
||||||
* @export
|
* @export
|
||||||
* @class MediaTypeTreeServerDataSource
|
* @class UmbMediaTypeTreeServerDataSource
|
||||||
* @implements {MediaTypeTreeDataSource}
|
* @implements {UmbTreeDataSource}
|
||||||
*/
|
*/
|
||||||
export class MediaTypeTreeServerDataSource implements UmbTreeDataSource {
|
export class UmbMediaTypeTreeServerDataSource implements UmbTreeDataSource {
|
||||||
#host: UmbControllerHostElement;
|
#host: UmbControllerHostElement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,7 +24,7 @@ export class MediaTypeTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
/**
|
/**
|
||||||
* Fetches the root items for the tree from the server
|
* Fetches the root items for the tree from the server
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof MediaTypeTreeServerDataSource
|
* @memberof UmbMediaTypeTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getRootItems() {
|
async getRootItems() {
|
||||||
return tryExecuteAndNotify(this.#host, MediaTypeResource.getTreeMediaTypeRoot({}));
|
return tryExecuteAndNotify(this.#host, MediaTypeResource.getTreeMediaTypeRoot({}));
|
||||||
@@ -34,7 +34,7 @@ export class MediaTypeTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
* Fetches the children of a given parent id from the server
|
* Fetches the children of a given parent id from the server
|
||||||
* @param {(string | null)} parentId
|
* @param {(string | null)} parentId
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof MediaTypeTreeServerDataSource
|
* @memberof UmbMediaTypeTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getChildrenOf(parentId: string | null) {
|
async getChildrenOf(parentId: string | null) {
|
||||||
if (!parentId) {
|
if (!parentId) {
|
||||||
@@ -54,7 +54,7 @@ export class MediaTypeTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
* Fetches the items for the given ids from the server
|
* Fetches the items for the given ids from the server
|
||||||
* @param {Array<string>} ids
|
* @param {Array<string>} ids
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof MediaTypeTreeServerDataSource
|
* @memberof UmbMediaTypeTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getItems(ids: Array<string>) {
|
async getItems(ids: Array<string>) {
|
||||||
if (!ids || ids.length === 0) {
|
if (!ids || ids.length === 0) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { UmbWorkspaceContext } from '../../../shared/components/workspace/worksp
|
|||||||
import { UmbMediaTypeRepository } from '../repository/media-type.repository';
|
import { UmbMediaTypeRepository } from '../repository/media-type.repository';
|
||||||
import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace';
|
import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
import { ObjectState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import type { MediaTypeDetails } from '@umbraco-cms/backoffice/models';
|
import type { MediaTypeDetails } from '@umbraco-cms/backoffice/models';
|
||||||
|
|
||||||
type EntityType = MediaTypeDetails;
|
type EntityType = MediaTypeDetails;
|
||||||
@@ -10,7 +10,7 @@ export class UmbWorkspaceMediaTypeContext
|
|||||||
extends UmbWorkspaceContext<UmbMediaTypeRepository, EntityType>
|
extends UmbWorkspaceContext<UmbMediaTypeRepository, EntityType>
|
||||||
implements UmbEntityWorkspaceContextInterface<EntityType | undefined>
|
implements UmbEntityWorkspaceContextInterface<EntityType | undefined>
|
||||||
{
|
{
|
||||||
#data = new ObjectState<MediaTypeDetails | undefined>(undefined);
|
#data = new UmbObjectState<MediaTypeDetails | undefined>(undefined);
|
||||||
data = this.#data.asObservable();
|
data = this.#data.asObservable();
|
||||||
name = this.#data.getObservablePart((data) => data?.name);
|
name = this.#data.getObservablePart((data) => data?.name);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { MediaDetails } from '../';
|
import type { MediaDetails } from '../';
|
||||||
import { MediaTreeServerDataSource } from './sources/media.tree.server.data';
|
import { UmbMediaTreeServerDataSource } from './sources/media.tree.server.data';
|
||||||
import { UmbMediaTreeStore, UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN } from './media.tree.store';
|
import { UmbMediaTreeStore, UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN } from './media.tree.store';
|
||||||
import { UmbMediaStore, UMB_MEDIA_STORE_CONTEXT_TOKEN } from './media.store';
|
import { UmbMediaStore, UMB_MEDIA_STORE_CONTEXT_TOKEN } from './media.store';
|
||||||
import { UmbMediaDetailServerDataSource } from './sources/media.detail.server.data';
|
import { UmbMediaDetailServerDataSource } from './sources/media.detail.server.data';
|
||||||
@@ -36,7 +36,7 @@ export class UmbMediaRepository
|
|||||||
this.#host = host;
|
this.#host = host;
|
||||||
|
|
||||||
// TODO: figure out how spin up get the correct data source
|
// TODO: figure out how spin up get the correct data source
|
||||||
this.#treeSource = new MediaTreeServerDataSource(this.#host);
|
this.#treeSource = new UmbMediaTreeServerDataSource(this.#host);
|
||||||
this.#detailDataSource = new UmbMediaDetailServerDataSource(this.#host);
|
this.#detailDataSource = new UmbMediaDetailServerDataSource(this.#host);
|
||||||
|
|
||||||
new UmbContextConsumerController(this.#host, UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN, (instance) => {
|
new UmbContextConsumerController(this.#host, UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN, (instance) => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { MediaDetails } from '../';
|
import type { MediaDetails } from '../';
|
||||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||||
import { ArrayState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
|||||||
* @description - Data Store for Template Details
|
* @description - Data Store for Template Details
|
||||||
*/
|
*/
|
||||||
export class UmbMediaStore extends UmbStoreBase {
|
export class UmbMediaStore extends UmbStoreBase {
|
||||||
#data = new ArrayState<MediaDetails>([], (x) => x.id);
|
#data = new UmbArrayState<MediaDetails>([], (x) => x.id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance of UmbMediaStore.
|
* Creates an instance of UmbMediaStore.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
import { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||||
import { ArrayState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store';
|
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ export const UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbMediaTr
|
|||||||
* @description - Tree Data Store for Media
|
* @description - Tree Data Store for Media
|
||||||
*/
|
*/
|
||||||
export class UmbMediaTreeStore extends UmbEntityTreeStore {
|
export class UmbMediaTreeStore extends UmbEntityTreeStore {
|
||||||
#data = new ArrayState<EntityTreeItemResponseModel>([], (x) => x.id);
|
#data = new UmbArrayState<EntityTreeItemResponseModel>([], (x) => x.id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance of UmbMediaTreeStore.
|
* Creates an instance of UmbMediaTreeStore.
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
|
|||||||
/**
|
/**
|
||||||
* A data source for the Media tree that fetches data from the server
|
* A data source for the Media tree that fetches data from the server
|
||||||
* @export
|
* @export
|
||||||
* @class MediaTreeServerDataSource
|
* @class UmbMediaTreeServerDataSource
|
||||||
* @implements {MediaTreeDataSource}
|
* @implements {UmbTreeDataSource}
|
||||||
*/
|
*/
|
||||||
export class MediaTreeServerDataSource implements UmbTreeDataSource {
|
export class UmbMediaTreeServerDataSource implements UmbTreeDataSource {
|
||||||
#host: UmbControllerHostElement;
|
#host: UmbControllerHostElement;
|
||||||
|
|
||||||
// TODO: how do we handle trashed items?
|
// TODO: how do we handle trashed items?
|
||||||
@@ -42,9 +42,9 @@ export class MediaTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance of MediaTreeServerDataSource.
|
* Creates an instance of UmbMediaTreeServerDataSource.
|
||||||
* @param {UmbControllerHostElement} host
|
* @param {UmbControllerHostElement} host
|
||||||
* @memberof MediaTreeServerDataSource
|
* @memberof UmbMediaTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
constructor(host: UmbControllerHostElement) {
|
constructor(host: UmbControllerHostElement) {
|
||||||
this.#host = host;
|
this.#host = host;
|
||||||
@@ -53,7 +53,7 @@ export class MediaTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
/**
|
/**
|
||||||
* Fetches the root items for the tree from the server
|
* Fetches the root items for the tree from the server
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof MediaTreeServerDataSource
|
* @memberof UmbMediaTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getRootItems() {
|
async getRootItems() {
|
||||||
return tryExecuteAndNotify(this.#host, MediaResource.getTreeMediaRoot({}));
|
return tryExecuteAndNotify(this.#host, MediaResource.getTreeMediaRoot({}));
|
||||||
@@ -63,7 +63,7 @@ export class MediaTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
* Fetches the children of a given parent id from the server
|
* Fetches the children of a given parent id from the server
|
||||||
* @param {(string | null)} parentId
|
* @param {(string | null)} parentId
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof MediaTreeServerDataSource
|
* @memberof UmbMediaTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getChildrenOf(parentId: string | null) {
|
async getChildrenOf(parentId: string | null) {
|
||||||
if (!parentId) {
|
if (!parentId) {
|
||||||
@@ -83,7 +83,7 @@ export class MediaTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
* Fetches the items for the given ids from the server
|
* Fetches the items for the given ids from the server
|
||||||
* @param {Array<string>} ids
|
* @param {Array<string>} ids
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof MediaTreeServerDataSource
|
* @memberof UmbMediaTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getItems(ids: Array<string>) {
|
async getItems(ids: Array<string>) {
|
||||||
if (!ids) {
|
if (!ids) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { UmbWorkspaceContext } from '../../../shared/components/workspace/worksp
|
|||||||
import { UmbMediaRepository } from '../repository/media.repository';
|
import { UmbMediaRepository } from '../repository/media.repository';
|
||||||
import type { MediaDetails } from '../';
|
import type { MediaDetails } from '../';
|
||||||
import type { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace';
|
import type { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace';
|
||||||
import { appendToFrozenArray, ObjectState } from '@umbraco-cms/backoffice/observable-api';
|
import { appendToFrozenArray, UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
|
|
||||||
type EntityType = MediaDetails;
|
type EntityType = MediaDetails;
|
||||||
@@ -10,7 +10,7 @@ export class UmbMediaWorkspaceContext
|
|||||||
extends UmbWorkspaceContext<UmbMediaRepository, EntityType>
|
extends UmbWorkspaceContext<UmbMediaRepository, EntityType>
|
||||||
implements UmbEntityWorkspaceContextInterface<EntityType | undefined>
|
implements UmbEntityWorkspaceContextInterface<EntityType | undefined>
|
||||||
{
|
{
|
||||||
#data = new ObjectState<EntityType | undefined>(undefined);
|
#data = new UmbObjectState<EntityType | undefined>(undefined);
|
||||||
data = this.#data.asObservable();
|
data = this.#data.asObservable();
|
||||||
name = this.#data.getObservablePart((data) => data?.name);
|
name = this.#data.getObservablePart((data) => data?.name);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { UmbMemberGroupTreeStore, UMB_MEMBER_GROUP_TREE_STORE_CONTEXT_TOKEN } from './member-group.tree.store';
|
import { UmbMemberGroupTreeStore, UMB_MEMBER_GROUP_TREE_STORE_CONTEXT_TOKEN } from './member-group.tree.store';
|
||||||
import { UmbMemberGroupDetailServerDataSource } from './sources/member-group.detail.server.data';
|
import { UmbMemberGroupDetailServerDataSource } from './sources/member-group.detail.server.data';
|
||||||
import { UmbMemberGroupStore, UMB_MEMBER_GROUP_STORE_CONTEXT_TOKEN } from './member-group.store';
|
import { UmbMemberGroupStore, UMB_MEMBER_GROUP_STORE_CONTEXT_TOKEN } from './member-group.store';
|
||||||
import { MemberGroupTreeServerDataSource } from './sources/member-group.tree.server.data';
|
import { UmbMemberGroupTreeServerDataSource } from './sources/member-group.tree.server.data';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification';
|
import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification';
|
||||||
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
|
||||||
@@ -26,7 +26,7 @@ export class UmbMemberGroupRepository implements UmbTreeRepository, UmbDetailRep
|
|||||||
constructor(host: UmbControllerHostElement) {
|
constructor(host: UmbControllerHostElement) {
|
||||||
this.#host = host;
|
this.#host = host;
|
||||||
// TODO: figure out how spin up get the correct data source
|
// TODO: figure out how spin up get the correct data source
|
||||||
this.#treeSource = new MemberGroupTreeServerDataSource(this.#host);
|
this.#treeSource = new UmbMemberGroupTreeServerDataSource(this.#host);
|
||||||
this.#detailSource = new UmbMemberGroupDetailServerDataSource(this.#host);
|
this.#detailSource = new UmbMemberGroupDetailServerDataSource(this.#host);
|
||||||
|
|
||||||
new UmbContextConsumerController(this.#host, UMB_MEMBER_GROUP_TREE_STORE_CONTEXT_TOKEN, (instance) => {
|
new UmbContextConsumerController(this.#host, UMB_MEMBER_GROUP_TREE_STORE_CONTEXT_TOKEN, (instance) => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { MemberGroupDetails } from '@umbraco-cms/backoffice/models';
|
import type { MemberGroupDetails } from '@umbraco-cms/backoffice/models';
|
||||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||||
import { ArrayState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
|||||||
* @description - Data Store for Member Groups
|
* @description - Data Store for Member Groups
|
||||||
*/
|
*/
|
||||||
export class UmbMemberGroupStore extends UmbStoreBase {
|
export class UmbMemberGroupStore extends UmbStoreBase {
|
||||||
#data = new ArrayState<MemberGroupDetails>([], (x) => x.id);
|
#data = new UmbArrayState<MemberGroupDetails>([], (x) => x.id);
|
||||||
|
|
||||||
constructor(host: UmbControllerHostElement) {
|
constructor(host: UmbControllerHostElement) {
|
||||||
super(host, UMB_MEMBER_GROUP_STORE_CONTEXT_TOKEN.toString());
|
super(host, UMB_MEMBER_GROUP_STORE_CONTEXT_TOKEN.toString());
|
||||||
|
|||||||
@@ -6,16 +6,16 @@ import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
|
|||||||
/**
|
/**
|
||||||
* A data source for the Member Group tree that fetches data from the server
|
* A data source for the Member Group tree that fetches data from the server
|
||||||
* @export
|
* @export
|
||||||
* @class MemberGroupTreeServerDataSource
|
* @class UmbMemberGroupTreeServerDataSource
|
||||||
* @implements {MemberGroupTreeDataSource}
|
* @implements {UmbTreeDataSource}
|
||||||
*/
|
*/
|
||||||
export class MemberGroupTreeServerDataSource implements UmbTreeDataSource {
|
export class UmbMemberGroupTreeServerDataSource implements UmbTreeDataSource {
|
||||||
#host: UmbControllerHostElement;
|
#host: UmbControllerHostElement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance of MemberGroupTreeServerDataSource.
|
* Creates an instance of UmbMemberGroupTreeServerDataSource.
|
||||||
* @param {UmbControllerHostElement} host
|
* @param {UmbControllerHostElement} host
|
||||||
* @memberof MemberGroupTreeServerDataSource
|
* @memberof UmbMemberGroupTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
constructor(host: UmbControllerHostElement) {
|
constructor(host: UmbControllerHostElement) {
|
||||||
this.#host = host;
|
this.#host = host;
|
||||||
@@ -24,7 +24,7 @@ export class MemberGroupTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
/**
|
/**
|
||||||
* Fetches the root items for the tree from the server
|
* Fetches the root items for the tree from the server
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof MemberGroupTreeServerDataSource
|
* @memberof UmbMemberGroupTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getRootItems() {
|
async getRootItems() {
|
||||||
return tryExecuteAndNotify(this.#host, MemberGroupResource.getTreeMemberGroupRoot({}));
|
return tryExecuteAndNotify(this.#host, MemberGroupResource.getTreeMemberGroupRoot({}));
|
||||||
@@ -34,7 +34,7 @@ export class MemberGroupTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
* Fetches the children of a given parent id from the server
|
* Fetches the children of a given parent id from the server
|
||||||
* @param {(string | null)} parentId
|
* @param {(string | null)} parentId
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof MemberGroupTreeServerDataSource
|
* @memberof UmbMemberGroupTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getChildrenOf(parentId: string | null) {
|
async getChildrenOf(parentId: string | null) {
|
||||||
// Not implemented for this tree
|
// Not implemented for this tree
|
||||||
@@ -45,7 +45,7 @@ export class MemberGroupTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
* Fetches the items for the given ids from the server
|
* Fetches the items for the given ids from the server
|
||||||
* @param {Array<string>} ids
|
* @param {Array<string>} ids
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof MemberGroupTreeServerDataSource
|
* @memberof UmbMemberGroupTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getItems(ids: Array<string>) {
|
async getItems(ids: Array<string>) {
|
||||||
if (!ids || ids.length === 0) {
|
if (!ids || ids.length === 0) {
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ import { UmbMemberGroupRepository } from '../repository/member-group.repository'
|
|||||||
import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace';
|
import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace';
|
||||||
import type { MemberGroupDetails } from '@umbraco-cms/backoffice/models';
|
import type { MemberGroupDetails } from '@umbraco-cms/backoffice/models';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
import { ObjectState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
|
|
||||||
type EntityType = MemberGroupDetails;
|
type EntityType = MemberGroupDetails;
|
||||||
export class UmbWorkspaceMemberGroupContext
|
export class UmbWorkspaceMemberGroupContext
|
||||||
extends UmbWorkspaceContext<UmbMemberGroupRepository, EntityType>
|
extends UmbWorkspaceContext<UmbMemberGroupRepository, EntityType>
|
||||||
implements UmbEntityWorkspaceContextInterface<EntityType | undefined>
|
implements UmbEntityWorkspaceContextInterface<EntityType | undefined>
|
||||||
{
|
{
|
||||||
#data = new ObjectState<EntityType | undefined>(undefined);
|
#data = new UmbObjectState<EntityType | undefined>(undefined);
|
||||||
data = this.#data.asObservable();
|
data = this.#data.asObservable();
|
||||||
name = this.#data.getObservablePart((data) => data?.name);
|
name = this.#data.getObservablePart((data) => data?.name);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MemberTypeTreeServerDataSource } from './sources/member-type.tree.server.data';
|
import { UmbMemberTypeTreeServerDataSource } from './sources/member-type.tree.server.data';
|
||||||
import { UmbMemberTypeTreeStore, UMB_MEMBER_TYPE_TREE_STORE_CONTEXT_TOKEN } from './member-type.tree.store';
|
import { UmbMemberTypeTreeStore, UMB_MEMBER_TYPE_TREE_STORE_CONTEXT_TOKEN } from './member-type.tree.store';
|
||||||
import { UmbMemberTypeStore, UMB_MEMBER_TYPE_STORE_CONTEXT_TOKEN } from './member-type.store';
|
import { UmbMemberTypeStore, UMB_MEMBER_TYPE_STORE_CONTEXT_TOKEN } from './member-type.store';
|
||||||
import { UmbMemberTypeDetailServerDataSource } from './sources/member-type.detail.server.data';
|
import { UmbMemberTypeDetailServerDataSource } from './sources/member-type.detail.server.data';
|
||||||
@@ -30,7 +30,7 @@ export class UmbMemberTypeRepository implements UmbTreeRepository<TreeItemType>,
|
|||||||
this.#host = host;
|
this.#host = host;
|
||||||
|
|
||||||
// TODO: figure out how spin up get the correct data source
|
// TODO: figure out how spin up get the correct data source
|
||||||
this.#treeSource = new MemberTypeTreeServerDataSource(this.#host);
|
this.#treeSource = new UmbMemberTypeTreeServerDataSource(this.#host);
|
||||||
this.#detailSource = new UmbMemberTypeDetailServerDataSource(this.#host);
|
this.#detailSource = new UmbMemberTypeDetailServerDataSource(this.#host);
|
||||||
|
|
||||||
this.#init = Promise.all([
|
this.#init = Promise.all([
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||||
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
import { ArrayState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import type { MemberTypeDetails } from '@umbraco-cms/backoffice/models';
|
import type { MemberTypeDetails } from '@umbraco-cms/backoffice/models';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -11,7 +11,7 @@ import type { MemberTypeDetails } from '@umbraco-cms/backoffice/models';
|
|||||||
* @description - Data Store for Member Types
|
* @description - Data Store for Member Types
|
||||||
*/
|
*/
|
||||||
export class UmbMemberTypeStore extends UmbStoreBase {
|
export class UmbMemberTypeStore extends UmbStoreBase {
|
||||||
#data = new ArrayState<MemberTypeDetails>([], (x) => x.id);
|
#data = new UmbArrayState<MemberTypeDetails>([], (x) => x.id);
|
||||||
|
|
||||||
constructor(host: UmbControllerHostElement) {
|
constructor(host: UmbControllerHostElement) {
|
||||||
super(host, UMB_MEMBER_TYPE_STORE_CONTEXT_TOKEN.toString());
|
super(host, UMB_MEMBER_TYPE_STORE_CONTEXT_TOKEN.toString());
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
|
|||||||
/**
|
/**
|
||||||
* A data source for the MemberType tree that fetches data from the server
|
* A data source for the MemberType tree that fetches data from the server
|
||||||
* @export
|
* @export
|
||||||
* @class MemberTypeTreeServerDataSource
|
* @class UmbMemberTypeTreeServerDataSource
|
||||||
* @implements {MemberTypeTreeDataSource}
|
* @implements {UmbTreeDataSource}
|
||||||
*/
|
*/
|
||||||
export class MemberTypeTreeServerDataSource implements UmbTreeDataSource {
|
export class UmbMemberTypeTreeServerDataSource implements UmbTreeDataSource {
|
||||||
#host: UmbControllerHostElement;
|
#host: UmbControllerHostElement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,7 +24,7 @@ export class MemberTypeTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
/**
|
/**
|
||||||
* Fetches the root items for the tree from the server
|
* Fetches the root items for the tree from the server
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof MemberTypeTreeServerDataSource
|
* @memberof UmbMemberTypeTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getRootItems() {
|
async getRootItems() {
|
||||||
return tryExecuteAndNotify(this.#host, MemberTypeResource.getTreeMemberTypeRoot({}));
|
return tryExecuteAndNotify(this.#host, MemberTypeResource.getTreeMemberTypeRoot({}));
|
||||||
@@ -34,7 +34,7 @@ export class MemberTypeTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
* Fetches the children of a given parent id from the server
|
* Fetches the children of a given parent id from the server
|
||||||
* @param {(string | null)} parentId
|
* @param {(string | null)} parentId
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof MemberTypeTreeServerDataSource
|
* @memberof UmbMemberTypeTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getChildrenOf(parentId: string | null) {
|
async getChildrenOf(parentId: string | null) {
|
||||||
const error: ProblemDetailsModel = { title: 'Not implemented for Member Type' };
|
const error: ProblemDetailsModel = { title: 'Not implemented for Member Type' };
|
||||||
@@ -45,7 +45,7 @@ export class MemberTypeTreeServerDataSource implements UmbTreeDataSource {
|
|||||||
* Fetches the items for the given ids from the server
|
* Fetches the items for the given ids from the server
|
||||||
* @param {Array<string>} ids
|
* @param {Array<string>} ids
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof MemberTypeTreeServerDataSource
|
* @memberof UmbMemberTypeTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getItems(ids: Array<string>) {
|
async getItems(ids: Array<string>) {
|
||||||
if (!ids || ids.length === 0) {
|
if (!ids || ids.length === 0) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { UmbWorkspaceContext } from '../../../shared/components/workspace/workspace-context/workspace-context';
|
import { UmbWorkspaceContext } from '../../../shared/components/workspace/workspace-context/workspace-context';
|
||||||
import { UmbMemberTypeRepository } from '../repository/member-type.repository';
|
import { UmbMemberTypeRepository } from '../repository/member-type.repository';
|
||||||
import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace';
|
import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace';
|
||||||
import { ObjectState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
|
|
||||||
// TODO => use correct tpye
|
// TODO => use correct tpye
|
||||||
@@ -11,7 +11,7 @@ export class UmbMemberTypeWorkspaceContext
|
|||||||
extends UmbWorkspaceContext<UmbMemberTypeRepository, EntityType>
|
extends UmbWorkspaceContext<UmbMemberTypeRepository, EntityType>
|
||||||
implements UmbEntityWorkspaceContextInterface<EntityType | undefined>
|
implements UmbEntityWorkspaceContextInterface<EntityType | undefined>
|
||||||
{
|
{
|
||||||
#data = new ObjectState<EntityType | undefined>(undefined);
|
#data = new UmbObjectState<EntityType | undefined>(undefined);
|
||||||
name = this.#data.getObservablePart((data) => data?.name);
|
name = this.#data.getObservablePart((data) => data?.name);
|
||||||
|
|
||||||
constructor(host: UmbControllerHostElement) {
|
constructor(host: UmbControllerHostElement) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Observable } from 'rxjs';
|
|||||||
import { umbMemberData } from '../../../core/mocks/data/member.data';
|
import { umbMemberData } from '../../../core/mocks/data/member.data';
|
||||||
import type { MemberDetails, MemberGroupDetails } from '@umbraco-cms/backoffice/models';
|
import type { MemberDetails, MemberGroupDetails } from '@umbraco-cms/backoffice/models';
|
||||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||||
import { ArrayState, createObservablePart } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbArrayState, createObservablePart } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
import { UmbEntityDetailStore, UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
import { UmbEntityDetailStore, UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ import { UmbEntityDetailStore, UmbStoreBase } from '@umbraco-cms/backoffice/stor
|
|||||||
* @description - Data Store for Members
|
* @description - Data Store for Members
|
||||||
*/
|
*/
|
||||||
export class UmbMemberStore extends UmbStoreBase implements UmbEntityDetailStore<MemberDetails> {
|
export class UmbMemberStore extends UmbStoreBase implements UmbEntityDetailStore<MemberDetails> {
|
||||||
#data = new ArrayState<MemberDetails>([], (x) => x.id);
|
#data = new UmbArrayState<MemberDetails>([], (x) => x.id);
|
||||||
public groups = this.#data.asObservable();
|
public groups = this.#data.asObservable();
|
||||||
|
|
||||||
constructor(private host: UmbControllerHostElement) {
|
constructor(private host: UmbControllerHostElement) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { UmbMemberTreeStore, UMB_MEMBER_TREE_STORE_CONTEXT_TOKEN } from './member.tree.store';
|
import { UmbMemberTreeStore, UMB_MEMBER_TREE_STORE_CONTEXT_TOKEN } from './member.tree.store';
|
||||||
import { MemberTreeServerDataSource } from './sources/member.tree.server.data';
|
import { UmbMemberTreeServerDataSource } from './sources/member.tree.server.data';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification';
|
import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification';
|
||||||
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
|
||||||
@@ -8,7 +8,7 @@ import { ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api';
|
|||||||
|
|
||||||
export class UmbMemberRepository implements UmbTreeRepository {
|
export class UmbMemberRepository implements UmbTreeRepository {
|
||||||
#host: UmbControllerHostElement;
|
#host: UmbControllerHostElement;
|
||||||
#dataSource: MemberTreeServerDataSource;
|
#dataSource: UmbMemberTreeServerDataSource;
|
||||||
#treeStore?: UmbMemberTreeStore;
|
#treeStore?: UmbMemberTreeStore;
|
||||||
#notificationContext?: UmbNotificationContext;
|
#notificationContext?: UmbNotificationContext;
|
||||||
#initResolver?: () => void;
|
#initResolver?: () => void;
|
||||||
@@ -17,7 +17,7 @@ export class UmbMemberRepository implements UmbTreeRepository {
|
|||||||
constructor(host: UmbControllerHostElement) {
|
constructor(host: UmbControllerHostElement) {
|
||||||
this.#host = host;
|
this.#host = host;
|
||||||
// TODO: figure out how spin up get the correct data source
|
// TODO: figure out how spin up get the correct data source
|
||||||
this.#dataSource = new MemberTreeServerDataSource(this.#host);
|
this.#dataSource = new UmbMemberTreeServerDataSource(this.#host);
|
||||||
|
|
||||||
new UmbContextConsumerController(this.#host, UMB_MEMBER_TREE_STORE_CONTEXT_TOKEN, (instance) => {
|
new UmbContextConsumerController(this.#host, UMB_MEMBER_TREE_STORE_CONTEXT_TOKEN, (instance) => {
|
||||||
this.#treeStore = instance;
|
this.#treeStore = instance;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||||
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
import { ArrayState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import type { MemberDetails } from '@umbraco-cms/backoffice/models';
|
import type { MemberDetails } from '@umbraco-cms/backoffice/models';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -11,7 +11,7 @@ import type { MemberDetails } from '@umbraco-cms/backoffice/models';
|
|||||||
* @description - Data Store for Members
|
* @description - Data Store for Members
|
||||||
*/
|
*/
|
||||||
export class UmbMemberStore extends UmbStoreBase {
|
export class UmbMemberStore extends UmbStoreBase {
|
||||||
#data = new ArrayState<MemberDetails>([], (x) => x.id);
|
#data = new UmbArrayState<MemberDetails>([], (x) => x.id);
|
||||||
|
|
||||||
constructor(host: UmbControllerHostElement) {
|
constructor(host: UmbControllerHostElement) {
|
||||||
super(host, UMB_MEMBER_STORE_CONTEXT_TOKEN.toString());
|
super(host, UMB_MEMBER_STORE_CONTEXT_TOKEN.toString());
|
||||||
|
|||||||
@@ -4,16 +4,16 @@ import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
|||||||
/**
|
/**
|
||||||
* A data source for the Member tree that fetches data from the server
|
* A data source for the Member tree that fetches data from the server
|
||||||
* @export
|
* @export
|
||||||
* @class MemberTreeServerDataSource
|
* @class UmbMemberTreeServerDataSource
|
||||||
* @implements {MemberTreeDataSource}
|
* @implements {MemberTreeDataSource}
|
||||||
*/
|
*/
|
||||||
export class MemberTreeServerDataSource implements MemberTreeDataSource {
|
export class UmbMemberTreeServerDataSource implements MemberTreeDataSource {
|
||||||
#host: UmbControllerHostElement;
|
#host: UmbControllerHostElement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance of MemberTreeServerDataSource.
|
* Creates an instance of UmbMemberTreeServerDataSource.
|
||||||
* @param {UmbControllerHostElement} host
|
* @param {UmbControllerHostElement} host
|
||||||
* @memberof MemberTreeServerDataSource
|
* @memberof UmbMemberTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
constructor(host: UmbControllerHostElement) {
|
constructor(host: UmbControllerHostElement) {
|
||||||
this.#host = host;
|
this.#host = host;
|
||||||
@@ -22,7 +22,7 @@ export class MemberTreeServerDataSource implements MemberTreeDataSource {
|
|||||||
/**
|
/**
|
||||||
* Fetches the root items for the tree from the server
|
* Fetches the root items for the tree from the server
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof MemberTreeServerDataSource
|
* @memberof UmbMemberTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getRootItems() {
|
async getRootItems() {
|
||||||
const response = await fetch('/umbraco/management/api/v1/tree/member/root');
|
const response = await fetch('/umbraco/management/api/v1/tree/member/root');
|
||||||
@@ -36,7 +36,7 @@ export class MemberTreeServerDataSource implements MemberTreeDataSource {
|
|||||||
* Fetches the items for the given ids from the server
|
* Fetches the items for the given ids from the server
|
||||||
* @param {Array<string>} ids
|
* @param {Array<string>} ids
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof MemberTreeServerDataSource
|
* @memberof UmbMemberTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getItems(ids: Array<string>) {
|
async getItems(ids: Array<string>) {
|
||||||
const response = await fetch('/umbraco/management/api/v1/tree/member/item');
|
const response = await fetch('/umbraco/management/api/v1/tree/member/item');
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
|||||||
import type { UmbPackage } from '@umbraco-cms/backoffice/models';
|
import type { UmbPackage } from '@umbraco-cms/backoffice/models';
|
||||||
import type { PackageMigrationStatusResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
import type { PackageMigrationStatusResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
import type { ManifestBase } from '@umbraco-cms/backoffice/extensions-registry';
|
import type { ManifestBase } from '@umbraco-cms/backoffice/extensions-registry';
|
||||||
import { ArrayState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
|
|
||||||
export const UMB_PACKAGE_STORE_TOKEN = new UmbContextToken<UmbPackageStore>('UmbPackageStore');
|
export const UMB_PACKAGE_STORE_TOKEN = new UmbContextToken<UmbPackageStore>('UmbPackageStore');
|
||||||
|
|
||||||
@@ -21,9 +21,9 @@ export class UmbPackageStore extends UmbStoreBase {
|
|||||||
*/
|
*/
|
||||||
#packages = new ReplaySubject<Array<UmbPackage>>(1);
|
#packages = new ReplaySubject<Array<UmbPackage>>(1);
|
||||||
|
|
||||||
#extensions = new ArrayState<ManifestBase>([], (e) => e.alias);
|
#extensions = new UmbArrayState<ManifestBase>([], (e) => e.alias);
|
||||||
|
|
||||||
#migrations = new ArrayState<PackageMigrationStatusResponseModel>([], (e) => e.packageName);
|
#migrations = new UmbArrayState<PackageMigrationStatusResponseModel>([], (e) => e.packageName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Observable of packages with extensions
|
* Observable of packages with extensions
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ export class UmbDashboardModelsBuilderElement extends UmbLitElement {
|
|||||||
</p>
|
</p>
|
||||||
${this._modelsBuilder?.lastError
|
${this._modelsBuilder?.lastError
|
||||||
? html`<p class="error">Last generation failed with the following error:</p>
|
? html`<p class="error">Last generation failed with the following error:</p>
|
||||||
<uui-code-block>${this._modelsBuilder.lastError}</uui-code-block>`
|
<umb-code-block>${this._modelsBuilder.lastError}</umb-code-block>`
|
||||||
: nothing}
|
: nothing}
|
||||||
</uui-box>
|
</uui-box>
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { DataTypeResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
import type { DataTypeResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||||
import { ArrayState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ export const UMB_DATA_TYPE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbDataType
|
|||||||
* @description - Data Store for Template Details
|
* @description - Data Store for Template Details
|
||||||
*/
|
*/
|
||||||
export class UmbDataTypeStore extends UmbStoreBase {
|
export class UmbDataTypeStore extends UmbStoreBase {
|
||||||
#data = new ArrayState<DataTypeResponseModel>([], (x) => x.id);
|
#data = new UmbArrayState<DataTypeResponseModel>([], (x) => x.id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance of UmbDataTypeStore.
|
* Creates an instance of UmbDataTypeStore.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { UmbWorkspaceContext } from '../../../shared/components/workspace/worksp
|
|||||||
import { UmbDataTypeRepository } from '../repository/data-type.repository';
|
import { UmbDataTypeRepository } from '../repository/data-type.repository';
|
||||||
import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace';
|
import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace';
|
||||||
import type { CreateDataTypeRequestModel, DataTypeResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
import type { CreateDataTypeRequestModel, DataTypeResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
import { appendToFrozenArray, ObjectState } from '@umbraco-cms/backoffice/observable-api';
|
import { appendToFrozenArray, UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
|
|
||||||
export class UmbDataTypeWorkspaceContext
|
export class UmbDataTypeWorkspaceContext
|
||||||
@@ -10,7 +10,7 @@ export class UmbDataTypeWorkspaceContext
|
|||||||
implements UmbEntityWorkspaceContextInterface<DataTypeResponseModel | undefined>
|
implements UmbEntityWorkspaceContextInterface<DataTypeResponseModel | undefined>
|
||||||
{
|
{
|
||||||
// TODO: revisit. temp solution because the create and response models are different.
|
// TODO: revisit. temp solution because the create and response models are different.
|
||||||
#data = new ObjectState<DataTypeResponseModel | undefined>(undefined);
|
#data = new UmbObjectState<DataTypeResponseModel | undefined>(undefined);
|
||||||
data = this.#data.asObservable();
|
data = this.#data.asObservable();
|
||||||
|
|
||||||
name = this.#data.getObservablePart((data) => data?.name);
|
name = this.#data.getObservablePart((data) => data?.name);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { UmbLanguageRepository } from '../repository/language.repository';
|
import { UmbLanguageRepository } from '../repository/language.repository';
|
||||||
import { ObjectState, UmbObserverController } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbObjectState, UmbObserverController } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||||
import { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
import { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
@@ -10,7 +10,7 @@ export class UmbAppLanguageContext {
|
|||||||
|
|
||||||
#languages: Array<LanguageResponseModel> = [];
|
#languages: Array<LanguageResponseModel> = [];
|
||||||
|
|
||||||
#appLanguage = new ObjectState<LanguageResponseModel | undefined>(undefined);
|
#appLanguage = new UmbObjectState<LanguageResponseModel | undefined>(undefined);
|
||||||
appLanguage = this.#appLanguage.asObservable();
|
appLanguage = this.#appLanguage.asObservable();
|
||||||
|
|
||||||
constructor(host: UmbControllerHostElement) {
|
constructor(host: UmbControllerHostElement) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||||
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
import { ArrayState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
import { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
|
|
||||||
export const UMB_LANGUAGE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbLanguageStore>('UmbLanguageStore');
|
export const UMB_LANGUAGE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbLanguageStore>('UmbLanguageStore');
|
||||||
@@ -13,7 +13,7 @@ export const UMB_LANGUAGE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbLanguageS
|
|||||||
* @description - Details Data Store for Languages
|
* @description - Details Data Store for Languages
|
||||||
*/
|
*/
|
||||||
export class UmbLanguageStore extends UmbStoreBase {
|
export class UmbLanguageStore extends UmbStoreBase {
|
||||||
#data = new ArrayState<LanguageResponseModel>([], (x) => x.isoCode);
|
#data = new UmbArrayState<LanguageResponseModel>([], (x) => x.isoCode);
|
||||||
data = this.#data.asObservable();
|
data = this.#data.asObservable();
|
||||||
|
|
||||||
constructor(host: UmbControllerHostElement) {
|
constructor(host: UmbControllerHostElement) {
|
||||||
|
|||||||
@@ -2,18 +2,18 @@ import { UmbLanguageRepository } from '../../repository/language.repository';
|
|||||||
import { UmbWorkspaceContext } from '../../../../shared/components/workspace/workspace-context/workspace-context';
|
import { UmbWorkspaceContext } from '../../../../shared/components/workspace/workspace-context/workspace-context';
|
||||||
import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace';
|
import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace';
|
||||||
import type { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
import type { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
import { ObjectState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
|
|
||||||
export class UmbLanguageWorkspaceContext
|
export class UmbLanguageWorkspaceContext
|
||||||
extends UmbWorkspaceContext<UmbLanguageRepository, LanguageResponseModel>
|
extends UmbWorkspaceContext<UmbLanguageRepository, LanguageResponseModel>
|
||||||
implements UmbEntityWorkspaceContextInterface
|
implements UmbEntityWorkspaceContextInterface
|
||||||
{
|
{
|
||||||
#data = new ObjectState<LanguageResponseModel | undefined>(undefined);
|
#data = new UmbObjectState<LanguageResponseModel | undefined>(undefined);
|
||||||
data = this.#data.asObservable();
|
data = this.#data.asObservable();
|
||||||
|
|
||||||
// TODO: this is a temp solution to bubble validation errors to the UI
|
// TODO: this is a temp solution to bubble validation errors to the UI
|
||||||
#validationErrors = new ObjectState<any | undefined>(undefined);
|
#validationErrors = new UmbObjectState<any | undefined>(undefined);
|
||||||
validationErrors = this.#validationErrors.asObservable();
|
validationErrors = this.#validationErrors.asObservable();
|
||||||
|
|
||||||
constructor(host: UmbControllerHostElement) {
|
constructor(host: UmbControllerHostElement) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { UmbLogMessagesServerDataSource, UmbLogSearchesServerDataSource } from '
|
|||||||
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification';
|
import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification';
|
||||||
import { DirectionModel, LogLevelModel } from '@umbraco-cms/backoffice/backend-api';
|
import { DirectionModel, LogLevelModel, SavedLogSearchPresenationBaseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
|
|
||||||
// Move to documentation / JSdoc
|
// Move to documentation / JSdoc
|
||||||
/* We need to create a new instance of the repository from within the element context. We want the notifications to be displayed in the right context. */
|
/* We need to create a new instance of the repository from within the element context. We want the notifications to be displayed in the right context. */
|
||||||
@@ -47,10 +47,30 @@ export class UmbLogViewerRepository {
|
|||||||
return this.#searchDataSource.getAllSavedSearches({ skip, take });
|
return this.#searchDataSource.getAllSavedSearches({ skip, take });
|
||||||
}
|
}
|
||||||
|
|
||||||
async getMessageTemplates({ skip, take }: { skip: number; take: number }) {
|
async saveSearch({ name, query }: SavedLogSearchPresenationBaseModel) {
|
||||||
|
await this.#init();
|
||||||
|
this.#searchDataSource.postLogViewerSavedSearch({ name, query });
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeSearch({ name }: { name: string }) {
|
||||||
|
await this.#init();
|
||||||
|
this.#searchDataSource.deleteSavedSearchByName({ name });
|
||||||
|
}
|
||||||
|
|
||||||
|
async getMessageTemplates({
|
||||||
|
skip,
|
||||||
|
take,
|
||||||
|
startDate,
|
||||||
|
endDate,
|
||||||
|
}: {
|
||||||
|
skip: number;
|
||||||
|
take: number;
|
||||||
|
startDate?: string;
|
||||||
|
endDate?: string;
|
||||||
|
}) {
|
||||||
await this.#init();
|
await this.#init();
|
||||||
|
|
||||||
return this.#messagesDataSource.getLogViewerMessageTemplate({ skip, take });
|
return this.#messagesDataSource.getLogViewerMessageTemplate({ skip, take, startDate, endDate });
|
||||||
}
|
}
|
||||||
|
|
||||||
async getLogCount({ startDate, endDate }: { startDate?: string; endDate?: string }) {
|
async getLogCount({ startDate, endDate }: { startDate?: string; endDate?: string }) {
|
||||||
|
|||||||
@@ -20,11 +20,7 @@ export interface LogSearchDataSource {
|
|||||||
}): Promise<DataSourceResponse<PagedSavedLogSearchResponseModel>>;
|
}): Promise<DataSourceResponse<PagedSavedLogSearchResponseModel>>;
|
||||||
getSavedSearchByName({ name }: { name: string }): Promise<DataSourceResponse<SavedLogSearchResponseModel>>;
|
getSavedSearchByName({ name }: { name: string }): Promise<DataSourceResponse<SavedLogSearchResponseModel>>;
|
||||||
deleteSavedSearchByName({ name }: { name: string }): Promise<DataSourceResponse<unknown>>;
|
deleteSavedSearchByName({ name }: { name: string }): Promise<DataSourceResponse<unknown>>;
|
||||||
postLogViewerSavedSearch({
|
postLogViewerSavedSearch({ name, query }: SavedLogSearchResponseModel): Promise<DataSourceResponse<unknown>>;
|
||||||
requestBody,
|
|
||||||
}: {
|
|
||||||
requestBody?: SavedLogSearchResponseModel;
|
|
||||||
}): Promise<DataSourceResponse<unknown>>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LogMessagesDataSource {
|
export interface LogMessagesDataSource {
|
||||||
|
|||||||
@@ -54,8 +54,11 @@ export class UmbLogSearchesServerDataSource implements LogSearchDataSource {
|
|||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof UmbLogSearchesServerDataSource
|
* @memberof UmbLogSearchesServerDataSource
|
||||||
*/
|
*/
|
||||||
async postLogViewerSavedSearch({ requestBody }: { requestBody?: SavedLogSearchResponseModel }) {
|
async postLogViewerSavedSearch({ name, query }: SavedLogSearchResponseModel) {
|
||||||
return await tryExecuteAndNotify(this.#host, LogViewerResource.postLogViewerSavedSearch({ requestBody }));
|
return await tryExecuteAndNotify(
|
||||||
|
this.#host,
|
||||||
|
LogViewerResource.postLogViewerSavedSearch({ requestBody: { name, query } })
|
||||||
|
);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Remove a log viewer saved search by name from the server
|
* Remove a log viewer saved search by name from the server
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
UMB_APP_LOG_VIEWER_CONTEXT_TOKEN,
|
UMB_APP_LOG_VIEWER_CONTEXT_TOKEN,
|
||||||
} from '../../logviewer.context';
|
} from '../../logviewer.context';
|
||||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||||
|
import { query as getQuery, path, toQueryString } from '@umbraco-cms/backoffice/router';
|
||||||
|
|
||||||
@customElement('umb-log-viewer-date-range-selector')
|
@customElement('umb-log-viewer-date-range-selector')
|
||||||
export class UmbLogViewerDateRangeSelectorElement extends UmbLitElement {
|
export class UmbLogViewerDateRangeSelectorElement extends UmbLitElement {
|
||||||
@@ -86,8 +87,15 @@ export class UmbLogViewerDateRangeSelectorElement extends UmbLitElement {
|
|||||||
this._endDate = input.value;
|
this._endDate = input.value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const newDateRange: LogViewerDateRange = { startDate: this._startDate, endDate: this._endDate };
|
|
||||||
this.#logViewerContext?.setDateRange(newDateRange);
|
const query = getQuery();
|
||||||
|
const qs = toQueryString({
|
||||||
|
...query,
|
||||||
|
startDate: this._startDate,
|
||||||
|
endDate: this._endDate,
|
||||||
|
});
|
||||||
|
|
||||||
|
window.history.pushState({}, '', `${path()}?${qs}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|||||||
@@ -27,7 +27,10 @@ export class UmbLogViewerLevelTagElement extends LitElement {
|
|||||||
Information: { look: 'primary', color: 'positive' },
|
Information: { look: 'primary', color: 'positive' },
|
||||||
Warning: { look: 'primary', color: 'warning' },
|
Warning: { look: 'primary', color: 'warning' },
|
||||||
Error: { look: 'primary', color: 'danger' },
|
Error: { look: 'primary', color: 'danger' },
|
||||||
Fatal: { look: 'primary' },
|
Fatal: {
|
||||||
|
look: 'primary',
|
||||||
|
style: 'background-color: var(--umb-log-viewer-fatal-color); color: var(--uui-color-surface)',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import './components';
|
import './components';
|
||||||
import { map } from 'rxjs';
|
import { map } from 'rxjs';
|
||||||
import { css, html, nothing } from 'lit';
|
import { PropertyValueMap, css, html, nothing } from 'lit';
|
||||||
import { customElement, state } from 'lit/decorators.js';
|
import { customElement, state } from 'lit/decorators.js';
|
||||||
import { UUITextStyles } from '@umbraco-ui/uui-css';
|
import { UUITextStyles } from '@umbraco-ui/uui-css';
|
||||||
import { repeat } from 'lit/directives/repeat.js';
|
import { repeat } from 'lit/directives/repeat.js';
|
||||||
@@ -8,7 +8,7 @@ import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '
|
|||||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||||
import { umbExtensionsRegistry, createExtensionElement } from '@umbraco-cms/backoffice/extensions-api';
|
import { umbExtensionsRegistry, createExtensionElement } from '@umbraco-cms/backoffice/extensions-api';
|
||||||
import { ManifestWorkspaceView, ManifestWorkspaceViewCollection } from '@umbraco-cms/backoffice/extensions-registry';
|
import { ManifestWorkspaceView, ManifestWorkspaceViewCollection } from '@umbraco-cms/backoffice/extensions-registry';
|
||||||
import { UmbRouterSlotInitEvent, UmbRouterSlotChangeEvent } from '@umbraco-cms/internal/router';
|
import type { UmbRouterSlotInitEvent, UmbRouterSlotChangeEvent } from '@umbraco-cms/internal/router';
|
||||||
import type { IRoute } from '@umbraco-cms/backoffice/router';
|
import type { IRoute } from '@umbraco-cms/backoffice/router';
|
||||||
|
|
||||||
//TODO make uui-input accept min and max values
|
//TODO make uui-input accept min and max values
|
||||||
@@ -26,7 +26,7 @@ export class UmbLogViewerWorkspaceElement extends UmbLitElement {
|
|||||||
--umb-log-viewer-information-color: var(--uui-color-positive);
|
--umb-log-viewer-information-color: var(--uui-color-positive);
|
||||||
--umb-log-viewer-warning-color: var(--uui-color-warning);
|
--umb-log-viewer-warning-color: var(--uui-color-warning);
|
||||||
--umb-log-viewer-error-color: var(--uui-color-danger);
|
--umb-log-viewer-error-color: var(--uui-color-danger);
|
||||||
--umb-log-viewer-fatal-color: var(--uui-color-default);
|
--umb-log-viewer-fatal-color: var(--uui-palette-black);
|
||||||
--umb-log-viewer-verbose-color: var(--uui-color-current);
|
--umb-log-viewer-verbose-color: var(--uui-color-current);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,12 +64,24 @@ export class UmbLogViewerWorkspaceElement extends UmbLitElement {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.#logViewerContext.init();
|
this.#logViewerContext.init();
|
||||||
|
this.provideContext(UMB_APP_LOG_VIEWER_CONTEXT_TOKEN, this.#logViewerContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
firstUpdated(props: PropertyValueMap<unknown>) {
|
||||||
|
super.firstUpdated(props);
|
||||||
|
|
||||||
|
window.addEventListener('changestate', this.#logViewerContext.onChangeState);
|
||||||
|
this.#logViewerContext.onChangeState();
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
this._observeWorkspaceViews();
|
this._observeWorkspaceViews();
|
||||||
this.provideContext(UMB_APP_LOG_VIEWER_CONTEXT_TOKEN, this.#logViewerContext);
|
}
|
||||||
|
|
||||||
|
disconnectedCallback(): void {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
window.removeEventListener('changestate', this.#logViewerContext.onChangeState);
|
||||||
}
|
}
|
||||||
|
|
||||||
load(): void {
|
load(): void {
|
||||||
@@ -101,9 +113,7 @@ export class UmbLogViewerWorkspaceElement extends UmbLitElement {
|
|||||||
this._routes = this._workspaceViews.map((view) => {
|
this._routes = this._workspaceViews.map((view) => {
|
||||||
return {
|
return {
|
||||||
path: `${view.meta.pathname}`,
|
path: `${view.meta.pathname}`,
|
||||||
component: () => {
|
component: () => createExtensionElement(view),
|
||||||
return createExtensionElement(view);
|
|
||||||
},
|
|
||||||
setup: (component) => {
|
setup: (component) => {
|
||||||
(component as any).manifest = view;
|
(component as any).manifest = view;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type {
|
import type {
|
||||||
|
ManifestModal,
|
||||||
ManifestWorkspace,
|
ManifestWorkspace,
|
||||||
ManifestWorkspaceAction,
|
ManifestWorkspaceAction,
|
||||||
ManifestWorkspaceView,
|
ManifestWorkspaceView,
|
||||||
@@ -51,4 +52,13 @@ const workspaceViews: Array<ManifestWorkspaceView> = [
|
|||||||
|
|
||||||
const workspaceActions: Array<ManifestWorkspaceAction> = [];
|
const workspaceActions: Array<ManifestWorkspaceAction> = [];
|
||||||
|
|
||||||
export const manifests = [workspace, ...workspaceViews, ...workspaceActions];
|
const modals: Array<ManifestModal> = [
|
||||||
|
{
|
||||||
|
type: 'modal',
|
||||||
|
alias: 'Umb.Modal.LogViewer.SaveSearch',
|
||||||
|
name: 'Saved Searches Modal',
|
||||||
|
loader: () => import('../views/search/components/log-viewer-search-input-modal.element'),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const manifests = [workspace, ...workspaceViews, ...workspaceActions, ...modals];
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { UmbLogViewerRepository } from '../repository/log-viewer.repository';
|
import { UmbLogViewerRepository } from '../repository/log-viewer.repository';
|
||||||
import {
|
import {
|
||||||
BasicState,
|
UmbBasicState,
|
||||||
ArrayState,
|
UmbArrayState,
|
||||||
createObservablePart,
|
createObservablePart,
|
||||||
DeepState,
|
UmbDeepState,
|
||||||
ObjectState,
|
UmbObjectState,
|
||||||
StringState,
|
UmbStringState,
|
||||||
} from '@umbraco-cms/backoffice/observable-api';
|
} from '@umbraco-cms/backoffice/observable-api';
|
||||||
import {
|
import {
|
||||||
DirectionModel,
|
DirectionModel,
|
||||||
@@ -15,9 +15,11 @@ import {
|
|||||||
PagedLogMessageResponseModel,
|
PagedLogMessageResponseModel,
|
||||||
PagedLogTemplateResponseModel,
|
PagedLogTemplateResponseModel,
|
||||||
PagedSavedLogSearchResponseModel,
|
PagedSavedLogSearchResponseModel,
|
||||||
|
SavedLogSearchPresenationBaseModel,
|
||||||
} from '@umbraco-cms/backoffice/backend-api';
|
} from '@umbraco-cms/backoffice/backend-api';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||||
|
import { query } from '@umbraco-cms/backoffice/router';
|
||||||
|
|
||||||
export type PoolingInterval = 0 | 2000 | 5000 | 10000 | 20000 | 30000;
|
export type PoolingInterval = 0 | 2000 | 5000 | 10000 | 20000 | 30000;
|
||||||
export interface PoolingCOnfig {
|
export interface PoolingCOnfig {
|
||||||
@@ -56,38 +58,38 @@ export class UmbLogViewerWorkspaceContext {
|
|||||||
endDate: this.today,
|
endDate: this.today,
|
||||||
};
|
};
|
||||||
|
|
||||||
#savedSearches = new DeepState<PagedSavedLogSearchResponseModel | undefined>(undefined);
|
#savedSearches = new UmbObjectState<PagedSavedLogSearchResponseModel | undefined>(undefined);
|
||||||
savedSearches = createObservablePart(this.#savedSearches, (data) => data?.items);
|
savedSearches = createObservablePart(this.#savedSearches, (data) => data?.items);
|
||||||
|
|
||||||
#logCount = new DeepState<LogLevelCountsReponseModel | null>(null);
|
#logCount = new UmbDeepState<LogLevelCountsReponseModel | null>(null);
|
||||||
logCount = createObservablePart(this.#logCount, (data) => data);
|
logCount = createObservablePart(this.#logCount, (data) => data);
|
||||||
|
|
||||||
#dateRange = new DeepState<LogViewerDateRange>(this.defaultDateRange);
|
#dateRange = new UmbDeepState<LogViewerDateRange>(this.defaultDateRange);
|
||||||
dateRange = createObservablePart(this.#dateRange, (data) => data);
|
dateRange = createObservablePart(this.#dateRange, (data) => data);
|
||||||
|
|
||||||
#loggers = new DeepState<PagedLoggerResponseModel | null>(null);
|
#loggers = new UmbDeepState<PagedLoggerResponseModel | null>(null);
|
||||||
loggers = createObservablePart(this.#loggers, (data) => data?.items);
|
loggers = createObservablePart(this.#loggers, (data) => data?.items);
|
||||||
|
|
||||||
#canShowLogs = new BasicState<boolean | null>(null);
|
#canShowLogs = new UmbBasicState<boolean | null>(null);
|
||||||
canShowLogs = createObservablePart(this.#canShowLogs, (data) => data);
|
canShowLogs = createObservablePart(this.#canShowLogs, (data) => data);
|
||||||
|
|
||||||
#filterExpression = new StringState<string>('');
|
#filterExpression = new UmbStringState<string>('');
|
||||||
filterExpression = createObservablePart(this.#filterExpression, (data) => data);
|
filterExpression = createObservablePart(this.#filterExpression, (data) => data);
|
||||||
|
|
||||||
#messageTemplates = new DeepState<PagedLogTemplateResponseModel | null>(null);
|
#messageTemplates = new UmbDeepState<PagedLogTemplateResponseModel | null>(null);
|
||||||
messageTemplates = createObservablePart(this.#messageTemplates, (data) => data);
|
messageTemplates = createObservablePart(this.#messageTemplates, (data) => data);
|
||||||
|
|
||||||
#logLevelsFilter = new ArrayState<LogLevelModel>([]);
|
#logLevelsFilter = new UmbArrayState<LogLevelModel>([]);
|
||||||
logLevelsFilter = createObservablePart(this.#logLevelsFilter, (data) => data);
|
logLevelsFilter = createObservablePart(this.#logLevelsFilter, (data) => data);
|
||||||
|
|
||||||
#logs = new DeepState<PagedLogMessageResponseModel | null>(null);
|
#logs = new UmbDeepState<PagedLogMessageResponseModel | null>(null);
|
||||||
logs = createObservablePart(this.#logs, (data) => data?.items);
|
logs = createObservablePart(this.#logs, (data) => data?.items);
|
||||||
logsTotal = createObservablePart(this.#logs, (data) => data?.total);
|
logsTotal = createObservablePart(this.#logs, (data) => data?.total);
|
||||||
|
|
||||||
#polling = new ObjectState<PoolingCOnfig>({ enabled: false, interval: 2000 });
|
#polling = new UmbObjectState<PoolingCOnfig>({ enabled: false, interval: 2000 });
|
||||||
polling = createObservablePart(this.#polling, (data) => data);
|
polling = createObservablePart(this.#polling, (data) => data);
|
||||||
|
|
||||||
#sortingDirection = new BasicState<DirectionModel>(DirectionModel.ASCENDING);
|
#sortingDirection = new UmbBasicState<DirectionModel>(DirectionModel.ASCENDING);
|
||||||
sortingDirection = createObservablePart(this.#sortingDirection, (data) => data);
|
sortingDirection = createObservablePart(this.#sortingDirection, (data) => data);
|
||||||
|
|
||||||
#intervalID: number | null = null;
|
#intervalID: number | null = null;
|
||||||
@@ -103,8 +105,54 @@ export class UmbLogViewerWorkspaceContext {
|
|||||||
this.validateLogSize();
|
this.validateLogSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
setDateRange(dateRange: LogViewerDateRange) {
|
reset() {
|
||||||
const { startDate, endDate } = dateRange;
|
this.#logs.next({ items: [], total: 0 });
|
||||||
|
this.setCurrentPage(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
onChangeState = () => {
|
||||||
|
this.reset();
|
||||||
|
|
||||||
|
const searchQuery = query();
|
||||||
|
let sanitizedQuery = '';
|
||||||
|
if (searchQuery.lq) {
|
||||||
|
sanitizedQuery = decodeURIComponent(searchQuery.lq);
|
||||||
|
}
|
||||||
|
this.setFilterExpression(sanitizedQuery);
|
||||||
|
|
||||||
|
let validLogLevels: LogLevelModel[] = [];
|
||||||
|
if (searchQuery.loglevels) {
|
||||||
|
const loglevels = searchQuery.loglevels.split(',') as LogLevelModel[];
|
||||||
|
|
||||||
|
// Filter out invalid log levels that do not exist in LogLevelModel
|
||||||
|
validLogLevels = loglevels.filter((loglevel) => {
|
||||||
|
return Object.values(LogLevelModel).includes(loglevel);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.setLogLevelsFilter(validLogLevels);
|
||||||
|
|
||||||
|
const dateRange: Partial<LogViewerDateRange> = {};
|
||||||
|
|
||||||
|
if (searchQuery.startDate) {
|
||||||
|
dateRange.startDate = searchQuery.startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (searchQuery.endDate) {
|
||||||
|
dateRange.endDate = searchQuery.endDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setDateRange(dateRange);
|
||||||
|
|
||||||
|
this.setCurrentPage(searchQuery.page ? Number(searchQuery.page) : 1);
|
||||||
|
|
||||||
|
this.getLogs();
|
||||||
|
};
|
||||||
|
|
||||||
|
setDateRange(dateRange: Partial<LogViewerDateRange>) {
|
||||||
|
let { startDate, endDate } = dateRange;
|
||||||
|
|
||||||
|
if (!startDate) startDate = this.defaultDateRange.startDate;
|
||||||
|
if (!endDate) endDate = this.defaultDateRange.endDate;
|
||||||
|
|
||||||
const isAnyDateInTheFuture = new Date(startDate) > new Date() || new Date(endDate) > new Date();
|
const isAnyDateInTheFuture = new Date(startDate) > new Date() || new Date(endDate) > new Date();
|
||||||
const isStartDateBiggerThenEndDate = new Date(startDate) > new Date(endDate);
|
const isStartDateBiggerThenEndDate = new Date(startDate) > new Date(endDate);
|
||||||
@@ -112,9 +160,10 @@ export class UmbLogViewerWorkspaceContext {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#dateRange.next(dateRange);
|
this.#dateRange.next({ startDate, endDate });
|
||||||
this.validateLogSize();
|
this.validateLogSize();
|
||||||
this.getLogCount();
|
this.getLogCount();
|
||||||
|
this.getMessageTemplates(0, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSavedSearches() {
|
async getSavedSearches() {
|
||||||
@@ -122,7 +171,7 @@ export class UmbLogViewerWorkspaceContext {
|
|||||||
if (data) {
|
if (data) {
|
||||||
this.#savedSearches.next(data);
|
this.#savedSearches.next(data);
|
||||||
} else {
|
} else {
|
||||||
//falback to some default searches like in the old backoffice
|
//falback to some default searches resembling Umbraco <= 12
|
||||||
this.#savedSearches.next({
|
this.#savedSearches.next({
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@@ -155,6 +204,26 @@ export class UmbLogViewerWorkspaceContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async saveSearch({ name, query }: SavedLogSearchPresenationBaseModel) {
|
||||||
|
const previousSavedSearches = this.#savedSearches.getValue()?.items ?? [];
|
||||||
|
try {
|
||||||
|
this.#savedSearches.update({ items: [...previousSavedSearches, { name, query }] });
|
||||||
|
await this.#repository.saveSearch({ name, query });
|
||||||
|
} catch (err) {
|
||||||
|
this.#savedSearches.update({ items: previousSavedSearches });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeSearch({ name }: { name: string }) {
|
||||||
|
const previousSavedSearches = this.#savedSearches.getValue()?.items ?? [];
|
||||||
|
try {
|
||||||
|
this.#savedSearches.update({ items: previousSavedSearches.filter((search) => search.name !== name) });
|
||||||
|
await this.#repository.removeSearch({ name });
|
||||||
|
} catch (err) {
|
||||||
|
this.#savedSearches.update({ items: previousSavedSearches });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async getLogCount() {
|
async getLogCount() {
|
||||||
const { data } = await this.#repository.getLogCount({ ...this.#dateRange.getValue() });
|
const { data } = await this.#repository.getLogCount({ ...this.#dateRange.getValue() });
|
||||||
|
|
||||||
@@ -164,7 +233,7 @@ export class UmbLogViewerWorkspaceContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getMessageTemplates(skip: number, take: number) {
|
async getMessageTemplates(skip: number, take: number) {
|
||||||
const { data } = await this.#repository.getMessageTemplates({ skip, take });
|
const { data } = await this.#repository.getMessageTemplates({ skip, take, ...this.#dateRange.getValue() });
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
this.#messageTemplates.next(data);
|
this.#messageTemplates.next(data);
|
||||||
@@ -180,14 +249,12 @@ export class UmbLogViewerWorkspaceContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async validateLogSize() {
|
async validateLogSize() {
|
||||||
const { data, error } = await this.#repository.getLogViewerValidateLogsSize({ ...this.#dateRange.getValue() });
|
const { error } = await this.#repository.getLogViewerValidateLogsSize({ ...this.#dateRange.getValue() });
|
||||||
if (error) {
|
if (error) {
|
||||||
this.#canShowLogs.next(false);
|
this.#canShowLogs.next(false);
|
||||||
console.info('LogViewer: ', error);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.#canShowLogs.next(true);
|
this.#canShowLogs.next(true);
|
||||||
console.info('LogViewer:showinfg logs');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setCurrentPage(page: number) {
|
setCurrentPage(page: number) {
|
||||||
@@ -244,7 +311,7 @@ export class UmbLogViewerWorkspaceContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setPollingInterval(interval: PoolingInterval) {
|
setPollingInterval(interval: PoolingInterval) {
|
||||||
this.#polling.update({ interval, enabled: true });
|
this.#polling.update({ interval });
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleSortOrder() {
|
toggleSortOrder() {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { html } from 'lit';
|
import { html, nothing } from 'lit';
|
||||||
import { customElement, property, state } from 'lit/decorators.js';
|
import { customElement, property, state } from 'lit/decorators.js';
|
||||||
import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../../logviewer.context';
|
import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../../logviewer.context';
|
||||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||||
@@ -37,7 +37,7 @@ export class UmbLogViewerLogLevelOverviewElement extends UmbLitElement {
|
|||||||
render() {
|
render() {
|
||||||
return html`${this._loggers.length > 0
|
return html`${this._loggers.length > 0
|
||||||
? this._loggers.find((logger) => logger.name === this.loggerName)?.level
|
? this._loggers.find((logger) => logger.name === this.loggerName)?.level
|
||||||
: ''}`;
|
: nothing}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,14 +66,11 @@ export class UmbLogViewerMessageTemplatesOverviewElement extends UmbLitElement {
|
|||||||
#renderSearchItem = (searchListItem: SavedLogSearchResponseModel) => {
|
#renderSearchItem = (searchListItem: SavedLogSearchResponseModel) => {
|
||||||
return html` <li>
|
return html` <li>
|
||||||
<uui-button
|
<uui-button
|
||||||
@click=${() => {
|
|
||||||
this.#setCurrentQuery(searchListItem.query ?? '');
|
|
||||||
}}
|
|
||||||
label="${searchListItem.name ?? ''}"
|
label="${searchListItem.name ?? ''}"
|
||||||
title="${searchListItem.name ?? ''}"
|
title="${searchListItem.name ?? ''}"
|
||||||
href=${'/section/settings/logviewer/search?lq=' + searchListItem.query}
|
href=${`section/settings/workspace/logviewer/search/?lq=${searchListItem.query}`}>
|
||||||
><uui-icon name="umb:search"></uui-icon>${searchListItem.name}</uui-button
|
<uui-icon name="umb:search"></uui-icon>${searchListItem.name}
|
||||||
>
|
</uui-button>
|
||||||
</li>`;
|
</li>`;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -90,13 +87,12 @@ export class UmbLogViewerMessageTemplatesOverviewElement extends UmbLitElement {
|
|||||||
${this._messageTemplates
|
${this._messageTemplates
|
||||||
? this._messageTemplates.items.map(
|
? this._messageTemplates.items.map(
|
||||||
(template) =>
|
(template) =>
|
||||||
html`<uui-table-row
|
html`<uui-table-row>
|
||||||
><uui-table-cell>
|
<uui-table-cell>
|
||||||
<a
|
<a
|
||||||
@click=${() => {
|
href=${`section/settings/workspace/logviewer/search/?lq=${encodeURIComponent(
|
||||||
this.#setCurrentQuery(`@MessageTemplate='${template.messageTemplate}'` ?? '');
|
`@MessageTemplate='${template.messageTemplate}'`
|
||||||
}}
|
)}`}>
|
||||||
href=${'/section/settings/logviewer/search?lg=@MessageTemplate%3D' + template.messageTemplate}>
|
|
||||||
<span>${template.messageTemplate}</span> <span>${template.count}</span>
|
<span>${template.messageTemplate}</span> <span>${template.count}</span>
|
||||||
</a>
|
</a>
|
||||||
</uui-table-cell>
|
</uui-table-cell>
|
||||||
@@ -109,9 +105,9 @@ export class UmbLogViewerMessageTemplatesOverviewElement extends UmbLitElement {
|
|||||||
id="show-more-templates-btn"
|
id="show-more-templates-btn"
|
||||||
look="primary"
|
look="primary"
|
||||||
@click=${this.#getMessageTemplates}
|
@click=${this.#getMessageTemplates}
|
||||||
label="Show more templates"
|
label="Show more templates">
|
||||||
>Show more</uui-button
|
Show more
|
||||||
>
|
</uui-button>
|
||||||
</uui-box>
|
</uui-box>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ export class UmbLogViewerSavedSearchesOverviewElement extends UmbLitElement {
|
|||||||
private _savedSearches: SavedLogSearchResponseModel[] = [];
|
private _savedSearches: SavedLogSearchResponseModel[] = [];
|
||||||
|
|
||||||
#logViewerContext?: UmbLogViewerWorkspaceContext;
|
#logViewerContext?: UmbLogViewerWorkspaceContext;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.consumeContext(UMB_APP_LOG_VIEWER_CONTEXT_TOKEN, (instance) => {
|
this.consumeContext(UMB_APP_LOG_VIEWER_CONTEXT_TOKEN, (instance) => {
|
||||||
@@ -56,39 +57,21 @@ export class UmbLogViewerSavedSearchesOverviewElement extends UmbLitElement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#setCurrentQuery(query: string) {
|
|
||||||
this.#logViewerContext?.setFilterExpression(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
#renderSearchItem = (searchListItem: SavedLogSearchResponseModel) => {
|
#renderSearchItem = (searchListItem: SavedLogSearchResponseModel) => {
|
||||||
return html` <li>
|
return html` <li>
|
||||||
<uui-button
|
<uui-button
|
||||||
@click=${() => {
|
|
||||||
this.#setCurrentQuery(searchListItem.query ?? '');
|
|
||||||
}}
|
|
||||||
label="${searchListItem.name ?? ''}"
|
label="${searchListItem.name ?? ''}"
|
||||||
title="${searchListItem.name ?? ''}"
|
title="${searchListItem.name ?? ''}"
|
||||||
href=${'/section/settings/logviewer/search?lq=' + searchListItem.query}
|
href=${`section/settings/workspace/logviewer/search/?lq=${encodeURIComponent(searchListItem.query ?? '')}`}>
|
||||||
><uui-icon name="umb:search"></uui-icon>${searchListItem.name}</uui-button
|
<uui-icon name="umb:search"></uui-icon>${searchListItem.name}
|
||||||
>
|
</uui-button>
|
||||||
</li>`;
|
</li>`;
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html` <uui-box id="saved-searches" headline="Saved searches">
|
return html` <uui-box id="saved-searches" headline="Saved searches">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
${this.#renderSearchItem({ name: 'All logs', query: '' })} ${this._savedSearches.map(this.#renderSearchItem)}
|
||||||
<uui-button
|
|
||||||
@click=${() => {
|
|
||||||
this.#setCurrentQuery('');
|
|
||||||
}}
|
|
||||||
label="All logs"
|
|
||||||
title="All logs"
|
|
||||||
href="/section/settings/logviewer/search"
|
|
||||||
><uui-icon name="umb:search"></uui-icon>All logs</uui-button
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
${this._savedSearches.map(this.#renderSearchItem)}
|
|
||||||
</ul>
|
</ul>
|
||||||
</uui-box>`;
|
</uui-box>`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,8 +107,8 @@ export class UmbLogViewerOverviewViewElement extends UmbLitElement {
|
|||||||
#observeErrorCount() {
|
#observeErrorCount() {
|
||||||
if (!this.#logViewerContext) return;
|
if (!this.#logViewerContext) return;
|
||||||
|
|
||||||
this.observe(this.#logViewerContext.logCount, () => {
|
this.observe(this.#logViewerContext.logCount, (logLevelCount) => {
|
||||||
this._errorCount = this._logLevelCount?.error ?? 0;
|
this._errorCount = logLevelCount?.error ?? 0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +128,13 @@ export class UmbLogViewerOverviewViewElement extends UmbLitElement {
|
|||||||
</uui-box>
|
</uui-box>
|
||||||
|
|
||||||
<uui-box id="errors" headline="Number of Errors">
|
<uui-box id="errors" headline="Number of Errors">
|
||||||
<h1 id="error-count">${this._errorCount}</h1>
|
<uui-button
|
||||||
|
label="Show error logs"
|
||||||
|
href=${`section/settings/workspace/logviewer/search/?lq=${encodeURIComponent(
|
||||||
|
`@Level='Fatal' or @Level='Error' or Has(@Exception)`
|
||||||
|
)}`}>
|
||||||
|
<h1 id="error-count">${this._errorCount}</h1></uui-button
|
||||||
|
>
|
||||||
</uui-box>
|
</uui-box>
|
||||||
|
|
||||||
<uui-box id="level" headline="Log level">
|
<uui-box id="level" headline="Log level">
|
||||||
|
|||||||
@@ -2,10 +2,11 @@ import { UUICheckboxElement } from '@umbraco-ui/uui';
|
|||||||
import { UUITextStyles } from '@umbraco-ui/uui-css';
|
import { UUITextStyles } from '@umbraco-ui/uui-css';
|
||||||
import { css, html } from 'lit';
|
import { css, html } from 'lit';
|
||||||
import { customElement, queryAll, state } from 'lit/decorators.js';
|
import { customElement, queryAll, state } from 'lit/decorators.js';
|
||||||
import _ from 'lodash';
|
import { debounce } from 'lodash-es';
|
||||||
import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../../logviewer.context';
|
import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../../logviewer.context';
|
||||||
import { LogLevelModel } from '@umbraco-cms/backoffice/backend-api';
|
import { LogLevelModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||||
|
import { path, query, toQueryString } from '@umbraco-cms/backoffice/router';
|
||||||
|
|
||||||
@customElement('umb-log-viewer-log-level-filter-menu')
|
@customElement('umb-log-viewer-log-level-filter-menu')
|
||||||
export class UmbLogViewerLogLevelFilterMenuElement extends UmbLitElement {
|
export class UmbLogViewerLogLevelFilterMenuElement extends UmbLitElement {
|
||||||
@@ -58,16 +59,23 @@ export class UmbLogViewerLogLevelFilterMenuElement extends UmbLitElement {
|
|||||||
|
|
||||||
#setLogLevel() {
|
#setLogLevel() {
|
||||||
if (!this.#logViewerContext) return;
|
if (!this.#logViewerContext) return;
|
||||||
this.#logViewerContext?.setCurrentPage(1);
|
|
||||||
|
|
||||||
const logLevels = Array.from(this._logLevelSelectorCheckboxes)
|
const logLevels = Array.from(this._logLevelSelectorCheckboxes)
|
||||||
.filter((checkbox) => checkbox.checked)
|
.filter((checkbox) => checkbox.checked)
|
||||||
.map((checkbox) => checkbox.value as LogLevelModel);
|
.map((checkbox) => checkbox.value as LogLevelModel);
|
||||||
this.#logViewerContext?.setLogLevelsFilter(logLevels);
|
|
||||||
this.#logViewerContext.getLogs();
|
let q = query();
|
||||||
|
|
||||||
|
if (logLevels.length) {
|
||||||
|
q = { ...q, loglevels: logLevels.join(',') };
|
||||||
|
} else {
|
||||||
|
delete q.loglevels;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.history.pushState({}, '', `${path()}?${toQueryString(q)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
setLogLevelDebounce = _.debounce(this.#setLogLevel, 300);
|
setLogLevelDebounce = debounce(this.#setLogLevel, 300);
|
||||||
|
|
||||||
#selectAllLogLevels() {
|
#selectAllLogLevels() {
|
||||||
this._logLevelSelectorCheckboxes.forEach((checkbox) => (checkbox.checked = true));
|
this._logLevelSelectorCheckboxes.forEach((checkbox) => (checkbox.checked = true));
|
||||||
@@ -84,9 +92,13 @@ export class UmbLogViewerLogLevelFilterMenuElement extends UmbLitElement {
|
|||||||
<div slot="dropdown" id="log-level-selector" @change=${this.setLogLevelDebounce}>
|
<div slot="dropdown" id="log-level-selector" @change=${this.setLogLevelDebounce}>
|
||||||
${Object.values(LogLevelModel).map(
|
${Object.values(LogLevelModel).map(
|
||||||
(logLevel) =>
|
(logLevel) =>
|
||||||
html`<uui-checkbox class="log-level-menu-item" .value=${logLevel} label="${logLevel}"
|
html`<uui-checkbox
|
||||||
><umb-log-viewer-level-tag .level=${logLevel}></umb-log-viewer-level-tag
|
class="log-level-menu-item"
|
||||||
></uui-checkbox>`
|
.checked=${this._logLevelFilter.includes(logLevel)}
|
||||||
|
.value=${logLevel}
|
||||||
|
label="${logLevel}">
|
||||||
|
<umb-log-viewer-level-tag .level=${logLevel}></umb-log-viewer-level-tag>
|
||||||
|
</uui-checkbox>`
|
||||||
)}
|
)}
|
||||||
<uui-button class="log-level-menu-item" @click=${this.#selectAllLogLevels} label="Select all"
|
<uui-button class="log-level-menu-item" @click=${this.#selectAllLogLevels} label="Select all"
|
||||||
>Select all</uui-button
|
>Select all</uui-button
|
||||||
@@ -100,8 +112,8 @@ export class UmbLogViewerLogLevelFilterMenuElement extends UmbLitElement {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<umb-button-with-dropdown label="Select log levels"
|
<umb-button-with-dropdown label="Select log levels">
|
||||||
>Log Level:
|
Log Level:
|
||||||
${this._logLevelFilter.length > 0
|
${this._logLevelFilter.length > 0
|
||||||
? this._logLevelFilter.map((level) => html`<span class="log-level-button-indicator">${level}</span>`)
|
? this._logLevelFilter.map((level) => html`<span class="log-level-button-indicator">${level}</span>`)
|
||||||
: 'All'}
|
: 'All'}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { customElement, property, query, state } from 'lit/decorators.js';
|
|||||||
import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../../logviewer.context';
|
import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../../logviewer.context';
|
||||||
import { LogLevelModel, LogMessagePropertyPresentationModel } from '@umbraco-cms/backoffice/backend-api';
|
import { LogLevelModel, LogMessagePropertyPresentationModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||||
|
import { query as getQuery, toQueryString } from '@umbraco-cms/backoffice/router';
|
||||||
|
|
||||||
//TODO: check how to display EventId field in the message properties
|
//TODO: check how to display EventId field in the message properties
|
||||||
@customElement('umb-log-viewer-message')
|
@customElement('umb-log-viewer-message')
|
||||||
@@ -211,18 +212,23 @@ export class UmbLogViewerMessageElement extends UmbLitElement {
|
|||||||
private _propertiesWithSearchMenu: Array<string> = ['HttpRequestNumber', 'SourceContext', 'MachineName'];
|
private _propertiesWithSearchMenu: Array<string> = ['HttpRequestNumber', 'SourceContext', 'MachineName'];
|
||||||
|
|
||||||
private _findLogsWithProperty({ name, value }: LogMessagePropertyPresentationModel) {
|
private _findLogsWithProperty({ name, value }: LogMessagePropertyPresentationModel) {
|
||||||
let queryString = '';
|
if (!name) return '';
|
||||||
|
|
||||||
|
let query = getQuery();
|
||||||
|
let sanitizedValue = value ?? '';
|
||||||
|
|
||||||
if (isNaN(+(value ?? ''))) {
|
if (isNaN(+(value ?? ''))) {
|
||||||
queryString = name + "='" + value + "'";
|
sanitizedValue = "'" + value + "'";
|
||||||
} else {
|
|
||||||
queryString = name + '=' + value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#logViewerContext?.setFilterExpression(queryString);
|
query = {
|
||||||
this.#logViewerContext?.setCurrentPage(1);
|
...query,
|
||||||
this.details.removeAttribute('open');
|
lq: encodeURIComponent(`${name}=${sanitizedValue}`),
|
||||||
this.#logViewerContext?.getLogs();
|
};
|
||||||
|
|
||||||
|
const queryString = toQueryString(query);
|
||||||
|
|
||||||
|
return queryString;
|
||||||
}
|
}
|
||||||
|
|
||||||
#setOpen(event: Event) {
|
#setOpen(event: Event) {
|
||||||
@@ -259,14 +265,12 @@ export class UmbLogViewerMessageElement extends UmbLitElement {
|
|||||||
${this._propertiesWithSearchMenu.includes(property.name ?? '')
|
${this._propertiesWithSearchMenu.includes(property.name ?? '')
|
||||||
? html`<uui-button
|
? html`<uui-button
|
||||||
compact
|
compact
|
||||||
@click=${() => {
|
|
||||||
this._findLogsWithProperty(property);
|
|
||||||
}}
|
|
||||||
look="secondary"
|
look="secondary"
|
||||||
label="Find logs with ${property.name}"
|
label="Find logs with ${property.name}"
|
||||||
title="Find logs with ${property.name}"
|
title="Find logs with ${property.name}"
|
||||||
><uui-icon name="umb:search"></uui-icon
|
href=${`section/settings/workspace/logviewer/search/?${this._findLogsWithProperty(property)}`}>
|
||||||
></uui-button>`
|
<uui-icon name="umb:search"></uui-icon>
|
||||||
|
</uui-button>`
|
||||||
: ''}
|
: ''}
|
||||||
</div>
|
</div>
|
||||||
</li>`
|
</li>`
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ export class UmbLogViewerMessagesListElement extends UmbLitElement {
|
|||||||
static styles = [
|
static styles = [
|
||||||
UUITextStyles,
|
UUITextStyles,
|
||||||
css`
|
css`
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
#message-list-header {
|
#message-list-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
@@ -129,23 +132,21 @@ export class UmbLogViewerMessagesListElement extends UmbLitElement {
|
|||||||
<div id="machine">Machine name</div>
|
<div id="machine">Machine name</div>
|
||||||
<div id="message">Message</div>
|
<div id="message">Message</div>
|
||||||
</div>
|
</div>
|
||||||
<uui-scroll-container id="logs-scroll-container" style="max-height: calc(100vh - 490px)">
|
${this._logs.length > 0
|
||||||
${this._logs.length > 0
|
? html` ${this._logs.map(
|
||||||
? html` ${this._logs.map(
|
(log) => html`<umb-log-viewer-message
|
||||||
(log) => html`<umb-log-viewer-message
|
.timestamp=${log.timestamp ?? ''}
|
||||||
.timestamp=${log.timestamp ?? ''}
|
.level=${log.level ?? ''}
|
||||||
.level=${log.level ?? ''}
|
.renderedMessage=${log.renderedMessage ?? ''}
|
||||||
.renderedMessage=${log.renderedMessage ?? ''}
|
.properties=${log.properties ?? []}
|
||||||
.properties=${log.properties ?? []}
|
.exception=${log.exception ?? ''}
|
||||||
.exception=${log.exception ?? ''}
|
.messageTemplate=${log.messageTemplate ?? ''}></umb-log-viewer-message>`
|
||||||
.messageTemplate=${log.messageTemplate ?? ''}></umb-log-viewer-message>`
|
)}`
|
||||||
)}`
|
: html`<umb-empty-state size="small"
|
||||||
: html`<umb-empty-state size="small"
|
><span id="empty">
|
||||||
><span id="empty">
|
<uui-icon name="umb:search"></uui-icon>Sorry, we cannot find what you are looking for.
|
||||||
<uui-icon name="umb:search"></uui-icon>Sorry, we cannot find what you are looking for.
|
</span></umb-empty-state
|
||||||
</span></umb-empty-state
|
>`}
|
||||||
>`}
|
|
||||||
</uui-scroll-container>
|
|
||||||
${this._renderPagination()}
|
${this._renderPagination()}
|
||||||
</uui-box>`;
|
</uui-box>`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,10 +90,11 @@ export class UmbLogViewerPollingButtonElement extends UmbLitElement {
|
|||||||
this.#logViewerContext?.togglePolling();
|
this.#logViewerContext?.togglePolling();
|
||||||
}
|
}
|
||||||
|
|
||||||
#setPolingInterval(interval: PoolingInterval) {
|
#setPolingInterval = (interval: PoolingInterval) => {
|
||||||
this.#logViewerContext?.setPollingInterval(interval);
|
this.#logViewerContext?.setPollingInterval(interval);
|
||||||
|
|
||||||
this.#closePoolingPopover();
|
this.#closePoolingPopover();
|
||||||
}
|
};
|
||||||
|
|
||||||
#openPoolingPopover() {
|
#openPoolingPopover() {
|
||||||
this._pollingPopover.open = true;
|
this._pollingPopover.open = true;
|
||||||
@@ -103,6 +104,7 @@ export class UmbLogViewerPollingButtonElement extends UmbLitElement {
|
|||||||
#closePoolingPopover() {
|
#closePoolingPopover() {
|
||||||
this._pollingPopover.open = false;
|
this._pollingPopover.open = false;
|
||||||
this._polingExpandSymbol.open = false;
|
this._polingExpandSymbol.open = false;
|
||||||
|
this.#togglePolling();
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -111,7 +113,7 @@ export class UmbLogViewerPollingButtonElement extends UmbLitElement {
|
|||||||
>${this._poolingConfig.enabled
|
>${this._poolingConfig.enabled
|
||||||
? html`<uui-icon name="umb:axis-rotation" id="polling-enabled-icon"></uui-icon>Polling
|
? html`<uui-icon name="umb:axis-rotation" id="polling-enabled-icon"></uui-icon>Polling
|
||||||
${this._poolingConfig.interval / 1000} seconds`
|
${this._poolingConfig.interval / 1000} seconds`
|
||||||
: 'Pooling'}</uui-button
|
: 'Polling'}</uui-button
|
||||||
>
|
>
|
||||||
<uui-popover placement="bottom-end" id="polling-popover" @close=${() => (this._polingExpandSymbol.open = false)}>
|
<uui-popover placement="bottom-end" id="polling-popover" @close=${() => (this._polingExpandSymbol.open = false)}>
|
||||||
<uui-button slot="trigger" compact label="Choose pooling time" @click=${this.#openPoolingPopover}>
|
<uui-button slot="trigger" compact label="Choose pooling time" @click=${this.#openPoolingPopover}>
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import { html, css } from 'lit';
|
||||||
|
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||||
|
import { customElement, query, state } from 'lit/decorators.js';
|
||||||
|
import { UmbModalBaseElement } from '@umbraco-cms/internal/modal';
|
||||||
|
import { SavedLogSearchPresenationBaseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
|
import { UUIInputElement } from '@umbraco-ui/uui';
|
||||||
|
|
||||||
|
@customElement('umb-log-viewer-save-search-modal')
|
||||||
|
export default class UmbLogViewerSaveSearchModalElement extends UmbModalBaseElement<
|
||||||
|
{ query: string },
|
||||||
|
SavedLogSearchPresenationBaseModel
|
||||||
|
> {
|
||||||
|
static styles = [
|
||||||
|
UUITextStyles,
|
||||||
|
css`
|
||||||
|
uui-input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
|
||||||
|
@query('uui-input')
|
||||||
|
private _input!: UUIInputElement;
|
||||||
|
|
||||||
|
private _handleClose() {
|
||||||
|
this.modalHandler?.reject();
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleSubmit() {
|
||||||
|
this.modalHandler?.submit({ name: this._input.value as string, query: this.data?.query });
|
||||||
|
}
|
||||||
|
|
||||||
|
@state()
|
||||||
|
private _hasValue = false;
|
||||||
|
|
||||||
|
#validate(event: Event) {
|
||||||
|
const target = event.target as UUIInputElement;
|
||||||
|
this._hasValue = (target.value as string).length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<uui-dialog-layout headline="Save Search">
|
||||||
|
<span>Enter a friendly name for your search query</span>
|
||||||
|
<uui-form-layout-item>
|
||||||
|
<uui-label slot="label">Query:</uui-label>
|
||||||
|
<span>${this.data?.query}</span>
|
||||||
|
</uui-form-layout-item>
|
||||||
|
<uui-form-layout-item>
|
||||||
|
<uui-label slot="label" for="input">Name:</uui-label>
|
||||||
|
<uui-input label="Search name" id="input" @input=${this.#validate}></uui-input>
|
||||||
|
</uui-form-layout-item>
|
||||||
|
|
||||||
|
<uui-button slot="actions" @click="${this._handleClose}" label="Close dialog">Close</uui-button>
|
||||||
|
<uui-button
|
||||||
|
.disabled=${!this._hasValue}
|
||||||
|
slot="actions"
|
||||||
|
look="primary"
|
||||||
|
color="positive"
|
||||||
|
label="Save search"
|
||||||
|
@click="${this._handleSubmit}"
|
||||||
|
>Save</uui-button
|
||||||
|
>
|
||||||
|
</uui-dialog-layout>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
'umb-log-viewer-save-search-modal': UmbLogViewerSaveSearchModalElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,31 @@
|
|||||||
import { UUIInputElement, UUIPopoverElement, UUISymbolExpandElement } from '@umbraco-ui/uui';
|
import { UUIButtonElement, UUIInputElement, UUIPopoverElement, UUISymbolExpandElement } from '@umbraco-ui/uui';
|
||||||
import { UUITextStyles } from '@umbraco-ui/uui-css';
|
import { UUITextStyles } from '@umbraco-ui/uui-css';
|
||||||
import { css, html } from 'lit';
|
import { css, html } from 'lit';
|
||||||
import { customElement, query, state } from 'lit/decorators.js';
|
import { customElement, query, state } from 'lit/decorators.js';
|
||||||
|
import { Subject, debounceTime, tap } from 'rxjs';
|
||||||
import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../../logviewer.context';
|
import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../../logviewer.context';
|
||||||
import { SavedLogSearchResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
import { SavedLogSearchResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||||
|
import { query as getQuery, path, toQueryString } from '@umbraco-cms/backoffice/router';
|
||||||
|
import {
|
||||||
|
UMB_MODAL_CONTEXT_TOKEN,
|
||||||
|
UmbModalContext,
|
||||||
|
UmbModalHandler,
|
||||||
|
UmbModalToken,
|
||||||
|
} from '@umbraco-cms/backoffice/modal';
|
||||||
|
|
||||||
|
import './log-viewer-search-input-modal.element';
|
||||||
|
export interface UmbContextSaveSearchModalData {
|
||||||
|
query: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const UMB_LOG_VIEWER_SAVE_SEARCH_MODAL = new UmbModalToken<UmbContextSaveSearchModalData>(
|
||||||
|
'Umb.Modal.LogViewer.SaveSearch',
|
||||||
|
{
|
||||||
|
type: 'dialog',
|
||||||
|
size: 'small',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
@customElement('umb-log-viewer-search-input')
|
@customElement('umb-log-viewer-search-input')
|
||||||
export class UmbLogViewerSearchInputElement extends UmbLitElement {
|
export class UmbLogViewerSearchInputElement extends UmbLitElement {
|
||||||
@@ -37,6 +58,13 @@ export class UmbLogViewerSearchInputElement extends UmbLitElement {
|
|||||||
box-shadow: var(--uui-shadow-depth-1);
|
box-shadow: var(--uui-shadow-depth-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#loader-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0 var(--uui-size-space-4);
|
||||||
|
}
|
||||||
|
|
||||||
.saved-search-item {
|
.saved-search-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@@ -92,15 +120,38 @@ export class UmbLogViewerSearchInputElement extends UmbLitElement {
|
|||||||
@state()
|
@state()
|
||||||
private _inputQuery = '';
|
private _inputQuery = '';
|
||||||
|
|
||||||
|
@state()
|
||||||
|
private _showLoader = false;
|
||||||
|
|
||||||
|
private inputQuery$ = new Subject<string>();
|
||||||
|
|
||||||
#logViewerContext?: UmbLogViewerWorkspaceContext;
|
#logViewerContext?: UmbLogViewerWorkspaceContext;
|
||||||
|
|
||||||
|
private _modalContext?: UmbModalContext;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.consumeContext(UMB_APP_LOG_VIEWER_CONTEXT_TOKEN, (instance) => {
|
this.consumeContext(UMB_APP_LOG_VIEWER_CONTEXT_TOKEN, (instance) => {
|
||||||
this.#logViewerContext = instance;
|
this.#logViewerContext = instance;
|
||||||
this.#observeStuff();
|
this.#observeStuff();
|
||||||
|
this.#logViewerContext?.getSavedSearches();
|
||||||
this.#logViewerContext.getLogs();
|
this.#logViewerContext.getLogs();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => {
|
||||||
|
this._modalContext = instance;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.inputQuery$
|
||||||
|
.pipe(
|
||||||
|
tap(() => (this._showLoader = true)),
|
||||||
|
debounceTime(250)
|
||||||
|
)
|
||||||
|
.subscribe((query) => {
|
||||||
|
this.#logViewerContext?.setFilterExpression(query);
|
||||||
|
this.#persist(query);
|
||||||
|
this._showLoader = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#observeStuff() {
|
#observeStuff() {
|
||||||
@@ -129,36 +180,54 @@ export class UmbLogViewerSearchInputElement extends UmbLitElement {
|
|||||||
|
|
||||||
#setQuery(event: Event) {
|
#setQuery(event: Event) {
|
||||||
const target = event.target as UUIInputElement;
|
const target = event.target as UUIInputElement;
|
||||||
this._inputQuery = target.value as string;
|
this.inputQuery$.next(target.value as string);
|
||||||
this.#logViewerContext?.setFilterExpression(this._inputQuery);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#setQueryFromSavedSearch(query: string) {
|
#setQueryFromSavedSearch(query: string) {
|
||||||
this._inputQuery = query;
|
this.inputQuery$.next(query);
|
||||||
this.#logViewerContext?.setFilterExpression(query);
|
|
||||||
this.#logViewerContext?.setCurrentPage(1);
|
|
||||||
|
|
||||||
this.#logViewerContext?.getLogs();
|
|
||||||
this._savedSearchesPopover.open = false;
|
this._savedSearchesPopover.open = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#persist(filter: string) {
|
||||||
|
let q = getQuery();
|
||||||
|
|
||||||
|
q = {
|
||||||
|
...q,
|
||||||
|
lq: filter,
|
||||||
|
};
|
||||||
|
|
||||||
|
window.history.pushState({}, '', `${path()}?${toQueryString(q)}`);
|
||||||
|
}
|
||||||
|
|
||||||
#clearQuery() {
|
#clearQuery() {
|
||||||
this._inputQuery = '';
|
this.inputQuery$.next('');
|
||||||
this.#logViewerContext?.setFilterExpression('');
|
this.#logViewerContext?.setFilterExpression('');
|
||||||
this.#logViewerContext?.getLogs();
|
this.#logViewerContext?.getLogs();
|
||||||
}
|
}
|
||||||
|
|
||||||
#search() {
|
#modalHandler?: UmbModalHandler;
|
||||||
this.#logViewerContext?.setCurrentPage(1);
|
|
||||||
|
|
||||||
this.#logViewerContext?.getLogs();
|
#saveSearch(savedSearch: SavedLogSearchResponseModel) {
|
||||||
|
this.#logViewerContext?.saveSearch(savedSearch);
|
||||||
|
}
|
||||||
|
|
||||||
|
#removeSearch(event: Event) {
|
||||||
|
const target = event.target as UUIButtonElement;
|
||||||
|
this.#logViewerContext?.removeSearch({ name: target.id });
|
||||||
|
}
|
||||||
|
|
||||||
|
#openSaveSearchDialog() {
|
||||||
|
this.#modalHandler = this._modalContext?.open(UMB_LOG_VIEWER_SAVE_SEARCH_MODAL, { query: this._inputQuery });
|
||||||
|
this.#modalHandler?.onSubmit().then((savedSearch) => {
|
||||||
|
if (savedSearch) {
|
||||||
|
this.#saveSearch(savedSearch);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html` <uui-popover
|
return html`
|
||||||
placement="bottom-start"
|
<uui-popover placement="bottom-start" id="saved-searches-popover" @close=${this.#toggleSavedSearchesExpandSymbol}>
|
||||||
id="saved-searches-popover"
|
|
||||||
@close=${this.#toggleSavedSearchesExpandSymbol}>
|
|
||||||
<uui-input
|
<uui-input
|
||||||
id="search-input"
|
id="search-input"
|
||||||
label="Search logs"
|
label="Search logs"
|
||||||
@@ -166,8 +235,13 @@ export class UmbLogViewerSearchInputElement extends UmbLitElement {
|
|||||||
slot="trigger"
|
slot="trigger"
|
||||||
@input=${this.#setQuery}
|
@input=${this.#setQuery}
|
||||||
.value=${this._inputQuery}>
|
.value=${this._inputQuery}>
|
||||||
|
${this._showLoader
|
||||||
|
? html`<div id="loader-container" slot="append">
|
||||||
|
<uui-loader-circle></uui-loader-circle>
|
||||||
|
</div>`
|
||||||
|
: ''}
|
||||||
${this._inputQuery
|
${this._inputQuery
|
||||||
? html`<uui-button compact slot="append" label="Save search"
|
? html`<uui-button compact slot="append" label="Save search" @click=${this.#openSaveSearchDialog}
|
||||||
><uui-icon name="umb:favorite"></uui-icon></uui-button
|
><uui-icon name="umb:favorite"></uui-icon></uui-button
|
||||||
><uui-button compact slot="append" label="Clear" @click=${this.#clearQuery}
|
><uui-button compact slot="append" label="Clear" @click=${this.#clearQuery}
|
||||||
><uui-icon name="umb:delete"></uui-icon
|
><uui-icon name="umb:delete"></uui-icon
|
||||||
@@ -193,14 +267,14 @@ export class UmbLogViewerSearchInputElement extends UmbLitElement {
|
|||||||
@click=${() => this.#setQueryFromSavedSearch(search.query ?? '')}>
|
@click=${() => this.#setQueryFromSavedSearch(search.query ?? '')}>
|
||||||
<span class="saved-search-item-name">${search.name}</span>
|
<span class="saved-search-item-name">${search.name}</span>
|
||||||
<span class="saved-search-item-query">${search.query}</span></button
|
<span class="saved-search-item-query">${search.query}</span></button
|
||||||
><uui-button label="Remove saved search" color="danger"
|
><uui-button label="Remove saved search" id="${search.name}" color="danger" @click=${this.#removeSearch}
|
||||||
><uui-icon name="umb:trash"></uui-icon
|
><uui-icon name="umb:trash"></uui-icon
|
||||||
></uui-button>
|
></uui-button>
|
||||||
</li>`
|
</li>`
|
||||||
)}
|
)}
|
||||||
</uui-scroll-container>
|
</uui-scroll-container>
|
||||||
</uui-popover>
|
</uui-popover>
|
||||||
<uui-button look="primary" @click=${this.#search} label="Search">Search</uui-button>`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { css, html } from 'lit';
|
|||||||
import { customElement, state } from 'lit/decorators.js';
|
import { customElement, state } from 'lit/decorators.js';
|
||||||
import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../logviewer.context';
|
import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../logviewer.context';
|
||||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||||
|
import type { UmbObserverController } from '@umbraco-cms/backoffice/observable-api';
|
||||||
|
|
||||||
@customElement('umb-log-viewer-search-view')
|
@customElement('umb-log-viewer-search-view')
|
||||||
export class UmbLogViewerSearchViewElement extends UmbLitElement {
|
export class UmbLogViewerSearchViewElement extends UmbLitElement {
|
||||||
@@ -11,6 +12,7 @@ export class UmbLogViewerSearchViewElement extends UmbLitElement {
|
|||||||
css`
|
css`
|
||||||
#layout {
|
#layout {
|
||||||
margin: 20px;
|
margin: 20px;
|
||||||
|
padding-bottom: 20px;
|
||||||
}
|
}
|
||||||
#levels-container,
|
#levels-container,
|
||||||
#input-container {
|
#input-container {
|
||||||
@@ -44,6 +46,9 @@ export class UmbLogViewerSearchViewElement extends UmbLitElement {
|
|||||||
private _canShowLogs = false;
|
private _canShowLogs = false;
|
||||||
|
|
||||||
#logViewerContext?: UmbLogViewerWorkspaceContext;
|
#logViewerContext?: UmbLogViewerWorkspaceContext;
|
||||||
|
|
||||||
|
#canShowLogsObserver?: UmbObserverController<boolean | null>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.consumeContext(UMB_APP_LOG_VIEWER_CONTEXT_TOKEN, (instance) => {
|
this.consumeContext(UMB_APP_LOG_VIEWER_CONTEXT_TOKEN, (instance) => {
|
||||||
@@ -53,8 +58,10 @@ export class UmbLogViewerSearchViewElement extends UmbLitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#observeCanShowLogs() {
|
#observeCanShowLogs() {
|
||||||
|
if (this.#canShowLogsObserver) this.#canShowLogsObserver.destroy();
|
||||||
if (!this.#logViewerContext) return;
|
if (!this.#logViewerContext) return;
|
||||||
this.observe(this.#logViewerContext.canShowLogs, (canShowLogs) => {
|
|
||||||
|
this.#canShowLogsObserver = this.observe(this.#logViewerContext.canShowLogs, (canShowLogs) => {
|
||||||
this._canShowLogs = canShowLogs ?? false;
|
this._canShowLogs = canShowLogs ?? false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { UmbRelationTypeTreeStore, UMB_RELATION_TYPE_TREE_STORE_CONTEXT_TOKEN } from './relation-type.tree.store';
|
import { UmbRelationTypeTreeStore, UMB_RELATION_TYPE_TREE_STORE_CONTEXT_TOKEN } from './relation-type.tree.store';
|
||||||
import { UmbRelationTypeServerDataSource } from './sources/relation-type.server.data';
|
import { UmbRelationTypeServerDataSource } from './sources/relation-type.server.data';
|
||||||
import { UmbRelationTypeStore, UMB_RELATION_TYPE_STORE_CONTEXT_TOKEN } from './relation-type.store';
|
import { UmbRelationTypeStore, UMB_RELATION_TYPE_STORE_CONTEXT_TOKEN } from './relation-type.store';
|
||||||
import { RelationTypeTreeServerDataSource } from './sources/relation-type.tree.server.data';
|
import { UmbRelationTypeTreeServerDataSource } from './sources/relation-type.tree.server.data';
|
||||||
import { RelationTypeTreeDataSource } from './sources';
|
import { UmbRelationTypeTreeDataSource } from './sources';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
|
||||||
import {
|
import {
|
||||||
@@ -23,7 +23,7 @@ export class UmbRelationTypeRepository
|
|||||||
|
|
||||||
#host: UmbControllerHostElement;
|
#host: UmbControllerHostElement;
|
||||||
|
|
||||||
#treeSource: RelationTypeTreeDataSource;
|
#treeSource: UmbRelationTypeTreeDataSource;
|
||||||
#treeStore?: UmbRelationTypeTreeStore;
|
#treeStore?: UmbRelationTypeTreeStore;
|
||||||
|
|
||||||
#detailDataSource: UmbRelationTypeServerDataSource;
|
#detailDataSource: UmbRelationTypeServerDataSource;
|
||||||
@@ -35,7 +35,7 @@ export class UmbRelationTypeRepository
|
|||||||
this.#host = host;
|
this.#host = host;
|
||||||
|
|
||||||
// TODO: figure out how spin up get the correct data source
|
// TODO: figure out how spin up get the correct data source
|
||||||
this.#treeSource = new RelationTypeTreeServerDataSource(this.#host);
|
this.#treeSource = new UmbRelationTypeTreeServerDataSource(this.#host);
|
||||||
this.#detailDataSource = new UmbRelationTypeServerDataSource(this.#host);
|
this.#detailDataSource = new UmbRelationTypeServerDataSource(this.#host);
|
||||||
|
|
||||||
this.#init = Promise.all([
|
this.#init = Promise.all([
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { RelationTypeResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
import type { RelationTypeResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||||
import { ArrayState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ export const UMB_RELATION_TYPE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbRela
|
|||||||
* @description - Data Store for Template Details
|
* @description - Data Store for Template Details
|
||||||
*/
|
*/
|
||||||
export class UmbRelationTypeStore extends UmbStoreBase {
|
export class UmbRelationTypeStore extends UmbStoreBase {
|
||||||
#data = new ArrayState<RelationTypeResponseModel>([], (x) => x.id);
|
#data = new UmbArrayState<RelationTypeResponseModel>([], (x) => x.id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance of UmbRelationTypeStore.
|
* Creates an instance of UmbRelationTypeStore.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { DataSourceResponse } from '@umbraco-cms/backoffice/repository';
|
import type { DataSourceResponse } from '@umbraco-cms/backoffice/repository';
|
||||||
import { ItemResponseModelBaseModel, PagedEntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
import { ItemResponseModelBaseModel, PagedEntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
|
|
||||||
export interface RelationTypeTreeDataSource {
|
export interface UmbRelationTypeTreeDataSource {
|
||||||
getRootItems(): Promise<DataSourceResponse<PagedEntityTreeItemResponseModel>>;
|
getRootItems(): Promise<DataSourceResponse<PagedEntityTreeItemResponseModel>>;
|
||||||
getItems(ids: Array<string>): Promise<DataSourceResponse<ItemResponseModelBaseModel[]>>;
|
getItems(ids: Array<string>): Promise<DataSourceResponse<ItemResponseModelBaseModel[]>>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { RelationTypeTreeDataSource } from '.';
|
import { UmbRelationTypeTreeDataSource } from '.';
|
||||||
import { ProblemDetailsModel, RelationTypeResource } from '@umbraco-cms/backoffice/backend-api';
|
import { ProblemDetailsModel, RelationTypeResource } from '@umbraco-cms/backoffice/backend-api';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
|
|
||||||
@@ -7,10 +7,10 @@ import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
|
|||||||
/**
|
/**
|
||||||
* A data source for the RelationType tree that fetches data from the server
|
* A data source for the RelationType tree that fetches data from the server
|
||||||
* @export
|
* @export
|
||||||
* @class RelationTypeTreeServerDataSource
|
* @class UmbRelationTypeTreeServerDataSource
|
||||||
* @implements {RelationTypeTreeDataSource}
|
* @implements {UmbRelationTypeTreeDataSource}
|
||||||
*/
|
*/
|
||||||
export class RelationTypeTreeServerDataSource implements RelationTypeTreeDataSource {
|
export class UmbRelationTypeTreeServerDataSource implements UmbRelationTypeTreeDataSource {
|
||||||
#host: UmbControllerHostElement;
|
#host: UmbControllerHostElement;
|
||||||
|
|
||||||
// TODO: how do we handle trashed items?
|
// TODO: how do we handle trashed items?
|
||||||
@@ -47,9 +47,9 @@ export class RelationTypeTreeServerDataSource implements RelationTypeTreeDataSou
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance of RelationTypeTreeServerDataSource.
|
* Creates an instance of UmbRelationTypeTreeServerDataSource.
|
||||||
* @param {UmbControllerHostElement} host
|
* @param {UmbControllerHostElement} host
|
||||||
* @memberof RelationTypeTreeServerDataSource
|
* @memberof UmbRelationTypeTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
constructor(host: UmbControllerHostElement) {
|
constructor(host: UmbControllerHostElement) {
|
||||||
this.#host = host;
|
this.#host = host;
|
||||||
@@ -58,7 +58,7 @@ export class RelationTypeTreeServerDataSource implements RelationTypeTreeDataSou
|
|||||||
/**
|
/**
|
||||||
* Fetches the root items for the tree from the server
|
* Fetches the root items for the tree from the server
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof RelationTypeTreeServerDataSource
|
* @memberof UmbRelationTypeTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getRootItems() {
|
async getRootItems() {
|
||||||
return tryExecuteAndNotify(this.#host, RelationTypeResource.getTreeRelationTypeRoot({}));
|
return tryExecuteAndNotify(this.#host, RelationTypeResource.getTreeRelationTypeRoot({}));
|
||||||
@@ -68,7 +68,7 @@ export class RelationTypeTreeServerDataSource implements RelationTypeTreeDataSou
|
|||||||
* Fetches the items for the given ids from the server
|
* Fetches the items for the given ids from the server
|
||||||
* @param {Array<string>} ids
|
* @param {Array<string>} ids
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @memberof RelationTypeTreeServerDataSource
|
* @memberof UmbRelationTypeTreeServerDataSource
|
||||||
*/
|
*/
|
||||||
async getItems(ids: Array<string>) {
|
async getItems(ids: Array<string>) {
|
||||||
if (ids) {
|
if (ids) {
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ import { UmbRelationTypeRepository } from '../repository/relation-type.repositor
|
|||||||
import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace';
|
import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace';
|
||||||
import type { RelationTypeBaseModel, RelationTypeResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
import type { RelationTypeBaseModel, RelationTypeResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
|
|
||||||
import { ObjectState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
|
|
||||||
export class UmbRelationTypeWorkspaceContext
|
export class UmbRelationTypeWorkspaceContext
|
||||||
extends UmbWorkspaceContext<UmbRelationTypeRepository, RelationTypeResponseModel>
|
extends UmbWorkspaceContext<UmbRelationTypeRepository, RelationTypeResponseModel>
|
||||||
implements UmbEntityWorkspaceContextInterface<RelationTypeResponseModel | undefined>
|
implements UmbEntityWorkspaceContextInterface<RelationTypeResponseModel | undefined>
|
||||||
{
|
{
|
||||||
#data = new ObjectState<RelationTypeResponseModel | undefined>(undefined);
|
#data = new UmbObjectState<RelationTypeResponseModel | undefined>(undefined);
|
||||||
data = this.#data.asObservable();
|
data = this.#data.asObservable();
|
||||||
name = this.#data.getObservablePart((data) => data?.name);
|
name = this.#data.getObservablePart((data) => data?.name);
|
||||||
id = this.#data.getObservablePart((data) => data?.id);
|
id = this.#data.getObservablePart((data) => data?.id);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Observable } from 'rxjs';
|
|||||||
import type { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
import type { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
import { UmbContextToken, UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextToken, UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
|
||||||
import { ArrayState, UmbObserverController } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbArrayState, UmbObserverController } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { umbExtensionsRegistry, createExtensionClass } from '@umbraco-cms/backoffice/extensions-api';
|
import { umbExtensionsRegistry, createExtensionClass } from '@umbraco-cms/backoffice/extensions-api';
|
||||||
import { UmbTreeRepository } from '@umbraco-cms/backoffice/repository';
|
import { UmbTreeRepository } from '@umbraco-cms/backoffice/repository';
|
||||||
|
|
||||||
@@ -17,15 +17,15 @@ export class UmbCollectionContext<DataType extends EntityTreeItemResponseModel =
|
|||||||
private _store?: any;
|
private _store?: any;
|
||||||
protected _dataObserver?: UmbObserverController<DataType[]>;
|
protected _dataObserver?: UmbObserverController<DataType[]>;
|
||||||
|
|
||||||
#data = new ArrayState(<Array<DataType>>[]);
|
#data = new UmbArrayState(<Array<DataType>>[]);
|
||||||
public readonly data = this.#data.asObservable();
|
public readonly data = this.#data.asObservable();
|
||||||
|
|
||||||
#selection = new ArrayState(<Array<string>>[]);
|
#selection = new UmbArrayState(<Array<string>>[]);
|
||||||
public readonly selection = this.#selection.asObservable();
|
public readonly selection = this.#selection.asObservable();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO:
|
TODO:
|
||||||
private _search = new StringState('');
|
private _search = new UmbStringState('');
|
||||||
public readonly search = this._search.asObservable();
|
public readonly search = this._search.asObservable();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api';
|
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api';
|
||||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||||
import { StringState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbStringState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
|
|
||||||
export class UmbBackofficeContext {
|
export class UmbBackofficeContext {
|
||||||
#activeSectionAlias = new StringState(undefined);
|
#activeSectionAlias = new UmbStringState(undefined);
|
||||||
public readonly activeSectionAlias = this.#activeSectionAlias.asObservable();
|
public readonly activeSectionAlias = this.#activeSectionAlias.asObservable();
|
||||||
|
|
||||||
public getAllowedSections() {
|
public getAllowedSections() {
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import { customElement } from 'lit/decorators.js';
|
|||||||
* @slot the full message
|
* @slot the full message
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@customElement('uui-code-block')
|
@customElement('umb-code-block')
|
||||||
export class UUICodeBlockElement extends LitElement {
|
export class UmbCodeBlockElement extends LitElement {
|
||||||
static styles = [
|
static styles = [
|
||||||
UUITextStyles,
|
UUITextStyles,
|
||||||
css`
|
css`
|
||||||
@@ -54,6 +54,6 @@ export class UUICodeBlockElement extends LitElement {
|
|||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
'uui-code-block': UUICodeBlockElement;
|
'umb-code-block': UmbCodeBlockElement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import { Meta, StoryObj } from '@storybook/web-components';
|
import { Meta, StoryObj } from '@storybook/web-components';
|
||||||
import { html } from 'lit';
|
import { html } from 'lit';
|
||||||
import './code-block.element';
|
import './code-block.element';
|
||||||
import type { UUICodeBlockElement } from './code-block.element';
|
import type { UmbCodeBlockElement } from './code-block.element';
|
||||||
|
|
||||||
const meta: Meta<UUICodeBlockElement> = {
|
const meta: Meta<UmbCodeBlockElement> = {
|
||||||
title: 'Components/Code Block',
|
title: 'Components/Code Block',
|
||||||
component: 'uui-code-block',
|
component: 'umb-code-block',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default meta;
|
export default meta;
|
||||||
type Story = StoryObj<UUICodeBlockElement>;
|
type Story = StoryObj<UmbCodeBlockElement>;
|
||||||
|
|
||||||
export const Overview: Story = {
|
export const Overview: Story = {
|
||||||
args: {},
|
args: {},
|
||||||
@@ -17,5 +17,5 @@ export const Overview: Story = {
|
|||||||
|
|
||||||
export const WithCode: Story = {
|
export const WithCode: Story = {
|
||||||
decorators: [],
|
decorators: [],
|
||||||
render: () => html` <uui-code-block> // Lets write some javascript alert("Hello World"); </uui-code-block>`,
|
render: () => html` <umb-code-block> // Lets write some javascript alert("Hello World"); </umb-code-block>`,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -111,12 +111,12 @@ const codeSnippets: Record<CodeEditorLanguage, string> = {
|
|||||||
"Smartypants, double quotes" and 'single quotes'`,
|
"Smartypants, double quotes" and 'single quotes'`,
|
||||||
typescript: `import { UmbTemplateRepository } from '../repository/template.repository';
|
typescript: `import { UmbTemplateRepository } from '../repository/template.repository';
|
||||||
import { UmbWorkspaceContext } from '../../../shared/components/workspace/workspace-context/workspace-context';
|
import { UmbWorkspaceContext } from '../../../shared/components/workspace/workspace-context/workspace-context';
|
||||||
import { createObservablePart, DeepState } from '@umbraco-cms/observable-api';
|
import { createObservablePart, UmbDeepState } from '@umbraco-cms/observable-api';
|
||||||
import { TemplateModel } from '@umbraco-cms/backend-api';
|
import { TemplateModel } from '@umbraco-cms/backend-api';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/controller';
|
||||||
|
|
||||||
export class UmbTemplateWorkspaceContext extends UmbWorkspaceContext<UmbTemplateRepository, TemplateModel> {
|
export class UmbTemplateWorkspaceContext extends UmbWorkspaceContext<UmbTemplateRepository, TemplateModel> {
|
||||||
#data = new DeepState<TemplateModel | undefined>(undefined);
|
#data = new UmbDeepState<TemplateModel | undefined>(undefined);
|
||||||
data = this.#data.asObservable();
|
data = this.#data.asObservable();
|
||||||
name = createObservablePart(this.#data, (data) => data?.name);
|
name = createObservablePart(this.#data, (data) => data?.name);
|
||||||
content = createObservablePart(this.#data, (data) => data?.content);
|
content = createObservablePart(this.#data, (data) => data?.content);
|
||||||
|
|||||||
@@ -180,10 +180,17 @@ export class UmbDebugElement extends UmbLitElement {
|
|||||||
|
|
||||||
const props: TemplateResult[] = [];
|
const props: TemplateResult[] = [];
|
||||||
instance.properties?.forEach((property) => {
|
instance.properties?.forEach((property) => {
|
||||||
if (property.type === 'string') {
|
switch(property.type){
|
||||||
props.push(html`<li>${property.key} = ${property.value}</li>`);
|
case 'string':
|
||||||
} else {
|
case 'number':
|
||||||
props.push(html`<li>${property.key} <em>(${property.type})</em></li>`);
|
case 'boolean':
|
||||||
|
case 'object':
|
||||||
|
props.push(html`<li>${property.key} <em>(${property.type})</em> = ${property.value}</li>`);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
props.push(html`<li>${property.key} <em>(${property.type})</em></li>`);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ export interface Circle {
|
|||||||
name: string;
|
name: string;
|
||||||
percent: number;
|
percent: number;
|
||||||
kind: string;
|
kind: string;
|
||||||
|
number: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CircleWithCommands extends Circle {
|
interface CircleWithCommands extends Circle {
|
||||||
@@ -195,6 +196,7 @@ export class UmbDonutChartElement extends LitElement {
|
|||||||
this._slices.map((slice) => {
|
this._slices.map((slice) => {
|
||||||
return {
|
return {
|
||||||
percent: this.#calculatePercentage(slice.amount),
|
percent: this.#calculatePercentage(slice.amount),
|
||||||
|
number: slice.amount,
|
||||||
color: slice.color,
|
color: slice.color,
|
||||||
name: slice.name,
|
name: slice.name,
|
||||||
kind: slice.kind,
|
kind: slice.kind,
|
||||||
@@ -249,7 +251,7 @@ export class UmbDonutChartElement extends LitElement {
|
|||||||
const index = target.dataset.index as unknown as number;
|
const index = target.dataset.index as unknown as number;
|
||||||
const circle = this.circles[index];
|
const circle = this.circles[index];
|
||||||
this._detailName = circle.name;
|
this._detailName = circle.name;
|
||||||
this._detailAmount = circle.percent;
|
this._detailAmount = circle.number;
|
||||||
this._detailColor = circle.color;
|
this._detailColor = circle.color;
|
||||||
this._detailKind = circle.kind;
|
this._detailKind = circle.kind;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,9 @@ import { expect, fixture, html } from '@open-wc/testing';
|
|||||||
import { InitializedExtension, UmbExtensionSlotElement } from './extension-slot.element';
|
import { InitializedExtension, UmbExtensionSlotElement } from './extension-slot.element';
|
||||||
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api';
|
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api';
|
||||||
import { ManifestDashboard } from '@umbraco-cms/backoffice/extensions-registry';
|
import { ManifestDashboard } from '@umbraco-cms/backoffice/extensions-registry';
|
||||||
import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils';
|
|
||||||
|
|
||||||
@customElement('test-extension-slot-manifest-element')
|
@customElement('umb-test-extension-slot-manifest-element')
|
||||||
class MyExtensionSlotManifestElement extends HTMLElement {}
|
class UmbTestExtensionSlotManifestElement extends HTMLElement {}
|
||||||
|
|
||||||
function sleep(ms: number) {
|
function sleep(ms: number) {
|
||||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
@@ -52,7 +51,7 @@ describe('UmbExtensionSlotElement', () => {
|
|||||||
type: 'dashboard',
|
type: 'dashboard',
|
||||||
alias: 'unit-test-ext-slot-element-manifest',
|
alias: 'unit-test-ext-slot-element-manifest',
|
||||||
name: 'unit-test-extension',
|
name: 'unit-test-extension',
|
||||||
elementName: 'test-extension-slot-manifest-element',
|
elementName: 'umb-test-extension-slot-manifest-element',
|
||||||
meta: {
|
meta: {
|
||||||
pathname: 'test/test',
|
pathname: 'test/test',
|
||||||
},
|
},
|
||||||
@@ -75,7 +74,7 @@ describe('UmbExtensionSlotElement', () => {
|
|||||||
|
|
||||||
await sleep(0);
|
await sleep(0);
|
||||||
|
|
||||||
expect(element.shadowRoot!.firstElementChild).to.be.instanceOf(MyExtensionSlotManifestElement);
|
expect(element.shadowRoot!.firstElementChild).to.be.instanceOf(UmbTestExtensionSlotManifestElement);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('use the render method', async () => {
|
it('use the render method', async () => {
|
||||||
@@ -90,7 +89,9 @@ describe('UmbExtensionSlotElement', () => {
|
|||||||
await sleep(0);
|
await sleep(0);
|
||||||
|
|
||||||
expect(element.shadowRoot!.firstElementChild?.nodeName).to.be.equal('BLA');
|
expect(element.shadowRoot!.firstElementChild?.nodeName).to.be.equal('BLA');
|
||||||
expect(element.shadowRoot!.firstElementChild?.firstElementChild).to.be.instanceOf(MyExtensionSlotManifestElement);
|
expect(element.shadowRoot!.firstElementChild?.firstElementChild).to.be.instanceOf(
|
||||||
|
UmbTestExtensionSlotManifestElement
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
import { StringState, BooleanState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbStringState, UmbBooleanState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
|
|
||||||
export class UmbSectionSidebarContext {
|
export class UmbSectionSidebarContext {
|
||||||
#host: UmbControllerHostElement;
|
#host: UmbControllerHostElement;
|
||||||
#contextMenuIsOpen = new BooleanState(false);
|
#contextMenuIsOpen = new UmbBooleanState(false);
|
||||||
contextMenuIsOpen = this.#contextMenuIsOpen.asObservable();
|
contextMenuIsOpen = this.#contextMenuIsOpen.asObservable();
|
||||||
|
|
||||||
#entityType = new StringState<undefined>(undefined);
|
#entityType = new UmbStringState<undefined>(undefined);
|
||||||
entityType = this.#entityType.asObservable();
|
entityType = this.#entityType.asObservable();
|
||||||
|
|
||||||
#unique = new StringState<undefined>(undefined);
|
#unique = new UmbStringState<undefined>(undefined);
|
||||||
unique = this.#unique.asObservable();
|
unique = this.#unique.asObservable();
|
||||||
|
|
||||||
#headline = new StringState<undefined>(undefined);
|
#headline = new UmbStringState<undefined>(undefined);
|
||||||
headline = this.#headline.asObservable();
|
headline = this.#headline.asObservable();
|
||||||
|
|
||||||
constructor(host: UmbControllerHostElement) {
|
constructor(host: UmbControllerHostElement) {
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import type { ManifestSection } from '@umbraco-cms/backoffice/extensions-registry';
|
import type { ManifestSection } from '@umbraco-cms/backoffice/extensions-registry';
|
||||||
import type { Entity } from '@umbraco-cms/backoffice/models';
|
import type { Entity } from '@umbraco-cms/backoffice/models';
|
||||||
import { ObjectState, StringState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbObjectState, UmbStringState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||||
|
|
||||||
export type ActiveTreeItemType = Entity | undefined;
|
export type ActiveTreeItemType = Entity | undefined;
|
||||||
|
|
||||||
export class UmbSectionContext {
|
export class UmbSectionContext {
|
||||||
#manifestAlias = new StringState<string | undefined>(undefined);
|
#manifestAlias = new UmbStringState<string | undefined>(undefined);
|
||||||
#manifestPathname = new StringState<string | undefined>(undefined);
|
#manifestPathname = new UmbStringState<string | undefined>(undefined);
|
||||||
#manifestLabel = new StringState<string | undefined>(undefined);
|
#manifestLabel = new UmbStringState<string | undefined>(undefined);
|
||||||
public readonly alias = this.#manifestAlias.asObservable();
|
public readonly alias = this.#manifestAlias.asObservable();
|
||||||
public readonly pathname = this.#manifestPathname.asObservable();
|
public readonly pathname = this.#manifestPathname.asObservable();
|
||||||
public readonly label = this.#manifestLabel.asObservable();
|
public readonly label = this.#manifestLabel.asObservable();
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css';
|
|||||||
import { css, nothing, PropertyValueMap } from 'lit';
|
import { css, nothing, PropertyValueMap } from 'lit';
|
||||||
import { customElement, property, state } from 'lit/decorators.js';
|
import { customElement, property, state } from 'lit/decorators.js';
|
||||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||||
import { DeepState } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbDeepState } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||||
|
|
||||||
// TODO: Refactor this, its not a service and the data should be handled by a context api.
|
// TODO: Refactor this, its not a service and the data should be handled by a context api.
|
||||||
@@ -13,7 +13,7 @@ export class UmbTreeContextMenuPageServiceElement extends UmbLitElement {
|
|||||||
@property({ type: Object })
|
@property({ type: Object })
|
||||||
public actionEntity: any = { key: '', name: '' };
|
public actionEntity: any = { key: '', name: '' };
|
||||||
|
|
||||||
#entity = new DeepState({ key: '', name: '' } as any);
|
#entity = new UmbDeepState({ key: '', name: '' } as any);
|
||||||
public readonly entity = this.#entity.asObservable();
|
public readonly entity = this.#entity.asObservable();
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
|
|||||||
@@ -7,7 +7,12 @@ import { UmbSectionContext, UMB_SECTION_CONTEXT_TOKEN } from '../../section/sect
|
|||||||
import { UmbTreeContextBase } from '../tree.context';
|
import { UmbTreeContextBase } from '../tree.context';
|
||||||
import { UmbTreeItemContext } from '../tree-item.context.interface';
|
import { UmbTreeItemContext } from '../tree-item.context.interface';
|
||||||
import { ManifestEntityAction } from '@umbraco-cms/backoffice/extensions-registry';
|
import { ManifestEntityAction } from '@umbraco-cms/backoffice/extensions-registry';
|
||||||
import { BooleanState, DeepState, StringState, UmbObserverController } from '@umbraco-cms/backoffice/observable-api';
|
import {
|
||||||
|
UmbBooleanState,
|
||||||
|
UmbDeepState,
|
||||||
|
UmbStringState,
|
||||||
|
UmbObserverController,
|
||||||
|
} from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
import {
|
import {
|
||||||
UmbContextConsumerController,
|
UmbContextConsumerController,
|
||||||
@@ -27,28 +32,28 @@ export class UmbTreeItemContextBase<T extends TreeItemPresentationModel = TreeIt
|
|||||||
public unique?: string;
|
public unique?: string;
|
||||||
public type?: string;
|
public type?: string;
|
||||||
|
|
||||||
#treeItem = new DeepState<T | undefined>(undefined);
|
#treeItem = new UmbDeepState<T | undefined>(undefined);
|
||||||
treeItem = this.#treeItem.asObservable();
|
treeItem = this.#treeItem.asObservable();
|
||||||
|
|
||||||
#hasChildren = new BooleanState(false);
|
#hasChildren = new UmbBooleanState(false);
|
||||||
hasChildren = this.#hasChildren.asObservable();
|
hasChildren = this.#hasChildren.asObservable();
|
||||||
|
|
||||||
#isLoading = new BooleanState(false);
|
#isLoading = new UmbBooleanState(false);
|
||||||
isLoading = this.#isLoading.asObservable();
|
isLoading = this.#isLoading.asObservable();
|
||||||
|
|
||||||
#isSelectable = new BooleanState(false);
|
#isSelectable = new UmbBooleanState(false);
|
||||||
isSelectable = this.#isSelectable.asObservable();
|
isSelectable = this.#isSelectable.asObservable();
|
||||||
|
|
||||||
#isSelected = new BooleanState(false);
|
#isSelected = new UmbBooleanState(false);
|
||||||
isSelected = this.#isSelected.asObservable();
|
isSelected = this.#isSelected.asObservable();
|
||||||
|
|
||||||
#isActive = new BooleanState(false);
|
#isActive = new UmbBooleanState(false);
|
||||||
isActive = this.#isActive.asObservable();
|
isActive = this.#isActive.asObservable();
|
||||||
|
|
||||||
#hasActions = new BooleanState(false);
|
#hasActions = new UmbBooleanState(false);
|
||||||
hasActions = this.#hasActions.asObservable();
|
hasActions = this.#hasActions.asObservable();
|
||||||
|
|
||||||
#path = new StringState('');
|
#path = new UmbStringState('');
|
||||||
path = this.#path.asObservable();
|
path = this.#path.asObservable();
|
||||||
|
|
||||||
treeContext?: UmbTreeContextBase;
|
treeContext?: UmbTreeContextBase;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { Observable } from 'rxjs';
|
import type { Observable } from 'rxjs';
|
||||||
import { UmbTreeRepository } from '@umbraco-cms/backoffice/repository';
|
import { UmbTreeRepository } from '@umbraco-cms/backoffice/repository';
|
||||||
import type { ManifestTree } from '@umbraco-cms/backoffice/extensions-registry';
|
import type { ManifestTree } from '@umbraco-cms/backoffice/extensions-registry';
|
||||||
import { DeepState, UmbObserverController } from '@umbraco-cms/backoffice/observable-api';
|
import { UmbDeepState, UmbObserverController } from '@umbraco-cms/backoffice/observable-api';
|
||||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
import { createExtensionClass, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api';
|
import { createExtensionClass, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api';
|
||||||
|
|
||||||
@@ -18,10 +18,10 @@ export class UmbTreeContextBase implements UmbTreeContext {
|
|||||||
host: UmbControllerHostElement;
|
host: UmbControllerHostElement;
|
||||||
public tree: ManifestTree;
|
public tree: ManifestTree;
|
||||||
|
|
||||||
#selectable = new DeepState(false);
|
#selectable = new UmbDeepState(false);
|
||||||
public readonly selectable = this.#selectable.asObservable();
|
public readonly selectable = this.#selectable.asObservable();
|
||||||
|
|
||||||
#selection = new DeepState(<Array<string>>[]);
|
#selection = new UmbDeepState(<Array<string>>[]);
|
||||||
public readonly selection = this.#selection.asObservable();
|
public readonly selection = this.#selection.asObservable();
|
||||||
|
|
||||||
repository?: UmbTreeRepository;
|
repository?: UmbTreeRepository;
|
||||||
|
|||||||
@@ -3,7 +3,12 @@ import { UmbWorkspaceVariableEntityContextInterface } from '../workspace/workspa
|
|||||||
import { UMB_WORKSPACE_VARIANT_CONTEXT_TOKEN } from '../workspace/workspace-variant/workspace-variant.context';
|
import { UMB_WORKSPACE_VARIANT_CONTEXT_TOKEN } from '../workspace/workspace-variant/workspace-variant.context';
|
||||||
import type { DataTypeResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
import type { DataTypeResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||||
import { ClassState, ObjectState, StringState, UmbObserverController } from '@umbraco-cms/backoffice/observable-api';
|
import {
|
||||||
|
UmbClassState,
|
||||||
|
UmbObjectState,
|
||||||
|
UmbStringState,
|
||||||
|
UmbObserverController,
|
||||||
|
} from '@umbraco-cms/backoffice/observable-api';
|
||||||
import {
|
import {
|
||||||
UmbContextConsumerController,
|
UmbContextConsumerController,
|
||||||
UmbContextProviderController,
|
UmbContextProviderController,
|
||||||
@@ -25,7 +30,7 @@ export class UmbWorkspacePropertyContext<ValueType = any> {
|
|||||||
|
|
||||||
private _providerController: UmbContextProviderController;
|
private _providerController: UmbContextProviderController;
|
||||||
|
|
||||||
private _data = new ObjectState<WorkspacePropertyData<ValueType>>({});
|
private _data = new UmbObjectState<WorkspacePropertyData<ValueType>>({});
|
||||||
|
|
||||||
public readonly alias = this._data.getObservablePart((data) => data.alias);
|
public readonly alias = this._data.getObservablePart((data) => data.alias);
|
||||||
public readonly label = this._data.getObservablePart((data) => data.label);
|
public readonly label = this._data.getObservablePart((data) => data.label);
|
||||||
@@ -35,10 +40,10 @@ export class UmbWorkspacePropertyContext<ValueType = any> {
|
|||||||
|
|
||||||
#workspaceVariantId?: UmbVariantId;
|
#workspaceVariantId?: UmbVariantId;
|
||||||
|
|
||||||
#variantId = new ClassState<UmbVariantId | undefined>(undefined);
|
#variantId = new UmbClassState<UmbVariantId | undefined>(undefined);
|
||||||
public readonly variantId = this.#variantId.asObservable();
|
public readonly variantId = this.#variantId.asObservable();
|
||||||
|
|
||||||
private _variantDifference = new StringState(undefined);
|
private _variantDifference = new UmbStringState(undefined);
|
||||||
public readonly variantDifference = this._variantDifference.asObservable();
|
public readonly variantDifference = this._variantDifference.asObservable();
|
||||||
|
|
||||||
private _workspaceContext?: UmbWorkspaceVariableEntityContextInterface;
|
private _workspaceContext?: UmbWorkspaceVariableEntityContextInterface;
|
||||||
@@ -88,7 +93,7 @@ export class UmbWorkspacePropertyContext<ValueType = any> {
|
|||||||
this._data.update({ description });
|
this._data.update({ description });
|
||||||
}
|
}
|
||||||
public setValue(value: WorkspacePropertyData<ValueType>['value']) {
|
public setValue(value: WorkspacePropertyData<ValueType>['value']) {
|
||||||
// Note: Do not try to compare new / old value, as it can of any type. We trust the ObjectState in doing such.
|
// Note: Do not try to compare new / old value, as it can of any type. We trust the UmbObjectState in doing such.
|
||||||
this._data.update({ value });
|
this._data.update({ value });
|
||||||
}
|
}
|
||||||
public changeValue(value: WorkspacePropertyData<ValueType>['value']) {
|
public changeValue(value: WorkspacePropertyData<ValueType>['value']) {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user