diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/mail/static/src/components/attachment/attachment.js | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/mail/static/src/components/attachment/attachment.js')
| -rw-r--r-- | addons/mail/static/src/components/attachment/attachment.js | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/addons/mail/static/src/components/attachment/attachment.js b/addons/mail/static/src/components/attachment/attachment.js new file mode 100644 index 00000000..a4b7b136 --- /dev/null +++ b/addons/mail/static/src/components/attachment/attachment.js @@ -0,0 +1,204 @@ +odoo.define('mail/static/src/components/attachment/attachment.js', function (require) { +'use strict'; + +const useShouldUpdateBasedOnProps = require('mail/static/src/component_hooks/use_should_update_based_on_props/use_should_update_based_on_props.js'); +const useStore = require('mail/static/src/component_hooks/use_store/use_store.js'); + +const components = { + AttachmentDeleteConfirmDialog: require('mail/static/src/components/attachment_delete_confirm_dialog/attachment_delete_confirm_dialog.js'), +}; + +const { Component, useState } = owl; + +class Attachment extends Component { + + /** + * @override + */ + constructor(...args) { + super(...args); + useShouldUpdateBasedOnProps({ + compareDepth: { + attachmentLocalIds: 1, + }, + }); + useStore(props => { + const attachment = this.env.models['mail.attachment'].get(props.attachmentLocalId); + return { + attachment: attachment ? attachment.__state : undefined, + }; + }); + this.state = useState({ + hasDeleteConfirmDialog: false, + }); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + /** + * @returns {mail.attachment} + */ + get attachment() { + return this.env.models['mail.attachment'].get(this.props.attachmentLocalId); + } + + /** + * Return the url of the attachment. Temporary attachments, a.k.a. uploading + * attachments, do not have an url. + * + * @returns {string} + */ + get attachmentUrl() { + if (this.attachment.isTemporary) { + return ''; + } + return this.env.session.url('/web/content', { + id: this.attachment.id, + download: true, + }); + } + + /** + * Get the details mode after auto mode is computed + * + * @returns {string} 'card', 'hover' or 'none' + */ + get detailsMode() { + if (this.props.detailsMode !== 'auto') { + return this.props.detailsMode; + } + if (this.attachment.fileType !== 'image') { + return 'card'; + } + return 'hover'; + } + + /** + * Get the attachment representation style to be applied + * + * @returns {string} + */ + get imageStyle() { + if (this.attachment.fileType !== 'image') { + return ''; + } + if (this.env.isQUnitTest) { + // background-image:url is hardly mockable, and attachments in + // QUnit tests do not actually exist in DB, so style should not + // be fetched at all. + return ''; + } + let size; + if (this.detailsMode === 'card') { + size = '38x38'; + } else { + // The size of background-image depends on the props.imageSize + // to sync with width and height of `.o_Attachment_image`. + if (this.props.imageSize === "large") { + size = '400x400'; + } else if (this.props.imageSize === "medium") { + size = '200x200'; + } else if (this.props.imageSize === "small") { + size = '100x100'; + } + } + // background-size set to override value from `o_image` which makes small image stretched + return `background-image:url(/web/image/${this.attachment.id}/${size}); background-size: auto;`; + } + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * Download the attachment when clicking on donwload icon. + * + * @private + * @param {MouseEvent} ev + */ + _onClickDownload(ev) { + ev.stopPropagation(); + window.location = `/web/content/ir.attachment/${this.attachment.id}/datas?download=true`; + } + + /** + * Open the attachment viewer when clicking on viewable attachment. + * + * @private + * @param {MouseEvent} ev + */ + _onClickImage(ev) { + if (!this.attachment.isViewable) { + return; + } + this.env.models['mail.attachment'].view({ + attachment: this.attachment, + attachments: this.props.attachmentLocalIds.map( + attachmentLocalId => this.env.models['mail.attachment'].get(attachmentLocalId) + ), + }); + } + + /** + * @private + * @param {MouseEvent} ev + */ + _onClickUnlink(ev) { + ev.stopPropagation(); + if (!this.attachment) { + return; + } + if (this.attachment.isLinkedToComposer) { + this.attachment.remove(); + this.trigger('o-attachment-removed', { attachmentLocalId: this.props.attachmentLocalId }); + } else { + this.state.hasDeleteConfirmDialog = true; + } + } + + /** + * @private + */ + _onDeleteConfirmDialogClosed() { + this.state.hasDeleteConfirmDialog = false; + } +} + +Object.assign(Attachment, { + components, + defaultProps: { + attachmentLocalIds: [], + detailsMode: 'auto', + imageSize: 'medium', + isDownloadable: false, + isEditable: true, + showExtension: true, + showFilename: true, + }, + props: { + attachmentLocalId: String, + attachmentLocalIds: { + type: Array, + element: String, + }, + detailsMode: { + type: String, + validate: prop => ['auto', 'card', 'hover', 'none'].includes(prop), + }, + imageSize: { + type: String, + validate: prop => ['small', 'medium', 'large'].includes(prop), + }, + isDownloadable: Boolean, + isEditable: Boolean, + showExtension: Boolean, + showFilename: Boolean, + }, + template: 'mail.Attachment', +}); + +return Attachment; + +}); |
