Skip to content

Commit 0e21c8e

Browse files
authored
Merge pull request #159 from performant-software/feature/udcsl46_projects
UDCSL #46 - Projects
2 parents 66f17fc + 31970dd commit 0e21c8e

File tree

15 files changed

+132
-32
lines changed

15 files changed

+132
-32
lines changed

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.16",
3+
"version": "0.5.17",
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": "^0.5.16",
15+
"@performant-software/shared-components": "^0.5.17",
1616
"@react-google-maps/api": "^2.8.1",
1717
"axios": "^0.26.1",
1818
"i18next": "^19.4.4",
@@ -33,7 +33,7 @@
3333
"react-dom": ">= 16.13.1 < 18.0.0"
3434
},
3535
"devDependencies": {
36-
"@performant-software/webpack-config": "^0.5.16",
36+
"@performant-software/webpack-config": "^0.5.17",
3737
"flow-copy-source": "^2.0.9",
3838
"less": "^4.1.2",
3939
"less-loader": "^11.0.0",

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@import 'react-calendar/dist/Calendar.css';
2+
13
div.react-calendar {
24
margin-top: 3em;
35
background: #fff;

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { InfiniteScroll } from '@performant-software/shared-components';
44
import React, { Component } from 'react';
55
import uuid from 'react-uuid';
66
import { Loader } from 'semantic-ui-react';
7+
import _ from 'underscore';
78
import i18n from '../i18n/i18n';
89
import Items from './Items';
910
import './ItemCollection.css';
@@ -64,7 +65,8 @@ class ItemCollection extends Component<Props, State> {
6465
*/
6566
getItems(): Array<any> {
6667
const endIndex = this.state.page * this.props.perPage;
67-
return (this.props.items && this.props.items.slice(0, endIndex)) || [];
68+
const items = (this.props.items && this.props.items.slice(0, endIndex)) || [];
69+
return _.filter(items, (item) => !item._destroy);
6870
}
6971

7072
/**

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

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import React, {
77
useMemo,
88
useState
99
} from 'react';
10-
import _ from 'underscore';
1110
import { Dropdown } from 'semantic-ui-react';
11+
import _ from 'underscore';
1212

1313
type Item = {
1414
reference_table_id: number,
@@ -28,6 +28,14 @@ const ReferenceCodeDropdown = (props: Props) => {
2828
const [loading, setLoading] = useState(false);
2929
const [options, setOptions] = useState([]);
3030

31+
/**
32+
* Sets the "value" variable for the Dropdown component.
33+
*/
34+
const value = useMemo(() => {
35+
const v = _.pluck(_.filter(props.value, (x) => !x._destroy), 'reference_code_id');
36+
return props.multiple ? v : _.first(v);
37+
}, [props.multiple, props.value]);
38+
3139
/**
3240
* Converts the passed ID to a reference code item.
3341
*
@@ -53,25 +61,37 @@ const ReferenceCodeDropdown = (props: Props) => {
5361
*
5462
* @type {(function(*, {value: *}): void)|*}
5563
*/
56-
const onChange = useCallback((e, { value }) => {
57-
let values;
64+
const onChange = useCallback((e, data) => {
65+
let referenceCodeIds;
5866

5967
if (props.multiple) {
60-
values = value;
68+
referenceCodeIds = data.value;
6169
} else {
62-
values = _.compact([value]);
70+
referenceCodeIds = _.compact([data.value]);
6371
}
6472

65-
props.onChange(_.map(values, toItem));
66-
}, [toItem, props.multiple, props.onChange]);
73+
const items = [];
6774

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+
// Find existing records or create new records
76+
_.each(referenceCodeIds, (referenceCodeId) => {
77+
let newValue = _.findWhere(props.value, { reference_code_id: referenceCodeId });
78+
79+
if (!newValue) {
80+
newValue = toItem(referenceCodeId);
81+
}
82+
83+
items.push(_.omit(newValue, '_destroy'));
84+
});
85+
86+
// Mark records for delete
87+
_.each(props.value, (v) => {
88+
if (v.id && !_.contains(referenceCodeIds, v.reference_code_id)) {
89+
items.push({ ...v, _destroy: true });
90+
}
91+
});
92+
93+
props.onChange(items);
94+
}, [toItem, props.multiple, props.onChange, props.value]);
7595

7696
/**
7797
* Loads the list of reference codes from the server.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.ui.form .field > label.reference-code-form-label {
2+
display: inline-block;
3+
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
Popup
1010
} from 'semantic-ui-react';
1111
import i18n from '../i18n/i18n';
12+
import './ReferenceCodeFormLabel.css';
1213

1314
type Props = {
1415
label: string,
@@ -17,8 +18,9 @@ type Props = {
1718
};
1819

1920
const ReferenceCodeFormLabel: ComponentType<any> = withTranslation()((props: Props) => (
20-
<div>
21+
<>
2122
<label
23+
className='reference-code-form-label'
2224
htmlFor={props.referenceTable}
2325
>
2426
{ props.label }
@@ -45,7 +47,7 @@ const ReferenceCodeFormLabel: ComponentType<any> = withTranslation()((props: Pro
4547
onClick={props.onClick}
4648
/>
4749
</Popup>
48-
</div>
50+
</>
4951
));
5052

5153
export default ReferenceCodeFormLabel;

packages/semantic-ui/webpack.config.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ module.exports = configure(__dirname, {
66
alias: {
77
'../../theme.config$': path.join(__dirname, '/src/css/theme.config'),
88
'../src/css/site': path.join(__dirname, '/src/css/site'),
9-
'../src/css/themes': path.join(__dirname, '/src/css/themes')
9+
'../src/css/themes': path.join(__dirname, '/src/css/themes'),
10+
'./react-calendar/dist/Calendar.css$': path.resolve(
11+
__dirname,
12+
'../../node_modules/react-calendar/dist/Calendar.css'
13+
)
1014
}
1115
},
1216
optimization: {

packages/shared/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/shared-components",
3-
"version": "0.5.16",
3+
"version": "0.5.17",
44
"description": "A package of shared, framework agnostic, components.",
55
"license": "MIT",
66
"main": "./build/index.js",
@@ -29,7 +29,7 @@
2929
"react-dom": ">= 16.13.1 < 18.0.0"
3030
},
3131
"devDependencies": {
32-
"@performant-software/webpack-config": "^0.5.16",
32+
"@performant-software/webpack-config": "^0.5.17",
3333
"react": "^17.0.2",
3434
"react-dom": "^17.0.2"
3535
}

packages/shared/src/components/InfiniteScroll.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import React, {
66
useState,
77
type Element
88
} from 'react';
9-
import { isBrowser } from '../utils/Browser';
9+
import Browser from '../utils/Browser';
1010

1111
type Props = {
1212
children: Element<any>,
@@ -29,7 +29,7 @@ const InfiniteScroll = (props: Props) => {
2929

3030
if (props.context) {
3131
scrollElement = props.context.current;
32-
} else if (isBrowser()) {
32+
} else if (Browser.isBrowser()) {
3333
scrollElement = document.documentElement;
3434
}
3535

@@ -59,7 +59,7 @@ const InfiniteScroll = (props: Props) => {
5959

6060
if (props.context) {
6161
scrollContainer = props.context.current;
62-
} else if (isBrowser()) {
62+
} else if (Browser.isBrowser()) {
6363
scrollContainer = window;
6464
}
6565

@@ -89,7 +89,7 @@ const InfiniteScroll = (props: Props) => {
8989
};
9090

9191
/**
92-
* Upon initial render, the DOM may not be tall enough to scroll and trigger the onScroll event. In this case,
92+
* Upon initial render, the DO M may not be tall enough to scroll and trigger the onScroll event. In this case,
9393
* we'll call the onBottomReached prop when the component is mounted until the container's scrollHeight is greater
9494
* than the height of the container.
9595
*/

packages/shared/src/utils/Date.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,38 @@
11
// @flow
22

3+
/**
4+
* Formats the passed date string.
5+
*
6+
* @param value
7+
* @param locale
8+
* @param options
9+
*
10+
* @returns {string}
11+
*/
312
const formatDate = (value: any, locale?: string, options?: any) => {
413
const date = new Date(value);
514
return date.toLocaleDateString(locale, options);
615
};
716

17+
/**
18+
* Parses the passed date string and strips the time components.
19+
*
20+
* @param dateString
21+
*
22+
* @returns {null|Date}
23+
*/
24+
const withoutTime = (dateString: ?string) => {
25+
if (!dateString) {
26+
return null;
27+
}
28+
29+
const date = new Date(dateString);
30+
date.setTime(date.getTime() + date.getTimezoneOffset() * 60 * 1000);
31+
32+
return date;
33+
};
34+
835
export default {
9-
formatDate
36+
formatDate,
37+
withoutTime
1038
};

0 commit comments

Comments
 (0)