import {gettext} from 'core/utils'; import {isPublished} from 'apps/archive/utils'; import {AuthoringWorkspaceService} from 'apps/authoring/authoring/services/AuthoringWorkspaceService'; import {appConfig} from 'appConfig'; angular.module('superdesk.apps.dashboard.widgets.relatedItem', [ 'superdesk.apps.dashboard.widgets.base', 'superdesk.apps.authoring.widgets', ]) .controller('relatedItemController', RelatedItemController) .config(['authoringWidgetsProvider', function(authoringWidgets) { authoringWidgets.widget('related-item', { label: gettext('Related Items'), icon: 'related', template: 'scripts/apps/archive/related-item-widget/widget-relatedItem.html', order: 7, side: 'right', display: { authoring: true, packages: false, killedItem: true, legalArchive: false, archived: false, picture: false, personal: false, }, isWidgetVisible: (item) => ['content', function(content) { if (item.profile == null) { return Promise.resolve(true); } return new Promise((resolve) => { content.getType(item.profile).then((type) => { resolve(type.schema.hasOwnProperty('slugline')); }); }); }], configurationTemplate: 'scripts/apps/archive/related-item-widget/relatedItem-configuration.html', configurable: false, needEditable: true, needUnlock: true, configuration: { sluglineMatch: 'EXACT', modificationDateAfter: 'today', }, }); }]); RelatedItemController.$inject = [ '$scope', 'api', 'BaseWidgetController', 'notify', 'superdesk', '$q', 'authoringWorkspace', 'authoring', 'privileges', 'storage', 'familyService', 'moment', 'content', ]; function RelatedItemController( $scope, api, BaseWidgetController, notify, superdesk, $q, authoringWorkspace: AuthoringWorkspaceService, authoring, privileges, storage, familyService, moment, content, ) { $scope.type = 'archiveWidget'; $scope.itemListOptions = { endpoint: 'search', repo: ['archive', 'published'], notStates: ['spiked'], types: ['text', 'composite'], page: 1, modificationDateAfter: storage.getItem('modificationDateAfter') === 'today' ? today() : storage.getItem('modificationDateAfter') || today(), sluglineMatch: storage.getItem('sluglineMatch') || 'EXACT', }; $scope.options = { pinEnabled: true, modeEnabled: true, itemTypeEnabled: true, mode: 'basic', pinMode: 'archive', related: true, itemTypes: ['text', 'composite'], sort: [{versioncreated: 'desc'}], }; $scope.loading = true; familyService.fetchRelatedItems($scope.item) .then((items) => { if (items && items._items && items._items.length > 1) { $scope.options.existingRelations = items._items; $scope.widget.configurable = false; $scope.options.searchEnabled = false; $scope.widget.label = gettext('Related Items'); } else { $scope.options.existingRelations = false; $scope.widget.configurable = true; $scope.options.searchEnabled = true; $scope.widget.label = gettext('Relate an item'); } }) .finally(() => { $scope.loading = false; }); function today() { if (appConfig.search != null && appConfig.search.useDefaultTimezone) { return moment() .tz(appConfig.defaultTimezone) .format('YYYY-MM-DD') + 'T00:00:00' + moment.tz(appConfig.defaultTimezone).format('ZZ'); } return moment().format('YYYY-MM-DD') + 'T00:00:00' + moment().format('ZZ'); } /** * Copies the field values from source object to destination * if destination has a content profile then copies fields * defined in the content profile only */ const copyMetadata = (source, destination) => { const fields = ['subject', 'anpa_category', 'headline', 'urgency', 'priority', 'slugline', 'place']; destination.related_to = source._id; if (destination.profile) { return content.getType(destination.profile).then((type) => { fields.forEach((field) => { if (type.schema.hasOwnProperty(field)) { destination[field] = source[field]; } }); return $q.when(destination); }); } fields.forEach((field) => { destination[field] = source[field]; }); return $q.when(destination); }; $scope.actions = { apply: { title: 'Associate metadata', method: function(item) { $scope.origItem = $scope.options.item; copyMetadata(item, {}).then((copied) => api.save('archive', $scope.origItem, copied) .then(() => { Object.assign($scope.options.item, copied); notify.success(gettext('item metadata associated.')); return item; })); }, class: 'open', icon: 'icon-expand', condition: function(item) { return item.type !== 'composite'; }, }, update: { title: 'Associate as update', method: function(item) { api.save('archive_rewrite', {}, {update: angular.extend({}, $scope.origItem, $scope.item)}, item) .then((newItem) => { notify.success(gettext('Story is associated as update.')); authoringWorkspace.edit(newItem); }, (response) => { if (angular.isDefined(response.data._message)) { notify.error( gettext( 'Failed to associate update: {{message}}', {message: response.data._message}, ), ); } else { notify.error(gettext('There is an error. Failed to associate update.')); } }); }, class: 'open', icon: 'icon-expand', condition: function(item) { var userHasPermission = privileges.userHasPrivileges({rewrite: 1}); var canBeRewrite = !isPublished($scope.item) && $scope.item.type === 'text' && !$scope.item.rewrite_of && (!$scope.item.broadcast || !$scope.item.broadcast.master_id); var canBeRewritten = authoring.itemActions(item).re_write; return canBeRewritten && canBeRewrite && userHasPermission; }, }, open: { title: 'Open', method: function(item) { $q.when(superdesk.intent('edit', 'item', item)).then(null, (value) => { superdesk.intent('view', 'item', item); }); }, class: 'open', icon: 'icon-external', condition: function(item) { return true; }, }, }; BaseWidgetController.call(this, $scope); $scope.$watch('widget.configuration', (_config) => { if (_config && _config.sluglineMatch && _config.sluglineMatch !== $scope.itemListOptions.sluglineMatch) { $scope.itemListOptions.sluglineMatch = _config.sluglineMatch; } if (_config && _config.modificationDateAfter && _config.modificationDateAfter !== $scope.itemListOptions.modificationDateAfter) { if (_config.modificationDateAfter === 'today') { $scope.itemListOptions.modificationDateAfter = today(); } else { $scope.itemListOptions.modificationDateAfter = _config.modificationDateAfter; } } }, true); function reset() { if ($scope.widget && $scope.widget.configuration) { $scope.widget.configuration.modificationDateAfter = storage.getItem('modificationDateAfter') || 'today'; $scope.widget.configuration.sluglineMatch = storage.getItem('sluglineMatch') || 'EXACT'; } } if ($scope.widget) { $scope.widget.save = function() { storage.setItem('sluglineMatch', $scope.widget.configuration.sluglineMatch); storage.setItem('modificationDateAfter', $scope.widget.configuration.modificationDateAfter); }; } reset(); }