Skip to content

Commit

Permalink
#19562 add white list feature to key value webcomponent (#1900)
Browse files Browse the repository at this point in the history
* dot-key-value: Added reorder functionality

* #19562 Allow whitelist key-values in dot-key-value webcomponent

* Feedback
  • Loading branch information
alfredo-dotcms authored Mar 3, 2022
1 parent 48e27db commit ff66fd5
Show file tree
Hide file tree
Showing 9 changed files with 422 additions and 60 deletions.
44 changes: 44 additions & 0 deletions libs/dotcms-webcomponents/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -624,10 +624,22 @@ export namespace Components {
* Reset properties of the field, clear value and emit events.
*/
"reset": () => Promise<void>;
/**
* (optional) Allows unique keys only
*/
"uniqueKeys": boolean;
/**
* Value of the field
*/
"value": string;
/**
* (optional) The string containing the value to be parsed for whitelist key/value
*/
"whiteList": string;
/**
* (optional) The string to use in the empty option of whitelist dropdown key/value item
*/
"whiteListEmptyOptionLabel": string;
}
interface DotLabel {
/**
Expand Down Expand Up @@ -1024,6 +1036,10 @@ export namespace Components {
* (optional) Disables all form interaction
*/
"disabled": boolean;
/**
* (optional) Label for the empty option in white-list select
*/
"emptyDropdownOptionLabel": string;
/**
* (optional) The string to use in the key input label
*/
Expand All @@ -1040,6 +1056,10 @@ export namespace Components {
* (optional) Placeholder for the value input text
*/
"valuePlaceholder": string;
/**
* (optional) The string to use for white-list key/values
*/
"whiteList": string;
}
interface KeyValueTable {
/**
Expand Down Expand Up @@ -1961,10 +1981,22 @@ declare namespace LocalJSX {
* (optional) Text that will be shown when required is set and condition is not met
*/
"requiredMessage"?: string;
/**
* (optional) Allows unique keys only
*/
"uniqueKeys"?: boolean;
/**
* Value of the field
*/
"value"?: string;
/**
* (optional) The string containing the value to be parsed for whitelist key/value
*/
"whiteList"?: string;
/**
* (optional) The string to use in the empty option of whitelist dropdown key/value item
*/
"whiteListEmptyOptionLabel"?: string;
}
interface DotLabel {
/**
Expand Down Expand Up @@ -2346,6 +2378,10 @@ declare namespace LocalJSX {
* (optional) Disables all form interaction
*/
"disabled"?: boolean;
/**
* (optional) Label for the empty option in white-list select
*/
"emptyDropdownOptionLabel"?: string;
/**
* (optional) The string to use in the key input label
*/
Expand All @@ -2370,6 +2406,10 @@ declare namespace LocalJSX {
* (optional) Placeholder for the value input text
*/
"valuePlaceholder"?: string;
/**
* (optional) The string to use for white-list key/values
*/
"whiteList"?: string;
}
interface KeyValueTable {
/**
Expand All @@ -2392,6 +2432,10 @@ declare namespace LocalJSX {
* Emit the index of the item deleted from the list
*/
"onDelete"?: (event: CustomEvent<number>) => void;
/**
* Emit the notification of list reordered
*/
"onReorder"?: (event: CustomEvent<any>) => void;
}
interface IntrinsicElements {
"dot-asset-drop-zone": DotAssetDropZone;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
key-value-form form {
display: flex;
align-items: center;

button {
margin: 0;
}

input {
margin: 0 1rem 0 0.5rem;
}

label {
align-items: center;
display: flex;
flex-grow: 1;
}

table {
width: 100%;

input {
flex-grow: 1;
width: 100%;
}
}

.key-value-table-form__key {
width: 45%;
}

.key-value-table-form__value {
width: 45%;
}

.key-value-table-form__action {
text-align: right;
width: 10%;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, Prop, State, Element, Event, EventEmitter, h } from '@stencil/core';
import { Component, Prop, State, Element, Event, EventEmitter, h, Watch } from '@stencil/core';
import { DotKeyValueField } from '../../../../../models';

const DEFAULT_VALUE = { key: '', value: '' };
Expand Down Expand Up @@ -45,6 +45,18 @@ export class DotKeyValueComponent {
})
valueLabel = 'Value';

/** (optional) Label for the empty option in white-list select */
@Prop({
reflect: true
})
emptyDropdownOptionLabel = 'Pick an option';

/** (optional) The string to use for white-list key/values */
@Prop({
reflect: true
})
whiteList = '';

/** Emit the added value, key/value pair */
@Event()
add: EventEmitter<DotKeyValueField>;
Expand All @@ -56,12 +68,48 @@ export class DotKeyValueComponent {
@State()
inputs: DotKeyValueField = { ...DEFAULT_VALUE };

@State()
selectedWhiteListKey = '';

@Watch('selectedWhiteListKey')
selectedWhiteListKeyWatch(): void {
/* */
}

private whiteListArray = {};

componentWillLoad(): void {
this.whiteListArray = this.whiteList.length ? JSON.parse(this.whiteList) : '';
}

render() {
const buttonDisabled = this.isButtonDisabled();
return (
<form onSubmit={this.addKey.bind(this)}>
<label>
{this.keyLabel}
<table>
<tbody>
<tr>
<td class="key-value-table-form__key">
<label>{this.keyLabel}</label>
</td>
<td class="key-value-table-form__value">
<label>{this.valueLabel}</label>
</td>
<td class="key-value-table-form__action"></td>
</tr>
{Object.keys(this.whiteListArray).length === 0
? this.getKeyValueForm(buttonDisabled)
: this.getWhiteListForm(buttonDisabled)}
</tbody>
</table>
</form>
);
}

private getKeyValueForm(buttonDisabled: boolean): JSX.Element {
return (
<tr>
<td class="key-value-table-form__key">
<input
disabled={this.disabled}
name="key"
Expand All @@ -71,9 +119,8 @@ export class DotKeyValueComponent {
type="text"
value={this.inputs.key}
/>
</label>
<label>
{this.valueLabel}
</td>
<td class="key-value-table-form__value">
<input
disabled={this.disabled}
name="value"
Expand All @@ -83,18 +130,99 @@ export class DotKeyValueComponent {
type="text"
value={this.inputs.value}
/>
</label>
<button
class="key-value-form__save__button"
type="submit"
disabled={buttonDisabled}
>
{this.addButtonLabel}
</button>
</form>
</td>
<td class="key-value-table-form__action">
<button
class="key-value-form__save__button"
type="submit"
disabled={buttonDisabled}
>
{this.addButtonLabel}
</button>
</td>
</tr>
);
}

private getWhiteListForm(buttonDisabled: boolean): JSX.Element {
return (
<tr>
<td class="key-value-table-form__key">{this.getWhiteListKeysDropdown()}</td>
<td class="key-value-table-form__value">
{this.selectedWhiteListKey ? this.getWhiteListValueControl() : null}
</td>
<td class="key-value-table-form__action">
<button
class="key-value-form__save__button"
type="submit"
disabled={buttonDisabled}
>
{this.addButtonLabel}
</button>
</td>
</tr>
);
}

private getWhiteListValueControl(): boolean {
return this.whiteListArray[this.selectedWhiteListKey].length ? (
this.getWhiteListValuesDropdown()
) : (
<input
disabled={this.disabled}
name="value"
onBlur={(e: FocusEvent) => this.lostFocus.emit(e)}
onInput={(event: Event) => this.setValue(event)}
placeholder={this.valuePlaceholder}
type="text"
value={this.inputs.value}
/>
);
}

private getWhiteListKeysDropdown(): JSX.Element {
return (
<select
disabled={this.disabled}
name="key"
onChange={(event: Event) => this.changeWhiteListKey(event)}
>
<option value="">{this.emptyDropdownOptionLabel}</option>
{Object.keys(this.whiteListArray).map((key: string) => {
return <option value={key}>{key}</option>;
})}
</select>
);
}

private getWhiteListValuesDropdown(): JSX.Element {
return (
<select
disabled={this.disabled}
name="value"
onChange={(event: Event) => this.changeWhiteListValue(event)}
>
<option value="">{this.emptyDropdownOptionLabel}</option>
{this.whiteListArray[this.selectedWhiteListKey].map((item: string) => {
return <option value={item}>{item}</option>;
})}
</select>
);
}

private changeWhiteListKey(event: Event): void {
event.stopImmediatePropagation();
this.clearForm();
const target = event.target as HTMLInputElement;
this.selectedWhiteListKey = target.value;
this.setValue(event);
}

private changeWhiteListValue(event: Event): void {
event.stopImmediatePropagation();
this.setValue(event);
}

private isButtonDisabled(): boolean {
return !this.isFormValid() || this.disabled || null;
}
Expand Down Expand Up @@ -129,7 +257,7 @@ export class DotKeyValueComponent {
}

private focusKeyInputField(): void {
const input: HTMLInputElement = this.el.querySelector('input[name="key"]');
const input: HTMLInputElement = this.el.querySelector('[name="key"]');
input.focus();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@

## Properties

| Property | Attribute | Description | Type | Default |
| ------------------ | ------------------- | ----------------------------------------------------- | --------- | --------- |
| `addButtonLabel` | `add-button-label` | (optional) Label for the add item button | `string` | `'Add'` |
| `disabled` | `disabled` | (optional) Disables all form interaction | `boolean` | `false` |
| `keyLabel` | `key-label` | (optional) The string to use in the key input label | `string` | `'Key'` |
| `keyPlaceholder` | `key-placeholder` | (optional) Placeholder for the key input text | `string` | `''` |
| `valueLabel` | `value-label` | (optional) The string to use in the value input label | `string` | `'Value'` |
| `valuePlaceholder` | `value-placeholder` | (optional) Placeholder for the value input text | `string` | `''` |
| Property | Attribute | Description | Type | Default |
| -------------------------- | ----------------------------- | ---------------------------------------------------------- | --------- | ------------------ |
| `addButtonLabel` | `add-button-label` | (optional) Label for the add item button | `string` | `'Add'` |
| `disabled` | `disabled` | (optional) Disables all form interaction | `boolean` | `false` |
| `emptyDropdownOptionLabel` | `empty-dropdown-option-label` | (optional) Label for the empty option in white-list select | `string` | `'Pick an option'` |
| `keyLabel` | `key-label` | (optional) The string to use in the key input label | `string` | `'Key'` |
| `keyPlaceholder` | `key-placeholder` | (optional) Placeholder for the key input text | `string` | `''` |
| `valueLabel` | `value-label` | (optional) The string to use in the value input label | `string` | `'Value'` |
| `valuePlaceholder` | `value-placeholder` | (optional) Placeholder for the value input text | `string` | `''` |
| `whiteList` | `white-list` | (optional) The string to use for white-list key/values | `string` | `''` |


## Events
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
key-value-table {

table {
width: 100%;
}

.key-value-table-wc__key {
padding-left: 5%;
width: 45%;
}

.key-value-table-wc__value {
padding-left: 9%;
width: 45%;
}

.key-value-table-wc__action {
text-align: right;
width: 10%;
}

.key-value-table-wc__placeholder-transit {
border-bottom: 1px solid;
}
}
Loading

0 comments on commit ff66fd5

Please sign in to comment.