Skip to content

Commit

Permalink
Merge branch 'develop' into adding-related-items-to-plannings-and-events
Browse files Browse the repository at this point in the history
  • Loading branch information
tomaskikutis committed Oct 28, 2024
2 parents 8741a9d + 7a14184 commit 61bceb8
Show file tree
Hide file tree
Showing 18 changed files with 494 additions and 252 deletions.
4 changes: 2 additions & 2 deletions client/actions/assignments/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import * as actions from '../';
import {ASSIGNMENTS, ALL_DESKS, SORT_DIRECTION} from '../../constants';
import planningUtils from '../../utils/planning';
import {getErrorMessage, isExistingItem, gettext} from '../../utils';
import planning from '../planning';
import planningActions from '../planning/api';
import {assignmentsViewRequiresArchiveItems} from '../../components/Assignments/AssignmentItem/fields';

const setBaseQuery = ({must = []}) => ({
Expand Down Expand Up @@ -415,7 +415,7 @@ const receiveAssignmentHistory = (items) => ({
* @param {object} assignment - The Assignment to load items for
*/
const loadPlanningAndEvent = (assignment) => (dispatch) =>
dispatch(planning.api.fetchById(assignment.planning_item));
dispatch(planningActions.fetchById(assignment.planning_item));

/**
* Loads the Archive items that are linked to the provided Assignment list
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import {
import {superdeskApi} from '../../../superdeskApi';
import * as selectors from '../../../selectors';
import * as actions from '../../../actions';
import planningActions from '../../../actions/planning/api';

import {assignmentUtils, eventUtils, planningUtils, getFileDownloadURL} from '../../../utils';
import {ASSIGNMENTS, WORKSPACE} from '../../../constants';

Expand Down Expand Up @@ -262,7 +264,7 @@ const mapDispatchToProps = (dispatch) => ({
removeAssignment: (assignment) => dispatch(actions.assignments.ui.showRemoveAssignmentModal(assignment)),
openArchivePreview: (assignment) => dispatch(actions.assignments.ui.openArchivePreview(assignment)),
fetchEventFiles: (event) => dispatch(actions.events.api.fetchEventFiles(event)),
fetchPlanningFiles: (planning) => dispatch(actions.planning.api.fetchPlanningFiles(planning)),
fetchPlanningFiles: (planning) => dispatch(planningActions.fetchPlanningFiles(planning)),
});

export const AssignmentPreviewContainer = connect<IStateProps, IDispatchProps>(
Expand Down
4 changes: 3 additions & 1 deletion client/components/Coverages/CoverageIcons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,15 @@ export function getAvatarForCoverage(

return placeholder;
} else {
const statusDotColor = planningUtils.getNewsCoverageStatusDotColor(coverage);

const avatar: Omit<IPropsAvatar, 'size'> = {
initials: getUserInitials(user.display_name),
imageUrl: user.picture_url,
displayName: user.display_name,
icon: icon,
customContent: getCustomAvatarContent(user),
statusDot: {color: planningUtils.getNewsCoverageStatusDotColor(coverage)},
statusDot: statusDotColor != null ? {color: statusDotColor} : null,
};

return avatar;
Expand Down
7 changes: 4 additions & 3 deletions client/components/Planning/PlanningEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {planningUtils, eventUtils, lockUtils} from '../../../utils';
import {EditorForm} from '../../Editor/EditorForm';
import {PlanningEditorHeader} from './PlanningEditorHeader';
import {COVERAGES} from '../../../constants';
import planningActions from '../../../actions/planning/api';

interface IProps {
original?: IPlanningItem;
Expand Down Expand Up @@ -99,9 +100,9 @@ const mapStateToProps = (state) => ({

const mapDispatchToProps = (dispatch) => ({
fetchEventFiles: (event) => dispatch(actions.events.api.fetchEventFiles(event)),
fetchPlanningFiles: (planning) => dispatch(actions.planning.api.fetchPlanningFiles(planning)),
uploadFiles: (files) => dispatch(actions.planning.api.uploadFiles({files: files})),
removeFile: (file) => dispatch(actions.planning.api.removeFile(file)),
fetchPlanningFiles: (planning) => dispatch(planningActions.fetchPlanningFiles(planning)),
uploadFiles: (files) => dispatch(planningActions.uploadFiles({files: files})),
removeFile: (file) => dispatch(planningActions.removeFile(file)),
setCoverageDefaultDesk: (coverage) => dispatch(actions.users.setCoverageDefaultDesk(coverage)),
setCoverageAddAdvancedMode: (advancedMode) => dispatch(actions.users.setCoverageAddAdvancedMode(advancedMode)),
});
Expand Down
3 changes: 2 additions & 1 deletion client/components/Planning/PlanningPreviewContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {eventUtils, getCreator, getFileDownloadURL} from '../../utils';
import {getUserInterfaceLanguageFromCV} from '../../utils/users';
import * as selectors from '../../selectors';
import * as actions from '../../actions';
import planningActions from '../../actions/planning/api';

import {
AuditInformation,
Expand Down Expand Up @@ -83,7 +84,7 @@ const mapStateToProps = (state, ownProps): IReduxProps => ({
const mapDispatchToProps = (dispatch): IDispatchProps => ({
onEditEvent: (event) => dispatch(actions.main.openForEdit(event)),
fetchEventFiles: (event) => dispatch(actions.events.api.fetchEventFiles(event)),
fetchPlanningFiles: (planning) => dispatch(actions.planning.api.fetchPlanningFiles(planning)),
fetchPlanningFiles: (planning) => dispatch(planningActions.fetchPlanningFiles(planning)),
});

export class PlanningPreviewContentComponent extends React.PureComponent<IProps> {
Expand Down
63 changes: 36 additions & 27 deletions client/components/fields/editor/CustomVocabularies.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import {ISubject, IVocabulary} from 'superdesk-api';
import {superdeskApi} from '../../../superdeskApi';
import {IEditorFieldProps, IProfileSchemaTypeList} from '../../../interfaces';
import {Row} from '../../UI/Form';
import {getVocabularyItemNameFromString} from '../../../utils/vocabularies';
import {EditorFieldTreeSelect} from '../editor/base/treeSelect';
import {getVocabularyItemFieldTranslated} from '../../../utils/vocabularies';
import {arrayToTree} from 'superdesk-core/scripts/core/helpers/tree';
import {TreeSelect} from 'superdesk-ui-framework/react';

interface IProps extends IEditorFieldProps {
schema?: IProfileSchemaTypeList;
Expand All @@ -33,6 +34,8 @@ class CustomVocabulariesComponent extends React.PureComponent<IProps> {
required,
testId,
language,
disabled,
invalid,
} = this.props;

const customVocabularies = vocabularies.filter((cv) =>
Expand All @@ -41,43 +44,49 @@ class CustomVocabulariesComponent extends React.PureComponent<IProps> {

return customVocabularies.map((cv) => {
const cvFieldName = `custom_vocabularies.${cv._id}`;
const parentField = cv.schema_field || 'subject';
const itemFieldName = cv.schema_field ?? 'subject';

return (
<Row
key={cv._id}
id={`form-row-${cvFieldName}`}
data-test-id={testId?.length ? `${testId}.${cv._id}` : cv._id}
>
<EditorFieldTreeSelect
filterScheme={(values) => values.filter((value) => cv._id == null || value?.scheme === cv._id)}
item={item}
field={parentField}
label={gettext(cv.display_name)}
required={required || schema?.required}
allowMultiple={true}
<TreeSelect
sortable={true}
getOptions={() => cv.items.map((item: ISubject) => ({value: {...item, scheme: cv._id}}))}
getId={(item: ISubject) => item.qcode}
getLabel={(item: ISubject) => (
getVocabularyItemNameFromString(
item.qcode,
cv.items,
'qcode',
'name',
language
)
kind="synchronous"
allowMultiple={true}
value={(item.subject ?? []).filter((x) => x.scheme === cv._id)}
label={gettext(cv.display_name)}
required={required ?? schema?.required}
getOptions={() => arrayToTree(
cv.items.map((cvItem) => ({
...cvItem,
scheme: cv._id,
})) as Array<ISubject>,
({qcode}) => qcode.toString(),
({parent}) => parent?.toString(),
).result}
getLabel={(item) => getVocabularyItemFieldTranslated(
item,
'name',
language,
)}
onChange={(field, value) => {
const otherCvValues = item[parentField] ?? [];
getId={(item) => item.qcode}
invalid={errors?.length > 0 || invalid}
error={showErrors ? errors[itemFieldName] : undefined}
readOnly={disabled}
disabled={disabled}
onChange={(vals) => {
const restOfItems = (item.subject ?? []).filter((x) => x.scheme !== cv._id);

const newValues = value.concat(
otherCvValues.filter((value) => value?.scheme != cv._id)
onChange(
'subject',
[...restOfItems, ...vals],
);

onChange(field, newValues);
}}
errors={errors}
tabindex={0}
zIndex={1051}
/>
</Row>
);
Expand Down
33 changes: 26 additions & 7 deletions client/controllers/AddToPlanningController.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import ReactDOM from 'react-dom';
import {Provider} from 'react-redux';
import {ModalsContainer} from '../components';
import {planning} from '../actions';
import {get, isEmpty, isNumber} from 'lodash';
import {get, isEmpty, isNumber, noop} from 'lodash';
import {registerNotifications, getErrorMessage, isExistingItem} from '../utils';
import {WORKSPACE, MODALS} from '../constants';
import {GET_LABEL_MAP} from 'superdesk-core/scripts/apps/workspace/content/constants';
import {IArticle, IContentProfile} from 'superdesk-api';
import {authoringReactViewEnabled} from 'appConfig';
import {planningApi, superdeskApi} from '../superdeskApi';
import {PLANNING_VIEW} from '../interfaces';

Expand Down Expand Up @@ -87,7 +88,7 @@ export class AddToPlanningController {
return sdPlanningStore.initWorkspace(WORKSPACE.AUTHORING, this.loadWorkspace)
.then(
this.render,
this.$scope.resolve
!authoringReactViewEnabled ? this.$scope.resolve : noop
);
}

Expand Down Expand Up @@ -190,7 +191,9 @@ export class AddToPlanningController {
this.store.dispatch(actions.resetStore());

if (this.superdeskFlags.flags.authoring || !this.rendered) {
this.$scope.resolve();
if (!authoringReactViewEnabled) {
this.$scope.resolve();
}
return;
}

Expand All @@ -205,7 +208,9 @@ export class AddToPlanningController {
body: this.gettext('The item was unlocked by "{{ username }}"', {username}),
action: () => {
this.newsItem.lock_session = null;
this.$scope.resolve();
if (!authoringReactViewEnabled) {
this.$scope.resolve();
}
},
},
})));
Expand Down Expand Up @@ -263,15 +268,19 @@ export class AddToPlanningController {
this.notify.error(err);
});

this.$scope.resolve('foo');
if (!authoringReactViewEnabled) {
this.$scope.resolve('foo');
}
return Promise.reject('foo');
}

if (this.lock.isLocked(newsItem)) {
this.notify.error(
this.gettext('Item already locked.')
);
this.$scope.resolve('bar');
if (!authoringReactViewEnabled) {
this.$scope.resolve('bar');
}
return Promise.reject('bar');
}

Expand All @@ -284,13 +293,23 @@ export class AddToPlanningController {
this.notify.error(
getErrorMessage(error, this.gettext('Failed to lock the item.'))
);
this.$scope.resolve(error);
if (!authoringReactViewEnabled) {
this.$scope.resolve(error);
}
return Promise.reject(error);
}
);
}

return Promise.resolve(newsItem);
}, (error) => {
this.notify.error(
getErrorMessage(error, this.gettext('Failed to load the item.'))
);
if (!authoringReactViewEnabled) {
this.$scope.resolve(error);
}
return Promise.reject(error);
});
}
}
Expand Down
Loading

0 comments on commit 61bceb8

Please sign in to comment.