[issue-17531] - prevent user from exporting annotations when there is no annotation

This commit is contained in:
GuiLeme 2023-05-04 08:48:32 -03:00
parent f3969c083a
commit f650ade561
9 changed files with 47 additions and 28 deletions

View File

@ -151,7 +151,7 @@ trait MakePresentationDownloadReqMsgHdlr extends RightsManagementTrait {
val annotationCount: Int = storeAnnotationPages.map(_.annotations.size).sum
val isOriginalPresentationType = m.body.typeOfExport == "Original"
if (annotationCount > 0 && !isOriginalPresentationType) {
if (!isOriginalPresentationType && annotationCount > 0) {
// Send Export Job to Redis
val job = buildStoreExportJobInRedisSysMsg(exportJob, liveMeeting)
bus.outGW.send(job)
@ -159,7 +159,9 @@ trait MakePresentationDownloadReqMsgHdlr extends RightsManagementTrait {
// Send Annotations to Redis
val annotations = StoredAnnotations(jobId, presId, storeAnnotationPages)
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
val convertedFileName = currentPres.get.presentationConvertedName
val filename = if (convertedFileName == "") currentPres.get.name else convertedFileName

View File

@ -14,7 +14,7 @@ export default async function handlePresentationExport({ body }, meetingId) {
check(typeOfExport, Match.Maybe(String));
if (typeOfExport === "Original") {
setOriginalUriDownload(meetingId, presId, fileURI)
await setOriginalUriDownload(meetingId, presId, fileURI)
} else {
await sendExportedPresentationChatMsg(meetingId, presId, fileURI, typeOfExport);
}

View File

@ -3,12 +3,12 @@ import removePresentation from './methods/removePresentation';
import setPresentationRenderedInToast from './methods/setPresentationRenderedInToast';
import setPresentation from './methods/setPresentation';
import setPresentationDownloadable from './methods/setPresentationDownloadable';
import exportPresentationToChat from './methods/exportPresentationToChat';
import exportPresentation from './methods/exportPresentation';
Meteor.methods({
removePresentation,
setPresentation,
setPresentationDownloadable,
exportPresentationToChat,
exportPresentation,
setPresentationRenderedInToast,
});

View File

@ -7,7 +7,7 @@ import Presentations from '/imports/api/presentations';
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 CHANNEL = REDIS_CONFIG.channels.toAkkaApps;
const EVENT_NAME = 'MakePresentationDownloadReqMsg';
@ -56,6 +56,6 @@ export default async function exportPresentationToChat(presentationId, type) {
RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload);
} catch (err) {
Logger.error(`Exception while invoking method exportPresentationToChat ${err.stack}`);
Logger.error(`Exception while invoking method exportPresentation ${err.stack}`);
}
}

View File

@ -46,7 +46,8 @@ const propTypes = {
presentationUploadExternalUrl: PropTypes.string.isRequired,
}).isRequired,
isPresenter: PropTypes.bool.isRequired,
exportPresentationToChat: PropTypes.func.isRequired,
exportPresentation: PropTypes.func.isRequired,
getHasAnnotations: PropTypes.func.isRequired,
};
const defaultProps = {
@ -687,7 +688,7 @@ class PresentationUploader extends Component {
handleDownloadingOfPresentation(item, type) {
const {
exportPresentationToChat,
exportPresentation,
intl,
} = this.props;
@ -743,7 +744,7 @@ class PresentationUploader extends Component {
}
};
exportPresentationToChat(item.id, observer, type);
exportPresentation(item.id, observer, type);
}
getPresentationsToShow() {
@ -1003,6 +1004,7 @@ class PresentationUploader extends Component {
selectedToBeNextCurrent,
allowDownloadable,
renderPresentationItemStatus,
getHasAnnotations,
} = this.props;
const isActualCurrent = selectedToBeNextCurrent
@ -1034,6 +1036,7 @@ class PresentationUploader extends Component {
const formattedDownloadAriaLabel = `${formattedDownloadLabel} ${item.filename}`;
const hasAnnotations = getHasAnnotations(item.id);
return (
<Styled.PresentationItem
key={item.id}
@ -1076,8 +1079,9 @@ class PresentationUploader extends Component {
<Styled.TableItemActions notDownloadable={!allowDownloadable}>
{allowDownloadable ? (
<PresentationDownloadDropdown
hasAnnotations={hasAnnotations}
disabled={shouldDisableExportButton}
data-test="exportPresentationToPublicChat"
data-test="exportPresentation"
aria-label={formattedDownloadAriaLabel}
color="primary"
isDownloadable={isDownloadable}

View File

@ -9,6 +9,7 @@ import PresentationUploader from './component';
import { UsersContext } from '/imports/ui/components/components-data/users-context/context';
import Auth from '/imports/ui/services/auth';
import { isDownloadPresentationWithAnnotationsEnabled, isPresentationEnabled } from '/imports/ui/services/features';
import { getHasAnnotations } from '/imports/ui/components/whiteboard/service'
const PRESENTATION_CONFIG = Meteor.settings.public.presentation;
@ -31,7 +32,7 @@ export default withTracker(() => {
dispatchDisableDownloadable,
dispatchEnableDownloadable,
dispatchTogglePresentationDownloadable,
exportPresentationToChat,
exportPresentation,
} = Service;
const isOpen = isPresentationEnabled() && (Session.get('showUploadPresentationView') || false);
@ -49,10 +50,11 @@ export default withTracker(() => {
dispatchDisableDownloadable,
dispatchEnableDownloadable,
dispatchTogglePresentationDownloadable,
exportPresentationToChat,
exportPresentation,
isOpen,
selectedToBeNextCurrent: Session.get('selectedToBeNextCurrent') || null,
externalUploadData: Service.getExternalUploadData(),
handleFiledrop: Service.handleFiledrop,
getHasAnnotations,
};
})(PresentationUploaderContainer);

View File

@ -51,6 +51,7 @@ class PresentationDownloadDropdown extends PureComponent {
isDownloadable,
item,
closeModal,
hasAnnotations
} = this.props;
this.menuItems = [];
@ -83,6 +84,7 @@ class PresentationDownloadDropdown extends PureComponent {
);
}
if (hasAnnotations) {
this.menuItems.push(
{
key: this.actionsKey[1],
@ -95,6 +97,7 @@ class PresentationDownloadDropdown extends PureComponent {
},
},
);
}
return this.menuItems;
}

View File

@ -378,7 +378,7 @@ const getExternalUploadData = () => {
};
};
const exportPresentationToChat = (presentationId, observer, type) => {
const exportPresentation = (presentationId, observer, type) => {
let lastStatus = {};
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) {
@ -487,7 +487,7 @@ export default {
setPresentation,
requestPresentationUploadToken,
getExternalUploadData,
exportPresentationToChat,
exportPresentation,
uploadAndConvertPresentation,
handleFiledrop,
};

View File

@ -38,6 +38,13 @@ async function handleAddedAnnotation({
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({
meetingId, whiteboardId, userId, shapeId,
}) {
@ -388,4 +395,5 @@ export {
changeCurrentSlide,
notifyNotAllowedChange,
notifyShapeNumberExceeded,
getHasAnnotations,
};