diff --git a/client/src/components/Modal/TagModal.js b/client/src/components/Modal/TagModal.js
new file mode 100644
index 00000000..f84e510c
--- /dev/null
+++ b/client/src/components/Modal/TagModal.js
@@ -0,0 +1,117 @@
+import React, { Component } from 'react';
+import CheckBox from 'react-native-check-box';
+
+import PropTypes from 'prop-types';
+import { View, Modal, TouchableOpacity, TouchableWithoutFeedback, Text, ScrollView } from 'react-native';
+import { SearchBar } from 'react-native-elements';
+
+import { Center } from '../Container';
+
+import styles from './styles';
+
+class TagModal extends Component {
+ isChecked = (option) => {
+ const index = this.props.selectedTags.indexOf(option.id);
+ return index !== -1;
+ };
+
+ renderOption(option, isLastItem) {
+ return (
+
+
+ this.props.onSelect(option)}
+ isChecked={this.isChecked(option)}
+ />
+
+
+ );
+ }
+
+ renderOptionList() {
+ const options = this.props.dataIn.map((item, index) =>
+ this.renderOption(item, index === this.props.dataIn.length - 1));
+
+ if (options.length) {
+ return [options];
+ }
+ return (
+
+ No matching tags found
+
+ );
+ }
+
+ render() {
+ return (
+
+
+
+
+
+
+
+ {this.props.headerText}
+
+
+
+
+
+
+
+
+
+
+ {this.renderOptionList()}
+
+
+
+
+
+ Save
+
+
+
+
+
+
+
+ );
+ }
+}
+TagModal.propTypes = {
+ dataIn: PropTypes.array, // eslint-disable-line react/forbid-prop-types
+ selectedTags: PropTypes.array, // eslint-disable-line react/forbid-prop-types
+ headerText: PropTypes.string.isRequired,
+ closeModal: PropTypes.func.isRequired,
+ onSearch: PropTypes.func.isRequired,
+ onSelect: PropTypes.func.isRequired,
+ isLoading: PropTypes.bool,
+ backModal: PropTypes.func.isRequired,
+ visible: PropTypes.bool.isRequired,
+};
+
+export default TagModal;
diff --git a/client/src/components/Modal/__tests__/TagModal.js b/client/src/components/Modal/__tests__/TagModal.js
new file mode 100644
index 00000000..af7c4393
--- /dev/null
+++ b/client/src/components/Modal/__tests__/TagModal.js
@@ -0,0 +1,65 @@
+import React from 'react';
+import renderer from 'react-test-renderer';
+
+import TagModal from '../TagModal';
+
+const noop = () => {};
+
+test('renders correctly', () => {
+ const normal = renderer.create(
+ ,
+ ).toJSON();
+ const selection = renderer.create(
+ ,
+ ).toJSON();
+ const loading = renderer.create(
+ ,
+ ).toJSON();
+ const empty = renderer.create(
+ ,
+ ).toJSON();
+ expect(normal).toMatchSnapshot();
+ expect(selection).toMatchSnapshot();
+ expect(loading).toMatchSnapshot();
+ expect(empty).toMatchSnapshot();
+});
diff --git a/client/src/components/Modal/__tests__/__snapshots__/TagModal.js.snap b/client/src/components/Modal/__tests__/__snapshots__/TagModal.js.snap
new file mode 100644
index 00000000..30a72c75
--- /dev/null
+++ b/client/src/components/Modal/__tests__/__snapshots__/TagModal.js.snap
@@ -0,0 +1,1550 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+
+
+
+
+
+
+
+ test
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ item1
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Save
+
+
+
+
+
+
+
+`;
+
+exports[`renders correctly 2`] = `
+
+
+
+
+
+
+
+ test
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ item1
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Save
+
+
+
+
+
+
+
+`;
+
+exports[`renders correctly 3`] = `
+
+
+
+
+
+
+
+ test
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ item1
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Save
+
+
+
+
+
+
+
+`;
+
+exports[`renders correctly 4`] = `
+
+
+
+
+
+
+
+ test
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matching tags found
+
+
+
+
+
+
+
+
+
+
+ Save
+
+
+
+
+
+
+
+`;
diff --git a/client/src/components/Modal/index.js b/client/src/components/Modal/index.js
index b8365d8f..0b2b609e 100644
--- a/client/src/components/Modal/index.js
+++ b/client/src/components/Modal/index.js
@@ -3,6 +3,7 @@ import ListModal from './ListModal';
import NumberInputModal from './NumberInputModal';
import TextInputModal from './TextInputModal';
import MapModal from './MapModal';
+import TagModal from './TagModal';
import styles from './styles';
-export { Modal, ListModal, NumberInputModal, TextInputModal, MapModal, styles };
+export { Modal, ListModal, NumberInputModal, TextInputModal, MapModal, TagModal, styles };
diff --git a/client/src/components/Modal/styles.js b/client/src/components/Modal/styles.js
index 723d6003..8ac770e9 100644
--- a/client/src/components/Modal/styles.js
+++ b/client/src/components/Modal/styles.js
@@ -31,6 +31,19 @@ const styles = StyleSheet.create({
backgroundColor: 'rgba(255,255,255,0.8)',
},
+ optionContainerTags: {
+ borderBottomLeftRadius: BORDER_RADIUS,
+ borderBottomRightRadius: BORDER_RADIUS,
+ borderTopLeftRadius: 0,
+ borderTopRightRadius: 0,
+ justifyContent: 'center',
+ flexShrink: 1,
+ marginBottom: 8,
+ height: '50%',
+ padding: PADDING,
+ backgroundColor: 'rgba(255,255,255,0.9)',
+ },
+
cancelContainer: {
alignSelf: 'stretch',
},
@@ -140,6 +153,21 @@ const styles = StyleSheet.create({
padding: PADDING,
backgroundColor: 'rgba(255,255,255,0.8)',
},
+ searchContainer: {
+ borderBottomLeftRadius: 0,
+ borderBottomRightRadius: 0,
+ borderTopLeftRadius: BORDER_RADIUS,
+ borderTopRightRadius: BORDER_RADIUS,
+ marginTop: 8,
+ alignSelf: 'stretch',
+ backgroundColor: 'rgba(255,255,255,0.9)',
+ padding: PADDING,
+ },
+ searchbar: {
+ backgroundColor: 'transparent',
+ borderTopWidth: 0,
+ borderBottomWidth: 0,
+ },
map: {
backgroundColor: '#f9f9f9',
diff --git a/client/src/screens/groups/NewGroup.js b/client/src/screens/groups/NewGroup.js
index ef25e042..9d6fbc59 100644
--- a/client/src/screens/groups/NewGroup.js
+++ b/client/src/screens/groups/NewGroup.js
@@ -13,9 +13,8 @@ import { connect } from 'react-redux';
import { Container } from '../../components/Container';
import { Button } from '../../components/Button';
import { Progress } from '../../components/Progress';
-
+import { TagModal } from '../../components/Modal';
import IconModal from './IconModal';
-import TagModal from './TagModal';
import groupIcons from '../../fixtures/icons';
import CURRENT_USER_QUERY from '../../graphql/current-user.query';
import { CREATE_GROUP_MUTATION } from '../../graphql/group.mutation';
@@ -70,17 +69,9 @@ class NewGroup extends Component {
});
}
-handleTagChange = (changedTag) => {
- const newTags = [...this.state.tags];
- const index = newTags.findIndex(el => el.label === changedTag.label);
- newTags[index] = { ...newTags[index], checked: !newTags[index].checked };
- this.setState({ tags: newTags });
-}
-
-handleTagBack = (tags) => {
+handleTagBack = () => {
this.setState({
tagsModal: false,
- tags,
});
}
@@ -97,6 +88,17 @@ searchTagOnPress = (text) => {
});
}
+handleTagChange = (option) => {
+ const tmpSelectedTags = [...this.state.tags];
+ const index = tmpSelectedTags.indexOf(option.id);
+ if (index !== -1) {
+ tmpSelectedTags.splice(index, 1);
+ } else {
+ tmpSelectedTags.push(option.id);
+ }
+ this.setState({ tags: tmpSelectedTags });
+}
+
applyTagSearchFilter = () => {
this.props.refetch({ nameFilter: this.state.filterString });
}
@@ -187,10 +189,13 @@ applyTagSearchFilter = () => {
this.searchTagOnPress(text)}
+ onSearch={this.searchTagOnPress}
+ onSelect={this.handleTagChange}
isLoading={loading}
- backModal={tags => this.handleTagBack(tags)}
+ headerText="Select Group Tags"
+ backModal={this.handleTagBack}
dataIn={user && user.organisation.tags}
+ selectedTags={this.state.tags}
/>
);
diff --git a/client/src/screens/groups/TagModal.js b/client/src/screens/groups/TagModal.js
deleted file mode 100644
index 228d2d9f..00000000
--- a/client/src/screens/groups/TagModal.js
+++ /dev/null
@@ -1,125 +0,0 @@
-import React, { Component } from 'react';
-import CheckBox from 'react-native-check-box';
-
-import PropTypes from 'prop-types';
-import { View, Modal, TouchableOpacity, Text, ScrollView } from 'react-native';
-import { SearchBar } from 'react-native-elements';
-
-import { Center } from '../../components/Container';
-
-import styles from './styles';
-
-class TagModal extends Component {
- state = {
- checked: [],
- };
-
- isChecked = (option) => {
- const index = this.state.checked.indexOf(option.id);
- return index !== -1;
- };
-
- Checked = (option) => {
- const newChecked = [...this.state.checked];
- const index = newChecked.indexOf(option.id);
- if (index !== -1) {
- newChecked.splice(index, 1);
- } else {
- newChecked.push(option.id);
- }
- this.setState({ checked: newChecked });
- };
-
- renderOption(option, isLastItem) {
- return (
-
-
- this.Checked(option)}
- isChecked={this.isChecked(option)}
- />
-
-
- );
- }
-
- renderOptionList() {
- const options = this.props.dataIn.map((item, index) =>
- this.renderOption(item, index === this.props.dataIn.length - 1));
-
- if (options.length) {
- return [options];
- }
- return (
-
- No matching tags found
-
- );
- }
-
- render() {
- return (
-
-
-
-
-
-
- Select Group Tags
-
-
-
-
- this.props.onSearch(text)}
- onClearText={null}
- placeholder="Search"
- />
-
-
-
-
-
- {this.renderOptionList()}
-
-
-
- this.props.backModal(this.state.checked)}>
-
- Save
-
-
-
-
-
-
- );
- }
-}
-TagModal.propTypes = {
- dataIn: PropTypes.array, // eslint-disable-line react/forbid-prop-types
- closeModal: PropTypes.func.isRequired,
- onSearch: PropTypes.func.isRequired,
- isLoading: PropTypes.bool,
- backModal: PropTypes.func.isRequired,
- visible: PropTypes.bool.isRequired,
-};
-
-export default TagModal;
diff --git a/client/src/screens/groups/styles.js b/client/src/screens/groups/styles.js
index 63ad86d6..0ab98563 100644
--- a/client/src/screens/groups/styles.js
+++ b/client/src/screens/groups/styles.js
@@ -123,23 +123,6 @@ const styles = StyleSheet.create({
backgroundColor: 'rgba(0,0,0,0.7)',
},
- searchContainer: {
- borderBottomLeftRadius: 0,
- borderBottomRightRadius: 0,
- borderTopLeftRadius: BORDER_RADIUS,
- borderTopRightRadius: BORDER_RADIUS,
- marginTop: 8,
- alignSelf: 'stretch',
- backgroundColor: 'rgba(255,255,255,0.9)',
- padding: PADDING,
- },
-
- searchbar: {
- backgroundColor: 'transparent',
- borderTopWidth: 0,
- borderBottomWidth: 0,
- },
-
optionContainer: {
borderRadius: BORDER_RADIUS,
justifyContent: 'center',
@@ -151,19 +134,6 @@ const styles = StyleSheet.create({
backgroundColor: 'rgba(255,255,255,0.9)',
},
- optionContainerTags: {
- borderBottomLeftRadius: BORDER_RADIUS,
- borderBottomRightRadius: BORDER_RADIUS,
- borderTopLeftRadius: 0,
- borderTopRightRadius: 0,
- justifyContent: 'center',
- flexShrink: 1,
- marginBottom: 8,
- height: '50%',
- padding: PADDING,
- backgroundColor: 'rgba(255,255,255,0.9)',
- },
-
cancelContainer: {
alignSelf: 'stretch',
},