mirror of
https://github.com/opensupports/opensupports.git
synced 2025-07-27 07:44:29 +02:00
Ivan - Table Component - Working table in dashboard [skip ci]
This commit is contained in:
parent
307946ff22
commit
c9c9d7c80c
@ -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,11 +1,96 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Table from 'core-components/table';
|
import Table from 'core-components/table';
|
||||||
|
import Button from 'core-components/button';
|
||||||
|
|
||||||
|
let mockTickets = [
|
||||||
|
{
|
||||||
|
ticketNumber: '445441',
|
||||||
|
title: 'Problem with installation',
|
||||||
|
content: 'I had a problem with the installation of the php server',
|
||||||
|
department: 'Environment Setup',
|
||||||
|
date: '15 Apr 2016',
|
||||||
|
file: 'http://www.opensupports.com/some_file.zip',
|
||||||
|
language: 'en',
|
||||||
|
unread: true,
|
||||||
|
closed: false,
|
||||||
|
author: {
|
||||||
|
name: 'John Smith',
|
||||||
|
email: 'john@smith.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: 'John Smith',
|
||||||
|
steve: 'john@smith.com',
|
||||||
|
staff: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ticketNumber: '87852',
|
||||||
|
title: 'Lorem ipsum door',
|
||||||
|
content: 'I had a problem with the installation of the php server',
|
||||||
|
department: 'Environment Setup',
|
||||||
|
date: '15 Apr 2016',
|
||||||
|
file: 'http://www.opensupports.com/some_file.zip',
|
||||||
|
language: 'en',
|
||||||
|
unread: false,
|
||||||
|
closed: false,
|
||||||
|
author: {
|
||||||
|
name: 'John Smith',
|
||||||
|
email: 'john@smith.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: 'John Smith',
|
||||||
|
steve: 'john@smith.com',
|
||||||
|
staff: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
class DashboardListTicketsPage extends React.Component {
|
class DashboardListTicketsPage extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
tickets: React.PropTypes.arrayOf(React.PropTypes.object)
|
||||||
|
};
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
tickets: mockTickets.concat([mockTickets[1], mockTickets[1]])
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="dashboard-ticket-list">
|
||||||
|
<div className="dashboard-ticket-list__header">Tickets</div>
|
||||||
<Table headers={this.getTableHeaders()} rows={this.getTableRows()} />
|
<Table headers={this.getTableHeaders()} rows={this.getTableRows()} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -21,12 +106,12 @@ class DashboardListTicketsPage extends React.Component {
|
|||||||
{
|
{
|
||||||
key: 'title',
|
key: 'title',
|
||||||
value: 'Title',
|
value: 'Title',
|
||||||
className: 'dashboard-ticket-list__title col-md-7'
|
className: 'dashboard-ticket-list__title col-md-6'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'department',
|
key: 'department',
|
||||||
value: 'Department',
|
value: 'Department',
|
||||||
className: 'dashboard-ticket-list__department col-md-2'
|
className: 'dashboard-ticket-list__department col-md-3'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'date',
|
key: 'date',
|
||||||
@ -37,44 +122,19 @@ class DashboardListTicketsPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getTableRows() {
|
getTableRows() {
|
||||||
return [
|
return this.props.tickets.map(this.gerTicketTableObject.bind(this));
|
||||||
{
|
}
|
||||||
number: '#445441',
|
|
||||||
title: 'Problem with installation',
|
gerTicketTableObject(ticket) {
|
||||||
department: 'Environment Setup',
|
let titleText = (ticket.unread) ? ticket.title + ' (1)' : ticket.title;
|
||||||
date: '15 Apr 2016'
|
|
||||||
},
|
return {
|
||||||
{
|
number: '#' + ticket.ticketNumber,
|
||||||
number: '#445441',
|
title: <Button type="clean" route={{to: '/app/dashboard/view-ticket/' + ticket.ticketNumber}}>{titleText}</Button>,
|
||||||
title: 'Problem with installation',
|
department: ticket.department,
|
||||||
department: 'Environment Setup',
|
date: ticket.date,
|
||||||
date: '15 Apr 2016'
|
highlighted: ticket.unread
|
||||||
},
|
};
|
||||||
{
|
|
||||||
number: '#445441',
|
|
||||||
title: 'Problem with installation',
|
|
||||||
department: 'Environment Setup',
|
|
||||||
date: '15 Apr 2016'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
number: '#445441',
|
|
||||||
title: 'Problem with installation',
|
|
||||||
department: 'Environment Setup',
|
|
||||||
date: '15 Apr 2016'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
number: '#445441',
|
|
||||||
title: 'Problem with installation',
|
|
||||||
department: 'Environment Setup',
|
|
||||||
date: '15 Apr 2016'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
number: '#445441',
|
|
||||||
title: 'Problem with installation',
|
|
||||||
department: 'Environment Setup',
|
|
||||||
date: '15 Apr 2016'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,13 @@
|
|||||||
|
@import "../../../../scss/vars";
|
||||||
|
|
||||||
.dashboard-ticket-list {
|
.dashboard-ticket-list {
|
||||||
|
|
||||||
|
&__header {
|
||||||
|
text-align: left;
|
||||||
|
font-variant: small-caps;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
&__number {
|
&__number {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,10 @@ import _ from 'lodash';
|
|||||||
import Menu from 'core-components/menu';
|
import Menu from 'core-components/menu';
|
||||||
|
|
||||||
let dashboardRoutes = [
|
let dashboardRoutes = [
|
||||||
{ path: '/app/dashboard', text: 'Ticket List' },
|
{ path: '/app/dashboard', text: 'Ticket List', icon: 'file-text-o' },
|
||||||
{ path: '/app/dashboard/create-ticket', text: 'Create Ticket' },
|
{ path: '/app/dashboard/create-ticket', text: 'Create Ticket', icon: 'plus' },
|
||||||
{ path: '/app/dashboard/articles', text: 'View Articles' },
|
{ path: '/app/dashboard/articles', text: 'View Articles', icon: 'book' },
|
||||||
{ path: '/app/dashboard/edit-profile', text: 'Edit Profile' }
|
{ path: '/app/dashboard/edit-profile', text: 'Edit Profile', icon: 'pencil' }
|
||||||
];
|
];
|
||||||
|
|
||||||
class DashboardMenu extends React.Component {
|
class DashboardMenu extends React.Component {
|
||||||
@ -27,9 +27,11 @@ 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.goToPathByIndex.bind(this),
|
||||||
|
type: 'secondary'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +41,8 @@ class DashboardMenu extends React.Component {
|
|||||||
|
|
||||||
getMenuItem(item) {
|
getMenuItem(item) {
|
||||||
return {
|
return {
|
||||||
content: item.text
|
content: item.text,
|
||||||
|
icon: item.icon
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ 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,
|
||||||
@ -22,12 +23,25 @@ class Menu extends React.Component {
|
|||||||
|
|
||||||
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,8 +59,9 @@ 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;
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,7 +8,7 @@ class Table extends React.Component {
|
|||||||
value: React.PropTypes.string,
|
value: React.PropTypes.string,
|
||||||
className: React.PropTypes.string
|
className: React.PropTypes.string
|
||||||
})),
|
})),
|
||||||
rows: React.PropTypes.arrayOf(React.PropTypes.objectOf(React.PropTypes.node)),
|
rows: React.PropTypes.arrayOf(React.PropTypes.object),
|
||||||
type: React.PropTypes.oneOf(['default'])
|
type: React.PropTypes.oneOf(['default'])
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ class Table extends React.Component {
|
|||||||
let headersKeys = this.props.headers.map(header => header.key);
|
let headersKeys = this.props.headers.map(header => header.key);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<tr className="table__row" key={index}>
|
<tr className={this.getRowClass(row)} key={index}>
|
||||||
{headersKeys.map(this.renderCell.bind(this, row))}
|
{headersKeys.map(this.renderCell.bind(this, row))}
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
@ -62,6 +62,15 @@ class Table extends React.Component {
|
|||||||
<td className={classNames(classes)} key={key}>{row[key]}</td>
|
<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;
|
export default Table;
|
@ -5,11 +5,11 @@
|
|||||||
&__header {
|
&__header {
|
||||||
background-color: $primary-blue;
|
background-color: $primary-blue;
|
||||||
color: white;
|
color: white;
|
||||||
font-variant: small-caps;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__header-column {
|
&__header-column {
|
||||||
padding: 10px;
|
font-weight: normal;
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
border-top-left-radius: 4px;
|
border-top-left-radius: 4px;
|
||||||
@ -21,6 +21,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&__row {
|
&__row {
|
||||||
|
border: 0;
|
||||||
color: #B8B8B8;
|
color: #B8B8B8;
|
||||||
|
|
||||||
&:nth-child(even) {
|
&:nth-child(even) {
|
||||||
@ -28,11 +29,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&:nth-child(odd) {
|
&:nth-child(odd) {
|
||||||
background-color: $light-grey;
|
background-color: #F1F1F1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-highlighted {
|
||||||
|
color: $secondary-blue;
|
||||||
|
font-weight: bold;
|
||||||
|
background-color: white !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__cell {
|
&__cell00 {
|
||||||
|
border: 0;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1473,11 +1473,11 @@ th {
|
|||||||
padding: 8px;
|
padding: 8px;
|
||||||
line-height: 1.42857143;
|
line-height: 1.42857143;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
border-top: 1px solid #dddddd;
|
//border-top: 1px solid #dddddd;
|
||||||
}
|
}
|
||||||
.table > thead > tr > th {
|
.table > thead > tr > th {
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
border-bottom: 2px solid #dddddd;
|
//border-bottom: 2px solid #dddddd;
|
||||||
}
|
}
|
||||||
.table > caption + thead > tr:first-child > th,
|
.table > caption + thead > tr:first-child > th,
|
||||||
.table > colgroup + thead > tr:first-child > th,
|
.table > colgroup + thead > tr:first-child > th,
|
||||||
@ -1488,7 +1488,7 @@ th {
|
|||||||
border-top: 0;
|
border-top: 0;
|
||||||
}
|
}
|
||||||
.table > tbody + tbody {
|
.table > tbody + tbody {
|
||||||
border-top: 2px solid #dddddd;
|
//border-top: 2px solid #dddddd;
|
||||||
}
|
}
|
||||||
.table .table {
|
.table .table {
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
@ -1502,7 +1502,7 @@ th {
|
|||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
.table-bordered {
|
.table-bordered {
|
||||||
border: 1px solid #dddddd;
|
//border: 1px solid #dddddd;
|
||||||
}
|
}
|
||||||
.table-bordered > thead > tr > th,
|
.table-bordered > thead > tr > th,
|
||||||
.table-bordered > tbody > tr > th,
|
.table-bordered > tbody > tr > th,
|
||||||
@ -1510,11 +1510,11 @@ th {
|
|||||||
.table-bordered > thead > tr > td,
|
.table-bordered > thead > tr > td,
|
||||||
.table-bordered > tbody > tr > td,
|
.table-bordered > tbody > tr > td,
|
||||||
.table-bordered > tfoot > tr > td {
|
.table-bordered > tfoot > tr > td {
|
||||||
border: 1px solid #dddddd;
|
//border: 1px solid #dddddd;
|
||||||
}
|
}
|
||||||
.table-bordered > thead > tr > th,
|
.table-bordered > thead > tr > th,
|
||||||
.table-bordered > thead > tr > td {
|
.table-bordered > thead > tr > td {
|
||||||
border-bottom-width: 2px;
|
//border-bottom-width: 2px;
|
||||||
}
|
}
|
||||||
.table-striped > tbody > tr:nth-of-type(odd) {
|
.table-striped > tbody > tr:nth-of-type(odd) {
|
||||||
background-color: #f9f9f9;
|
background-color: #f9f9f9;
|
||||||
@ -1648,7 +1648,7 @@ table th[class*="col-"] {
|
|||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
-ms-overflow-style: -ms-autohiding-scrollbar;
|
-ms-overflow-style: -ms-autohiding-scrollbar;
|
||||||
border: 1px solid #dddddd;
|
//border: 1px solid #dddddd;
|
||||||
}
|
}
|
||||||
.table-responsive > .table {
|
.table-responsive > .table {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user