diff --git a/app/javascript/vue/shared/content/attachments/context_menu.vue b/app/javascript/vue/shared/content/attachments/context_menu.vue index 3ce4acfae..308c0b0d3 100644 --- a/app/javascript/vue/shared/content/attachments/context_menu.vue +++ b/app/javascript/vue/shared/content/attachments/context_menu.vue @@ -52,13 +52,14 @@ import deleteAttachmentModal from './delete_modal.vue' import moveAssetModal from '../modal/move.vue' import MoveMixin from './mixins/move.js' + import OpenLocallyMixin from './mixins/open_locally.js' import MenuDropdown from '../../menu_dropdown.vue' import axios from '../../../../packs/custom_axios' export default { name: 'contextMenu', components: { deleteAttachmentModal, moveAssetModal, MenuDropdown }, - mixins: [MoveMixin], + mixins: [MoveMixin, OpenLocallyMixin], props: { attachment: { type: Object, @@ -102,9 +103,13 @@ emit: 'open_scinote_editor', }) } - if (this.attachment.attributes.urls.open_locally) { + if (this.canOpenLocally) { + const text = this.localAppName ? + this.i18n.t('attachments.open_locally_in', { application: this.localAppName }) : + this.i18n.t('attachments.open_locally') + menu.push({ - text: this.i18n.t('Open_locally'), + text: text, emit: 'open_locally' }) } @@ -140,18 +145,6 @@ } }, methods: { - async openLocally() { - try { - const response = await axios.get(this.attachment.attributes.urls.open_locally); - const data = response.data; - const syncUrlResponse = await axios.get('/asset_sync_api_url'); - const syncUrl = syncUrlResponse.data; - await axios.post(syncUrl, data); - } catch (error) { - console.error("Error in request:", error); - } - }, - // TODO: add method to handle get to SciNote and then post to local URL changeViewMode(viewMode) { this.$emit('attachment:viewMode', viewMode) $.ajax({ diff --git a/app/javascript/vue/shared/content/attachments/mixins/open_locally.js b/app/javascript/vue/shared/content/attachments/mixins/open_locally.js new file mode 100644 index 000000000..d49baf054 --- /dev/null +++ b/app/javascript/vue/shared/content/attachments/mixins/open_locally.js @@ -0,0 +1,56 @@ +import axios from '../../../../../packs/custom_axios.js'; + +export default { + data() { + return { + localAppName: null, + scinoteEditRunning: false + }; + }, + computed: { + canOpenLocally() { + return this.scinoteEditRunning && + !!this.attachment.attributes.urls.open_locally && + this.attachment.attributes.asset_type !== 'gene_sequence' && + this.attachment.attributes.asset_type !== 'marvinjs' + } + }, + mounted() { + this.$nextTick(() => { + this.fetchLocalAppInfo(); + }); + }, + methods: { + async fetchLocalAppInfo() { + try { + const statusResponse = await axios.get( + `${this.attachment.attributes.urls.open_locally_api}/status` + ); + + if (statusResponse.status === 200) { + this.scinoteEditRunning = true; + } else { + return; + } + + const response = await axios.get( + `${this.attachment.attributes.urls.open_locally_api}/default-application/${this.attachment.attributes.file_extension}` + ); + + this.localAppName = response.data.application; + } catch (error) { + console.error("Error in request: ", error); + } + }, + async openLocally() { + try { + const response = await axios.get(this.attachment.attributes.urls.open_locally); + const data = response.data; + await axios.post(this.attachment.attributes.urls.open_locally_api + '/download', data); + } catch (error) { + console.error("Error in request:", error); + } + } + } +} + diff --git a/app/permissions/asset.rb b/app/permissions/asset.rb index 7bf9821e8..fca1cde59 100644 --- a/app/permissions/asset.rb +++ b/app/permissions/asset.rb @@ -31,4 +31,8 @@ Canaid::Permissions.register_for(Asset) do end end end + + can :open_asset_locally do |_user, asset| + ENV['ASSET_SYNC_URL'].present? + end end diff --git a/app/serializers/asset_serializer.rb b/app/serializers/asset_serializer.rb index 9f601f7f2..9dcbfade1 100644 --- a/app/serializers/asset_serializer.rb +++ b/app/serializers/asset_serializer.rb @@ -8,7 +8,7 @@ class AssetSerializer < ActiveModel::Serializer include InputSanitizeHelper include ApplicationHelper - attributes :file_name, :view_mode, :icon, :urls, :updated_at_formatted, + attributes :file_name, :file_extension, :view_mode, :icon, :urls, :updated_at_formatted, :file_size, :medium_preview, :large_preview, :asset_type, :wopi, :wopi_context, :pdf_previewable, :file_size_formatted, :asset_order, :updated_at, :metadata, :image_editable, :image_context, :pdf, :attached, :parent_type @@ -21,6 +21,10 @@ class AssetSerializer < ActiveModel::Serializer object.render_file_name end + def file_extension + File.extname(object.file_name)[1..] + end + def updated_at object.updated_at.to_i end @@ -135,16 +139,15 @@ class AssetSerializer < ActiveModel::Serializer ) end urls[:open_vector_editor_edit] = edit_gene_sequence_asset_path(object.id) if can_manage_asset?(user, object) - urls[:open_locally] = asset_sync_show_path(object) if can_manage_asset?(user, object) && can_open_locally? + + if can_manage_asset?(user, object) && can_open_asset_locally?(user, object) + urls[:open_locally] = asset_sync_show_path(object) + urls[:open_locally_api] = Constants::ASSET_SYNC_URL + end + urls[:wopi_action] = object.get_action_url(user, 'embedview') if wopi && can_manage_asset?(user, object) urls[:blob] = rails_blob_path(object.file, disposition: 'attachment') if object.file.attached? urls end - - private - - def can_open_locally? - ENV['ASSET_SYNC_URL'].present? - end end diff --git a/config/initializers/extends.rb b/config/initializers/extends.rb index 73cd9b033..a5d9926fd 100644 --- a/config/initializers/extends.rb +++ b/config/initializers/extends.rb @@ -611,7 +611,8 @@ class Extends ) if Constants::ASSET_SYNC_URL && EXTERNAL_SERVICES.exclude?(Constants::ASSET_SYNC_URL) - EXTERNAL_SERVICES << Constants::ASSET_SYNC_URL + asset_sync_url = URI.parse(Constants::ASSET_SYNC_URL) + EXTERNAL_SERVICES << "#{asset_sync_url.host}:#{asset_sync_url.port}" end COLORED_BACKGROUND_ACTIONS = %w( diff --git a/config/locales/en.yml b/config/locales/en.yml index ea1addb34..9535cd0b4 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -395,6 +395,8 @@ en: add: "ADD" sort_by: "SORT BY" attachments_view_mode: "ALL ATTACHMENTS VIEW SIZE" + open_locally_in: "Open in %{application}" + open_locally: "Open locally" new: description: 'New' uploading: 'Uploading' @@ -3867,7 +3869,6 @@ en: Add: "Add" Asset: "File" Assets: "Files" - Open_locally: "Open locally" Download: "Download" Edit: "Edit" Save: "Save"