Skip to content

Commit

Permalink
Issue #28: Specoffer list
Browse files Browse the repository at this point in the history
  • Loading branch information
ormus2002 committed Apr 1, 2016
1 parent 3fc5193 commit bdebeb0
Show file tree
Hide file tree
Showing 18 changed files with 452 additions and 7 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "ums-frontned",
"name": "ums-frontend",
"version": "0.0.1",
"description": "",
"homepage": "https://github.com/mkozhukharenko/ums-frontend",
Expand All @@ -25,6 +25,7 @@
"amcharts3": "github:amcharts/amcharts3",
"ammap3": "github:amcharts/ammap3",
"bootstrap": "^3.3.6",
"fixed-data-table": "^0.6.0",
"history": "2.0.0",
"lodash": "^4.6.1",
"lscache": "^1.0.5",
Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import store from 'store';
import routes from './system/routes';
import '../assets/stylesheets/index.css';
import 'bootstrap/dist/css/bootstrap.css';
import 'fixed-data-table/dist/fixed-data-table.css';
import {syncHistoryWithStore} from 'react-router-redux';

// Create an enhanced history that syncs navigation events with the store
Expand Down
5 changes: 3 additions & 2 deletions src/modules/enrolments/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ let {

/**
* check if data is loaded
* @param storeState
* @param reducerName
* @param entityData
* @returns {boolean}
*/
export function isEntityDataLoaded(entityData) {
Expand Down Expand Up @@ -90,6 +89,8 @@ export function decodeOneEnrolment(item, dictionaries) {
* @returns {Array} - array of decoded enrolments
*/
export function decodeEnrolments(rowEnrolments, dictionaries) {
if (!rowEnrolments) return [];

return rowEnrolments.resources.map((item)=> {
return decodeOneEnrolment(item, dictionaries);
});
Expand Down
6 changes: 3 additions & 3 deletions src/modules/enrolments/view/MainInfo.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Loading from 'loading';
import {DEPARTMENTS, ENROLMENTS_TYPES, ENROLMENTS_STATUS_TYPES} from '../../dictionaries/constants';
import { createSelector } from 'reselect';

export default class MainInfo extends Component {
class MainInfo extends Component {
static propTypes = {
decodedEnrolment: PropTypes.arrayOf(React.PropTypes.object).isRequired,
id: PropTypes.string.isRequired
Expand Down Expand Up @@ -77,11 +77,11 @@ MainInfo.propTypes = {
// };

export const getOneDecodedEnrolment = createSelector(
[ (state) => state.enrolments.view.mainInfo,
[ (state, ownProps) => state.enrolments.view.mainInfo.data[ownProps.params.id],
(state) => state.dictionaries,
(state, ownProps) => ownProps.params.id],
(mainInfo, listOfDict, enrolId) => ({
decodedEnrolment: decodeOneEnrolment(mainInfo.data[enrolId], listOfDict),
decodedEnrolment: decodeOneEnrolment(mainInfo, listOfDict),
isDataLoaded: isDataForOneEnrolmentLoaded(ENROLMENT_MAININFO_REDUCER, {'enrolId': enrolId})
})
)
Expand Down
8 changes: 8 additions & 0 deletions src/modules/navbar/NavBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ export default class NavBar extends Component {
<NavItem>Статистика</NavItem>
</LinkContainer>

<LinkContainer to={{ pathname: '/specoffers', query: this.props.specoffersQueryParams}}>
<NavItem>Пропозиції</NavItem>
</LinkContainer>

{this.authItem('rating', 'Рейтинг', {query: this.props.ratingQueryParams})}
{this.authItem('persons', 'Персони')}
</Nav>
Expand Down Expand Up @@ -91,6 +95,10 @@ function select(state) {
ratingQueryParams: {
departmentId: state.rating.specofferChooser.departmentId,
specofferId: state.rating.specofferChooser.specofferId
},
specoffersQueryParams: {
timePeriodId: state.specoffers.list.timePeriodId,
limit: state.specoffers.list.limit
}
};
}
Expand Down
2 changes: 1 addition & 1 deletion src/modules/rating/container/SpecofferChooser.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {connect} from 'react-redux';
import {loadSpecoffersChooser} from './../actions';
import Nav from 'react-bootstrap/lib/Nav';
import NavItem from 'react-bootstrap/lib/NavItem';
import { LinkContainer } from 'react-router-bootstrap';
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
import find from 'lodash/find'
import DepartmentsList from './../components/DepartmentsList'
import SpecoffersList from './../components/SpecoffersList'
Expand Down
39 changes: 39 additions & 0 deletions src/modules/specoffers/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {REQUEST_API} from '../../system/constants';
import * as types from './constants';

export function loadSpecoffersList(params) {
return {
type: REQUEST_API,
request: {
url: `/specoffers?timePeriodId=${params.timePeriodId}&limit=${params.limit}`,
actions: {
start: {type: types.LOAD_ALL_SPECOFFERS_START},
success: {type: types.LOAD_ALL_SPECOFFERS_SUCCESS},
fail: {type: types.LOAD_ALL_SPECOFFERS_FAIL}
},
params,
cache: true
},
interrupt: (store) => !!store.getState().specoffers.list.resources.length
};
}

export function loadEnrolmentsListBySpecoffer(params) {
return {
type: REQUEST_API,
request: {
url: `/enrolments?specOfferId=${params.specOfferId}`,
actions: {
start: {type: types.LOAD_ENROLMENTS_BY_SPECOFFERS_START},
success: {type: types.LOAD_ENROLMENTS_BY_SPECOFFERS_SUCCESS},
fail: {type: types.LOAD_ENROLMENTS_BY_SPECOFFERS_FAIL}
},
params,
cache: true
},
interrupt: (store) => !!store.getState().specoffers.specofferEnrolments.data[params.specOfferId],
payload: {
specOfferId: params.specOfferId
}
};
}
54 changes: 54 additions & 0 deletions src/modules/specoffers/components/Enrolments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React, {Component, PropTypes} from 'react';
import find from 'lodash/find'
import {createSelector} from 'reselect';
import {connect} from 'react-redux';

import Loading from 'loading';
import * as dictConst from '../../dictionaries/constants';
import loadDictionaries from '../../dictionaries/actions';
import {decodeEnrolments} from '../../enrolments/helpers';

import {loadEnrolmentsListBySpecoffer} from './../actions';
import {isDataForSpecoffersLoaded, decodeOneSpecoffer} from './../helpers';
import {SPECOFFERS_LIST_REDUCER} from './../constants';

class SpecofferEnrolments extends Component {
constructor(props) {
super(props);
}

componentDidMount() {
const {specOfferId} = this.props;
this.props.loadDictionaries([dictConst.DEPARTMENTS]);
this.props.loadEnrolmentsListBySpecoffer({specOfferId: specOfferId});
}

render() {
if (!isDataForSpecoffersLoaded(SPECOFFERS_LIST_REDUCER)) {
return <Loading/>;
}

return (
<div>
SpecofferEnrolments
</div>
);
}
}

const mapStateToSpecofferEnrolments = createSelector(
(state, ownProps) => state.specoffers.specofferEnrolments.data[ownProps.location.query.specOfferId],
(state, ownProps) => find(state.specoffers.list, {id: ownProps.location.query.specOfferId}),
(state) => state.dictionaries,
(state, ownProps) => ownProps.location.query.specOfferId,
(enrolments, specoffer, listOfDict, specOfferId) => ({
decodedEnrolments: decodeEnrolments(enrolments, listOfDict),
decodedOneSpecoffer: decodeOneSpecoffer(specoffer, listOfDict),
specOfferId: specOfferId
})
);

export default connect(
mapStateToSpecofferEnrolments,
{loadEnrolmentsListBySpecoffer, loadDictionaries}
)(SpecofferEnrolments);
7 changes: 7 additions & 0 deletions src/modules/specoffers/components/SpecofferInfoMain.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React, {Component, PropTypes} from 'react';

export default class SpecofferInfoMain extends Component {
render() {
return <div>SpecofferInfoMain</div>;
}
}
33 changes: 33 additions & 0 deletions src/modules/specoffers/components/SpecofferInfoPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React, {Component, PropTypes} from 'react';
import Button from 'react-bootstrap/lib/Button';
import {LinkContainer} from 'react-router-bootstrap';

class SpecofferInfoPage extends Component {
render() {
return (
<div>
<div className="btn-group">
<LinkContainer to={{ pathname: `/specoffers-info/enrolments`, query: this.props.location.query }}>
<Button eventKey={1} className="btn btn-default"> Заяви </Button>
</LinkContainer>
<LinkContainer to={{ pathname: `/specoffers-info/info`, query: this.props.location.query }}>
<Button eventKey={2} className="btn btn-default"> Info </Button>
</LinkContainer>
<LinkContainer to={{ pathname: `/specoffers/${this.props.params.id}/statuses`}}>
<Button eventKey={3} className="btn btn-default"> Statuses </Button>
</LinkContainer>
<LinkContainer to={{ pathname: `/specoffers/${this.props.params.id}/subjects`}}>
<Button eventKey={4} className="btn btn-default"> Subjects </Button>
</LinkContainer>
</div>
{this.props.children}
</div>
);
}
}

SpecofferInfoPage.propTypes = {
children: PropTypes.any
};

export default SpecofferInfoPage;
23 changes: 23 additions & 0 deletions src/modules/specoffers/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export const LOAD_ALL_SPECOFFERS_START = 'LOAD_ALL_SPECOFFERS_START';
export const LOAD_ALL_SPECOFFERS_SUCCESS = 'LOAD_ALL_SPECOFFERS_SUCCESS';
export const LOAD_ALL_SPECOFFERS_FAIL = 'LOAD_ALL_SPECOFFERS_START';

export const LOAD_ENROLMENTS_BY_SPECOFFERS_START = 'LOAD_ENROLMENTS_BY_SPECOFFERS_START';
export const LOAD_ENROLMENTS_BY_SPECOFFERS_SUCCESS = 'LOAD_ENROLMENTS_BY_SPECOFFERS_SUCCESS';
export const LOAD_ENROLMENTS_BY_SPECOFFERS_FAIL = 'LOAD_ENROLMENTS_BY_SPECOFFERS_FAIL';

export const SPECOFFERS_REDUCER = 'specoffers';
export const SPECOFFERS_LIST_REDUCER = 'list';


export const FIELD_NAMES = [
{'name': 'Спеціальність', 'field': 'specialtyId'},
{'name': 'Структурний підрозділ', 'field': 'departmentId'},
{'name': 'Тип пропозиції', 'field': 'specofferTypeId'},
{'name': 'docNum', 'field': 'docNum'},
{'name': 'weightCertificate', 'field': 'weightCertificate'},
{'name': 'weightAward', 'field': 'weightAward'},
{'name': 'Форма навчання', 'field': 'educationFormTypeId'},
{'name': 'Ліцензований обсяг', 'field': 'licCount'},
{'name': 'Державне замовлення', 'field': 'stateCount'},
];
113 changes: 113 additions & 0 deletions src/modules/specoffers/containers/SpecoffersListPage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {createSelector} from 'reselect';
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
import Button from 'react-bootstrap/lib/Button';
import {Table, Column, Cell} from 'fixed-data-table';

import Loading from 'loading';
import {loadSpecoffersList} from './../actions';
import {isDataForSpecoffersLoaded, decodeSpecoffers} from './../helpers';
import * as dictConst from '../../dictionaries/constants';
import loadDictionaries from '../../dictionaries/actions';
import {SPECOFFERS_LIST_REDUCER, FIELD_NAMES} from './../constants';

class MyLinkCell extends Component {
render() {
const {rowIndex, field, data, ...props} = this.props;
let path = `/specoffers-info/enrolments`;
let query = {specOfferId: data[rowIndex][field]};
return (
<Cell {...props}>
<LinkContainer to={{ pathname: path, query: query }}>
<a>{data[rowIndex][field]}</a>
</LinkContainer>
</Cell>
);
}
}

class SpecoffersListPage extends Component {
constructor(props) {
super(props);
}

componentDidMount() {
const {timePeriodId, limit} = this.props;
this.props.loadDictionaries([dictConst.DEPARTMENTS]);
this.props.loadSpecoffersList({timePeriodId, limit});
}

render() {
if (!isDataForSpecoffersLoaded(SPECOFFERS_LIST_REDUCER)) {
return <Loading/>;
}

let {decodedSpecoffers} = this.props;

let cells = FIELD_NAMES.map((item) => {
return <Column
header={<Cell>{item.name}</Cell>}
cell={props => (
<Cell {...props}>
{decodedSpecoffers[props.rowIndex][item.field]}
</Cell>
)
}
flexGrow={1}
width={20}
/>
});

return (
<div>
<Table
rowsCount={decodedSpecoffers.length}
rowHeight={50}
headerHeight={50}
width={950}
height={420}>
<Column
header={<Cell></Cell>}
cell={
<MyLinkCell
data={decodedSpecoffers}
field="id"
/>
}
width={40}
/>
{cells}
<Column
header=''
cell={props => (
<Cell {...props}>
<LinkContainer to={{ pathname: `/specoffers/${decodedSpecoffers[props.rowIndex]['id']}/info`}}>
<Button eventKey={1} bsStyle="info" bsSize="xsmall"> M </Button>
</LinkContainer>
</Cell>
)
}
width={50}
/>
</Table>
</div>
);
}
}

const mapStateToSpecoffers = createSelector(
(state) => state.specoffers.list,
(state) => state.dictionaries,
(state, ownProps) => ownProps.location.query,
(list, listOfDict, query) => ({
decodedSpecoffers: decodeSpecoffers(list, listOfDict),
timePeriodId: query.timePeriodId,
limit: query.limit
})
);

export default connect(
mapStateToSpecoffers,
{loadSpecoffersList, loadDictionaries}
)(SpecoffersListPage);
Loading

0 comments on commit bdebeb0

Please sign in to comment.