mirror of
https://github.com/openmhz/trunk-server.git
synced 2026-11-12 08:47:40 -05:00
Filter modal is now working too
This commit is contained in:
@@ -139,7 +139,7 @@ https://create-react-app.dev/docs/updating-to-new-releases/
|
||||
## Managing MongoDB
|
||||
|
||||
MongoDB is used in the backend to store data. It is pretty fast, flexible and has worked well enough for me.
|
||||
All of the files that MongoDB uses to store the DB are in the */data* directory, which gets mapped into the contianer.
|
||||
All of the files that MongoDB uses to store the DB are in the */data* directory, which gets mapped into the container.
|
||||
Mapping this directory makes sure that the data persists each time you run the mongo container.
|
||||
|
||||
### Working with the MongoDB Container
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"date-fns": "2.29.3",
|
||||
"ejs": "3.1.8",
|
||||
"history": "^5.3.0",
|
||||
"mongodb": "^4.13.0",
|
||||
"react": "^18.2.0",
|
||||
"react-audio-player": "0.17.0",
|
||||
"react-datepicker": "4.8.0",
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React from "react";
|
||||
import { Link } from 'react-router-dom';
|
||||
import MediaPlayer from "./MediaPlayer";
|
||||
import FilterModal from "./FilterModalContainer";
|
||||
import GroupModal from "./GroupModalContainer";
|
||||
import FilterModal from "./FilterModal";
|
||||
import GroupModal from "./GroupModal";
|
||||
import SupportModal from "./SupportModal";
|
||||
import CalendarModal from "./CalendarModalContainer";
|
||||
import CallInfo from "./CallInfo";
|
||||
@@ -198,11 +198,11 @@ class CallPlayer extends React.Component {
|
||||
}
|
||||
search = search + `starred=true`;
|
||||
}
|
||||
|
||||
/*
|
||||
this.props.history.push({
|
||||
pathname: this.props.history.location.pathname,
|
||||
search: search
|
||||
});
|
||||
});*/
|
||||
}
|
||||
|
||||
handleCalendarClose(didUpdate) {
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import React, { Component } from "react";
|
||||
import React, { Component, useState } from "react";
|
||||
import { setGroupFilter, setTalkgroupFilter, setAllFilter, setStarredFilter } from "../features/callPlayer/callPlayerSlice";
|
||||
import { useGetGroupsQuery, useGetTalkgroupsQuery } from '../features/api/apiSlice'
|
||||
import { useSelector, useDispatch } from 'react-redux'
|
||||
import {
|
||||
Modal,
|
||||
Button,
|
||||
@@ -12,136 +15,134 @@ import {
|
||||
import "./FilterModal.css";
|
||||
|
||||
|
||||
class FilterModal extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.handleInputChange = this.handleInputChange.bind(this);
|
||||
this.handleTabChange = this.handleTabChange.bind(this);
|
||||
this.toggleStarred = this.toggleStarred.bind(this);
|
||||
this.handleDone = this.handleDone.bind(this);
|
||||
this.handleClose = this.handleClose.bind(this);
|
||||
function FilterModal(props) {
|
||||
const shortName = useSelector((state) => state.callPlayer.shortName);
|
||||
const globalFilterStarred = useSelector((state) => state.callPlayer.filterStarred);
|
||||
const { data:groupsData, isSuccess:isGroupsSuccess } = useGetGroupsQuery(props.shortName);
|
||||
const { data:talkgroupsData, isSuccess:isTalkgroupsSuccess } = useGetTalkgroupsQuery(props.shortName);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [selectedTalkgroup, setSelectedTalkgroup] = useState([]);
|
||||
const [selectedGroup, setSelectedGroup] = useState(false);
|
||||
const [filterStarred, setFilterStarred] = useState(false);
|
||||
const [activeTab, setActiveTab] = useState(0);
|
||||
const dispatch = useDispatch()
|
||||
|
||||
this.state = {
|
||||
open: false,
|
||||
selectedTalkgroup: this.props.selectedTalkgroups,
|
||||
selectedGroup: this.props.selectedGroup,
|
||||
filterStarred: this.props.filterStarred,
|
||||
activeTab: this.props.activeTab
|
||||
const handleTabChange = (e, data) => setActiveTab(data.activeIndex);
|
||||
const handleGroupChange = (e, { name, value }) => setSelectedGroup(value);
|
||||
const handleTalkgroupChange = (e, { name, value }) => setSelectedTalkgroup(value);
|
||||
const toggleStarred = () => setFilterStarred(!filterStarred);
|
||||
const handleClose = () => props.onClose(false);
|
||||
const onClose = props.onClose;
|
||||
|
||||
function handleDone(onClose) {
|
||||
switch (activeTab) {
|
||||
|
||||
case 1:
|
||||
if (selectedGroup) {
|
||||
dispatch(setGroupFilter(selectedGroup));
|
||||
props.onClose(true);
|
||||
} else {
|
||||
props.onClose(false);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (selectedTalkgroup) {
|
||||
dispatch(setTalkgroupFilter(selectedTalkgroup))
|
||||
props.onClose(true);
|
||||
} else {
|
||||
props.onClose(false);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
case 0:
|
||||
dispatch(setAllFilter());
|
||||
props.onClose(true);
|
||||
break;
|
||||
}
|
||||
if (globalFilterStarred !== filterStarred) {
|
||||
dispatch(setStarredFilter(filterStarred));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
handleTabChange = (e, data) => this.setState({activeTab: data.activeIndex});
|
||||
handleInputChange = (e, { name, value }) => this.setState({ [name]: value });
|
||||
toggleStarred = () => this.setState(prevState => ({ filterStarred: !prevState.filterStarred }));
|
||||
handleClose = () => this.props.onClose(false);
|
||||
handleDone(event) {
|
||||
switch(this.state.activeTab) {
|
||||
|
||||
case 1:
|
||||
if (this.state.selectedGroup) {
|
||||
this.props.callActions.setGroupFilter(this.state.selectedGroup);
|
||||
this.props.onClose(true);
|
||||
} else {
|
||||
this.props.onClose(false);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (this.state.selectedTalkgroup) {
|
||||
this.props.callActions.setTalkgroupFilter(this.state.selectedTalkgroup);
|
||||
this.props.onClose(true);
|
||||
} else {
|
||||
this.props.onClose(false);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
case 0:
|
||||
this.props.callActions.setAllFilter();
|
||||
this.props.onClose(true);
|
||||
break;
|
||||
}
|
||||
if (this.state.filterStarred !== this.props.filterStarred) {
|
||||
this.props.callActions.setStarred(this.state.filterStarred);
|
||||
this.props.onClose(true);
|
||||
|
||||
|
||||
var obj;
|
||||
let talkgroupList = [];
|
||||
if (isTalkgroupsSuccess) {
|
||||
for (const num in talkgroupsData["talkgroups"]) {
|
||||
const talkgroup = talkgroupsData["talkgroups"][num];
|
||||
obj = {
|
||||
key: talkgroup.num,
|
||||
value: talkgroup.num,
|
||||
text: talkgroup.description
|
||||
}
|
||||
talkgroupList.push(obj);
|
||||
}
|
||||
}
|
||||
|
||||
let groupList = [];
|
||||
if (isGroupsSuccess) {
|
||||
for (const num in groupsData) {
|
||||
const group = groupsData[num]
|
||||
obj = {
|
||||
key: group._id,
|
||||
value: group._id,
|
||||
text: group.groupName
|
||||
}
|
||||
groupList.push(obj);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
componentDidUpdate(prevProps) {
|
||||
|
||||
const filterChanged = ((prevProps.selectedTalkgroups !== this.props.selectedTalkgroups) || (prevProps.selectedGroup !== this.props.selectedGroup));
|
||||
if (filterChanged) {
|
||||
this.setState({selectedTalkgroup: prevProps.selectedTalkgroups, selectedGroup: prevProps.selectedGroup, activeTab: prevProps.activeTab});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
var obj;
|
||||
var talkgroupList = [];
|
||||
if (this.props.talkgroups) {
|
||||
for (const num in this.props.talkgroups) {
|
||||
const talkgroup = this.props.talkgroups[num];
|
||||
obj = {
|
||||
key: talkgroup.num,
|
||||
value: talkgroup.num,
|
||||
text: talkgroup.description
|
||||
}
|
||||
talkgroupList.push(obj);
|
||||
const panes = [
|
||||
{
|
||||
menuItem: 'All', render: () => {
|
||||
return (
|
||||
<Tab.Pane attached={false}>
|
||||
<Header>All Calls</Header>
|
||||
<p>Dispaly all of the calls.</p>
|
||||
</Tab.Pane>
|
||||
)
|
||||
}
|
||||
}
|
||||
var groupList = [];
|
||||
if (this.props.groups) {
|
||||
for (const num in this.props.groups) {
|
||||
const group = this.props.groups[num];
|
||||
obj = {
|
||||
key: group._id,
|
||||
value: group._id,
|
||||
text: group.groupName
|
||||
}
|
||||
groupList.push(obj);
|
||||
},
|
||||
{
|
||||
menuItem: 'Groups', render: () => {
|
||||
return (
|
||||
<Tab.Pane attached={false}>
|
||||
<Dropdown placeholder='Groups' fluid selection options={groupList} value={selectedGroup} name='selectedGroup' onChange={handleGroupChange} />
|
||||
|
||||
</Tab.Pane>
|
||||
)
|
||||
}
|
||||
}
|
||||
const panes = [
|
||||
{ menuItem: 'All', render: () =>
|
||||
{ return (
|
||||
<Tab.Pane attached={false}>
|
||||
<Header>All Calls</Header>
|
||||
<p>Dispaly all of the calls.</p>
|
||||
</Tab.Pane>
|
||||
)}},
|
||||
{ menuItem: 'Groups', render: () =>
|
||||
{ return (
|
||||
<Tab.Pane attached={false}>
|
||||
<Dropdown placeholder='Groups' fluid selection options={groupList} value={this.state.selectedGroup} name='selectedGroup' onChange={this.handleInputChange} />
|
||||
},
|
||||
{
|
||||
menuItem: 'Talkgroups', render: () => {
|
||||
return (
|
||||
<Tab.Pane attached={false}>
|
||||
<Dropdown placeholder='Talkgroups' fluid multiple selection options={talkgroupList} value={selectedTalkgroup} name='selectedTalkgroup' onChange={handleTalkgroupChange} />
|
||||
</Tab.Pane>
|
||||
)
|
||||
}
|
||||
},
|
||||
]
|
||||
return (
|
||||
|
||||
</Tab.Pane>
|
||||
)} },
|
||||
{ menuItem: 'Talkgroups', render: () =>
|
||||
{ return (
|
||||
<Tab.Pane attached={false}>
|
||||
<Dropdown placeholder='Talkgroups' fluid multiple selection options={talkgroupList} value={this.state.selectedTalkgroup} name='selectedTalkgroup' onChange={this.handleInputChange} />
|
||||
</Tab.Pane>
|
||||
)} },
|
||||
]
|
||||
return (
|
||||
<Modal open={props.open} onClose={handleClose} centered={false} size="tiny">
|
||||
<Modal.Header>Select a Filter</Modal.Header>
|
||||
<Modal.Content >
|
||||
<Modal.Description>
|
||||
<Tab menu={{ pointing: true }} panes={panes} defaultActiveIndex={activeTab} onTabChange={handleTabChange} />
|
||||
<Divider />
|
||||
<Checkbox label='Show only Starred calls' checked={filterStarred} name='filterStarred' onChange={toggleStarred} />
|
||||
</Modal.Description>
|
||||
</Modal.Content>
|
||||
<Modal.Actions>
|
||||
<Button onClick={()=> handleDone(onClose)} >
|
||||
<Icon name='checkmark' /> Done
|
||||
</Button>
|
||||
</Modal.Actions>
|
||||
</Modal>
|
||||
|
||||
<Modal open={this.props.open} onClose={this.handleClose} centered={false} size="tiny">
|
||||
<Modal.Header>Select a Filter</Modal.Header>
|
||||
<Modal.Content >
|
||||
<Modal.Description>
|
||||
<Tab menu={{ pointing: true }} panes={panes} defaultActiveIndex={this.props.activeTab} onTabChange={this.handleTabChange}/>
|
||||
<Divider/>
|
||||
<Checkbox label='Show only Starred calls' checked={this.state.filterStarred} name='filterStarred' onChange={this.toggleStarred}/>
|
||||
</Modal.Description>
|
||||
</Modal.Content>
|
||||
<Modal.Actions>
|
||||
<Button onClick={this.handleDone} >
|
||||
<Icon name='checkmark' /> Done
|
||||
</Button>
|
||||
</Modal.Actions>
|
||||
</Modal>
|
||||
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
export default FilterModal;
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import React, { Component } from "react";
|
||||
import React, { Component, useState } from "react";
|
||||
import { useGetGroupsQuery } from '../features/api/apiSlice'
|
||||
import { setGroupFilter } from "../features/callPlayer/callPlayerSlice";
|
||||
import { useSelector, useDispatch } from 'react-redux'
|
||||
|
||||
import {
|
||||
Modal,
|
||||
Button,
|
||||
@@ -6,8 +10,67 @@ import {
|
||||
Dropdown
|
||||
} from "semantic-ui-react";
|
||||
import "./FilterModal.css";
|
||||
import * as types from "./call-constants";
|
||||
|
||||
function GroupModal (props) {
|
||||
const shortName = useSelector((state) => state.callPlayer.shortName);
|
||||
const { data, isError, isLoading, isSuccess,error } = useGetGroupsQuery(props.shortName);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [selectedGroup, setSelectedGroup] = useState(false);
|
||||
const dispatch = useDispatch()
|
||||
const onClose = props.onClose;
|
||||
|
||||
function handleDone(onClose) {
|
||||
|
||||
if (selectedGroup) {
|
||||
dispatch(setGroupFilter(selectedGroup))
|
||||
//dispatch({type: types.SET_GROUP_FILTER, groupId: selectedGroup })
|
||||
onClose(true);
|
||||
} else {
|
||||
onClose(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let groupOptions = []
|
||||
|
||||
if (isSuccess) {
|
||||
|
||||
for (const num in data) {
|
||||
const group = data[num];
|
||||
var obj = {
|
||||
key: group._id,
|
||||
value: group._id,
|
||||
text: group.groupName
|
||||
}
|
||||
groupOptions.push(obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
|
||||
<Modal open={props.open} onClose={() => setOpen(false)} onOpen={() => setOpen(true)} size='tiny'>
|
||||
|
||||
<Modal.Header>Select a Group</Modal.Header>
|
||||
<Modal.Content >
|
||||
<Modal.Description>
|
||||
<p>Choose the type of calls you want to listen to</p>
|
||||
<Dropdown placeholder='Group...' fluid selection options={groupOptions} name='selectedGroup' onChange={(e, data) => setSelectedGroup(data.value)} />
|
||||
|
||||
</Modal.Description>
|
||||
|
||||
</Modal.Content>
|
||||
<Modal.Actions>
|
||||
<Button onClick={()=> handleDone(onClose)} >
|
||||
<Icon name='headphones' /> Listen
|
||||
</Button>
|
||||
</Modal.Actions>
|
||||
</Modal>
|
||||
|
||||
)
|
||||
}
|
||||
/*
|
||||
class GroupModal extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
@@ -80,6 +143,6 @@ componentDidUpdate(prevProps) {
|
||||
|
||||
)
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
export default GroupModal;
|
||||
|
||||
@@ -1,177 +0,0 @@
|
||||
import React, { Component } from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import {
|
||||
Container,
|
||||
Header,
|
||||
Form,
|
||||
Grid,
|
||||
Rail,
|
||||
Segment,
|
||||
List,
|
||||
Input,
|
||||
Button,
|
||||
Message,
|
||||
Icon,
|
||||
Table
|
||||
} from "semantic-ui-react";
|
||||
|
||||
// ----------------------------------------------------
|
||||
const requestMessageStyle = {
|
||||
color: "red"
|
||||
};
|
||||
|
||||
// ----------------------------------------------------
|
||||
class CreateGroup extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleSubmit = this.handleSubmit.bind(this);
|
||||
|
||||
// Set initial state
|
||||
this.state = {
|
||||
groupName: "",
|
||||
group: {
|
||||
name: "",
|
||||
items: []
|
||||
},
|
||||
talkgroups: (this.props.talkgroups ? this.props.talkgroups : [])
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
//this.props.groupActions.fetchGroups(this.props.shortName);
|
||||
|
||||
this.props.talkgroupActions.fetchTalkgroups(this.props.shortName);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
this.setState({ talkgroups: nextProps.talkgroups });
|
||||
}
|
||||
|
||||
removeTalkgroup(event, index) {
|
||||
const item = {
|
||||
num: this.state.group.items[index].num,
|
||||
description: this.state.group.items[index].description
|
||||
};
|
||||
|
||||
const talkgroups = this.state.talkgroups.slice(0); // copy
|
||||
|
||||
for (var i = 0, len = talkgroups.length; i < len; i++) {
|
||||
if (item.num < talkgroups[i].num) {
|
||||
talkgroups.splice(i, 0, item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.setState({
|
||||
group: { items: this.state.group.items
|
||||
.slice(0, index)
|
||||
.concat(this.state.group.items.slice(index + 1))},
|
||||
talkgroups: talkgroups
|
||||
});
|
||||
}
|
||||
|
||||
handleInputChange = (e, { name, value }) => this.setState({ [name]: value });
|
||||
|
||||
addTalkgroup(event, index) {
|
||||
const item = {
|
||||
num: this.state.talkgroups[index].num,
|
||||
description: this.state.talkgroups[index].description
|
||||
};
|
||||
|
||||
this.setState({
|
||||
group: { items: this.state.group.items.concat(item) },
|
||||
talkgroups: this.state.talkgroups
|
||||
.slice(0, index)
|
||||
.concat(this.state.talkgroups.slice(index + 1))
|
||||
});
|
||||
}
|
||||
handleSubmit() {
|
||||
var talkgroupNums = this.state.group.items.map(a => a.num);
|
||||
const data = {shortName: this.props.shortName, groupName: this.state.groupName, talkgroups: JSON.stringify(talkgroupNums) }
|
||||
this.props.groupActions.createGroup(data).then(requestMessage => {
|
||||
if (requestMessage) {
|
||||
// report to the user is there was a problem during registration
|
||||
this.setState({
|
||||
requestMessage
|
||||
});
|
||||
} else {
|
||||
this.props.groupActions.changeUrl("/system/" + this.props.shortName + "/2");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const talkgroups = this.state.talkgroups;
|
||||
const group = this.state.group.items;
|
||||
const railStyle = {
|
||||
top: "15px",
|
||||
minHeight: "200px"
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
{talkgroups.length ? (
|
||||
<Container text>
|
||||
<Message
|
||||
icon='upload'
|
||||
header='Import Talkgroups'
|
||||
content='Before you can create groups of Talkgroups, you need to import some talkgroups.'
|
||||
/>
|
||||
</Container>
|
||||
) : (
|
||||
<Grid container columns={2}>
|
||||
<Grid.Column>
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>Number</Table.HeaderCell>
|
||||
|
||||
<Table.HeaderCell>Description</Table.HeaderCell>
|
||||
<Table.HeaderCell />
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{talkgroups.map((talkgroup, i) => (
|
||||
<Table.Row link="true" key={talkgroup.num + "-" + i}>
|
||||
<Table.Cell>{talkgroup.num}</Table.Cell>
|
||||
|
||||
<Table.Cell>{talkgroup.description}</Table.Cell>
|
||||
<Table.Cell>
|
||||
<Icon
|
||||
link
|
||||
name="plus"
|
||||
onClick={e => this.addTalkgroup(e, i)}
|
||||
/>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
))}
|
||||
</Table.Body>
|
||||
</Table>
|
||||
<Rail position="right">
|
||||
<Segment style={railStyle}>
|
||||
<Input action={{ onClick: this.handleSubmit, content: 'Save' }} name="groupName" onChange={this.handleInputChange} placeholder="Group Name" />
|
||||
<List divided relaxed>
|
||||
{group.map((talkgroup, i) => (
|
||||
<List.Item key={"Group-" + i}>
|
||||
<List.Icon
|
||||
name="remove"
|
||||
verticalAlign="middle"
|
||||
link={true}
|
||||
onClick={e => this.removeTalkgroup(e, i)}
|
||||
/>
|
||||
<List.Content>
|
||||
{talkgroup.description}
|
||||
|
||||
</List.Content>
|
||||
</List.Item>
|
||||
))}
|
||||
</List>
|
||||
</Segment>
|
||||
</Rail>
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default CreateGroup;
|
||||
@@ -1,25 +0,0 @@
|
||||
import { connect } from "react-redux"
|
||||
import * as groupActionCreators from "./group-actions"
|
||||
import * as talkgroupActionCreators from "../Talkgroups/talkgroup-actions"
|
||||
import { bindActionCreators } from 'redux'
|
||||
import CreateGroup from "./CreateGroup"
|
||||
|
||||
//groups: state.group.items[props.match.params.shortName],
|
||||
function mapStateToProps(state,props) {
|
||||
return {
|
||||
talkgroups: state.talkgroup.items[props.match.params.shortName],
|
||||
shortName: props.match.params.shortName
|
||||
}
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
groupActions: bindActionCreators(groupActionCreators,dispatch),
|
||||
talkgroupActions: bindActionCreators(talkgroupActionCreators, dispatch)
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(CreateGroup)
|
||||
@@ -1,77 +0,0 @@
|
||||
import React, { Component } from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import { Link } from 'react-router-dom'
|
||||
import {
|
||||
Container,
|
||||
Header,
|
||||
Form,
|
||||
Grid,
|
||||
Segment,
|
||||
Input,
|
||||
Button,
|
||||
Message,
|
||||
Icon,
|
||||
Table
|
||||
} from "semantic-ui-react";
|
||||
|
||||
// ----------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------
|
||||
class ListGroups extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//https://stackoverflow.com/questions/36559661/how-can-i-dispatch-from-child-components-in-react-redux
|
||||
//https://stackoverflow.com/questions/42597602/react-onclick-pass-event-with-parameter
|
||||
render() {
|
||||
const groups = this.props.groups;
|
||||
if (groups) {
|
||||
return (
|
||||
|
||||
<Table >
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>Name</Table.HeaderCell>
|
||||
<Table.HeaderCell>Talkgroup Count</Table.HeaderCell>
|
||||
<Table.HeaderCell></Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{groups.map((group, i) => (
|
||||
<Table.Row key={ "Group-" + i}>
|
||||
<Table.Cell>{group.groupName}</Table.Cell>
|
||||
<Table.Cell>{group.talkgroups.length}</Table.Cell>
|
||||
<Table.Cell><Icon
|
||||
name="up arrow"
|
||||
link={true}
|
||||
onClick={e => this.props.reorderGroup(i, i-1)}
|
||||
/><Icon
|
||||
name="down arrow"
|
||||
link={true}
|
||||
onClick={e => this.props.reorderGroup(i, i+1)}
|
||||
/><Icon
|
||||
name="remove"
|
||||
link={true}
|
||||
onClick={e => this.props.deleteGroup(group._id)}
|
||||
/>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
))}
|
||||
</Table.Body>
|
||||
</Table>
|
||||
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div/>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default ListGroups;
|
||||
76
frontend/src/features/callPlayer/callPlayerSlice.js
Normal file
76
frontend/src/features/callPlayer/callPlayerSlice.js
Normal file
@@ -0,0 +1,76 @@
|
||||
import { createSlice } from '@reduxjs/toolkit'
|
||||
const now = new Date();
|
||||
const initialState = {
|
||||
isWaiting: false,
|
||||
shortName: "",
|
||||
byId: {},
|
||||
allIds: [],
|
||||
oldestCallTime: now,
|
||||
newestCallTime: now,
|
||||
filterType: 0,
|
||||
filterTalkgroups: [],
|
||||
filterGroupId: false,
|
||||
filterDate: false,
|
||||
filterStarred: false,
|
||||
currentCallId: false,
|
||||
live: false
|
||||
}
|
||||
|
||||
export const callPlayerSlice = createSlice({
|
||||
name: 'callPlayer',
|
||||
initialState,
|
||||
reducers: {
|
||||
setCurrentCallId: (state, action) => {
|
||||
state.currentCallId = action.payload;
|
||||
},
|
||||
setCallTime: (state, action) => {
|
||||
state.newestCallTime = action.payload;
|
||||
state.oldestCallTime = action.payload;
|
||||
},
|
||||
setFilter: (state,action) => {
|
||||
var filter={};
|
||||
state.live = !action.payload.live ? state.live : action.payload.live;
|
||||
state.filterStarred = !action.payload.filterStarred ? false : action.payload.filterStarred;
|
||||
state.filterType = !action.payload.filterType ? 0 : action.payload.filterType;
|
||||
state.filterTalkgroups = !action.payload.filterTalkgroups ? [] : action.payload.filterTalkgroups;
|
||||
state.filterGroupId = !action.payload.filterGroupId ? false : action.payload.filterGroupId;
|
||||
state.filterDate = !action.payload.filterDate ? 0 : action.payload.filterDate;
|
||||
},
|
||||
setLive: (state,action) => {
|
||||
state.live = action.payload;
|
||||
},
|
||||
setShortName: (state, action) => {
|
||||
state.shortName = action.payload;
|
||||
},
|
||||
setDateFilter: (state, action) => {
|
||||
state.filterDate = action.payload;
|
||||
},
|
||||
setStarredFilter: (state, action) => {
|
||||
state.filterStarred = action.payload;
|
||||
},
|
||||
setAllFilter: (state) => {
|
||||
state.filterType = 0;
|
||||
state.filterTalkgroups = [];
|
||||
state.filterGroupId = 0;
|
||||
},
|
||||
setGroupFilter: (state, action) => {
|
||||
state.filterType = 1;
|
||||
state.filterTalkgroups = [];
|
||||
state.filterGroupId = action.payload;
|
||||
},
|
||||
setTalkgroupFilter: (state, action) => {
|
||||
state.filterType = 2;
|
||||
state.filterTalkgroups = action.payload;
|
||||
state.filterGroupId = 0;
|
||||
},
|
||||
|
||||
},
|
||||
})
|
||||
|
||||
// Action creators are generated for each case reducer function
|
||||
export const { setCurrentCallId, setCallTime, setFilter, setLive, setShortName, setDateFilter, setStarredFilter, setAllFilter, setGroupFilter, setTalkgroupFilter } = callPlayerSlice.actions
|
||||
|
||||
export default callPlayerSlice.reducer
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { applyMiddleware, compose, createStore } from 'redux'
|
||||
import { routerMiddleware } from 'connected-react-router'
|
||||
import createRootReducer from './reducers'
|
||||
import { apiSlice } from '../features/api/apiSlice'
|
||||
import {callPlayerSlice} from "../features/callPlayer/callPlayerSlice"
|
||||
|
||||
import thunk from 'redux-thunk';
|
||||
|
||||
@@ -20,7 +21,7 @@ export default function configureStore(preloadedState) {
|
||||
applyMiddleware(
|
||||
routerMiddleware(history), // for dispatching history actions
|
||||
thunk,
|
||||
apiSlice.middleware
|
||||
apiSlice.middleware,
|
||||
// ... other middlewares ...
|
||||
),
|
||||
),
|
||||
|
||||
@@ -7,12 +7,16 @@ import talkgroupReducer from "../Talkgroups/talkgroup-reducer"
|
||||
import groupReducer from "../Group/group-reducer"
|
||||
import callReducer from "../Call/call-reducer"
|
||||
import {apiSlice} from "../features/api/apiSlice"
|
||||
import callPlayerSlice from "../features/callPlayer/callPlayerSlice"
|
||||
|
||||
export default (history) => combineReducers({
|
||||
router: connectRouter(history),
|
||||
system: systemReducer,
|
||||
talkgroup: talkgroupReducer,
|
||||
group: groupReducer,
|
||||
callPlayer: callPlayerSlice,
|
||||
call: callReducer,
|
||||
[apiSlice.reducerPath]: apiSlice.reducer
|
||||
|
||||
[apiSlice.reducerPath]: apiSlice.reducer,
|
||||
|
||||
})
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user