diff --git a/src/components/EventActionButton/EventActionButton.js b/src/components/EventActionButton/EventActionButton.js index 07a10c2a2..3dd23eadc 100644 --- a/src/components/EventActionButton/EventActionButton.js +++ b/src/components/EventActionButton/EventActionButton.js @@ -12,7 +12,7 @@ import {confirmAction} from '../../actions/app' import {getButtonLabel} from '../../utils/helpers' import {Link} from 'react-router-dom' -const {PUBLICATION_STATUS, USER_TYPE} = constants +const {PUBLICATION_STATUS, EVENT_STATUS, USER_TYPE} = constants /** * Returns whether the button is a save button based on given action @@ -71,9 +71,10 @@ const EventActionButton = (props) => { const isRegularUser = get(user, 'userType') === USER_TYPE.REGULAR const formHasSubEvents = get(editor, ['values', 'sub_events'], []).length > 0 const isDraft = get(event, 'publication_status') === PUBLICATION_STATUS.DRAFT + const isPostponed = get(event, 'event_status') === EVENT_STATUS.POSTPONED const {editable, explanationId} = checkEventEditability(user, event, action, editor) const showTermsCheckbox = isRegularUser && isSaveButton(action) && !isDraft - const disabled = !editable || loading || (showTermsCheckbox && !agreedToTerms) + let disabled = !editable || loading || (showTermsCheckbox && !agreedToTerms) let color = 'default' const buttonLabel = customButtonLabel || getButtonLabel(action, isRegularUser, isDraft, eventIsPublished, formHasSubEvents) @@ -85,6 +86,10 @@ const EventActionButton = (props) => { color = 'secondary' } + if (action === 'postpone' && isPostponed) { + disabled = true + } + const button = {showTermsCheckbox && diff --git a/src/components/EventGrid/index.js b/src/components/EventGrid/index.js index 902f162e2..f95f5d936 100644 --- a/src/components/EventGrid/index.js +++ b/src/components/EventGrid/index.js @@ -6,6 +6,7 @@ import PropTypes from 'prop-types' import {FormattedMessage} from 'react-intl' import get from 'lodash/get' import forEach from 'lodash/forEach' +import {getBadge} from '../../utils/helpers' import defaultThumbnail from '../../assets/images/helsinki-coat-of-arms-white.png' @@ -68,18 +69,20 @@ const EventItem = (props) => { backgroundImage: 'url(' + image + ')', } const getDay = props.event.start_time - const date = getDay.split('T') - const convertedDate = date[0].split('-').reverse().join('.') + let convertedDate = '' + if (getDay) { + const date = getDay.split('T') + convertedDate = date[0].split('-').reverse().join('.') + } const isCancelled = props.event.event_status === constants.EVENT_STATUS.CANCELLED + const isPostponed = props.event.event_status === constants.EVENT_STATUS.POSTPONED return (
- { - isCancelled && - - } + {isCancelled && getBadge('cancelled')} + {isPostponed && getBadge('postponed')}
{convertedDate} diff --git a/src/components/EventTable/CellTypes/NameCell.js b/src/components/EventTable/CellTypes/NameCell.js index 2cf69a916..33d210d34 100644 --- a/src/components/EventTable/CellTypes/NameCell.js +++ b/src/components/EventTable/CellTypes/NameCell.js @@ -11,6 +11,7 @@ const NameCell = props => { const {event, nestLevel, isSuperEvent, superEventType, hasSubEvents, showSubEvents, toggleSubEvent} = props const draft = event.publication_status === constants.PUBLICATION_STATUS.DRAFT const cancelled = event.event_status === constants.EVENT_STATUS.CANCELLED + const postponed = event.event_status === constants.EVENT_STATUS.POSTPONED const name = getEventName(event) const indentationStyle = { paddingLeft: `${nestLevel * 24}px`, @@ -28,6 +29,7 @@ const NameCell = props => { {showSubEvents ? : } } + {postponed && getBadge('postponed')} {cancelled && getBadge('cancelled')} {draft && getBadge('draft')} {isSuperEvent && superEventType === constants.SUPER_EVENT_TYPE_UMBRELLA && diff --git a/src/components/FormFields/index.js b/src/components/FormFields/index.js index 87b40e803..6509f3f5e 100644 --- a/src/components/FormFields/index.js +++ b/src/components/FormFields/index.js @@ -368,6 +368,7 @@ class FormFields extends React.Component {

+

diff --git a/src/components/HelFormFields/HelKeywordSelector/HelKeywordSelector.js b/src/components/HelFormFields/HelKeywordSelector/HelKeywordSelector.js index 19da92d38..2224ea4ff 100644 --- a/src/components/HelFormFields/HelKeywordSelector/HelKeywordSelector.js +++ b/src/components/HelFormFields/HelKeywordSelector/HelKeywordSelector.js @@ -54,12 +54,20 @@ const HelKeywordSelector = ({intl, editor, setDirtyState, setData}) => { const {values, keywordSets, validationErrors} = editor const keywords = get(values, 'keywords', []) const mainCategoryOptions = mapKeywordSetToForm(keywordSets, 'helsinki:topics') + // Internet location automatically implies "remote participation" + const remoteParticipationKeyword = mainCategoryOptions.find(keyword => keyword['value'].includes('yso:p26626')) + if (remoteParticipationKeyword + && values['location'] + && values['location']['id'] == 'helsinki:internet' + && !keywords.find(keyword => keyword['value'].includes('yso:p26626'))) { + keywords.push(remoteParticipationKeyword) + } return ( } - selectedValues={values['keywords']} + selectedValues={keywords} name="keywords" validationErrors={validationErrors['keywords']} itemClassName="col-md-12 col-lg-6" diff --git a/src/components/HelFormFields/HelSelect.js b/src/components/HelFormFields/HelSelect.js index 0ba821e82..ef50d0ff3 100644 --- a/src/components/HelFormFields/HelSelect.js +++ b/src/components/HelFormFields/HelSelect.js @@ -146,6 +146,11 @@ const HelSelect = ({ ) + const filterOptions = (candidate, input) => { + // no need to filter data returned by the api, text filter might have matched to non-displayed fields + return true + } + return ( @@ -160,7 +165,7 @@ const HelSelect = ({ placeholder={intl.formatMessage({id: placeholderId})} loadingMessage={() => intl.formatMessage({id: 'loading'})} noOptionsMessage={() => intl.formatMessage({id: 'search-no-results'})} - filterOption={createFilter({ignoreAccents: false})} + filterOption={filterOptions} formatOptionLabel={formatOption} styles={HelSelectStyles} theme={HelSelectTheme} diff --git a/src/components/ImagePicker/__snapshots__/ImagePicker.test.js.snap b/src/components/ImagePicker/__snapshots__/ImagePicker.test.js.snap index 29e2a4c72..60ee7b33c 100644 --- a/src/components/ImagePicker/__snapshots__/ImagePicker.test.js.snap +++ b/src/components/ImagePicker/__snapshots__/ImagePicker.test.js.snap @@ -25,9 +25,12 @@ exports[`Image add form ImagePicker component should render correctly with data "confirm": "Suorita", "confirm-action-header": "Varmista toiminto", "confirm-cancel": "Varmista tapahtuman peruminen", + "confirm-cancel-extra": "Muistathan, että perumisen sijaan voit myös järjestää tapahtuman etänä internetissä. Valitse tällöin muokkauslomakkeella tapahtumapaikaksi Internet. Voit myös lykätä tapahtuman tulevaisuuteen.", "confirm-delete": "Varmista tapahtuman poistaminen", "confirm-delete-draft": "Varmista luonnoksen poistaminen", "confirm-image-delete": "Varmista kuvan poistaminen", + "confirm-postpone": "Varmista tapahtuman lykkääminen", + "confirm-postpone-draft": "Varmista luonnostapahtuman lykkääminen", "confirm-publish": "Varmista tapahtuman julkaiseminen", "confirm-publish-draft": "Varmista luonnoksen julkaiseminen", "confirm-update": "Varmista tapahtuman tallentaminen", @@ -52,11 +55,13 @@ exports[`Image add form ImagePicker component should render correctly with data "edit-selected-image": "Muokkaa valittua kuvaa", "editor-authorization-required": "Jos haluat julkaista tapahtuman, kirjaudu ensin sisään.", "editor-cancel-extra-warning": "Seuraavat tapahtumat peruutetaan:", - "editor-cancel-warning": "VAROITUS: Tämä toiminto peruuttaa tapahtuman. Voit myös poistaa sellaisen tapahtuman, jonka syötit vahingossa.", + "editor-cancel-warning": "VAROITUS: Tämä toiminto peruuttaa tapahtuman. Voit myös lykätä tapahtuman tulevaisuuteen, tai poistaa sellaisen tapahtuman, jonka syötit vahingossa.", "editor-delete-draft-extra-warning": "Seuraavat tapahtumat poistetaan:", "editor-delete-draft-warning": "VAROITUS: Tämä toiminto poistaa tapahtuman lopullisesti. Voit tarvittaessa myös pyytää, että tapahtumaehdotuksen tekijä muokkaa ilmoitustaan.", "editor-delete-extra-warning": "Seuraavat tapahtumat poistetaan:", "editor-delete-warning": "VAROITUS: Tämä toiminto poistaa tapahtuman lopullisesti. Voit tarvittaessa myös perua tapahtuman tai lykätä sitä.", + "editor-postpone-extra-warning": "Seuraavat tapahtumat lykätään:", + "editor-postpone-warning": "VAROITUS: Tämä toiminto lykkää tapahtuman tulevaisuuteen. Lykättyäsi voit myöhemmin syöttää tapahtumalle uuden ajankohdan.", "editor-publish-draft-extra-warning": "Seuraavat tapahtumat julkaistaan:", "editor-publish-draft-warning": "HUOM. Tämä toiminto julkaisee tapahtuman Internetiin. Tapahtumaehdotuksen alkuperäinen tekijä ei voi enää muokata tapahtumaa.", "editor-sentinel-alert": "Voit katsella lomaketta, mutta sinulla ei ole oikeuksia julkaista tai muokata tapahtumia. Et ole kirjautunut sisään tai kirjautumisesi on vanhentunut.", @@ -66,6 +71,7 @@ exports[`Image add form ImagePicker component should render correctly with data "editor-tip-keywords": "Liitä tapahtumaan vähintään yksi asiasana, joka kuvaa tapahtuman teemaa. Aloita kirjoittamaan asiasanaa ja valitse lisättävä asiasana alle ilmestyvästä listasta.", "editor-tip-location": "Kirjoita kenttään tapahtumapaikan nimi tai katuosoite ja valitse oikea paikka listasta.", "editor-tip-location-extra": "Jos tapahtumapaikka löytyy listasta, sen sijaintia ei tarvitse kuvailla erikseen. Voit kuitenkin antaa lisätietoja tapahtumapaikan löytämiseksi, esimerkiksi kerrosnumeron tai luokkahuoneen nimen.", + "editor-tip-location-internet": "Jos tapahtuma järjestetään vain etänä internetissä, valitse tapahtumapaikaksi Internet. Tapahtuman URL-osoite laitetaan kotisivu-kenttään ja/tai tapahtuma sosiaalisessa mediassa -kenttiin.", "editor-tip-location-not-found": "Jos tarkkaa tapahtumapaikkaa ei löydy listasta, valitse tapahtumapaikaksi lähin katuosoite ja kirjoita paikan nimi tai muut tarkemmat saapumisohjeet tiiviisti lisätietokenttään.", "editor-tip-price": "Merkitse onko tapahtuma maksuton. Syötä maksulliselle tapahtumalle hinta muodossa \\"5€\\".", "editor-tip-price-multi": "Jos tapahtumalla on useita hintoja, klikkaa Lisää uusi hintatieto ja merkitse kunkin hintaryhmän nimi (esim. Lapset) Hintatietojen kuvaus -kenttään.", @@ -225,6 +231,8 @@ exports[`Image add form ImagePicker component should render correctly with data "photographer": "Kuvaaja", "pick-time-range": "Etsi vain ajalta", "play-date-label": "Toistopäivät", + "postpone-events": "Lykkää tapahtumaa", + "postponed": "Lykätty", "publish-events": "Julkaise tapahtuma", "publish-events-multi": "Julkaise tapahtumat", "ready": "Valmis", @@ -282,10 +290,11 @@ exports[`Image add form ImagePicker component should render correctly with data "validation-atLeastOneIsTrue": "Valitse vähintään yksi toistopäivä", "validation-atLeastOneMainCategory": "Valitse vähintään yksi pääkategoria", "validation-daysWithinInterval": "Yksi tai useampi valituista päivistä ei esiinny toistovälillä", + "validation-defaultEndInTheFuture": "Alkamisajan pitää olla tulevaisuudessa, jos päättymisaikaa ei tunneta", "validation-error": "Lomakkeessa on virheitä. Tarkasta lomake.", "validation-error-goto-error": "Siirry virheeseen", "validation-hasPrice": "Hintatietoja puuttuu", - "validation-inTheFuture": "Tapahtuman pitää olla tulevaisuudessa", + "validation-inTheFuture": "Päättymisajan pitää olla tulevaisuudessa", "validation-isDate": "Kirjoita päivämäärä muodossa pp.kk.vvvv hh.mm", "validation-isInt": "Tulon on oltava numero", "validation-isMoreThanOne": "Toistovälin tulee olla vähintään 1 viikko", diff --git a/src/i18n/en.json b/src/i18n/en.json index 863460c3e..deca9664f 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -31,11 +31,15 @@ "confirm-delete": "Delete event", "confirm-delete-draft": "Delete draft", "confirm-cancel": "Cancel event", + "confirm-cancel-extra": "Instead of canceling, you may also organize the event online on the internet. In such a case, edit the event and pick the location Internet in the location menu. You may also postpone the event.", "confirm-publish": "Publish event", "confirm-publish-draft": "Publish draft", + "confirm-postpone": "Postpone event", + "confirm-postpone-draft": "Postpone draft", "delete": "Delete", "confirm": "Confirm", "draft": "Draft", + "postponed": "Postponed", "cancelled": "Cancelled", "series": "Series", "umbrella": "Umbrella", @@ -191,6 +195,7 @@ "validation-requiredAtId": "This field is required", "validation-requiredString": "This field is required", "validation-requiredStringForCourses": "This field is required", + "validation-defaultEndInTheFuture": "The start time must be in the future if end time is not specified", "validation-afterStartTime": "The end time must be later than start time", "validation-afterStartTimeAndInFuture": "The end time must be in the future and later than the start time", "validation-afterEnrolmentStartTime": "The end time must be later than start time", @@ -277,6 +282,7 @@ "editor-tip-time-multi": "If the event is held more than once, you can add new times to the event. If the event repeats regularly, you can add all times at once by selecting Recurring event.", "editor-tip-time-delete": "To delete an extra time, select the trash bin next to the time.", "editor-tip-location": "Start typing the beginning of the name of the venue and then choose the correct place from the emerging list.", + "editor-tip-location-internet": "If the event is strictly online on the internet, pick Internet as the location. The URL of the event should be filled in the event home page field and/or the social media URL fields.", "editor-tip-location-extra": "If an event location is found in the list, the address and location doesn't need not be described more closely. However, you can add more information to find the event, such as a floor number or other more accurate location.", "editor-tip-location-not-found": "If you can not find a venue from the list, choose Helsinki as your venue and enter a more detailed place or address in the additional information box.", "editor-tip-price": "Check if the event is free of charge. If there is a fee enter it like \"5€\".", diff --git a/src/i18n/fi.json b/src/i18n/fi.json index fd351511f..e25bb770c 100644 --- a/src/i18n/fi.json +++ b/src/i18n/fi.json @@ -21,6 +21,7 @@ "update-events": "Tallenna", "delete-events": "Poista tapahtuma", "cancel-events": "Peruuta tapahtuma", + "postpone-events": "Lykkää tapahtumaa", "publish-events": "Julkaise tapahtuma", "delete-events-multi": "Poista tapahtumat", "publish-events-multi": "Julkaise tapahtumat", @@ -31,11 +32,15 @@ "confirm-delete": "Varmista tapahtuman poistaminen", "confirm-delete-draft": "Varmista luonnoksen poistaminen", "confirm-cancel": "Varmista tapahtuman peruminen", + "confirm-cancel-extra": "Muistathan, että perumisen sijaan voit myös järjestää tapahtuman etänä internetissä. Valitse tällöin muokkauslomakkeella tapahtumapaikaksi Internet. Voit myös lykätä tapahtuman tulevaisuuteen.", "confirm-publish": "Varmista tapahtuman julkaiseminen", "confirm-publish-draft": "Varmista luonnoksen julkaiseminen", + "confirm-postpone": "Varmista tapahtuman lykkääminen", + "confirm-postpone-draft": "Varmista luonnostapahtuman lykkääminen", "delete": "Poista", "confirm": "Suorita", "draft": "Luonnos", + "postponed": "Lykätty", "cancelled": "Peruutettu", "series": "Sarja", "umbrella": "Kattotapahtuma", @@ -194,7 +199,8 @@ "validation-afterStartTime": "Päättymisajan pitää olla alkamisaikaa myöhemmin", "validation-afterStartTimeAndInFuture": "Päättymisajan pitää olla tulevaisuudessa ja alkamisaikaa myöhemmin", "validation-afterEnrolmentStartTime": "Päättymisajan pitää olla alkamisaikaa myöhemmin", - "validation-inTheFuture": "Tapahtuman pitää olla tulevaisuudessa", + "validation-defaultEndInTheFuture": "Alkamisajan pitää olla tulevaisuudessa, jos päättymisaikaa ei tunneta", + "validation-inTheFuture": "Päättymisajan pitää olla tulevaisuudessa", "validation-stringLimitReached": "Tämä kenttä voi olla korkeintaan {limit} merkkiä pitkä", "validation-stringLengthCounter": "{counter} merkkiä jäljellä", "validation-longStringLengthCounter": " merkkiä käytetty", @@ -261,9 +267,12 @@ "editor-update-draft-extra-warning": "Tiedot tallennetaan seuraaviin tapahtumiin:", "editor-update-draft-draft-extra-warning": "Tiedot tallennetaan seuraaviin tapahtumiin:", - "editor-cancel-warning": "VAROITUS: Tämä toiminto peruuttaa tapahtuman. Voit myös poistaa sellaisen tapahtuman, jonka syötit vahingossa.", + "editor-cancel-warning": "VAROITUS: Tämä toiminto peruuttaa tapahtuman. Voit myös lykätä tapahtuman tulevaisuuteen, tai poistaa sellaisen tapahtuman, jonka syötit vahingossa.", "editor-cancel-extra-warning": "Seuraavat tapahtumat peruutetaan:", + "editor-postpone-warning": "VAROITUS: Tämä toiminto lykkää tapahtuman tulevaisuuteen. Lykättyäsi voit myöhemmin syöttää tapahtumalle uuden ajankohdan.", + "editor-postpone-extra-warning": "Seuraavat tapahtumat lykätään:", + "editor-delete-warning": "VAROITUS: Tämä toiminto poistaa tapahtuman lopullisesti. Voit tarvittaessa myös perua tapahtuman tai lykätä sitä.", "editor-delete-extra-warning": "Seuraavat tapahtumat poistetaan:", "editor-delete-draft-warning": "VAROITUS: Tämä toiminto poistaa tapahtuman lopullisesti. Voit tarvittaessa myös pyytää, että tapahtumaehdotuksen tekijä muokkaa ilmoitustaan.", @@ -277,6 +286,7 @@ "editor-tip-time-multi": "Jos tapahtuma järjestetään useamman kerran, voit lisätä tapahtumalle uusia ajankohtia. Jos tapahtuma toistuu säännöllisesti, voit lisätä kaikki ajankohdat kerralla valitsemalla Toistuva tapahtuma.", "editor-tip-time-delete": "Ylimääräisen ajankohdan voit poistaa valitsemalla ajankohdan vieressä olevan roskakorisymbolin.", "editor-tip-location": "Kirjoita kenttään tapahtumapaikan nimi tai katuosoite ja valitse oikea paikka listasta.", + "editor-tip-location-internet": "Jos tapahtuma järjestetään vain etänä internetissä, valitse tapahtumapaikaksi Internet. Tapahtuman URL-osoite laitetaan kotisivu-kenttään ja/tai tapahtuma sosiaalisessa mediassa -kenttiin.", "editor-tip-location-extra": "Jos tapahtumapaikka löytyy listasta, sen sijaintia ei tarvitse kuvailla erikseen. Voit kuitenkin antaa lisätietoja tapahtumapaikan löytämiseksi, esimerkiksi kerrosnumeron tai luokkahuoneen nimen.", "editor-tip-location-not-found": "Jos tarkkaa tapahtumapaikkaa ei löydy listasta, valitse tapahtumapaikaksi lähin katuosoite ja kirjoita paikan nimi tai muut tarkemmat saapumisohjeet tiiviisti lisätietokenttään.", "editor-tip-price": "Merkitse onko tapahtuma maksuton. Syötä maksulliselle tapahtumalle hinta muodossa \"5€\".", diff --git a/src/utils/checkEventEditability.js b/src/utils/checkEventEditability.js index 8ea8080dc..0aae4058a 100644 --- a/src/utils/checkEventEditability.js +++ b/src/utils/checkEventEditability.js @@ -11,7 +11,7 @@ const {PUBLICATION_STATUS, EVENT_STATUS, USER_TYPE, SUPER_EVENT_TYPE_UMBRELLA} = export const userMayEdit = (user, event) => { const adminOrganizations = get(user, 'adminOrganizations') const userOrganization = get(user, 'organization') - const eventOrganization = get(event, 'organization') + const eventOrganization = get(event, 'publisher') const organizationMemberships = get(user, 'organizationMemberships') const publicationStatus = get(event, 'publication_status') const userHasOrganizations = !isNull(getOrganizationMembershipIds(user)) @@ -83,13 +83,35 @@ export const userCanDoAction = (user, event, action, editor) => { return true } +export const eventIsEditable = (event) => { + const eventIsCancelled = get(event, 'event_status') === EVENT_STATUS.CANCELLED + const eventIsDeleted = get(event, 'deleted') + const startTime = get(event, 'start_time', '') + const endTime = get(event, 'end_time', null) + const eventIsInThePast = + (endTime && moment(endTime, moment.defaultFormatUtc).isBefore(moment())) + || (!endTime && moment(startTime, moment.defaultFormatUtc).isBefore(moment().startOf('day'))) + if (eventIsCancelled) { + return {editable: false, explanationId: 'event-canceled'}; + } + if (eventIsDeleted) { + return {editable: false, explanationId: 'event-deleted'}; + } + if (eventIsInThePast) { + return {editable: false, explanationId: 'event-in-the-past'}; + } + return {editable: true, explanationId: ''} +} + export const checkEventEditability = (user, event, action, editor) => { + const eventIsEditable = module.exports.eventIsEditable(event) + if (!eventIsEditable['editable']) { + return eventIsEditable + } + const userMayEdit = module.exports.userMayEdit(user, event) const userCanDoAction = module.exports.userCanDoAction(user, event, action, editor) const isDraft = get(event, 'publication_status') === PUBLICATION_STATUS.DRAFT - const endTime = get(event, 'end_time', '') - const eventIsInThePast = moment(endTime, moment.defaultFormatUtc).isBefore(moment()); - const eventIsCancelled = get(event, 'event_status') === EVENT_STATUS.CANCELLED const isSubEvent = !isUndefined(get(event, ['super_event', '@id'])) const getExplanationId = () => { @@ -102,23 +124,13 @@ export const checkEventEditability = (user, event, action, editor) => { if (!userCanDoAction && action === 'publish') { return 'event-validation-errors' } - if (eventIsInThePast && !isDraft) { - return 'event-in-the-past' - } - if (eventIsCancelled) { - return 'event-canceled' - } if (!userMayEdit || !userCanDoAction) { return 'user-no-rights-edit' } } const explanationId = getExplanationId() - const editable = - (!eventIsInThePast || (eventIsInThePast && isDraft)) - && !eventIsCancelled - && userMayEdit - && userCanDoAction + const editable = userMayEdit && userCanDoAction return {editable, explanationId} } diff --git a/src/utils/confirm.js b/src/utils/confirm.js index 7731a27af..00823fdab 100644 --- a/src/utils/confirm.js +++ b/src/utils/confirm.js @@ -1,5 +1,5 @@ import {getFirstMultiLanguageFieldValue} from './helpers' -import {cancelEvents, deleteEvents, mapSubEventDataToSuperEvents, publishEvents} from './events' +import {postponeEvents, cancelEvents, deleteEvents, mapSubEventDataToSuperEvents, publishEvents} from './events' import constants from '../constants' import moment from 'moment' import {get, isUndefined, isNull, isNil} from 'lodash' @@ -95,12 +95,14 @@ const getEventListing = (subEventsMappedToEvents, events, intl) => /** * Returns the additional markup for the confirmation dialog based on given action type + * @param extraMessage Any extra message that needs to be displayed before other warnings * @param action Either 'update', 'publish', 'delete' or 'cancel' * @param intl React Intl * @param events Possible sub events for the event * @returns {string} Markup for the confirmation dialog */ -const getConfirmationMarkup = (action, intl, events = []) => { +const getConfirmationMarkup = (extraMessage = null, action, intl, events = []) => { + const extraMessageText = extraMessage ? `

${intl.formatMessage({id: extraMessage})}

` : '' const warningText = `

${intl.formatMessage({id: `editor-${action}-warning`})}

` let extraWarningText = intl.formatMessage({id: `editor-${action}-extra-warning`}) extraWarningText = extraWarningText === `editor-${action}-extra-warning` ? '' : `

${extraWarningText}

` @@ -109,8 +111,8 @@ const getConfirmationMarkup = (action, intl, events = []) => { const eventListing = getEventListing(subEventsMappedToEvents, events, intl) return eventListing.length > 0 - ? `${warningText}${extraWarningText}${eventListing}` - : warningText + ? `${extraMessageText}${warningText}${extraWarningText}${eventListing}` + : `${extraMessageText}${warningText}` } /** @@ -132,7 +134,6 @@ const showConfirmationModal = ( publicationStatus = PUBLICATION_STATUS.PUBLIC, customAction, ) => new Promise((resolve) => { - const eventIds = eventData.map(item => item.id) const isDraft = publicationStatus === PUBLICATION_STATUS.DRAFT // set the modal texts based on the action to run @@ -140,6 +141,9 @@ const showConfirmationModal = ( const message = isDraft ? `confirm-${action}-draft` : `confirm-${action}` + const extraMessage = (action === 'cancel') + ? `confirm-cancel-extra` + : null const warningMessage = isDraft ? `${action}-draft` : action @@ -157,11 +161,14 @@ const showConfirmationModal = ( update() { console.warn(`action '${action}' is not implemented!`) }, + postpone() { + resolve(postponeEvents(eventData)) + }, cancel() { resolve(cancelEvents(eventData)) }, delete() { - resolve(deleteEvents(eventIds)) + resolve(deleteEvents(eventData)) }, } @@ -171,7 +178,7 @@ const showConfirmationModal = ( actionButtonLabel, { action: customAction || confirmActionMapping[action], - additionalMarkup: getConfirmationMarkup(warningMessage, intl, eventData), + additionalMarkup: getConfirmationMarkup(extraMessage, warningMessage, intl, eventData), } ) }) diff --git a/src/utils/events.js b/src/utils/events.js index 21f869e6c..71e5c925a 100644 --- a/src/utils/events.js +++ b/src/utils/events.js @@ -3,6 +3,7 @@ import moment from 'moment' import constants from '../constants' import {get, isUndefined, set} from 'lodash' import {getFirstMultiLanguageFieldValue} from './helpers' +import {eventIsEditable} from './checkEventEditability' const {PUBLICATION_STATUS, EVENT_STATUS} = constants @@ -28,9 +29,6 @@ export class EventQueryParams { setSort(sortBy, sortDirection) { this.sort = sortDirection === 'desc' ? `-${sortBy}` : sortBy } - setText(query) { - this.text = encodeURI(query) - } get values() { return Object.keys(this) .filter(key => typeof this[key] !== 'function') @@ -104,9 +102,9 @@ export const publishEvents = async (eventData) => { * @param eventId ID of event that should be deleted * @returns {Promise} */ -export const deleteEvent = async (eventId) => { +export const deleteEvent = async (eventData) => { try { - return await client.delete(`event/${eventId}`) + return await client.delete(`event/${eventData.id}`) } catch (e) { throw Error(e) } @@ -117,7 +115,10 @@ export const deleteEvent = async (eventId) => { * @param eventIds List of ID's that should be deleted * @returns {Promise} */ -export const deleteEvents = async (eventIds) => Promise.all(eventIds.map(deleteEvent)) +export const deleteEvents = async (eventData) => Promise.all(eventData + .filter(event => eventIsEditable(event)['editable']) + .map(deleteEvent) +) /** * Cancels given events @@ -126,6 +127,7 @@ export const deleteEvents = async (eventIds) => Promise.all(eventIds.map(deleteE */ export const cancelEvents = async (eventData) => { const updatedEventData = eventData + .filter(event => eventIsEditable(event)['editable']) .map(event => ({ ...event, event_status: EVENT_STATUS.CANCELLED, @@ -138,6 +140,27 @@ export const cancelEvents = async (eventData) => { } } +/** + * Postpones given events + * @param eventData Data for the events that should be postponed + * @returns {Promise} + */ +export const postponeEvents = async (eventData) => { + const updatedEventData = eventData + .filter(event => eventIsEditable(event)['editable']) + .map(event => ({ + ...event, + start_time: null, + end_time: null, + })) + + try { + return await client.put('event', updatedEventData) + } catch (e) { + throw Error(e) + } +} + /** * Returns the data for the given ID's * @param ids ID's that the data is filtered based on diff --git a/src/utils/formDataMapping.js b/src/utils/formDataMapping.js index 7c8563699..9fc06ba0a 100644 --- a/src/utils/formDataMapping.js +++ b/src/utils/formDataMapping.js @@ -2,6 +2,7 @@ import {find, map, forOwn, isEmpty, values, set} from 'lodash' import constants from 'src/constants.js' import moment from 'moment-timezone' import {getStringWithLocale} from './locale' +import {eventIsEditable} from './checkEventEditability' export { mapUIDataToAPIFormat, @@ -299,7 +300,7 @@ export const updateSubEventsFromFormValues = (formValues, subEventsToUpdate) => const keysToUpdate = ['start_time', 'end_time', 'id', 'super_event', 'super_event_type'] // update form data with sub event data where applicable return subEventsToUpdate - // don't update canceled events - .filter(subEvent => subEvent.event_status !== EVENT_STATUS.CANCELLED) + // don't update canceled, deleted or past subevents (when editing an ongoing series =) + .filter(subEvent => eventIsEditable(subEvent)['editable']) .map(subEvent => keysToUpdate.reduce((acc, key) => set(acc, key, subEvent[key]), {...formValues})) } diff --git a/src/utils/helpers.js b/src/utils/helpers.js index fe9d99d35..b613edc35 100644 --- a/src/utils/helpers.js +++ b/src/utils/helpers.js @@ -153,6 +153,10 @@ export const getBadge = (type, size = 'small') => { backgroundColor: helBrandColors.summer.main, color: helBrandColors.gray.black90, }, + '&.postponed': { + backgroundColor: helBrandColors.fog.main, + color: helBrandColors.gray.black90, + }, }, sizeSmall: { '&.badge-chip': { diff --git a/src/validation/validationRules.js b/src/validation/validationRules.js index 252eddfb2..44711cda0 100644 --- a/src/validation/validationRules.js +++ b/src/validation/validationRules.js @@ -130,7 +130,9 @@ var validations = { return validations.matchRegexp(values, value, /(24((:|\.)00)?)|^((2[0-3]|1[0-9]|0[0-9]|[0-9])((:|\.)[0-5][0-9])?)$/i); }, isDate(values, value) { - return moment(value, moment.ISO_8601, true).isValid() + // Emtpy string needs to match, to allow empty *or* valid date. + // Required (non-empty) fields are validated separately. + return !value | moment(value, moment.ISO_8601, true).isValid() }, afterStartTime: function afterStartTime(values, value) { if (!values.start_time || !value) return true diff --git a/src/validation/validator.js b/src/validation/validator.js index 4441b6365..aa97534ae 100644 --- a/src/validation/validator.js +++ b/src/validation/validator.js @@ -39,8 +39,8 @@ const draftValidations = { const publicValidations = { name: [VALIDATION_RULES.REQUIRE_MULTI, VALIDATION_RULES.REQUIRED_IN_CONTENT_LANGUAGE], location: [VALIDATION_RULES.REQUIRE_AT_ID], - start_time: [VALIDATION_RULES.REQUIRED_STRING, VALIDATION_RULES.IS_DATE], // Datetime is saved as ISO string - end_time: [VALIDATION_RULES.AFTER_START_TIME, VALIDATION_RULES.IN_THE_FUTURE], + start_time: [VALIDATION_RULES.REQUIRED_STRING, VALIDATION_RULES.IS_DATE, VALIDATION_RULES.DEFAULT_END_IN_FUTURE], // Datetime is saved as ISO string + end_time: [VALIDATION_RULES.AFTER_START_TIME, VALIDATION_RULES.IS_DATE, VALIDATION_RULES.IN_THE_FUTURE], price: [VALIDATION_RULES.HAS_PRICE], short_description: [VALIDATION_RULES.REQUIRE_MULTI, VALIDATION_RULES.REQUIRED_IN_CONTENT_LANGUAGE, VALIDATION_RULES.SHORT_STRING], description: [VALIDATION_RULES.REQUIRE_MULTI, VALIDATION_RULES.REQUIRED_IN_CONTENT_LANGUAGE, VALIDATION_RULES.LONG_STRING], @@ -49,8 +49,8 @@ const publicValidations = { extlink_twitter: [VALIDATION_RULES.IS_URL], extlink_instagram: [VALIDATION_RULES.IS_URL], sub_events: { - start_time: [VALIDATION_RULES.REQUIRED_STRING, VALIDATION_RULES.IS_DATE], - end_time: [VALIDATION_RULES.AFTER_START_TIME, VALIDATION_RULES.IN_THE_FUTURE], + start_time: [VALIDATION_RULES.REQUIRED_STRING, VALIDATION_RULES.IS_DATE, VALIDATION_RULES.DEFAULT_END_IN_FUTURE], + end_time: [VALIDATION_RULES.AFTER_START_TIME, VALIDATION_RULES.IS_DATE, VALIDATION_RULES.IN_THE_FUTURE], }, keywords: [VALIDATION_RULES.AT_LEAST_ONE_MAIN_CATEGORY], audience_min_age: [VALIDATION_RULES.IS_INT], diff --git a/src/views/App/index.js b/src/views/App/index.js index 142fca8ef..9ef5e717e 100644 --- a/src/views/App/index.js +++ b/src/views/App/index.js @@ -119,10 +119,11 @@ class App extends React.Component { >

Tervetuloa käyttämään Linked Eventsiä, {this.props.user.displayName}!

Sinulla ei ole vielä oikeutta hallinnoida yhdenkään yksikön tapahtumia. - Ota yhteyttä Aleksi Saloseen saadaksesi oikeudet - muokata yksikkösi tapahtumia.

+ Ota yhteyttä Paavo Jantuseen saadaksesi oikeudet + muokata yksikkösi tapahtumia.

Jos olet jo saanut käyttöoikeudet, kirjautumisesi saattaa olla vanhentunut. Kokeile sivun - päivittämistä (F5) ja kirjautumista uudestaan.

+ päivittämistä (F5) ja kirjautumista uudestaan.

+

Helsinki Marketingin yhteistyökumppanit: Toni Uuttu

} } diff --git a/src/views/Editor/index.js b/src/views/Editor/index.js index be9e4824b..ac50d0697 100644 --- a/src/views/Editor/index.js +++ b/src/views/Editor/index.js @@ -301,6 +301,7 @@ export class EditorPage extends React.Component { {loading ? :
+ {editMode === 'update' && this.getActionButton('postpone')} {editMode === 'update' && this.getActionButton('cancel')} {editMode === 'update' && this.getActionButton('delete')} {isDraft && hasOrganizationWithRegularUsers(user) && diff --git a/src/views/Editor/index.scss b/src/views/Editor/index.scss index 6b4b31d02..eefb5d9bc 100644 --- a/src/views/Editor/index.scss +++ b/src/views/Editor/index.scss @@ -66,6 +66,10 @@ $actionBtnHeight: 60px; color: #373a3c; } + strong { + font-weight: bold; + } + &.padded { padding-top: 66px; } diff --git a/src/views/Event/index.js b/src/views/Event/index.js index 02682a09d..d17bf468a 100644 --- a/src/views/Event/index.js +++ b/src/views/Event/index.js @@ -151,11 +151,13 @@ class EventPage extends React.Component { const isAdmin = userType === USER_TYPE.ADMIN const editEventButton = this.getActionButton('edit', this.openEventInEditor, false) const publishEventButton = this.getActionButton('publish') + const postponeEventButton = this.getActionButton('postpone') const cancelEventButton = this.getActionButton('cancel') const deleteEventButton = this.getActionButton('delete') return
+ {postponeEventButton} {cancelEventButton} {deleteEventButton}
@@ -206,8 +208,8 @@ class EventPage extends React.Component { routerPush('/') } } - // re-fetch event data after cancel or publish action - if (action === 'cancel' || action === 'publish') { + // re-fetch event data after cancel, postpone or publish action + if (action === 'cancel' || action === 'publish' || action === 'postpone') { this.fetchEventData() } } @@ -221,6 +223,7 @@ class EventPage extends React.Component { const isRecurringEvent = event.super_event_type === SUPER_EVENT_TYPE_RECURRING const isDraft = event.publication_status === PUBLICATION_STATUS.DRAFT const isCancelled = event.event_status === EVENT_STATUS.CANCELLED + const isPostponed = event.event_status === EVENT_STATUS.POSTPONED const publishedText = this.getPublishedText(); return ( @@ -234,6 +237,7 @@ class EventPage extends React.Component { {!loading &&

+ {isPostponed && getBadge('postponed', 'medium')} {isCancelled && getBadge('cancelled', 'medium')} {isDraft && getBadge('draft', 'medium')} {isUmbrellaEvent && getBadge('umbrella', 'medium')} diff --git a/src/views/EventListing/__snapshots__/EventListing.test.js.snap b/src/views/EventListing/__snapshots__/EventListing.test.js.snap index 9f6703386..a74dea738 100644 --- a/src/views/EventListing/__snapshots__/EventListing.test.js.snap +++ b/src/views/EventListing/__snapshots__/EventListing.test.js.snap @@ -72,9 +72,12 @@ exports[`EventListing Snapshot should render view correctly 1`] = ` "confirm": "Suorita", "confirm-action-header": "Varmista toiminto", "confirm-cancel": "Varmista tapahtuman peruminen", + "confirm-cancel-extra": "Muistathan, että perumisen sijaan voit myös järjestää tapahtuman etänä internetissä. Valitse tällöin muokkauslomakkeella tapahtumapaikaksi Internet. Voit myös lykätä tapahtuman tulevaisuuteen.", "confirm-delete": "Varmista tapahtuman poistaminen", "confirm-delete-draft": "Varmista luonnoksen poistaminen", "confirm-image-delete": "Varmista kuvan poistaminen", + "confirm-postpone": "Varmista tapahtuman lykkääminen", + "confirm-postpone-draft": "Varmista luonnostapahtuman lykkääminen", "confirm-publish": "Varmista tapahtuman julkaiseminen", "confirm-publish-draft": "Varmista luonnoksen julkaiseminen", "confirm-update": "Varmista tapahtuman tallentaminen", @@ -99,11 +102,13 @@ exports[`EventListing Snapshot should render view correctly 1`] = ` "edit-selected-image": "Muokkaa valittua kuvaa", "editor-authorization-required": "Jos haluat julkaista tapahtuman, kirjaudu ensin sisään.", "editor-cancel-extra-warning": "Seuraavat tapahtumat peruutetaan:", - "editor-cancel-warning": "VAROITUS: Tämä toiminto peruuttaa tapahtuman. Voit myös poistaa sellaisen tapahtuman, jonka syötit vahingossa.", + "editor-cancel-warning": "VAROITUS: Tämä toiminto peruuttaa tapahtuman. Voit myös lykätä tapahtuman tulevaisuuteen, tai poistaa sellaisen tapahtuman, jonka syötit vahingossa.", "editor-delete-draft-extra-warning": "Seuraavat tapahtumat poistetaan:", "editor-delete-draft-warning": "VAROITUS: Tämä toiminto poistaa tapahtuman lopullisesti. Voit tarvittaessa myös pyytää, että tapahtumaehdotuksen tekijä muokkaa ilmoitustaan.", "editor-delete-extra-warning": "Seuraavat tapahtumat poistetaan:", "editor-delete-warning": "VAROITUS: Tämä toiminto poistaa tapahtuman lopullisesti. Voit tarvittaessa myös perua tapahtuman tai lykätä sitä.", + "editor-postpone-extra-warning": "Seuraavat tapahtumat lykätään:", + "editor-postpone-warning": "VAROITUS: Tämä toiminto lykkää tapahtuman tulevaisuuteen. Lykättyäsi voit myöhemmin syöttää tapahtumalle uuden ajankohdan.", "editor-publish-draft-extra-warning": "Seuraavat tapahtumat julkaistaan:", "editor-publish-draft-warning": "HUOM. Tämä toiminto julkaisee tapahtuman Internetiin. Tapahtumaehdotuksen alkuperäinen tekijä ei voi enää muokata tapahtumaa.", "editor-sentinel-alert": "Voit katsella lomaketta, mutta sinulla ei ole oikeuksia julkaista tai muokata tapahtumia. Et ole kirjautunut sisään tai kirjautumisesi on vanhentunut.", @@ -113,6 +118,7 @@ exports[`EventListing Snapshot should render view correctly 1`] = ` "editor-tip-keywords": "Liitä tapahtumaan vähintään yksi asiasana, joka kuvaa tapahtuman teemaa. Aloita kirjoittamaan asiasanaa ja valitse lisättävä asiasana alle ilmestyvästä listasta.", "editor-tip-location": "Kirjoita kenttään tapahtumapaikan nimi tai katuosoite ja valitse oikea paikka listasta.", "editor-tip-location-extra": "Jos tapahtumapaikka löytyy listasta, sen sijaintia ei tarvitse kuvailla erikseen. Voit kuitenkin antaa lisätietoja tapahtumapaikan löytämiseksi, esimerkiksi kerrosnumeron tai luokkahuoneen nimen.", + "editor-tip-location-internet": "Jos tapahtuma järjestetään vain etänä internetissä, valitse tapahtumapaikaksi Internet. Tapahtuman URL-osoite laitetaan kotisivu-kenttään ja/tai tapahtuma sosiaalisessa mediassa -kenttiin.", "editor-tip-location-not-found": "Jos tarkkaa tapahtumapaikkaa ei löydy listasta, valitse tapahtumapaikaksi lähin katuosoite ja kirjoita paikan nimi tai muut tarkemmat saapumisohjeet tiiviisti lisätietokenttään.", "editor-tip-price": "Merkitse onko tapahtuma maksuton. Syötä maksulliselle tapahtumalle hinta muodossa \\"5€\\".", "editor-tip-price-multi": "Jos tapahtumalla on useita hintoja, klikkaa Lisää uusi hintatieto ja merkitse kunkin hintaryhmän nimi (esim. Lapset) Hintatietojen kuvaus -kenttään.", @@ -272,6 +278,8 @@ exports[`EventListing Snapshot should render view correctly 1`] = ` "photographer": "Kuvaaja", "pick-time-range": "Etsi vain ajalta", "play-date-label": "Toistopäivät", + "postpone-events": "Lykkää tapahtumaa", + "postponed": "Lykätty", "publish-events": "Julkaise tapahtuma", "publish-events-multi": "Julkaise tapahtumat", "ready": "Valmis", @@ -329,10 +337,11 @@ exports[`EventListing Snapshot should render view correctly 1`] = ` "validation-atLeastOneIsTrue": "Valitse vähintään yksi toistopäivä", "validation-atLeastOneMainCategory": "Valitse vähintään yksi pääkategoria", "validation-daysWithinInterval": "Yksi tai useampi valituista päivistä ei esiinny toistovälillä", + "validation-defaultEndInTheFuture": "Alkamisajan pitää olla tulevaisuudessa, jos päättymisaikaa ei tunneta", "validation-error": "Lomakkeessa on virheitä. Tarkasta lomake.", "validation-error-goto-error": "Siirry virheeseen", "validation-hasPrice": "Hintatietoja puuttuu", - "validation-inTheFuture": "Tapahtuman pitää olla tulevaisuudessa", + "validation-inTheFuture": "Päättymisajan pitää olla tulevaisuudessa", "validation-isDate": "Kirjoita päivämäärä muodossa pp.kk.vvvv hh.mm", "validation-isInt": "Tulon on oltava numero", "validation-isMoreThanOne": "Toistovälin tulee olla vähintään 1 viikko", diff --git a/src/views/Search/__snapshots__/Search.test.js.snap b/src/views/Search/__snapshots__/Search.test.js.snap index 0adae2455..a4415d734 100644 --- a/src/views/Search/__snapshots__/Search.test.js.snap +++ b/src/views/Search/__snapshots__/Search.test.js.snap @@ -25,9 +25,12 @@ exports[`Search Snapshot should render view correctly 1`] = ` "confirm": "Suorita", "confirm-action-header": "Varmista toiminto", "confirm-cancel": "Varmista tapahtuman peruminen", + "confirm-cancel-extra": "Muistathan, että perumisen sijaan voit myös järjestää tapahtuman etänä internetissä. Valitse tällöin muokkauslomakkeella tapahtumapaikaksi Internet. Voit myös lykätä tapahtuman tulevaisuuteen.", "confirm-delete": "Varmista tapahtuman poistaminen", "confirm-delete-draft": "Varmista luonnoksen poistaminen", "confirm-image-delete": "Varmista kuvan poistaminen", + "confirm-postpone": "Varmista tapahtuman lykkääminen", + "confirm-postpone-draft": "Varmista luonnostapahtuman lykkääminen", "confirm-publish": "Varmista tapahtuman julkaiseminen", "confirm-publish-draft": "Varmista luonnoksen julkaiseminen", "confirm-update": "Varmista tapahtuman tallentaminen", @@ -52,11 +55,13 @@ exports[`Search Snapshot should render view correctly 1`] = ` "edit-selected-image": "Muokkaa valittua kuvaa", "editor-authorization-required": "Jos haluat julkaista tapahtuman, kirjaudu ensin sisään.", "editor-cancel-extra-warning": "Seuraavat tapahtumat peruutetaan:", - "editor-cancel-warning": "VAROITUS: Tämä toiminto peruuttaa tapahtuman. Voit myös poistaa sellaisen tapahtuman, jonka syötit vahingossa.", + "editor-cancel-warning": "VAROITUS: Tämä toiminto peruuttaa tapahtuman. Voit myös lykätä tapahtuman tulevaisuuteen, tai poistaa sellaisen tapahtuman, jonka syötit vahingossa.", "editor-delete-draft-extra-warning": "Seuraavat tapahtumat poistetaan:", "editor-delete-draft-warning": "VAROITUS: Tämä toiminto poistaa tapahtuman lopullisesti. Voit tarvittaessa myös pyytää, että tapahtumaehdotuksen tekijä muokkaa ilmoitustaan.", "editor-delete-extra-warning": "Seuraavat tapahtumat poistetaan:", "editor-delete-warning": "VAROITUS: Tämä toiminto poistaa tapahtuman lopullisesti. Voit tarvittaessa myös perua tapahtuman tai lykätä sitä.", + "editor-postpone-extra-warning": "Seuraavat tapahtumat lykätään:", + "editor-postpone-warning": "VAROITUS: Tämä toiminto lykkää tapahtuman tulevaisuuteen. Lykättyäsi voit myöhemmin syöttää tapahtumalle uuden ajankohdan.", "editor-publish-draft-extra-warning": "Seuraavat tapahtumat julkaistaan:", "editor-publish-draft-warning": "HUOM. Tämä toiminto julkaisee tapahtuman Internetiin. Tapahtumaehdotuksen alkuperäinen tekijä ei voi enää muokata tapahtumaa.", "editor-sentinel-alert": "Voit katsella lomaketta, mutta sinulla ei ole oikeuksia julkaista tai muokata tapahtumia. Et ole kirjautunut sisään tai kirjautumisesi on vanhentunut.", @@ -66,6 +71,7 @@ exports[`Search Snapshot should render view correctly 1`] = ` "editor-tip-keywords": "Liitä tapahtumaan vähintään yksi asiasana, joka kuvaa tapahtuman teemaa. Aloita kirjoittamaan asiasanaa ja valitse lisättävä asiasana alle ilmestyvästä listasta.", "editor-tip-location": "Kirjoita kenttään tapahtumapaikan nimi tai katuosoite ja valitse oikea paikka listasta.", "editor-tip-location-extra": "Jos tapahtumapaikka löytyy listasta, sen sijaintia ei tarvitse kuvailla erikseen. Voit kuitenkin antaa lisätietoja tapahtumapaikan löytämiseksi, esimerkiksi kerrosnumeron tai luokkahuoneen nimen.", + "editor-tip-location-internet": "Jos tapahtuma järjestetään vain etänä internetissä, valitse tapahtumapaikaksi Internet. Tapahtuman URL-osoite laitetaan kotisivu-kenttään ja/tai tapahtuma sosiaalisessa mediassa -kenttiin.", "editor-tip-location-not-found": "Jos tarkkaa tapahtumapaikkaa ei löydy listasta, valitse tapahtumapaikaksi lähin katuosoite ja kirjoita paikan nimi tai muut tarkemmat saapumisohjeet tiiviisti lisätietokenttään.", "editor-tip-price": "Merkitse onko tapahtuma maksuton. Syötä maksulliselle tapahtumalle hinta muodossa \\"5€\\".", "editor-tip-price-multi": "Jos tapahtumalla on useita hintoja, klikkaa Lisää uusi hintatieto ja merkitse kunkin hintaryhmän nimi (esim. Lapset) Hintatietojen kuvaus -kenttään.", @@ -225,6 +231,8 @@ exports[`Search Snapshot should render view correctly 1`] = ` "photographer": "Kuvaaja", "pick-time-range": "Etsi vain ajalta", "play-date-label": "Toistopäivät", + "postpone-events": "Lykkää tapahtumaa", + "postponed": "Lykätty", "publish-events": "Julkaise tapahtuma", "publish-events-multi": "Julkaise tapahtumat", "ready": "Valmis", @@ -282,10 +290,11 @@ exports[`Search Snapshot should render view correctly 1`] = ` "validation-atLeastOneIsTrue": "Valitse vähintään yksi toistopäivä", "validation-atLeastOneMainCategory": "Valitse vähintään yksi pääkategoria", "validation-daysWithinInterval": "Yksi tai useampi valituista päivistä ei esiinny toistovälillä", + "validation-defaultEndInTheFuture": "Alkamisajan pitää olla tulevaisuudessa, jos päättymisaikaa ei tunneta", "validation-error": "Lomakkeessa on virheitä. Tarkasta lomake.", "validation-error-goto-error": "Siirry virheeseen", "validation-hasPrice": "Hintatietoja puuttuu", - "validation-inTheFuture": "Tapahtuman pitää olla tulevaisuudessa", + "validation-inTheFuture": "Päättymisajan pitää olla tulevaisuudessa", "validation-isDate": "Kirjoita päivämäärä muodossa pp.kk.vvvv hh.mm", "validation-isInt": "Tulon on oltava numero", "validation-isMoreThanOne": "Toistovälin tulee olla vähintään 1 viikko", diff --git a/src/views/Search/index.js b/src/views/Search/index.js index 8565472f9..150a3bf2f 100644 --- a/src/views/Search/index.js +++ b/src/views/Search/index.js @@ -27,7 +27,7 @@ class SearchPage extends React.Component { queryParams.page_size = 100 queryParams.sort = 'start_time' queryParams.nocache = Date.now() - queryParams.setText(searchQuery) + queryParams.text = searchQuery if (startDate) queryParams.start = startDate.format('YYYY-MM-DD') if (endDate) queryParams.end = endDate.format('YYYY-MM-DD')