fetch media items
This commit is contained in:
@@ -3,11 +3,13 @@ import { css, html, LitElement } from 'lit';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import type { ManifestEditorView, ManifestWithLoader } from '@umbraco-cms/models';
|
||||
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
|
||||
import { UmbMediaStore } from 'src/core/stores/media/media.store';
|
||||
import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/context-api';
|
||||
|
||||
import '../shared/editor-content/editor-content.element';
|
||||
|
||||
@customElement('umb-editor-media')
|
||||
export class UmbEditorMediaElement extends LitElement {
|
||||
export class UmbEditorMediaElement extends UmbContextConsumerMixin(UmbContextProviderMixin(LitElement)) {
|
||||
static styles = [
|
||||
UUITextStyles,
|
||||
css`
|
||||
@@ -26,6 +28,10 @@ export class UmbEditorMediaElement extends LitElement {
|
||||
super();
|
||||
|
||||
this._registerEditorViews();
|
||||
|
||||
this.consumeContext('umbMediaStore', (mediaStore: UmbMediaStore) => {
|
||||
this.provideContext('umbContentStore', mediaStore);
|
||||
});
|
||||
}
|
||||
|
||||
private _registerEditorViews() {
|
||||
|
||||
@@ -17,6 +17,8 @@ import '../editor-entity-layout/editor-entity-layout.element';
|
||||
// TODO: Make this dynamic, use load-extensions method to loop over extensions for this node.
|
||||
import './views/edit/editor-view-content-edit.element';
|
||||
import './views/info/editor-view-content-info.element';
|
||||
import { UmbDocumentStore } from 'src/core/stores/document/document.store';
|
||||
import { UmbMediaStore } from 'src/core/stores/media/media.store';
|
||||
|
||||
@customElement('umb-editor-content')
|
||||
export class UmbEditorContentElement extends UmbContextProviderMixin(
|
||||
@@ -60,19 +62,19 @@ export class UmbEditorContentElement extends UmbContextProviderMixin(
|
||||
alias!: string;
|
||||
|
||||
@state()
|
||||
_node?: NodeEntity;
|
||||
_content?: NodeEntity;
|
||||
|
||||
private _nodeStore?: UmbNodeStore;
|
||||
private _store?: UmbDocumentStore | UmbMediaStore;
|
||||
private _nodeContext?: UmbNodeContext;
|
||||
private _notificationService?: UmbNotificationService;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.consumeAllContexts(['umbNodeStore', 'umbNotificationService'], (instances) => {
|
||||
this._nodeStore = instances['umbNodeStore'];
|
||||
this.consumeAllContexts(['umbContentStore', 'umbNotificationService'], (instances) => {
|
||||
this._store = instances['umbContentStore'];
|
||||
this._notificationService = instances['umbNotificationService'];
|
||||
this._useNode();
|
||||
this._observeContent();
|
||||
});
|
||||
|
||||
this.addEventListener('property-value-change', this._onPropertyValueChange);
|
||||
@@ -82,7 +84,7 @@ export class UmbEditorContentElement extends UmbContextProviderMixin(
|
||||
const target = e.composedPath()[0] as any;
|
||||
|
||||
// TODO: Set value.
|
||||
const property = this._node?.properties.find((x) => x.alias === target.alias);
|
||||
const property = this._content?.properties.find((x) => x.alias === target.alias);
|
||||
if (property) {
|
||||
this._setPropertyValue(property.alias, target.value);
|
||||
} else {
|
||||
@@ -91,28 +93,29 @@ export class UmbEditorContentElement extends UmbContextProviderMixin(
|
||||
};
|
||||
|
||||
private _setPropertyValue(alias: string, value: unknown) {
|
||||
this._node?.data.forEach((data) => {
|
||||
this._content?.data.forEach((data) => {
|
||||
if (data.alias === alias) {
|
||||
data.value = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _useNode() {
|
||||
if (!this._nodeStore) return;
|
||||
private _observeContent() {
|
||||
if (!this._store) return;
|
||||
|
||||
this.observe<NodeEntity>(this._nodeStore.getByKey(this.entityKey), (node) => {
|
||||
if (!node) return; // TODO: Handle nicely if there is no node.
|
||||
this.observe<NodeEntity>(this._store.getByKey(this.entityKey), (content) => {
|
||||
debugger
|
||||
if (!content) return; // TODO: Handle nicely if there is no node.
|
||||
|
||||
if (!this._nodeContext) {
|
||||
this._nodeContext = new UmbNodeContext(node);
|
||||
this._nodeContext = new UmbNodeContext(content);
|
||||
this.provideContext('umbNodeContext', this._nodeContext);
|
||||
} else {
|
||||
this._nodeContext.update(node);
|
||||
this._nodeContext.update(content);
|
||||
}
|
||||
|
||||
this.observe<NodeEntity>(this._nodeContext.data.pipe(distinctUntilChanged()), (data) => {
|
||||
this._node = data;
|
||||
this._content = data;
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -122,9 +125,9 @@ export class UmbEditorContentElement extends UmbContextProviderMixin(
|
||||
}
|
||||
|
||||
private _onSave() {
|
||||
// TODO: What if store is not present, what if node is not loaded....
|
||||
if (this._node) {
|
||||
this._nodeStore?.save([this._node]).then(() => {
|
||||
// TODO: What if store is not present, what if content is not loaded....
|
||||
if (this._content) {
|
||||
this._store?.save([this._content]).then(() => {
|
||||
const data: UmbNotificationDefaultData = { message: 'Document Saved' };
|
||||
this._notificationService?.peek('positive', { data });
|
||||
});
|
||||
@@ -161,9 +164,9 @@ export class UmbEditorContentElement extends UmbContextProviderMixin(
|
||||
return html`
|
||||
<umb-editor-entity-layout alias=${this.alias}>
|
||||
<div slot="name">
|
||||
<uui-input .value=${this._node?.name} @input="${this._handleInput}">
|
||||
<uui-input .value=${this._content?.name} @input="${this._handleInput}">
|
||||
<!-- Implement Variant Selector -->
|
||||
${this._node && this._node.variants.length > 0
|
||||
${this._content && this._content.variants.length > 0
|
||||
? html`
|
||||
<div slot="append">
|
||||
<uui-button id="trigger" @click=${this._toggleVariantSelector}>
|
||||
@@ -176,7 +179,7 @@ export class UmbEditorContentElement extends UmbContextProviderMixin(
|
||||
</uui-input>
|
||||
|
||||
<!-- Implement Variant Selector -->
|
||||
${this._node && this._node.variants.length > 0
|
||||
${this._content && this._content.variants.length > 0
|
||||
? html`
|
||||
<uui-popover id="popover" .open=${this._variantSelectorIsOpen} @close=${this._close}>
|
||||
<div id="dropdown" slot="popover">
|
||||
|
||||
@@ -2,6 +2,7 @@ import { html } from 'lit';
|
||||
import { customElement } from 'lit/decorators.js';
|
||||
import { UmbTreeBase } from '../shared/tree-base.element';
|
||||
import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/context-api';
|
||||
import { UmbMediaStore } from 'src/core/stores/media/media.store';
|
||||
|
||||
import '../shared/tree-navigator.element';
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import { handlers as modelsBuilderHandlers } from './domains/modelsbuilder.handl
|
||||
import { handlers as profilingHandlers } from './domains/performance-profiling.handlers';
|
||||
|
||||
import { handlers as documentHandlers } from './domains/document.handlers';
|
||||
import { handlers as mediaHandlers } from './domains/media.handlers';
|
||||
|
||||
// treeHandlers
|
||||
import { handlers as treeDocumentHandlers } from './domains/tree-document.handlers';
|
||||
@@ -33,6 +34,7 @@ const handlers = [
|
||||
...upgradeHandlers,
|
||||
...userHandlers,
|
||||
...documentHandlers,
|
||||
...mediaHandlers,
|
||||
...dataTypeHandlers,
|
||||
...documentTypeHandlers,
|
||||
...treeHandlers,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { UmbData } from './data';
|
||||
import { ContentTreeItem, PagedContentTreeItem } from '@umbraco-cms/backend-api';
|
||||
import type { MediaDetails } from '@umbraco-cms/models';
|
||||
import { UmbEntityData } from './entity.data';
|
||||
|
||||
export const data: Array<MediaDetails> = [
|
||||
{
|
||||
@@ -12,6 +13,7 @@ export const data: Array<MediaDetails> = [
|
||||
isContainer: false,
|
||||
parentKey: null,
|
||||
noAccess: false,
|
||||
isTrashed: false,
|
||||
properties: [
|
||||
{
|
||||
alias: 'myMediaHeadline',
|
||||
@@ -37,6 +39,7 @@ export const data: Array<MediaDetails> = [
|
||||
isContainer: false,
|
||||
parentKey: null,
|
||||
noAccess: false,
|
||||
isTrashed: false,
|
||||
properties: [
|
||||
{
|
||||
alias: 'myMediaDescription',
|
||||
@@ -56,7 +59,7 @@ export const data: Array<MediaDetails> = [
|
||||
];
|
||||
|
||||
// Temp mocked database
|
||||
class UmbMediaData extends UmbData<MediaDetails> {
|
||||
class UmbMediaData extends UmbEntityData<MediaDetails> {
|
||||
constructor() {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import { rest } from 'msw';
|
||||
import { umbMediaData } from '../data/media.data';
|
||||
import type { MediaDetails } from '@umbraco-cms/models';
|
||||
|
||||
// TODO: add schema
|
||||
export const handlers = [
|
||||
rest.get('/umbraco/management/api/v1/media/details/:key', (req, res, ctx) => {
|
||||
console.warn('Please move to schema');
|
||||
const key = req.params.key as string;
|
||||
if (!key) return;
|
||||
|
||||
const media = umbMediaData.getByKey(key);
|
||||
|
||||
return res(ctx.status(200), ctx.json([media]));
|
||||
}),
|
||||
|
||||
rest.post<MediaDetails[]>('/umbraco/management/api/v1/media/save', async (req, res, ctx) => {
|
||||
console.warn('Please move to schema');
|
||||
const data = await req.json();
|
||||
if (!data) return;
|
||||
|
||||
const saved = umbMediaData.save(data);
|
||||
|
||||
return res(ctx.status(200), ctx.json(saved));
|
||||
}),
|
||||
|
||||
rest.post<string[]>('/umbraco/management/api/v1/media/trash', async (req, res, ctx) => {
|
||||
console.warn('Please move to schema');
|
||||
const keys = await req.json();
|
||||
|
||||
const trashed = umbMediaData.trash(keys);
|
||||
|
||||
return res(ctx.status(200), ctx.json(trashed));
|
||||
}),
|
||||
];
|
||||
@@ -10,6 +10,59 @@ import { ApiError, ContentTreeItem, MediaResource, ProblemDetails } from '@umbra
|
||||
* @description - Data Store for Media
|
||||
*/
|
||||
export class UmbMediaStore extends UmbDataStoreBase<MediaDetails | ContentTreeItem> {
|
||||
getByKey(key: string): Observable<MediaDetails | null> {
|
||||
// fetch from server and update store
|
||||
fetch(`/umbraco/management/api/v1/media/details/${key}`)
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
this.update(data);
|
||||
});
|
||||
|
||||
return this.items.pipe(map((media) => media.find((media) => media.key === key) || null));
|
||||
}
|
||||
|
||||
// TODO: make sure UI somehow can follow the status of this action.
|
||||
save(data: MediaDetails[]): Promise<void> {
|
||||
// fetch from server and update store
|
||||
// TODO: use Fetcher API.
|
||||
let body: string;
|
||||
|
||||
try {
|
||||
body = JSON.stringify(data);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
// TODO: Use node type to hit the right API, or have a general Node API?
|
||||
return fetch('/umbraco/management/api/v1/media/save', {
|
||||
method: 'POST',
|
||||
body: body,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((data: Array<MediaDetails>) => {
|
||||
this.update(data);
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: how do we handle trashed items?
|
||||
async trash(keys: Array<string>) {
|
||||
// fetch from server and update store
|
||||
// TODO: Use node type to hit the right API, or have a general Node API?
|
||||
const res = await fetch('/umbraco/management/api/v1/media/trash', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(keys),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
const data = await res.json();
|
||||
this.update(data);
|
||||
}
|
||||
|
||||
getTreeRoot(): Observable<Array<ContentTreeItem>> {
|
||||
MediaResource.getTreeMediaRoot({}).then(
|
||||
(res) => {
|
||||
@@ -24,8 +77,9 @@ export class UmbMediaStore extends UmbDataStoreBase<MediaDetails | ContentTreeIt
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return this.items.pipe(map((items) => items.filter((item) => item.parentKey === null)));
|
||||
|
||||
// TODO: how do we handle trashed items?
|
||||
return this.items.pipe(map((items) => items.filter((item) => item.parentKey === null && item.isTrashed === false)));
|
||||
}
|
||||
|
||||
getTreeItemChildren(key: string): Observable<Array<ContentTreeItem>> {
|
||||
@@ -44,7 +98,8 @@ export class UmbMediaStore extends UmbDataStoreBase<MediaDetails | ContentTreeIt
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return this.items.pipe(map((items) => items.filter((item) => item.parentKey === key)));
|
||||
|
||||
// TODO: how do we handle trashed items?
|
||||
return this.items.pipe(map((items) => items.filter((item) => item.parentKey === key && item.isTrashed === false)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user