Skip to content

Commit

Permalink
feat: dynamic data loading
Browse files Browse the repository at this point in the history
Closes #197
Closes #256
  • Loading branch information
Skaiir committed Jul 1, 2022
1 parent d34e339 commit aaaab34
Show file tree
Hide file tree
Showing 23 changed files with 1,465 additions and 214 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
CustomValuesGroup,
GeneralGroup,
ValidationGroup,
ValuesGroup
ValuesGroups
} from './groups';

import {
Expand All @@ -22,7 +22,7 @@ function getGroups(field, editField) {

const groups = [
GeneralGroup(field, editField),
ValuesGroup(field, editField),
...ValuesGroups(field, editField),
ValidationGroup(field, editField),
CustomValuesGroup(field, editField)
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const INPUTS = [
'textfield'
];

export const OPTIONS_INPUTS = [
export const VALUES_INPUTS = [
'checklist',
'radio',
'select',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import { get } from 'min-dash';

import { useService } from '../../../hooks';

import { INPUTS } from '../Util';
import { INPUTS, VALUES_INPUTS } from '../Util';


export default function DefaultValueEntry(props) {
export default function DefaultOptionEntry(props) {
const {
editField,
field
Expand All @@ -26,7 +26,8 @@ export default function DefaultValueEntry(props) {

const entries = [];

if (!INPUTS.includes(type)) {
// Only make default values available when they are statically defined
if (!INPUTS.includes(type) || VALUES_INPUTS.includes(type) && !field.values) {
return entries;
}

Expand Down Expand Up @@ -56,11 +57,13 @@ export default function DefaultValueEntry(props) {
if (type === 'radio' || type === 'select') {
entries.push({
...defaultOptions,
component: DefaultValueMulti,
component: DefaultValueSingleSelect,
isEdited: isSelectEntryEdited
});
}

// Todo: implement a multiselect equivalent (https://github.com/bpmn-io/form-js/issues/265)

if (type === 'textfield') {
entries.push({
...defaultOptions,
Expand Down Expand Up @@ -147,7 +150,7 @@ function DefaultValueNumber(props) {
});
}

function DefaultValueMulti(props) {
function DefaultValueSingleSelect(props) {
const {
editField,
field,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
import { get, isUndefined, without } from 'min-dash';

import { SelectEntry, isSelectEntryEdited, TextFieldEntry } from '@bpmn-io/properties-panel';
import ValueEntry from './ValueEntry';

import { arrayAdd } from '../Util';
import { useService } from '../../../hooks';

export function ValuesSourceSelectorEntry(props) {
const {
editField,
field
} = props;

return [ {
id: 'values-source',
component: ValuesSourceSelect,
isEdited: isSelectEntryEdited,
editField,
field,
} ];
}

export function InputKeyValuesSourceEntry(props) {
const {
editField,
field
} = props;

return [{
id: 'input-values-key',
component: InputValuesKey,
label: 'Input values key',
description: 'Define which input property to populate the values from',
isEdited: isSelectEntryEdited,
editField,
field,
}];
}

export function StaticValuesSourceEntry(props) {
const {
editField,
field,
id: idPrefix
} = props;

const {
values
} = field;

const addEntry = (e) => {

e.preventDefault();

const index = values.length + 1;

const entry = {
label: `Value ${index}`,
value: `value${index}`
};

editField(field, VALUES_SOURCES_PATHS[VALUES_SOURCES.STATIC], arrayAdd(values, values.length, entry));
};

const removeEntry = (entry) => {
editField(field, VALUES_SOURCES_PATHS[VALUES_SOURCES.STATIC], without(values, entry));
};

const validateFactory = (key) => {
return (value) => {
if (value === key) {
return;
}

if (isUndefined(value) || !value.length) {
return 'Must not be empty.';
}

const isValueAssigned = values.find(entry => entry.value === value);

if (isValueAssigned) {
return 'Must be unique.';
}
};
};

const items = values.map((entry, index) => {
const id = idPrefix + '-staticValue-' + index;

return {
id,
label: entry.label,
entries: ValueEntry({
editField,
field,
idPrefix: id,
index,
validateFactory
}),
autoFocusEntry: true,
remove: () => removeEntry(entry)
};
});

return {
items,
add: addEntry
};
}

function ValuesSourceSelect(props) {

const {
editField,
field,
id
} = props;

const getValue = getValuesSource;

const setValue = (value) => {

let newField = field;

Object.values(VALUES_SOURCES).forEach(source => {

// Clear all values source definitions and default the newly selected one
const newValue = value === source ? VALUES_SOURCES_DEFAULTS[source] : undefined;
newField = editField(field, VALUES_SOURCES_PATHS[source], newValue);
});

return newField;
};

const getValuesSourceOptions = () => {

return Object.values(VALUES_SOURCES).map((valueSource) => ({
label: VALUES_SOURCES_LABELS[valueSource],
value: valueSource
}));
};

return SelectEntry({
element: field,
getOptions: getValuesSourceOptions,
getValue,
id,
label: 'Values source',
setValue
});
}

function InputValuesKey(props) {
const {
editField,
field,
id,
label,
description
} = props;

const debounce = useService('debounce');

const path = VALUES_SOURCES_PATHS[VALUES_SOURCES.INPUT];

const getValue = () => get(field, path, '');

const setValue = (value) => editField(field, path, value || '');

return TextFieldEntry({
debounce,
description,
element: field,
getValue,
id,
label,
setValue
});
}


//* CONFIG

export const VALUES_SOURCES = {
STATIC: 'static',
INPUT: 'input'
};

const VALUES_SOURCE_DEFAULT = VALUES_SOURCES.STATIC;

const VALUES_SOURCES_LABELS = {
[VALUES_SOURCES.STATIC]: 'Static',
[VALUES_SOURCES.INPUT]: 'Input data',
};

const VALUES_SOURCES_PATHS = {
[VALUES_SOURCES.STATIC]: ['values'],
[VALUES_SOURCES.INPUT]: ['valuesKey'],
};

const VALUES_SOURCES_DEFAULTS = {
[VALUES_SOURCES.STATIC]: [],
[VALUES_SOURCES.INPUT]: '',
};


//* Helpers

export function getValuesSource(field) {

for (const source of Object.values(VALUES_SOURCES)) {
if (get(field, VALUES_SOURCES_PATHS[source]) !== undefined) {
return source;
}
}

return VALUES_SOURCE_DEFAULT;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export { default as KeyEntry } from './KeyEntry';
export { default as LabelEntry } from './LabelEntry';
export { default as TextEntry } from './TextEntry';
export { default as ValueEntry } from './ValueEntry';
export { default as CustomValueEntry } from './CustomValueEntry';
export { default as CustomValueEntry } from './CustomValueEntry';
export * from './ValuesSourceEntries';

This file was deleted.

Loading

0 comments on commit aaaab34

Please sign in to comment.