renaming
This commit is contained in:
@@ -1 +1 @@
|
|||||||
import './input-user-group/input-user-group.element';
|
import './input-user-group/user-group-input.element';
|
||||||
|
|||||||
@@ -1,99 +0,0 @@
|
|||||||
import { UUITextStyles } from '@umbraco-ui/uui-css';
|
|
||||||
import { css, html, nothing } from 'lit';
|
|
||||||
import { customElement, state } from 'lit/decorators.js';
|
|
||||||
import { UmbInputListBaseElement } from '../../../../core/components/input-list-base/input-list-base';
|
|
||||||
import { UmbUserGroupStore, UMB_USER_GROUP_STORE_CONTEXT_TOKEN } from '../../repository/user-group.store';
|
|
||||||
import type { UserGroupEntity } from '../../types';
|
|
||||||
import { UMB_USER_GROUP_PICKER_MODAL } from '@umbraco-cms/backoffice/modal';
|
|
||||||
|
|
||||||
@customElement('umb-input-user-group')
|
|
||||||
export class UmbInputPickerUserGroupElement extends UmbInputListBaseElement {
|
|
||||||
@state()
|
|
||||||
private _userGroups: Array<UserGroupEntity> = [];
|
|
||||||
|
|
||||||
private _userGroupStore?: UmbUserGroupStore;
|
|
||||||
|
|
||||||
connectedCallback(): void {
|
|
||||||
super.connectedCallback();
|
|
||||||
this.pickerToken = UMB_USER_GROUP_PICKER_MODAL;
|
|
||||||
this.consumeContext(UMB_USER_GROUP_STORE_CONTEXT_TOKEN, (usersContext) => {
|
|
||||||
this._userGroupStore = usersContext;
|
|
||||||
//this._observeUserGroups();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
private _observeUserGroups() {
|
|
||||||
if (this.value.length > 0 && this._userGroupStore) {
|
|
||||||
this.observe(this._userGroupStore.getByKeys(this.value), (userGroups) => (this._userGroups = userGroups));
|
|
||||||
} else {
|
|
||||||
this._userGroups = [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
selectionUpdated() {
|
|
||||||
//this._observeUserGroups();
|
|
||||||
this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }));
|
|
||||||
}
|
|
||||||
|
|
||||||
private _renderUserGroupList() {
|
|
||||||
if (this._userGroups.length === 0) return nothing;
|
|
||||||
|
|
||||||
return html`<div id="user-list">
|
|
||||||
${this._userGroups.map(
|
|
||||||
(userGroup) => html`
|
|
||||||
<div class="user-group">
|
|
||||||
<div>
|
|
||||||
<uui-icon .name=${userGroup.icon}></uui-icon>
|
|
||||||
<span>${userGroup.name}</span>
|
|
||||||
</div>
|
|
||||||
<uui-button
|
|
||||||
@click=${() => this.removeFromSelection(userGroup.id)}
|
|
||||||
label="remove"
|
|
||||||
color="danger"></uui-button>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
</div> `;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderContent() {
|
|
||||||
return html`${this._renderUserGroupList()}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
static styles = [
|
|
||||||
UUITextStyles,
|
|
||||||
css`
|
|
||||||
:host {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: var(--uui-size-space-4);
|
|
||||||
}
|
|
||||||
#user-group-list {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: var(--uui-size-space-4);
|
|
||||||
}
|
|
||||||
.user-group {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: var(--uui-size-space-2);
|
|
||||||
}
|
|
||||||
.user-group div {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: var(--uui-size-4);
|
|
||||||
}
|
|
||||||
.user-group uui-button {
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface HTMLElementTagNameMap {
|
|
||||||
'umb-input-user-group': UmbInputPickerUserGroupElement;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import { Meta, StoryObj } from '@storybook/web-components';
|
|
||||||
import './input-user-group.element';
|
|
||||||
import type { UmbInputPickerUserGroupElement } from './input-user-group.element';
|
|
||||||
|
|
||||||
const meta: Meta<UmbInputPickerUserGroupElement> = {
|
|
||||||
title: 'Components/Inputs/User Group',
|
|
||||||
component: 'umb-user-group-input',
|
|
||||||
argTypes: {
|
|
||||||
modalType: {
|
|
||||||
control: 'inline-radio',
|
|
||||||
options: ['dialog', 'sidebar'],
|
|
||||||
defaultValue: 'sidebar',
|
|
||||||
description: 'The type of modal to use when selecting user groups',
|
|
||||||
},
|
|
||||||
modalSize: {
|
|
||||||
control: 'select',
|
|
||||||
options: ['small', 'medium', 'large', 'full'],
|
|
||||||
defaultValue: 'small',
|
|
||||||
description: 'The size of the modal to use when selecting user groups, only applicable to sidebar not dialog',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default meta;
|
|
||||||
type Story = StoryObj<UmbInputPickerUserGroupElement>;
|
|
||||||
|
|
||||||
export const Overview: Story = {
|
|
||||||
args: {},
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
import { css, html } from 'lit';
|
||||||
|
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||||
|
import { customElement, property, state } from 'lit/decorators.js';
|
||||||
|
import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins';
|
||||||
|
import { UmbUserGroupPickerContext } from './user-group-input.context';
|
||||||
|
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||||
|
import type { UserItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||||
|
|
||||||
|
@customElement('umb-user-group-input')
|
||||||
|
export class UmbUserGroupInputElement extends FormControlMixin(UmbLitElement) {
|
||||||
|
/**
|
||||||
|
* This is a minimum amount of selected items in this input.
|
||||||
|
* @type {number}
|
||||||
|
* @attr
|
||||||
|
* @default 0
|
||||||
|
*/
|
||||||
|
@property({ type: Number })
|
||||||
|
public get min(): number {
|
||||||
|
return this.#pickerContext.min;
|
||||||
|
}
|
||||||
|
public set min(value: number) {
|
||||||
|
this.#pickerContext.min = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Min validation message.
|
||||||
|
* @type {boolean}
|
||||||
|
* @attr
|
||||||
|
* @default
|
||||||
|
*/
|
||||||
|
@property({ type: String, attribute: 'min-message' })
|
||||||
|
minMessage = 'This field need more items';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a maximum amount of selected items in this input.
|
||||||
|
* @type {number}
|
||||||
|
* @attr
|
||||||
|
* @default Infinity
|
||||||
|
*/
|
||||||
|
@property({ type: Number })
|
||||||
|
public get max(): number {
|
||||||
|
return this.#pickerContext.max;
|
||||||
|
}
|
||||||
|
public set max(value: number) {
|
||||||
|
this.#pickerContext.max = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Max validation message.
|
||||||
|
* @type {boolean}
|
||||||
|
* @attr
|
||||||
|
* @default
|
||||||
|
*/
|
||||||
|
@property({ type: String, attribute: 'min-message' })
|
||||||
|
maxMessage = 'This field exceeds the allowed amount of items';
|
||||||
|
|
||||||
|
public get selectedIds(): Array<string> {
|
||||||
|
return this.#pickerContext.getSelection();
|
||||||
|
}
|
||||||
|
public set selectedIds(ids: Array<string>) {
|
||||||
|
this.#pickerContext.setSelection(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
@property()
|
||||||
|
public set value(idsString: string) {
|
||||||
|
console.log('set value', idsString);
|
||||||
|
|
||||||
|
// Its with full purpose we don't call super.value, as thats being handled by the observation of the context selection.
|
||||||
|
this.selectedIds = idsString.split(/[ ,]+/);
|
||||||
|
}
|
||||||
|
|
||||||
|
@state()
|
||||||
|
private _items?: Array<UserItemResponseModel>;
|
||||||
|
|
||||||
|
#pickerContext = new UmbUserGroupPickerContext(this);
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.addValidator(
|
||||||
|
'rangeUnderflow',
|
||||||
|
() => this.minMessage,
|
||||||
|
() => !!this.min && this.#pickerContext.getSelection().length < this.min
|
||||||
|
);
|
||||||
|
|
||||||
|
this.addValidator(
|
||||||
|
'rangeOverflow',
|
||||||
|
() => this.maxMessage,
|
||||||
|
() => !!this.max && this.#pickerContext.getSelection().length > this.max
|
||||||
|
);
|
||||||
|
|
||||||
|
this.observe(this.#pickerContext.selection, (selection) => (super.value = selection.join(',')));
|
||||||
|
this.observe(this.#pickerContext.selectedItems, (selectedItems) => (this._items = selectedItems));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected getFormElement() {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<uui-ref-list>${this._items?.map((item) => this._renderItem(item))}</uui-ref-list>
|
||||||
|
<uui-button id="add-button" look="placeholder" @click=${() => this.#pickerContext.openPicker()} label="open"
|
||||||
|
>Add</uui-button
|
||||||
|
>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _renderItem(item: UserItemResponseModel) {
|
||||||
|
if (!item.id) return;
|
||||||
|
return html`
|
||||||
|
<uui-ref-node-user name=${item.name}>
|
||||||
|
<uui-action-bar slot="actions">
|
||||||
|
<uui-button @click=${() => this.#pickerContext.requestRemoveItem(item.id!)} label="Remove ${item.name}"
|
||||||
|
>Remove</uui-button
|
||||||
|
>
|
||||||
|
</uui-action-bar>
|
||||||
|
</uui-ref-node-user>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static styles = [
|
||||||
|
UUITextStyles,
|
||||||
|
css`
|
||||||
|
#add-button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default UmbUserGroupInputElement;
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
'umb-user-group-input': UmbUserGroupInputElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { Meta, StoryObj } from '@storybook/web-components';
|
||||||
|
import './input-user-group.element';
|
||||||
|
import type { UmbUserGroupInputElement } from './user-group-input.element';
|
||||||
|
|
||||||
|
const meta: Meta<UmbUserGroupInputElement> = {
|
||||||
|
title: 'Components/Inputs/User Group',
|
||||||
|
component: 'umb-input-user-group',
|
||||||
|
argTypes: {
|
||||||
|
// modalType: {
|
||||||
|
// control: 'inline-radio',
|
||||||
|
// options: ['dialog', 'sidebar'],
|
||||||
|
// defaultValue: 'sidebar',
|
||||||
|
// description: 'The type of modal to use when selecting user groups',
|
||||||
|
// },
|
||||||
|
// modalSize: {
|
||||||
|
// control: 'select',
|
||||||
|
// options: ['small', 'medium', 'large', 'full'],
|
||||||
|
// defaultValue: 'small',
|
||||||
|
// description: 'The size of the modal to use when selecting user groups, only applicable to sidebar not dialog',
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
type Story = StoryObj<UmbUserGroupInputElement>;
|
||||||
|
|
||||||
|
export const Overview: Story = {
|
||||||
|
args: {},
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user