Merge branch 'develop' into kb_SCI-10761_data-e2e-protocol-templates

This commit is contained in:
Klemen Benedicic 2024-06-05 05:09:26 +02:00
commit 86c99feb39
15 changed files with 119 additions and 70 deletions

View file

@ -201,6 +201,7 @@ var zebraPrint = (function() {
});
}
if (dataZebra?.responseJSON?.labels?.length && printData.number_of_copies > 0) {
updateProgressModalData(progressModal, printData.printer_name, PRINTER_STATUS_SEARCH, PRINTER_STATUS_SEARCH);
device = findDevice(printData.printer_name);
@ -212,12 +213,15 @@ var zebraPrint = (function() {
printData.number_of_copies,
printData.printer_name,
dataZebra.responseJSON.labels,
0,
0
);
} else {
updateProgressModalData(progressModal, printData.printer_name, PRINTER_STATUS_ERROR, PRINTER_STATUS_ERROR);
}
});
} else {
updateProgressModalData(progressModal, printData.printer_name, PRINTER_STATUS_ERROR, PRINTER_STATUS_ERROR);
}
}).fail(() => {
HelperModule.flashAlertMsg(I18n.t('repository_row.modal_print_label.general_error'), 'danger');
});

View file

@ -323,7 +323,7 @@ class AssetsController < ApplicationController
end
ActiveRecord::Base.transaction do
old_name = @asset.name
old_name = @asset.file_name
@asset.last_modified_by = current_user
@asset.rename_file(new_name)
@asset.save!
@ -332,7 +332,7 @@ class AssetsController < ApplicationController
when Step
message_items = { old_name:, new_name:, user: current_user.id }
message_items[:my_module] = @assoc.protocol.my_module.id if @assoc.protocol.in_module?
@asset.parent.touch
log_step_activity(
"#{@assoc.protocol.in_module? ? 'task' : 'protocol'}_step_asset_renamed",
@assoc,

View file

@ -210,13 +210,19 @@ class Users::RegistrationsController < Devise::RegistrationsController
def regenerate_api_key
current_user.regenerate_api_key!
redirect_to edit_user_registration_path
redirect_to(edit_user_registration_path(anchor: 'api-key'),
flash: {
success: t('users.registrations.edit.api_key.generated')
})
end
def revoke_api_key
current_user.revoke_api_key!
redirect_to edit_user_registration_path
redirect_to(edit_user_registration_path(anchor: 'api-key'),
flash: {
success: t('users.registrations.edit.api_key.revoked')
})
end
protected

View file

@ -255,6 +255,7 @@ export default {
});
},
initZebraPrinter() {
this.printers = this.printers.filter((printer) => !printer.id.startsWith('zebra'));
this.zebraPrinters = zebraPrint.init($('#LabelPrinterSelector'), {
clearSelectorOnFirstDevice: false,
appendDevice: (device) => {

View file

@ -44,8 +44,7 @@
<Teleport to="body">
<RenameAttachmentModal
v-if="renameModal"
:url_path="attachment.attributes.urls.rename"
:fileName="attachment.attributes.file_name"
:attachment="attachment"
@attachment:update="$emit('attachment:update', $event)"
@close="renameModal = false"
/>
@ -170,18 +169,18 @@ export default {
data_e2e: 'e2e-BT-attachmentOptions-move'
});
}
if (this.attachment.attributes.urls.rename) {
menu.push({
text: this.i18n.t('assets.context_menu.rename'),
emit: 'rename'
});
}
if (this.attachment.attributes.urls.duplicate) {
menu.push({
text: this.i18n.t('assets.context_menu.duplicate'),
emit: 'duplicate'
});
}
if (this.attachment.attributes.urls.rename) {
menu.push({
text: this.i18n.t('assets.context_menu.rename'),
emit: 'rename'
});
}
if (this.attachment.attributes.urls.delete) {
menu.push({
text: this.i18n.t('assets.context_menu.delete'),

View file

@ -1,6 +1,6 @@
<template>
<div ref="modal" @keydown.esc="close" class="modal" id="renameAttachmentModal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-md" role="document">
<div class="modal-dialog modal-sm" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="sn-icon sn-icon-close"></i></button>
@ -9,10 +9,15 @@
</h4>
</div>
<div class="modal-body">
<p>{{ i18n.t('assets.from_clipboard.file_name')}}</p>
<label class="sci-label">
{{ i18n.t('assets.from_clipboard.file_name')}}
</label>
<div class="flex gap-1 items-center">
<div class="sci-input-container" :class="{ 'error': error }" :data-error-text="error">
<input ref="input" v-model="name" type="text" class="sci-input-field" @keyup.enter="renameAttachment(name)" required="true" />
</div>
<div class="shrink-0">.{{ this.attachment.attributes.file_extension }}</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" @click="close">{{ i18n.t('general.cancel') }}</button>
@ -31,14 +36,10 @@ export default {
name: 'RenameAttachmentModal',
mixins: [modalMixin],
props: {
url_path: {
type: String,
attachment: {
type: Object,
required: true
},
fileName: {
type: String,
required: true
}
},
data() {
return {
@ -47,7 +48,7 @@ export default {
};
},
created() {
this.name = this.fileName;
this.name = this.attachment.attributes.file_name_without_extension;
},
watch: {
name() {
@ -71,10 +72,9 @@ export default {
return;
}
const payload = { asset: { name: newName } };
const payload = { asset: { name: `${newName}.${this.attachment.attributes.file_extension}` } };
try {
const response = await axios.patch(this.url_path, payload);
const response = await axios.patch(this.attachment.attributes.urls.rename, payload);
this.$emit('attachment:update', response.data.data);
this.close();
} catch (error) {

View file

@ -2,6 +2,7 @@
module SearchableModel
extend ActiveSupport::Concern
DATA_VECTOR_ATTRIBUTES = ['asset_text_data.data_vector', 'tables.data_vector'].freeze
included do
# Helper function for relations that
@ -174,21 +175,19 @@ module SearchableModel
def self.create_query_clause(attrs, index, negate, query_clauses, value_hash, phrase, current_operator)
phrase = sanitize_sql_like(phrase)
phrase = Regexp.escape(phrase)
exact_match = phrase =~ /^".*"$/
like = exact_match ? '~' : 'ILIKE'
phrase = exact_match ? "(^|\\s)#{phrase[1..-2]}(\\s|$)" : "%#{phrase}%"
where_clause = (attrs.map.with_index do |a, i|
where_clause = (attrs.map.with_index do |attribute, i|
i = (index * attrs.count) + i
if %w(repository_rows.id repository_number_values.data).include?(a)
"#{a} IS NOT NULL AND (((#{a})::text) #{like} :t#{i}) OR "
elsif defined?(model::PREFIXED_ID_SQL) && a == model::PREFIXED_ID_SQL
"#{a} IS NOT NULL AND (#{a} #{like} :t#{i}) OR "
elsif ['asset_text_data.data_vector', 'tables.data_vector'].include?(a)
"#{a} @@ plainto_tsquery(:t#{i}) OR "
if %w(repository_rows.id repository_number_values.data).include?(attribute)
"#{attribute} IS NOT NULL AND (((#{attribute})::text) #{like} :t#{i}) OR "
elsif defined?(model::PREFIXED_ID_SQL) && attribute == model::PREFIXED_ID_SQL
"#{attribute} IS NOT NULL AND (#{attribute} #{like} :t#{i}) OR "
elsif DATA_VECTOR_ATTRIBUTES.include?(attribute)
"#{attribute} @@ to_tsquery(:t#{i}) OR "
else
"#{a} IS NOT NULL AND ((trim_html_tags(#{a})) #{like} :t#{i}) OR "
"#{attribute} IS NOT NULL AND ((trim_html_tags(#{attribute})) #{like} :t#{i}) OR "
end
end).join[0..-5]
@ -199,9 +198,20 @@ module SearchableModel
end
value_hash.merge!(
(attrs.map.with_index do |_, i|
(attrs.map.with_index do |attribute, i|
i = (index * attrs.count) + i
["t#{i}".to_sym, phrase]
new_phrase = exact_match ? phrase[1..-2] : phrase
if DATA_VECTOR_ATTRIBUTES.include?(attribute)
new_phrase = Regexp.escape(new_phrase.gsub(/[!()&|:<]/, ' ').strip).split(/\s+/)
new_phrase.map! { |t| "#{t}:*" } unless exact_match
new_phrase = new_phrase.join('&').tr('\'', '"')
else
new_phrase = Regexp.escape(new_phrase)
new_phrase = exact_match ? "(^|\\s)#{new_phrase}(\\s|$)" : "%#{new_phrase}%"
end
["t#{i}".to_sym, new_phrase]
end).to_h
)
end

View file

@ -516,6 +516,7 @@ class User < ApplicationRecord
def regenerate_api_key!
update!(
api_key: SecureRandom.urlsafe_base64(33),
api_key_created_at: Time.current,
api_key_expires_at: Constants::API_KEY_EXPIRES_IN.from_now
)
end

View file

@ -9,7 +9,7 @@ class AssetSerializer < ActiveModel::Serializer
include ApplicationHelper
attributes :file_name, :file_extension, :view_mode, :icon, :urls, :updated_at_formatted,
:file_size, :medium_preview, :large_preview, :asset_type, :wopi,
:file_size, :medium_preview, :large_preview, :asset_type, :wopi, :file_name_without_extension,
:wopi_context, :pdf_previewable, :file_size_formatted, :asset_order,
:updated_at, :metadata, :image_editable, :image_context, :pdf, :attached, :parent_type,
:edit_version_range
@ -23,6 +23,10 @@ class AssetSerializer < ActiveModel::Serializer
object.render_file_name
end
def file_name_without_extension
File.basename(object.file_name, '.*')
end
def file_extension
File.extname(object.file_name)[1..]
end

View file

@ -1,11 +1,19 @@
<div class="mb-8">
<h3><%= t("users.registrations.edit.api_key.title") %></h3>
<h3 id="api-key"><%= t("users.registrations.edit.api_key.title") %></h3>
<p>
<%= t("users.registrations.edit.api_key.description") %>
</p>
<% if current_user.api_key %>
<div class="api-key-display">
<%= text_field_tag :api_key, current_user.api_key, class: "p-3 mb-2 w-full", disabled: "disabled" %>
<div class="form-group sci-input-container right-icon !w-1/2">
<%= password_field_tag :api_key,
current_user.api_key,
name: 'api_key',
class: 'form-control sci-input-field !text-sn-black !font-mono !cursor-text',
disabled: 'disabled'
%>
<i class="sn-icon sn-icon-visibility-show show-password" style="cursor: pointer; z-index: 10"></i>
</div>
<% if current_user.api_key_expires_at < Time.current %>
<p class="">
<%= t("users.registrations.edit.api_key.expired") %>

View file

@ -13,5 +13,5 @@ Rails.application.configure do
config.x.core_api_v2_enabled = ENV['CORE_API_V2_ENABLED'] || false
config.x.core_api_key_enabled = ENV['CORE_API_KEY_ENABLED'] || false
config.x.core_api_key_enabled = ENV['CORE_API_KEY_ENABLED'] == 'true'
end

View file

@ -3,6 +3,7 @@
module PermissionExtends
module TeamPermissions
%w(
NONE
READ
MANAGE
USERS_MANAGE
@ -17,6 +18,7 @@ module PermissionExtends
module ProtocolPermissions
%w(
NONE
READ
READ_ARCHIVED
MANAGE
@ -27,6 +29,7 @@ module PermissionExtends
module ReportPermissions
%w(
NONE
READ
MANAGE
USERS_MANAGE
@ -35,6 +38,7 @@ module PermissionExtends
module ProjectPermissions
%w(
NONE
READ
READ_ARCHIVED
MANAGE
@ -52,6 +56,7 @@ module PermissionExtends
module ExperimentPermissions
%w(
NONE
READ
READ_ARCHIVED
MANAGE
@ -65,6 +70,7 @@ module PermissionExtends
module MyModulePermissions
%w(
NONE
READ
READ_ARCHIVED
ACTIVITIES_READ
@ -106,6 +112,7 @@ module PermissionExtends
module RepositoryPermissions
%w(
NONE
READ
READ_ARCHIVED
MANAGE
@ -132,7 +139,7 @@ module PermissionExtends
ExperimentPermissions.constants.map { |const| ExperimentPermissions.const_get(const) } +
MyModulePermissions.constants.map { |const| MyModulePermissions.const_get(const) } +
RepositoryPermissions.constants.map { |const| RepositoryPermissions.const_get(const) }
)
).reject { |p| p.end_with?("_none") }
NORMAL_USER_PERMISSIONS = [
TeamPermissions::PROJECTS_CREATE,

View file

@ -2832,6 +2832,8 @@ en:
regenerate: "Regenerate"
revoke: "Revoke"
expired: "This key has expired!"
generated: "API key generated!"
revoked: "API key revoked!"
new:
head_title: "Sign up"
team_name_label: "Team name"

View file

@ -0,0 +1,7 @@
# frozen_string_literal: true
class AddApiKeyCreatedAtToUsers < ActiveRecord::Migration[7.0]
def change
add_column :users, :api_key_created_at, :timestamp
end
end

View file

@ -2255,9 +2255,9 @@ axios@^0.21.1:
follow-redirects "^1.14.0"
axios@^1.6.0:
version "1.6.8"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.8.tgz#66d294951f5d988a00e87a0ffb955316a619ea66"
integrity sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==
version "1.7.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.2.tgz#b625db8a7051fbea61c35a3cbb3a1daa7b9c7621"
integrity sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==
dependencies:
follow-redirects "^1.15.6"
form-data "^4.0.0"
@ -5384,10 +5384,10 @@ minipass@^3.0.0, minipass@^3.1.1, minipass@^3.1.6:
dependencies:
yallist "^4.0.0"
minipass@^4.0.0:
version "4.2.5"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.2.5.tgz#9e0e5256f1e3513f8c34691dd68549e85b2c8ceb"
integrity sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==
minipass@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d"
integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==
minizlib@^2.1.1, minizlib@^2.1.2:
version "2.1.2"
@ -7331,13 +7331,13 @@ tar-stream@^3.1.5:
streamx "^2.15.0"
tar@^6.1.11, tar@^6.1.2:
version "6.1.13"
resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.13.tgz#46e22529000f612180601a6fe0680e7da508847b"
integrity sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==
version "6.2.1"
resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a"
integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==
dependencies:
chownr "^2.0.0"
fs-minipass "^2.0.0"
minipass "^4.0.0"
minipass "^5.0.0"
minizlib "^2.1.1"
mkdirp "^1.0.3"
yallist "^4.0.0"