Skip to content

Commit

Permalink
includes superdesk-ui-framework and uses it for lists
Browse files Browse the repository at this point in the history
Event list: show the search bar in another bar than the title

Custom Modal component
  • Loading branch information
vied12 committed Apr 27, 2017
1 parent 8b42918 commit 7c2c381
Show file tree
Hide file tree
Showing 25 changed files with 293 additions and 133 deletions.
3 changes: 2 additions & 1 deletion client/components/ConfirmationModal.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react'
import { Modal, Button } from 'react-bootstrap'
import { Modal } from './index'
import { Button } from 'react-bootstrap'

export function ConfirmationModal({ handleHide, modalProps }) {
const action = () => (
Expand Down
60 changes: 33 additions & 27 deletions client/components/EventItem/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ export const EventItem = ({ event, onClick, deleteEvent, selectedEvent }) => {
{
icon: 'icon-file',
count: get(event, 'files.length', 0),
className: 'files-attached-count',
},
{
icon: 'icon-link',
count: get(event, 'links.length', 0),
className: 'links-count',
},
]
const classes = [
Expand All @@ -30,34 +28,42 @@ export const EventItem = ({ event, onClick, deleteEvent, selectedEvent }) => {
].join(' ')
return (
<ListItem item={event} onClick={onClick.bind(this, event)} deleteEvent={deleteEvent.bind(this, event)} draggable={true} className={classes} active={selectedEvent === event._id}>
<div className="line">
<span className="event__title keyword">{event.name}</span>
<span className="item-heading">{event.definition_short}</span>
<time className="time--short" title={time}>{time}</time>

</div>
<div className="line">
<span className="container">
{location &&
<span className="location">location: {location}</span>
<div className="sd-list-item__column sd-list-item__column--grow sd-list-item__column--no-border">
<div className="sd-list-item__row">
<span className="sd-overflow-ellipsis sd-list-item--element-grow event__title">
{event.name}
{(event.definition_short && event.name !== event.definition_short) &&
<span>&nbsp;|&nbsp;{event.definition_short}</span>
}
</span>
<dl className="event__counts">
{counters.map(({ icon, count, className }) => {
if (count > 0) {
return [
<dt className={className}><i className={icon}/></dt>,
<dd className={className}>{count}</dd>,
]
}
})}
</dl>
<time title={time}>{time}</time>
</div>
<div className="sd-list-item__row">
{location &&
<span className="sd-overflow-ellipsis sd-list-item--element-grow">
Location: {location}&nbsp;
</span>
}
{counters.map(({ icon, count }) => {
if (count > 0) {
return (
<span key={icon}>
<i className={icon}/>&nbsp;{count}&nbsp;&nbsp;
</span>
)
}
})}
</div>
<span className="ListItem__actions">
<OverlayTrigger placement="left" overlay={tooltips.deleteEventTooltip}>
<i className="icon-trash" onClick={(e)=>{e.stopPropagation(); deleteEvent(event)}}/>
</OverlayTrigger>
</span>
</div>
<div className="sd-list-item__action-menu">
<OverlayTrigger placement="left" overlay={tooltips.deleteEventTooltip}>
<button
className="dropdown__toggle"
onClick={(e)=>{e.stopPropagation(); deleteEvent(event)}}>
<i className="icon-trash"/>
</button>
</OverlayTrigger>
</div>
</ListItem>
)
}
Expand Down
7 changes: 0 additions & 7 deletions client/components/EventItem/style.scss
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
.event {
border-left: 4px solid #bababa;
box-sizing: border-box;
.event__title { overflow: hidden; text-overflow: ellipsis }
&--has-planning {
border-left: 4px solid #00aa4d;
}
&--has-been-canceled {
.event__title { text-decoration: line-through; }
}
}
.event__counts {
i { color: #bababa; }
dt { padding-left: 5px }
}
25 changes: 11 additions & 14 deletions client/components/EventsList/_test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@ describe('<EventsList />', () => {
</Provider>
)
// there is three events to show
expect(wrapper.find('.ListItem__list-item').length).toEqual(3)
expect(wrapper.find('.ListItem').length).toEqual(3)
// only two groups, because two share the same date
expect(wrapper.find('.events-list__list').length).toEqual(2)
// check order
expect(wrapper.find('.events-list__title').map((e) => e.text()))
.toEqual(['Saturday October 15, 2016', 'Monday October 17, 2016'])
// check classes
expect(wrapper.find('.ListItem__list-item').first().hasClass('event--has-planning')).toBe(true)
expect(wrapper.find('.ListItem__list-item').last().hasClass('event--has-planning')).toBe(false)
expect(wrapper.find('.ListItem').first().hasClass('event--has-planning')).toBe(true)
expect(wrapper.find('.ListItem').last().hasClass('event--has-planning')).toBe(false)
// add a new item
const newEvent = {
_id: '123',
Expand All @@ -84,27 +84,24 @@ describe('<EventsList />', () => {
}
store.dispatch(actions.receiveEvents([newEvent]))
store.dispatch(actions.addToEventsList([newEvent._id]))
expect(wrapper.find('.ListItem__list-item').length).toEqual(4)
expect(wrapper.find('.ListItem').length).toEqual(4)
// update an item
const updatedEvent = {
...newEvent,
name: 'new name',
}
store.dispatch(actions.receiveEvents([updatedEvent]))
expect(wrapper.find('.ListItem__list-item').length).toEqual(4)
expect(wrapper.find('.ListItem').length).toEqual(4)
expect(
wrapper.find('.ListItem__list-item').last()
.find('.keyword').text())
.toBe('new name')
wrapper.find('.sd-list-item__row span').last().text())
.toContain('location3')
// check attached file count
expect(
wrapper.find('.ListItem__list-item').first()
.find('.event__counts dd.files-attached-count').text())
.toBe(events['5800d71930627218866f1e80'].files.length.toString())
wrapper.find('.ListItem').first().find('[className="icon-file"]').length
).toBe(1)
expect(
wrapper.find('.ListItem__list-item').last()
.find('.event__counts dd.files-attached-count').length)
.toBe(0)
wrapper.find('.ListItem').first().find('[className="icon-link"]').length
).toBe(0)
})
it('trigger an event click', () => {
const onButtonClick = sinon.spy()
Expand Down
19 changes: 10 additions & 9 deletions client/components/ListItem/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,20 @@ export class ListItem extends React.Component {
render() {
const { item, onClick, children, active, className, draggable=false } = this.props
const classes = [
'ListItem__list-item',
'list-item-view',
'ListItem',
'sd-list-item',
'sd-shadow--z1',
(active ? 'active' : null),
className,
].join(' ')
return (
<li className={classes} draggable={draggable} onDragStart={this.handleDragStart.bind(this)}>
<div className="media-box media-text">
<div className="item-info" onClick={onClick.bind(this, item)}>
{children}
</div>
</div>
</li>
<div className={classes}
draggable={draggable}
onDragStart={this.handleDragStart.bind(this)}
onClick={onClick.bind(this, item)}>
<div className="sd-list-item__border"/>
{children}
</div>
)
}
}
Expand Down
33 changes: 0 additions & 33 deletions client/components/ListItem/style.scss
Original file line number Diff line number Diff line change
@@ -1,33 +0,0 @@
.ListItem__list-item {
.media-box {
border-right: 0 solid black;
.item-info {
.line { margin-left: 0; }
.highlights-box { margin-right: 0; }
// second line, with location and icons
.line:nth-child(2) { .container { flex-grow: 1 } }
}
&:hover {
border-right: 0 solid black;
.item-info { padding: 10px 10px 10px 10px; }
.ListItem__actions { visibility: visible; }
}
}
}

.ListItem__actions {
position: absolute;
right: 0px;
top: 0px;
visibility: hidden;
height: 60px;
padding-top: 20px;
padding-left: 17px;
padding-right: 15px;
&:hover {
i { color: #436278 }
}
}

.ListItem__list-item:not(.active) .ListItem__actions { background-color: rgb(222, 222, 222) }
.ListItem__list-item.active .ListItem__actions { background-color: rgb(200, 228, 238) }
16 changes: 16 additions & 0 deletions client/components/Modal/Body.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react'
import { Modal as _Modal } from 'react-bootstrap'

export default function Body({ children }) {
return (
<_Modal.Body className="modal__body">
{children}
</_Modal.Body>)
}

Body.propTypes = {
children: React.PropTypes.oneOfType([
React.PropTypes.element,
React.PropTypes.arrayOf(React.PropTypes.element),
]),
}
16 changes: 16 additions & 0 deletions client/components/Modal/Footer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react'
import { Modal as _Modal } from 'react-bootstrap'

export default function Footer({ children }) {
return (
<_Modal.Footer className="modal__footer">
{children}
</_Modal.Footer>)
}

Footer.propTypes = {
children: React.PropTypes.oneOfType([
React.PropTypes.element,
React.PropTypes.arrayOf(React.PropTypes.element),
]),
}
16 changes: 16 additions & 0 deletions client/components/Modal/Header.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react'
import { Modal as _Modal } from 'react-bootstrap'

export default function Header({ children }) {
return (
<_Modal.Header className="modal__header">
{children}
</_Modal.Header>)
}

Header.propTypes = {
children: React.PropTypes.oneOfType([
React.PropTypes.element,
React.PropTypes.arrayOf(React.PropTypes.element),
]),
}
41 changes: 41 additions & 0 deletions client/components/Modal/ModalDialog.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react'
import classNames from 'classnames'
import { pickBy } from 'lodash'

export default function ModalDialog({ dialogClassName, children, style, className, ...props }) {
const modalStyle = {
display: 'block',
...style,
}
const bsClasses = [
'bsClass',
'bsSize',
'bsStyle',
'bsRole',
]
const elementProps = pickBy(props, (value, key) => (bsClasses.indexOf(key) === -1))
return (
<div
{...elementProps}
tabIndex="-1"
role="dialog"
style={modalStyle}
className={className}>
<div className={classNames(dialogClassName, 'modal__dialog')}>
<div className="modal__content" role="document">
{children}
</div>
</div>
</div>
)
}

ModalDialog.propTypes = {
children: React.PropTypes.oneOfType([
React.PropTypes.element,
React.PropTypes.arrayOf(React.PropTypes.element),
]),
style: React.PropTypes.object,
className: React.PropTypes.string,
dialogClassName: React.PropTypes.string,
}
51 changes: 51 additions & 0 deletions client/components/Modal/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react'
import { Modal as _Modal } from 'react-bootstrap'
import { default as ModalDialog } from './ModalDialog'
import { default as Header } from './Header'
import { default as Body } from './Body'
import { default as Footer } from './Footer'
import classNames from 'classnames'
import './style.scss'

export default function Modal({
show,
handleHide,
children,
large,
fill,
fullscreen,
white,
className,
}) {
const classes = classNames(className, {
'modal': true,
'modal--large': large,
'modal--fill': fill,
'modal--fullscreen': fullscreen,
'modal--white': white,
})
return (
<_Modal
show={show}
backdrop={true}
className={classes}
onHide={handleHide}
dialogComponentClass={ModalDialog}
>{children}</_Modal>
)
}

Modal.propTypes = {
show: React.PropTypes.bool,
handleHide: React.PropTypes.func,
children: React.PropTypes.array,
large: React.PropTypes.bool,
fill: React.PropTypes.bool,
fullscreen: React.PropTypes.bool,
white: React.PropTypes.bool,
className: React.PropTypes.string,
}

Modal.Header = Header
Modal.Body = Body
Modal.Footer = Footer
10 changes: 10 additions & 0 deletions client/components/Modal/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@import '~superdesk-core/styles/sass/mixins.scss';
@import '~superdesk-core/styles/sass/variables.scss';
// required for extending .modal__backdrop :
@import '~superdesk-ui-framework/app/styles/_mixins.scss';
@import '~superdesk-ui-framework/app/styles/_modals.scss';


.modal-backdrop {
@extend .modal__backdrop;
}
3 changes: 2 additions & 1 deletion client/components/ModalWithForm/index.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react'
import { Modal, Button } from 'react-bootstrap'
import { Modal } from '../index'
import { Button } from 'react-bootstrap'
import './style.scss'

export class ModalWithForm extends React.Component {
Expand Down

0 comments on commit 7c2c381

Please sign in to comment.