From 7376b363a87d6e898dfdecc970dc7c9c873ae94d Mon Sep 17 00:00:00 2001
From: Martin Artnik <85488244+artoscinote@users.noreply.github.com>
Date: Tue, 17 Oct 2023 11:36:08 +0200
Subject: [PATCH 001/128] Asset sync model and endpoints [SCI-9465] (#6399)
---
app/controllers/asset_sync_controller.rb | 43 +++++++++++++++++++
app/models/asset.rb | 1 +
app/models/asset_sync_token.rb | 33 ++++++++++++++
app/models/user.rb | 1 +
.../asset_sync_token_serializer.rb | 19 ++++++++
config/initializers/constants.rb | 2 +
config/routes.rb | 3 ++
...20231006141428_create_asset_sync_tokens.rb | 15 +++++++
db/schema.rb | 17 +++++++-
9 files changed, 133 insertions(+), 1 deletion(-)
create mode 100644 app/controllers/asset_sync_controller.rb
create mode 100644 app/models/asset_sync_token.rb
create mode 100644 app/serializers/asset_sync_token_serializer.rb
create mode 100644 db/migrate/20231006141428_create_asset_sync_tokens.rb
diff --git a/app/controllers/asset_sync_controller.rb b/app/controllers/asset_sync_controller.rb
new file mode 100644
index 000000000..75b9a7ad9
--- /dev/null
+++ b/app/controllers/asset_sync_controller.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+class AssetSyncController < ApplicationController
+ skip_before_action :authenticate_user!, only: :update
+ skip_before_action :verify_authenticity_token, only: :update
+ before_action :authenticate_asset_sync_token!, only: :update
+
+ def show
+ asset = Asset.find_by(params[:asset_id])
+
+ head :forbidden unless asset && can_manage_asset?(asset)
+
+ asset_sync_token = current_user.asset_sync_tokens.find_or_create_by(asset_id: params[:asset_id])
+
+ unless asset_sync_token.token_valid?
+ asset_sync_token = current_user.asset_sync_tokens.create(asset_id: params[:asset_id])
+ end
+
+ render json: AssetSyncTokenSerializer.new(asset_sync_token).as_json
+ end
+
+ def update
+ head(:conflict) and return if @asset_sync_token.conflicts?(request.headers['VersionToken'])
+
+ @asset.file.attach(io: request.body, filename: @asset.file.filename)
+ @asset.touch
+
+ render json: AssetSyncTokenSerializer.new(@asset_sync_token).as_json
+ end
+
+ # private
+
+ def authenticate_asset_sync_token!
+ @asset_sync_token = AssetSyncToken.find_by(token: request.headers['Authentication'])
+
+ head(:unauthorized) and return unless @asset_sync_token&.token_valid?
+
+ @asset = @asset_sync_token.asset
+ @current_user = @asset_sync_token.user
+
+ head :forbidden unless can_manage_asset?(@asset)
+ end
+end
diff --git a/app/models/asset.rb b/app/models/asset.rb
index 64a9e1235..928710fd2 100644
--- a/app/models/asset.rb
+++ b/app/models/asset.rb
@@ -44,6 +44,7 @@ class Asset < ApplicationRecord
dependent: :nullify
has_many :report_elements, inverse_of: :asset, dependent: :destroy
has_one :asset_text_datum, inverse_of: :asset, dependent: :destroy
+ has_many :asset_sync_tokens, dependent: :destroy
scope :sort_assets, lambda { |sort_value = 'new'|
sort = case sort_value
diff --git a/app/models/asset_sync_token.rb b/app/models/asset_sync_token.rb
new file mode 100644
index 000000000..8c1224366
--- /dev/null
+++ b/app/models/asset_sync_token.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+class AssetSyncToken < ApplicationRecord
+ belongs_to :user
+ belongs_to :asset
+
+ after_initialize :generate_token
+ after_initialize :set_default_expiration
+
+ validates :token, uniqueness: true, presence: true
+
+ def version_token
+ asset.updated_at.to_i.to_s
+ end
+
+ def token_valid?
+ !revoked_at? && expires_at > Time.current
+ end
+
+ def conflicts?(token)
+ version_token != token
+ end
+
+ private
+
+ def generate_token
+ self.token ||= SecureRandom.urlsafe_base64(32)
+ end
+
+ def set_default_expiration
+ self.expires_at ||= Constants::ASSET_SYNC_TOKEN_EXPIRATION.from_now
+ end
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index d659da492..3458807e2 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -318,6 +318,7 @@ class User < ApplicationRecord
has_many :access_tokens, class_name: 'Doorkeeper::AccessToken',
foreign_key: :resource_owner_id,
dependent: :delete_all
+ has_many :asset_sync_tokens, dependent: :destroy
has_many :hidden_repository_cell_reminders, dependent: :destroy
diff --git a/app/serializers/asset_sync_token_serializer.rb b/app/serializers/asset_sync_token_serializer.rb
new file mode 100644
index 000000000..cccf23a36
--- /dev/null
+++ b/app/serializers/asset_sync_token_serializer.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AssetSyncTokenSerializer < ActiveModel::Serializer
+ include Rails.application.routes.url_helpers
+
+ attributes :url, :asset_id, :filename, :token, :asset_id, :version_token, :checksum
+
+ def checksum
+ object.asset.file.checksum
+ end
+
+ def url
+ object.asset.file.url
+ end
+
+ def filename
+ object.asset.file.filename
+ end
+end
diff --git a/config/initializers/constants.rb b/config/initializers/constants.rb
index b1b035f19..246b48430 100644
--- a/config/initializers/constants.rb
+++ b/config/initializers/constants.rb
@@ -416,6 +416,8 @@ class Constants
FAST_STATUS_POLLING_INTERVAL = 5000
SLOW_STATUS_POLLING_INTERVAL = 10000
+ ASSET_SYNC_TOKEN_EXPIRATION = 1.year
+
# ) \ / (
# /|\ )\_/( /|\
# * / | \ (/\|/\) / | \ *
diff --git a/config/routes.rb b/config/routes.rb
index 0aec0fcc9..d97a6e320 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1002,6 +1002,9 @@ Rails.application.routes.draw do
end
end
+ get 'asset_sync/:asset_id', to: 'asset_sync#show'
+ put 'asset_sync', to: 'asset_sync#update'
+
post 'global_activities', to: 'global_activities#index'
constraints WopiSubdomain do
diff --git a/db/migrate/20231006141428_create_asset_sync_tokens.rb b/db/migrate/20231006141428_create_asset_sync_tokens.rb
new file mode 100644
index 000000000..f9734cd81
--- /dev/null
+++ b/db/migrate/20231006141428_create_asset_sync_tokens.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class CreateAssetSyncTokens < ActiveRecord::Migration[7.0]
+ def change
+ create_table :asset_sync_tokens do |t|
+ t.references :user, null: false, foreign_key: true
+ t.references :asset, null: false, foreign_key: true
+ t.string :token, index: { unique: true }
+ t.timestamp :expires_at
+ t.timestamp :revoked_at
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 184a209eb..eac28b41c 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.0].define(version: 2023_10_03_114337) do
+ActiveRecord::Schema[7.0].define(version: 2023_10_06_141428) do
# These are extensions that must be enabled in order to support this database
enable_extension "btree_gist"
enable_extension "pg_trgm"
@@ -76,6 +76,19 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_03_114337) do
t.datetime "updated_at", null: false
end
+ create_table "asset_sync_tokens", force: :cascade do |t|
+ t.bigint "user_id", null: false
+ t.bigint "asset_id", null: false
+ t.string "token"
+ t.datetime "expires_at", precision: nil
+ t.datetime "revoked_at", precision: nil
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["asset_id"], name: "index_asset_sync_tokens_on_asset_id"
+ t.index ["token"], name: "index_asset_sync_tokens_on_token", unique: true
+ t.index ["user_id"], name: "index_asset_sync_tokens_on_user_id"
+ end
+
create_table "asset_text_data", force: :cascade do |t|
t.text "data", null: false
t.bigint "asset_id", null: false
@@ -1309,6 +1322,8 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_03_114337) do
add_foreign_key "activities", "my_modules"
add_foreign_key "activities", "projects"
add_foreign_key "activities", "users", column: "owner_id"
+ add_foreign_key "asset_sync_tokens", "assets"
+ add_foreign_key "asset_sync_tokens", "users"
add_foreign_key "asset_text_data", "assets"
add_foreign_key "assets", "users", column: "created_by_id"
add_foreign_key "assets", "users", column: "last_modified_by_id"
From 20312862614cd8c7e057f8f903b7e4f0920e094c Mon Sep 17 00:00:00 2001
From: Ivan Kljun
Date: Thu, 19 Oct 2023 11:53:18 +0200
Subject: [PATCH 002/128] Implement file-checkout localhost call [SCI-9466]
---
.../javascripts/sitewide/constants.js.erb | 1 +
app/controllers/asset_sync_controller.rb | 2 +-
.../shared/content/attachments/context_menu.vue | 17 +++++++++++++++++
app/serializers/asset_serializer.rb | 3 ++-
config/initializers/constants.rb | 1 +
config/initializers/extends.rb | 2 ++
config/locales/en.yml | 1 +
config/routes.rb | 2 +-
8 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/app/assets/javascripts/sitewide/constants.js.erb b/app/assets/javascripts/sitewide/constants.js.erb
index 7f473c423..8e37b3abc 100644
--- a/app/assets/javascripts/sitewide/constants.js.erb
+++ b/app/assets/javascripts/sitewide/constants.js.erb
@@ -14,4 +14,5 @@ const GLOBAL_CONSTANTS = {
FILENAME_MAX_LENGTH: <%= Constants::FILENAME_MAX_LENGTH %>,
FAST_STATUS_POLLING_INTERVAL: <%= Constants::FAST_STATUS_POLLING_INTERVAL %>,
SLOW_STATUS_POLLING_INTERVAL: <%= Constants::SLOW_STATUS_POLLING_INTERVAL %>,
+ ASSET_SYNC_URL: '<%= Constants::ASSET_SYNC_URL %>',
};
diff --git a/app/controllers/asset_sync_controller.rb b/app/controllers/asset_sync_controller.rb
index 75b9a7ad9..c271fc518 100644
--- a/app/controllers/asset_sync_controller.rb
+++ b/app/controllers/asset_sync_controller.rb
@@ -6,7 +6,7 @@ class AssetSyncController < ApplicationController
before_action :authenticate_asset_sync_token!, only: :update
def show
- asset = Asset.find_by(params[:asset_id])
+ asset = Asset.find_by(id: params[:asset_id])
head :forbidden unless asset && can_manage_asset?(asset)
diff --git a/app/javascript/vue/shared/content/attachments/context_menu.vue b/app/javascript/vue/shared/content/attachments/context_menu.vue
index 768093634..fe10d58b8 100644
--- a/app/javascript/vue/shared/content/attachments/context_menu.vue
+++ b/app/javascript/vue/shared/content/attachments/context_menu.vue
@@ -30,6 +30,7 @@
@open_ove_editor="openOVEditor(attachment.attributes.urls.open_vector_editor_edit)"
@open_marvinjs_editor="openMarvinJsEditor"
@open_scinote_editor="openScinoteEditor"
+ @open_locally="openLocally"
@delete="deleteModal = true"
@viewMode="changeViewMode"
@move="showMoveModal"
@@ -52,6 +53,7 @@
import moveAssetModal from '../modal/move.vue'
import MoveMixin from './mixins/move.js'
import MenuDropdown from '../../menu_dropdown.vue'
+ import axios from '../../../../packs/custom_axios'
export default {
name: 'contextMenu',
@@ -100,6 +102,10 @@
emit: 'open_scinote_editor',
})
}
+ menu.push({
+ text: this.i18n.t('Open_locally'),
+ emit: 'open_locally'
+ })
menu.push({
text: this.i18n.t('Download'),
url: this.attachment.attributes.urls.download,
@@ -132,6 +138,17 @@
}
},
methods: {
+ async openLocally() {
+ try {
+ const response = await axios.get(this.attachment.attributes.urls.open_locally);
+ const data = response.data;
+ const syncUrl = GLOBAL_CONSTANTS.ASSET_SYNC_URL;
+ 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/serializers/asset_serializer.rb b/app/serializers/asset_serializer.rb
index 810f1d5fc..0b344a64a 100644
--- a/app/serializers/asset_serializer.rb
+++ b/app/serializers/asset_serializer.rb
@@ -131,7 +131,8 @@ class AssetSerializer < ActiveModel::Serializer
start_edit_image: start_edit_image_path(object),
delete: asset_destroy_path(object),
move_targets: asset_move_tagets_path(object),
- move: asset_move_path(object)
+ move: asset_move_path(object),
+ open_locally: asset_sync_show_path(object)
)
end
urls[:open_vector_editor_edit] = edit_gene_sequence_asset_path(object.id) if can_manage_asset?(user, object)
diff --git a/config/initializers/constants.rb b/config/initializers/constants.rb
index 246b48430..94fc56bc5 100644
--- a/config/initializers/constants.rb
+++ b/config/initializers/constants.rb
@@ -417,6 +417,7 @@ class Constants
SLOW_STATUS_POLLING_INTERVAL = 10000
ASSET_SYNC_TOKEN_EXPIRATION = 1.year
+ ASSET_SYNC_URL = ENV['ASSET_SYNC_URL'].freeze
# ) \ / (
# /|\ )\_/( /|\
diff --git a/config/initializers/extends.rb b/config/initializers/extends.rb
index adce2e064..f4719ef2e 100644
--- a/config/initializers/extends.rb
+++ b/config/initializers/extends.rb
@@ -610,6 +610,8 @@ class Extends
www.gstatic.com/recaptcha/
)
+ EXTERNAL_SERVICES << Constants::ASSET_SYNC_URL unless EXTERNAL_SERVICES.include?(Constants::ASSET_SYNC_URL)
+
COLORED_BACKGROUND_ACTIONS = %w(
my_modules/protocols
my_modules/signatures
diff --git a/config/locales/en.yml b/config/locales/en.yml
index f62736425..9b1ae3f34 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -3858,6 +3858,7 @@ en:
Add: "Add"
Asset: "File"
Assets: "Files"
+ Open_locally: "Open locally"
Download: "Download"
Edit: "Edit"
Save: "Save"
diff --git a/config/routes.rb b/config/routes.rb
index d97a6e320..1d61ab2db 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1002,7 +1002,7 @@ Rails.application.routes.draw do
end
end
- get 'asset_sync/:asset_id', to: 'asset_sync#show'
+ get 'asset_sync/:asset_id', to: 'asset_sync#show', as: :asset_sync_show
put 'asset_sync', to: 'asset_sync#update'
post 'global_activities', to: 'global_activities#index'
From d181465e121f11c5e21801adba8d2c7fc67452c6 Mon Sep 17 00:00:00 2001
From: Martin Artnik
Date: Tue, 24 Oct 2023 13:51:25 +0200
Subject: [PATCH 003/128] Fix initialization and add download endpoint
[SCI-9465]
---
app/controllers/asset_sync_controller.rb | 10 +++++++---
app/serializers/asset_sync_token_serializer.rb | 2 +-
config/initializers/extends.rb | 4 +++-
config/routes.rb | 1 +
4 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/app/controllers/asset_sync_controller.rb b/app/controllers/asset_sync_controller.rb
index c271fc518..00b51ef30 100644
--- a/app/controllers/asset_sync_controller.rb
+++ b/app/controllers/asset_sync_controller.rb
@@ -1,9 +1,9 @@
# frozen_string_literal: true
class AssetSyncController < ApplicationController
- skip_before_action :authenticate_user!, only: :update
- skip_before_action :verify_authenticity_token, only: :update
- before_action :authenticate_asset_sync_token!, only: :update
+ skip_before_action :authenticate_user!, only: %i(update download)
+ skip_before_action :verify_authenticity_token, only: %i(update download)
+ before_action :authenticate_asset_sync_token!, only: %i(update download)
def show
asset = Asset.find_by(id: params[:asset_id])
@@ -19,6 +19,10 @@ class AssetSyncController < ApplicationController
render json: AssetSyncTokenSerializer.new(asset_sync_token).as_json
end
+ def download
+ redirect_to @asset.file.url
+ end
+
def update
head(:conflict) and return if @asset_sync_token.conflicts?(request.headers['VersionToken'])
diff --git a/app/serializers/asset_sync_token_serializer.rb b/app/serializers/asset_sync_token_serializer.rb
index cccf23a36..87ded4ad6 100644
--- a/app/serializers/asset_sync_token_serializer.rb
+++ b/app/serializers/asset_sync_token_serializer.rb
@@ -10,7 +10,7 @@ class AssetSyncTokenSerializer < ActiveModel::Serializer
end
def url
- object.asset.file.url
+ asset_sync_download_url(asset_id: object.asset)
end
def filename
diff --git a/config/initializers/extends.rb b/config/initializers/extends.rb
index f4719ef2e..73cd9b033 100644
--- a/config/initializers/extends.rb
+++ b/config/initializers/extends.rb
@@ -610,7 +610,9 @@ class Extends
www.gstatic.com/recaptcha/
)
- EXTERNAL_SERVICES << Constants::ASSET_SYNC_URL unless EXTERNAL_SERVICES.include?(Constants::ASSET_SYNC_URL)
+ if Constants::ASSET_SYNC_URL && EXTERNAL_SERVICES.exclude?(Constants::ASSET_SYNC_URL)
+ EXTERNAL_SERVICES << Constants::ASSET_SYNC_URL
+ end
COLORED_BACKGROUND_ACTIONS = %w(
my_modules/protocols
diff --git a/config/routes.rb b/config/routes.rb
index 1d61ab2db..82b899f8a 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1003,6 +1003,7 @@ Rails.application.routes.draw do
end
get 'asset_sync/:asset_id', to: 'asset_sync#show', as: :asset_sync_show
+ get 'asset_sync/:asset_id/download', to: 'asset_sync#download', as: :asset_sync_download
put 'asset_sync', to: 'asset_sync#update'
post 'global_activities', to: 'global_activities#index'
From 22a130e5025f558a81aee454ee9cacc326b3bcbe Mon Sep 17 00:00:00 2001
From: Martin Artnik
Date: Wed, 25 Oct 2023 09:27:27 +0200
Subject: [PATCH 004/128] Fix download endpoint to allow redirects to other
hosts [SCI-9465]
---
app/controllers/asset_sync_controller.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/controllers/asset_sync_controller.rb b/app/controllers/asset_sync_controller.rb
index 00b51ef30..1eff86d04 100644
--- a/app/controllers/asset_sync_controller.rb
+++ b/app/controllers/asset_sync_controller.rb
@@ -20,7 +20,7 @@ class AssetSyncController < ApplicationController
end
def download
- redirect_to @asset.file.url
+ redirect_to(@asset.file.url, allow_other_host: true)
end
def update
From f015c8c56e8487dc7b6641c8d82c01afa2243f2b Mon Sep 17 00:00:00 2001
From: Martin Artnik
Date: Fri, 3 Nov 2023 09:46:05 +0100
Subject: [PATCH 005/128] Create a copy of the synced file in case of conflict
[SCI-9640]
---
app/controllers/asset_sync_controller.rb | 28 +++++++++++++++++++++++-
app/models/asset.rb | 4 ++++
config/locales/en.yml | 1 +
3 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/app/controllers/asset_sync_controller.rb b/app/controllers/asset_sync_controller.rb
index 1eff86d04..5cf619ccc 100644
--- a/app/controllers/asset_sync_controller.rb
+++ b/app/controllers/asset_sync_controller.rb
@@ -24,7 +24,13 @@ class AssetSyncController < ApplicationController
end
def update
- head(:conflict) and return if @asset_sync_token.conflicts?(request.headers['VersionToken'])
+ if @asset_sync_token.conflicts?(request.headers['VersionToken'])
+ render(
+ json: AssetSyncTokenSerializer.new(conflicting_asset_copy_token).as_json,
+ status: :conflict
+ )
+ return
+ end
@asset.file.attach(io: request.body, filename: @asset.file.filename)
@asset.touch
@@ -34,6 +40,26 @@ class AssetSyncController < ApplicationController
# private
+ def conflicting_asset_copy_token
+ Asset.transaction do
+ new_asset = @asset.dup
+ new_asset.save
+ new_asset.file.attach(
+ io: request.body,
+ filename: "#{@asset.file.filename.base} (#{t('general.copy')}).#{@asset.file.filename.extension}"
+ )
+
+ case @asset.parent
+ when Step
+ StepAsset.create!(step: @asset.step, asset: new_asset)
+ when Result
+ ResultAsset.create!(result: @asset.result, asset: new_asset)
+ end
+
+ current_user.asset_sync_tokens.create!(asset_id: new_asset.id)
+ end
+ end
+
def authenticate_asset_sync_token!
@asset_sync_token = AssetSyncToken.find_by(token: request.headers['Authentication'])
diff --git a/app/models/asset.rb b/app/models/asset.rb
index 1429f6a11..1c6387828 100644
--- a/app/models/asset.rb
+++ b/app/models/asset.rb
@@ -466,6 +466,10 @@ class Asset < ApplicationRecord
(result || step)&.my_module
end
+ def parent
+ step || result || repository_cell
+ end
+
private
def tempdir
diff --git a/config/locales/en.yml b/config/locales/en.yml
index bdb781e4a..773218f9e 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -3690,6 +3690,7 @@ en:
edit: "Edit"
delete: "Delete"
cancel: "Cancel"
+ copy: "Copy"
duplicate: "Duplicate"
okay: "Okay"
back: "Back"
From 39ce9c1781aba1b21bdc0694c6ae6138ec1d34f2 Mon Sep 17 00:00:00 2001
From: Giga Chubinidze
Date: Wed, 8 Nov 2023 12:22:34 +0400
Subject: [PATCH 006/128] Enable access to "SciNote File Editor" app installers
via the SciNote web app [SCI-9625]
---
.../settings/account/addons_controller.rb | 1 +
.../settings/account/addons/index.html.erb | 53 ++++++++++++++++++-
config/locales/en.yml | 6 +++
3 files changed, 59 insertions(+), 1 deletion(-)
diff --git a/app/controllers/users/settings/account/addons_controller.rb b/app/controllers/users/settings/account/addons_controller.rb
index c1777ba3c..1c89c96d4 100644
--- a/app/controllers/users/settings/account/addons_controller.rb
+++ b/app/controllers/users/settings/account/addons_controller.rb
@@ -9,6 +9,7 @@ module Users
def index
@label_printer_any = LabelPrinter.any?
+ @user_agent = request.user_agent
end
private
diff --git a/app/views/users/settings/account/addons/index.html.erb b/app/views/users/settings/account/addons/index.html.erb
index e1550715e..68f58a22a 100644
--- a/app/views/users/settings/account/addons/index.html.erb
+++ b/app/views/users/settings/account/addons/index.html.erb
@@ -7,7 +7,58 @@
-
From 53c9be6f21c08a966e4c81fcdc19d4e3ae219f18 Mon Sep 17 00:00:00 2001
From: Ivan Kljun
Date: Thu, 4 Jan 2024 13:59:54 +0100
Subject: [PATCH 035/128] Fix hound suggestions [SCI-9862]
---
.../content/attachments/context_menu.vue | 20 ++++--
.../shared/content/attachments/thumbnail.vue | 66 ++++++++++---------
.../content/modal/no_predefined_app_modal.vue | 2 +-
3 files changed, 50 insertions(+), 38 deletions(-)
diff --git a/app/javascript/vue/shared/content/attachments/context_menu.vue b/app/javascript/vue/shared/content/attachments/context_menu.vue
index 6c60a7d78..b3dfaae5c 100644
--- a/app/javascript/vue/shared/content/attachments/context_menu.vue
+++ b/app/javascript/vue/shared/content/attachments/context_menu.vue
@@ -62,17 +62,23 @@
diff --git a/app/javascript/vue/shared/content/modal/no_predefined_app_modal.vue b/app/javascript/vue/shared/content/modal/no_predefined_app_modal.vue
index d3f42149e..0df7e6ceb 100644
--- a/app/javascript/vue/shared/content/modal/no_predefined_app_modal.vue
+++ b/app/javascript/vue/shared/content/modal/no_predefined_app_modal.vue
@@ -36,5 +36,5 @@ export default {
$(this.$refs.modal).modal('hide');
}
}
-}
+};
From 44556f50702be2193ae266ca3e090b4381a3f7bb Mon Sep 17 00:00:00 2001
From: Ivan Kljun
Date: Fri, 5 Jan 2024 10:50:39 +0100
Subject: [PATCH 036/128] Add Teleport for modals [SCI-9862]
---
.../content/attachments/context_menu.vue | 52 +++++++++----------
.../attachments/mixins/open_locally.js | 13 ++---
config/locales/en.yml | 3 ++
3 files changed, 35 insertions(+), 33 deletions(-)
diff --git a/app/javascript/vue/shared/content/attachments/context_menu.vue b/app/javascript/vue/shared/content/attachments/context_menu.vue
index b3dfaae5c..14ff4e8a4 100644
--- a/app/javascript/vue/shared/content/attachments/context_menu.vue
+++ b/app/javascript/vue/shared/content/attachments/context_menu.vue
@@ -30,34 +30,36 @@
@open_ove_editor="openOVEditor(attachment.attributes.urls.open_vector_editor_edit)"
@open_marvinjs_editor="openMarvinJsEditor"
@open_scinote_editor="openScinoteEditor"
- @open_locally="openLocallyButton"
+ @open_locally="openLocally"
@delete="deleteModal = true"
@viewMode="changeViewMode"
@move="showMoveModal"
>
-
-
-
-
+
+ @confirm="deleteAttachment"
+ @cancel="deleteModal = false"
+ />
+
+
+
+
@@ -193,10 +195,6 @@ export default {
);
$(this.$refs.marvinjsEditButton).trigger('click');
},
- openLocallyButton() {
- this.editAppModal = true;
- this.$emit(this.openLocally());
- },
openScinoteEditor() {
$(this.$refs.imageEditButton).trigger('click');
}
diff --git a/app/javascript/vue/shared/content/attachments/mixins/open_locally.js b/app/javascript/vue/shared/content/attachments/mixins/open_locally.js
index 5c8014ca8..fab8ea447 100644
--- a/app/javascript/vue/shared/content/attachments/mixins/open_locally.js
+++ b/app/javascript/vue/shared/content/attachments/mixins/open_locally.js
@@ -39,20 +39,21 @@ export default {
this.localAppName = response.data.application;
} catch (error) {
- console.error("Error in request: ", error);
+ console.error('Error in request: ', error);
}
},
async openLocally() {
if (this.localAppName === null) {
- this.showNoPredefinedAppModal = true;
- return
+ this.showNoPredefinedAppModal = true;
+ return;
}
+
+ this.editAppModal = true;
try {
- const response = await axios.get(this.attachment.attributes.urls.open_locally);
- const data = response.data;
+ const { data } = await axios.get(this.attachment.attributes.urls.open_locally);
await axios.post(this.attachment.attributes.urls.open_locally_api + '/download', data);
} catch (error) {
- console.error("Error in request:", error);
+ console.error('Error in request:', error);
}
}
}
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 4293c342e..e6eb5ee3e 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -3566,6 +3566,9 @@ en:
body_text_html: "The specified application for accessing the %{file_name} is not preconfigured. To successfully open this file, please set up the appropriate application in your local environment beforehand.
"
no_predefined_app: "I understand"
set_up_app: "Set up an application to open this file"
+ edit_launching_application_modal:
+ title: "Launching application"
+ description: "%{file_name} will now open in %{application}. Saved changes in %{application} will automatically be synced in SciNote."
atwho:
no_results:
From 245c848c9996acb1d15410a709874ad4d6bd7c41 Mon Sep 17 00:00:00 2001
From: Ivan Kljun
Date: Tue, 9 Jan 2024 09:44:00 +0100
Subject: [PATCH 037/128] Change to asset_download_path in Asset Serializer
[SCI-9806]
---
app/serializers/asset_serializer.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/serializers/asset_serializer.rb b/app/serializers/asset_serializer.rb
index 764a08f8e..a3049393d 100644
--- a/app/serializers/asset_serializer.rb
+++ b/app/serializers/asset_serializer.rb
@@ -120,7 +120,7 @@ class AssetSerializer < ActiveModel::Serializer
def urls
urls = {
preview: asset_file_preview_path(object),
- download: (rails_blob_path(object.file, disposition: 'attachment') if attached),
+ download: (asset_download_path(object) if attached),
load_asset: load_asset_path(object),
asset_file: asset_file_url_path(object),
marvin_js: marvin_js_asset_path(object),
From 22b7424884514e43e2808c011e9f1019e78d1810 Mon Sep 17 00:00:00 2001
From: Ivan Kljun
Date: Thu, 11 Jan 2024 10:41:11 +0100
Subject: [PATCH 038/128] Handle Windows not having an appropriate app for
SciNote Edit [SCI-9862]
---
.../vue/shared/content/attachments/mixins/open_locally.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/app/javascript/vue/shared/content/attachments/mixins/open_locally.js b/app/javascript/vue/shared/content/attachments/mixins/open_locally.js
index fab8ea447..777b59ff9 100644
--- a/app/javascript/vue/shared/content/attachments/mixins/open_locally.js
+++ b/app/javascript/vue/shared/content/attachments/mixins/open_locally.js
@@ -37,7 +37,9 @@ export default {
`${this.attachment.attributes.urls.open_locally_api}/default-application/${this.attachment.attributes.file_extension}`
);
- this.localAppName = response.data.application;
+ if (response.data.application.toLowerCase() !== 'pick an app') {
+ this.localAppName = response.data.application;
+ }
} catch (error) {
console.error('Error in request: ', error);
}
From 83a2657bd1500bcb78033b9e9191d0ad0e03fd04 Mon Sep 17 00:00:00 2001
From: Giga Chubinidze
Date: Fri, 12 Jan 2024 03:10:11 +0400
Subject: [PATCH 039/128] Improvements of the SciNote Edit option in "Add-ons"
[SCI-9962][SCI9760]
---
.../packs/vue/scinote_edit_download.js | 9 ++
.../vue/shared/scinote_edit_download.vue | 100 ++++++++++++++++++
.../settings/account/addons/index.html.erb | 70 ++++--------
config/initializers/extends.rb | 2 +
config/locales/en.yml | 6 +-
config/webpack/webpack.config.js | 1 +
6 files changed, 133 insertions(+), 55 deletions(-)
create mode 100644 app/javascript/packs/vue/scinote_edit_download.js
create mode 100644 app/javascript/vue/shared/scinote_edit_download.vue
diff --git a/app/javascript/packs/vue/scinote_edit_download.js b/app/javascript/packs/vue/scinote_edit_download.js
new file mode 100644
index 000000000..ad7eabd15
--- /dev/null
+++ b/app/javascript/packs/vue/scinote_edit_download.js
@@ -0,0 +1,9 @@
+import { createApp } from 'vue/dist/vue.esm-bundler.js';
+import ScinoteEditDownload from '../../vue/shared/scinote_edit_download.vue';
+import { mountWithTurbolinks } from './helpers/turbolinks.js';
+
+
+const app = createApp({});
+app.component('ScinoteEditDownload', ScinoteEditDownload);
+app.config.globalProperties.i18n = window.I18n;
+mountWithTurbolinks(app, '#scinoteEditDownload');
diff --git a/app/javascript/vue/shared/scinote_edit_download.vue b/app/javascript/vue/shared/scinote_edit_download.vue
new file mode 100644
index 000000000..f1f7f5d40
--- /dev/null
+++ b/app/javascript/vue/shared/scinote_edit_download.vue
@@ -0,0 +1,100 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/views/users/settings/account/addons/index.html.erb b/app/views/users/settings/account/addons/index.html.erb
index 68f58a22a..9871106d8 100644
--- a/app/views/users/settings/account/addons/index.html.erb
+++ b/app/views/users/settings/account/addons/index.html.erb
@@ -7,58 +7,6 @@
<%= t('users.settings.account.addons.title') %>
-
-
-
-
-
<%= t('users.settings.account.addons.desktop_app.title') %>
-
- <%= t('users.settings.account.addons..desktop_app.description') %>
-
-
-
-
-
-
<%= t('users.settings.account.addons.scinote_addons') %>
@@ -68,6 +16,22 @@
+
+
+
+
+
+
<%= t('users.settings.account.addons.desktop_app.title') %>
+
+ <%= t('users.settings.account.addons.desktop_app.description') %>
+
+
+
+
+
+
+
+
<%= t('users.settings.account.addons.label_printers') %>
@@ -117,3 +81,5 @@
+
+<%= javascript_include_tag "vue_scinote_edit_download", nonce: true %>
diff --git a/config/initializers/extends.rb b/config/initializers/extends.rb
index 3247672cb..5924070a9 100644
--- a/config/initializers/extends.rb
+++ b/config/initializers/extends.rb
@@ -605,6 +605,8 @@ class Extends
*.nr-data.net
www.recaptcha.net/
www.gstatic.com/recaptcha/
+ extras.scinote.net
+ https://www.scinote.net
)
if Constants::ASSET_SYNC_URL && EXTERNAL_SERVICES.exclude?(Constants::ASSET_SYNC_URL)
diff --git a/config/locales/en.yml b/config/locales/en.yml
index e6eb5ee3e..f4e26e0f7 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -2754,11 +2754,11 @@ en:
description: 'Print labels of custom styles and sizes in seconds flat from your PC or Mac via your Zebra printer connected via USB, Internet or LAN.'
details: 'Details'
desktop_app:
- title: 'SciNote File Editor desktop app'
- description: 'Download the SciNote File Editor desktop app to automatically edit files using locally installed software'
+ title: 'SciNote Edit'
+ description: 'Download the SciNote Edit desktop app to automatically edit files using locally installed software.'
macos_button: 'Download for macOS'
windows_button: 'Download for Windows'
- version: 'Version'
+ version: 'Version %{version}'
label_printer:
fluics_printer: "FLUICS Print: Label printers"
zebra_printer: 'Zebra label printers'
diff --git a/config/webpack/webpack.config.js b/config/webpack/webpack.config.js
index 12a4d9e76..42ccf40be 100644
--- a/config/webpack/webpack.config.js
+++ b/config/webpack/webpack.config.js
@@ -47,6 +47,7 @@ const entryList = {
vue_user_preferences: './app/javascript/packs/vue/user_preferences.js',
vue_components_manage_stock_value_modal: './app/javascript/packs/vue/manage_stock_value_modal.js',
vue_legacy_datetime_picker: './app/javascript/packs/vue/legacy/datetime_picker.js',
+ vue_scinote_edit_download: './app/javascript/packs/vue/scinote_edit_download.js'
}
// Engine pack loading based on https://github.com/rails/webpacker/issues/348#issuecomment-635480949
From 5250bade57b909427c549859b41ee29848244600 Mon Sep 17 00:00:00 2001
From: Giga Chubinidze
Date: Fri, 12 Jan 2024 03:16:10 +0400
Subject: [PATCH 040/128] hound fix
---
.../packs/vue/scinote_edit_download.js | 1 -
.../vue/shared/scinote_edit_download.vue | 20 +++++++++++--------
2 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/app/javascript/packs/vue/scinote_edit_download.js b/app/javascript/packs/vue/scinote_edit_download.js
index ad7eabd15..85640284a 100644
--- a/app/javascript/packs/vue/scinote_edit_download.js
+++ b/app/javascript/packs/vue/scinote_edit_download.js
@@ -2,7 +2,6 @@ import { createApp } from 'vue/dist/vue.esm-bundler.js';
import ScinoteEditDownload from '../../vue/shared/scinote_edit_download.vue';
import { mountWithTurbolinks } from './helpers/turbolinks.js';
-
const app = createApp({});
app.component('ScinoteEditDownload', ScinoteEditDownload);
app.config.globalProperties.i18n = window.I18n;
diff --git a/app/javascript/vue/shared/scinote_edit_download.vue b/app/javascript/vue/shared/scinote_edit_download.vue
index f1f7f5d40..43d82b6ea 100644
--- a/app/javascript/vue/shared/scinote_edit_download.vue
+++ b/app/javascript/vue/shared/scinote_edit_download.vue
@@ -40,7 +40,9 @@
{{ i18n.t('users.settings.account.addons.desktop_app.windows_button') }}
- {{ i18n.t('users.settings.account.addons.desktop_app.version', { version: this.responseData[0]['version']}) }}
+ {{ i18n.t('users.settings.account.addons.desktop_app.version',
+ { version: this.responseData[0]['version']})
+ }}
@@ -54,7 +56,9 @@
{{ i18n.t('users.settings.account.addons.desktop_app.macos_button') }}
- {{ i18n.t('users.settings.account.addons.desktop_app.version', { version: this.responseData[1]['version']}) }}
+ {{ i18n.t('users.settings.account.addons.desktop_app.version',
+ { version: this.responseData[1]['version']})
+ }}
@@ -66,12 +70,12 @@
export default {
name: 'ScinoteEditDownload',
props: {
- data: { type: String, required: true },
+ data: { type: String, required: true }
},
data() {
return {
userAgent: this.data,
- responseData: {},
+ responseData: {}
};
},
computed: {
@@ -80,7 +84,7 @@ export default {
},
isMac() {
return /Mac OS/.test(this.userAgent);
- },
+ }
},
created() {
window.scinoteEditDownload = this;
@@ -94,7 +98,7 @@ export default {
$.get('https://extras.scinote.net/scinote-edit/latest.json', (result) => {
this.responseData = result;
});
- },
- },
+ }
+ }
};
-
\ No newline at end of file
+
From aa47cbad950723bf015b95d50a4b16a72db9060c Mon Sep 17 00:00:00 2001
From: Giga Chubinidze
Date: Mon, 15 Jan 2024 04:43:00 +0400
Subject: [PATCH 041/128] Make File Checkout feature switchable in settings
[SCI-9987]
---
.../settings/account/addons/index.html.erb | 24 ++++++++++---------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/app/views/users/settings/account/addons/index.html.erb b/app/views/users/settings/account/addons/index.html.erb
index 9871106d8..daabf6b61 100644
--- a/app/views/users/settings/account/addons/index.html.erb
+++ b/app/views/users/settings/account/addons/index.html.erb
@@ -17,21 +17,23 @@
-
-
-
-
-
<%= t('users.settings.account.addons.desktop_app.title') %>
-
- <%= t('users.settings.account.addons.desktop_app.description') %>
-
-
-
+ <% if ENV['ASSET_SYNC_URL'] %>
+
+
+
+
+
<%= t('users.settings.account.addons.desktop_app.title') %>
+
+ <%= t('users.settings.account.addons.desktop_app.description') %>
+
+
+
+
-
+ <% end %>
<%= t('users.settings.account.addons.label_printers') %>
From 4e29b4dab80571f5d03bd4647588fc9fb89acb8a Mon Sep 17 00:00:00 2001
From: Giga Chubinidze
Date: Mon, 15 Jan 2024 05:03:18 +0400
Subject: [PATCH 042/128] Add Settings link to Notifications modal [SCI-9986]
---
.../vue/navigation/notifications/notifications_flyout.vue | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/app/javascript/vue/navigation/notifications/notifications_flyout.vue b/app/javascript/vue/navigation/notifications/notifications_flyout.vue
index 75ec2213b..833d07777 100644
--- a/app/javascript/vue/navigation/notifications/notifications_flyout.vue
+++ b/app/javascript/vue/navigation/notifications/notifications_flyout.vue
@@ -2,7 +2,9 @@
From 695c938f22cf5966cd62041cf7d56968c0903118 Mon Sep 17 00:00:00 2001
From: Martin Artnik
Date: Mon, 15 Jan 2024 13:44:50 +0100
Subject: [PATCH 043/128] Fix asset thumbnail hover [SCI-9838]
---
app/javascript/vue/shared/content/attachments/thumbnail.vue | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/javascript/vue/shared/content/attachments/thumbnail.vue b/app/javascript/vue/shared/content/attachments/thumbnail.vue
index 2ec1c0be9..3bbe80b48 100644
--- a/app/javascript/vue/shared/content/attachments/thumbnail.vue
+++ b/app/javascript/vue/shared/content/attachments/thumbnail.vue
@@ -44,7 +44,7 @@
Date: Mon, 15 Jan 2024 15:16:02 +0100
Subject: [PATCH 044/128] Fix issues with local edit buttons after merging
develop [SCI-9841][SCI-9862]
---
app/javascript/vue/shared/content/attachments/context_menu.vue | 1 -
app/javascript/vue/shared/menu_dropdown.vue | 1 +
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/javascript/vue/shared/content/attachments/context_menu.vue b/app/javascript/vue/shared/content/attachments/context_menu.vue
index 6bb3cb3cf..6a1451837 100644
--- a/app/javascript/vue/shared/content/attachments/context_menu.vue
+++ b/app/javascript/vue/shared/content/attachments/context_menu.vue
@@ -83,7 +83,6 @@ export default {
editLaunchingApplicationModal
},
mixins: [MoveMixin, OpenLocallyMixin],
- components: { deleteAttachmentModal, moveAssetModal, MenuDropdown },
props: {
attachment: {
type: Object,
diff --git a/app/javascript/vue/shared/menu_dropdown.vue b/app/javascript/vue/shared/menu_dropdown.vue
index bec8ed99f..cffb6848e 100644
--- a/app/javascript/vue/shared/menu_dropdown.vue
+++ b/app/javascript/vue/shared/menu_dropdown.vue
@@ -79,6 +79,7 @@ export default {
btnClasses: { type: String, default: 'btn btn-light' },
btnText: { type: String, required: false },
btnIcon: { type: String, required: false },
+ title: { type: String, default: '' },
caret: { type: Boolean, default: false }
},
data() {
From 2e1b86f9b2b41e93174becb586fe6f0908d2b6d9 Mon Sep 17 00:00:00 2001
From: Ivan Kljun
Date: Thu, 11 Jan 2024 14:41:32 +0100
Subject: [PATCH 045/128] Fix open locally buttons for thumbnail view
[SCI-9838]
---
.../shared/content/attachments/thumbnail.vue | 36 ++++++++++---------
1 file changed, 20 insertions(+), 16 deletions(-)
diff --git a/app/javascript/vue/shared/content/attachments/thumbnail.vue b/app/javascript/vue/shared/content/attachments/thumbnail.vue
index b4b087b6c..660deaa5f 100644
--- a/app/javascript/vue/shared/content/attachments/thumbnail.vue
+++ b/app/javascript/vue/shared/content/attachments/thumbnail.vue
@@ -44,8 +44,10 @@
-
diff --git a/app/javascript/vue/shared/menu_dropdown.vue b/app/javascript/vue/shared/menu_dropdown.vue
index cffb6848e..61df17ca9 100644
--- a/app/javascript/vue/shared/menu_dropdown.vue
+++ b/app/javascript/vue/shared/menu_dropdown.vue
@@ -1,5 +1,5 @@
-
+
Date: Fri, 19 Jan 2024 20:33:34 +0100
Subject: [PATCH 059/128] Add wizard component [SCI-10035]
---
.../packs/vue/design_system/modals.js | 56 ++++++++++++++
.../vue/design_system/wizard_steps/step_1.vue | 37 ++++++++++
.../vue/design_system/wizard_steps/step_2.vue | 41 +++++++++++
.../vue/design_system/wizard_steps/step_3.vue | 42 +++++++++++
app/javascript/vue/shared/wizard_modal.vue | 73 +++++++++++++++++++
app/views/design_elements/_modals.html.erb | 16 ++++
app/views/design_elements/index.html.erb | 1 +
config/webpack/webpack.config.js | 3 +-
8 files changed, 268 insertions(+), 1 deletion(-)
create mode 100644 app/javascript/packs/vue/design_system/modals.js
create mode 100644 app/javascript/packs/vue/design_system/wizard_steps/step_1.vue
create mode 100644 app/javascript/packs/vue/design_system/wizard_steps/step_2.vue
create mode 100644 app/javascript/packs/vue/design_system/wizard_steps/step_3.vue
create mode 100644 app/javascript/vue/shared/wizard_modal.vue
create mode 100644 app/views/design_elements/_modals.html.erb
diff --git a/app/javascript/packs/vue/design_system/modals.js b/app/javascript/packs/vue/design_system/modals.js
new file mode 100644
index 000000000..66f138567
--- /dev/null
+++ b/app/javascript/packs/vue/design_system/modals.js
@@ -0,0 +1,56 @@
+import { createApp } from 'vue/dist/vue.esm-bundler.js';
+import { shallowRef } from 'vue';
+
+import WizardModal from '../../../vue/shared/wizard_modal.vue';
+import Step1 from './wizard_steps/step_1.vue';
+import Step2 from './wizard_steps/step_2.vue';
+import Step3 from './wizard_steps/step_3.vue';
+import { mountWithTurbolinks } from '../helpers/turbolinks.js';
+
+const app = createApp({
+ components: {
+ Step1,
+ Step2,
+ Step3
+ },
+ methods: {
+ fireAlert() {
+ alert('Fired!');
+ }
+ },
+ data() {
+ return {
+ wizardConfig: {
+ title: 'Wizard steps',
+ subtitle: 'Wizard subtitle description',
+ steps: [
+ {
+ id: 'step1',
+ icon: 'sn-icon sn-icon-open',
+ label: 'Step 1',
+ component: shallowRef(Step1)
+ },
+ {
+ id: 'step2',
+ icon: 'sn-icon sn-icon-edit',
+ label: 'Step 2',
+ component: shallowRef(Step2)
+ },
+ {
+ id: 'step3',
+ icon: 'sn-icon sn-icon-inventory',
+ label: 'Step 3',
+ component: shallowRef(Step3)
+ }
+ ]
+ },
+ wizardParams: {
+ text: 'Some text'
+ },
+ showWizard: false
+ };
+ }
+});
+app.component('WizardModal', WizardModal);
+app.config.globalProperties.i18n = window.I18n;
+mountWithTurbolinks(app, '#modals');
diff --git a/app/javascript/packs/vue/design_system/wizard_steps/step_1.vue b/app/javascript/packs/vue/design_system/wizard_steps/step_1.vue
new file mode 100644
index 000000000..bd7f8851c
--- /dev/null
+++ b/app/javascript/packs/vue/design_system/wizard_steps/step_1.vue
@@ -0,0 +1,37 @@
+
+
+
+ You can add any custom html here or render params like this:
+
+ {{ params }}
+
+
+
+
+
diff --git a/app/javascript/packs/vue/design_system/wizard_steps/step_2.vue b/app/javascript/packs/vue/design_system/wizard_steps/step_2.vue
new file mode 100644
index 000000000..590836b8c
--- /dev/null
+++ b/app/javascript/packs/vue/design_system/wizard_steps/step_2.vue
@@ -0,0 +1,41 @@
+
+
+
+ All steps have access to shared params
+
+
+
+
+
+
+
diff --git a/app/javascript/packs/vue/design_system/wizard_steps/step_3.vue b/app/javascript/packs/vue/design_system/wizard_steps/step_3.vue
new file mode 100644
index 000000000..c8571e599
--- /dev/null
+++ b/app/javascript/packs/vue/design_system/wizard_steps/step_3.vue
@@ -0,0 +1,42 @@
+
+
+
+ Our params - {{ params }}
+
+ If you want emit action use wizardComponent
+
+
+
+
+ Launch alert
+
+
+
+
+
diff --git a/app/javascript/vue/shared/wizard_modal.vue b/app/javascript/vue/shared/wizard_modal.vue
new file mode 100644
index 000000000..cdc2b4ee3
--- /dev/null
+++ b/app/javascript/vue/shared/wizard_modal.vue
@@ -0,0 +1,73 @@
+
+
+
+
+
+
{{ config.title }}
+
+ {{ config.subtitle }}
+
+
+
+
+
+
+
+
+
+ {{ step.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/views/design_elements/_modals.html.erb b/app/views/design_elements/_modals.html.erb
new file mode 100644
index 000000000..a241d91b2
--- /dev/null
+++ b/app/views/design_elements/_modals.html.erb
@@ -0,0 +1,16 @@
+
+
Modals
+
+ Show Wizard Modal
+
+
+
+
+
+<%= javascript_include_tag 'vue_design_system_modals' %>
diff --git a/app/views/design_elements/index.html.erb b/app/views/design_elements/index.html.erb
index e69de29bb..b9138c5ca 100644
--- a/app/views/design_elements/index.html.erb
+++ b/app/views/design_elements/index.html.erb
@@ -0,0 +1 @@
+<%= render partial: 'modals' %>
diff --git a/config/webpack/webpack.config.js b/config/webpack/webpack.config.js
index 3d286cedf..2241edbf6 100644
--- a/config/webpack/webpack.config.js
+++ b/config/webpack/webpack.config.js
@@ -49,7 +49,8 @@ const entryList = {
vue_components_manage_stock_value_modal: './app/javascript/packs/vue/manage_stock_value_modal.js',
vue_legacy_datetime_picker: './app/javascript/packs/vue/legacy/datetime_picker.js',
vue_open_locally_menu: './app/javascript/packs/vue/open_locally_menu.js',
- vue_scinote_edit_download: './app/javascript/packs/vue/scinote_edit_download.js'
+ vue_scinote_edit_download: './app/javascript/packs/vue/scinote_edit_download.js',
+ vue_design_system_modals: './app/javascript/packs/vue/design_system/modals.js'
}
// Engine pack loading based on https://github.com/rails/webpacker/issues/348#issuecomment-635480949
From 9b49e891a08106d35f51f36c55fe4044590e7602 Mon Sep 17 00:00:00 2001
From: Giga Chubinidze
Date: Mon, 22 Jan 2024 02:16:24 +0400
Subject: [PATCH 060/128] changed experiment move logic similar to modules move
---
app/controllers/experiments_controller.rb | 30 +++++++++++------------
config/locales/en.yml | 1 +
2 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/app/controllers/experiments_controller.rb b/app/controllers/experiments_controller.rb
index 800b3341d..00db69f7d 100644
--- a/app/controllers/experiments_controller.rb
+++ b/app/controllers/experiments_controller.rb
@@ -299,27 +299,27 @@ class ExperimentsController < ApplicationController
def move
project = Project.find_by(id: params[:project_id])
- ActiveRecord::Base.transaction do
+ project.transaction do
@experiments.each do |experiment|
- @experiment = experiment
- service = Experiments::MoveToProjectService
+ Experiments::MoveToProjectService
.call(experiment_id: experiment.id,
project_id: params[:project_id],
user_id: current_user.id)
- if service.succeed?
- flash[:success] = t('experiments.move.success_flash', experiment: experiment.name)
- view_state = experiment.current_view_state(current_user)
- view_type = view_state.state['my_modules']['view_type'] || 'canvas'
- else
- render json: {
- message: service.errors.values.join('. ')
- }, status: :unprocessable_entity
- end
end
- end
- render json: { message: t('experiments.table.move_success_flash',
- project: escape_input(project.name)), path: project_path(project) }
+ flash[:success] = t('experiments.table.move_success_flash', project: escape_input(project.name))
+ render json: { message: t('experiments.table.move_success_flash',
+ project: escape_input(project.name)), path: project_path(project) }
+ rescue StandardError => e
+ Rails.logger.error(e.message)
+ Rails.logger.error(e.backtrace.join("\n"))
+ render json: {
+ message: t('experiments.table.move_success_flash', project: escape_input(project.name))
+ }, status: :unprocessable_entity
+ raise ActiveRecord::Rollback
+ end
+ rescue ActiveRecord::RecordNotFound
+ render_404
end
def move_modules_modal
diff --git a/config/locales/en.yml b/config/locales/en.yml
index ffbd8e011..19f445fec 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -1527,6 +1527,7 @@ en:
table:
head_title: "%{experiment} | Overview"
move_success_flash: "Successfully moved experiment(s) to project %{project}."
+ error_flash: "Failed to move experiment(s) to project %{project}."
column:
id_html: 'ID'
task_name_html: 'Task name'
From 1fff6da45deae04a0798ae0d3ec8ba24a7fae720 Mon Sep 17 00:00:00 2001
From: Anton
Date: Mon, 22 Jan 2024 13:48:37 +0100
Subject: [PATCH 061/128] Refactor checklist [SCI-9959]
---
.../checklist_items_controller.rb | 7 +-
.../vue/shared/content/checklist.vue | 86 ++++++++++---------
.../vue/shared/content/checklistItem.vue | 23 ++---
app/javascript/vue/shared/inline_edit.vue | 2 +-
app/models/checklist_item.rb | 10 +--
5 files changed, 66 insertions(+), 62 deletions(-)
diff --git a/app/controllers/step_elements/checklist_items_controller.rb b/app/controllers/step_elements/checklist_items_controller.rb
index 9889d6f51..6870ce8fe 100644
--- a/app/controllers/step_elements/checklist_items_controller.rb
+++ b/app/controllers/step_elements/checklist_items_controller.rb
@@ -18,7 +18,7 @@ module StepElements
checklist_item = @checklist.checklist_items.new(checklist_item_params.merge!(created_by: current_user))
new_items = []
ActiveRecord::Base.transaction do
- new_items = checklist_item.save_multiline!
+ new_items = checklist_item.save_multiline!(after_id: params[:after_id])
new_items.each do |item|
log_activity(
"#{@step.protocol.in_module? ? :task : :protocol}_step_checklist_item_added",
@@ -102,9 +102,10 @@ module StepElements
end
def reorder
- checklist_item = @checklist.checklist_items.find(checklist_item_params[:id])
+ checklist_item = @checklist.checklist_items.find(params[:id])
ActiveRecord::Base.transaction do
- checklist_item.insert_at(checklist_item_params[:position])
+ insert_at = (@checklist.checklist_items.find_by(id: params[:after_id])&.position || 0)
+ checklist_item.insert_at(insert_at)
end
render json: params[:checklist_item_positions], status: :ok
rescue ActiveRecord::RecordInvalid
diff --git a/app/javascript/vue/shared/content/checklist.vue b/app/javascript/vue/shared/content/checklist.vue
index 01f878aa9..b891fa1a0 100644
--- a/app/javascript/vue/shared/content/checklist.vue
+++ b/app/javascript/vue/shared/content/checklist.vue
@@ -30,7 +30,7 @@
@delete="showDeleteModal"
>
-
+
+ @keyup.enter="addItem(checklistItems[checklistItems.length - 1]?.id)"
+ @click="addItem(checklistItems[checklistItems.length - 1]?.id)">
{{ i18n.t('protocols.steps.insert.checklist_item') }}
@@ -81,6 +81,9 @@
diff --git a/app/views/shared/file_preview/_content.html.erb b/app/views/shared/file_preview/_content.html.erb
index 31fd8e0d8..51130f3e5 100644
--- a/app/views/shared/file_preview/_content.html.erb
+++ b/app/views/shared/file_preview/_content.html.erb
@@ -27,7 +27,7 @@
<% elsif asset.editable_image? %>
-
<%= t('assets.file_preview.edit_in_scinote') %>
+
<% end %>
<% end %>
From 0eb323b2f12ce8d916219122e787e7077c90fe35 Mon Sep 17 00:00:00 2001
From: Ivan Kljun
Date: Tue, 23 Jan 2024 11:52:35 +0100
Subject: [PATCH 063/128] Add wrong-version modal for SciNote Edit [SCI-10010]
---
.../javascripts/sitewide/constants.js.erb | 2 +
.../content/attachments/context_menu.vue | 17 ++++--
.../attachments/mixins/open_locally.js | 16 +++++-
.../content/attachments/open_locally_menu.vue | 54 +++++++++++--------
.../shared/content/attachments/thumbnail.vue | 9 +++-
.../content/modal/no_predefined_app_modal.vue | 6 +--
.../content/modal/update_version_modal.vue | 54 +++++++++++++++++++
.../vue/shared/scinote_edit_download.vue | 30 +++++++----
.../shared/file_preview/_content.html.erb | 2 +-
config/initializers/constants.rb | 4 ++
config/locales/en.yml | 7 ++-
11 files changed, 155 insertions(+), 46 deletions(-)
create mode 100644 app/javascript/vue/shared/content/modal/update_version_modal.vue
diff --git a/app/assets/javascripts/sitewide/constants.js.erb b/app/assets/javascripts/sitewide/constants.js.erb
index 8e37b3abc..2ba7d7fc4 100644
--- a/app/assets/javascripts/sitewide/constants.js.erb
+++ b/app/assets/javascripts/sitewide/constants.js.erb
@@ -15,4 +15,6 @@ const GLOBAL_CONSTANTS = {
FAST_STATUS_POLLING_INTERVAL: <%= Constants::FAST_STATUS_POLLING_INTERVAL %>,
SLOW_STATUS_POLLING_INTERVAL: <%= Constants::SLOW_STATUS_POLLING_INTERVAL %>,
ASSET_SYNC_URL: '<%= Constants::ASSET_SYNC_URL %>',
+ MIN_SCINOTE_EDIT_VERSION: '<%= Constants::MIN_SCINOTE_EDIT_VERSION %>',
+ MAX_SCINOTE_EDIT_VERSION: '<%= Constants::MAX_SCINOTE_EDIT_VERSION %>',
};
diff --git a/app/javascript/vue/shared/content/attachments/context_menu.vue b/app/javascript/vue/shared/content/attachments/context_menu.vue
index 1dd6c0af0..d78379525 100644
--- a/app/javascript/vue/shared/content/attachments/context_menu.vue
+++ b/app/javascript/vue/shared/content/attachments/context_menu.vue
@@ -57,11 +57,15 @@
:fileName="attachment.attributes.file_name"
@confirm="showNoPredefinedAppModal = false"
/>
+
@@ -72,6 +76,7 @@ import deleteAttachmentModal from './delete_modal.vue';
import editLaunchingApplicationModal from './edit_launching_application_modal.vue';
import moveAssetModal from '../modal/move.vue';
import NoPredefinedAppModal from '../modal/no_predefined_app_modal.vue';
+import UpdateVersionModal from '../modal/update_version_modal.vue';
import MoveMixin from './mixins/move.js';
import OpenLocallyMixin from './mixins/open_locally.js';
import MenuDropdown from '../../menu_dropdown.vue';
@@ -83,6 +88,7 @@ export default {
moveAssetModal,
MenuDropdown,
NoPredefinedAppModal,
+ UpdateVersionModal,
editLaunchingApplicationModal
},
mixins: [MoveMixin, OpenLocallyMixin],
@@ -98,7 +104,8 @@ export default {
viewModeOptions: ['inline', 'thumbnail', 'list'],
deleteModal: false,
editAppModal: false,
- showNoPredefinedAppModal: false
+ showNoPredefinedAppModal: false,
+ showUpdateVersionModal: false
};
},
computed: {
diff --git a/app/javascript/vue/shared/content/attachments/mixins/open_locally.js b/app/javascript/vue/shared/content/attachments/mixins/open_locally.js
index 6ce3d06d4..a104e7a7c 100644
--- a/app/javascript/vue/shared/content/attachments/mixins/open_locally.js
+++ b/app/javascript/vue/shared/content/attachments/mixins/open_locally.js
@@ -1,10 +1,12 @@
import axios from '../../../../../packs/custom_axios.js';
+import { satisfies } from 'compare-versions';
export default {
data() {
return {
localAppName: null,
- scinoteEditRunning: false
+ scinoteEditRunning: false,
+ scinoteEditVersion: null
};
},
computed: {
@@ -24,6 +26,7 @@ export default {
if (statusResponse.status === 200) {
this.scinoteEditRunning = true;
+ this.scinoteEditVersion = statusResponse.data.version;
} else {
return;
}
@@ -40,7 +43,10 @@ export default {
}
},
async openLocally() {
- if (this.localAppName === null) {
+ if (this.isWrongVersion(this.scinoteEditVersion)) {
+ this.showUpdateVersionModal = true;
+ return;
+ } else if (this.localAppName === null) {
this.showNoPredefinedAppModal = true;
return;
}
@@ -52,6 +58,12 @@ export default {
} catch (error) {
console.error('Error in request:', error);
}
+ },
+ isWrongVersion(version) {
+ const min = GLOBAL_CONSTANTS.MIN_SCINOTE_EDIT_VERSION;
+ const max = GLOBAL_CONSTANTS.MAX_SCINOTE_EDIT_VERSION;
+ version = "3.0"
+ return !satisfies(version, `${min} - ${max}`);
}
}
}
diff --git a/app/javascript/vue/shared/content/attachments/open_locally_menu.vue b/app/javascript/vue/shared/content/attachments/open_locally_menu.vue
index 43d1498aa..16fe92443 100644
--- a/app/javascript/vue/shared/content/attachments/open_locally_menu.vue
+++ b/app/javascript/vue/shared/content/attachments/open_locally_menu.vue
@@ -1,21 +1,27 @@
-
diff --git a/app/javascript/vue/shared/content/modal/update_version_modal.vue b/app/javascript/vue/shared/content/modal/update_version_modal.vue
new file mode 100644
index 000000000..c1650915f
--- /dev/null
+++ b/app/javascript/vue/shared/content/modal/update_version_modal.vue
@@ -0,0 +1,54 @@
+
+
+
+
+
diff --git a/app/javascript/vue/shared/scinote_edit_download.vue b/app/javascript/vue/shared/scinote_edit_download.vue
index 80e994ef0..a655f8968 100644
--- a/app/javascript/vue/shared/scinote_edit_download.vue
+++ b/app/javascript/vue/shared/scinote_edit_download.vue
@@ -1,7 +1,7 @@