Skip to content

Commit

Permalink
feat: add filepicker properties panel (#1244)
Browse files Browse the repository at this point in the history
* feat: add filepicker properties panel

* refactor: rework filepicker properties panel
  • Loading branch information
vsgoulart authored Aug 23, 2024
1 parent dece9ee commit 8985b26
Show file tree
Hide file tree
Showing 12 changed files with 197 additions and 13 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
Expand Up @@ -17,7 +17,7 @@ export function DescriptionEntry(props) {
editField: editField,
field: field,
isEdited: isFeelEntryEdited,
isDefaultVisible: (field) => INPUTS.includes(field.type),
isDefaultVisible: (field) => field.type !== 'filepicker' && INPUTS.includes(field.type),
});

return entries;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { get } from 'min-dash';

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

import { FeelToggleSwitchEntry, isFeelEntryEdited } 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: isFeelEntryEdited,
isDefaultVisible: (field) => field.type === 'filepicker',
});

return entries;
}

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

const debounce = useService('debounce');

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

const path = ['multiple'];

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

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

return FeelToggleSwitchEntry({
debounce,
element: field,
feel: 'optional',
getValue,
id,
label: 'Upload multiple files',
inline: true,
setValue,
variables,
});
}
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,6 +48,8 @@ export function GeneralGroup(field, editField, getService) {
...ImageSourceEntry({ field, editField }),
...AltTextEntry({ field, editField }),
...SelectEntries({ field, editField }),
...AcceptEntry({ field, editField }),
...MultipleEntry({ field, editField }),
...DisabledEntry({ field, editField }),
...ReadonlyEntry({ field, editField }),
...TableDataSourceEntry({ field, editField }),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3416,6 +3416,26 @@ 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', 'Key', 'Supported file formats', 'Upload multiple files', 'Disabled', 'Read only'],
Condition: [],
Validation: ['Required'],
'Custom properties': [],
});
});
});
});

describe('custom properties', function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ describe('GeneralGroup', function () {

it('should render for INPUTS', function () {
// given
for (const type of INPUTS) {
for (const type of INPUTS.filter((type) => type !== 'filepicker')) {
const field = { type };

// when
Expand Down 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
2 changes: 1 addition & 1 deletion packages/form-json-schema/src/defs/component.json
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@
"multiple": {
"$id": "#/component/multiple",
"description": "Allow multiple files to be selected.",
"type": "boolean"
"type": ["boolean", "string"]
}
},
"required": ["type"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,21 @@
"multiple": false
}
}
},
{
"if": {
"properties": {
"type": {
"const": "filepicker"
}
},
"required": ["type"]
},
"then": {
"properties": {
"description": false
}
}
}
]
}

0 comments on commit 8985b26

Please sign in to comment.