Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2501f8d
wip sortChildrenOfContent kind
madsrasmussen Apr 15, 2025
b2ff16c
Merge branch 'v16/dev' into v16/chore/rename-sort-children-of
madsrasmussen Apr 15, 2025
bb02713
export types
madsrasmussen Apr 15, 2025
44f0089
add modal token + consts
madsrasmussen Apr 15, 2025
d49df3f
Update manifests.ts
madsrasmussen Apr 15, 2025
92388d8
add content tree item model
madsrasmussen Apr 15, 2025
b314575
wip use umb-table element
madsrasmussen Apr 15, 2025
61ab9e2
set as prop
madsrasmussen Apr 15, 2025
adf3974
render sort icon
madsrasmussen Apr 15, 2025
cb5722a
prevent selection when sortable
madsrasmussen Apr 15, 2025
c1bb5c9
remove unused
madsrasmussen Apr 15, 2025
2619d49
clean up
madsrasmussen Apr 15, 2025
fcdef18
reflect sortable prop
madsrasmussen Apr 15, 2025
7ab0c37
start implementing sortChildrenOfContent
madsrasmussen Apr 15, 2025
bb387c5
render name and create date
madsrasmussen Apr 15, 2025
beaefe4
handle date ordering
madsrasmussen Apr 15, 2025
bae4d55
remove unused
madsrasmussen Apr 16, 2025
79f4989
clean up
madsrasmussen Apr 16, 2025
9c6c1ef
Merge branch 'v16/dev' into v16/chore/rename-sort-children-of
madsrasmussen Apr 22, 2025
d43a0b4
fix grab and grabbing styling for sortable table rows
madsrasmussen Apr 22, 2025
c3d48a1
render label when no children
madsrasmussen Apr 22, 2025
efa559e
Update sort-children-of-content-modal.element.ts
madsrasmussen Apr 22, 2025
7b65f46
fix styling of load more
madsrasmussen Apr 22, 2025
f1c2d5e
only allow sorting when all items are loaded
madsrasmussen Apr 22, 2025
6dd0941
Update index.js
madsrasmussen Apr 22, 2025
865467e
Merge branch 'v16/dev' into v16/chore/rename-sort-children-of
madsrasmussen Apr 23, 2025
bc6e0d4
Merge branch 'v16/dev' into v16/chore/split-sort-children-of
madsrasmussen Apr 23, 2025
8dd4f94
Merge branch 'v16/dev' into v16/chore/split-sort-children-of
nielslyngsoe Apr 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import fs from 'fs';
import path from 'path';
import { createImportMap } from '../importmap/index.js';

const ILLEGAL_CORE_IMPORTS_THRESHOLD = 6;
const ILLEGAL_CORE_IMPORTS_THRESHOLD = 5;
const SELF_IMPORTS_THRESHOLD = 0;
const BIDIRECTIONAL_IMPORTS_THRESHOLD = 18;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export const UMB_CONTENT_SECTION_ALIAS = 'Umb.Section.Content';
export * from './workspace/constants.js';
export * from './conditions/constants.js';
export * from './collection/constants.js';
export * from './conditions/constants.js';
export * from './tree/constants.js';
export * from './workspace/constants.js';
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { manifests as workspaceManifests } from './workspace/manifests.js';
import { manifests as conditionManifests } from './conditions/manifests.js';
import { manifests as collectionManifests } from './collection/manifests.js';
import { manifests as conditionManifests } from './conditions/manifests.js';
import { manifests as contentTreeManifests } from './tree/manifests.js';
import { manifests as workspaceManifests } from './workspace/manifests.js';

export const manifests = [...workspaceManifests, ...conditionManifests, ...collectionManifests];
export const manifests = [
...collectionManifests,
...conditionManifests,
...contentTreeManifests,
...workspaceManifests,
];
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './sort-children-of-content/constants.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { manifests as sortChildrenOfContentManifests } from './sort-children-of-content/manifests.js';
import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';

export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [...sortChildrenOfContentManifests];
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './modal/constants.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './sort-children-of-content.action.js';
export type * from './types.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { manifest as sortChildrenOfContentKindManifest } from './sort-children-of-content.action.kind.js';
import { manifests as modalManifests } from './modal/manifests.js';

import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';

export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [
sortChildrenOfContentKindManifest,
...modalManifests,
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export {
UMB_SORT_CHILDREN_OF_CONTENT_MODAL,
UMB_SORT_CHILDREN_OF_CONTENT_MODAL_ALIAS,
} from './sort-children-of-content-modal.token.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './sort-children-of-content-modal.token.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { UMB_SORT_CHILDREN_OF_CONTENT_MODAL_ALIAS } from './constants.js';
import type { ManifestModal } from '@umbraco-cms/backoffice/modal';

export const manifests: Array<ManifestModal> = [
{
type: 'modal',
alias: UMB_SORT_CHILDREN_OF_CONTENT_MODAL_ALIAS,
name: 'Sort Children Of Content Modal',
element: () => import('./sort-children-of-content-modal.element.js'),
},
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import type { UmbContentTreeItemModel } from '../../types.js';
import { customElement } from '@umbraco-cms/backoffice/external/lit';
import { UmbSortChildrenOfModalElement } from '@umbraco-cms/backoffice/tree';

@customElement('umb-sort-children-of-content-modal')
export class UmbSortChildrenOfContentModalElement extends UmbSortChildrenOfModalElement<UmbContentTreeItemModel> {
#localizeDateOptions: Intl.DateTimeFormatOptions = {
day: 'numeric',
month: 'short',
year: 'numeric',
hour: 'numeric',
minute: '2-digit',
};

protected override _setTableColumns() {
this._tableColumns = [
{
name: this.localize.term('general_name'),
alias: 'name',
allowSorting: this._hasMorePages() === false,
},
{
name: this.localize.term('content_createDate'),
alias: 'createDate',
allowSorting: this._hasMorePages() === false,
},
];
}

protected override _createTableItems() {
this._tableItems = this._children.map((treeItem) => {
// TODO: implement ItemDataResolver for document and media
// This will fix both the icon and the variant name
return {
id: treeItem.unique,
icon: 'icon-document',
data: [
{
columnAlias: 'name',
value: treeItem.name,
},
{
columnAlias: 'createDate',
value: this.localize.date(treeItem.createDate, this.#localizeDateOptions),
},
],
};
});
}

protected override _sortCompare(columnAlias: string, valueA: unknown, valueB: unknown): number {
if (columnAlias === 'createDate') {
return Date.parse(valueA as string) - Date.parse(valueB as string);
}

return super._sortCompare(columnAlias, valueA, valueB);
}

protected override _onLoadMore(event: PointerEvent): void {
super._onLoadMore(event);
// TODO: make nicer API for enable/disable orderBy for individual columns
const allowOrderBy = this._hasMorePages() === false;
this._tableColumns[0].allowSorting = allowOrderBy;
this._tableColumns[1].allowSorting = allowOrderBy;
}
}

export { UmbSortChildrenOfContentModalElement as element };

declare global {
interface HTMLElementTagNameMap {
['umb-sort-children-of-content-modal']: UmbSortChildrenOfContentModalElement;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
import type { UmbSortChildrenOfModalData, UmbSortChildrenOfModalValue } from '@umbraco-cms/backoffice/tree';

export const UMB_SORT_CHILDREN_OF_CONTENT_MODAL_ALIAS = 'Umb.Modal.SortChildrenOfContent';

export const UMB_SORT_CHILDREN_OF_CONTENT_MODAL = new UmbModalToken<
UmbSortChildrenOfModalData,
UmbSortChildrenOfModalValue
>(UMB_SORT_CHILDREN_OF_CONTENT_MODAL_ALIAS, {
modal: {
type: 'sidebar',
size: 'small',
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';
import { UMB_ENTITY_ACTION_SORT_CHILDREN_OF_KIND_MANIFEST } from '@umbraco-cms/backoffice/tree';

export const manifest: UmbExtensionManifestKind = {
type: 'kind',
alias: 'Umb.Kind.EntityAction.SortChildrenOfContent',
matchKind: 'sortChildrenOfContent',
matchType: 'entityAction',
manifest: {
...UMB_ENTITY_ACTION_SORT_CHILDREN_OF_KIND_MANIFEST.manifest,
type: 'entityAction',
kind: 'sortChildrenOfContent',
api: () => import('./sort-children-of-content.action.js'),
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { UMB_SORT_CHILDREN_OF_CONTENT_MODAL } from './constants.js';
import type { UmbModalToken } from '@umbraco-cms/backoffice/modal';
import {
UmbSortChildrenOfEntityAction,
type UmbSortChildrenOfModalData,
type UmbSortChildrenOfModalValue,
} from '@umbraco-cms/backoffice/tree';

/**
* Entity action for sorting children of a content item
* @class UmbSortChildrenOfContentEntityAction
* @augments UmbSortChildrenOfEntityAction
*/
export class UmbSortChildrenOfContentEntityAction extends UmbSortChildrenOfEntityAction {
protected override _getModalToken(): UmbModalToken<UmbSortChildrenOfModalData, UmbSortChildrenOfModalValue> {
return UMB_SORT_CHILDREN_OF_CONTENT_MODAL;
}
}

export { UmbSortChildrenOfContentEntityAction as api };
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { ManifestEntityAction } from '@umbraco-cms/backoffice/entity-action';
import type { MetaEntityActionSortChildrenOfKind } from '@umbraco-cms/backoffice/tree';

export interface ManifestEntityActionSortChildrenOfContentKind
extends ManifestEntityAction<MetaEntityActionSortChildrenOfKind> {
type: 'entityAction';
kind: 'sortChildrenOfContent';
}

declare global {
interface UmbExtensionManifestMap {
umbManifestEntityActionSortChildrenOfContentKind: ManifestEntityActionSortChildrenOfContentKind;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity';
import type { UmbTreeItemModel } from '@umbraco-cms/backoffice/tree';

export type * from './sort-children-of-content/types.js';

export interface UmbContentTreeItemModel extends UmbTreeItemModel {
ancestors: Array<UmbEntityModel>;
entityType: string;
createDate: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { UmbPropertyValueData } from '@umbraco-cms/backoffice/property';
import type { UmbEntityVariantModel } from '@umbraco-cms/backoffice/variant';

export type * from './collection/types.js';
export type * from './tree/types.js';

export interface UmbElementDetailModel {
values: Array<UmbElementValueModel>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import {
repeat,
state,
when,
LitElement,
} from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbSorterController } from '@umbraco-cms/backoffice/sorter';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';

// TODO: move to UI Library - entity actions should NOT be moved to UI Library but stay in an UmbTable element
export interface UmbTableItem {
id: string;
icon?: string | null;
Expand Down Expand Up @@ -64,6 +64,19 @@ export class UmbTableOrderedEvent extends Event {
}
}

export class UmbTableSortedEvent extends Event {
#itemId: string;

public constructor({ itemId }: { itemId: string }) {
super('sorted', { bubbles: true, composed: true });
this.#itemId = itemId;
}

public getItemId() {
return this.#itemId;
}
}

/**
* @element umb-table
* @description - Element for displaying a table
Expand All @@ -73,14 +86,21 @@ export class UmbTableOrderedEvent extends Event {
* @augments LitElement
*/
@customElement('umb-table')
export class UmbTableElement extends LitElement {
export class UmbTableElement extends UmbLitElement {
/**
* Table Items
* @type {Array<UmbTableItem>}
* @memberof UmbTableElement
*/
@property({ type: Array, attribute: false })
public items: Array<UmbTableItem> = [];
private _items: Array<UmbTableItem> = [];
public get items(): Array<UmbTableItem> {
return this._items;
}
public set items(value: Array<UmbTableItem>) {
this._items = value;
this.#sorter.setModel(value);
}

/**
* @description Table Columns
Expand Down Expand Up @@ -115,9 +135,53 @@ export class UmbTableElement extends LitElement {
@property({ type: Boolean, attribute: false })
public orderingDesc = false;

private _sortable = false;
@property({ type: Boolean, reflect: true })
get sortable() {
return this._sortable;
}
set sortable(newVal) {
const oldVal = this._sortable;
if (oldVal === newVal) return;
this._sortable = newVal;

if (this._sortable) {
this.#sorter.enable();
} else {
this.#sorter.disable();
}

this.requestUpdate('sortable', oldVal);
}

@state()
private _selectionMode = false;

#sorter = new UmbSorterController<UmbTableItem>(this, {
getUniqueOfElement: (element) => {
return element.dataset.sortableId;
},
getUniqueOfModel: (item) => {
return item.id;
},
identifier: 'Umb.SorterIdentifier.UmbTable',
itemSelector: 'uui-table-row',
containerSelector: 'uui-table',
onChange: ({ model }) => {
const oldValue = this.items;
this.items = model;
this.requestUpdate('items', oldValue);
},
onEnd: ({ item }) => {
this.dispatchEvent(new UmbTableSortedEvent({ itemId: item.id }));
},
});

constructor() {
super();
this.#sorter.disable();
}

private _isSelected(key: string) {
return this.selection.includes(key);
}
Expand Down Expand Up @@ -230,7 +294,8 @@ export class UmbTableElement extends LitElement {
private _renderRow = (item: UmbTableItem) => {
return html`
<uui-table-row
?selectable="${this.config.allowSelection}"
data-sortable-id=${item.id}
?selectable="${this.config.allowSelection && !this._sortable}"
?select-only=${this._selectionMode}
?selected=${this._isSelected(item.id)}
@selected=${() => this._selectRow(item.id)}
Expand All @@ -241,6 +306,12 @@ export class UmbTableElement extends LitElement {
};

private _renderRowCheckboxCell(item: UmbTableItem) {
if (this.sortable === true) {
return html`<uui-table-cell style="text-align: center;">
<uui-icon name="icon-grip"></uui-icon>
</uui-table-cell>`;
}

if (this.config.hideIcon && !this.config.allowSelection) return;

return html`
Expand Down Expand Up @@ -301,6 +372,16 @@ export class UmbTableElement extends LitElement {
height: fit-content;
}

:host([sortable]) {
uui-table-row:hover {
cursor: grab;
}

uui-table-row:active {
cursor: grabbing;
}
}

uui-table {
box-shadow: var(--uui-shadow-depth-1);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './modal/constants.js';
export { UMB_ENTITY_ACTION_SORT_CHILDREN_OF_KIND_MANIFEST } from './sort-children-of.action.kind.js';
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { UmbSortChildrenOfEntityAction } from './sort-children-of.action.js';
export * from './modal/index.js';
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './sort-children-of-modal.token.js';
export * from './sort-children-of-modal.element.js';
Loading