Merge branch 'features/protocol_versioning' into gc_SCI_8058

This commit is contained in:
G-Chubinidze 2023-03-14 17:07:52 +04:00 committed by GitHub
commit 7881ffbd3d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 203 additions and 99 deletions

View file

@ -491,29 +491,37 @@ var ExperimnetTable = {
}
});
},
initFilters: function() {
this.filterDropdown = filterDropdown.init();
getFilterValues: function() {
let $experimentFilter = $('#experimentTable .my-modules-filters');
$.each(this.filters, (_i, filter) => {
this.activeFilters[filter.name] = filter.apply($experimentFilter);
});
// filters are active if they have any non-empty value
let filtersEmpty = Object.values(this.activeFilters).every(value => /^\s+$/.test(value)
|| value === null
|| value === undefined
|| (value && value.length === 0));
this.filtersActive = !filtersEmpty;
},
filtersEnabled: function() {
this.getFilterValues();
return this.filters.some((filter) => {
return filter.active(this.activeFilters[filter.name]);
});
},
initFilters: function() {
let $experimentFilter = $('#experimentTable .my-modules-filters');
this.filterDropdown = filterDropdown.init(() => this.filtersEnabled());
$.each(this.filters, (_i, filter) => {
filter.init($experimentFilter);
});
this.filterDropdown.on('filter:apply', () => {
$.each(this.filters, (_i, filter) => {
this.activeFilters[filter.name] = filter.apply($experimentFilter);
});
// filters are active if they have any non-empty value
let filtersEmpty = Object.values(this.activeFilters).every(value => /^\s+$/.test(value) || value === null || value === undefined || value && value.length === 0);
this.filtersActive = !filtersEmpty;
filterDropdown.toggleFilterMark(
this.filterDropdown,
this.filters.some((filter) => {
return filter.active(this.activeFilters[filter.name]);
})
);
filterDropdown.toggleFilterMark(this.filterDropdown, this.filtersEnabled());
this.loadTable();
});

View file

@ -40,8 +40,9 @@ function initLinkUpdate() {
var modalTitle = modal.find('.modal-title');
var modalMessage = modal.find('.modal-body .message');
var updateBtn = modal.find(".modal-footer [data-action='submit']");
$("[data-action='unlink'], [data-action='revert'], [data-action='update-parent'], [data-action='update-self']")
.on('ajax:success', function(e, data) {
$('.protocol-options-dropdown')
.on('ajax:success', "[data-action='unlink'], [data-action='revert'], [data-action='update-parent'],"
+ "[data-action='update-self']", function(e, data) {
modalTitle.html(data.title);
modalMessage.html(data.message);
updateBtn.text(data.btn_text);

View file

@ -559,7 +559,7 @@ var ProjectsIndex = (function() {
}
function initProjectsFilters() {
var $filterDropdown = filterDropdown.init();
var $filterDropdown = filterDropdown.init(filtersEnabled);
let $projectsFilter = $('.projects-index .projects-filters');
let $membersFilter = $('.members-filter', $projectsFilter);
let $foldersCB = $('#folder_search', $projectsFilter);
@ -569,15 +569,30 @@ var ProjectsIndex = (function() {
let $archivedOnToFilter = $('.archived-on-filter .to-date', $projectsFilter);
let $textFilter = $('#textSearchFilterInput', $projectsFilter);
function getFilterValues() {
createdOnFromFilter = selectDate($createdOnFromFilter);
createdOnToFilter = selectDate($createdOnToFilter);
membersFilter = dropdownSelector.getValues($('.members-filter'));
lookInsideFolders = $foldersCB.prop('checked') ? 'true' : '';
archivedOnFromFilter = selectDate($archivedOnFromFilter);
archivedOnToFilter = selectDate($archivedOnToFilter);
projectsViewSearch = $textFilter.val();
}
function filtersEnabled() {
getFilterValues();
return projectsViewSearch
|| createdOnFromFilter
|| createdOnToFilter
|| (membersFilter && membersFilter.length !== 0)
|| lookInsideFolders
|| archivedOnFromFilter
|| archivedOnToFilter;
}
function appliedFiltersMark() {
let filtersEnabled = projectsViewSearch
|| createdOnFromFilter
|| createdOnToFilter
|| (membersFilter && membersFilter.length !== 0)
|| lookInsideFolders
|| archivedOnFromFilter
|| archivedOnToFilter;
filterDropdown.toggleFilterMark($filterDropdown, filtersEnabled);
filterDropdown.toggleFilterMark($filterDropdown, filtersEnabled());
}
dropdownSelector.init($membersFilter, {
@ -602,14 +617,6 @@ var ProjectsIndex = (function() {
});
$filterDropdown.on('filter:apply', function() {
createdOnFromFilter = selectDate($createdOnFromFilter);
createdOnToFilter = selectDate($createdOnToFilter);
membersFilter = dropdownSelector.getValues($('.members-filter'));
lookInsideFolders = $foldersCB.prop('checked') ? 'true' : '';
archivedOnFromFilter = selectDate($archivedOnFromFilter);
archivedOnToFilter = selectDate($archivedOnToFilter);
projectsViewSearch = $textFilter.val();
appliedFiltersMark();
refreshCurrentView();
});

View file

@ -147,7 +147,7 @@
}
function initExperimentsFilters() {
var $filterDropdown = filterDropdown.init();
var $filterDropdown = filterDropdown.init(filtersEnabled);
let $experimentsFilter = $('.experiments-filters');
let $startedOnFromFilter = $('.started-on-filter .from-date', $experimentsFilter);
@ -158,18 +158,7 @@
let $archivedOnToFilter = $('.archived-on-filter .to-date', $experimentsFilter);
let $textFilter = $('#textSearchFilterInput', $experimentsFilter);
function appliedFiltersMark() {
let filtersEnabled = experimentsViewSearch
|| startedOnFromFilter
|| startedOnToFilter
|| modifiedOnFromFilter
|| modifiedOnToFilter
|| archivedOnFromFilter
|| archivedOnToFilter;
filterDropdown.toggleFilterMark($filterDropdown, filtersEnabled);
}
$filterDropdown.on('filter:apply', function() {
function getFilterValues() {
startedOnFromFilter = selectDate($startedOnFromFilter);
startedOnToFilter = selectDate($startedOnToFilter);
modifiedOnFromFilter = selectDate($modifiedOnFromFilter);
@ -177,6 +166,26 @@
archivedOnFromFilter = selectDate($archivedOnFromFilter);
archivedOnToFilter = selectDate($archivedOnToFilter);
experimentsViewSearch = $textFilter.val();
}
function filtersEnabled() {
getFilterValues();
return experimentsViewSearch
|| startedOnFromFilter
|| startedOnToFilter
|| modifiedOnFromFilter
|| modifiedOnToFilter
|| archivedOnFromFilter
|| archivedOnToFilter;
}
function appliedFiltersMark() {
filterDropdown.toggleFilterMark($filterDropdown, filtersEnabled());
}
$filterDropdown.on('filter:apply', function() {
appliedFiltersMark();
refreshCurrentView();
});

View file

@ -51,7 +51,7 @@ var ProtocolsIndex = (function() {
}
function initProtocolsFilters() {
var $filterDropdown = filterDropdown.init();
var $filterDropdown = filterDropdown.init(filtersEnabled);
let $protocolsFilter = $('.protocols-index .protocols-filters');
let $publishedByFilter = $('.published-by-filter', $protocolsFilter);
let $accessByFilter = $('.access-by-filter', $protocolsFilter);
@ -64,18 +64,36 @@ var ProtocolsIndex = (function() {
let $archivedOnToFilter = $('.archived-on-filter .to-date', $protocolsFilter);
let $textFilter = $('#textSearchFilterInput', $protocolsFilter);
function getFilterValues() {
publishedOnFromFilter = selectDate($publishedOnFromFilter);
publishedOnToFilter = selectDate($publishedOnToFilter);
modifiedOnFromFilter = selectDate($modifiedOnFromFilter);
modifiedOnToFilter = selectDate($modifiedOnToFilter);
publishedByFilter = dropdownSelector.getValues($('.published-by-filter'));
accessByFilter = dropdownSelector.getValues($('.access-by-filter'));
hasDraftFilter = $hasDraft.prop('checked') ? 'true' : '';
archivedOnFromFilter = selectDate($archivedOnFromFilter);
archivedOnToFilter = selectDate($archivedOnToFilter);
protocolsViewSearch = $textFilter.val();
}
function filtersEnabled() {
getFilterValues();
return protocolsViewSearch
|| publishedOnFromFilter
|| publishedOnToFilter
|| modifiedOnFromFilter
|| modifiedOnToFilter
|| (publishedByFilter && publishedByFilter.length !== 0)
|| (accessByFilter && accessByFilter.length !== 0)
|| hasDraftFilter
|| archivedOnFromFilter
|| archivedOnToFilter;
}
function appliedFiltersMark() {
let filtersEnabled = protocolsViewSearch
|| publishedOnFromFilter
|| publishedOnToFilter
|| modifiedOnFromFilter
|| modifiedOnToFilter
|| (publishedByFilter && publishedByFilter.length !== 0)
|| (accessByFilter && accessByFilter.length !== 0)
|| hasDraftFilter
|| archivedOnFromFilter
|| archivedOnToFilter;
filterDropdown.toggleFilterMark($filterDropdown, filtersEnabled);
filterDropdown.toggleFilterMark($filterDropdown, filtersEnabled());
}
$.each([$publishedByFilter, $accessByFilter], function(_i, selector) {
@ -97,17 +115,6 @@ var ProtocolsIndex = (function() {
});
$filterDropdown.on('filter:apply', function() {
publishedOnFromFilter = selectDate($publishedOnFromFilter);
publishedOnToFilter = selectDate($publishedOnToFilter);
modifiedOnFromFilter = selectDate($modifiedOnFromFilter);
modifiedOnToFilter = selectDate($modifiedOnToFilter);
publishedByFilter = dropdownSelector.getValues($('.published-by-filter'));
accessByFilter = dropdownSelector.getValues($('.access-by-filter'));
hasDraftFilter = $hasDraft.prop('checked') ? 'true' : '';
archivedOnFromFilter = selectDate($archivedOnFromFilter);
archivedOnToFilter = selectDate($archivedOnToFilter);
protocolsViewSearch = $textFilter.val();
appliedFiltersMark();
protocolsDatatable.ajax.reload();
});

View file

@ -7,7 +7,7 @@
})
.on('show.bs.modal', function() {
$(`${protocolModal} #protocol_name`).parent().removeClass('error');
$(`${protocolModal} form[data-action="new"] #protocol_name`).val('');
$(`${protocolModal} #protocol_name`).val('');
});
let roleSelector = `${protocolModal} #protocol_role_selector`;

View file

@ -1,5 +1,6 @@
var filterDropdown = (function() {
var $filterContainer = '';
var $filtersEnabled = false;
function initClearButton() {
$('.clear-button', $filterContainer).click(function(e) {
@ -21,7 +22,7 @@ var filterDropdown = (function() {
});
}
function initSearchField() {
function initSearchField(filtersEnabledFunction) {
var $textFilter = $('#textSearchFilterInput', $filterContainer);
$filterContainer.on('show.bs.dropdown', function() {
@ -47,7 +48,9 @@ var filterDropdown = (function() {
}).on('hide.bs.dropdown', function(e) {
if (e.target === e.currentTarget) {
$('#textSearchFilterHistory').hide();
$('.apply-filters', $filterContainer).click();
if (filtersEnabledFunction() || $filtersEnabled) {
$('.apply-filters', $filterContainer).click();
}
}
});
@ -98,15 +101,17 @@ var filterDropdown = (function() {
}
return {
init: function() {
init: function(filtersEnabledFunction) {
$filterContainer = $('.filter-container');
$filtersEnabled = false;
initClearButton();
preventDropdownClose();
initApplyButton();
initSearchField();
initSearchField(filtersEnabledFunction);
return $filterContainer;
},
toggleFilterMark: function(filterContainer, filtersEnabled) {
$filtersEnabled = filtersEnabled;
if (filtersEnabled) {
filterContainer.addClass('filters-applied');
} else {

View file

@ -426,10 +426,10 @@
left: -125px;
max-width: 100vw;
width: 506px;
padding: 15px 0;
padding: 0;
.dropdown-content {
padding: 24px;
padding: 12px 24px;
}
.dropdown-header,
@ -489,16 +489,19 @@
}
}
}
}
.dropdown-footer {
border-top: $border-tertiary;
.notification-line {
@include font-button;
color: $color-silver-chalice;
display: flex;
margin: 8px 0;
.fas {
line-height: 21px;
margin-right: 3px;
margin-right: 11px;
}
&.new-parent-version {
@ -510,10 +513,6 @@
}
}
}
.dropdown-footer {
border-top: $border-tertiary;
}
}
}

View file

@ -20,6 +20,14 @@
width: 100%;
tbody {
td {
vertical-align: middle;
}
td:first-child {
padding-top: 4px;
}
td:not(:first-child) {
max-width: 30rem;
overflow: hidden;
@ -78,7 +86,7 @@
}
td:not(:first-child) {
padding: 14px 8px;
padding: 12px 8px;
}
}

View file

@ -96,12 +96,17 @@
padding-left: 20px;
}
}
.protocol-details {
.protocol-metadata {
margin-bottom: 2em;
.data-block {
margin-bottom: 16px;
> :nth-child(2) {
margin-left: 8px;
}
}
.authors-data {
@ -113,12 +118,18 @@
flex-basis: calc(100% - 90px);
flex-grow: 1;
line-height: 32px;
margin-left: .75em;
margin-left: 8px;
font-weight: bold;
}
* {
flex-shrink: 0;
}
.sci-inline-edit__view,
textarea {
padding-left: 10px;
}
}
.keywords-data {
@ -133,6 +144,11 @@
.dropdown-selector-container {
padding-right: 10px;
margin-left: 0;
.input-field {
margin-left: 0;
}
&:not(.active) {
.input-field {
@ -146,7 +162,7 @@
&.active {
.input-field {
border: 1px solid $color-alto;
border: 1px solid $brand-focus;
}
}
}

View file

@ -64,6 +64,20 @@
.btn {
margin-right: .25em;
}
.btn:focus {
box-shadow: 0 0 0 3px $brand-focus;
}
.btn-light {
&:active {
background-color: $color-alto !important;
}
&:hover {
background: $color-white;
}
}
}
.pagination-info,

View file

@ -554,9 +554,12 @@ mark,.mark {
table tbody tr .breadcrumb {
padding: 0 5px;
position: relative;
right: 15px;
& li + li::before {
content: "> ";
color: $color-volcano;
content: "/ ";
}
}
@ -573,6 +576,10 @@ mark,.mark {
}
}
.no-linked-children {
padding: 16px 0;
}
a.edit-name-link small {
margin-left: 5px;
display: none;

View file

@ -189,6 +189,9 @@
inRepository() {
return this.protocol.attributes.in_repository
},
linked() {
return this.protocol.attributes.linked;
},
urls() {
return this.protocol.attributes.urls || {}
}
@ -232,21 +235,34 @@
if (this.inRepository) return
// legacy method from app/assets/javascripts/my_modules/protocols.js
refreshProtocolStatusBar();
// Update protocol options drowpdown for linked tasks
this.refreshProtocolDropdownOptions();
},
refreshProtocolDropdownOptions() {
if (!this.linked && this.inRepository) return
$.get(this.protocolUrl, (result) => {
this.protocol.attributes.urls = result.data.attributes.urls;
});
},
updateProtocol(attributes) {
this.protocol.attributes = attributes
},
updateName(newName) {
this.protocol.attributes.name = newName;
this.refreshProtocolStatus();
$.ajax({
type: 'PATCH',
url: this.urls.update_protocol_name_url,
data: { protocol: { name: newName } }
data: { protocol: { name: newName } },
success: () => {
this.refreshProtocolStatus();
}
});
},
updateDescription(protocol) {
this.protocol.attributes = protocol.attributes
this.refreshProtocolStatus();
},
addStep(position) {
$.post(this.urls.add_step_url, {position: position}, (result) => {
@ -257,8 +273,8 @@
if(position === this.steps.length - 1) {
this.$nextTick(() => this.scrollToBottom());
}
this.refreshProtocolStatus();
})
this.refreshProtocolStatus();
},
updateStepsPosition(step, action = 'add') {
let position = step.attributes.position;

View file

@ -86,7 +86,9 @@ export default {
});
filesUploadedCntr += 1;
if (filesUploadedCntr === filesToUploadCntr) {
this.$emit('stepUpdated');
setTimeout(() => {
this.$emit('stepUpdated');
}, 1000);
resolve('done');
}
}

View file

@ -25,19 +25,19 @@
<div id="details-container" class="protocol-details collapse in">
<div class="protocol-metadata">
<p class="data-block">
{{ i18n.t("protocols.header.version") }}
<span>{{ i18n.t("protocols.header.version") }}</span>
<b>{{ protocol.attributes.version }}</b>
</p>
<p class="data-block">
{{ i18n.t("protocols.header.updated_at") }}
<span>{{ i18n.t("protocols.header.updated_at") }}</span>
<b>{{ protocol.attributes.updated_at_formatted }}</b>
</p>
<p class="data-block">
{{ i18n.t("protocols.header.created_at") }}
<span>{{ i18n.t("protocols.header.created_at") }}</span>
<b>{{ protocol.attributes.created_at_formatted }}</b>
</p>
<p class="data-block">
{{ i18n.t("protocols.header.added_by") }}
<span>{{ i18n.t("protocols.header.added_by") }}</span>
<img :src="protocol.attributes.added_by.avatar"/>
{{ protocol.attributes.added_by.name }}
</p>

View file

@ -419,6 +419,7 @@
$.post(this.urls[`create_${elementType}_url`], (result) => {
result.data.isNew = true;
this.elements.push(result.data)
this.$emit('stepUpdated')
}).error(() => {
HelperModule.flashAlertMsg(this.i18n.t('errors.general'), 'danger');
})

View file

@ -8,7 +8,7 @@ class ProtocolSerializer < ActiveModel::Serializer
attributes :name, :id, :urls, :description, :description_view, :updated_at, :in_repository,
:created_at_formatted, :updated_at_formatted, :added_by, :authors, :keywords, :version, :code,
:published, :version_comment, :archived, :disabled_drafting
:published, :version_comment, :archived, :linked, :disabled_drafting
def updated_at
object.updated_at.to_i
@ -95,6 +95,10 @@ class ProtocolSerializer < ActiveModel::Serializer
true
end
end
def linked
object.linked?
end
private

View file

@ -11,7 +11,7 @@
</table>
</div>
<% else %>
<div>
<div class="no-linked-children">
<em><%= t("protocols.index.linked_children.no_linked_children") %></em>
</div>
<% end %>
<% end %>