MultiText enhancement when Options are provided.
This commit is contained in:
parent
27e0e76884
commit
bbe3aa22fd
|
|
@ -0,0 +1,17 @@
|
|||
:host {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tag-input:focus {
|
||||
outline: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.pr-8 {
|
||||
padding-right: 2rem !important;
|
||||
}
|
||||
|
||||
.bg-green-350 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgba(52,191,113,var(--tw-bg-opacity));
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
import { Component, h, Prop, Event, EventEmitter, State, Watch } from '@stencil/core';
|
||||
import { MultiTextDefinition } from '../../../models/domain';
|
||||
|
||||
@Component({
|
||||
tag: 'elsa-input-tags-dropdown',
|
||||
styleUrl: 'elsa-input-tags-dropdown.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class ElsaInputTagsDropdown {
|
||||
|
||||
@Prop() fieldName?: string;
|
||||
@Prop() fieldId?: string;
|
||||
@Prop() placeHolder?: string = 'Add tag';
|
||||
@Prop() values?: Array<string | MultiTextDefinition> = [];
|
||||
@Prop() dropdownValues?: Array<MultiTextDefinition> = [];
|
||||
@Event({ bubbles: true }) valueChanged: EventEmitter<Array<string | MultiTextDefinition>>;
|
||||
@State() currentValues?: Array<MultiTextDefinition> = [];
|
||||
@State() dropdownTags?: Array<MultiTextDefinition> = [];
|
||||
|
||||
@Watch('values')
|
||||
valuesChangedHandler(newValue: Array<string | MultiTextDefinition>) {
|
||||
let values: Array<MultiTextDefinition> = [];
|
||||
|
||||
newValue.forEach(value => {
|
||||
this.dropdownValues.forEach(tag => {
|
||||
if (value === tag.value) {
|
||||
values.push(tag);
|
||||
}
|
||||
})
|
||||
})
|
||||
this.currentValues = values || [];
|
||||
}
|
||||
|
||||
componentWillLoad() {
|
||||
this.dropdownTags = this.dropdownValues;
|
||||
let values: Array<MultiTextDefinition> = [];
|
||||
|
||||
this.values.forEach(value => {
|
||||
this.dropdownValues.forEach(tag => {
|
||||
if (value === tag.value) {
|
||||
values.push(tag);
|
||||
}
|
||||
})
|
||||
})
|
||||
this.currentValues = values;
|
||||
|
||||
const tagsToRemove: Array<string> = this.currentValues.map(tag => tag.value);
|
||||
this.dropdownTags = this.dropdownTags.filter(tag => !tagsToRemove.includes(tag.value));
|
||||
}
|
||||
|
||||
async onTagSelected(e: any) {
|
||||
e.preventDefault();
|
||||
|
||||
const input = e.target as HTMLSelectElement;
|
||||
const currentTag: MultiTextDefinition = {
|
||||
text: input.options[input.selectedIndex].text.trim(),
|
||||
value: input.value
|
||||
}
|
||||
|
||||
if (currentTag.value.length == 0)
|
||||
return;
|
||||
|
||||
const values: Array<MultiTextDefinition> = [...this.currentValues];
|
||||
values.push(currentTag);
|
||||
this.currentValues = values.distinct();
|
||||
input.value = "Add";
|
||||
this.dropdownTags = this.dropdownTags.filter(tag => tag.value !== currentTag.value);
|
||||
await this.valueChanged.emit(values);
|
||||
}
|
||||
|
||||
async onDeleteTagClick(e: any, currentTag: MultiTextDefinition) {
|
||||
e.preventDefault();
|
||||
|
||||
this.currentValues = this.currentValues.filter(tag => tag.value !== currentTag.value);
|
||||
this.dropdownTags = [...this.dropdownTags, currentTag].sort((tag1, tag2) => tag1.value.localeCompare(tag2.value));
|
||||
await this.valueChanged.emit(this.currentValues);
|
||||
}
|
||||
|
||||
render() {
|
||||
let values: Array<MultiTextDefinition> = this.currentValues || [];
|
||||
|
||||
if (!Array.isArray(values))
|
||||
values = [];
|
||||
|
||||
const valuesJson = JSON.stringify(values.map(tag => tag.value));
|
||||
|
||||
return (
|
||||
<div class="py-2 px-3 bg-white shadow-sm border border-gray-300 rounded-md">
|
||||
{values.map(tag =>
|
||||
(
|
||||
<a href="#" onClick={e => this.onDeleteTagClick(e, tag)} class="inline-block text-xs bg-blue-400 text-white py-2 px-3 mr-1 mb-1 rounded">
|
||||
<input type="hidden" value={tag.value} />
|
||||
<span>{tag.text}</span>
|
||||
<span class="text-white hover:text-white ml-1">×</span>
|
||||
</a>
|
||||
))}
|
||||
|
||||
<select id={this.fieldId} class="inline-block text-xs bg-green-350 text-white py-2 px-3 mr-1 mb-1 pr-8 rounded" onChange={(e) => this.onTagSelected(e)}>
|
||||
<option value="Add" disabled selected>{this.placeHolder}</option>
|
||||
{this.dropdownTags.map(tag =>
|
||||
(
|
||||
<option value={tag.value}>
|
||||
<span>{tag.text}</span>
|
||||
</option>
|
||||
)
|
||||
)}
|
||||
</select>
|
||||
<input type="hidden" name={this.fieldName} value={valuesJson} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import {Component, h, Prop, State} from '@stencil/core';
|
||||
import {ActivityDefinitionProperty, ActivityPropertyDescriptor, SyntaxNames} from "../../../../models";
|
||||
import {ActivityDefinitionProperty, ActivityPropertyDescriptor, SyntaxNames, MultiTextDefinition} from "../../../../models";
|
||||
import {parseJson} from "../../../../utils/utils";
|
||||
|
||||
@Component({
|
||||
|
|
@ -11,14 +11,20 @@ export class ElsaMultiTextProperty {
|
|||
|
||||
@Prop() propertyDescriptor: ActivityPropertyDescriptor;
|
||||
@Prop() propertyModel: ActivityDefinitionProperty;
|
||||
@State() currentValue?: string
|
||||
@State() currentValue?: string;
|
||||
|
||||
async componentWillLoad() {
|
||||
this.currentValue = this.propertyModel.expressions[SyntaxNames.Json] || '[]';
|
||||
}
|
||||
|
||||
onValueChanged(newValue: Array<string>){
|
||||
this.currentValue = JSON.stringify(newValue);
|
||||
onValueChanged(newValue: Array<string | MultiTextDefinition>) {
|
||||
const newValues = newValue.map(dropdown => {
|
||||
if (typeof dropdown === 'string') return dropdown;
|
||||
|
||||
return dropdown.value;
|
||||
})
|
||||
|
||||
this.currentValue = JSON.stringify(newValues);
|
||||
this.propertyModel.expressions[SyntaxNames.Json] = this.currentValue;
|
||||
}
|
||||
|
||||
|
|
@ -26,6 +32,13 @@ export class ElsaMultiTextProperty {
|
|||
this.currentValue = e.detail;
|
||||
}
|
||||
|
||||
createKeyValueOptions(options: Array<MultiTextDefinition>) {
|
||||
if (options === null)
|
||||
return options;
|
||||
|
||||
return options.map(option => typeof option === 'string' ? { text: option, value: option } : option);
|
||||
}
|
||||
|
||||
render() {
|
||||
const propertyDescriptor = this.propertyDescriptor;
|
||||
const propertyModel = this.propertyModel;
|
||||
|
|
@ -33,14 +46,20 @@ export class ElsaMultiTextProperty {
|
|||
const fieldId = propertyName;
|
||||
const fieldName = propertyName;
|
||||
const values = parseJson(this.currentValue);
|
||||
|
||||
const valueType = propertyDescriptor.options !== null ? 'dropdown' : 'multi-text';
|
||||
const propertyOptions = this.createKeyValueOptions(propertyDescriptor.options);
|
||||
|
||||
const elsaInputTags = valueType === 'multi-text' ?
|
||||
<elsa-input-tags values={values} fieldId={fieldId} fieldName={fieldName} onValueChanged={e => this.onValueChanged(e.detail)} /> :
|
||||
<elsa-input-tags-dropdown dropdownValues={propertyOptions} values={values} fieldId={fieldId} fieldName={fieldName} onValueChanged={e => this.onValueChanged(e.detail)} />;
|
||||
|
||||
return (
|
||||
<elsa-property-editor propertyDescriptor={propertyDescriptor}
|
||||
propertyModel={propertyModel}
|
||||
onDefaultSyntaxValueChanged={e => this.onDefaultSyntaxValueChanged(e)}
|
||||
editor-height="2em"
|
||||
single-line={true}>
|
||||
<elsa-input-tags values={values} fieldId={fieldId} fieldName={fieldName} onValueChanged={e => this.onValueChanged(e.detail)}/>
|
||||
{elsaInputTags}
|
||||
</elsa-property-editor>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -168,6 +168,11 @@ export interface ConnectionDefinitionMapped {
|
|||
outcome: string;
|
||||
}
|
||||
|
||||
export interface MultiTextDefinition {
|
||||
text: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface ActivityDefinitionProperty {
|
||||
name: string;
|
||||
syntax?: string;
|
||||
|
|
|
|||
Loading…
Reference in a new issue