diff --git a/package.json b/package.json
index a5f55c5fc..7e2b1c422 100644
--- a/package.json
+++ b/package.json
@@ -19,10 +19,12 @@
},
"dependencies": {
"app-module-path": "^1.0.5",
+ "axios": "^0.19.0",
"babel-polyfill": "^6.23.0",
"babel-preset-stage-2": "^6.1.18",
"body-parser": "^1.14.1",
"bootstrap": "^4.1.3",
+ "classnames": "^2.2.6",
"codecov": "^3.0.0",
"connect-history-api-fallback": "^1.1.0",
"cookie-parser": "^1.4.0",
diff --git a/src/actions/events.js b/src/actions/events.js
index d3d143e86..6751b9c37 100644
--- a/src/actions/events.js
+++ b/src/actions/events.js
@@ -84,7 +84,7 @@ export function startFetchingEventDetails() {
}
export function fetchEventDetails(eventID, user = {}) {
- let url = `${appSettings.api_base}/event/${eventID}/?include=keywords,location,audience,in_language,external_links,image`
+ let url = `${appSettings.api_base}/event/${eventID}/?include=keywords,location,audience,in_language,external_links`
if(appSettings.nocache) {
url += `&nocache=${Date.now()}`
diff --git a/src/api/client.js b/src/api/client.js
new file mode 100644
index 000000000..66022a86d
--- /dev/null
+++ b/src/api/client.js
@@ -0,0 +1,134 @@
+import axios from 'axios'
+import get from 'lodash/get'
+
+import store from '../store'
+import CONSTANTS from '../constants'
+
+let authToken
+
+const getToken = () => {
+ const state = store.getState()
+ return get(state, 'user.token')
+}
+
+store.subscribe(() => {
+ authToken = getToken()
+})
+
+export class ApiClient {
+ baseUrl
+
+ constructor(baseUrl) {
+ this.baseUrl = baseUrl
+ authToken = getToken()
+ }
+
+ getUrl = (endpoint) => {
+ // URLs in Django must have a trailing slash
+ const endsWithTrailingSlash = endpoint.substring(endpoint.length - 1) === '/'
+ return `${this.baseUrl}/${endpoint}${endsWithTrailingSlash ? '' : '/'}`
+ }
+
+ getHeaders = () => ({
+ ...CONSTANTS.API_HEADERS,
+ ...(authToken
+ ? {Authorization: `JWT ${authToken}`}
+ : {}),
+ })
+
+ request = async ({
+ method,
+ endpoint,
+ data = {},
+ headers = {},
+ }) => {
+ const dataOrParams = ['GET', 'DELETE'].includes(method.toUpperCase()) ? 'params' : 'data'
+
+ return axios
+ .request({
+ method,
+ url: this.getUrl(endpoint),
+ headers: {
+ ...this.getHeaders(),
+ ...headers,
+ },
+ [dataOrParams]: data,
+ })
+ .then(response => ({
+ data: get(response, 'data'),
+ error: null,
+ }))
+ }
+
+ /**
+ * Make a GET request into the API.
+ * @param endpoint
+ * @param data
+ * @param config
+ * @returns {Promise}
+ */
+ get = async (endpoint, data = {}, config = {}) => this.request({
+ method: 'GET',
+ endpoint,
+ data,
+ ...config,
+ })
+
+ /**
+ * Make a POST request into the API.
+ * @param endpoint
+ * @param data
+ * @param config
+ * @returns {Promise}
+ */
+ post = (endpoint, data = {}, config = {}) => this.request({
+ method: 'POST',
+ endpoint,
+ data,
+ ...config,
+ })
+
+ /**
+ * Make a DELETE request into the API.
+ * @param endpoint
+ * @param data
+ * @param config
+ * @returns {Promise}
+ */
+ delete = (endpoint, data = {}, config = {}) => this.request({
+ method: 'DELETE',
+ endpoint,
+ data,
+ ...config,
+ })
+
+ /**
+ * Make a PUT request into the API.
+ * @param endpoint
+ * @param data
+ * @param config
+ * @returns {Promise}
+ */
+ put = (endpoint, data = {}, config = {}) => this.request({
+ method: 'PUT',
+ endpoint,
+ data,
+ ...config,
+ })
+
+ /**
+ * Make a PATCH request into the API.
+ * @param endpoint
+ * @param data
+ * @param config
+ * @returns {Promise}
+ */
+ patch = (endpoint, data = {}, config = {}) => this.request({
+ method: 'PATCH',
+ endpoint,
+ data,
+ ...config,
+ })
+}
+
+export default new ApiClient(appSettings.api_base)
diff --git a/src/components/EventDetails/index.js b/src/components/EventDetails/index.js
index 3356c4158..319814bd0 100644
--- a/src/components/EventDetails/index.js
+++ b/src/components/EventDetails/index.js
@@ -1,35 +1,50 @@
-import './index.scss'
-
import moment from 'moment'
import React from 'react'
import PropTypes from 'prop-types'
+import get from 'lodash/get'
+import {
+ injectIntl,
+ FormattedMessage,
+ FormattedDate,
+ FormattedTime,
+ intlShape,
+} from 'react-intl'
-import {injectIntl, FormattedMessage, FormattedDate, FormattedTime} from 'react-intl'
-import {getStringWithLocale} from 'src/utils/locale'
+import {getStringWithLocale} from '../../utils/locale'
-import {mapKeywordSetToForm, mapLanguagesSetToForm} from 'src/utils/apiDataMapping.js'
+import './index.scss'
-let NoValue = (props) => {
- let header = props.labelKey ? ( ) : null
+const NoValue = (props) => {
+ let header = props.labelKey ? ( ) : null
return (
{header}
-
+
)
}
-let CheckedValue = (props) => {
- let checkIcon = props.checked ? ( ) : ( )
- let label = props.labelKey ? : props.label
+NoValue.propTypes = {
+ labelKey: PropTypes.string,
+}
+
+const CheckedValue = (props) => {
+ let checkIcon = props.checked ? ( ) : (
+ )
+ let label = props.labelKey ? : props.label
return (
{checkIcon}{label}
)
}
-let MultiLanguageValue = (props) => {
+CheckedValue.propTypes = {
+ checked: PropTypes.bool,
+ labelKey: PropTypes.string,
+ label: PropTypes.string,
+}
- if(props.hidden) {
+const MultiLanguageValue = (props) => {
+ if (props.hidden) {
return (
)
}
@@ -39,7 +54,7 @@ let MultiLanguageValue = (props) => {
// Determine column size depending on the amount of language options
let colClass = 'col-md-12'
- if(count > 1) {
+ if (count > 1) {
colClass = (count === 2) ? 'col-md-6' : 'col-md-4'
}
@@ -51,15 +66,20 @@ let MultiLanguageValue = (props) => {
let val = value[key]
const createHTML = () => ({__html: val})
- if(val) {
- elements.push()
+ if (val) {
+ elements.push(
+
)
}
})
- if(elements.length > 0) {
+ if (elements.length > 0) {
return (
-
+
{elements}
@@ -68,7 +88,7 @@ let MultiLanguageValue = (props) => {
} else {
return (
-
+
@@ -78,11 +98,11 @@ let MultiLanguageValue = (props) => {
}
}
-let TextValue = (props) => {
+const TextValue = (props) => {
if (_.isInteger(props.value) || (props.value && props.value.length !== undefined && props.value.length > 0)) {
return (
-
+
{props.value}
@@ -91,7 +111,7 @@ let TextValue = (props) => {
} else {
return (
-
+
@@ -100,24 +120,23 @@ let TextValue = (props) => {
}
}
-let ImageValue = (props) => {
- if(props.value !== undefined && props.value instanceof Object) {
- return (
-
-
-
- )
- } else {
- return (
-
-
-
- )
+const ImageValue = (props) => {
+ if (props.value !== undefined && props.value instanceof Object) {
+ return
}
+
+ return (
+
+
+
+ )
}
-let OptionGroup = (props) => {
+ImageValue.propTypes = {
+ value: PropTypes.object,
+}
+const OptionGroup = (props) => {
let values = props.values || []
let elements = _.map(values, (val, key) => {
@@ -125,35 +144,38 @@ let OptionGroup = (props) => {
return (
)
})
- if(elements.length === 0) {
+ if (elements.length === 0) {
elements = ()
}
return (
-
-
+
)
}
-let DateTime = (props) => {
+OptionGroup.propTypes = {
+ values: PropTypes.array,
+ labelKey: PropTypes.string,
+}
+const DateTime = (props) => {
// TODO: if all day event show it on this field. Add a props for it
- if(props.value && props.value.length !== undefined && props.value.length > 0) {
-
- let time = moment(props.value).tz('Europe/Helsinki');
+ if (props.value && props.value.length !== undefined && props.value.length > 0) {
+ let time = moment(props.value).tz('Europe/Helsinki')
let value = ''
- if(time.isValid()) {
+ if (time.isValid()) {
value =
-
-
+
{
}
return (
-
+
{value}
@@ -171,7 +193,7 @@ let DateTime = (props) => {
} else {
return (
-
+
@@ -180,181 +202,142 @@ let DateTime = (props) => {
}
}
-let FormHeader = (props) => (
-
- { props.children }
-
-)
+const FormHeader = props =>
{props.children}
+FormHeader.propTypes = {
+ children: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.object,
+ ]),
+}
-let OffersValue = (props) => {
+const OffersValue = (props) => {
const {offers} = props.values
- if (offers && offers[0] && typeof offers[0] === 'object') {
- const offersValueList = []
- for (const key in props.values.offers) {
- const offerValues = (
-
-
-
-
-
- )
- offersValueList.push(offerValues)
- }
- return (
-
-
- {offersValueList}
-
- )
- } else {
+ if (!offers || offers[0] && typeof offers[0] !== 'object') {
return (
)
}
+
+ return (
+
+
+ {props.values.offers.map((offer, key) => (
+
+
+
+
+
+ ))}
+
+ )
}
-class EventDetails extends React.Component {
+OffersValue.propTypes = {
+ values: PropTypes.object,
+ labelKey: PropTypes.string,
+}
- render() {
+const EventDetails = (props) => {
+ // NOTE: Currently don't show not selected options
- let props = this.props
- // NOTE: Currently don't show not selected options
+ // let helMainOptions = mapKeywordSetToForm(props.keywordSets, 'helfi:topics')
+ // let helTargetOptions = mapKeywordSetToForm(props.keywordSets, 'helfi:audiences')
+ // let helEventLangOptions = mapLanguagesSetToForm(props.languages)
+ let helfiCategories = _.map(props.values.hel_main, (id) => (
+ _.find(props.rawData.keywords, (item) => (id.indexOf(item['@id']) > -1))
+ ))
- // let helMainOptions = mapKeywordSetToForm(props.keywordSets, 'helfi:topics')
- // let helTargetOptions = mapKeywordSetToForm(props.keywordSets, 'helfi:audiences')
- // let helEventLangOptions = mapLanguagesSetToForm(props.languages)
- let helfiCategories = _.map(props.values.hel_main, (id) => (
- _.find(props.rawData.keywords, (item) => (id.indexOf(item['@id']) > -1))
- ))
-
- return (
-
-
-
- { props.intl.formatMessage({id: 'event-description-fields-header'}) }
-
-
+ return (
+
+
+
+ {props.intl.formatMessage({id: 'event-description-fields-header'})}
+
-
- { props.intl.formatMessage({id: 'event-datetime-fields-header'}) }
-
-
+
+
+
+
+
+ {props.publisher && }
-
- { props.intl.formatMessage({id: 'event-location-fields-header'}) }
-
-
+
+ {props.intl.formatMessage({id: 'event-datetime-fields-header'})}
+
+
+
+
+
+ {props.intl.formatMessage({id: 'event-location-fields-header'})}
+
+
+
+
+
+
+ {props.intl.formatMessage({id: 'event-price-fields-header'})}
+
+
+
+
+ {props.intl.formatMessage({id: 'event-social-media-fields-header'})}
+
+
+
+
+
+
+ {props.intl.formatMessage({id: 'event-categorization'})}
+
+
+
+
+
+
+
+ {appSettings.ui_mode === 'courses' &&
- { props.intl.formatMessage({id: 'event-price-fields-header'}) }
+ {props.intl.formatMessage({id: 'audience-age-restrictions'})}
-
+
+
- { props.intl.formatMessage({id: 'event-social-media-fields-header'}) }
+ {props.intl.formatMessage({id: 'enrolment-time'})}
-
+
+
- { props.intl.formatMessage({id: 'event-categorization'}) }
+ {props.intl.formatMessage({id: 'attendee-capacity'})}
-
-
- {appSettings.ui_mode === 'courses' &&
-
-
- { props.intl.formatMessage({id: 'audience-age-restrictions'})}
-
-
-
-
- { props.intl.formatMessage({id: 'enrolment-time'})}
-
-
-
-
- { props.intl.formatMessage({id: 'attendee-capacity'})}
-
-
-
- }
-
- )
- }
-}
-
-NoValue.propTypes = {
- labelKey: PropTypes.string,
-}
-
-CheckedValue.propTypes = {
- checked: PropTypes.bool,
- labelKey: PropTypes.string,
- label: PropTypes.string,
-}
-
-OptionGroup.propTypes = {
- values: PropTypes.array,
- labelKey: PropTypes.string,
+
+
+ }
+
+ )
}
-FormHeader.propTypes = {
- children: PropTypes.oneOfType([
- PropTypes.string,
- PropTypes.object,
- ]),
+EventDetails.propTypes = {
+ values: PropTypes.object,
+ rawData: PropTypes.object,
+ intl: intlShape,
+ publisher: PropTypes.object,
}
export default injectIntl(EventDetails)
diff --git a/src/constants.js b/src/constants.js
index b9158d712..c40ba2603 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -1,4 +1,8 @@
const constants = {
+ API_HEADERS: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json',
+ },
APP_SET_FLASHMSG: 'APP_SET_FLASHMSG',
APP_CLEAR_FLASHMSG: 'APP_CLEAR_FLASHMSG',
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 0003c081a..283b8d795 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -58,7 +58,9 @@
"event-provider": "Event organizer",
"event-provider-input": "Event organizer (if different than the publisher)",
"event-publisher": "Event publisher",
-
+ "event-publisher-info": "Publisher: {publisher}, {publishedAt}",
+ "event-publisher-info-with-created-by": "Publisher: {publisher} / {createdBy}, {publishedAt}",
+
"events-management": "Manage events",
"events-management-prompt": "to manage events.",
"events-management-description": "Browse and edit drafts and published events of your organization.",
diff --git a/src/i18n/fi.json b/src/i18n/fi.json
index 1ce95b96f..62b81f838 100644
--- a/src/i18n/fi.json
+++ b/src/i18n/fi.json
@@ -58,7 +58,8 @@
"event-provider": "Tapahtuman järjestäjä",
"event-provider-input": "Tapahtuman järjestäjä (jos eri kuin julkaisija)",
"event-publisher": "Tapahtuman julkaisija",
-
+ "event-publisher-info": "Julkaisija: {publisher}, {publishedAt}",
+ "event-publisher-info-with-created-by": "Julkaisija: {publisher} / {createdBy}, {publishedAt}",
"events-management": "Tapahtumien hallinta",
"events-management-prompt": "muokataksesi tapahtumia.",
"events-management-description": "Selaa ja muokkaa oman organisaatiosi julkisia tapahtumia sekä luonnoksia. Voit lisätä uuden tapahtuman yläpalkista.",
diff --git a/src/index.js b/src/index.js
index 64b577c3c..c8ea8141d 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,17 +1,12 @@
-
import React from 'react'
import ReactDOM from 'react-dom'
import {Route} from 'react-router'
import PropTypes from 'prop-types'
-
-import {Link, withRouter} from 'react-router-dom'
-import createHistory from 'history/createBrowserHistory' //'history/createHashHistory'
-
+import {withRouter} from 'react-router-dom'
+import createHistory from 'history/createBrowserHistory'
import {createStore, combineReducers, applyMiddleware, compose} from 'redux'
import {Provider, connect} from 'react-redux'
-
-import {ConnectedRouter, routerReducer, routerMiddleware, push} from 'react-router-redux'
-
+import {ConnectedRouter, routerReducer, routerMiddleware} from 'react-router-redux'
import thunk from 'redux-thunk'
import reducers from './reducers'
@@ -35,22 +30,7 @@ import {Modal, Button, Glyphicon} from 'react-bootstrap';
// translation
import IntlProviderWrapper from './components/IntlProviderWrapper'
-
-const history = createHistory()
-
-const allReducers = combineReducers(Object.assign({}, reducers, {
- router: routerReducer,
-}))
-
-const allMiddlewares = compose(
- applyMiddleware(thunk),
- applyMiddleware(routerMiddleware(history)),
- typeof window === 'object' && typeof window.devToolsExtension !== 'undefined' ? window.devToolsExtension() : f => f
-)
-
-const store = createStore(allReducers, allMiddlewares)
-
-
+import store, {history} from './store'
// Setup actor for validation. Actor is a viewless component which can listen to store changes
// and send new actions accordingly. Bind the store as this for function
diff --git a/src/store.js b/src/store.js
new file mode 100644
index 000000000..e186a13c2
--- /dev/null
+++ b/src/store.js
@@ -0,0 +1,21 @@
+import createHistory from 'history/createBrowserHistory'
+import {applyMiddleware, combineReducers, compose, createStore} from 'redux'
+import reducers from './reducers'
+import {routerMiddleware, routerReducer} from 'react-router-redux'
+import thunk from 'redux-thunk'
+
+export const history = createHistory()
+
+const allReducers = combineReducers(Object.assign({}, reducers, {
+ router: routerReducer,
+}))
+
+const allMiddlewares = compose(
+ applyMiddleware(thunk),
+ applyMiddleware(routerMiddleware(history)),
+ typeof window === 'object' && typeof window.devToolsExtension !== 'undefined' ? window.devToolsExtension() : f => f
+)
+
+const store = createStore(allReducers, allMiddlewares)
+
+export default store
diff --git a/src/utils/locale.js b/src/utils/locale.js
index 60b11b4e7..64c0ca692 100644
--- a/src/utils/locale.js
+++ b/src/utils/locale.js
@@ -7,14 +7,15 @@ import {get} from 'lodash'
* // let label = getStringWithLocale(this.props, 'editor.values.name', 'fi')
*
* @param {object} obj multi language field
- * @param {string} fieldpath string path for the field
+ * @param {string} fieldPath string path for the field
* @param {string} locale 'fi', 'sv' or 'en'
- * @return {string} language string
+ * @param {string} defaultValue
+ * @return {string} language string
*/
-export function getStringWithLocale(obj, fieldpath = '', locale = 'fi', defaultValue = '') {
- let field = get(obj, fieldpath, {})
+export function getStringWithLocale(obj, fieldPath = '', locale = 'fi', defaultValue = '') {
+ let field = get(obj, fieldPath, {})
- if(typeof field === 'object' && field) {
+ if (typeof field === 'object' && field) {
return field[locale] || field.fi || field.sv || field.en || defaultValue
}
diff --git a/src/views/Editor/index.scss b/src/views/Editor/index.scss
index e74c36c7a..b2afe3462 100644
--- a/src/views/Editor/index.scss
+++ b/src/views/Editor/index.scss
@@ -3,7 +3,6 @@ $actionBtnMargin: 0 10px;
$actionBtnHeight: 64px;
.editor-page {
-
font-weight: 300;
background-color: #ffffff;
diff --git a/src/views/Event/index.js b/src/views/Event/index.js
index 3c8cde7bd..c9f500b4c 100644
--- a/src/views/Event/index.js
+++ b/src/views/Event/index.js
@@ -1,57 +1,73 @@
-import './index.scss'
-
import React from 'react'
import {connect} from 'react-redux'
import EventDetails from 'src/components/EventDetails'
import moment from 'moment'
import PropTypes from 'prop-types'
-
+import get from 'lodash/get'
import {FormattedMessage, injectIntl, intlShape} from 'react-intl'
-
import {Button} from 'material-ui'
import Tooltip from 'material-ui/Tooltip'
import {push} from 'react-router-redux'
+import classNames from 'classnames'
-import {fetchEventDetails as fetchEventDetailsAction} from 'src/actions/events.js'
+import {fetchEventDetails as fetchEventDetailsAction} from 'src/actions/events'
import {
replaceData as replaceDataAction,
- deleteEvent as deleteEventAction,
+ deleteEvent as deleteEventAction,
cancelEvent as cancelEventAction,
} from 'src/actions/editor.js'
import {fetchSubEvents as fetchSubEventsAction} from 'src/actions/subEvents'
-
-import {
- confirmAction,
- clearFlashMsg as clearFlashMsgAction,
-} from 'src/actions/app.js'
-
+import {confirmAction} from 'src/actions/app.js'
import {getStringWithLocale} from 'src/utils/locale'
import {mapAPIDataToUIFormat} from 'src/utils/formDataMapping.js'
import {checkEventEditability} from 'src/utils/checkEventEditability.js'
-
+import client from '../../api/client'
import constants from 'src/constants'
+import './index.scss'
+
class EventPage extends React.Component {
+ state = {
+ publisher: null,
+ }
- UNSAFE_componentWillMount() {
- const {match, fetchEventDetails, user, fetchSubEvents} = this.props
+ componentDidMount() {
+ const {
+ match,
+ fetchEventDetails,
+ user,
+ fetchSubEvents,
+ } = this.props
fetchEventDetails(match.params.eventId, user)
fetchSubEvents(this.props.match.params.eventId, user)
}
+ componentDidUpdate(prevProps) {
+ const publisherId = get(this.props, 'events.event.publisher')
+ const oldPublisherId = get(prevProps, 'events.event.publisher')
+
+ if (publisherId && publisherId !== oldPublisherId) {
+ client.get(`organization/${publisherId}`).then(response => {
+ this.setState({
+ publisher: response.data,
+ })
+ })
+ }
+ }
+
copyAsTemplate() {
- const {events:{event}, replaceData, routerPush} = this.props
- if(event) {
+ const {events: {event}, replaceData, routerPush} = this.props
+ if (event) {
replaceData(event)
routerPush(`/event/create/new`)
}
}
editEvent() {
- const {events:{event}, replaceData, routerPush} = this.props
- if(event) {
- replaceData(event)
+ const {events: {event}, replaceData, routerPush} = this.props
+ if (event) {
+ replaceData(event)
routerPush(`/event/update/${event.id}`)
}
}
@@ -59,8 +75,8 @@ class EventPage extends React.Component {
getActionButtons() {
let {eventIsEditable, eventEditabilityExplanation} = checkEventEditability(this.props.user, this.props.events.event)
let buttons =
- { this.getDeleteButton(!eventIsEditable) }
- { this.getCancelButton(!eventIsEditable) }
+ {this.getDeleteButton(!eventIsEditable)}
+ {this.getCancelButton(!eventIsEditable)}
return (
@@ -74,8 +90,8 @@ class EventPage extends React.Component {
}
confirmCancel() {
- const {user, events, cancelEvent} = this.props;
- const eventId = this.props.match.params.eventId;
+ const {user, events, cancelEvent} = this.props
+ const eventId = this.props.match.params.eventId
// TODO: maybe do a decorator for confirmable actions etc...?
this.props.confirm(
'confirm-cancel',
@@ -91,8 +107,8 @@ class EventPage extends React.Component {
confirmDelete() {
// TODO: maybe do a decorator for confirmable actions etc...?
- const eventId = this.props.match.params.eventId;
- const {user, deleteEvent, events} = this.props;
+ const eventId = this.props.match.params.eventId
+ const {user, deleteEvent, events} = this.props
this.props.confirm(
'confirm-delete',
@@ -120,91 +136,111 @@ class EventPage extends React.Component {
return warningText + subEventWarning
}
- render() {
- const user = this.props.user
-
- let event = mapAPIDataToUIFormat(this.props.events.event)
-
- // To prevent 'Can't access field of undefined errors'
- event.location = event.location || {}
- // Tooltip is empty if the event is editable
- let {eventIsEditable, eventEditabilityExplanation} = checkEventEditability(user, event)
+ getPublishedText = () => {
+ const {events: {event}, intl} = this.props
+ const {publisher} = this.state
- // Add necessary badges
- let draftClass = event.publication_status == constants.PUBLICATION_STATUS.DRAFT ? 'event-page draft' : 'event-page'
- let draftBadge = null
- if (event.publication_status === constants.PUBLICATION_STATUS.DRAFT) {
- draftBadge = (
)
+ if (!publisher) {
+ return null
}
- let cancelledClass = event.publication_status == constants.EVENT_STATUS.CANCELLED ? 'event-page' : 'event-page'
- let cancelledBadge = null
- if (event.event_status === constants.EVENT_STATUS.CANCELLED) {
- cancelledBadge = (
)
+
+ const values = {
+ publisher: publisher.name,
+ createdBy: get(event, 'created_by', ''),
+ publishedAt: moment(event.last_modified_time).format('D.M.YYYY HH:mm'),
}
- if(this.props.events.eventError) {
+ return intl.formatMessage({
+ id: values.createdBy ? 'event-publisher-info-with-created-by' : 'event-publisher-info',
+ }, values);
+ }
+
+ render() {
+ const {user} = this.props
+ let event = mapAPIDataToUIFormat(this.props.events.event)
+
+ if (!event || !event.name) {
return (
-
-
-
-
+
)
}
- const editEventButton = this.editEvent(e)} disabled={!eventIsEditable} color="primary">
- const cancelEventButton = this.confirmCancel(e)} color="accent">
- const deleteEventButton = this.confirmDelete(e)} color="accent">
- if(event && event.name) {
+ if (this.props.events.eventError) {
return (
-
-
+
+ )
+ }
+
+ // Tooltip is empty if the event is editable
+ let {eventIsEditable, eventEditabilityExplanation} = checkEventEditability(user, event)
+
+ const isDraft = event.publication_status === constants.PUBLICATION_STATUS.DRAFT
+ const isCancelled = event.publication_status === constants.EVENT_STATUS.CANCELLED
+
+ const editEventButton = this.editEvent(e)} disabled={!eventIsEditable}
+ color="primary">
+ const cancelEventButton = this.confirmCancel(e)}
+ color="accent">
+ const deleteEventButton = this.confirmDelete(e)}
+ color="accent">
+
+ const publishedText = this.getPublishedText();
+ return (
+
+
+
- {cancelledBadge}
- {draftBadge}
- { getStringWithLocale(event, 'name') }
+ {isCancelled && }
+ {isDraft && }
+ {getStringWithLocale(event, 'name')}
-
-
-
-
- {eventIsEditable ? cancelEventButton :
-
- {cancelEventButton}
-
- }
- {eventIsEditable ? deleteEventButton :
-
- {deleteEventButton}
-
- }
-
-
- {eventIsEditable ? editEventButton :
-
- {editEventButton}
-
- }
- this.copyAsTemplate(e)} color="default">
-
+
+
+ {eventIsEditable ? cancelEventButton :
+
+ {cancelEventButton}
+
+ }
+ {eventIsEditable ? deleteEventButton :
+
+ {deleteEventButton}
+
+ }
+
+
+ {eventIsEditable ? editEventButton :
+
+ {editEventButton}
+
+ }
+ this.copyAsTemplate(e)} color="default">
+
+
-
- )
- }
- else {
- return (
-
- )
- }
+
+ )
}
}
diff --git a/src/views/Event/index.scss b/src/views/Event/index.scss
index 3d95e407b..4d0ec5702 100644
--- a/src/views/Event/index.scss
+++ b/src/views/Event/index.scss
@@ -23,7 +23,7 @@ $buttonActionMargin: 10px;
}
pre {
- margin: 2rem 0rem
+ margin: 2rem 0
}
.highlighted-block {
@@ -35,6 +35,11 @@ $buttonActionMargin: 10px;
color: #5a5959;
}
+
+ .published-information {
+ text-align: right;
+ margin: 20px 10px;
+ }
}
.draft {
diff --git a/yarn.lock b/yarn.lock
index 1595a871c..c32b5252a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -628,6 +628,14 @@ aws4@^1.2.1, aws4@^1.6.0, aws4@^1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
+axios@^0.19.0:
+ version "0.19.0"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8"
+ integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==
+ dependencies:
+ follow-redirects "1.5.10"
+ is-buffer "^2.0.2"
+
babel-cli@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1"
@@ -1980,7 +1988,7 @@ class-utils@^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"
-classnames@^2.2.4, classnames@^2.2.5:
+classnames@^2.2.4, classnames@^2.2.5, classnames@^2.2.6:
version "2.2.6"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
@@ -3555,6 +3563,13 @@ flux-standard-action@^0.6.0:
dependencies:
lodash.isplainobject "^3.2.0"
+follow-redirects@1.5.10:
+ version "1.5.10"
+ resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
+ integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
+ dependencies:
+ debug "=3.1.0"
+
follow-redirects@^1.0.0:
version "1.5.9"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.9.tgz#c9ed9d748b814a39535716e531b9196a845d89c6"
@@ -4394,6 +4409,11 @@ is-buffer@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
+is-buffer@^2.0.2:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623"
+ integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==
+
is-builtin-module@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe"