Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SDESK-3138] Contacts were not autosaved and autosaved data was lost if event had files #963

Merged
merged 1 commit into from
Aug 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions client/actions/events/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -657,13 +657,13 @@ const selectCalendar = (calendarId = '', params = {}) => (
}
);

const fetchEventWithFiles = (event, saveToStore = true) => (
const fetchEventWithFiles = (event) => (
(dispatch) => {
if (!isExistingItem(event) || get(event, 'files.length', 0) === 0) {
return Promise.resolve(event);
}

return dispatch(eventsApi.fetchById(event._id, {force: true, saveToStore: saveToStore}));
return dispatch(eventsApi.fetchById(event._id, {force: true, saveToStore: false}));
}
);

Expand Down
22 changes: 14 additions & 8 deletions client/components/Contacts/ContactField.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import {connect} from 'react-redux';
import * as selectors from '../../selectors';
import {get, isEqual} from 'lodash';
import {get, isEqual, difference} from 'lodash';
import {ContactEditor, SelectSearchContactsField} from './index';
import eventsApi from '../../actions/events/api';
import {CONTACTS} from '../../constants';
Expand Down Expand Up @@ -75,11 +75,16 @@ export class ContactFieldComponent extends React.Component {
}

fetchEventContacts(values) {
this.props.fetchContacts(values)
.then(this.getResponseResult)
.then((results) => {
this.getOptions(results || []);
});
if (get(values, 'length', 0) &&
difference(values, this.props.eventContacts.map((c) => c._id)).length > 0) {
this.props.fetchContacts(values)
.then(this.getResponseResult)
.then((results) => {
this.getOptions(results || []);
});
} else {
this.getOptions(this.props.eventContacts, false, values);
}
}

getResponseResult(data = null) {
Expand Down Expand Up @@ -126,15 +131,16 @@ export class ContactFieldComponent extends React.Component {
};
}

getOptions(filteredContacts = this.props.eventContacts, onSearch) {
getOptions(filteredContacts = this.props.eventContacts, onSearch, currentValues = this.props.value) {
let options = [];
let values = [];
let _filteredValues = [];

options = (filteredContacts).map((contact) => this.getOption(contact));

if (!onSearch) {
values = (filteredContacts).map((contact) => this.getValue(contact));
values = (filteredContacts.filter((c) => currentValues.includes(c._id)))
.map((contact) => this.getValue(contact));

_filteredValues = values;
} else {
Expand Down
14 changes: 5 additions & 9 deletions client/components/Events/EventEditor/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,6 @@ export class EventEditorComponent extends React.Component {
};
}

componentWillMount() {
if (this.props.itemExists) {
// Get the event with files with it
this.props.fetchEventWithFiles(this.props.item);
}
}

componentDidMount() {
if (!get(this.props, 'navigation.scrollToViewItem')) {
this.dom.slugline.focus();
Expand Down Expand Up @@ -88,8 +81,11 @@ export class EventEditorComponent extends React.Component {
}
}

if (eventUtils.shouldFetchFilesForEvent(this.props.item)) {
this.props.fetchEventWithFiles(this.props.item);
if (eventUtils.shouldFetchFilesForEvent(this.props.diff)) {
this.props.fetchEventWithFiles(this.props.item)
.then((eventWithFiles) => {
this.props.onChangeHandler('files', eventWithFiles.files, false, false);
});
}

if (this.dom.top) {
Expand Down
14 changes: 11 additions & 3 deletions client/components/Events/EventPreviewContent.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import {connect} from 'react-redux';
import {gettext, getCreator, isValidFileInput} from '../../utils';
import {gettext, getCreator, isValidFileInput, eventUtils} from '../../utils';
import * as selectors from '../../selectors';
import {get, isEqual} from 'lodash';
import {Row} from '../UI/Preview';
Expand Down Expand Up @@ -29,6 +29,7 @@ export class EventPreviewContentComponent extends React.Component {
currentContact: [],
editDetails: false,
viewIndex: null,
files: [],
};
this.fetchEventContacts = this.fetchEventContacts.bind(this);
this.getResponseResult = this.getResponseResult.bind(this);
Expand All @@ -43,7 +44,14 @@ export class EventPreviewContentComponent extends React.Component {
}

componentWillMount() {
this.props.fetchEventWithFiles(this.props.item);
if (eventUtils.shouldFetchFilesForEvent(this.props.item)) {
this.props.fetchEventWithFiles(this.props.item)
.then((eventWithFiles) => {
this.setState({files: eventWithFiles.files});
});
} else if (get(this.props, 'item.files.length', 0) > 0) {
this.setState({files: [...this.props.item.files]});
}
}

componentDidMount() {
Expand Down Expand Up @@ -248,7 +256,7 @@ export class EventPreviewContentComponent extends React.Component {
badgeValue={get(item, 'files.length', 0) > 0 ? item.files.length : null}>
{get(item, 'files.length') > 0 ?
<ul>
{get(item, 'files', []).map((file, index) => (
{this.state.files.map((file, index) => (
isValidFileInput(file, true) ? (<li key={index}>
<FileInput
value={file}
Expand Down
28 changes: 26 additions & 2 deletions client/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {createStore as _createStore, applyMiddleware, compose} from 'redux';
import planningApp from '../reducers';
import thunkMiddleware from 'redux-thunk';
import {createLogger} from 'redux-logger';
import {get, set, map, cloneDeep, forEach, pickBy, includes, isEqual} from 'lodash';
import {get, set, map, cloneDeep, forEach, pickBy, includes, isEqual, isEmpty, isObjectLike, xor, some} from 'lodash';
import {
POST_STATE,
WORKFLOW_STATE,
Expand Down Expand Up @@ -791,11 +791,35 @@ export const itemsEqual = (nextItem, currentItem) => {
const pickField = (value, key) => (
!key.startsWith('_') &&
!key.startsWith('lock_') &&
key !== 'files' &&
value !== null &&
value !== undefined
);

return isEqual(pickBy(nextItem, pickField), pickBy(currentItem, pickField));
return isEqual(pickBy(nextItem, pickField), pickBy(currentItem, pickField)) &&
filesAreSame(nextItem, currentItem);
};

export const filesAreSame = (nextItem, currentItem) => {
if (isEmpty(get(nextItem, 'files')) && isEmpty(get(currentItem, 'files'))) {
// Possibly not an event type or events with no files
return true;
}

if (get(nextItem, 'files.length') !== get(currentItem, 'files.length')) {
return false;
}

if (some(get(currentItem, 'files', []), isValidFileInput) ||
some(get(nextItem, 'files', []), isValidFileInput)) {
// Inputs modified by editing files
return false;
}

const nextFiles = get(nextItem, 'files', []).map((f) => isObjectLike(f) ? f._id : f);
const currentFiles = get(currentItem, 'files', []).map((f) => isObjectLike(f) ? f._id : f);

return xor(nextFiles, currentFiles).length === 0;
};

/**
Expand Down