Skip to content

Commit 7593975

Browse files
authored
Merge pull request #130 from performant-software/feature/rc129_customize_axios
RC #129 - Customize Axios
2 parents 4deea83 + 86a85fd commit 7593975

24 files changed

+463
-18
lines changed

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
"packages/*"
77
],
88
"scripts": {
9-
"build-storybook": "yarn --cwd packages/storybook build",
9+
"build-semantic": "yarn --cwd packages/semantic-ui build",
10+
"build-shared": "yarn --cwd packages/shared build",
11+
"build-storybook": "yarn build-shared && yarn build-semantic && yarn --cwd packages/storybook build",
1012
"flow": "flow",
1113
"storybook": "yarn --cwd packages/storybook storybook",
1214
"test": "jest"

packages/semantic-ui/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/semantic-components",
3-
"version": "0.5.2",
3+
"version": "0.5.3",
44
"description": "A package of shared components based on the Semantic UI Framework.",
55
"license": "MIT",
66
"main": "./build/index.js",
@@ -9,7 +9,7 @@
99
"build": "webpack --mode production && flow-copy-source -v src types"
1010
},
1111
"dependencies": {
12-
"@performant-software/shared-components": "^0.5.2",
12+
"@performant-software/shared-components": "^0.5.3",
1313
"@react-google-maps/api": "^2.8.1",
1414
"axios": "^0.26.1",
1515
"flow-copy-source": "^2.0.9",
@@ -30,7 +30,7 @@
3030
"react-dom": ">= 16.13.1 < 18.0.0"
3131
},
3232
"devDependencies": {
33-
"@performant-software/webpack-config": "^0.5.2",
33+
"@performant-software/webpack-config": "^0.5.3",
3434
"react": "^17.0.2",
3535
"react-dom": "^17.0.2"
3636
}

packages/semantic-ui/src/components/ReferenceCodeDropdown.css

Whitespace-only changes.
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// @flow
2+
3+
import { ReferenceCodesService } from '@performant-software/shared-components';
4+
import React, {
5+
useCallback,
6+
useEffect,
7+
useMemo,
8+
useState
9+
} from 'react';
10+
import _ from 'underscore';
11+
import { Dropdown } from 'semantic-ui-react';
12+
13+
type Item = {
14+
reference_table_id: number,
15+
key: string
16+
};
17+
18+
type Props = {
19+
fluid?: boolean,
20+
multiple?: boolean,
21+
onChange: (item: Item) => void,
22+
placeholder?: string,
23+
referenceTable: string,
24+
value: Item | Array<Item>
25+
};
26+
27+
const ReferenceCodeDropdown = (props: Props) => {
28+
const [loading, setLoading] = useState(false);
29+
const [options, setOptions] = useState([]);
30+
31+
/**
32+
* Converts the passed ID to a reference code item.
33+
*
34+
* @type {function(*): {reference_code_id: *}}
35+
*/
36+
const toItem = useCallback((id) => ({
37+
reference_code_id: id
38+
}), []);
39+
40+
/**
41+
* Converts the passed reference code to a dropdown option.
42+
*
43+
* @type {function(*): {text: *, value: *, key: *}}
44+
*/
45+
const toOption = useCallback((referenceCode) => ({
46+
key: referenceCode.id,
47+
value: referenceCode.id,
48+
text: referenceCode.name
49+
}), []);
50+
51+
/**
52+
* Converts the selected values and calls the onChange prop.
53+
*
54+
* @type {(function(*, {value: *}): void)|*}
55+
*/
56+
const onChange = useCallback((e, { value }) => {
57+
let values;
58+
59+
if (props.multiple) {
60+
values = value;
61+
} else {
62+
values = _.compact([value]);
63+
}
64+
65+
props.onChange(_.map(values, toItem));
66+
}, [toItem, props.multiple, props.onChange]);
67+
68+
/**
69+
* Sets the "value" variable for the Dropdown component.
70+
*/
71+
const value = useMemo(() => {
72+
const v = _.pluck(_.filter(props.value, (x) => !x._destroy), 'reference_code_id');
73+
return props.multiple ? v : _.first(v);
74+
}, [props.multiple, props.value]);
75+
76+
/**
77+
* Loads the list of reference codes from the server.
78+
*/
79+
useEffect(() => {
80+
setLoading(true);
81+
82+
const params = {
83+
per_page: 0,
84+
reference_table: props.referenceTable,
85+
sort_by: 'name'
86+
};
87+
88+
ReferenceCodesService
89+
.fetchAll(params)
90+
.then(({ data }) => setOptions(_.map(data.reference_codes, toOption)))
91+
.finally(() => setLoading(false));
92+
}, [toOption]);
93+
94+
return (
95+
<Dropdown
96+
clearable
97+
disabled={loading}
98+
fluid={props.fluid}
99+
loading={loading}
100+
multiple={props.multiple}
101+
onChange={onChange}
102+
options={options}
103+
placeholder={props.placeholder}
104+
search
105+
selection
106+
selectOnBlur={false}
107+
value={value}
108+
/>
109+
);
110+
};
111+
112+
ReferenceCodeDropdown.defaultProps = {
113+
fluid: true,
114+
multiple: false,
115+
placeholder: undefined
116+
};
117+
118+
export default ReferenceCodeDropdown;

packages/semantic-ui/src/components/ReferenceCodeModal.css

Whitespace-only changes.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// @flow
2+
3+
import type { EditContainerProps } from '@performant-software/shared-components';
4+
import React from 'react';
5+
import { Form, Modal } from 'semantic-ui-react';
6+
import i18n from '../i18n/i18n';
7+
8+
const ReferenceCodeModal = (props: EditContainerProps) => (
9+
<Modal
10+
as={Form}
11+
centered={false}
12+
open
13+
>
14+
<Modal.Header
15+
content={props.item.id
16+
? i18n.t('ReferenceCodeModal.title.edit')
17+
: i18n.t('ReferenceCodeModal.title.add')}
18+
/>
19+
<Modal.Content>
20+
<Form.Input
21+
error={props.isError('name')}
22+
label={i18n.t('ReferenceCodeModal.labels.name')}
23+
onChange={props.onTextInputChange.bind(this, 'name')}
24+
required={props.isRequired('name')}
25+
value={props.item.name}
26+
/>
27+
</Modal.Content>
28+
{ props.children }
29+
</Modal>
30+
);
31+
32+
export default ReferenceCodeModal;

packages/semantic-ui/src/components/ReferenceTableModal.css

Whitespace-only changes.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// @flow
2+
3+
import type { EditContainerProps } from '@performant-software/shared-components';
4+
import React from 'react';
5+
import { Form, Header, Modal } from 'semantic-ui-react';
6+
import EmbeddedList from './EmbeddedList';
7+
import ReferenceCodeModal from './ReferenceCodeModal';
8+
import i18n from '../i18n/i18n';
9+
10+
const ReferenceTableModal = (props: EditContainerProps) => (
11+
<Modal
12+
as={Form}
13+
centered={false}
14+
className='reference-table-modal'
15+
open
16+
>
17+
<Modal.Header
18+
content={props.item.id
19+
? i18n.t('ReferenceTableModal.title.edit')
20+
: i18n.t('ReferenceTableModal.title.add')}
21+
/>
22+
<Modal.Content>
23+
<Form.Input
24+
error={props.isError('name')}
25+
label={i18n.t('ReferenceTableModal.labels.name')}
26+
onChange={props.onTextInputChange.bind(this, 'name')}
27+
required={props.isRequired('name')}
28+
value={props.item.name}
29+
/>
30+
<Form.Input
31+
error={props.isError('key')}
32+
label={i18n.t('ReferenceTableModal.labels.key')}
33+
onChange={props.onTextInputChange.bind(this, 'key')}
34+
required={props.isRequired('key')}
35+
value={props.item.key}
36+
/>
37+
<Header
38+
content={i18n.t('ReferenceTableModal.labels.referenceCodes')}
39+
/>
40+
<EmbeddedList
41+
actions={[{
42+
name: 'edit'
43+
}, {
44+
name: 'copy'
45+
}, {
46+
name: 'delete'
47+
}]}
48+
columns={[{
49+
name: 'name',
50+
label: i18n.t('ReferenceTableModal.referenceCodes.columns.name')
51+
}]}
52+
items={props.item.reference_codes}
53+
modal={{
54+
component: ReferenceCodeModal,
55+
props: {
56+
required: ['name']
57+
}
58+
}}
59+
onDelete={props.onDeleteChildAssociation.bind(this, 'reference_codes')}
60+
onSave={props.onSaveChildAssociation.bind(this, 'reference_codes')}
61+
/>
62+
</Modal.Content>
63+
{ props.children }
64+
</Modal>
65+
);
66+
67+
export default ReferenceTableModal;

packages/semantic-ui/src/components/ReferenceTablesList.css

Whitespace-only changes.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// @flow
2+
3+
import { ReferenceTablesService } from '@performant-software/shared-components';
4+
import React from 'react';
5+
import ListTable from './ListTable';
6+
import ReferenceTableModal from './ReferenceTableModal';
7+
8+
const ReferenceTablesList = () => (
9+
<ListTable
10+
actions={[{
11+
name: 'edit'
12+
}, {
13+
name: 'copy'
14+
}, {
15+
name: 'delete'
16+
}]}
17+
collectionName='reference_tables'
18+
columns={[{
19+
name: 'name',
20+
label: 'Name',
21+
sortable: true
22+
}, {
23+
name: 'key',
24+
label: 'Key',
25+
sortable: true
26+
}]}
27+
modal={{
28+
component: ReferenceTableModal,
29+
props: {
30+
onInitialize: (id) => (
31+
ReferenceTablesService
32+
.fetchOne(id)
33+
.then(({ data }) => data.reference_table)
34+
),
35+
required: ['name', 'key']
36+
}
37+
}}
38+
onDelete={(referenceTable) => ReferenceTablesService.delete(referenceTable)}
39+
onLoad={(params) => ReferenceTablesService.fetchAll(params)}
40+
onSave={(referenceTable) => ReferenceTablesService.save(referenceTable)}
41+
/>
42+
);
43+
44+
export default ReferenceTablesList;

0 commit comments

Comments
 (0)