Skip to content

Commit

Permalink
Media Picker: only allow navigating to folders/media with children + …
Browse files Browse the repository at this point in the history
…other fixes (#17617)

* only allow navigating into folders or item with children

* export media search provider

* mark search on media item repo as deprecated

* use media search provider for searching

* rename method

* change the look of the upload button

* only render checkbox if we are not in the root

* clear search when navigating

* add type

* set value so it gets updated when cleared

* default to search within an item

* hide breadcrumb if searching in root

* scope search on server

* Update media-picker-modal.element.ts

* hide breadcrumb when doing a global search within another item

* add selection mode

* remove unused state

* handle start node when searching

* fix if wrong order

* fix type error

* pass start node to breadcrumb

* handle start node in breadcrumb

* make start node optional

* map data

* clean up

* Update media-picker-folder-path.element.ts

* add searching load indicator

* don't show unique in detail

* Add information to item response model

* Update OpenApi.json

* generate new server models

* update mocks

* move interface to types

* add hasChildren and parent to media item model interface

* fix import

* map data

* map media item

* treat tree item and search result the same

* Fix: bump uui version (#17626)

* lint fix

* temp fix for media selection

* UX corrections for media selection

* temp uui fix for media picker modal

* fix table selection mode

* fix search from when having a start node

* remove private

* wait for all missing parts before create table items

---------

Co-authored-by: nikolajlauridsen <nikolajlauridsen@protonmail.ch>
Co-authored-by: Niels Lyngsø <niels.lyngso@gmail.com>
  • Loading branch information
3 people authored Nov 25, 2024
1 parent 5856fd9 commit 16a5f8d
Show file tree
Hide file tree
Showing 33 changed files with 371 additions and 158 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,11 @@ const itemMapper = (model: UmbMockDocumentBlueprintModel): DocumentItemResponseM
icon: model.documentType.icon,
id: model.documentType.id,
},
hasChildren: model.hasChildren,
id: model.id,
isProtected: model.isProtected,
isTrashed: model.isTrashed,
parent: model.parent,
variants: model.variants,
hasChildren: model.hasChildren,
parent: model.parent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,11 @@ const itemMapper = (model: UmbMockDocumentModel): DocumentItemResponseModel => {
icon: model.documentType.icon,
id: model.documentType.id,
},
hasChildren: model.hasChildren,
id: model.id,
isProtected: model.isProtected,
isTrashed: model.isTrashed,
parent: model.parent,
variants: model.variants,
hasChildren: model.hasChildren,
parent: model.parent,
Expand Down
2 changes: 2 additions & 0 deletions src/Umbraco.Web.UI.Client/src/mocks/data/media/media.db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,10 @@ const itemMapper = (model: UmbMockMediaModel): MediaItemResponseModel => {
icon: model.mediaType.icon,
id: model.mediaType.id,
},
hasChildren: model.hasChildren,
id: model.id,
isTrashed: model.isTrashed,
parent: model.parent,
variants: model.variants,
hasChildren: model.hasChildren,
parent: model.parent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,18 @@ export class UmbTableElement extends LitElement {
this.dispatchEvent(new UmbTableOrderedEvent());
}

private _selectAllRows() {
this.selection = this.items.map((item: UmbTableItem) => item.id);
this._selectionMode = true;
this.dispatchEvent(new UmbTableSelectedEvent());
}

private _deselectAllRows() {
this.selection = [];
this._selectionMode = false;
this.dispatchEvent(new UmbTableDeselectedEvent());
}

private _selectRow(key: string) {
this.selection = [...this.selection, key];
this._selectionMode = this.selection.length > 0;
Expand All @@ -158,16 +170,14 @@ export class UmbTableElement extends LitElement {
this.dispatchEvent(new UmbTableDeselectedEvent());
}

private _selectAllRows() {
this.selection = this.items.map((item: UmbTableItem) => item.id);
this._selectionMode = true;
this.dispatchEvent(new UmbTableSelectedEvent());
}

private _deselectAllRows() {
this.selection = [];
this._selectionMode = false;
this.dispatchEvent(new UmbTableDeselectedEvent());
#onClickRow(key: string) {
if (this._selectionMode) {
if (this._isSelected(key)) {
this._deselectRow(key);
} else {
this._selectRow(key);
}
}
}

override render() {
Expand Down Expand Up @@ -234,7 +244,8 @@ export class UmbTableElement extends LitElement {
?select-only=${this._selectionMode}
?selected=${this._isSelected(item.id)}
@selected=${() => this._selectRow(item.id)}
@deselected=${() => this._deselectRow(item.id)}>
@deselected=${() => this._deselectRow(item.id)}
@click=${() => this.#onClickRow(item.id)}>
${this._renderRowCheckboxCell(item)} ${this.columns.map((column) => this._renderRowCell(column, item))}
</uui-table-row>
`;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import type { UmbContentTypeCompositionModel, UmbContentTypeDetailModel, UmbContentTypeSortModel } from '../types.js';
import { UmbContentTypeStructureManager } from '../structure/index.js';
import type { UmbContentTypeWorkspaceContext } from './content-type-workspace-context.interface.js';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { UmbDetailRepository } from '@umbraco-cms/backoffice/repository';
import {
Expand All @@ -6,10 +9,7 @@ import {
type UmbEntityDetailWorkspaceContextCreateArgs,
type UmbRoutableWorkspaceContext,
} from '@umbraco-cms/backoffice/workspace';
import type { UmbContentTypeWorkspaceContext } from './content-type-workspace-context.interface.js';
import type { UmbContentTypeCompositionModel, UmbContentTypeDetailModel, UmbContentTypeSortModel } from '../types.js';
import { UmbValidationContext } from '@umbraco-cms/backoffice/validation';
import { UmbContentTypeStructureManager } from '../structure/index.js';
import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models';
import { jsonStringComparison, type Observable } from '@umbraco-cms/backoffice/observable-api';
import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action';
Expand Down Expand Up @@ -221,7 +221,6 @@ export abstract class UmbContentTypeWorkspaceContextBase<
* Sets the compositions of the content type
* @param { string } compositions The compositions of the content type
* @returns { void }
*
*/
public setCompositions(compositions: Array<UmbContentTypeCompositionModel>) {
this.structure.updateOwnerContentType({ compositions } as Partial<DetailModelType>);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface UmbNumberRangeValueType {
max?: number;
}

// TODO: this needs to use the UmbEntityUnique so we ensure that unique can be null
export interface UmbReferenceByUnique {
unique: string;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ export type UmbSorterConfig<T, ElementType extends HTMLElement = HTMLElement> =
Partial<Pick<INTERNAL_UmbSorterConfig<T, ElementType>, 'ignorerSelector' | 'containerSelector' | 'identifier'>>;

/**
* @class UmbSorterController
* @implements {UmbControllerInterface}
* @description This controller can make user able to sort items.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UMB_ENTITY_DETAIL_WORKSPACE_CONTEXT } from '../entity-detail-workspace.context-token.js';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { css, customElement, html, ifDefined, nothing, property, state } from '@umbraco-cms/backoffice/external/lit';

@customElement('umb-entity-detail-workspace-editor')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import {
} from '../../paths.js';
import type { UmbDocumentTypeDetailModel } from '../../types.js';
import { UMB_DOCUMENT_TYPE_ENTITY_TYPE } from '../../entity.js';
import { UMB_DOCUMENT_TYPE_DETAIL_REPOSITORY_ALIAS } from '../../repository/index.js';
import { UmbDocumentTypeWorkspaceEditorElement } from './document-type-workspace-editor.element.js';
import { UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS } from './constants.js';
import { UmbContentTypeWorkspaceContextBase } from '@umbraco-cms/backoffice/content-type';
import {
UmbWorkspaceIsNewRedirectController,
Expand All @@ -18,8 +20,6 @@ import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models';
import type { UmbRoutableWorkspaceContext } from '@umbraco-cms/backoffice/workspace';
import type { UmbPathPatternTypeAsEncodedParamsType } from '@umbraco-cms/backoffice/router';
import { UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS } from './constants.js';
import { UMB_DOCUMENT_TYPE_DETAIL_REPOSITORY_ALIAS } from '../../repository/index.js';
import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity';
import { UmbTemplateDetailRepository } from '@umbraco-cms/backoffice/template';

Expand Down Expand Up @@ -185,6 +185,7 @@ export class UmbDocumentTypeWorkspaceContext

/**
* @deprecated Use the createScaffold method instead. Will be removed in 17.
* @param presetAlias
* @param {UmbEntityModel} parent
* @memberof UmbMediaTypeWorkspaceContext
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,24 @@ const getItems = (uniques: Array<string>) => DocumentService.getItemDocument({ i

const mapper = (item: DocumentItemResponseModel): UmbDocumentItemModel => {
return {
entityType: UMB_DOCUMENT_ENTITY_TYPE,
unique: item.id,
isTrashed: item.isTrashed,
isProtected: item.isProtected,
documentType: {
unique: item.documentType.id,
icon: item.documentType.icon,
collection: item.documentType.collection ? { unique: item.documentType.collection.id } : null,
icon: item.documentType.icon,
unique: item.documentType.id,
},
entityType: UMB_DOCUMENT_ENTITY_TYPE,
hasChildren: item.hasChildren,
isProtected: item.isProtected,
isTrashed: item.isTrashed,
name: item.variants[0]?.name, // TODO: this is not correct. We need to get it from the variants. This is a temp solution.
parent: item.parent ? { unique: item.parent.id } : null,
unique: item.id,
variants: item.variants.map((variant) => {
return {
culture: variant.culture || null,
name: variant.name,
state: variant.state,
};
}),
name: item.variants[0]?.name, // TODO: this is not correct. We need to get it from the variants. This is a temp solution.
};
};
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import type { UmbDocumentEntityType } from '../../entity.js';
import type { UmbEntityUnique } from '@umbraco-cms/backoffice/entity';
import type { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api';
import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models';

export interface UmbDocumentItemModel {
entityType: UmbDocumentEntityType;
name: string; // TODO: this is not correct. We need to get it from the variants. This is a temp solution.
unique: string;
isTrashed: boolean;
isProtected: boolean;
documentType: {
unique: string;
icon: string;
collection: UmbReferenceByUnique | null;
};
entityType: UmbDocumentEntityType;
hasChildren: boolean;
isProtected: boolean;
isTrashed: boolean;
name: string; // TODO: this is not correct. We need to get it from the variants. This is a temp solution.
parent: { unique: UmbEntityUnique } | null; // TODO: Use UmbReferenceByUnique when it support unique as null
unique: string;
variants: Array<UmbDocumentItemVariantModel>;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { UmbDocumentSearchServerDataSource } from './document-search.server.data-source.js';
import type { UmbDocumentSearchItemModel } from './document.search-provider.js';
import type { UmbDocumentSearchItemModel } from './types.js';
import type { UmbSearchRepository, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js';
import type { UmbDocumentSearchItemModel } from './document.search-provider.js';
import type { UmbDocumentSearchItemModel } from './types.js';
import type { UmbSearchDataSource, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { DocumentService } from '@umbraco-cms/backoffice/external/backend-api';
Expand Down Expand Up @@ -40,24 +40,26 @@ export class UmbDocumentSearchServerDataSource implements UmbSearchDataSource<Um
if (data) {
const mappedItems: Array<UmbDocumentSearchItemModel> = data.items.map((item) => {
return {
href: '/section/content/workspace/document/edit/' + item.id,
entityType: UMB_DOCUMENT_ENTITY_TYPE,
unique: item.id,
isTrashed: item.isTrashed,
isProtected: item.isProtected,
documentType: {
unique: item.documentType.id,
icon: item.documentType.icon,
collection: item.documentType.collection ? { unique: item.documentType.collection.id } : null,
icon: item.documentType.icon,
unique: item.documentType.id,
},
entityType: UMB_DOCUMENT_ENTITY_TYPE,
hasChildren: item.hasChildren,
href: '/section/content/workspace/document/edit/' + item.id,
isProtected: item.isProtected,
isTrashed: item.isTrashed,
name: item.variants[0]?.name, // TODO: this is not correct. We need to get it from the variants. This is a temp solution.
parent: item.parent ? { unique: item.parent.id } : null,
unique: item.id,
variants: item.variants.map((variant) => {
return {
culture: variant.culture || null,
name: variant.name,
state: variant.state,
};
}),
name: item.variants[0]?.name, // TODO: this is not correct. We need to get it from the variants. This is a temp solution.
};
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import type { UmbDocumentItemModel } from '../index.js';
import { UmbDocumentSearchRepository } from './document-search.repository.js';
import type { UmbDocumentSearchItemModel } from './types.js';
import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
export interface UmbDocumentSearchItemModel extends UmbDocumentItemModel {
href: string;
}

export class UmbDocumentSearchProvider
extends UmbControllerBase
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { UmbDocumentItemModel } from '../repository/index.js';

export interface UmbDocumentSearchItemModel extends UmbDocumentItemModel {
href: string;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { UMB_LANGUAGE_ROOT_ENTITY_TYPE } from '../../entity.js';
import { UMB_SETTINGS_SECTION_PATHNAME } from '@umbraco-cms/backoffice/settings';
import { UMB_WORKSPACE_PATH_PATTERN } from '@umbraco-cms/backoffice/workspace';
import { UMB_LANGUAGE_ROOT_ENTITY_TYPE } from '../../entity.js';

export const UMB_LANGUAGE_ROOT_WORKSPACE_PATH = UMB_WORKSPACE_PATH_PATTERN.generateAbsolute({
sectionName: UMB_SETTINGS_SECTION_PATHNAME,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { UMB_LANGUAGE_ROOT_WORKSPACE_PATH } from '../language-root/paths.js';
import { UMB_LANGUAGE_WORKSPACE_CONTEXT } from './language-workspace.context-token.js';
import { html, customElement, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { UMB_LANGUAGE_ROOT_WORKSPACE_PATH } from '../language-root/paths.js';
@customElement('umb-language-workspace-editor')
export class UmbLanguageWorkspaceEditorElement extends UmbLitElement {
#workspaceContext?: typeof UMB_LANGUAGE_WORKSPACE_CONTEXT.TYPE;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { UMB_MEDIA_TYPE_ENTITY_TYPE } from '../entity.js';
import type { UmbMediaTypeDetailModel } from '../types.js';
import { UMB_MEDIA_TYPE_DETAIL_REPOSITORY_ALIAS } from '../repository/index.js';
import { UmbMediaTypeWorkspaceEditorElement } from './media-type-workspace-editor.element.js';
import { UMB_MEDIA_TYPE_WORKSPACE_ALIAS } from './constants.js';
import {
type UmbRoutableWorkspaceContext,
UmbWorkspaceIsNewRedirectController,
Expand All @@ -9,8 +11,6 @@ import { UmbContentTypeWorkspaceContextBase } from '@umbraco-cms/backoffice/cont
import type { UmbContentTypeSortModel, UmbContentTypeWorkspaceContext } from '@umbraco-cms/backoffice/content-type';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models';
import { UMB_MEDIA_TYPE_WORKSPACE_ALIAS } from './constants.js';
import { UMB_MEDIA_TYPE_DETAIL_REPOSITORY_ALIAS } from '../repository/index.js';
import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity';

type DetailModelType = UmbMediaTypeDetailModel;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export class UmbMediaGridCollectionViewElement extends UmbLitElement {
<uui-card-media
name=${ifDefined(item.name)}
selectable
?select-only=${this._selection && this._selection.length > 0}
?select-only=${this._selection.length > 0}
?selected=${this.#isSelected(item)}
href=${this.#getEditUrl(item)}
@selected=${() => this.#onSelect(item)}
Expand Down Expand Up @@ -136,6 +136,11 @@ export class UmbMediaGridCollectionViewElement extends UmbLitElement {
font-style: italic;
}
/** TODO: Remove this fix when UUI gets upgrade to 1.3 */
umb-imaging-thumbnail {
pointer-events: none;
}
#media-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement {
collectionContext.workspacePathBuilder,
(builder) => {
this._workspacePathBuilder = builder;
this.#createTableItems();
},
'observePath',
);
Expand All @@ -86,7 +87,7 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement {
this.#collectionContext.items,
(items) => {
this._items = items;
this.#createTableItems(this._items);
this.#createTableItems();
},
'_observeItems',
);
Expand Down Expand Up @@ -117,12 +118,17 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement {
}
}

#createTableItems(items: Array<UmbMediaCollectionItemModel>) {
#createTableItems() {
this._tableItems = [];

if (this._items === undefined) return;
if (this._workspacePathBuilder === undefined) return;

if (this._tableColumns.length === 0) {
this.#createTableHeadings();
}

this._tableItems = items.map((item) => {
this._tableItems = this._items.map((item) => {
if (!item.unique) throw new Error('Item id is missing.');

const data =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,6 @@ export class UmbInputMediaElement extends UmbFormControlMixin<string | undefined
return html`
<uui-card-media
name=${ifDefined(item.name === null ? undefined : item.name)}
detail=${ifDefined(item.unique)}
href="${ifDefined(href)}"
?readonly=${this.readonly}>
<umb-imaging-thumbnail
Expand Down
Loading

0 comments on commit 16a5f8d

Please sign in to comment.