Skip to content

Commit 104607c

Browse files
authored
Merge pull request #244 from performant-software/feature/cdc60_data_entry_form
CDC #60 - Data Entry Form
2 parents ca7f49f + d8cc222 commit 104607c

File tree

15 files changed

+172
-44
lines changed

15 files changed

+172
-44
lines changed

packages/controlled-vocabulary/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@performant-software/controlled-vocabulary",
3-
"version": "1.1.0",
3+
"version": "1.1.1",
44
"description": "A package of components to allow user to configure dropdown elements. Use with the \"controlled_vocabulary\" gem.",
55
"license": "MIT",
66
"main": "./build/index.js",
@@ -12,8 +12,8 @@
1212
"build": "webpack --mode production && flow-copy-source -v src types"
1313
},
1414
"dependencies": {
15-
"@performant-software/semantic-components": "^1.1.0",
16-
"@performant-software/shared-components": "^1.1.0",
15+
"@performant-software/semantic-components": "^1.1.1",
16+
"@performant-software/shared-components": "^1.1.1",
1717
"i18next": "^21.9.2",
1818
"semantic-ui-react": "^2.1.2",
1919
"underscore": "^1.13.2"

packages/geospatial/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@performant-software/geospatial",
3-
"version": "1.1.0",
3+
"version": "1.1.1",
44
"description": "TODO: ADD",
55
"license": "MIT",
66
"main": "./build/index.js",

packages/semantic-ui/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@performant-software/semantic-components",
3-
"version": "1.1.0",
3+
"version": "1.1.1",
44
"description": "A package of shared components based on the Semantic UI Framework.",
55
"license": "MIT",
66
"main": "./build/index.js",
@@ -12,7 +12,7 @@
1212
"build": "webpack --mode production && flow-copy-source -v src types"
1313
},
1414
"dependencies": {
15-
"@performant-software/shared-components": "^1.1.0",
15+
"@performant-software/shared-components": "^1.1.1",
1616
"@react-google-maps/api": "^2.8.1",
1717
"axios": "^0.26.1",
1818
"i18next": "^19.4.4",

packages/semantic-ui/src/components/AssociatedDropdown.js

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
import { Timer } from '@performant-software/shared-components';
44
import React, { Component, type ComponentType } from 'react';
5-
import { Button, Dropdown, Message } from 'semantic-ui-react';
5+
import {
6+
Button,
7+
Dropdown,
8+
Message,
9+
type ButtonProps
10+
} from 'semantic-ui-react';
611
import _ from 'underscore';
712
import EditModal from './EditModal';
813
import i18n from '../i18n/i18n';
@@ -16,6 +21,7 @@ type Option = {
1621
};
1722

1823
type Props = {
24+
buttons?: Array<ButtonProps>,
1925
className?: string,
2026
collectionName: string,
2127
header?: ComponentType<any>,
@@ -45,6 +51,10 @@ type State = {
4551
value: ?number | ?string
4652
};
4753

54+
const BUTTON_ADD = 'add';
55+
const BUTTON_CLEAR = 'clear';
56+
const BUTTON_EDIT = 'edit';
57+
4858
const TIMEOUT = 500;
4959

5060
class AssociatedDropdown extends Component<Props, State> {
@@ -243,13 +253,33 @@ class AssociatedDropdown extends Component<Props, State> {
243253
return null;
244254
}
245255

256+
return this.renderButton(BUTTON_ADD, {
257+
basic: true,
258+
content: i18n.t('Common.buttons.add'),
259+
icon: 'plus',
260+
onClick: () => this.setState({ modalAdd: true }),
261+
type: 'button'
262+
});
263+
}
264+
265+
/**
266+
* Renders the button with the passed name using the provided props.
267+
*
268+
* @param name
269+
* @param defaults
270+
*
271+
* @returns {JSX.Element|null}
272+
*/
273+
renderButton(name, defaults) {
274+
const button = _.findWhere(this.props.buttons, { name }) || {};
275+
276+
if (button.accept && !button.accept()) {
277+
return null;
278+
}
279+
246280
return (
247281
<Button
248-
basic
249-
content={i18n.t('Common.buttons.add')}
250-
icon='plus'
251-
onClick={() => this.setState({ modalAdd: true })}
252-
type='button'
282+
{..._.defaults(button, defaults)}
253283
/>
254284
);
255285
}
@@ -264,15 +294,13 @@ class AssociatedDropdown extends Component<Props, State> {
264294
return null;
265295
}
266296

267-
return (
268-
<Button
269-
basic
270-
content={i18n.t('Common.buttons.clear')}
271-
icon='times'
272-
onClick={this.onClear.bind(this)}
273-
type='button'
274-
/>
275-
);
297+
return this.renderButton(BUTTON_CLEAR, {
298+
basic: true,
299+
content: i18n.t('Common.buttons.clear'),
300+
icon: 'times',
301+
onClick: this.onClear.bind(this),
302+
type: 'button'
303+
});
276304
}
277305

278306
/**
@@ -285,15 +313,13 @@ class AssociatedDropdown extends Component<Props, State> {
285313
return null;
286314
}
287315

288-
return (
289-
<Button
290-
basic
291-
content={i18n.t('Common.buttons.edit')}
292-
icon='pencil'
293-
onClick={() => this.setState({ modalEdit: true })}
294-
type='button'
295-
/>
296-
);
316+
return this.renderButton(BUTTON_EDIT, {
317+
basic: true,
318+
content: i18n.t('Common.buttons.edit'),
319+
icon: 'pencil',
320+
onClick: () => this.setState({ modalEdit: true }),
321+
type: 'button'
322+
});
297323
}
298324

299325
/**

packages/semantic-ui/src/components/DataTableColumnSelector.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,12 @@ type Props = ListProps & {
4343
* If a <code>render</code> callback is provided, the item will be passed to the function and the return JSX
4444
* will display as the property value.
4545
*/
46-
columns: Array<Column>
46+
columns: Array<Column>,
47+
48+
/**
49+
* If <code>true</code>, columns can be shown/hidden by the user.
50+
*/
51+
configurable?: boolean
4752
};
4853

4954
type State = {
@@ -139,7 +144,9 @@ const useColumnSelector = (WrappedComponent: ComponentType<any>) => (
139144
{...this.props}
140145
className={`data-table-column-selector ${this.props.className}`}
141146
columns={this.state.columns}
142-
renderListHeader={this.renderHeader.bind(this)}
147+
renderListHeader={this.props.configurable
148+
? this.renderHeader.bind(this)
149+
: undefined}
143150
/>
144151
);
145152
}

packages/semantic-ui/src/components/Items.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ type Props = ListProps & {
4545
*/
4646
items: Array<any>,
4747

48+
/**
49+
* The number of cards to display per row in the grid view.
50+
*/
51+
itemsPerRow?: number,
52+
4853
/**
4954
* If true, the list items will be formatted as a link.
5055
*/
@@ -270,6 +275,7 @@ class ItemsClass extends Component<Props, {}> {
270275
icon={action.resolveIcon ? action.resolveIcon(item) : action.icon}
271276
key={actionIndex}
272277
onClick={action.onClick.bind(this, item)}
278+
size={action.size}
273279
/>
274280
))}
275281
{ this.isSelectable() && (
@@ -346,7 +352,9 @@ class ItemsClass extends Component<Props, {}> {
346352
}
347353

348354
return (
349-
<Card.Group>
355+
<Card.Group
356+
itemsPerRow={this.props.itemsPerRow}
357+
>
350358
{ _.map(this.props.items, this.renderCard.bind(this)) }
351359
</Card.Group>
352360
);
@@ -403,6 +411,7 @@ class ItemsClass extends Component<Props, {}> {
403411
key={actionIndex}
404412
icon={action.resolveIcon ? action.resolveIcon(item) : action.icon}
405413
onClick={action.onClick.bind(this, item)}
414+
size={action.size}
406415
/>
407416
))}
408417
</Item.Content>

packages/semantic-ui/src/components/ListTable.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,6 @@ import useDataList, { SORT_ASCENDING, SORT_DESCENDING, type Props as DataListPro
99
import './ListTable.css';
1010

1111
type Props = DataListProps & DataTableProps & {
12-
/**
13-
* If true, columns can be shown/hidden by the user.
14-
*/
15-
configurable?: boolean,
16-
1712
/**
1813
* The name of the default sort column.
1914
*/

packages/shared/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@performant-software/shared-components",
3-
"version": "1.1.0",
3+
"version": "1.1.1",
44
"description": "A package of shared, framework agnostic, components.",
55
"license": "MIT",
66
"main": "./build/index.js",

packages/storybook/src/semantic-ui/AssociatedDropdown.stories.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,3 +427,41 @@ export const FormField = () => (
427427
</Form.Input>
428428
</Form>
429429
);
430+
431+
export const CustomButtons = () => (
432+
<AssociatedDropdown
433+
buttons={[{
434+
name: 'edit',
435+
icon: 'edit'
436+
}, {
437+
basic: false,
438+
color: 'orange',
439+
name: 'add',
440+
icon: 'coffee'
441+
}, {
442+
name: 'clear',
443+
content: 'Clear Value!'
444+
}]}
445+
collectionName='items'
446+
modal={{
447+
component: AddModal,
448+
props: {
449+
onInitialize: () => Promise.resolve({ })
450+
},
451+
onSave: () => {
452+
action('save')();
453+
return Promise.resolve({});
454+
}
455+
}}
456+
onSearch={(search) => Api.onLoad({ items, search, sort_by: 'text' })}
457+
onSelection={action('selection')}
458+
placeholder={text('Placeholder', 'Search')}
459+
renderOption={(item) => ({
460+
key: item.id,
461+
value: item.id,
462+
text: item.company,
463+
description: item.country
464+
})}
465+
upward={boolean('Open upward', false)}
466+
/>
467+
);

packages/storybook/src/semantic-ui/EmbeddedList.stories.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,14 @@ export const TabbedModalConfig = useDragDrop(() => {
228228
</Container>
229229
);
230230
});
231+
232+
export const NoColumnSelector = useDragDrop(() => (
233+
<EmbeddedList
234+
actions={actions}
235+
configurable={false}
236+
onDelete={action('delete')}
237+
columns={columns}
238+
items={items}
239+
showRecordCount
240+
/>
241+
));

0 commit comments

Comments
 (0)