mirror of
https://github.com/opensupports/opensupports.git
synced 2025-07-30 01:05:18 +02:00
Merged in frontend-table-component (pull request #37)
Frontend table component + Implementation
This commit is contained in:
commit
cd49405f61
@ -8,7 +8,7 @@ gulp.task('browserSync', function() {
|
|||||||
|
|
||||||
browserSync({
|
browserSync({
|
||||||
proxy: 'localhost:' + config.serverport,
|
proxy: 'localhost:' + config.serverport,
|
||||||
startPath: 'app'
|
startPath: '/'
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
@ -21,7 +21,7 @@ var util = require('gulp-util');
|
|||||||
function buildScript(file, watch) {
|
function buildScript(file, watch) {
|
||||||
|
|
||||||
var bundler = browserify({
|
var bundler = browserify({
|
||||||
entries: [config.sourceDir + 'app/' + file],
|
entries: [config.sourceDir + file],
|
||||||
debug: !global.isProd,
|
debug: !global.isProd,
|
||||||
insertGlobalVars: {
|
insertGlobalVars: {
|
||||||
noFixtures: function() {
|
noFixtures: function() {
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
"app-module-path": "^1.0.3",
|
"app-module-path": "^1.0.3",
|
||||||
"classnames": "^2.1.3",
|
"classnames": "^2.1.3",
|
||||||
"jquery": "^2.1.4",
|
"jquery": "^2.1.4",
|
||||||
|
"keycode": "^2.1.4",
|
||||||
"localStorage": "^1.0.3",
|
"localStorage": "^1.0.3",
|
||||||
"lodash": "^3.10.0",
|
"lodash": "^3.10.0",
|
||||||
"messageformat": "^0.2.2",
|
"messageformat": "^0.2.2",
|
||||||
|
@ -11,42 +11,55 @@ const SessionActions = requireUnit('actions/session-actions', {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('Session Actions,', function () {
|
describe('Session Actions,', function () {
|
||||||
APICallMock.call.returns('API_RESULT');
|
|
||||||
|
|
||||||
describe('login action', function () {
|
describe('login action', function () {
|
||||||
it('should return LOGIN with with API_RESULT promise', function () {
|
it('should return LOGIN with with a result promise', function () {
|
||||||
APICallMock.call.reset();
|
APICallMock.call.returns({
|
||||||
|
then: function (resolve) {
|
||||||
|
resolve({
|
||||||
|
data: {
|
||||||
|
userId: 14
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let loginData = {
|
let loginData = {
|
||||||
email: 'SOME_EMAIL',
|
email: 'SOME_EMAIL',
|
||||||
password: 'SOME_PASSWORD',
|
password: 'SOME_PASSWORD',
|
||||||
remember: false
|
remember: false
|
||||||
};
|
};
|
||||||
|
|
||||||
expect(SessionActions.login(loginData)).to.deep.equal({
|
expect(SessionActions.login(loginData).type).to.equal('LOGIN');
|
||||||
type: 'LOGIN',
|
expect(storeMock.dispatch).to.have.been.calledWithMatch({type: 'USER_DATA'});
|
||||||
payload: 'API_RESULT'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(APICallMock.call).to.have.been.calledWith({
|
expect(APICallMock.call).to.have.been.calledWith({
|
||||||
path: '/user/login',
|
path: '/user/get',
|
||||||
data: loginData
|
data: {
|
||||||
|
userId: 14
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('autoLogin action', function () {
|
describe('autoLogin action', function () {
|
||||||
it('should return LOGIN_AUTO with remember data from sessionStore', function () {
|
it('should return LOGIN_AUTO with remember data from sessionStore', function () {
|
||||||
APICallMock.call.reset();
|
APICallMock.call.returns({
|
||||||
|
then: function (resolve) {
|
||||||
|
resolve({
|
||||||
|
data: {
|
||||||
|
userId: 14
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
sessionStoreMock.getRememberData.returns({
|
sessionStoreMock.getRememberData.returns({
|
||||||
token: 'SOME_TOKEN',
|
token: 'SOME_TOKEN',
|
||||||
userId: 'SOME_ID',
|
userId: 'SOME_ID',
|
||||||
expiration: 'SOME_EXPIRATION'
|
expiration: 'SOME_EXPIRATION'
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(SessionActions.autoLogin()).to.deep.equal({
|
expect(SessionActions.autoLogin().type).to.equal('LOGIN_AUTO');
|
||||||
type: 'LOGIN_AUTO',
|
expect(storeMock.dispatch).to.have.been.calledWithMatch({type: 'USER_DATA'});
|
||||||
payload: 'API_RESULT'
|
|
||||||
});
|
|
||||||
expect(APICallMock.call).to.have.been.calledWith({
|
expect(APICallMock.call).to.have.been.calledWith({
|
||||||
path: '/user/login',
|
path: '/user/login',
|
||||||
data: {
|
data: {
|
||||||
@ -60,6 +73,7 @@ describe('Session Actions,', function () {
|
|||||||
|
|
||||||
describe('logout action', function () {
|
describe('logout action', function () {
|
||||||
it('should return LOGOUT and call /user/logout', function () {
|
it('should return LOGOUT and call /user/logout', function () {
|
||||||
|
APICallMock.call.returns('API_RESULT');
|
||||||
APICallMock.call.reset();
|
APICallMock.call.reset();
|
||||||
|
|
||||||
expect(SessionActions.logout()).to.deep.equal({
|
expect(SessionActions.logout()).to.deep.equal({
|
||||||
|
@ -9,6 +9,10 @@ export default {
|
|||||||
payload: API.call({
|
payload: API.call({
|
||||||
path: '/user/login',
|
path: '/user/login',
|
||||||
data: loginData
|
data: loginData
|
||||||
|
}).then((result) => {
|
||||||
|
store.dispatch(this.getUserData(result.data.userId));
|
||||||
|
|
||||||
|
return result;
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -25,6 +29,10 @@ export default {
|
|||||||
rememberToken: rememberData.token,
|
rememberToken: rememberData.token,
|
||||||
isAutomatic: true
|
isAutomatic: true
|
||||||
}
|
}
|
||||||
|
}).then((result) => {
|
||||||
|
store.dispatch(this.getUserData(result.data.userId));
|
||||||
|
|
||||||
|
return result;
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -39,6 +47,18 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getUserData(userId) {
|
||||||
|
return {
|
||||||
|
type: 'USER_DATA',
|
||||||
|
payload: API.call({
|
||||||
|
path: '/user/get',
|
||||||
|
data: {
|
||||||
|
userId: userId
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
initSession() {
|
initSession() {
|
||||||
return {
|
return {
|
||||||
type: 'CHECK_SESSION',
|
type: 'CHECK_SESSION',
|
||||||
|
@ -28,8 +28,8 @@ class App extends React.Component {
|
|||||||
redirectIfPathIsNotValid(props) {
|
redirectIfPathIsNotValid(props) {
|
||||||
const validations = {
|
const validations = {
|
||||||
languageChanged: props.config.language !== this.props.config.language,
|
languageChanged: props.config.language !== this.props.config.language,
|
||||||
loggedIn: !_.includes(props.location.pathname, '/app/dashboard') && props.session.logged,
|
loggedIn: !_.includes(props.location.pathname, '/dashboard') && props.session.logged,
|
||||||
loggedOut: _.includes(props.location.pathname, '/app/dashboard') && !props.session.logged
|
loggedOut: _.includes(props.location.pathname, '/dashboard') && !props.session.logged
|
||||||
};
|
};
|
||||||
|
|
||||||
if (validations.languageChanged) {
|
if (validations.languageChanged) {
|
||||||
@ -37,11 +37,11 @@ class App extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (validations.loggedOut) {
|
if (validations.loggedOut) {
|
||||||
browserHistory.push('/app');
|
browserHistory.push('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (validations.loggedIn) {
|
if (validations.loggedIn) {
|
||||||
browserHistory.push('/app/dashboard');
|
browserHistory.push('/dashboard');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,8 @@ const history = syncHistoryWithStore(browserHistory, store);
|
|||||||
|
|
||||||
export default (
|
export default (
|
||||||
<Router history={history}>
|
<Router history={history}>
|
||||||
<Route component={App} path='/'>
|
<Route component={App}>
|
||||||
<Route path='/app' component={MainLayout}>
|
<Route path='/' component={MainLayout}>
|
||||||
<IndexRoute component={MainHomePage} />
|
<IndexRoute component={MainHomePage} />
|
||||||
<Route path='signup' component={MainSignUpPage}/>
|
<Route path='signup' component={MainSignUpPage}/>
|
||||||
<Route path='recover-password' component={MainRecoverPasswordPage}/>
|
<Route path='recover-password' component={MainRecoverPasswordPage}/>
|
||||||
@ -40,7 +40,7 @@ export default (
|
|||||||
<Route path='edit-profile' component={DashboardEditProfilePage}/>
|
<Route path='edit-profile' component={DashboardEditProfilePage}/>
|
||||||
|
|
||||||
<Route path='article' component={DashboardArticlePage}/>
|
<Route path='article' component={DashboardArticlePage}/>
|
||||||
<Route path='ticket' component={DashboardTicketPage}/>
|
<Route path='ticket/:ticketNumber' component={DashboardTicketPage}/>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
|
@ -2,14 +2,17 @@ import React from 'react';
|
|||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
|
|
||||||
import DashboardMenu from 'app/main/dashboard/dashboard-menu';
|
import DashboardMenu from 'app/main/dashboard/dashboard-menu';
|
||||||
|
import Widget from 'core-components/widget';
|
||||||
|
|
||||||
class DashboardLayout extends React.Component {
|
class DashboardLayout extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (this.props.session.logged) ? (
|
return (this.props.session.logged) ? (
|
||||||
<div>
|
<div className="dashboard">
|
||||||
<div><DashboardMenu location={this.props.location} /></div>
|
<div className="dashboard__menu col-md-3"><DashboardMenu location={this.props.location} /></div>
|
||||||
<div>{this.props.children}</div>
|
<Widget className="dashboard__content col-md-9">
|
||||||
|
{this.props.children}
|
||||||
|
</Widget>
|
||||||
</div>
|
</div>
|
||||||
) : null;
|
) : null;
|
||||||
}
|
}
|
||||||
|
9
client/src/app/main/dashboard/dashboard-layout.scss
Normal file
9
client/src/app/main/dashboard/dashboard-layout.scss
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
.dashboard {
|
||||||
|
&__menu {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +1,76 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import {connect} from 'react-redux';
|
||||||
|
|
||||||
|
import Table from 'core-components/table';
|
||||||
|
import Button from 'core-components/button';
|
||||||
|
|
||||||
class DashboardListTicketsPage extends React.Component {
|
class DashboardListTicketsPage extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
tickets: React.PropTypes.arrayOf(React.PropTypes.object)
|
||||||
|
};
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
tickets: []
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="dashboard-ticket-list">
|
||||||
DASHBOARD TICKET LIST
|
<div className="dashboard-ticket-list__header">Tickets</div>
|
||||||
|
<Table headers={this.getTableHeaders()} rows={this.getTableRows()} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTableHeaders() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
key: 'number',
|
||||||
|
value: 'Number',
|
||||||
|
className: 'dashboard-ticket-list__number col-md-1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'title',
|
||||||
|
value: 'Title',
|
||||||
|
className: 'dashboard-ticket-list__title col-md-6'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'department',
|
||||||
|
value: 'Department',
|
||||||
|
className: 'dashboard-ticket-list__department col-md-3'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'date',
|
||||||
|
value: 'Date',
|
||||||
|
className: 'dashboard-ticket-list__date col-md-2'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
getTableRows() {
|
||||||
|
return this.props.tickets.map(this.gerTicketTableObject.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
gerTicketTableObject(ticket) {
|
||||||
|
let titleText = (ticket.unread) ? ticket.title + ' (1)' : ticket.title;
|
||||||
|
|
||||||
|
return {
|
||||||
|
number: '#' + ticket.ticketNumber,
|
||||||
|
title: (
|
||||||
|
<Button className="dashboard-ticket-list__title-link" type="clean" route={{to: '/dashboard/ticket/' + ticket.ticketNumber}}>
|
||||||
|
{titleText}
|
||||||
|
</Button>
|
||||||
|
),
|
||||||
|
department: ticket.department.name,
|
||||||
|
date: ticket.date,
|
||||||
|
highlighted: ticket.unread
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default DashboardListTicketsPage;
|
|
||||||
|
export default connect((store) => {
|
||||||
|
return {
|
||||||
|
tickets: store.session.userTickets
|
||||||
|
};
|
||||||
|
})(DashboardListTicketsPage);
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
@import "../../../../scss/vars";
|
||||||
|
|
||||||
|
.dashboard-ticket-list {
|
||||||
|
|
||||||
|
&__header {
|
||||||
|
text-align: left;
|
||||||
|
font-variant: small-caps;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__number {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__department {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__date {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__title-link:hover,
|
||||||
|
&__title-link:focus {
|
||||||
|
outline: none;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +1,11 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import Menu from 'core-components/menu';
|
import {dispatch} from 'app/store';
|
||||||
|
import SessionActions from 'actions/session-actions';
|
||||||
|
import i18n from 'lib-app/i18n';
|
||||||
|
|
||||||
let dashboardRoutes = [
|
import Menu from 'core-components/menu';
|
||||||
{ path: '/app/dashboard', text: 'Ticket List' },
|
|
||||||
{ path: '/app/dashboard/create-ticket', text: 'Create Ticket' },
|
|
||||||
{ path: '/app/dashboard/articles', text: 'View Articles' },
|
|
||||||
{ path: '/app/dashboard/edit-profile', text: 'Edit Profile' }
|
|
||||||
];
|
|
||||||
|
|
||||||
class DashboardMenu extends React.Component {
|
class DashboardMenu extends React.Component {
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
@ -27,30 +24,62 @@ class DashboardMenu extends React.Component {
|
|||||||
|
|
||||||
getProps() {
|
getProps() {
|
||||||
return {
|
return {
|
||||||
|
header: 'Dashboard',
|
||||||
items: this.getMenuItems(),
|
items: this.getMenuItems(),
|
||||||
selectedIndex: this.getSelectedIndex(),
|
selectedIndex: this.getSelectedIndex(),
|
||||||
onItemClick: this.goToPathByIndex.bind(this)
|
onItemClick: this.onItemClick.bind(this),
|
||||||
|
tabbable: true,
|
||||||
|
type: 'secondary'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getMenuItems() {
|
getMenuItems() {
|
||||||
return dashboardRoutes.map(this.getMenuItem.bind(this));
|
let items = this.getDashboardRoutes().map(this.getMenuItem.bind(this));
|
||||||
|
|
||||||
|
items.push(this.getCloseSessionItem());
|
||||||
|
|
||||||
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
getMenuItem(item) {
|
getMenuItem(item) {
|
||||||
return {
|
return {
|
||||||
content: item.text
|
content: item.text,
|
||||||
|
icon: item.icon
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getCloseSessionItem() {
|
||||||
|
return {
|
||||||
|
content: i18n('CLOSE_SESSION'),
|
||||||
|
icon: 'lock'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getSelectedIndex() {
|
getSelectedIndex() {
|
||||||
let pathname = this.props.location.pathname;
|
let pathname = this.props.location.pathname;
|
||||||
|
|
||||||
return _.findIndex(dashboardRoutes, {path: pathname});
|
return _.findIndex(this.getDashboardRoutes(), {path: pathname});
|
||||||
|
}
|
||||||
|
|
||||||
|
onItemClick(itemIndex) {
|
||||||
|
if (itemIndex < this.getDashboardRoutes().length) {
|
||||||
|
this.goToPathByIndex(itemIndex)
|
||||||
|
} else {
|
||||||
|
dispatch(SessionActions.logout());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
goToPathByIndex(itemIndex) {
|
goToPathByIndex(itemIndex) {
|
||||||
this.context.router.push(dashboardRoutes[itemIndex].path);
|
this.context.router.push(this.getDashboardRoutes()[itemIndex].path);
|
||||||
|
}
|
||||||
|
|
||||||
|
getDashboardRoutes() {
|
||||||
|
return [
|
||||||
|
{ path: '/dashboard', text: i18n('TICKET_LIST'), icon: 'file-text-o' },
|
||||||
|
{ path: '/dashboard/create-ticket', text: i18n('CREATE_TICKET'), icon: 'plus' },
|
||||||
|
{ path: '/dashboard/articles', text: i18n('VIEW_ARTICLES'), icon: 'book' },
|
||||||
|
{ path: '/dashboard/edit-profile', text: i18n('EDIT_PROFILE'), icon: 'pencil' }
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,16 +34,16 @@ class MainLayoutHeader extends React.Component {
|
|||||||
|
|
||||||
if (this.props.session.logged) {
|
if (this.props.session.logged) {
|
||||||
result = (
|
result = (
|
||||||
<div className="main-layout-header--login-links">
|
<div className="main-layout-header__login-links">
|
||||||
Welcome, John
|
{i18n('WELCOME')},
|
||||||
<Button type="clean" onClick={this.logout.bind(this)}>(Close Session)</Button>
|
<span className="main-layout-header__user-name"> {this.props.session.userName}</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
result = (
|
result = (
|
||||||
<div className="main-layout-header--login-links">
|
<div className="main-layout-header__login-links">
|
||||||
<Button type="clean" route={{to:'/app'}}>{i18n('LOG_IN')}</Button>
|
<Button type="clean" route={{to:'/'}}>{i18n('LOG_IN')}</Button>
|
||||||
<Button type="clean" route={{to:'/app/signup'}}>Sign up</Button>
|
<Button type="clean" route={{to:'/signup'}}>Sign up</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@ class MainLayoutHeader extends React.Component {
|
|||||||
|
|
||||||
getLanguageSelectorProps() {
|
getLanguageSelectorProps() {
|
||||||
return {
|
return {
|
||||||
className: 'main-layout-header--languages',
|
className: 'main-layout-header__languages',
|
||||||
items: this.getLanguageList(),
|
items: this.getLanguageList(),
|
||||||
selectedIndex: Object.values(codeLanguages).indexOf(this.props.config.language),
|
selectedIndex: Object.values(codeLanguages).indexOf(this.props.config.language),
|
||||||
onChange: this.changeLanguage.bind(this)
|
onChange: this.changeLanguage.bind(this)
|
||||||
@ -74,10 +74,6 @@ class MainLayoutHeader extends React.Component {
|
|||||||
|
|
||||||
this.props.dispatch(ConfigActions.changeLanguage(codeLanguages[language]));
|
this.props.dispatch(ConfigActions.changeLanguage(codeLanguages[language]));
|
||||||
}
|
}
|
||||||
|
|
||||||
logout() {
|
|
||||||
this.props.dispatch(SessionActions.logout());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect((store) => {
|
export default connect((store) => {
|
||||||
|
@ -6,7 +6,11 @@
|
|||||||
height: 32px;
|
height: 32px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
&--login-links {
|
&__user-name {
|
||||||
|
color: $primary-red;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__login-links {
|
||||||
border-top-left-radius: 4px;
|
border-top-left-radius: 4px;
|
||||||
color: white;
|
color: white;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@ -14,7 +18,7 @@
|
|||||||
padding: 5px 20px 0 10px;
|
padding: 5px 20px 0 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&--languages {
|
&__languages {
|
||||||
float: right;
|
float: right;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
|
@ -74,7 +74,7 @@ class MainRecoverPasswordPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onPasswordRecovered() {
|
onPasswordRecovered() {
|
||||||
setTimeout(() => {this.props.history.push('/app')}, 2000);
|
setTimeout(() => {this.props.history.push('/')}, 2000);
|
||||||
this.setState({
|
this.setState({
|
||||||
recoverStatus: 'valid',
|
recoverStatus: 'valid',
|
||||||
loading: false
|
loading: false
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import keyCode from 'keycode';
|
||||||
|
|
||||||
import callback from 'lib-core/callback';
|
import callback from 'lib-core/callback';
|
||||||
import getIcon from 'lib-core/get-icon';
|
import getIcon from 'lib-core/get-icon';
|
||||||
@ -87,7 +88,7 @@ class CheckBox extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleIconKeyDown(event) {
|
handleIconKeyDown(event) {
|
||||||
if (event.keyCode == 32) {
|
if (event.keyCode === keyCode('SPACE')) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
callback(this.handleChange.bind(this), this.props.onChange)({
|
callback(this.handleChange.bind(this), this.props.onChange)({
|
||||||
|
@ -1,33 +1,50 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import keyCode from 'keycode';
|
||||||
|
|
||||||
import Icon from 'core-components/icon';
|
import Icon from 'core-components/icon';
|
||||||
|
|
||||||
class Menu extends React.Component {
|
class Menu extends React.Component {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
header: React.PropTypes.string,
|
||||||
type: React.PropTypes.oneOf(['primary', 'secondary']),
|
type: React.PropTypes.oneOf(['primary', 'secondary']),
|
||||||
items: React.PropTypes.arrayOf(React.PropTypes.shape({
|
items: React.PropTypes.arrayOf(React.PropTypes.shape({
|
||||||
content: React.PropTypes.string.isRequired,
|
content: React.PropTypes.string.isRequired,
|
||||||
icon: React.PropTypes.string
|
icon: React.PropTypes.string
|
||||||
})).isRequired,
|
})).isRequired,
|
||||||
selectedIndex: React.PropTypes.number
|
selectedIndex: React.PropTypes.number,
|
||||||
|
tabbable: React.PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
selectedIndex: 0
|
selectedIndex: 0,
|
||||||
|
tabbable: false
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<ul {...this.getProps()}>
|
<div className={this.getClass()}>
|
||||||
{this.props.items.map(this.renderListItem.bind(this))}
|
{this.renderHeader()}
|
||||||
</ul>
|
<ul {...this.getProps()}>
|
||||||
|
{this.props.items.map(this.renderListItem.bind(this))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderHeader() {
|
||||||
|
let header = null;
|
||||||
|
|
||||||
|
if (this.props.header) {
|
||||||
|
header = <div className="menu__header">{this.props.header}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
renderListItem(item, index) {
|
renderListItem(item, index) {
|
||||||
let iconNode = null;
|
let iconNode = null;
|
||||||
|
|
||||||
@ -45,11 +62,13 @@ class Menu extends React.Component {
|
|||||||
getProps() {
|
getProps() {
|
||||||
var props = _.clone(this.props);
|
var props = _.clone(this.props);
|
||||||
|
|
||||||
props.className = this.getClass();
|
props.className = 'menu__list';
|
||||||
|
|
||||||
|
delete props.header;
|
||||||
delete props.items;
|
delete props.items;
|
||||||
delete props.onItemClick;
|
delete props.onItemClick;
|
||||||
delete props.selectedIndex;
|
delete props.selectedIndex;
|
||||||
|
delete props.tabbable;
|
||||||
delete props.type;
|
delete props.type;
|
||||||
|
|
||||||
return props;
|
return props;
|
||||||
@ -69,7 +88,9 @@ class Menu extends React.Component {
|
|||||||
getItemProps(index) {
|
getItemProps(index) {
|
||||||
return {
|
return {
|
||||||
className: this.getItemClass(index),
|
className: this.getItemClass(index),
|
||||||
onClick: this.handleItemClick.bind(this, index),
|
onClick: this.onItemClick.bind(this, index),
|
||||||
|
tabIndex: (this.props.tabbable) ? '0' : null,
|
||||||
|
onKeyDown: this.onKeyDown.bind(this, index),
|
||||||
key: index
|
key: index
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -83,7 +104,16 @@ class Menu extends React.Component {
|
|||||||
return classNames(classes);
|
return classNames(classes);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleItemClick(index) {
|
onKeyDown(index, event) {
|
||||||
|
let enterKey = keyCode('ENTER');
|
||||||
|
let spaceKey = keyCode('SPACE');
|
||||||
|
|
||||||
|
if(event.keyCode === enterKey || event.keyCode === spaceKey) {
|
||||||
|
this.onItemClick(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onItemClick(index) {
|
||||||
if (this.props.onItemClick) {
|
if (this.props.onItemClick) {
|
||||||
this.props.onItemClick(index);
|
this.props.onItemClick(index);
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
@import "../scss/vars";
|
@import "../scss/vars";
|
||||||
|
|
||||||
.menu {
|
.menu {
|
||||||
background-color: white;
|
|
||||||
color: $dark-grey;
|
&__list {
|
||||||
margin: 0;
|
background-color: white;
|
||||||
padding: 0;
|
color: $dark-grey;
|
||||||
list-style-type: none;
|
margin: 0;
|
||||||
cursor: pointer;
|
padding: 0;
|
||||||
|
list-style-type: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
&__list-item {
|
&__list-item {
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
@ -28,5 +31,14 @@
|
|||||||
.menu__list-item:hover {
|
.menu__list-item:hover {
|
||||||
background-color: $secondary-blue;
|
background-color: $secondary-blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.menu__header {
|
||||||
|
padding: 8px;
|
||||||
|
background-color: $primary-blue;
|
||||||
|
color: white;
|
||||||
|
font-size: 16px;
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
76
client/src/core-components/table.js
Normal file
76
client/src/core-components/table.js
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
class Table extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
headers: React.PropTypes.arrayOf(React.PropTypes.shape({
|
||||||
|
key: React.PropTypes.string,
|
||||||
|
value: React.PropTypes.string,
|
||||||
|
className: React.PropTypes.string
|
||||||
|
})),
|
||||||
|
rows: React.PropTypes.arrayOf(React.PropTypes.object),
|
||||||
|
type: React.PropTypes.oneOf(['default'])
|
||||||
|
};
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
type: 'default'
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<table className="table table-responsive">
|
||||||
|
<thead>
|
||||||
|
<tr className="table__header">
|
||||||
|
{this.props.headers.map(this.renderHeaderColumn.bind(this))}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{this.props.rows.map(this.renderRow.bind(this))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderHeaderColumn(header) {
|
||||||
|
let classes = {
|
||||||
|
'table__header-column': true,
|
||||||
|
[header.className]: (header.className)
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<th className={classNames(classes)} key={header.key}>{header.value}</th>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderRow(row, index) {
|
||||||
|
let headersKeys = this.props.headers.map(header => header.key);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr className={this.getRowClass(row)} key={index}>
|
||||||
|
{headersKeys.map(this.renderCell.bind(this, row))}
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderCell(row, key, index) {
|
||||||
|
let classes = {
|
||||||
|
'table__cell': true,
|
||||||
|
[this.props.headers[index].className]: (this.props.headers[index].className)
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<td className={classNames(classes)} key={key}>{row[key]}</td>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getRowClass(row) {
|
||||||
|
let classes = {
|
||||||
|
'table__row': true,
|
||||||
|
'table__row-highlighted': row.highlighted
|
||||||
|
};
|
||||||
|
|
||||||
|
return classNames(classes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Table;
|
46
client/src/core-components/table.scss
Normal file
46
client/src/core-components/table.scss
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
@import "../scss/vars";
|
||||||
|
|
||||||
|
.table {
|
||||||
|
|
||||||
|
&__header {
|
||||||
|
background-color: $primary-blue;
|
||||||
|
color: white;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__header-column {
|
||||||
|
font-weight: normal;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-top-right-radius: 4px
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__row {
|
||||||
|
border: 0;
|
||||||
|
color: #B8B8B8;
|
||||||
|
|
||||||
|
&:nth-child(even) {
|
||||||
|
background-color: #F9F9F9;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(odd) {
|
||||||
|
background-color: #F1F1F1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-highlighted {
|
||||||
|
color: $secondary-blue;
|
||||||
|
font-weight: bold;
|
||||||
|
background-color: white !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__cell00 {
|
||||||
|
border: 0;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
}
|
@ -103,5 +103,107 @@ module.exports = [
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/user/get',
|
||||||
|
time: 100,
|
||||||
|
response: function () {
|
||||||
|
return {
|
||||||
|
status: 'success',
|
||||||
|
data: {
|
||||||
|
name: 'Haskell Curry',
|
||||||
|
email: 'haskell@lambda.com',
|
||||||
|
tickets: [
|
||||||
|
{
|
||||||
|
ticketNumber: '445441',
|
||||||
|
title: 'Problem with installation',
|
||||||
|
content: 'I had a problem with the installation of the php server',
|
||||||
|
department: {
|
||||||
|
id: 2,
|
||||||
|
name: 'Environment Setup'
|
||||||
|
},
|
||||||
|
date: '15 Apr 2016',
|
||||||
|
file: 'http://www.opensupports.com/some_file.zip',
|
||||||
|
language: 'en',
|
||||||
|
unread: true,
|
||||||
|
closed: false,
|
||||||
|
author: {
|
||||||
|
id: 12,
|
||||||
|
name: 'Haskell Curry',
|
||||||
|
email: 'haskell@lambda.com'
|
||||||
|
},
|
||||||
|
owner: {
|
||||||
|
id: 15,
|
||||||
|
name: 'Steve Jobs',
|
||||||
|
email: 'steve@jobs.com'
|
||||||
|
},
|
||||||
|
comments: [
|
||||||
|
{
|
||||||
|
content: 'Do you have apache installed? It generally happens if you dont have apache.',
|
||||||
|
author: {
|
||||||
|
id: 15,
|
||||||
|
name: 'Steve Jobs',
|
||||||
|
email: 'jobs@steve.com',
|
||||||
|
staff: true
|
||||||
|
},
|
||||||
|
date: '12 Dec 2016',
|
||||||
|
file: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
content: 'I have already installed apache, but the problem persists',
|
||||||
|
author: {
|
||||||
|
id: 12,
|
||||||
|
name: 'Haskell Curry',
|
||||||
|
steve: 'haskell@lambda.com',
|
||||||
|
staff: false
|
||||||
|
},
|
||||||
|
date: '12 Dec 2016',
|
||||||
|
file: ''
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ticketNumber: '878552',
|
||||||
|
title: 'Lorem ipsum door',
|
||||||
|
content: 'I had a problem with the installation of the php server',
|
||||||
|
department: {
|
||||||
|
id: 2,
|
||||||
|
name: 'Environment Setup'
|
||||||
|
},
|
||||||
|
date: '15 Apr 2016',
|
||||||
|
file: 'http://www.opensupports.com/some_file.zip',
|
||||||
|
language: 'en',
|
||||||
|
unread: false,
|
||||||
|
closed: false,
|
||||||
|
author: {
|
||||||
|
name: 'Haskell Curry',
|
||||||
|
email: 'haskell@lambda.com'
|
||||||
|
},
|
||||||
|
owner: {
|
||||||
|
name: 'Steve Jobs'
|
||||||
|
},
|
||||||
|
comments: [
|
||||||
|
{
|
||||||
|
content: 'Do you have apache installed? It generally happens if you dont have apache.',
|
||||||
|
author: {
|
||||||
|
name: 'Steve Jobs',
|
||||||
|
email: 'jobs@steve.com',
|
||||||
|
staff: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
content: 'I have already installed apache, but the problem persists',
|
||||||
|
author: {
|
||||||
|
name: 'Haskell Curry',
|
||||||
|
steve: 'haskell@lambda.com',
|
||||||
|
staff: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
@ -1,4 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
|
'WELCOME': 'Welcome',
|
||||||
'SUBMIT': 'Submit',
|
'SUBMIT': 'Submit',
|
||||||
'LOG_IN': 'Log in',
|
'LOG_IN': 'Log in',
|
||||||
'SIGN_UP': 'Sign up',
|
'SIGN_UP': 'Sign up',
|
||||||
@ -8,6 +9,11 @@ export default {
|
|||||||
'NEW_PASSWORD': 'New password',
|
'NEW_PASSWORD': 'New password',
|
||||||
'REPEAT_NEW_PASSWORD': 'Repeat new password',
|
'REPEAT_NEW_PASSWORD': 'Repeat new password',
|
||||||
'BACK_LOGIN_FORM': 'Back to login form',
|
'BACK_LOGIN_FORM': 'Back to login form',
|
||||||
|
'TICKET_LIST': 'Ticket List',
|
||||||
|
'CREATE_TICKET': 'Create Ticket',
|
||||||
|
'VIEW_ARTICLES': 'View Articles',
|
||||||
|
'EDIT_PROFILE': 'Edit Profile',
|
||||||
|
'CLOSE_SESSION': 'Close session',
|
||||||
|
|
||||||
//ERRORS
|
//ERRORS
|
||||||
'EMAIL_NOT_EXIST': 'Email does not exist',
|
'EMAIL_NOT_EXIST': 'Email does not exist',
|
||||||
|
@ -4,8 +4,8 @@ import { Provider } from 'react-redux';
|
|||||||
|
|
||||||
import SessionActions from 'actions/session-actions';
|
import SessionActions from 'actions/session-actions';
|
||||||
import ConfigActions from 'actions/config-actions';
|
import ConfigActions from 'actions/config-actions';
|
||||||
import routes from './Routes';
|
import routes from 'app/Routes';
|
||||||
import store from './store';
|
import store from 'app/store';
|
||||||
|
|
||||||
if ( process.env.NODE_ENV !== 'production' ) {
|
if ( process.env.NODE_ENV !== 'production' ) {
|
||||||
// Enable React devtools
|
// Enable React devtools
|
@ -1,5 +1,8 @@
|
|||||||
export default {
|
export default {
|
||||||
call: stub().returns(new Promise(function (resolve) {
|
call: stub().returns(new Promise(function (resolve) {
|
||||||
resolve();
|
resolve({
|
||||||
|
status: 'success',
|
||||||
|
data: {}
|
||||||
|
});
|
||||||
}))
|
}))
|
||||||
};
|
};
|
@ -29,6 +29,17 @@ class SessionStore {
|
|||||||
closeSession() {
|
closeSession() {
|
||||||
this.removeItem('userId');
|
this.removeItem('userId');
|
||||||
this.removeItem('token');
|
this.removeItem('token');
|
||||||
|
|
||||||
|
this.clearRememberData();
|
||||||
|
this.clearUserData();
|
||||||
|
}
|
||||||
|
|
||||||
|
storeUserData(data) {
|
||||||
|
this.setItem('userData', JSON.stringify(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
getUserData() {
|
||||||
|
return JSON.parse(this.getItem('userData'));
|
||||||
}
|
}
|
||||||
|
|
||||||
storeRememberData({token, userId, expiration}) {
|
storeRememberData({token, userId, expiration}) {
|
||||||
@ -73,6 +84,10 @@ class SessionStore {
|
|||||||
this.removeItem('rememberData-expiration');
|
this.removeItem('rememberData-expiration');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearUserData() {
|
||||||
|
this.removeItem('userData');
|
||||||
|
}
|
||||||
|
|
||||||
getItem(key) {
|
getItem(key) {
|
||||||
return this.storage.getItem(key);
|
return this.storage.getItem(key);
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,9 @@ class SessionReducer extends Reducer {
|
|||||||
'LOGIN_FULFILLED': this.onLoginCompleted.bind(this),
|
'LOGIN_FULFILLED': this.onLoginCompleted.bind(this),
|
||||||
'LOGIN_REJECTED': this.onLoginFailed,
|
'LOGIN_REJECTED': this.onLoginFailed,
|
||||||
'LOGOUT_FULFILLED': this.onLogout,
|
'LOGOUT_FULFILLED': this.onLogout,
|
||||||
|
'USER_DATA_FULFILLED': this.onUserDataRetrieved,
|
||||||
'CHECK_SESSION_REJECTED': (state) => { return _.extend({}, state, {initDone: true})},
|
'CHECK_SESSION_REJECTED': (state) => { return _.extend({}, state, {initDone: true})},
|
||||||
'SESSION_CHECKED': (state) => { return _.extend({}, state, {initDone: true, logged: true})},
|
'SESSION_CHECKED': this.onSessionChecked,
|
||||||
'LOGIN_AUTO_FULFILLED': this.onAutoLogin.bind(this),
|
'LOGIN_AUTO_FULFILLED': this.onAutoLogin.bind(this),
|
||||||
'LOGIN_AUTO_REJECTED': this.onAutoLoginFail
|
'LOGIN_AUTO_REJECTED': this.onAutoLoginFail
|
||||||
};
|
};
|
||||||
@ -54,7 +55,6 @@ class SessionReducer extends Reducer {
|
|||||||
|
|
||||||
onLogout(state) {
|
onLogout(state) {
|
||||||
sessionStore.closeSession();
|
sessionStore.closeSession();
|
||||||
sessionStore.clearRememberData();
|
|
||||||
|
|
||||||
return _.extend({}, state, {
|
return _.extend({}, state, {
|
||||||
initDone: true,
|
initDone: true,
|
||||||
@ -77,7 +77,6 @@ class SessionReducer extends Reducer {
|
|||||||
|
|
||||||
onAutoLoginFail(state) {
|
onAutoLoginFail(state) {
|
||||||
sessionStore.closeSession();
|
sessionStore.closeSession();
|
||||||
sessionStore.clearRememberData();
|
|
||||||
|
|
||||||
return _.extend({}, state, {
|
return _.extend({}, state, {
|
||||||
initDone: true
|
initDone: true
|
||||||
@ -95,6 +94,30 @@ class SessionReducer extends Reducer {
|
|||||||
|
|
||||||
sessionStore.createSession(resultData.userId, resultData.token);
|
sessionStore.createSession(resultData.userId, resultData.token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onUserDataRetrieved(state, payload) {
|
||||||
|
let userData = payload.data;
|
||||||
|
|
||||||
|
sessionStore.storeUserData(payload.data);
|
||||||
|
|
||||||
|
return _.extend({}, state, {
|
||||||
|
userName: userData.name,
|
||||||
|
userEmail: userData.email,
|
||||||
|
userTickets: userData.tickets
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onSessionChecked(state) {
|
||||||
|
let userData = sessionStore.getUserData();
|
||||||
|
|
||||||
|
return _.extend({}, state, {
|
||||||
|
initDone: true,
|
||||||
|
logged: true,
|
||||||
|
userName: userData.name,
|
||||||
|
userEmail: userData.email,
|
||||||
|
userTickets: userData.tickets
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SessionReducer.getInstance();
|
export default SessionReducer.getInstance();
|
@ -1,4 +1,53 @@
|
|||||||
|
/*!
|
||||||
|
* Bootstrap v3.3.7 (http://getbootstrap.com)
|
||||||
|
* Copyright 2011-2016 Twitter, Inc.
|
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=95955b93b458c15deb17e935e7374a2f)
|
||||||
|
* Config saved to config.json and https://gist.github.com/95955b93b458c15deb17e935e7374a2f
|
||||||
|
*/
|
||||||
|
/*!
|
||||||
|
* Bootstrap v3.3.7 (http://getbootstrap.com)
|
||||||
|
* Copyright 2011-2016 Twitter, Inc.
|
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
|
*/
|
||||||
|
/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
|
||||||
|
html {
|
||||||
|
font-family: sans-serif;
|
||||||
|
-ms-text-size-adjust: 100%;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
article,
|
||||||
|
aside,
|
||||||
|
details,
|
||||||
|
figcaption,
|
||||||
|
figure,
|
||||||
|
footer,
|
||||||
|
header,
|
||||||
|
hgroup,
|
||||||
|
main,
|
||||||
|
menu,
|
||||||
|
nav,
|
||||||
|
section,
|
||||||
|
summary {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
audio,
|
||||||
|
canvas,
|
||||||
|
progress,
|
||||||
|
video {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
audio:not([controls]) {
|
||||||
|
display: none;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
[hidden],
|
[hidden],
|
||||||
template {
|
template {
|
||||||
display: none;
|
display: none;
|
||||||
@ -148,6 +197,78 @@ td,
|
|||||||
th {
|
th {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
|
||||||
|
@media print {
|
||||||
|
*,
|
||||||
|
*:before,
|
||||||
|
*:after {
|
||||||
|
background: transparent !important;
|
||||||
|
color: #000 !important;
|
||||||
|
-webkit-box-shadow: none !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
text-shadow: none !important;
|
||||||
|
}
|
||||||
|
a,
|
||||||
|
a:visited {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
a[href]:after {
|
||||||
|
content: " (" attr(href) ")";
|
||||||
|
}
|
||||||
|
abbr[title]:after {
|
||||||
|
content: " (" attr(title) ")";
|
||||||
|
}
|
||||||
|
a[href^="#"]:after,
|
||||||
|
a[href^="javascript:"]:after {
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
pre,
|
||||||
|
blockquote {
|
||||||
|
border: 1px solid #999;
|
||||||
|
page-break-inside: avoid;
|
||||||
|
}
|
||||||
|
thead {
|
||||||
|
display: table-header-group;
|
||||||
|
}
|
||||||
|
tr,
|
||||||
|
img {
|
||||||
|
page-break-inside: avoid;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
max-width: 100% !important;
|
||||||
|
}
|
||||||
|
p,
|
||||||
|
h2,
|
||||||
|
h3 {
|
||||||
|
orphans: 3;
|
||||||
|
widows: 3;
|
||||||
|
}
|
||||||
|
h2,
|
||||||
|
h3 {
|
||||||
|
page-break-after: avoid;
|
||||||
|
}
|
||||||
|
.navbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.btn > .caret,
|
||||||
|
.dropup > .btn > .caret {
|
||||||
|
border-top-color: #000 !important;
|
||||||
|
}
|
||||||
|
.label {
|
||||||
|
border: 1px solid #000;
|
||||||
|
}
|
||||||
|
.table {
|
||||||
|
border-collapse: collapse !important;
|
||||||
|
}
|
||||||
|
.table td,
|
||||||
|
.table th {
|
||||||
|
background-color: #fff !important;
|
||||||
|
}
|
||||||
|
.table-bordered th,
|
||||||
|
.table-bordered td {
|
||||||
|
border: 1px solid #ddd !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
* {
|
* {
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
@ -188,7 +309,6 @@ a:focus {
|
|||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
a:focus {
|
a:focus {
|
||||||
outline: thin dotted;
|
|
||||||
outline: 5px auto -webkit-focus-ring-color;
|
outline: 5px auto -webkit-focus-ring-color;
|
||||||
outline-offset: -2px;
|
outline-offset: -2px;
|
||||||
}
|
}
|
||||||
@ -250,6 +370,416 @@ hr {
|
|||||||
[role="button"] {
|
[role="button"] {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6,
|
||||||
|
.h1,
|
||||||
|
.h2,
|
||||||
|
.h3,
|
||||||
|
.h4,
|
||||||
|
.h5,
|
||||||
|
.h6 {
|
||||||
|
font-family: inherit;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.1;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
h1 small,
|
||||||
|
h2 small,
|
||||||
|
h3 small,
|
||||||
|
h4 small,
|
||||||
|
h5 small,
|
||||||
|
h6 small,
|
||||||
|
.h1 small,
|
||||||
|
.h2 small,
|
||||||
|
.h3 small,
|
||||||
|
.h4 small,
|
||||||
|
.h5 small,
|
||||||
|
.h6 small,
|
||||||
|
h1 .small,
|
||||||
|
h2 .small,
|
||||||
|
h3 .small,
|
||||||
|
h4 .small,
|
||||||
|
h5 .small,
|
||||||
|
h6 .small,
|
||||||
|
.h1 .small,
|
||||||
|
.h2 .small,
|
||||||
|
.h3 .small,
|
||||||
|
.h4 .small,
|
||||||
|
.h5 .small,
|
||||||
|
.h6 .small {
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 1;
|
||||||
|
color: #777777;
|
||||||
|
}
|
||||||
|
h1,
|
||||||
|
.h1,
|
||||||
|
h2,
|
||||||
|
.h2,
|
||||||
|
h3,
|
||||||
|
.h3 {
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
h1 small,
|
||||||
|
.h1 small,
|
||||||
|
h2 small,
|
||||||
|
.h2 small,
|
||||||
|
h3 small,
|
||||||
|
.h3 small,
|
||||||
|
h1 .small,
|
||||||
|
.h1 .small,
|
||||||
|
h2 .small,
|
||||||
|
.h2 .small,
|
||||||
|
h3 .small,
|
||||||
|
.h3 .small {
|
||||||
|
font-size: 65%;
|
||||||
|
}
|
||||||
|
h4,
|
||||||
|
.h4,
|
||||||
|
h5,
|
||||||
|
.h5,
|
||||||
|
h6,
|
||||||
|
.h6 {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
h4 small,
|
||||||
|
.h4 small,
|
||||||
|
h5 small,
|
||||||
|
.h5 small,
|
||||||
|
h6 small,
|
||||||
|
.h6 small,
|
||||||
|
h4 .small,
|
||||||
|
.h4 .small,
|
||||||
|
h5 .small,
|
||||||
|
.h5 .small,
|
||||||
|
h6 .small,
|
||||||
|
.h6 .small {
|
||||||
|
font-size: 75%;
|
||||||
|
}
|
||||||
|
h1,
|
||||||
|
.h1 {
|
||||||
|
font-size: 36px;
|
||||||
|
}
|
||||||
|
h2,
|
||||||
|
.h2 {
|
||||||
|
font-size: 30px;
|
||||||
|
}
|
||||||
|
h3,
|
||||||
|
.h3 {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
h4,
|
||||||
|
.h4 {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
h5,
|
||||||
|
.h5 {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
h6,
|
||||||
|
.h6 {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
margin: 0 0 10px;
|
||||||
|
}
|
||||||
|
.lead {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 300;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.lead {
|
||||||
|
font-size: 21px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
small,
|
||||||
|
.small {
|
||||||
|
font-size: 85%;
|
||||||
|
}
|
||||||
|
mark,
|
||||||
|
.mark {
|
||||||
|
background-color: #fcf8e3;
|
||||||
|
padding: .2em;
|
||||||
|
}
|
||||||
|
.text-left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.text-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.text-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.text-justify {
|
||||||
|
text-align: justify;
|
||||||
|
}
|
||||||
|
.text-nowrap {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.text-lowercase {
|
||||||
|
text-transform: lowercase;
|
||||||
|
}
|
||||||
|
.text-uppercase {
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
.text-capitalize {
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
.text-muted {
|
||||||
|
color: #777777;
|
||||||
|
}
|
||||||
|
.text-primary {
|
||||||
|
color: #337ab7;
|
||||||
|
}
|
||||||
|
a.text-primary:hover,
|
||||||
|
a.text-primary:focus {
|
||||||
|
color: #286090;
|
||||||
|
}
|
||||||
|
.text-success {
|
||||||
|
color: #3c763d;
|
||||||
|
}
|
||||||
|
a.text-success:hover,
|
||||||
|
a.text-success:focus {
|
||||||
|
color: #2b542c;
|
||||||
|
}
|
||||||
|
.text-info {
|
||||||
|
color: #31708f;
|
||||||
|
}
|
||||||
|
a.text-info:hover,
|
||||||
|
a.text-info:focus {
|
||||||
|
color: #245269;
|
||||||
|
}
|
||||||
|
.text-warning {
|
||||||
|
color: #8a6d3b;
|
||||||
|
}
|
||||||
|
a.text-warning:hover,
|
||||||
|
a.text-warning:focus {
|
||||||
|
color: #66512c;
|
||||||
|
}
|
||||||
|
.text-danger {
|
||||||
|
color: #a94442;
|
||||||
|
}
|
||||||
|
a.text-danger:hover,
|
||||||
|
a.text-danger:focus {
|
||||||
|
color: #843534;
|
||||||
|
}
|
||||||
|
.bg-primary {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #337ab7;
|
||||||
|
}
|
||||||
|
a.bg-primary:hover,
|
||||||
|
a.bg-primary:focus {
|
||||||
|
background-color: #286090;
|
||||||
|
}
|
||||||
|
.bg-success {
|
||||||
|
background-color: #dff0d8;
|
||||||
|
}
|
||||||
|
a.bg-success:hover,
|
||||||
|
a.bg-success:focus {
|
||||||
|
background-color: #c1e2b3;
|
||||||
|
}
|
||||||
|
.bg-info {
|
||||||
|
background-color: #d9edf7;
|
||||||
|
}
|
||||||
|
a.bg-info:hover,
|
||||||
|
a.bg-info:focus {
|
||||||
|
background-color: #afd9ee;
|
||||||
|
}
|
||||||
|
.bg-warning {
|
||||||
|
background-color: #fcf8e3;
|
||||||
|
}
|
||||||
|
a.bg-warning:hover,
|
||||||
|
a.bg-warning:focus {
|
||||||
|
background-color: #f7ecb5;
|
||||||
|
}
|
||||||
|
.bg-danger {
|
||||||
|
background-color: #f2dede;
|
||||||
|
}
|
||||||
|
a.bg-danger:hover,
|
||||||
|
a.bg-danger:focus {
|
||||||
|
background-color: #e4b9b9;
|
||||||
|
}
|
||||||
|
.page-header {
|
||||||
|
padding-bottom: 9px;
|
||||||
|
margin: 40px 0 20px;
|
||||||
|
border-bottom: 1px solid #eeeeee;
|
||||||
|
}
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
ul ul,
|
||||||
|
ol ul,
|
||||||
|
ul ol,
|
||||||
|
ol ol {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.list-unstyled {
|
||||||
|
padding-left: 0;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
.list-inline {
|
||||||
|
padding-left: 0;
|
||||||
|
list-style: none;
|
||||||
|
margin-left: -5px;
|
||||||
|
}
|
||||||
|
.list-inline > li {
|
||||||
|
display: inline-block;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
dl {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
dt,
|
||||||
|
dd {
|
||||||
|
line-height: 1.42857143;
|
||||||
|
}
|
||||||
|
dt {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
dd {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.dl-horizontal dt {
|
||||||
|
float: left;
|
||||||
|
width: 160px;
|
||||||
|
clear: left;
|
||||||
|
text-align: right;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.dl-horizontal dd {
|
||||||
|
margin-left: 180px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
abbr[title],
|
||||||
|
abbr[data-original-title] {
|
||||||
|
cursor: help;
|
||||||
|
border-bottom: 1px dotted #777777;
|
||||||
|
}
|
||||||
|
.initialism {
|
||||||
|
font-size: 90%;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
blockquote {
|
||||||
|
padding: 10px 20px;
|
||||||
|
margin: 0 0 20px;
|
||||||
|
font-size: 17.5px;
|
||||||
|
border-left: 5px solid #eeeeee;
|
||||||
|
}
|
||||||
|
blockquote p:last-child,
|
||||||
|
blockquote ul:last-child,
|
||||||
|
blockquote ol:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
blockquote footer,
|
||||||
|
blockquote small,
|
||||||
|
blockquote .small {
|
||||||
|
display: block;
|
||||||
|
font-size: 80%;
|
||||||
|
line-height: 1.42857143;
|
||||||
|
color: #777777;
|
||||||
|
}
|
||||||
|
blockquote footer:before,
|
||||||
|
blockquote small:before,
|
||||||
|
blockquote .small:before {
|
||||||
|
content: '\2014 \00A0';
|
||||||
|
}
|
||||||
|
.blockquote-reverse,
|
||||||
|
blockquote.pull-right {
|
||||||
|
padding-right: 15px;
|
||||||
|
padding-left: 0;
|
||||||
|
border-right: 5px solid #eeeeee;
|
||||||
|
border-left: 0;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.blockquote-reverse footer:before,
|
||||||
|
blockquote.pull-right footer:before,
|
||||||
|
.blockquote-reverse small:before,
|
||||||
|
blockquote.pull-right small:before,
|
||||||
|
.blockquote-reverse .small:before,
|
||||||
|
blockquote.pull-right .small:before {
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
.blockquote-reverse footer:after,
|
||||||
|
blockquote.pull-right footer:after,
|
||||||
|
.blockquote-reverse small:after,
|
||||||
|
blockquote.pull-right small:after,
|
||||||
|
.blockquote-reverse .small:after,
|
||||||
|
blockquote.pull-right .small:after {
|
||||||
|
content: '\00A0 \2014';
|
||||||
|
}
|
||||||
|
address {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-style: normal;
|
||||||
|
line-height: 1.42857143;
|
||||||
|
}
|
||||||
|
code,
|
||||||
|
kbd,
|
||||||
|
pre,
|
||||||
|
samp {
|
||||||
|
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
|
||||||
|
}
|
||||||
|
code {
|
||||||
|
padding: 2px 4px;
|
||||||
|
font-size: 90%;
|
||||||
|
color: #c7254e;
|
||||||
|
background-color: #f9f2f4;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
kbd {
|
||||||
|
padding: 2px 4px;
|
||||||
|
font-size: 90%;
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #333333;
|
||||||
|
border-radius: 3px;
|
||||||
|
-webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||||
|
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
kbd kbd {
|
||||||
|
padding: 0;
|
||||||
|
font-size: 100%;
|
||||||
|
font-weight: bold;
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
display: block;
|
||||||
|
padding: 9.5px;
|
||||||
|
margin: 0 0 10px;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.42857143;
|
||||||
|
word-break: break-all;
|
||||||
|
word-wrap: break-word;
|
||||||
|
color: #333333;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border: 1px solid #cccccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
pre code {
|
||||||
|
padding: 0;
|
||||||
|
font-size: inherit;
|
||||||
|
color: inherit;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
background-color: transparent;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
.pre-scrollable {
|
||||||
|
max-height: 340px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
.container {
|
.container {
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
@ -917,8 +1447,250 @@ hr {
|
|||||||
margin-left: 0%;
|
margin-left: 0%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
table {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
caption {
|
||||||
|
padding-top: 8px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
color: #777777;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.table {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.table > thead > tr > th,
|
||||||
|
.table > tbody > tr > th,
|
||||||
|
.table > tfoot > tr > th,
|
||||||
|
.table > thead > tr > td,
|
||||||
|
.table > tbody > tr > td,
|
||||||
|
.table > tfoot > tr > td {
|
||||||
|
padding: 8px;
|
||||||
|
line-height: 1.42857143;
|
||||||
|
vertical-align: top;
|
||||||
|
//border-top: 1px solid #dddddd;
|
||||||
|
}
|
||||||
|
.table > thead > tr > th {
|
||||||
|
vertical-align: bottom;
|
||||||
|
//border-bottom: 2px solid #dddddd;
|
||||||
|
}
|
||||||
|
.table > caption + thead > tr:first-child > th,
|
||||||
|
.table > colgroup + thead > tr:first-child > th,
|
||||||
|
.table > thead:first-child > tr:first-child > th,
|
||||||
|
.table > caption + thead > tr:first-child > td,
|
||||||
|
.table > colgroup + thead > tr:first-child > td,
|
||||||
|
.table > thead:first-child > tr:first-child > td {
|
||||||
|
border-top: 0;
|
||||||
|
}
|
||||||
|
.table > tbody + tbody {
|
||||||
|
//border-top: 2px solid #dddddd;
|
||||||
|
}
|
||||||
|
.table .table {
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
.table-condensed > thead > tr > th,
|
||||||
|
.table-condensed > tbody > tr > th,
|
||||||
|
.table-condensed > tfoot > tr > th,
|
||||||
|
.table-condensed > thead > tr > td,
|
||||||
|
.table-condensed > tbody > tr > td,
|
||||||
|
.table-condensed > tfoot > tr > td {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
.table-bordered {
|
||||||
|
//border: 1px solid #dddddd;
|
||||||
|
}
|
||||||
|
.table-bordered > thead > tr > th,
|
||||||
|
.table-bordered > tbody > tr > th,
|
||||||
|
.table-bordered > tfoot > tr > th,
|
||||||
|
.table-bordered > thead > tr > td,
|
||||||
|
.table-bordered > tbody > tr > td,
|
||||||
|
.table-bordered > tfoot > tr > td {
|
||||||
|
//border: 1px solid #dddddd;
|
||||||
|
}
|
||||||
|
.table-bordered > thead > tr > th,
|
||||||
|
.table-bordered > thead > tr > td {
|
||||||
|
//border-bottom-width: 2px;
|
||||||
|
}
|
||||||
|
.table-striped > tbody > tr:nth-of-type(odd) {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
.table-hover > tbody > tr:hover {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
table col[class*="col-"] {
|
||||||
|
position: static;
|
||||||
|
float: none;
|
||||||
|
display: table-column;
|
||||||
|
}
|
||||||
|
table td[class*="col-"],
|
||||||
|
table th[class*="col-"] {
|
||||||
|
position: static;
|
||||||
|
float: none;
|
||||||
|
display: table-cell;
|
||||||
|
}
|
||||||
|
.table > thead > tr > td.active,
|
||||||
|
.table > tbody > tr > td.active,
|
||||||
|
.table > tfoot > tr > td.active,
|
||||||
|
.table > thead > tr > th.active,
|
||||||
|
.table > tbody > tr > th.active,
|
||||||
|
.table > tfoot > tr > th.active,
|
||||||
|
.table > thead > tr.active > td,
|
||||||
|
.table > tbody > tr.active > td,
|
||||||
|
.table > tfoot > tr.active > td,
|
||||||
|
.table > thead > tr.active > th,
|
||||||
|
.table > tbody > tr.active > th,
|
||||||
|
.table > tfoot > tr.active > th {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
.table-hover > tbody > tr > td.active:hover,
|
||||||
|
.table-hover > tbody > tr > th.active:hover,
|
||||||
|
.table-hover > tbody > tr.active:hover > td,
|
||||||
|
.table-hover > tbody > tr:hover > .active,
|
||||||
|
.table-hover > tbody > tr.active:hover > th {
|
||||||
|
background-color: #e8e8e8;
|
||||||
|
}
|
||||||
|
.table > thead > tr > td.success,
|
||||||
|
.table > tbody > tr > td.success,
|
||||||
|
.table > tfoot > tr > td.success,
|
||||||
|
.table > thead > tr > th.success,
|
||||||
|
.table > tbody > tr > th.success,
|
||||||
|
.table > tfoot > tr > th.success,
|
||||||
|
.table > thead > tr.success > td,
|
||||||
|
.table > tbody > tr.success > td,
|
||||||
|
.table > tfoot > tr.success > td,
|
||||||
|
.table > thead > tr.success > th,
|
||||||
|
.table > tbody > tr.success > th,
|
||||||
|
.table > tfoot > tr.success > th {
|
||||||
|
background-color: #dff0d8;
|
||||||
|
}
|
||||||
|
.table-hover > tbody > tr > td.success:hover,
|
||||||
|
.table-hover > tbody > tr > th.success:hover,
|
||||||
|
.table-hover > tbody > tr.success:hover > td,
|
||||||
|
.table-hover > tbody > tr:hover > .success,
|
||||||
|
.table-hover > tbody > tr.success:hover > th {
|
||||||
|
background-color: #d0e9c6;
|
||||||
|
}
|
||||||
|
.table > thead > tr > td.info,
|
||||||
|
.table > tbody > tr > td.info,
|
||||||
|
.table > tfoot > tr > td.info,
|
||||||
|
.table > thead > tr > th.info,
|
||||||
|
.table > tbody > tr > th.info,
|
||||||
|
.table > tfoot > tr > th.info,
|
||||||
|
.table > thead > tr.info > td,
|
||||||
|
.table > tbody > tr.info > td,
|
||||||
|
.table > tfoot > tr.info > td,
|
||||||
|
.table > thead > tr.info > th,
|
||||||
|
.table > tbody > tr.info > th,
|
||||||
|
.table > tfoot > tr.info > th {
|
||||||
|
background-color: #d9edf7;
|
||||||
|
}
|
||||||
|
.table-hover > tbody > tr > td.info:hover,
|
||||||
|
.table-hover > tbody > tr > th.info:hover,
|
||||||
|
.table-hover > tbody > tr.info:hover > td,
|
||||||
|
.table-hover > tbody > tr:hover > .info,
|
||||||
|
.table-hover > tbody > tr.info:hover > th {
|
||||||
|
background-color: #c4e3f3;
|
||||||
|
}
|
||||||
|
.table > thead > tr > td.warning,
|
||||||
|
.table > tbody > tr > td.warning,
|
||||||
|
.table > tfoot > tr > td.warning,
|
||||||
|
.table > thead > tr > th.warning,
|
||||||
|
.table > tbody > tr > th.warning,
|
||||||
|
.table > tfoot > tr > th.warning,
|
||||||
|
.table > thead > tr.warning > td,
|
||||||
|
.table > tbody > tr.warning > td,
|
||||||
|
.table > tfoot > tr.warning > td,
|
||||||
|
.table > thead > tr.warning > th,
|
||||||
|
.table > tbody > tr.warning > th,
|
||||||
|
.table > tfoot > tr.warning > th {
|
||||||
|
background-color: #fcf8e3;
|
||||||
|
}
|
||||||
|
.table-hover > tbody > tr > td.warning:hover,
|
||||||
|
.table-hover > tbody > tr > th.warning:hover,
|
||||||
|
.table-hover > tbody > tr.warning:hover > td,
|
||||||
|
.table-hover > tbody > tr:hover > .warning,
|
||||||
|
.table-hover > tbody > tr.warning:hover > th {
|
||||||
|
background-color: #faf2cc;
|
||||||
|
}
|
||||||
|
.table > thead > tr > td.danger,
|
||||||
|
.table > tbody > tr > td.danger,
|
||||||
|
.table > tfoot > tr > td.danger,
|
||||||
|
.table > thead > tr > th.danger,
|
||||||
|
.table > tbody > tr > th.danger,
|
||||||
|
.table > tfoot > tr > th.danger,
|
||||||
|
.table > thead > tr.danger > td,
|
||||||
|
.table > tbody > tr.danger > td,
|
||||||
|
.table > tfoot > tr.danger > td,
|
||||||
|
.table > thead > tr.danger > th,
|
||||||
|
.table > tbody > tr.danger > th,
|
||||||
|
.table > tfoot > tr.danger > th {
|
||||||
|
background-color: #f2dede;
|
||||||
|
}
|
||||||
|
.table-hover > tbody > tr > td.danger:hover,
|
||||||
|
.table-hover > tbody > tr > th.danger:hover,
|
||||||
|
.table-hover > tbody > tr.danger:hover > td,
|
||||||
|
.table-hover > tbody > tr:hover > .danger,
|
||||||
|
.table-hover > tbody > tr.danger:hover > th {
|
||||||
|
background-color: #ebcccc;
|
||||||
|
}
|
||||||
|
.table-responsive {
|
||||||
|
overflow-x: auto;
|
||||||
|
min-height: 0.01%;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
.table-responsive {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
overflow-y: hidden;
|
||||||
|
-ms-overflow-style: -ms-autohiding-scrollbar;
|
||||||
|
//border: 1px solid #dddddd;
|
||||||
|
}
|
||||||
|
.table-responsive > .table {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.table-responsive > .table > thead > tr > th,
|
||||||
|
.table-responsive > .table > tbody > tr > th,
|
||||||
|
.table-responsive > .table > tfoot > tr > th,
|
||||||
|
.table-responsive > .table > thead > tr > td,
|
||||||
|
.table-responsive > .table > tbody > tr > td,
|
||||||
|
.table-responsive > .table > tfoot > tr > td {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.table-responsive > .table-bordered {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
.table-responsive > .table-bordered > thead > tr > th:first-child,
|
||||||
|
.table-responsive > .table-bordered > tbody > tr > th:first-child,
|
||||||
|
.table-responsive > .table-bordered > tfoot > tr > th:first-child,
|
||||||
|
.table-responsive > .table-bordered > thead > tr > td:first-child,
|
||||||
|
.table-responsive > .table-bordered > tbody > tr > td:first-child,
|
||||||
|
.table-responsive > .table-bordered > tfoot > tr > td:first-child {
|
||||||
|
border-left: 0;
|
||||||
|
}
|
||||||
|
.table-responsive > .table-bordered > thead > tr > th:last-child,
|
||||||
|
.table-responsive > .table-bordered > tbody > tr > th:last-child,
|
||||||
|
.table-responsive > .table-bordered > tfoot > tr > th:last-child,
|
||||||
|
.table-responsive > .table-bordered > thead > tr > td:last-child,
|
||||||
|
.table-responsive > .table-bordered > tbody > tr > td:last-child,
|
||||||
|
.table-responsive > .table-bordered > tfoot > tr > td:last-child {
|
||||||
|
border-right: 0;
|
||||||
|
}
|
||||||
|
.table-responsive > .table-bordered > tbody > tr:last-child > th,
|
||||||
|
.table-responsive > .table-bordered > tfoot > tr:last-child > th,
|
||||||
|
.table-responsive > .table-bordered > tbody > tr:last-child > td,
|
||||||
|
.table-responsive > .table-bordered > tfoot > tr:last-child > td {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
.clearfix:before,
|
.clearfix:before,
|
||||||
.clearfix:after,
|
.clearfix:after,
|
||||||
|
.dl-horizontal dd:before,
|
||||||
|
.dl-horizontal dd:after,
|
||||||
.container:before,
|
.container:before,
|
||||||
.container:after,
|
.container:after,
|
||||||
.container-fluid:before,
|
.container-fluid:before,
|
||||||
@ -929,6 +1701,7 @@ hr {
|
|||||||
display: table;
|
display: table;
|
||||||
}
|
}
|
||||||
.clearfix:after,
|
.clearfix:after,
|
||||||
|
.dl-horizontal dd:after,
|
||||||
.container:after,
|
.container:after,
|
||||||
.container-fluid:after,
|
.container-fluid:after,
|
||||||
.row:after {
|
.row:after {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user