mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-12-16 05:42:13 +08:00
Merge branch 'develop' into features/storage-locations
This commit is contained in:
commit
49ddeb7403
40 changed files with 329 additions and 100 deletions
1
Gemfile
1
Gemfile
|
|
@ -108,6 +108,7 @@ group :development, :test do
|
|||
gem 'awesome_print'
|
||||
gem 'better_errors'
|
||||
gem 'binding_of_caller'
|
||||
gem 'brakeman', require: false
|
||||
gem 'bullet'
|
||||
gem 'byebug'
|
||||
gem 'factory_bot_rails'
|
||||
|
|
|
|||
|
|
@ -208,6 +208,8 @@ GEM
|
|||
debug_inspector (>= 0.0.1)
|
||||
bootsnap (1.16.0)
|
||||
msgpack (~> 1.2)
|
||||
brakeman (6.1.2)
|
||||
racc
|
||||
builder (3.2.4)
|
||||
bullet (7.0.7)
|
||||
activesupport (>= 3.0.0)
|
||||
|
|
@ -799,6 +801,7 @@ DEPENDENCIES
|
|||
better_errors
|
||||
binding_of_caller
|
||||
bootsnap
|
||||
brakeman
|
||||
bullet
|
||||
byebug
|
||||
canaid!
|
||||
|
|
|
|||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
1.35.0.2
|
||||
1.36.0
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ var RepositoryColumns = (function() {
|
|||
disableSearch: true,
|
||||
labelHTML: true,
|
||||
optionLabel: function(option) {
|
||||
return `<div class="column-type-option" data-disabled="${option.params.disabled}">
|
||||
return `<div class="column-type-option" data-e2e="${option.params.data_e2e || ''}" data-disabled="${option.params.disabled}">
|
||||
<span>${option.label}</span>
|
||||
<span class="text-description">${option.params.text_description || ''}</span>
|
||||
</div>`
|
||||
|
|
@ -284,6 +284,7 @@ var RepositoryColumns = (function() {
|
|||
let editableRow = ($(el).attr('data-editable-row') === 'true') ? 'has-permissions' : '';
|
||||
let editUrl = $(el).attr('data-edit-column-url');
|
||||
let destroyUrl = $(el).attr('data-destroy-column-url');
|
||||
const isDisabled = $(el).attr('data-disabled') === 'true';
|
||||
let thederName;
|
||||
|
||||
if ($(el).find('.modal-tooltiptext').length > 0) {
|
||||
|
|
@ -315,7 +316,9 @@ var RepositoryColumns = (function() {
|
|||
<span class="vis-controls">
|
||||
<span class="vis sn-icon ${visClass}" title="${visText}" data-e2e="e2e-BT-invItems-manageColumnsModal-${e2eName}-visibility"></span>
|
||||
</span>
|
||||
<div class="text truncate" title="${thederName}" data-e2e="e2e-TX-invItems-manageColumnsModal-${e2eName}-columnName">${thederName}</div>
|
||||
<div class="text truncate" title="${thederName}" data-e2e="e2e-TX-invItems-manageColumnsModal-${e2eName}-columnName">
|
||||
${thederName} ${isDisabled ? `<span data-e2e="e2e-LB-invItems-manageColumnsModal-${e2eName}-disabled"></span>` : ''}
|
||||
</div>
|
||||
<span class="column-type pull-right shrink-0">${
|
||||
getColumnTypeText(el, colId) || `<i class="sn-icon sn-icon-locked-task" data-e2e="e2e-IC-invItems-manageColumnsModal-${e2eName}-locked"></i>`
|
||||
}</span>
|
||||
|
|
|
|||
|
|
@ -202,10 +202,14 @@ var MarvinJsEditorApi = (function() {
|
|||
}
|
||||
$(marvinJsModal).modal('hide');
|
||||
|
||||
config.editor.focus();
|
||||
if (config.editor) config.editor.focus();
|
||||
|
||||
config.button.dataset.inProgress = false;
|
||||
|
||||
if (MarvinJsEditor.saveCallback) MarvinJsEditor.saveCallback();
|
||||
if (MarvinJsEditor.saveCallback) {
|
||||
MarvinJsEditor.saveCallback();
|
||||
delete MarvinJsEditor.saveCallback;
|
||||
}
|
||||
},
|
||||
error: function(response) {
|
||||
if (response.status === 403) {
|
||||
|
|
@ -264,8 +268,8 @@ var MarvinJsEditorApi = (function() {
|
|||
MarvinJsEditor.save(config);
|
||||
} else if (config.mode === 'edit') {
|
||||
config.objectType = 'Asset';
|
||||
MarvinJsEditor.saveCallback = (() => window.location.reload());
|
||||
MarvinJsEditor.update(config);
|
||||
location.reload();
|
||||
} else if (config.mode === 'new-tinymce') {
|
||||
config.objectType = 'TinyMceAsset';
|
||||
MarvinJsEditor.save(config);
|
||||
|
|
|
|||
|
|
@ -110,13 +110,13 @@
|
|||
}
|
||||
|
||||
.send-comment {
|
||||
bottom: 5px;
|
||||
color: $brand-primary;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
text-align: center;
|
||||
top: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@
|
|||
}
|
||||
|
||||
.btn.btn-light {
|
||||
@apply bg-transparent text-sn-blue border-transparent;
|
||||
@apply bg-transparent text-sn-blue border-transparent bg-sn-white;
|
||||
}
|
||||
|
||||
.btn.btn-light.btn-black {
|
||||
|
|
|
|||
|
|
@ -103,8 +103,6 @@ module AccessPermissions
|
|||
destroy: true
|
||||
)
|
||||
|
||||
user_assignment.destroy!
|
||||
|
||||
log_activity(:unassign_user_from_project, { user_target: user_assignment.user.id,
|
||||
role: user_assignment.user_role.name })
|
||||
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@
|
|||
<div v-for="(step, index) in steps" :key="step.id" class="step-block">
|
||||
<div v-if="index > 0 && urls.add_step_url" class="insert-step" @click="addStep(index)" data-e2e="e2e-BT-protocol-templateSteps-insertStep">
|
||||
<i class="sn-icon sn-icon-new-task"></i>
|
||||
<span class="mr-3">{{ i18n.t("protocols.steps.add_step") }}</span>
|
||||
</div>
|
||||
<Step
|
||||
ref="steps"
|
||||
|
|
@ -201,6 +202,7 @@
|
|||
/>
|
||||
<div v-if="(index === steps.length - 1) && urls.add_step_url" class="insert-step" @click="addStep(index + 1)" data-e2e="e2e-BT-protocol-templateSteps-insertStep">
|
||||
<i class="sn-icon sn-icon-new-task"></i>
|
||||
<span class="mr-3">{{ i18n.t("protocols.steps.add_step") }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="steps.length > 0 && urls.add_step_url && inRepository" class="py-5">
|
||||
|
|
|
|||
|
|
@ -145,7 +145,19 @@
|
|||
@attachments:viewMode="changeAttachmentsViewMode"
|
||||
@attachment:viewMode="updateAttachmentViewMode"/>
|
||||
</div>
|
||||
<ContentToolbar
|
||||
v-if="orderedElements.length > 2"
|
||||
:insertMenu="insertMenu"
|
||||
@create:table="(...args) => this.createElement('table', ...args)"
|
||||
@create:checklist="createElement('checklist')"
|
||||
@create:text="createElement('text')"
|
||||
@create:file="openLoadFromComputer"
|
||||
@create:wopi_file="openWopiFileModal"
|
||||
@create:ove_file="openOVEditor"
|
||||
@create:marvinjs_file="openMarvinJsModal($refs.marvinJsButton)"
|
||||
></ContentToolbar>
|
||||
</div>
|
||||
|
||||
<deleteStepModal v-if="confirmingDelete" @confirm="deleteStep" @cancel="closeDeleteModal"/>
|
||||
<ReorderableItemsModal v-if="reordering"
|
||||
:title="i18n.t('protocols.steps.modals.reorder_elements.title', { step_position: step.attributes.position + 1 })"
|
||||
|
|
@ -172,6 +184,7 @@
|
|||
import Attachments from '../shared/content/attachments.vue'
|
||||
import ReorderableItemsModal from '../shared/reorderable_items_modal.vue'
|
||||
import MenuDropdown from '../shared/menu_dropdown.vue'
|
||||
import ContentToolbar from '../shared/content/content_toolbar.vue'
|
||||
|
||||
import UtilsMixin from '../mixins/utils.js'
|
||||
import AttachmentsMixin from '../shared/content/mixins/attachments.js'
|
||||
|
|
@ -265,7 +278,8 @@
|
|||
Attachments,
|
||||
StorageUsage,
|
||||
ReorderableItemsModal,
|
||||
MenuDropdown
|
||||
MenuDropdown,
|
||||
ContentToolbar
|
||||
},
|
||||
created() {
|
||||
this.loadAttachments();
|
||||
|
|
@ -359,25 +373,30 @@
|
|||
if (this.urls.update_url) {
|
||||
menu = menu.concat([{
|
||||
text: this.i18n.t('protocols.steps.insert.text'),
|
||||
icon: 'sn-icon sn-icon-result-text',
|
||||
emit: 'create:text',
|
||||
data_e2e: `e2e-BT-protocol-step${this.step.id}-insertText`
|
||||
},{
|
||||
text: this.i18n.t('protocols.steps.insert.attachment'),
|
||||
submenu: this.filesMenu,
|
||||
position: 'left',
|
||||
icon: 'sn-icon sn-icon-file',
|
||||
data_e2e: `e2e-BT-protocol-step${this.step.id}-insertAttachment`
|
||||
},{
|
||||
text: this.i18n.t('protocols.steps.insert.table'),
|
||||
icon: 'sn-icon sn-icon-tables',
|
||||
emit: 'create:table',
|
||||
data_e2e: `e2e-BT-protocol-step${this.step.id}-insertTable`
|
||||
},{
|
||||
text: this.i18n.t('protocols.steps.insert.well_plate'),
|
||||
submenu: this.wellPlateOptions,
|
||||
icon: 'sn-icon sn-icon-tables',
|
||||
position: 'left',
|
||||
data_e2e: `e2e-BT-protocol-step${this.step.id}-insertWellplate`
|
||||
},{
|
||||
text: this.i18n.t('protocols.steps.insert.checklist'),
|
||||
emit: 'create:checklist',
|
||||
icon: 'sn-icon sn-icon-checkllist',
|
||||
data_e2e: `e2e-BT-protocol-step${this.step.id}-insertChecklist`
|
||||
}]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
<template>
|
||||
<div ref="modal" class="modal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-content" data-e2e="e2e-MD-protocolVersions">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close" data-e2e="e2e-BT-protocolVersionsModal-close">
|
||||
<i class="sn-icon sn-icon-close"></i>
|
||||
</button>
|
||||
<h4 class="modal-title truncate !block">
|
||||
<h4 class="modal-title truncate !block" data-e2e="e2e-TX-protocolVersionsModal-title">
|
||||
{{ i18n.t('protocols.index.versions.title', { protocol: protocol.name }) }}
|
||||
</h4>
|
||||
</div>
|
||||
|
|
@ -15,9 +15,9 @@
|
|||
<img src="/images/medium/loading.svg" alt="Loading" class="p-4 rounded-xl bg-sn-white" />
|
||||
</div>
|
||||
<div class="max-h-[400px] overflow-y-auto">
|
||||
<div v-if="draft">
|
||||
<div v-if="draft" data-e2e="e2e-CO-protocolVersionsModal-draft">
|
||||
<div class="flex items-center gap-4">
|
||||
<a :href="draft.urls.show" class="hover:no-underline cursor-pointer shrink-0">
|
||||
<a :href="draft.urls.show" class="hover:no-underline cursor-pointer shrink-0" data-e2e="e2e-TL-protocolVersionsModal-draft-draftLink">
|
||||
<span v-if="draft.previous_number"
|
||||
v-html="i18n.t('protocols.index.versions.draft_html', {
|
||||
parent_version: draft.previous_number
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
></span>
|
||||
<span v-else v-html="i18n.t('protocols.index.versions.first_draft_html')"></span>
|
||||
</a>
|
||||
<span class="text-xs" v-if="draft.modified_by">
|
||||
<span class="text-xs" v-if="draft.modified_by" data-e2e="e2e-TX-protocolVersionsModal-draft-timestamp">
|
||||
{{
|
||||
i18n.t('protocols.index.versions.draft_full_modification_info', {
|
||||
modified_on: draft.modified_on,
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
})
|
||||
}}
|
||||
</span>
|
||||
<span class="text-xs" v-else>
|
||||
<span class="text-xs" v-else data-e2e="e2e-TX-protocolVersionsModal-draft-timestamp">
|
||||
{{
|
||||
i18n.t('protocols.index.versions.draft_update_modification_info', {
|
||||
modified_on: draft.modified_on
|
||||
|
|
@ -41,11 +41,17 @@
|
|||
}}
|
||||
</span>
|
||||
<div class="flex items-center gap-2 ml-auto">
|
||||
<button v-if="draft.urls.publish" class="btn btn-light" :disabled="updating" @click="publishDraft">
|
||||
<button v-if="draft.urls.publish" class="btn btn-light" :disabled="updating" @click="publishDraft" data-e2e="e2e-BT-protocolVersionsModal-draft-publish">
|
||||
<i class="sn-icon sn-icon-Publish"></i>
|
||||
{{ i18n.t('protocols.index.versions.publish') }}
|
||||
</button>
|
||||
<button v-if="draft.urls.destroy" @click="destroyDraft" :disabled="updating" class="btn btn-light icon-btn">
|
||||
<button
|
||||
v-if="draft.urls.destroy"
|
||||
@click="destroyDraft"
|
||||
:disabled="updating"
|
||||
class="btn btn-light icon-btn"
|
||||
data-e2e="e2e-BT-protocolVersionsModal-draft-deleteDraft"
|
||||
>
|
||||
<i class="sn-icon sn-icon-delete"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -60,16 +66,17 @@
|
|||
:singleLine="false"
|
||||
:attributeName="`${i18n.t('Draft')} ${i18n.t('comment')}`"
|
||||
@update="updateComment"
|
||||
:dataE2e="'protocolVersionsModal-draft-revisionNotes'"
|
||||
/>
|
||||
</div>
|
||||
<div v-for="version in publishedVersions" :key="version.number">
|
||||
<div v-for="version in publishedVersions" :key="version.number" :data-e2e="`e2e-CO-protocolVersionsModal-version${version.number}`">
|
||||
<div class="flex items-center gap-4 group min-h-[40px]">
|
||||
<a :href="version.urls.show" class="hover:no-underline cursor-pointer shrink-0">
|
||||
<a :href="version.urls.show" class="hover:no-underline cursor-pointer shrink-0" :data-e2e="`e2e-TL-protocolVersionsModal-version${version.number}-versionLink`">
|
||||
<b>
|
||||
{{ i18n.t('protocols.index.versions.revision', { version: version.number }) }}
|
||||
</b>
|
||||
</a>
|
||||
<span class="text-xs">
|
||||
<span class="text-xs" :data-e2e="`e2e-TX-protocolVersionsModal-version${version.number}-timestamp`">
|
||||
{{
|
||||
i18n.t('protocols.index.versions.revision_publishing_info', {
|
||||
published_on: version.published_on,
|
||||
|
|
@ -83,11 +90,12 @@
|
|||
:title="i18n.t('protocols.index.versions.save_as_draft')"
|
||||
@click="saveAsDraft(version.urls.save_as_draft)"
|
||||
:disabled="draft || updating"
|
||||
:data-e2e="`e2e-BT-protocolVersionsModal-version${version.number}-saveAsDraft`"
|
||||
>
|
||||
<i class="sn-icon sn-icon-duplicate"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<div class="mb-4" :data-e2e="`e2e-TX-protocolVersionsModal-version${version.number}-revisionNotes`">
|
||||
{{ version.comment }}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
@changeStep="changeStep"
|
||||
@importRows="importRecords"
|
||||
@updateAutoMapping="updateAutoMapping"
|
||||
@updateAutoClearing="updateAutoClearing"
|
||||
/>
|
||||
<ExportModal
|
||||
v-else
|
||||
|
|
@ -49,7 +50,7 @@ export default {
|
|||
return {
|
||||
modalOpened: false,
|
||||
activeStep: 'UploadStep',
|
||||
params: { autoMapping: true },
|
||||
params: { autoMapping: true, autoClearing: false },
|
||||
modalId: null,
|
||||
loading: false
|
||||
};
|
||||
|
|
@ -62,6 +63,7 @@ export default {
|
|||
this.activeStep = 'UploadStep';
|
||||
this.params.selectedItems = null;
|
||||
this.params.autoMapping = true;
|
||||
this.params.autoClearing = false;
|
||||
this.fetchRepository();
|
||||
},
|
||||
fetchRepository() {
|
||||
|
|
@ -78,6 +80,11 @@ export default {
|
|||
},
|
||||
updateAutoMapping(value) {
|
||||
this.params.autoMapping = value;
|
||||
this.params.autoClearing = false;
|
||||
},
|
||||
updateAutoClearing() {
|
||||
this.params.autoMapping = false;
|
||||
this.params.autoClearing = true;
|
||||
},
|
||||
generatePreview(selectedItems, updateWithEmptyCells, onlyAddNewItems) {
|
||||
this.params.selectedItems = selectedItems;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
<div class="flex gap-6 items-center my-6">
|
||||
<div class="flex items-center gap-2" :title="i18n.t('repositories.import_records.steps.step2.autoMappingTooltip')">
|
||||
<div class="sci-checkbox-container">
|
||||
<input type="checkbox" class="sci-checkbox" @change="$emit('update-auto-mapping', $event.target.checked)" :checked="params.autoMapping" />
|
||||
<input type="checkbox" class="sci-checkbox" @change="toggleAutoMapping" :checked="params.autoMapping" />
|
||||
<span class="sci-checkbox-label"></span>
|
||||
</div>
|
||||
{{ i18n.t('repositories.import_records.steps.step2.autoMappingText') }}
|
||||
|
|
@ -57,6 +57,7 @@
|
|||
:value="this.selectedItems.find((item) => item.index === index)"
|
||||
@selection:changed="handleChange"
|
||||
:autoMapping="params.autoMapping"
|
||||
:autoClearing="params.autoClearing"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
|
|
@ -140,7 +141,12 @@ export default {
|
|||
methods: {
|
||||
handleChange(payload) {
|
||||
this.error = null;
|
||||
const { index, key, value } = payload;
|
||||
const {
|
||||
index,
|
||||
key,
|
||||
value,
|
||||
autoMap
|
||||
} = payload;
|
||||
|
||||
const item = this.selectedItems.find((i) => i.index === index);
|
||||
const usedBeforeItem = this.selectedItems.find((i) => i.key === key && i.index !== index);
|
||||
|
|
@ -152,6 +158,15 @@ export default {
|
|||
|
||||
item.key = key;
|
||||
item.value = value;
|
||||
|
||||
this.$emit('updateAutoMapping', autoMap);
|
||||
},
|
||||
toggleAutoMapping(event) {
|
||||
if (event.target.checked) {
|
||||
this.$emit('updateAutoMapping', true);
|
||||
} else {
|
||||
this.$emit('updateAutoClearing');
|
||||
}
|
||||
},
|
||||
loadAvailableFields() {
|
||||
// Adding alreadySelected attribute for tracking
|
||||
|
|
|
|||
|
|
@ -90,6 +90,10 @@ export default {
|
|||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
autoClearing: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
value: Object
|
||||
},
|
||||
data() {
|
||||
|
|
@ -122,11 +126,10 @@ export default {
|
|||
}
|
||||
},
|
||||
autoMapping(newVal) {
|
||||
if (newVal === true) {
|
||||
this.autoMap();
|
||||
} else {
|
||||
this.clearAutoMap();
|
||||
}
|
||||
if (newVal) this.autoMap();
|
||||
},
|
||||
autoClearing(newVal) {
|
||||
if (newVal) this.clearAutoMap();
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -151,19 +154,31 @@ export default {
|
|||
return this.systemColumns.includes(column);
|
||||
},
|
||||
autoMap() {
|
||||
this.changeSelected(null);
|
||||
this.changeAutoSelected(null);
|
||||
Object.entries(this.params.import_data.available_fields).forEach(([key, value]) => {
|
||||
if (this.item === value) {
|
||||
this.changeSelected(key);
|
||||
this.changeAutoSelected(key);
|
||||
}
|
||||
});
|
||||
},
|
||||
clearAutoMap() {
|
||||
this.changeSelected('do_not_import');
|
||||
},
|
||||
changeSelected(e) {
|
||||
updateSelectedColumnType(e, autoMap) {
|
||||
const value = this.params.import_data.available_fields[e];
|
||||
this.selectedColumnType = { index: this.index, key: e, value };
|
||||
this.selectedColumnType = {
|
||||
index: this.index,
|
||||
key: e,
|
||||
value,
|
||||
autoMap
|
||||
};
|
||||
},
|
||||
changeAutoSelected(e) {
|
||||
this.updateSelectedColumnType(e, true);
|
||||
this.$emit('selection:changed', this.selectedColumnType);
|
||||
},
|
||||
changeSelected(e) {
|
||||
this.updateSelectedColumnType(e, false);
|
||||
this.$emit('selection:changed', this.selectedColumnType);
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,17 +1,23 @@
|
|||
<template>
|
||||
<div ref="modal" class="modal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog flex" role="document" :class="{'!w-[900px]': showingInfo}">
|
||||
<div class="modal-dialog flex" role="document" :class="{'!w-[900px]': showingInfo}" data-e2e="e2e-MD-invInventoryImport-upload">
|
||||
<div v-if="showingInfo" class="w-[300px] shrink-0 h-full bg-sn-super-light-grey p-6 rounded-s text-sn-dark-grey">
|
||||
<h3 class="my-0 mb-4">{{ this.i18n.t('repositories.import_records.info_sidebar.title') }}</h3>
|
||||
<h3 class="my-0 mb-4" data-e2e="e2e-TX-invInventoryImport-uploadModal-help-title">{{ this.i18n.t('repositories.import_records.info_sidebar.title') }}</h3>
|
||||
<div v-for="i in 4" :key="i" class="flex gap-3 mb-4">
|
||||
<span class="btn btn-secondary icon-btn !text-sn-black !pointer-events-none">
|
||||
<i class="sn-icon"
|
||||
:class="i18n.t(`repositories.import_records.info_sidebar.elements.element${i - 1}.icon`)"
|
||||
:data-e2e="`e2e-IC-invInventoryImport-uploadModal-help-icon${i}`"
|
||||
></i>
|
||||
</span>
|
||||
<div>
|
||||
<div class="font-bold mb-2">{{ i18n.t(`repositories.import_records.info_sidebar.elements.element${i - 1}.label`) }}</div>
|
||||
<div>{{ i18n.t(`repositories.import_records.info_sidebar.elements.element${i - 1}.subtext`) }}</div>
|
||||
<div
|
||||
class="font-bold mb-2"
|
||||
:data-e2e="`e2e-TX-invInventoryImport-uploadModal-help-title${i}`"
|
||||
>{{ i18n.t(`repositories.import_records.info_sidebar.elements.element${i - 1}.label`) }}</div>
|
||||
<div
|
||||
:data-e2e="`e2e-TX-invInventoryImport-uploadModal-help-text${i}`"
|
||||
>{{ i18n.t(`repositories.import_records.info_sidebar.elements.element${i - 1}.subtext`) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-3 mb-4 items-center">
|
||||
|
|
@ -25,36 +31,41 @@
|
|||
</div>
|
||||
<div class="modal-content grow flex flex-col" :class="{'!rounded-s-none': showingInfo}">
|
||||
<div class="modal-header gap-4">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close" data-e2e="e2e-BT-newInventoryModal-close">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close" data-e2e="e2e-BT-invInventoryImport-uploadModal-close">
|
||||
<i class="sn-icon sn-icon-close"></i>
|
||||
</button>
|
||||
<button class="btn btn-light btn-sm mr-auto" @click="showingInfo = !showingInfo">
|
||||
<button class="btn btn-light btn-sm mr-auto" @click="showingInfo = !showingInfo" data-e2e="e2e-BT-invInventoryImport-uploadModal-help">
|
||||
<i class="sn-icon sn-icon-help-s"></i>
|
||||
{{ i18n.t('repositories.import_records.steps.step1.helpText') }}
|
||||
</button>
|
||||
<h4 class="modal-title truncate !block !mr-0" id="edit-project-modal-label" data-e2e="e2e-TX-newInventoryModal-title">
|
||||
<h4 class="modal-title truncate !block !mr-0" id="edit-project-modal-label" data-e2e="e2e-TX-invInventoryImport-uploadModal-title">
|
||||
{{ i18n.t('repositories.import_records.steps.step1.title') }}
|
||||
</h4>
|
||||
</div>
|
||||
<div class="modal-body flex flex-col grow">
|
||||
<p class="text-sn-dark-grey">
|
||||
<p class="text-sn-dark-grey" data-e2e="e2e-TX-invInventoryImport-uploadModal-description">
|
||||
{{ this.i18n.t('repositories.import_records.steps.step1.subtitle') }}
|
||||
</p>
|
||||
<h3 class="my-0 text-sn-dark-grey mb-3">
|
||||
<h3 class="my-0 text-sn-dark-grey mb-3" data-e2e="e2e-TX-invInventoryImport-uploadModal-exportSubtitle">
|
||||
{{ i18n.t('repositories.import_records.steps.step1.exportTitle') }}
|
||||
</h3>
|
||||
<div class="flex gap-4 mb-6">
|
||||
<button class="btn btn-secondary btn-sm" @click="$emit('changeStep', 'ExportModal')">
|
||||
<button class="btn btn-secondary btn-sm" @click="$emit('changeStep', 'ExportModal')" data-e2e="e2e-BT-invInventoryImport-uploadModal-exportAll">
|
||||
<i class="sn-icon sn-icon-export"></i>
|
||||
{{ i18n.t('repositories.import_records.steps.step1.exportFullInvBtnText') }}
|
||||
</button>
|
||||
<a :href="params.attributes.urls.export_empty_repository" target="_blank" class="btn btn-secondary btn-sm">
|
||||
<a
|
||||
:href="params.attributes.urls.export_empty_repository"
|
||||
target="_blank"
|
||||
class="btn btn-secondary btn-sm"
|
||||
data-e2e="e2e-BT-invInventoryImport-uploadModal-downloadTemplate"
|
||||
>
|
||||
<i class="sn-icon sn-icon-export"></i>
|
||||
{{ i18n.t('repositories.import_records.steps.step1.exportEmptyInvBtnText') }}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<h3 class="my-0 text-sn-dark-grey mb-3">
|
||||
<h3 class="my-0 text-sn-dark-grey mb-3" data-e2e="e2e-TX-invInventoryImport-uploadModal-importSubtitle">
|
||||
{{ i18n.t('repositories.import_records.steps.step1.importTitle') }}
|
||||
</h3>
|
||||
<DragAndDropUpload
|
||||
|
|
@ -64,6 +75,7 @@
|
|||
@file:error:clear="this.error = null"
|
||||
:supportingText="`${i18n.t('repositories.import_records.steps.step1.dragAndDropSupportingText')}`"
|
||||
:supportedFormats="['xlsx', 'csv', 'xls', 'txt', 'tsv']"
|
||||
:dataE2e="'invInventoryImport-uploadModal-dragDrop'"
|
||||
/>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
|
@ -75,7 +87,7 @@
|
|||
<i class="sn-icon sn-icon-check"></i>
|
||||
<div class="my-auto">{{ exportInventoryMessage }}</div>
|
||||
</div>
|
||||
<button class="btn btn-secondary" @click="close" aria-label="Close">
|
||||
<button class="btn btn-secondary" @click="close" aria-label="Close" data-e2e="e2e-BT-invInventoryImport-uploadModal-cancel">
|
||||
{{ i18n.t('repositories.import_records.steps.step1.cancelBtnText') }}
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -131,6 +131,16 @@
|
|||
@attachments:viewMode="changeAttachmentsViewMode"
|
||||
@attachment:viewMode="updateAttachmentViewMode"/>
|
||||
</div>
|
||||
<ContentToolbar
|
||||
v-if="orderedElements.length > 2"
|
||||
:insertMenu="insertMenu"
|
||||
@create:table="(...args) => this.createElement('table', ...args)"
|
||||
@create:text="createElement('text')"
|
||||
@create:file="openLoadFromComputer"
|
||||
@create:wopi_file="openWopiFileModal"
|
||||
@create:ove_file="openOVEditor"
|
||||
@create:marvinjs_file="openMarvinJsModal($refs.marvinJsButton)"
|
||||
></ContentToolbar>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -144,6 +154,7 @@ import Attachments from '../shared/content/attachments.vue';
|
|||
import InlineEdit from '../shared/inline_edit.vue';
|
||||
import MenuDropdown from '../shared/menu_dropdown.vue';
|
||||
import deleteResultModal from './delete_result.vue';
|
||||
import ContentToolbar from '../shared/content/content_toolbar';
|
||||
|
||||
import AttachmentsMixin from '../shared/content/mixins/attachments.js';
|
||||
import WopiFileModal from '../shared/content/attachments/mixins/wopi_file_modal.js';
|
||||
|
|
@ -195,7 +206,8 @@ export default {
|
|||
InlineEdit,
|
||||
MenuDropdown,
|
||||
deleteResultModal,
|
||||
StorageUsage
|
||||
StorageUsage,
|
||||
ContentToolbar
|
||||
},
|
||||
watch: {
|
||||
resultToReload() {
|
||||
|
|
@ -275,16 +287,20 @@ export default {
|
|||
if (this.urls.update_url) {
|
||||
menu = menu.concat([{
|
||||
text: this.i18n.t('my_modules.results.insert.text'),
|
||||
icon: 'sn-icon sn-icon-result-text',
|
||||
emit: 'create:text'
|
||||
}, {
|
||||
text: this.i18n.t('my_modules.results.insert.attachment'),
|
||||
submenu: this.filesMenu,
|
||||
icon: 'sn-icon sn-icon-file',
|
||||
position: 'left'
|
||||
}, {
|
||||
text: this.i18n.t('my_modules.results.insert.table'),
|
||||
icon: 'sn-icon sn-icon-tables',
|
||||
emit: 'create:table'
|
||||
}, {
|
||||
text: this.i18n.t('my_modules.results.insert.well_plate'),
|
||||
icon: 'sn-icon sn-icon-tables',
|
||||
submenu: this.wellPlateOptions,
|
||||
position: 'left'
|
||||
}]);
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
<template>
|
||||
<div>
|
||||
<button class="ml-2 btn"
|
||||
id="share-button"
|
||||
type="button"
|
||||
data-e2e="e2e-BT-tasks-shareTask"
|
||||
:class="shareClass"
|
||||
:title="shareValue"
|
||||
@click="openModal">
|
||||
<span class="sn-icon sn-icon-shared"></span>
|
||||
<span class="text-sm">
|
||||
{{ shareValue }}
|
||||
</span>
|
||||
</button>
|
||||
<div :title="shareTitle">
|
||||
<button class="btn"
|
||||
id="share-button"
|
||||
type="button"
|
||||
data-e2e="e2e-BT-tasks-shareTask"
|
||||
:class="[shareClass, {'disabled': !enabled}]"
|
||||
@click="openModal">
|
||||
<span class="sn-icon sn-icon-shared"></span>
|
||||
<span class="text-sm">
|
||||
{{ shareValue }}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div ref="modal">
|
||||
<shareModalContainer :shared="share"
|
||||
:open="visibleShareModal"
|
||||
|
|
@ -43,6 +44,10 @@ export default {
|
|||
canShare: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
enabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
|
@ -60,6 +65,9 @@ export default {
|
|||
},
|
||||
shareValue() {
|
||||
return this.i18n.t(this.share ? 'my_modules.shareable_links.shared' : 'my_modules.shareable_links.share');
|
||||
},
|
||||
shareTitle() {
|
||||
return this.enabled ? this.shareValue : this.i18n.t('my_modules.shareable_links.disabled');
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<span @mouseenter="fetchLocalAppInfo()">
|
||||
<span>
|
||||
<!-- multiple options -->
|
||||
<MenuDropdown
|
||||
v-if="multipleOpenOptions.length > 1"
|
||||
|
|
@ -124,6 +124,9 @@ export default {
|
|||
required: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.fetchLocalAppInfo();
|
||||
},
|
||||
computed: {
|
||||
multipleOpenOptions() {
|
||||
const options = [];
|
||||
|
|
|
|||
43
app/javascript/vue/shared/content/content_toolbar.vue
Normal file
43
app/javascript/vue/shared/content/content_toolbar.vue
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<template>
|
||||
<div class="px-4 py-2 bg-sn-super-light-blue flex gap-4 mt-10 mb-4 rounded">
|
||||
<span class="font-bold shrink-0 leading-10">
|
||||
{{ i18n.t('protocols.steps.insert.button') }}:
|
||||
</span>
|
||||
<div class="flex items-center gap-2 flex-wrap">
|
||||
<template v-for="item in insertMenu">
|
||||
<button v-if="!item.submenu" @click="$emit(item.emit)" class="btn btn-light">
|
||||
<i :class="item.icon"></i>
|
||||
{{ item.text }}
|
||||
</button>
|
||||
<MenuDropdown
|
||||
:listItems="item.submenu"
|
||||
:btnText="item.text"
|
||||
:btnClasses="'btn btn-light'"
|
||||
:position="'right'"
|
||||
:caret="true"
|
||||
:btnIcon="item.icon"
|
||||
@dtEvent="handleEvents"
|
||||
></MenuDropdown>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import MenuDropdown from '../menu_dropdown.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MenuDropdown
|
||||
},
|
||||
name: 'stepToolbar',
|
||||
props: {
|
||||
insertMenu: Array
|
||||
},
|
||||
methods: {
|
||||
handleEvents(event, option) {
|
||||
this.$emit(event, option.params);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
</script>
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
:allowBlank="true"
|
||||
:autofocus="editingName"
|
||||
:attributeName="`${i18n.t('Text')} ${i18n.t('name')}`"
|
||||
:dataE2e="`${dataE2e}-stepText${element.id}`"
|
||||
:dataE2e="`${dataE2e}-stepText${element.id}-title`"
|
||||
@editingEnabled="enableNameEdit"
|
||||
@editingDisabled="disableNameEdit"
|
||||
@update="updateName"
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
</div>
|
||||
<div class="flex rounded min-h-[2.25rem] mb-4 relative group/text_container content__text-body"
|
||||
:class="{ 'edit': inEditMode, 'component__element--locked': !element.attributes.orderable.urls.update_url }"
|
||||
:data-e2e="`e2e-IF-${dataE2e}-stepText${element.id}`"
|
||||
:data-e2e="`e2e-IF-${dataE2e}-stepText${element.id}-content`"
|
||||
@keyup.enter="enableEditMode($event)"
|
||||
tabindex="0">
|
||||
<Tinymce
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
@dragover.prevent
|
||||
@click="handleImportClick"
|
||||
class="flex h-full w-full p-6 rounded border border-sn-light-grey bg-sn-super-light-blue cursor-pointer"
|
||||
:data-e2e="`e2e-CO-${dataE2e}`"
|
||||
>
|
||||
<div id="centered-content" class="flex flex-col gap-4 items-center h-fit w-fit m-auto">
|
||||
<!-- icon -->
|
||||
|
|
@ -43,6 +44,10 @@ export default {
|
|||
type: Array,
|
||||
required: true,
|
||||
default: () => []
|
||||
},
|
||||
dataE2e: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
emits: ['file:dropped', 'file:error'],
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@
|
|||
<div class="buttons">
|
||||
<template v-if="isWindows">
|
||||
<a :href="getWindowsHref"
|
||||
class="btn btn-primary new-project-btn"
|
||||
class="w-full btn btn-primary new-project-btn"
|
||||
:title="i18n.t('users.settings.account.addons.desktop_app.windows_button')"
|
||||
role="button"
|
||||
target="_blank">
|
||||
<span class="hidden-xs">{{ i18n.t('users.settings.account.addons.desktop_app.windows_button') }}</span>
|
||||
<span :class="{'hidden-xs' : !isCompact }">
|
||||
{{ this.isCompact ? i18n.t('general.download') : i18n.t('users.settings.account.addons.desktop_app.windows_button') }}
|
||||
</span>
|
||||
</a>
|
||||
<div v-if="showButtonLabel" class="text-xs pt-2 pb-6" style="color: var(--sn-sleepy-grey);">
|
||||
{{ i18n.t('users.settings.account.addons.desktop_app.version', { version: this.responseData[0]['version']}) }}
|
||||
|
|
@ -15,18 +17,20 @@
|
|||
|
||||
<template v-else-if="isMac">
|
||||
<a :href="getMacHref"
|
||||
class="btn btn-primary new-project-btn"
|
||||
class="w-full btn btn-primary new-project-btn"
|
||||
:title="i18n.t('users.settings.account.addons.desktop_app.macos_button')"
|
||||
role="button"
|
||||
target="_blank">
|
||||
<span class="hidden-xs">{{ i18n.t('users.settings.account.addons.desktop_app.macos_button') }}</span>
|
||||
<span :class="{'hidden-xs' : !isCompact }">
|
||||
{{ this.isCompact ? i18n.t('general.download') : i18n.t('users.settings.account.addons.desktop_app.macos_button') }}
|
||||
</span>
|
||||
</a>
|
||||
<div v-if="showButtonLabel" class="text-xs pt-2 pb-6" style="color: var(--sn-sleepy-grey);">
|
||||
{{ i18n.t('users.settings.account.addons.desktop_app.version', { version: this.responseData[1]['version']}) }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<template v-else-if="!isCompact">
|
||||
<div class="flex">
|
||||
<div>
|
||||
<a :href="getWindowsHref"
|
||||
|
|
@ -60,7 +64,7 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<a v-if="!isUpdateVersionModal" :href="'https://knowledgebase.scinote.net/en/knowledge/how-to-use-scinote-edit'"
|
||||
<a v-if="!isUpdateVersionModal && !isCompact" :href="'https://knowledgebase.scinote.net/en/knowledge/how-to-use-scinote-edit'"
|
||||
:title="i18n.t('users.settings.account.addons.more_info')"
|
||||
class="text-sn-blue"
|
||||
target="_blank">
|
||||
|
|
@ -75,7 +79,8 @@ export default {
|
|||
name: 'ScinoteEditDownload',
|
||||
props: {
|
||||
data: { type: String, required: true },
|
||||
isUpdateVersionModal: { type: Boolean, required: false }
|
||||
isUpdateVersionModal: { type: Boolean, required: false },
|
||||
isCompact: { type: Boolean, required: false, default: false }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -91,7 +96,7 @@ export default {
|
|||
return /Mac OS/.test(this.userAgent);
|
||||
},
|
||||
showButtonLabel() {
|
||||
return this.responseData && this.responseData.length > 0 && !this.isUpdateVersionModal;
|
||||
return this.responseData && this.responseData.length > 0 && !this.isUpdateVersionModal && !this.isCompact;
|
||||
},
|
||||
getWindowsHref() {
|
||||
return this.responseData && this.responseData.length > 0 ? this.responseData[0].url : '#';
|
||||
|
|
|
|||
|
|
@ -29,18 +29,19 @@ module TinyMceImages
|
|||
)[0]
|
||||
next unless tm_asset_to_update
|
||||
|
||||
tm_asset = tm_asset.image.representation(resize_to_limit: Constants::LARGE_PIC_FORMAT).processed
|
||||
variant = tm_asset.image.variant(resize_to_limit: Constants::LARGE_PIC_FORMAT)
|
||||
resized_asset = ActiveStorage::Variant.new(variant.blob, variant.variation).processed
|
||||
|
||||
width_attr = tm_asset_to_update.attributes['width']
|
||||
height_attr = tm_asset_to_update.attributes['height']
|
||||
|
||||
if width_attr && height_attr && (width_attr.value.to_i >= Constants::LARGE_PIC_FORMAT[0] ||
|
||||
height_attr.value.to_i >= Constants::LARGE_PIC_FORMAT[1])
|
||||
width_attr.value = tm_asset.image.blob.metadata['width'].to_s
|
||||
height_attr.value = tm_asset.image.blob.metadata['height'].to_s
|
||||
width_attr.value = resized_asset.image.blob.metadata['width'].to_s
|
||||
height_attr.value = resized_asset.image.blob.metadata['height'].to_s
|
||||
end
|
||||
|
||||
tm_asset_to_update.attributes['src'].value = convert_to_base64(tm_asset.image)
|
||||
tm_asset_to_update.attributes['src'].value = convert_to_base64(resized_asset)
|
||||
description = html_description.css('body').inner_html.to_s
|
||||
end
|
||||
description
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ class MyModuleRepositoryRow < ApplicationRecord
|
|||
team_id: my_module.experiment.project.team.id
|
||||
}
|
||||
)
|
||||
stock_value.last_modified_by_id = last_modified_by_id
|
||||
stock_value.save!
|
||||
save!
|
||||
end
|
||||
|
|
|
|||
|
|
@ -52,7 +52,16 @@ class RepositoryCell < ApplicationRecord
|
|||
}
|
||||
|
||||
def update_repository_row_last_modified_by
|
||||
repository_row.update!(last_modified_by_id: value.last_modified_by_id)
|
||||
# RepositoryStockConsumptionValue currently don't store last_modified_by
|
||||
# so this would fail. Should probably be refactored to unify the behaviour (23.7.2024)
|
||||
if value.last_modified_by_id
|
||||
repository_row.update!(last_modified_by_id: value.last_modified_by_id)
|
||||
else
|
||||
Rails.logger.warn(
|
||||
"Missing last_modified_by_id for #{value.class} with id #{value.id}, " \
|
||||
"skipping update of last_modified_by on RepositoryRow with id #{repository_row_id}."
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def self.create_with_value!(row, column, data, user)
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ Canaid::Permissions.register_for(MyModule) do
|
|||
end
|
||||
|
||||
can :share_my_module do |user, my_module|
|
||||
my_module.permission_granted?(user, MyModulePermissions::SHARE)
|
||||
my_module.team.shareable_links_enabled? && my_module.permission_granted?(user, MyModulePermissions::SHARE)
|
||||
end
|
||||
|
||||
can :restore_my_module do |user, my_module|
|
||||
|
|
|
|||
|
|
@ -213,12 +213,7 @@ module RepositoryImportParser
|
|||
def handle_nil_cell_value(repository_cell)
|
||||
return unless repository_cell.present? && @should_overwrite_with_empty_cells
|
||||
|
||||
if @preview
|
||||
repository_cell.to_destroy = true
|
||||
@updated = true
|
||||
else
|
||||
repository_cell.value.destroy!
|
||||
end
|
||||
@updated = erase_cell!(repository_cell, preview: @preview)
|
||||
|
||||
repository_cell
|
||||
end
|
||||
|
|
@ -241,6 +236,12 @@ module RepositoryImportParser
|
|||
when RepositoryStatusValue
|
||||
repository_status_item_id = cell_value[:repository_status_item_id]
|
||||
repository_cell.value.update_data!(repository_status_item_id, @user, preview: @preview)
|
||||
when RepositoryTimeValue
|
||||
repository_cell.value.update_data!(
|
||||
repository_cell.value.data.change(hour: cell_value.data.hour, min: cell_value.data.min),
|
||||
@user,
|
||||
preview: @preview
|
||||
)
|
||||
else
|
||||
sanitized_cell_value_data = sanitize_cell_value_data(cell_value.data)
|
||||
repository_cell.value.update_data!(sanitized_cell_value_data, @user, preview: @preview)
|
||||
|
|
@ -296,5 +297,25 @@ module RepositoryImportParser
|
|||
# all rows minus header
|
||||
@rows.count - 1
|
||||
end
|
||||
|
||||
def erase_cell!(repository_cell, preview: false)
|
||||
case repository_cell.value
|
||||
when RepositoryStockValue
|
||||
return false if repository_cell.value.amount.zero?
|
||||
|
||||
repository_cell.value.update_data!(
|
||||
{
|
||||
amount: 0,
|
||||
unit_item_id: repository_cell.value.repository_stock_unit_item_id
|
||||
},
|
||||
@user,
|
||||
preview: preview
|
||||
)
|
||||
else
|
||||
preview ? repository_cell.to_destroy = true : repository_cell.value.destroy!
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
<div id="taskSecondaryMenu" class="sticky-header-element bg-sn-white border-b border-solid border-0 border-sn-sleepy-grey rounded-t px-4 py-2 pb-[16px] top-0 sticky flex items-center flex-wrap z-[106]">
|
||||
<div
|
||||
id="taskSecondaryMenu"
|
||||
class="sticky-header-element bg-sn-white border-b border-solid border-0 border-sn-sleepy-grey rounded-t px-4 py-2 pb-[16px] top-0 sticky flex items-center flex-wrap z-[106]"
|
||||
data-e2e="e2e-CO-taskTopToolbar"
|
||||
>
|
||||
<div class="flex items-center gap-4 mr-auto">
|
||||
<% if can_read_experiment?(@my_module.experiment) %>
|
||||
<a class="p-3 border-b-4 border-transparent hover:no-underline uppercase text-bold capitalize <%= is_module_protocols? ? "text-sn-blue" : "text-sn-grey" %>"
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
<div class="task-sharing-and-flows flex items-center gap-2 pl-3">
|
||||
<%= render partial: 'my_modules/status_flow/task_flow_button', locals: { my_module: @my_module } if @my_module.my_module_status_flow %>
|
||||
<%= javascript_include_tag("my_modules/status_flow") %>
|
||||
<% if current_team.shareable_links_enabled? %>
|
||||
<div id="share-task-container" data-behaviour="vue">
|
||||
<share-task-container
|
||||
shareable-link-url="<%= my_module_shareable_link_path(@my_module) %>"
|
||||
:enabled="<%= current_team.shareable_links_enabled? %>"
|
||||
:shared="<%= @my_module.shared? %>"
|
||||
:can-share="<%= can_share_my_module?(@my_module) %>" />
|
||||
</div>
|
||||
|
||||
<%= javascript_include_tag 'vue_share_task_container' %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@
|
|||
<th id="assigned" data-unmanageable="true"><%= t("repositories.table.assigned") %></th>
|
||||
<th id="row-id"><%= t("repositories.table.id") %></th>
|
||||
<th id="row-name"><%= t("repositories.table.row_name") %></th>
|
||||
<th id="relationship" title="<%= t("repositories.table.relationships") %>"><%= t("repositories.table.relationships") %></th>
|
||||
<th id="relationship" data-disabled="<%= !Repository.repository_row_connections_enabled? %>"
|
||||
title="<%= t("repositories.table.relationships") %>"><%= t("repositories.table.relationships") %></th>
|
||||
<th id="added-on" ><%= t("repositories.table.added_on") %></th>
|
||||
<th id="added-by" ><%= t("repositories.table.added_by") %></th>
|
||||
<th id="updated-on" ><%= t("repositories.table.updated_on") %></th>
|
||||
|
|
|
|||
|
|
@ -98,6 +98,14 @@
|
|||
selected>
|
||||
<%= t('libraries.manange_modal_column.select.repository_stock_value') %>
|
||||
</option>
|
||||
<% elsif !RepositoryBase.stock_management_enabled? %>
|
||||
<option value="RepositoryStockValue" class="disabled-option"
|
||||
data-params="<%= {
|
||||
optionClass: 'disabled-option',
|
||||
data_e2e: 'e2e-LB-invItems-manageColumnsModal-stock-dec_clm-disabled'
|
||||
}.to_json %>">
|
||||
<%= t('libraries.manange_modal_column.select.repository_stock_value') %>
|
||||
</option>
|
||||
<% end %>
|
||||
<option data-delimiter=true></option>
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
<div class="comment-input-container !pr-0 grid grid-flow-row">
|
||||
<textarea class="comment-input-field smart-text-area textarea-sm"
|
||||
placeholder="<%= t('comments.placeholder') %>"></textarea>
|
||||
<i class="sn-icon sn-icon-send send-comment !contents before:ml-auto"></i>
|
||||
<i class="sn-icon sn-icon-send send-comment"></i>
|
||||
</div>
|
||||
<div class="error-container"></div>
|
||||
<div class="update-buttons sci-btn-group">
|
||||
|
|
|
|||
|
|
@ -5,17 +5,17 @@
|
|||
</a>
|
||||
</div>
|
||||
<% left_menu_elements.each_with_index do |item, index| %>
|
||||
<%= link_to item[:url], title: item[:name], class:"sci--layout--menu-item", data: { e2e: "e2e-BT-leftMenu-#{item[:name].downcase}", active: item[:submenu].blank? && item[:active], disabled: current_user.teams.blank?, submenu: item[:submenu].any? } do %>
|
||||
<%= link_to item[:url], title: item[:title] || item[:name], class:"sci--layout--menu-item", data: { e2e: "e2e-BT-leftMenu-#{item[:name].downcase}", active: item[:submenu].blank? && item[:active], disabled: current_user.teams.blank?, submenu: item[:submenu].any? } do %>
|
||||
<i class="sn-icon <%= item[:icon] %>"></i>
|
||||
<%= item[:name] %>
|
||||
<%= item[:name].html_safe %>
|
||||
<i class="sn-icon <%= item[:active] ? 'sn-icon-down' : 'sn-icon-right' %> show-submenu"></i>
|
||||
<% end %>
|
||||
<% if item[:submenu].any? %>
|
||||
<div class="sci--layout--menu-submenu" data-id="<%= index %>" data-collapsed="<%= !item[:active] %>" style="--submenu-items:<%= item[:submenu].length %>">
|
||||
<% item[:submenu].each do |subitem| %>
|
||||
<%= link_to subitem[:url], title: subitem[:name], class:"sci--layout--menu-item", data: { e2e: "e2e-BT-leftMenu-#{item[:name].downcase}-#{subitem[:name].downcase}", active: subitem[:active], disabled: current_user.teams.blank? } do %>
|
||||
<%= link_to subitem[:url], title: subitem[:title] || subitem[:name], class:"sci--layout--menu-item", data: { e2e: "e2e-BT-leftMenu-#{item[:name].downcase}-#{subitem[:name].downcase}", active: subitem[:active], disabled: current_user.teams.blank? } do %>
|
||||
<i class="sn-icon sn-icon-dot-small"></i>
|
||||
<%= subitem[:name] %>
|
||||
<%= subitem[:name].html_safe %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1200,6 +1200,7 @@ en:
|
|||
shareable_links:
|
||||
share: "Share"
|
||||
shared: "Shared"
|
||||
disabled: "Sharing is disabled for your team.\nAsk your team admin to enable sharing in the team settings."
|
||||
notes:
|
||||
title: "Notes"
|
||||
no_description: "No task description"
|
||||
|
|
@ -3668,6 +3669,7 @@ en:
|
|||
expand_label: "Expand All"
|
||||
collapse_label: "Collapse All"
|
||||
new_step: "New step"
|
||||
add_step: "Add step"
|
||||
new_step_title: "Create new step"
|
||||
subtitle: "Protocol Steps"
|
||||
no_steps: "Protocol has no steps."
|
||||
|
|
|
|||
BIN
vendor/assets/stylesheets/fonts/SN-icon-font.eot
vendored
BIN
vendor/assets/stylesheets/fonts/SN-icon-font.eot
vendored
Binary file not shown.
|
|
@ -195,4 +195,8 @@
|
|||
<glyph unicode="" glyph-name="task-mini" data-tags="task-mini" d="M339.2 140.8c-23.894 0-43.725 7.885-59.494 23.654-15.804 15.805-23.706 35.651-23.706 59.546v448c0 23.894 7.902 43.742 23.706 59.546 15.77 15.77 35.601 23.654 59.494 23.654h249.6l179.2-179.2v-352c0-23.895-7.885-43.74-23.654-59.546-15.805-15.77-35.651-23.654-59.546-23.654h-345.6zM563.2 550.4v153.6h-224c-8.534 0-15.991-3.209-22.374-9.626-6.417-6.383-9.626-13.841-9.626-22.374v-448c0-8.535 3.209-15.99 9.626-22.374 6.383-6.415 13.841-9.626 22.374-9.626h345.6c8.535 0 15.99 3.21 22.374 9.626 6.415 6.385 9.626 13.839 9.626 22.374v326.4h-153.6zM652.984 468.48l-171.313-228.413-123.272 123.269 36.204 36.209 81.528-81.531 135.892 181.187 40.96-30.72z" />
|
||||
<glyph unicode="" glyph-name="flag" data-tags="flag" d="M256 128v661.333h306.871l17.067-85.333h230.729v-341.333h-221.538l-17.067 85.333h-273.395v-320h-42.667zM625.067 405.333h142.933v256h-224l-17.067 85.333h-228.267v-256h309.333l17.067-85.333z" />
|
||||
<glyph unicode="" glyph-name="undo" data-tags="undo" d="M315.893 192v42.667h309.506c44.25 0 81.954 15.181 113.109 45.538 31.142 30.357 46.72 67.413 46.72 111.177s-15.578 80.687-46.72 110.775c-31.155 30.084-68.86 45.129-113.109 45.129h-330.338l126.517-126.528-30.197-30.199-178.048 178.061 178.048 178.048 30.197-30.197-126.517-126.517h330.338c55.851 0 103.561-19.257 143.134-57.771 39.573-38.507 59.362-85.44 59.362-140.8 0-55.351-19.789-102.421-59.362-141.205s-87.283-58.176-143.134-58.176h-309.506z" />
|
||||
<glyph unicode="" glyph-name="upgrade" data-tags="upgrade" d="M418.808 393.519l33.233 110.114-87.468 64.162h109.292l33.476 111.261 33.476-111.261h109.295l-87.714-64.162 33.229-110.114-88.286 68.348-88.533-68.348zM294.008 44.309v281.186c-27.023 26.586-48 57.711-62.933 93.376s-22.4 73.818-22.4 114.462c0 83.255 28.964 153.847 86.892 211.775s128.521 86.892 211.775 86.892c83.255 0 153.847-28.964 211.776-86.892s86.891-128.521 86.891-211.775c0-40.644-7.467-78.797-22.4-114.462s-35.913-66.79-62.933-93.376v-281.186l-213.333 63.996-213.333-63.996zM507.341 277.333c71.113 0 131.554 24.887 181.333 74.667s74.667 110.221 74.667 181.333c0 71.111-24.887 131.555-74.667 181.333s-110.221 74.667-181.333 74.667c-71.113 0-131.555-24.889-181.333-74.667s-74.667-110.222-74.667-181.333c0-71.113 24.889-131.554 74.667-181.333s110.22-74.667 181.333-74.667zM336.675 104.781l170.666 47.834 170.667-47.834v184.777c-23.795-17.502-50.227-31.027-79.3-40.572-29.077-9.545-59.529-14.319-91.366-14.319-31.834 0-62.289 4.774-91.364 14.319-29.073 9.545-55.507 23.070-79.302 40.572v-184.777z" />
|
||||
<glyph unicode="" glyph-name="test-tube" data-tags="test-tube" d="M610.718 768l241.361-241.361-30.17-30.17-30.17 30.17-362.039-362.035c-49.988-49.988-131.033-49.988-181.020 0-49.987 49.984-49.987 131.029 0 181.018l362.038 362.039-30.17 30.17 30.17 30.17zM640.887 677.49l-235.11-235.11h241.36l114.432 114.43-120.683 120.68z" />
|
||||
<glyph unicode="" glyph-name="storage" data-tags="storage" d="M239.59 106.667c-19.637 0-36.034 6.579-49.19 19.733s-19.733 29.551-19.733 49.19v544.82c0 19.637 6.578 36.034 19.733 49.189s29.552 19.733 49.19 19.733h544.82c19.639 0 36.036-6.578 49.19-19.733s19.733-29.552 19.733-49.189v-544.82c0-19.639-6.579-36.036-19.733-49.19s-29.551-19.733-49.19-19.733h-544.82zM213.333 576.082h597.333v144.329c0 6.563-2.735 12.58-8.205 18.051s-11.486 8.205-18.052 8.205h-544.82c-6.564 0-12.581-2.735-18.051-8.205s-8.205-11.488-8.205-18.051v-144.329zM213.333 362.586h597.333v170.83h-597.333v-170.83zM239.59 149.333h544.82c6.566 0 12.582 2.735 18.052 8.205s8.205 11.486 8.205 18.052v144.329h-597.333v-144.329c0-6.566 2.735-12.582 8.205-18.052s11.488-8.205 18.051-8.205zM426.667 640v55.959h170.667v-55.959h-170.667zM426.667 426.667v55.795h170.667v-55.795h-170.667zM426.667 213.333v55.629h170.667v-55.629h-170.667z" />
|
||||
<glyph unicode="" glyph-name="outbound" data-tags="outbound" d="M264.043 222.357l-29.376 29.376 430.11 430.933h-396.467v42.667h469.333v-469.333h-42.667v396.469l-430.933-430.112z" />
|
||||
</font></defs></svg>
|
||||
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 128 KiB |
BIN
vendor/assets/stylesheets/fonts/SN-icon-font.ttf
vendored
BIN
vendor/assets/stylesheets/fonts/SN-icon-font.ttf
vendored
Binary file not shown.
BIN
vendor/assets/stylesheets/fonts/SN-icon-font.woff
vendored
BIN
vendor/assets/stylesheets/fonts/SN-icon-font.woff
vendored
Binary file not shown.
BIN
vendor/assets/stylesheets/fonts/SN-icon-font.woff2
vendored
BIN
vendor/assets/stylesheets/fonts/SN-icon-font.woff2
vendored
Binary file not shown.
24
vendor/assets/stylesheets/sn-icon-font.css
vendored
24
vendor/assets/stylesheets/sn-icon-font.css
vendored
|
|
@ -1,11 +1,11 @@
|
|||
@font-face {
|
||||
font-family: 'SN-icon-font';
|
||||
src: url('fonts/SN-icon-font.eot?m1g5fz');
|
||||
src: url('fonts/SN-icon-font.eot?m1g5fz#iefix') format('embedded-opentype'),
|
||||
url('fonts/SN-icon-font.woff2?m1g5fz') format('woff2'),
|
||||
url('fonts/SN-icon-font.ttf?m1g5fz') format('truetype'),
|
||||
url('fonts/SN-icon-font.woff?m1g5fz') format('woff'),
|
||||
url('fonts/SN-icon-font.svg?m1g5fz#SN-icon-font') format('svg');
|
||||
src: url('fonts/SN-icon-font.eot?9ywu8k');
|
||||
src: url('fonts/SN-icon-font.eot?9ywu8k#iefix') format('embedded-opentype'),
|
||||
url('fonts/SN-icon-font.woff2?9ywu8k') format('woff2'),
|
||||
url('fonts/SN-icon-font.ttf?9ywu8k') format('truetype'),
|
||||
url('fonts/SN-icon-font.woff?9ywu8k') format('woff'),
|
||||
url('fonts/SN-icon-font.svg?9ywu8k#SN-icon-font') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: block;
|
||||
|
|
@ -533,3 +533,15 @@
|
|||
.sn-icon-undo:before {
|
||||
content: "\e9a8";
|
||||
}
|
||||
.sn-icon-upgrade:before {
|
||||
content: "\e9a9";
|
||||
}
|
||||
.sn-icon-test-tube:before {
|
||||
content: "\e9aa";
|
||||
}
|
||||
.sn-icon-storage:before {
|
||||
content: "\e9ab";
|
||||
}
|
||||
.sn-icon-outbound:before {
|
||||
content: "\e9ac";
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue