[issue-17531] - prevent user from exporting annotations when there is no annotation
This commit is contained in:
parent
f3969c083a
commit
f650ade561
@ -151,7 +151,7 @@ trait MakePresentationDownloadReqMsgHdlr extends RightsManagementTrait {
|
|||||||
val annotationCount: Int = storeAnnotationPages.map(_.annotations.size).sum
|
val annotationCount: Int = storeAnnotationPages.map(_.annotations.size).sum
|
||||||
val isOriginalPresentationType = m.body.typeOfExport == "Original"
|
val isOriginalPresentationType = m.body.typeOfExport == "Original"
|
||||||
|
|
||||||
if (annotationCount > 0 && !isOriginalPresentationType) {
|
if (!isOriginalPresentationType && annotationCount > 0) {
|
||||||
// Send Export Job to Redis
|
// Send Export Job to Redis
|
||||||
val job = buildStoreExportJobInRedisSysMsg(exportJob, liveMeeting)
|
val job = buildStoreExportJobInRedisSysMsg(exportJob, liveMeeting)
|
||||||
bus.outGW.send(job)
|
bus.outGW.send(job)
|
||||||
@ -159,7 +159,9 @@ trait MakePresentationDownloadReqMsgHdlr extends RightsManagementTrait {
|
|||||||
// Send Annotations to Redis
|
// Send Annotations to Redis
|
||||||
val annotations = StoredAnnotations(jobId, presId, storeAnnotationPages)
|
val annotations = StoredAnnotations(jobId, presId, storeAnnotationPages)
|
||||||
bus.outGW.send(buildStoreAnnotationsInRedisSysMsg(annotations, liveMeeting))
|
bus.outGW.send(buildStoreAnnotationsInRedisSysMsg(annotations, liveMeeting))
|
||||||
} else {
|
} else if (!isOriginalPresentationType && annotationCount == 0) {
|
||||||
|
log.error("There is no annotations for presentation with Id {}... Ignoring", presId)
|
||||||
|
} else if (isOriginalPresentationType) {
|
||||||
// Return existing uploaded file directly
|
// Return existing uploaded file directly
|
||||||
val convertedFileName = currentPres.get.presentationConvertedName
|
val convertedFileName = currentPres.get.presentationConvertedName
|
||||||
val filename = if (convertedFileName == "") currentPres.get.name else convertedFileName
|
val filename = if (convertedFileName == "") currentPres.get.name else convertedFileName
|
||||||
|
@ -14,7 +14,7 @@ export default async function handlePresentationExport({ body }, meetingId) {
|
|||||||
check(typeOfExport, Match.Maybe(String));
|
check(typeOfExport, Match.Maybe(String));
|
||||||
|
|
||||||
if (typeOfExport === "Original") {
|
if (typeOfExport === "Original") {
|
||||||
setOriginalUriDownload(meetingId, presId, fileURI)
|
await setOriginalUriDownload(meetingId, presId, fileURI)
|
||||||
} else {
|
} else {
|
||||||
await sendExportedPresentationChatMsg(meetingId, presId, fileURI, typeOfExport);
|
await sendExportedPresentationChatMsg(meetingId, presId, fileURI, typeOfExport);
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,12 @@ import removePresentation from './methods/removePresentation';
|
|||||||
import setPresentationRenderedInToast from './methods/setPresentationRenderedInToast';
|
import setPresentationRenderedInToast from './methods/setPresentationRenderedInToast';
|
||||||
import setPresentation from './methods/setPresentation';
|
import setPresentation from './methods/setPresentation';
|
||||||
import setPresentationDownloadable from './methods/setPresentationDownloadable';
|
import setPresentationDownloadable from './methods/setPresentationDownloadable';
|
||||||
import exportPresentationToChat from './methods/exportPresentationToChat';
|
import exportPresentation from './methods/exportPresentation';
|
||||||
|
|
||||||
Meteor.methods({
|
Meteor.methods({
|
||||||
removePresentation,
|
removePresentation,
|
||||||
setPresentation,
|
setPresentation,
|
||||||
setPresentationDownloadable,
|
setPresentationDownloadable,
|
||||||
exportPresentationToChat,
|
exportPresentation,
|
||||||
setPresentationRenderedInToast,
|
setPresentationRenderedInToast,
|
||||||
});
|
});
|
||||||
|
@ -7,7 +7,7 @@ import Presentations from '/imports/api/presentations';
|
|||||||
|
|
||||||
const EXPORTING_THRESHOLD_PER_SLIDE = 2500;
|
const EXPORTING_THRESHOLD_PER_SLIDE = 2500;
|
||||||
|
|
||||||
export default async function exportPresentationToChat(presentationId, type) {
|
export default async function exportPresentation(presentationId, type) {
|
||||||
const REDIS_CONFIG = Meteor.settings.private.redis;
|
const REDIS_CONFIG = Meteor.settings.private.redis;
|
||||||
const CHANNEL = REDIS_CONFIG.channels.toAkkaApps;
|
const CHANNEL = REDIS_CONFIG.channels.toAkkaApps;
|
||||||
const EVENT_NAME = 'MakePresentationDownloadReqMsg';
|
const EVENT_NAME = 'MakePresentationDownloadReqMsg';
|
||||||
@ -56,6 +56,6 @@ export default async function exportPresentationToChat(presentationId, type) {
|
|||||||
|
|
||||||
RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload);
|
RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.error(`Exception while invoking method exportPresentationToChat ${err.stack}`);
|
Logger.error(`Exception while invoking method exportPresentation ${err.stack}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -46,7 +46,8 @@ const propTypes = {
|
|||||||
presentationUploadExternalUrl: PropTypes.string.isRequired,
|
presentationUploadExternalUrl: PropTypes.string.isRequired,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
isPresenter: PropTypes.bool.isRequired,
|
isPresenter: PropTypes.bool.isRequired,
|
||||||
exportPresentationToChat: PropTypes.func.isRequired,
|
exportPresentation: PropTypes.func.isRequired,
|
||||||
|
getHasAnnotations: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
@ -687,7 +688,7 @@ class PresentationUploader extends Component {
|
|||||||
|
|
||||||
handleDownloadingOfPresentation(item, type) {
|
handleDownloadingOfPresentation(item, type) {
|
||||||
const {
|
const {
|
||||||
exportPresentationToChat,
|
exportPresentation,
|
||||||
intl,
|
intl,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
@ -743,7 +744,7 @@ class PresentationUploader extends Component {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
exportPresentationToChat(item.id, observer, type);
|
exportPresentation(item.id, observer, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
getPresentationsToShow() {
|
getPresentationsToShow() {
|
||||||
@ -1003,6 +1004,7 @@ class PresentationUploader extends Component {
|
|||||||
selectedToBeNextCurrent,
|
selectedToBeNextCurrent,
|
||||||
allowDownloadable,
|
allowDownloadable,
|
||||||
renderPresentationItemStatus,
|
renderPresentationItemStatus,
|
||||||
|
getHasAnnotations,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const isActualCurrent = selectedToBeNextCurrent
|
const isActualCurrent = selectedToBeNextCurrent
|
||||||
@ -1034,6 +1036,7 @@ class PresentationUploader extends Component {
|
|||||||
|
|
||||||
const formattedDownloadAriaLabel = `${formattedDownloadLabel} ${item.filename}`;
|
const formattedDownloadAriaLabel = `${formattedDownloadLabel} ${item.filename}`;
|
||||||
|
|
||||||
|
const hasAnnotations = getHasAnnotations(item.id);
|
||||||
return (
|
return (
|
||||||
<Styled.PresentationItem
|
<Styled.PresentationItem
|
||||||
key={item.id}
|
key={item.id}
|
||||||
@ -1075,9 +1078,10 @@ class PresentationUploader extends Component {
|
|||||||
hasError ? null : (
|
hasError ? null : (
|
||||||
<Styled.TableItemActions notDownloadable={!allowDownloadable}>
|
<Styled.TableItemActions notDownloadable={!allowDownloadable}>
|
||||||
{allowDownloadable ? (
|
{allowDownloadable ? (
|
||||||
<PresentationDownloadDropdown
|
<PresentationDownloadDropdown
|
||||||
|
hasAnnotations={hasAnnotations}
|
||||||
disabled={shouldDisableExportButton}
|
disabled={shouldDisableExportButton}
|
||||||
data-test="exportPresentationToPublicChat"
|
data-test="exportPresentation"
|
||||||
aria-label={formattedDownloadAriaLabel}
|
aria-label={formattedDownloadAriaLabel}
|
||||||
color="primary"
|
color="primary"
|
||||||
isDownloadable={isDownloadable}
|
isDownloadable={isDownloadable}
|
||||||
|
@ -9,6 +9,7 @@ import PresentationUploader from './component';
|
|||||||
import { UsersContext } from '/imports/ui/components/components-data/users-context/context';
|
import { UsersContext } from '/imports/ui/components/components-data/users-context/context';
|
||||||
import Auth from '/imports/ui/services/auth';
|
import Auth from '/imports/ui/services/auth';
|
||||||
import { isDownloadPresentationWithAnnotationsEnabled, isPresentationEnabled } from '/imports/ui/services/features';
|
import { isDownloadPresentationWithAnnotationsEnabled, isPresentationEnabled } from '/imports/ui/services/features';
|
||||||
|
import { getHasAnnotations } from '/imports/ui/components/whiteboard/service'
|
||||||
|
|
||||||
const PRESENTATION_CONFIG = Meteor.settings.public.presentation;
|
const PRESENTATION_CONFIG = Meteor.settings.public.presentation;
|
||||||
|
|
||||||
@ -31,7 +32,7 @@ export default withTracker(() => {
|
|||||||
dispatchDisableDownloadable,
|
dispatchDisableDownloadable,
|
||||||
dispatchEnableDownloadable,
|
dispatchEnableDownloadable,
|
||||||
dispatchTogglePresentationDownloadable,
|
dispatchTogglePresentationDownloadable,
|
||||||
exportPresentationToChat,
|
exportPresentation,
|
||||||
} = Service;
|
} = Service;
|
||||||
const isOpen = isPresentationEnabled() && (Session.get('showUploadPresentationView') || false);
|
const isOpen = isPresentationEnabled() && (Session.get('showUploadPresentationView') || false);
|
||||||
|
|
||||||
@ -49,10 +50,11 @@ export default withTracker(() => {
|
|||||||
dispatchDisableDownloadable,
|
dispatchDisableDownloadable,
|
||||||
dispatchEnableDownloadable,
|
dispatchEnableDownloadable,
|
||||||
dispatchTogglePresentationDownloadable,
|
dispatchTogglePresentationDownloadable,
|
||||||
exportPresentationToChat,
|
exportPresentation,
|
||||||
isOpen,
|
isOpen,
|
||||||
selectedToBeNextCurrent: Session.get('selectedToBeNextCurrent') || null,
|
selectedToBeNextCurrent: Session.get('selectedToBeNextCurrent') || null,
|
||||||
externalUploadData: Service.getExternalUploadData(),
|
externalUploadData: Service.getExternalUploadData(),
|
||||||
handleFiledrop: Service.handleFiledrop,
|
handleFiledrop: Service.handleFiledrop,
|
||||||
|
getHasAnnotations,
|
||||||
};
|
};
|
||||||
})(PresentationUploaderContainer);
|
})(PresentationUploaderContainer);
|
||||||
|
@ -51,6 +51,7 @@ class PresentationDownloadDropdown extends PureComponent {
|
|||||||
isDownloadable,
|
isDownloadable,
|
||||||
item,
|
item,
|
||||||
closeModal,
|
closeModal,
|
||||||
|
hasAnnotations
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
this.menuItems = [];
|
this.menuItems = [];
|
||||||
@ -83,18 +84,20 @@ class PresentationDownloadDropdown extends PureComponent {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.menuItems.push(
|
if (hasAnnotations) {
|
||||||
{
|
this.menuItems.push(
|
||||||
key: this.actionsKey[1],
|
{
|
||||||
id: 'sendAnnotatedDocument',
|
key: this.actionsKey[1],
|
||||||
dataTest: 'sendAnnotatedDocument',
|
id: 'sendAnnotatedDocument',
|
||||||
label: intl.formatMessage(intlMessages.sendAnnotatedDocument),
|
dataTest: 'sendAnnotatedDocument',
|
||||||
onClick: () => {
|
label: intl.formatMessage(intlMessages.sendAnnotatedDocument),
|
||||||
closeModal();
|
onClick: () => {
|
||||||
handleDownloadingOfPresentation("Annotated");
|
closeModal();
|
||||||
|
handleDownloadingOfPresentation("Annotated");
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
);
|
||||||
);
|
}
|
||||||
|
|
||||||
return this.menuItems;
|
return this.menuItems;
|
||||||
}
|
}
|
||||||
|
@ -378,7 +378,7 @@ const getExternalUploadData = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const exportPresentationToChat = (presentationId, observer, type) => {
|
const exportPresentation = (presentationId, observer, type) => {
|
||||||
let lastStatus = {};
|
let lastStatus = {};
|
||||||
|
|
||||||
Tracker.autorun((c) => {
|
Tracker.autorun((c) => {
|
||||||
@ -407,7 +407,7 @@ const exportPresentationToChat = (presentationId, observer, type) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
makeCall('exportPresentationToChat', presentationId, type);
|
makeCall('exportPresentation', presentationId, type);
|
||||||
};
|
};
|
||||||
|
|
||||||
function handleFiledrop(files, files2, that, intl, intlMessages) {
|
function handleFiledrop(files, files2, that, intl, intlMessages) {
|
||||||
@ -487,7 +487,7 @@ export default {
|
|||||||
setPresentation,
|
setPresentation,
|
||||||
requestPresentationUploadToken,
|
requestPresentationUploadToken,
|
||||||
getExternalUploadData,
|
getExternalUploadData,
|
||||||
exportPresentationToChat,
|
exportPresentation,
|
||||||
uploadAndConvertPresentation,
|
uploadAndConvertPresentation,
|
||||||
handleFiledrop,
|
handleFiledrop,
|
||||||
};
|
};
|
||||||
|
@ -38,6 +38,13 @@ async function handleAddedAnnotation({
|
|||||||
Annotations.upsert(query.selector, query.modifier);
|
Annotations.upsert(query.selector, query.modifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getHasAnnotations = (presentationId) => {
|
||||||
|
const ann = Annotations.find(
|
||||||
|
{},
|
||||||
|
).fetch();
|
||||||
|
return ann.filter(a => a.whiteboardId.includes(presentationId)).length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
function handleRemovedAnnotation({
|
function handleRemovedAnnotation({
|
||||||
meetingId, whiteboardId, userId, shapeId,
|
meetingId, whiteboardId, userId, shapeId,
|
||||||
}) {
|
}) {
|
||||||
@ -388,4 +395,5 @@ export {
|
|||||||
changeCurrentSlide,
|
changeCurrentSlide,
|
||||||
notifyNotAllowedChange,
|
notifyNotAllowedChange,
|
||||||
notifyShapeNumberExceeded,
|
notifyShapeNumberExceeded,
|
||||||
|
getHasAnnotations,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user