Skip to content

Commit

Permalink
feat: add filepicker properties panel
Browse files Browse the repository at this point in the history
  • Loading branch information
vsgoulart committed Aug 21, 2024
1 parent dece9ee commit 697c19d
Show file tree
Hide file tree
Showing 9 changed files with 178 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export const INPUTS = [
'taglist',
'textfield',
'textarea',
'filepicker',
];

export const OPTIONS_INPUTS = ['checklist', 'radio', 'select', 'taglist'];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { get } from 'min-dash';

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

import { FeelTemplatingEntry, isFeelEntryEdited } from '@bpmn-io/properties-panel';

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

const entries = [];

entries.push({
id: 'accept',
component: Accept,
editField: editField,
field: field,
isEdited: isFeelEntryEdited,
isDefaultVisible: (field) => field.type === 'filepicker',
});

return entries;
}

function Accept(props) {
const { editField, field, id } = props;

const debounce = useService('debounce');

const variables = useVariables().map((name) => ({ name }));

const path = ['accept'];

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

const setValue = (value) => {
return editField(field, path, value);
};

return FeelTemplatingEntry({
debounce,
element: field,
getValue,
id,
label: 'Supported file formats',
singleLine: true,
setValue,
variables,
description,
});
}

// helpers //////////

const description = (
<>
A comma-separated list of{' '}
<a
href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#unique_file_type_specifiers"
target="_blank">
file type specifiers
</a>
</>
);
Original file line number Diff line number Diff line change
Expand Up @@ -36,29 +36,29 @@ export function DefaultValueEntry(props) {
};
}

const defaulValueBase = {
const defaultValueBase = {
editField,
field,
id: 'defaultValue',
label: 'Default value',
};

entries.push({
...defaulValueBase,
...defaultValueBase,
component: DefaultValueCheckbox,
isEdited: isSelectEntryEdited,
isDefaultVisible: isDefaultVisible((field) => field.type === 'checkbox'),
});

entries.push({
...defaulValueBase,
...defaultValueBase,
component: DefaultValueNumber,
isEdited: isTextFieldEntryEdited,
isDefaultVisible: isDefaultVisible((field) => field.type === 'number'),
});

entries.push({
...defaulValueBase,
...defaultValueBase,
component: DefaultValueSingleSelect,
isEdited: isSelectEntryEdited,
isDefaultVisible: isDefaultVisible((field) => field.type === 'radio' || field.type === 'select'),
Expand All @@ -67,14 +67,14 @@ export function DefaultValueEntry(props) {
// todo(Skaiir): implement a multiselect equivalent (cf. https://github.com/bpmn-io/form-js/issues/265)

entries.push({
...defaulValueBase,
...defaultValueBase,
component: DefaultValueTextfield,
isEdited: isTextFieldEntryEdited,
isDefaultVisible: isDefaultVisible((field) => field.type === 'textfield'),
});

entries.push({
...defaulValueBase,
...defaultValueBase,
component: DefaultValueTextarea,
isEdited: isTextAreaEntryEdited,
isDefaultVisible: isDefaultVisible((field) => field.type === 'textarea'),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { get } from 'min-dash';

import { ToggleSwitchEntry, isToggleSwitchEntryEdited } from '@bpmn-io/properties-panel';

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

const entries = [];

entries.push({
id: 'multiple',
component: Multiple,
editField: editField,
field: field,
isEdited: isToggleSwitchEntryEdited,
isDefaultVisible: (field) => field.type === 'filepicker',
});

return entries;
}

function Multiple(props) {
const { editField, field, id } = props;

const path = ['multiple'];

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

const setValue = (value) => {
return editField(field, path, value);
};

return ToggleSwitchEntry({
element: field,
getValue,
id,
label: 'Can upload multiple files',
inline: true,
setValue,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,5 @@ export { RowCountEntry } from './RowCountEntry';
export { HeadersSourceSelectEntry } from './HeadersSourceSelectEntry';
export { ColumnsExpressionEntry } from './ColumnsExpressionEntry';
export { StaticColumnsSourceEntry } from './StaticColumnsSourceEntry';
export { AcceptEntry } from './AcceptEntry';
export { MultipleEntry } from './MultipleEntry';
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import {
TableDataSourceEntry,
PaginationEntry,
RowCountEntry,
AcceptEntry,
MultipleEntry,
} from '../entries';

export function GeneralGroup(field, editField, getService) {
Expand All @@ -46,11 +48,13 @@ export function GeneralGroup(field, editField, getService) {
...ImageSourceEntry({ field, editField }),
...AltTextEntry({ field, editField }),
...SelectEntries({ field, editField }),
...AcceptEntry({ field, editField }),
...DisabledEntry({ field, editField }),
...ReadonlyEntry({ field, editField }),
...TableDataSourceEntry({ field, editField }),
...PaginationEntry({ field, editField }),
...RowCountEntry({ field, editField }),
...MultipleEntry({ field, editField }),
];

if (entries.length === 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3416,6 +3416,34 @@ describe('properties panel', function () {
});
});
});

describe('filepicker', function () {
it('entries', function () {
// given
const field = schema.components.find(({ key }) => key === 'files');

bootstrapPropertiesPanel({
container,
field,
});

// then
expectPanelStructure(container, {
General: [
'Field label',
'Field description',
'Key',
'Supported file formats',
'Disabled',
'Read only',
'Can upload multiple files',
],
Condition: [],
Validation: ['Required'],
'Custom properties': [],
});
});
});
});

describe('custom properties', function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -511,11 +511,14 @@ describe('GeneralGroup', function () {
});

describe('for all other INPUTS', () => {
const otherInputTypes = INPUTS.filter((i) => !OPTIONS_INPUTS.includes(i));
const nonDefaultValueInputs = new Set(['datetime', 'filepicker']);
const defaultValueInputs = INPUTS.filter(
(input) => !OPTIONS_INPUTS.includes(input) && !nonDefaultValueInputs.has(input),
);

it('should render', function () {
// given
for (const type of otherInputTypes) {
for (const type of defaultValueInputs) {
const field = { type };

// when
Expand All @@ -524,8 +527,22 @@ describe('GeneralGroup', function () {
// then
const defaultValueEntry = findEntry('defaultValue', container);

if (type === 'datetime') expect(defaultValueEntry).to.not.exist;
else expect(defaultValueEntry).to.exist;
expect(defaultValueEntry).to.exist;
}
});

it('should not render', function () {
// given
for (const type of nonDefaultValueInputs) {
const field = { type };

// when
const { container } = renderGeneralGroup({ field });

// then
const defaultValueEntry = findEntry('defaultValue', container);

expect(defaultValueEntry).to.not.exist;
}
});
});
Expand Down
8 changes: 8 additions & 0 deletions packages/form-js-editor/test/spec/form.json
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,14 @@
"alt": "The bpmn.io logo",
"type": "image"
},
{
"label": "Image files",
"type": "filepicker",
"id": "files",
"key": "files",
"multiple": true,
"accept": ".jpg,.png"
},
{
"id": "Spacer_1",
"type": "spacer",
Expand Down

0 comments on commit 697c19d

Please sign in to comment.